一、概念
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来更改此项默认设置。