Lightweight Communications and Marshalling (LCM)
LCM是一组用于消息传递和数据编组的库和工具,针对高带宽和低延迟至关重要的实时系统。它提供了一个发布、订阅消息的传递模型和自动编组、解组代码的生成。
1、安装:(https://lcm-proj.github.io/build_instructions.html)
下载:https://github.com/lcm-proj/lcm/releases
Ubuntu下依赖:
- build-essential
- libglib2.0-dev
建议安装的包:
- openjdk-6-jdk
- python-dev
安装:
$ unzip lcm-1.3.1.zip
$ cd lcm-1.3.1
$ ./configure
$ make
$ sudo make install
$ sudo ldconfig
安装后:
为lcm创建一个ld.so.conf文件
$ export LCM_INSTALL_DIR=/usr/local/lib
echoechoLCM_INSTALL_DIR > /etc/ld.so.conf.d/lcm.conf
配置pkgconfig来查找lcm.pc
$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$LCM_INSTALL_DIR/pkgconfig
2、LCM消息
通过lem-gen将定义的lcm消息格式,生成消息的自动编解码代码。
LCM支持的原生消息类型:
type |
Description |
---|---|
int8_t |
8-bit signed integer |
int16_t |
16-bit signed integer |
int32_t |
32-bit signed integer |
int64_t |
64-bit signed integer |
float |
32-bit IEEE floating point value |
double |
64-bit IEEE floating point value |
string |
UTF-8 string |
boolean |
true/false logical value |
byte |
8-bit value |
例如:
定义一个下面例程中用到的消息exlcm.lcm:
package exlcm;
struct Example
{
int16_t a;
double b;
}
注意namespace后表示的是域名,生成的类所属的namespace。
然后执行指令:lcm-gen -x exlcm.lcm 生成代码。
也可以生成组合式消息。以定义的激光雷达点云数据格式为例子。
一个激光点的格式 PointXYZIR.lcm:
package PointType;
struct PointXYZIR
{
float x;
float y;
float z;
float intensity;
int16_t ring;
}
点云的格式 Points.lcm:
package PointType;
struct Points
{
int64_t timestamp;
int32_t num_points;
PointXYZIR pointxyzir[num_points];
}
分别运行 lcm-gen -x PointXYZIR.lcm 与 lcm-gen -x Points.lcm生成代码。
3、消息收发
发送:
//pub.cpp
#include <lcm/lcm-cpp.hpp> #include "exlcm/Example.hpp" #include <iostream> int main(int argc, char** argv) { lcm::LCM lcm; if(!lcm.good()) return 1; exlcm::Example my_data; my_data.a=5; my_data.b=6.0; lcm.publish("EXAMPLE", &my_data); std::cout << "lgj" << std::endl; return 0; }
接收:
//sub.cpp
#include <iostream> #include <lcm/lcm-cpp.hpp> #include "exlcm/Example.hpp" class Handler { public: Handler() {} void handleMessage(const lcm::ReceiveBuffer* rbuf, const std::string& chan, const exlcm::Example* msg) { std::cout << msg->a << " " << msg->b << std::endl; } }; int main(int argc, char** argv) { lcm::LCM lcm; if(!lcm.good()) return 1; Handler handlerObject; lcm.subscribe("EXAMPLE", &Handler::handleMessage, &handlerObject); while(0==lcm.handle()); return 0; }
// CMakeLists.txt
cmake_minimum_required(VERSION 3.5.1)
project(lcm_test) set(CMAKE_CXX_STANDARD 11) add_executable(pub_test pub.cpp) target_link_libraries(pub_test lcm) add_executable(sub_test sub.cpp) target_link_libraries(sub_test lcm)
编译生成代码后,先执行sub_test,然后在每次执行pub_test后,sub_test的终端窗口将打印收到的“5 6”.
但用LCM延迟较大,不能传输太大的数据量。这里有篇论文里介绍了LCM和ROS的对比。
《基于共享内存的智能无人车进程间消息异步传输机制》:
http://www.jos.org.cn/jos/ch/reader/create_pdf.aspx?file_no=5144&year_id=2017&quarter_id=5&falg=1
基本使用就是这样子了。进一步了解可参考官网和相关博客。
https://lcm-proj.github.io/index.html