背景
自动驾驶领域有很多进程间通信的方式,如ROS、Apollo的Cyber RT… 以及一些自动驾驶初创公司对ROS进行改进的通信协议,今天介绍一种适用于高速自动驾驶场景的LCM通信协议,其特点是轻量化、传输速度快,易封装。
LCM(Lightweight Communications and Marshalling)是一组用于消息传递和数据编组的库和工具,其基于UDP传输的属性,传输速度较快,其目标是高带宽和低延迟的实时系统。它提供了一种发布/订阅消息传递模型以及带有各种编程语言C++、Java、python等应用程序绑定的自动编组/解组代码生成,LCM通过将消息封装在不同的Channel中进行通信,这点类似于ROS中的Topic。
参考LCM官方文档:https://github.com/lcm-proj/lcm
安装环境:
Ubuntu16.04;
lcm-1.3.1;
下载地址:https://github.com/lcm-proj/lcm/releases
安装
在Downloads目录下找到刚才下载的lcm-1.3.1.zip压缩包,解压
$ unzip lcm-1.3.1.zip
安装依赖
$ sudo apt-get install build-essential autoconf automake autopoint libglib2.0-dev libtool openjdk-8-jdk python-dev
我习惯在/home下安装,将刚才解压后的文件夹lcm-1.3.1移动到/home下开始安装
$ cd lcm-1.3.1
$ ./configure
$ make
$ sudo make install
为lcm创建一个ld.so.conf文件
$ export LCM_INSTALL_DIR=/usr/local/lib
$ sudo sh -c "echo $LCM_INSTALL_DIR > /etc/ld.so.conf.d/lcm.conf"
$ sudo ldconfig
配置pkgconfig
$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$LCM_INSTALL_DIR/pkgconfig
安装python扩展包
$ cd lcm-python
$ sudo python setup.py install
到这里LCM安装完成,介绍几个常用命令:
lcm-logger //记录log
lcm-spy //查看当前数据
lcm-logplayer, lcm-logplayer-gui //log回放
使用教程(C++)
lcm数据类型定义
lcm类型定义与编程语言无关,/home下新建文件夹lcm_example用于存放工程,进入lcm_example文件夹,新建example_t.lcm空白文档,写入以下内容
package exlcm;
struct example_t
{
int64_t timestamp;
double position[3];
double orientation[4];
int32_t num_ranges;
int16_t ranges[num_ranges];
string name;
boolean enabled;
}
打开终端,执行命令
$ lcm-gen -x example_t.lcm
如何你使用其他语言,lcm-gen -h 获取帮助,运行之后生成一个文件夹exlcm,并包含一个文件example_t.hpp,到这里lcm结构体定义完成。
发送消息
在lcm_example目录下,新建send_message.cpp复制以下内容
// file: send_message.cpp
//
// LCM example program.
//
// compile with:
// $ g++ -o send_message send_message.cpp -llcm
//
// On a system with pkg-config, you can also use:
// $ g++ -o send_message send_message.cpp `pkg-config --cflags --libs lcm`
#include <lcm/lcm-cpp.hpp>
#include "exlcm/example_t.hpp"
int main(int argc, char ** argv)
{
lcm::LCM lcm;
if(!lcm.good())
return 1;
exlcm::example_t my_data;
my_data.timestamp = 0;
my_data.position[0] = 1;
my_data.position[1] = 2;
my_data.position[2] = 3;
my_data