当前位置: 首页 > news >正文

lcm通信库介绍与使用指南

1. LCM 简介

LCM 全称是 Lightweight Communications and Marshalling,它是一个为 机器人系统、多进程通信 等场景设计的 高效消息传输与数据打包框架
它最早由麻省理工学院(MIT)为 DARPA Urban Challenge 项目开发,用于在多个进程、多个计算机之间进行低延迟的消息传输和类型安全的数据序列化。

主要特点:

  • 轻量级:只提供核心的通信和序列化功能,没有太多依赖。
  • 跨语言、跨平台:支持 C、C++、Java、Python、Lua、MATLAB 等。
  • 类型安全:消息格式通过专用的 .lcm 描述文件定义,并自动生成对应编程语言的代码。
  • 低延迟:采用 UDP 多播(也可以配置 TCP/Unicast)。
  • 支持多进程和多机通信

2. LCM 架构概述

LCM 由几部分组成:

  1. 消息类型定义

    • 用户通过 .lcm 文件定义消息类型(类似于IDL/ProtoBuf)
    • 编译后自动生成各语言的类/结构体,以及序列化/反序列化代码。
  2. 订阅-发布模型(pub/sub)

    • Publisher:发布者,把消息编码后发送到特定的信道(channel)。
    • Subscriber:订阅者,监听某个信道收到消息时触发回调处理函数。
    • 信道是按名字划分的(字符串),比如 "EXAMPLE"
  3. 传输层

    • 默认使用 UDP multicast (避免单独的Broker,分布式无中心结构)。
    • 也可以使用 TCP 单播(需要手动配置)。

3. 安装 LCM

Ubuntu/Debian

sudo apt-get update
sudo apt-get install liblcm-dev lcm

但是我的lcm其实是源码安装的,我是ubuntu20.04,还需要根据README.md回退到一个支持的commit,然后编译安装才行

macOS (brew)

brew install lcm

Python

pip install lcm

(需要先系统安装核心库)


4. 定义消息类型

LCM 的消息描述文件用 .lcm 扩展名,例如 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;
}

解释:

  • package 指定包名(对应代码生成的命名空间/模块)
  • struct 定义消息结构
  • 支持基础类型 (int8_t, int16_t, int32_t, int64_t, float, double, string, boolean) 以及数组(定长/变长)
  • 变长数组需前面有一个字段表示长度

5. 生成代码

假设你想用 Python 和 C++:

lcm-gen -p example_t.lcm    # 生成 Python 代码
lcm-gen -x example_t.lcm    # 生成 C++ 代码

生成后会在对应目录下出现:

  • Python: exlcm/example_t.py
  • C++: exlcm/example_t.hpp

6. Python 使用示例

发布端 publish.py

import lcm
from exlcm import example_t
import timelc = lcm.LCM()
msg = example_t()msg.timestamp = int(time.time() * 1e6)
msg.position = [1.0, 2.0, 3.5]
msg.orientation = [0, 0, 0, 1]
msg.num_ranges = 3
msg.ranges = [100, 200, 300]
msg.name = "Hello LCM"
msg.enabled = Truelc.publish("EXAMPLE", msg.encode())

订阅端 subscribe.py

import lcm
from exlcm import example_tdef my_handler(channel, data):msg = example_t.decode(data)print("Received message on channel \"%s\"" % channel)print("   timestamp   = %s" % msg.timestamp)print("   position    = %s" % list(msg.position))print("   orientation = %s" % list(msg.orientation))print("   ranges: %s" % list(msg.ranges))print("   name        = %s" % msg.name)print("   enabled     = %s" % msg.enabled)lc = lcm.LCM()
subscription = lc.subscribe("EXAMPLE", my_handler)try:while True:lc.handle()
except KeyboardInterrupt:pass

运行:

  1. 启动订阅端
    python subscribe.py
    
  2. 发布一条消息
    python publish.py
    

7. C++ 使用示例

publisher.cpp

