Ibeo LUX 开发学习手册(1)ubuntu 16.04

一、概念

IbeoDevice/DataBlock/DataListener

      IBEODevice会从雷达/ECU接收信息(scan、object list、vehicle data、images)并转换成Datablock数据块格式。接收后为已注册到ibeodevice的数据库的各个特定类型提供所有的datalistener。因此,设备接收数据块,它将调用所有已注册的DataListener的需要的方法,在那里可以执行用户操作。

Database access/Reader/Database Replayer

  对MongoDB数据库的访问将由特定的mongo-cxx-driver接口。这些接口(例如MongoDbInterface,MongoDbInterfaceT, MongoDbObjInterface)提供合适的函数来执行数据库查询。

根据接口和函数的不同,参数可以不同。

(e.g. mongo::BSONObj,mongo::DBClientCursor, DbQueryIterator<DataType>, bool). 

      DbQueryIterator<DataType>简化处理查询结果,他会自动转换接收的mongo::BSONObj (from a mongo::DBClientCursor)为数据类型。

     为了支持 DataBlocks 的查询(e.g.scan, object list, vehicle data),特定的DbDataBlockReader会处理数据库连接和数据的获取。

IbeoDevice的概念在上面已经进行了阐述,将通过DatabaseReplayer进行补充. 此设备将通知所有的 listeners.

DbDataBlockReaders按时间顺序对特定类型的数据库进行读取。

利用IBEOsdk 编程:

确定连接的设备,可选择的有:

 IbeoLux      (LUX3/4 Laserscanner)

 IbeoEcu      (Ibeo ECU device,connected to a scanner)

 IbeoScala    (Ibeo Scala (B1 orB2) Laserscanner)

 IbeoMiniLux  (Ibeo MiniLuxlaserscanner)

对应设备需要包含的头文件

 IbeoLux include:    <ibeosdk/lux.hpp>

 IbeoEcu include:    <ibeosdk/ecu.hpp>

 IbeoScala include:  <ibeosdk/scala.hpp>

 IbeoMiniLux include: <iboesdk/minilux.hpp>

决定你所感兴趣的信息,并未每个信息类型创建一个listener类

(示例在 IbeoSdkFileDemo:class MyScanListener, MyObjectListener,以及 IbeoSdkEcuLiveDemo:

AllEcuListener 及所有listener聚集在一个类中)

1. 创建 listener.

2. 提供IP地址和接口作为参数创建IbeoDevice

3. 可选: 设置设备的 LogFileManger

4. 注册所有的 listener

5. 建立硬件IbeoDevice 类的连接.

接收将在一个单独的线程中处理。所以主线程需要保持激活。

 注意:1、退出程序调用exit(cstdlib),而不是return从主函数关闭所有的openchannels,防止因打开通道而崩溃。

打开通道

           2、如果你在Linux上建立了静态的 libibeosdk.a你需要连接使用连接选项  --whole-archive (use"-Wl,--whole-archive" on the g++ 命令行). 否则将不能从设备中接收到 DataBlocks。

示例:

IbeoSdkEcuLiveDemo.cpp, class AllEcuListener.:

由于 AllEcuListener 是有许多listeners构成, the AllEcuListener object,allEcuListener需要在 live_demo 函数中注册.

ECU目标连通之后,任务将保持激活状态。所有工作将由ECU接收线程来处理。

当接收到一个新的数据块,会为他通知所有注册的Listener并调用适合的方法。

以防一个 ObjectListEcuEt 数据块被所有注册 ObjectListEcuEt的Listener 调用。这个调用在ECUobject线程的环境中。 

 这里,用户可执行一些操作,这不会花太长时间,因为在处理过程中TCP/IP接口无法接收。

例如可以显示所有接受目标的ID:

virtual void onData(const ObjectListEcuEt*const objectList)

{

       logInfo<< "ET Objects received: # " <<objectList->getNbOfObjects()

              <<std::endl;

       conststd::vector<ObjectEcuEt>& objects = objectList->getObjects();

       for(unsigned int i = 0; i < objects.size(); ++i) {

              std::cerr<< "Object " << i

                     <<" has id: " << objects.at(i).getObjectId() << std::endl;

       }

}

类型名称冲突

SDK中所有类的定义是在ibeosdk的命名空间中,为了避免命名冲突,不要使用:

       usingnamespace ibeosdk;

而是以ibeosdk:: 作为前缀。

日志

LogFile类提供了日志输出函数,如 可以使用logError, logInfo, logWarning, logDebug 来替代cerr or cout 加<<.

