[学习LCM]lcm教程与实例(C++ API)
背景
Ubuntu 16.04
C++ API
lcm 1.30
1. 安装
版本: 1.3.0, 下载
安装 autoconf :
$ sudo apt-get install autoconf
解压, 编译, 在LCM目录下执行:
$ autoreconf -i
$ ./configure
$ make -j8 -l8
$ sudo make install
安装位置:/usr/local/:
在/usr/local/bin目录下安装lcm-gen, lcm-logger, lcm-logplayer, lcm-logplayer-gui, lcm-spy可执行程序
在/usr/local/lib目录下安装liblcm.la, liblcm.so, liblcm.so.1, liblcm.so.1.3.3库文件
在/usr/local/include目录下安装eventlog.h, lcm_coretypes.h, lcm-cpp.hpp, lcm-cpp-impl.hpp, lcm.h头文件配置头文件, 在home/igs/.profile中添加以下内容后, 重启:
#glib c++
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/glib-2.0:/usr/lib/x86_64-linux-gnu/glib-2.0/include
#lcm
#export CLASSPATH=.:$CLASSPATH:/program/3rd/lcm/lcm-1.2.1/lcm-java/build/lcm
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
#glib c
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/glib-2.0:/usr/lib/x86_64-linux-gnu/glib-2.0/include
2. 介绍
LCM(Lightweight Communications and Marshalling)是一套用于消息传递和数据编组的库和工具,针对高带宽和低延迟至关重要的实时系统。 它提供了一个发布/订阅消息传递模型和自动编组/解组代码生成,并为各种编程语言的应用程序提供绑定。
- 网站
- Github
- LCM Overview
- Technical Report
C++ API 提供了三个类两个结构体封装LCM:
class lcm::LCM
struct lcm::ReceiveBuffer
class lcm::Subscription
struct lcm::LogEvent
class lcm::LogFile
3. 教程
该教程介绍了如何使用C++ API交换LCM信息(LCM 提供了多种语言的API, 这里只以C++ 为例). 教程包含以下几部分:
3.1 创建类型定义(type definition)
由于类型定义与编程语言类型无关,故第一步对所有编程语言都一样; 类型规则的定义与C语言非常像, 下面是一个名为example_t的示例类型, 创建一个名为 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;
}
更多类型规范,下表是基本类型规范:
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
除此之外还可以定义数组;
生成特定编程语言的绑定(bindings):
lcm-gen -x example_t.lcm
如果你用的不是C++, 运行lcm-gen -h 获取命令行帮助;
运行之后,会在当前文件夹生成一个exlcm/example_t.hpp 的文件, 它包含了之前定义类型的同名类:
class example_t
{public:int64_t timestamp;double position[3];double orientation[4];int32_t num_ranges;std::vector< int16_t > ranges;std::string name;int8_t enabled;
3.2 初始化LCM
任何使用LCM的应用程序第一步就是初始化LCM库, 下面是一个例子:
#include <lcm/lcm-cpp.hpp>int main(int argc, char ** argv)
{lcm::LCM lcm;if(!lcm.good())return 1;// Your application goes herereturn 0;
}
3.3 发布(publish)一个消息
// send_message.cpp
#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.orientation[0] = 1;my_data.orientation[1] = 0;my_data.orientation[2] = 0;my_data.orientation[3] = 0;my_data.num_ranges = 15;my_data.ranges.resize(my_data.num_ranges);for (int i = 0; i < my_data.num_ranges; i++)my_data.ranges[i] = i;my_data.name = "example string";my_data.enabled = true;lcm.publish("EXAMPLE", &my_data);return 0;
}
lcm::LCM::publish() 会将数据序列化为字节流,并使用LCM将数据包传输到任何感兴趣的接收者, 字符串 EXAMPLE 是频道名称, 是随每个数据包一起发送的字符串.
3.4 订阅和接收(subscribe and receive)一个消息
下面是一个接收 EXAMPLE 的例子:
// listener.cpp
#include <stdio.h>#include <lcm/lcm-cpp.hpp>
#include "exlcm/example_t.hpp"class Handler {public:~Handler() {}void handleMessage(const lcm::ReceiveBuffer *rbuf, const std::string &chan,const exlcm::example_t *msg){int i;printf("Received message on channel \"%s\":\n", chan.c_str());printf(" timestamp = %lld\n", (long long) msg->timestamp);printf(" position = (%f, %f, %f)\n", msg->position[0], msg->position[1],msg->position[2]);printf(" orientation = (%f, %f, %f, %f)\n", msg->orientation[0], msg->orientation[1],msg->orientation[2], msg->orientation[3]);printf(" ranges:");for (i = 0; i < msg->num_ranges; i++)printf(" %d", msg->ranges[i]);printf("\n");printf(" name = '%s'\n", msg->name.c_str());printf(" enabled = %d\n", msg->enabled);}
};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()) {// Do nothing}return 0;
}
3.5 运行
文件夹结构如下:
example_t.lcm
listener.cpp
Makefile
read_log.cpp
send_message.cpp
将 Makefile 28 行修改为 lcm-gen -x *.lcm;
在当前文件夹运行 make, 会出现三个可执行文件:listener, read_log, send_message;
运行 ./listener 再开一个窗口运行 ./send_message 可以看到 listener 窗口接收到信息:
Received message on channel "EXAMPLE":timestamp = 0position = (1.000000, 2.000000, 3.000000)orientation = (1.000000, 0.000000, 0.000000, 0.000000)ranges: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14name = 'example string'enabled = 1
以上文件可以在这里下载.
其他文章:
lcm实例(Python API)
lcm安装c++和python版本,不同编程语言之间相互通信
[学习LCM]lcm教程与实例(C++ API)相关推荐
- python菜鸟教程100实例-运维人员学习python菜鸟教程
这篇文章主要为大家详细介绍了运维人员学习python菜鸟教程,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! 从不会写代 ...
- C#基础教程-c#实例教程,适合初学者
C#基础教程-c#实例教程,适合初学者. 第一章 C#语言基础 本章介绍C#语言的基础知识,希望具有C语言的读者能够基本掌握C#语言,并以此为基础,能够进一步学习用C#语言编写window应用程序和W ...
- 30本pdf完整版的经典Linux学习和开发教程和资料下载 android arm java 资料大全
史上最牛的Linux内核学习方法论 点击下载 我的arm_linux移植笔记 点击下载 S3C2440完全开发流程 点击下载 Linux系统命令及其使用详解完整版 点击下载 Linux ...
- 30本pdf完整版的经典Linux学习和开发教程和资料下载 android arm java 资料大全...
史上最牛的Linux内核学习方法论 点击下载 我的arm_linux移植笔记 点击下载 S3C2440完全开发流程 点击下载 Linux系统命令及其使用详解完整版 点击下载 Linux主要shell命 ...
- 【libuv高效编程】libuv学习超详细教程3——libuv事件循环
文章目录 libuv系列文章 libuv事件循环 uv_loop_t demo uv_loop_init() uv_run() uv_loop_close() 参考 例程代码获取 libuv系列文章 ...
- 【特别推荐】Node.js 中文学习资料和教程导航
这篇文章来自 Github 上的一位开发者收集整理的 Node.js 中文学习资料和教程导航.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念,它的目标是帮助程 ...
- Java菜鸟到大牛学习路线培训教程
这是一套Java菜鸟到大牛学习路线培训教程,由工作了10年的资深Java架构师整理.主要分5个阶段:Java程序员->Java初级软件工程师->Java中级软件工程师->Java高级 ...
- 好程序员web前端教程分享JavaScript验证API
好程序员web前端教程分享JavaScript验证API,小编每天会分享一下干货给大家.那么今天说道的就是web前端培训课程中的章节. JavaScript验证API 约束验证DOM方法 Proper ...
- 【Go API 开发实战 1】该教程所实现的 API 功能
本教程所实现的 API 功能 本教程通过实现一个账号系统,来演示如何构建一个真实的 API 服务器,构建方法和技术是我根据之前的服务器开发经验不断优化沉淀而成.通过实战展示了 API 构建过程中各个流 ...
最新文章
- 《基于单幅图像的快速去雾》原理与C++复现(有一定工程意义)
- 《HTTP权威指南》– 8.网关、机器人
- silverlight后台加载本地图片
- struts2 简单应用
- vs如何设置对话框显示在最前面_“打开”对话框的使用
- mysql 排序 删除_是否可以删除mysql表排序规则?
- js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( )) 有区别?
- 在要求输入数字处找到非数字字符_剑指 Offer 67. 把字符串转换成整数 leetcode 剑指offer系列...
- Maven公共仓库/镜像站收集及使用技巧
- Java是如何实现跨平台运行的
- “再见,Linux!”
- 内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
- python随机森林库_随机森林库:R和Python中的不同结果
- vim编辑器的简单使用
- OSGI.NET,请求因HTTP状态404 失败:Not Found
- 易观数科代码埋点、全埋点、可视化埋点
- 系统架构师笔记——数据库
- 计算机主板与检测,主板知识详解:CPU自动检测和硬件错误的侦测
- 欧盟共同语言标准c1,阅读|【Reading Explorer】(pdf可下载)
- 链路层链路发现协议(LLDP)讲解