#include <lcm/lcm-cpp.hpp>
#include "exlcm/example_t.hpp"
#include <iostream>
#include <ctime>int main()
{lcm::LCM lcm;if(!lcm.good())return 1;exlcm::example_t msg;msg.timestamp = static_cast<int64_t>(time(NULL) * 1000000);msg.position[0] = 1.0;msg.position[1] = 2.0;msg.position[2] = 3.5;msg.orientation[0] = 0;msg.orientation[1] = 0;msg.orientation[2] = 0;msg.orientation[3] = 1;msg.num_ranges = 3;msg.ranges.resize(3);msg.ranges[0] = 100;msg.ranges[1] = 200;msg.ranges[2] = 300;msg.name = "Hello LCM";msg.enabled = true;lcm.publish("EXAMPLE", &msg);return 0;
}

subscriber.cpp

#include <lcm/lcm-cpp.hpp>
#include "exlcm/example_t.hpp"
#include <iostream>class Handler
{
public:void handleMessage(const lcm::ReceiveBuffer* rbuf,const std::string& chan,const exlcm::example_t* msg){std::cout << "Received message on channel " << chan << std::endl;std::cout << "  timestamp   = " << msg->timestamp << std::endl;}
};int main()
{lcm::LCM lcm;if(!lcm.good())return 1;Handler handler;lcm.subscribe("EXAMPLE", &Handler::handleMessage, &handler);while(0 == lcm.handle());return 0;
}

编译链接需要 -llcm


8. 调试工具

LCM 提供了很多可视化工具(基于 Java Swing):

  • lcm-spy:查看当前网络中传输的消息
    lcm-spy
    
  • lcm-logplayer:回放记录文件
  • lcm-logger:记录通信到日志文件

9. 环境变量与配置

常用环境变量:

  • LCM_DEFAULT_URL:设定默认通信URL,格式:
    • UDP 多播:udpm://239.255.76.67:7667?ttl=1
    • TCP:tcpq://<host>:<port>
  • 更改多播组 IP 与端口可避免冲突。

10. 使用注意事项

  • UDP 多播可能受交换机路由限制,在不同网络段要确保多播可达。
  • 大消息最好分片或使用 TCP 传输模式。
  • Python 下,lc.handle() 会阻塞等待一个消息,可以用 lc.handle_timeout(ms) 实现超时。
  • 订阅和发布的数据类型必须匹配,否则解码会失败。

如果你愿意的话,我可以帮你再画一张 LCM 工作流程图,帮助你更直观地理解它的运行过程。
要我画吗?

http://www.xdnf.cn/news/1304065.html

相关文章:

  • 使用Docker容器化Python测试Pytest项目并配置GitHub Actions CI/CD流程
  • Pytest项目_day16(yaml和parametrize结合)
  • week1-[循环嵌套]蛇
  • Vue2与Vue3生命周期函数全面解析:从入门到精通
  • Linux操作系统--多线程(锁、线程同步)
  • 基本电子元件:贴片电阻器的种类
  • 达梦数据库使用控制台disql执行脚本
  • Mac(二)Homebrew 的安装和使用
  • HDFS数据倾斜导致MapReduce作业失败的排查与优化实践
  • 一个集成多源威胁情报的聚合平台,提供实时威胁情报查询和播报服务、主动拦截威胁IP,集成AI等多项常用安全类工具
  • mac 通过homebrew 安装和使用nvm
  • 16进制pcm数据转py波形脚本
  • 超越模型中心:AI智能体(Agent)革命来临,AgenticOps将如何颠覆你的工作流?
  • Java-JVM是什么JVM的类加载机制
  • PAT 1064 Complete Binary Search Tree
  • 计算机网络:(十五)TCP拥塞控制与TCP拥塞控制算法
  • 【161页PPT】智慧方案企业数字化转型概述(课件)(附下载方式)
  • AutoSar AP平台功能组并行运行原理
  • [论文阅读] 人工智能 | 当Hugging Face遇上GitHub:预训练语言模型的跨平台同步难题与解决方案
  • JVM执行引擎深入理解
  • 剧本杀小程序系统开发:重构推理娱乐生态
  • 大模型幻觉涉及的违约责任探讨
  • 回路自感和回路互感
  • 补充日志之-配置文件解析指南(Centos7)
  • 德州扑克游戏术语
  • 银河麒麟服务器jar包部署自启动配置
  • 第十八讲:哈希2
  • 神经网络 小土堆pytorch记录
  • 开疆智能Ethernet转ModbusTCP网关连接测联无纸记录仪配置案例
  • 《探秘浏览器Web Bluetooth API设备发现流程》