这些“函数”实际上是用预定义的编译器宏作为参数调用LogFile methods_logError、_logInfo等的宏,即文件名、函数名和当前资源代码行数。

日志文件名可以是常规文件名,也可以是默认的"cerr" 。

在这种情况下,输出将被处理到 cerr 流。

使用LogFileManager类可以实现日志文件和一些其他IDC输出文件的 自动同步分割,在 SplitFile类中并被注册到 LogFileManager 目标。

执行文件分割以防日志文件达到或略微超过它的文件尺寸限制。此外,每个注册的SplitFile 可以发送它的分割请求到它的LogFileManager 以防溢出这个文件的尺寸限制。 

分割只在 DataType_LuxScan 或DataType_EcuScan之前执行。即在通知收到新的数据块之前LogFileManager::checkSplitRequired会被IbeoDevice调用  

只有这个数据块的数据类型是DataType_LuxScan 或DataType_EcuScan时,将实际检查条件并执行分割。

这导致实际输出文件\日志文件的大小将超过给定的尺寸限制,取决于在下一次扫描之前将会接收到多少数据块。

 这在设定文件尺寸限制时需要被考虑到。

文件分割示例见 IbeoSdkWriterDemo中的IdcWriter类。

使用日志

使用 LogFileManager

创建LogFileManager 

调用 LogFile::setTargetFileSize   (设置文件尺寸最大值)

LogFile::setLogFileBaseName  (可选; 默认是cerr)

LogFile::setLogLevel         (设置日志等级滤波器)

logFileManager.start         (打开日志文件)

可选:

创建 IbeoDevice

lux.setLogFileManager        (设置LogFileManager,使 IbeoDevice 可以触发是否执行分割的检查)


不使用LogFileManager


 LogFile::setLogFileBaseName  (optional; cerr is default)

LogFile::setLogLevel         (设置日志等级滤波器)

call LogFile::getLogFile          (打开日志文件)


捕捉日志流


为了能够在不提供cout/cerr或文件输出的环境中使用日志记录,还可以捕获日志输出流写入的内容。

捕获是面向行的,即当您发送一个endl到流时,您的回调方法(见下文)将以作为参数的c-string的形式被调用。

 示例见IbeoSdkFileDemo.cpp.

       CustomLogStreamCallback的派生类(如 CustomLogStreamCallbackExample)和实现方法

       virtual void onLineEnd(const char* const s, const int)

 在日志开始之前,创建一个类的对象并设置日志文件的CustomLogStreamCallback指针,使用

       LogFile::setCustomLogStreamCallback

(见 IbeoSdkFileDemo.cpp:main)在你的对象上建立指针.

CustomLogStreamCallback对象的使用权经由指针传递给调用方。需要确认当日志激活时,这个对象始终存在。

你可以调用适应环境的写/打印命令应用onLineEnd,例如使用 std::cerr 


排错

Receive Buffer too small:

 下面的消息代表接受缓冲区太小:

Error - MsgBuffer.cpp::recvMsg(134): Illegal message body size occured, buffer

 sizeexceeded: XXXXX Bytes in received DataBlock: 0xHHHH Set to 0.

其中 0xHHHH 是接收到的数据块的ID。 

增加缓冲区大小来解决这个问题:

src/ibeosdk/IbeoTcpIpDeviceBase.hpp

       staticconst int msgBufferSize = 196608;

适合你所要传达信息的尺寸并重新编译你的程序。

-----------------------------------------------------------------------------------------

The registration of the listener has changed with 4.2.1.

在这之前,需要为每个可以被这个类接收的数据锁注册一个多侦听器类之前。

现在,由于DataListener 类的内部结构已经改变了,这已经不需要了。相反每次你注册 listener, listener会增加监听所有他所支持的数据块。因此,仅仅调用一次注册的listener使用多侦听器类是必要的。


当使用日志自定义流时,日志输出突然崩溃。

------------------------------------------------------------

自定义的日志自定义流使用内部缓冲区来保存日志行,直到接收到行尾。如果行尾被接收,行是完整的,然后自定义日志流将被执行。

但是当行过长时,运算符<<将会阻止更多的数据存入已满的内部缓冲区,然而行尾将不会到达缓冲区,因此自定义行为将不会被执行且缓冲区将不会被耗尽。

默认的缓冲区大小是5000字符(4.3.1版本之前是1000)

改变Log.hpp中CustomLogStream::create 的signature来更改此项默认设置。



 

 







版权声明:本文为feccc原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。