ROS多机通信功能包——Multibotnet

引言

这是之前看到一位大佬做的集群通信中间件,突发奇想,自己也来做一个,实现更多的功能、更清楚的架构和性能更加高效的ROS多机通信的功能包
链接:https://blog.csdn.net/benchuspx/article/details/128576723

Multibotnet

Multibotnet 是一个专为多机器人系统设计的 ROS 包,利用 ZeroMQ 技术实现高效的分布式通信。简单来说,它能让多台机器人或电脑之间轻松共享 ROS 话题和服务,哪怕它们不在同一个网络环境下也能协作工作。无论是机器人团队协同任务,还是跨设备的数据共享,Multibotnet 都能派上用场!

  • 项目地址:github 仓库——Multibotnet

主要功能

话题共享

  • 发送话题:把本地的 ROS 话题通过网络发出去,其他机器人就能收到。
  • 接收话题:从网络上抓取其他机器人发来的话题,融入本地 ROS 系统。

服务管理

  • 提供服务:让你的机器人通过网络为别人提供 ROS 服务,比如远程开关控制。
  • 请求服务:调用其他机器人提供的服务,实现跨设备的功能交互。

支持的消息类型

支持常见的 ROS 消息类型,包括但不限于:

  • sensor_msgs/Imu(IMU 数据)
  • geometry_msgs/Twist(速度指令)
  • std_msgs/String(字符串)
  • nav_msgs/Odometry(里程计)
  • sensor_msgs/LaserScan(激光雷达)
  • sensor_msgs/Image(图像)
  • geometry_msgs/Pose(位姿)
  • geometry_msgs/Point(点坐标)
  • std_msgs/Float32(浮点数)
  • std_msgs/Int32(整数)
  • geometry_msgs/PoseStamped(带时间戳的位姿)
  • sensor_msgs/PointCloud2(点云)
  • geometry_msgs/Vector3(三维向量)
  • 自定义类型(稍作修改就能支持,超灵活!)

支持的服务类型

  • std_srvs/SetBool(布尔开关服务)
  • nav_msgs/GetPlan(路径规划服务)
  • 自定义服务(同样支持扩展)

项目优势

  • 简单配置,一键搞定
    通过一个 YAML 文件就能设置话题、服务、IP 和端口,想改啥改啥,完全不用碰代码。

  • 通信超快,效率爆表
    用 ZeroMQ 技术,支持多对多通信,哪怕是大规模机器人集群也能hold住。

  • 频率可控,不怕卡顿
    发送话题时可以限制频率,避免网络堵塞,带宽利用率刚刚好。

  • 扩展方便,随心所欲
    想加新的消息或服务类型?改几行代码就行,完美适配你的项目需求。

  • 跨平台无压力
    不管是机器人还是普通电脑,只要有 ROS 环境,就能跑起来,分布式系统so easy!

效果部分展示

在这里插入图片描述

安装步骤

准备工作

需要先装好以下依赖:

  • ZeroMQ:网络通信核心
  • yaml-cpp:解析配置文件用
  • ROS:确保你的 ROS 环境已经配置好

安装命令

  1. 安装依赖:

    sudo apt-get install libzmq3-dev libyaml-cpp-dev
    
  2. 克隆项目到你的 catkin 工作空间:

    cd ~/catkin_ws/src
    git clone https://github.com/nanwanuser/multibotnet.git
    
  3. 编译项目:

    cd ~/catkin_ws
    catkin_make
    

使用方法

  1. 配置一下
    打开 config/default.yaml 文件,填入你想要共享的话题和服务信息,比如 IP 地址、端口号等。

  2. 启动程序
    一行命令搞定:

    roslaunch multibotnet multibotnet.launch
    

配置说明

config/default.yaml 是你的“控制中心”,里面有这些关键项:

  • IP:给 IP 地址起个别名,比如 self: ‘*’ 表示本机所有 IP。
  • send_topics:设置要发出去的话题(话题名、类型、频率、地址、端口)。
  • recv_topics:设置要接收的话题(话题名、类型、地址、端口)。
  • provide_services:定义你要提供的服务(服务名、类型、地址、端口)。
  • request_services:定义你要调用的远程服务(服务名、类型、地址、端口)。

具体格式可以参考默认文件,照着改就行!

如何扩展自定义类型

想用自己的消息或服务类型?很简单,按以下步骤操作:

添加自定义消息类型

  1. 引入头文件
    在 include/multibotnet/ros_sub_pub.hpp 中加一行:

    #include <your_package/YourMessage.h>
    
  2. 映射类型
    在 getMsgType 函数中添加:

    if (type == "your_package/YourMessage") return "your_package::YourMessage";
    
  3. 发送逻辑
    在 src/zmq_manager.cpp 的 sendTopic 函数中加一段:

    else if (message_type == "your_package/YourMessage") {sub = nh.subscribe<your_package::YourMessage>(topic, 1, [this, &current_socket, index, topic](const your_package::YourMessage::ConstPtr& msg) {if (send_freq_control(index)) {auto buffer = serializeMsg(*msg);zmq::message_t zmq_msg(buffer.size());memcpy(zmq_msg.data(), buffer.data(), buffer.size());if (!current_socket.send(zmq_msg, zmq::send_flags::none)) {ROS_ERROR("Failed to send message on topic %s", topic.c_str());}}});
    }
    
  4. 接收逻辑
    在 src/zmq_manager.cpp 的 recvTopic 函数中,首先为新消息类型创建发布者:

    else if (message_type == "your_package/YourMessage") {pub = nh.advertise<your_package::YourMessage>(topic, 1);
    }
    

    然后,在接收线程中反序列化并发布:

    else if (message_type == "your_package/YourMessage") {your_package::YourMessage msg = deserializeMsg<your_package::YourMessage>(static_cast<uint8_t*>(zmq_msg.data()), zmq_msg.size());pub.publish(msg);
    }
    
  5. 更新依赖
    在 package.xml 中添加:

    <depend>your_package</depend>
    
  6. 重新编译

    catkin_make
    

添加自定义服务类型

  1. 引入头文件
    在 include/multibotnet/ros_sub_pub.hpp 中添加对你的服务类型头文件的引用,以便编译器识别该类型:

    #include <your_package/YourService.h>
    
  2. 在 ServiceManager 中支持新服务类型
    在 src/service_manager.cpp 的 createHandler 函数中,为你的服务类型添加一个条件分支,创建对应的 SpecificServiceHandler:

    else if (service_type == "your_package/YourService") {return std::make_shared<SpecificServiceHandler<your_package::YourService>>(service_name);
    }
    

    这步是核心,ServiceManager 通过 createHandler 为提供的服务创建处理程序,绑定到 REP 套接字。
    SpecificServiceHandler 会自动调用本地 ROS 服务并处理序列化/反序列化。

  3. 更新模板实例化(可选)
    如果你需要在代码中通过 callService 调用该服务,需要在 src/service_manager.cpp 文件末尾添加模板实例化:

    template bool ServiceManager::callService<your_package/YourService>(const std::string&, your_package/YourService::Request&, your_package/YourService::Response&);
    

    如果你只提供服务(provide_services),这步可以跳过;但如果涉及请求服务(request_services),则必须添加。

  4. 更新依赖
    在 package.xml 中添加对你服务包的依赖,确保项目能找到服务定义:

    <depend>your_package</depend>
    
  5. 重新编译
    在工作空间根目录下运行以下命令以应用更改:

    catkin_make
    
  6. 配置 YAML 文件
    在 config/default.yaml 中添加你的服务配置,例如:

    提供服务:

    provide_services:
    - service_name: /your_serviceservice_type: your_package/YourServicebind_address: selfport: 5560
    

    请求服务:

    request_services:
    - service_name: /remote_your_serviceservice_type: your_package/YourServiceconnect_address: robot1port: 5560
    

应用示例

场景描述

  • Robot1(IP: 192.168.1.101):发送 /imu 话题,提供 /set_bool 服务。
  • Robot2(IP: 192.168.1.102):接收 /imu 话题(显示为 /imu_recv),调用 /set_bool 服务。

Robot1 配置

IP:self: '*'robot2: 192.168.1.102send_topics:
- topic: /imumessage_type: sensor_msgs/Imumax_frequency: 50bind_address: selfport: 3001provide_services:
- service_name: /set_boolservice_type: std_srvs/SetBoolbind_address: selfport: 5555

Robot2 配置

IP:self: '*'robot1: 192.168.1.101recv_topics:
- topic: /imu_recvmessage_type: sensor_msgs/Imuconnect_address: robot1port: 3001request_services:
- service_name: /set_boolservice_type: std_srvs/SetBoolconnect_address: robot1port: 5555

启动两台机器上的 Multibotnet 后,Robot2 就能收到 Robot1 的 IMU 数据,并远程控制它的开关服务。

总结

Multibotnet 是一个简单又强大的工具,能让多机器人系统高效协作。无论是话题共享还是服务调用,它都能通过灵活的配置和高性能通信满足你的需求。快来试试吧,让你的机器人团队更聪明、更协同!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/74220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++:背包问题习题

1. 货币系统 1371. 货币系统 - AcWing题库 给定 V 种货币&#xff08;单位&#xff1a;元&#xff09;&#xff0c;每种货币使用的次数不限。 不同种类的货币&#xff0c;面值可能是相同的。 现在&#xff0c;要你用这 V 种货币凑出 N 元钱&#xff0c;请问共有多少种不同的…

IT工具 | node.js 进程管理工具 PM2 大升级!支持 Bun.js

P(rocess)M(anager)2 是一个 node.js 下的进程管理器&#xff0c;内置负载均衡&#xff0c;支持应用自动重启&#xff0c;常用于生产环境运行 node.js 应用&#xff0c;非常好用&#x1f44d; &#x1f33c;概述 2025-03-15日&#xff0c;PM2发布最新版本v6.0.5&#xff0c;这…

2025年01月02日浙江鼎永前端面试

目录 webpack 和 vite 区别react fiber 架构vue diff 算法react diff 算法hooks 源码垂直水平布局项目介绍单点登录大文件上传微前端 1. webpack 和 vite 区别 Webpack 和 Vite 是两种不同的前端构建工具&#xff0c;它们在设计理念、性能表现和使用场景上存在显著差异。以下…

1.企业级AD活动目录核心解析:架构、组件与集成实践

在当今数字化时代&#xff0c;企业级网络环境日益复杂&#xff0c;高效、安全的资源管理和用户认证成为企业 IT 运营的关键。AD&#xff08;Active Directory&#xff09;活动目录作为微软 Windows 系列服务器中的重要目录服务&#xff0c;为企业级网络管理提供了强大的解决方案…

【数据分享】2014-2024年我国各城市逐年空气质量指数(AQI)数据

空气质量指数&#xff08;AQI&#xff09;是一个衡量空气污染程度的综合指标&#xff0c;它并不直接表示具体污染物的浓度值&#xff0c;而是基于多种污染物的浓度进行的综合评价&#xff0c;具体基于六种主要污染物的浓度&#xff1a;PM2.5、PM10、SO₂、NO₂、O₃和CO。AQI是…

【C++】深入理解list迭代器的设计与实现

深入理解list迭代器的设计与实现 引言1、链表基础结构2、链表迭代器的封装2.1 初步封装迭代器类2.2 引入const迭代器2.2.1 参考STL源代码2.2.2 完善迭代器 3、迭代器实现机制结语 引言 在STL容器中&#xff0c;list作为经典的双向链表容器&#xff0c;其迭代器设计体现了C模板编…

C语言基础系列【27】typedef

博主介绍&#xff1a;程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章&#xff0c;首发gzh&#xff0c;见文末&#x1f447;&#x1f…

【CXX-Qt】2.5 继承

某些 Qt API 要求你从抽象基类中重写某些方法&#xff0c;例如 QAbstractItemModel。 为了支持直接从 Rust 中创建这样的子类&#xff0c;CXX-Qt 提供了多种辅助工具。 某些基类可能需要特殊的构造参数。这可以通过使用自定义构造函数来实现。 访问基类方法 要在 Rust 中访…

磁盘清理工具-TreeSize Free介绍

TreeSizeFree是一个磁盘空间管理工具&#xff0c;主要用于分析磁盘使用情况&#xff0c;帮助用户找到占用空间大的文件和文件夹: 特点&#xff1a;按大小排序&#xff1a;快速找到占用空间最大的文件或文件夹 一般可以删除: 扫描 C:\Users\XXX\AppData\Local\Temp 或 C:\Window…

OpenCV中距离公式

一、各类距离公式总结 常见距离公式 欧氏距离&#xff1a; 曼哈顿距离&#xff08;L1&#xff09;‌&#xff1a; 切比雪夫距离&#xff08;Chessboard&#xff09;‌&#xff1a; 1、点与点距离(欧氏距离) ‌二维空间‌ 设两点坐标为 P1(x1,y1)、P2(x2,y2)&#xff0c;其距离…

Vue.js 模板语法全解析:从基础到实战应用

引言 在 Vue.js 的开发体系中&#xff0c;模板语法是构建用户界面的核心要素&#xff0c;它让开发者能够高效地将数据与 DOM 进行绑定&#xff0c;实现动态交互效果。通过对《Vue.js 快速入门实战》中关于 Vue 项目部署章节&#xff08;实际围绕 Vue 模板语法展开&#xff09;…

论文笔记(七十三)Gemini Robotics: Bringing AI into the Physical World

Gemini Robotics: Bringing AI into the Physical World 文章概括1. 引言2. Gemini 2.0的具身推理2.1. 具身推理问答&#xff08;ERQA&#xff09;基准测试2.2. Gemini 2.0的具身推理能力2.3. Gemini 2.0支持零样本和少样本机器人控制 3. 使用 Gemini Robotics 执行机器人动作3…

centos7搭建postgresql12主从

主从搭建 192.168.159.101 node1 主库&#xff08;读写&#xff09; 192.168.159.102 node2 备库&#xff08;只读&#xff09; 两台机器首先安装postgrsql 主库 postgres用户操作&#xff1a; 修改postgresql.conf # 在文件中修改(此配置仅用于远程访问, 流复制后续还有额外…

嵌入式基础知识学习:SPI通信协议是什么?

SPI&#xff08;Serial Peripheral Interface&#xff09;是串行外设接口的缩写&#xff0c;是一种广泛应用于嵌入式系统的高速同步串行通信协议&#xff0c;由摩托罗拉公司于20世纪80年代提出。以下是其核心要点&#xff1a; 一、SPI的核心定义与特点 基本特性 全双工同步通信…

996引擎-接口测试:背包

996引擎-接口测试:背包 背包测试NPC参考资料背包测试NPC CONSTANT = require("Envir/QuestDiary/constant/CONSTANT.lua"); MsgUtil = require("Envir/QuestDiary/utils/996/MsgUtil.lua");

vulnhub靶场之【hack-me-please靶机】

前言 靶机&#xff1a;billu_b0x2靶机&#xff0c;IP地址为192.168.10.8 攻击&#xff1a;kali&#xff0c;IP地址为192.168.10.6 靶机和攻击机都采用VMware虚拟机&#xff0c;都采用桥接网卡模式 文章涉及的靶机及工具&#xff0c;都可以自行访问官网或者项目地址进行获取&…

机器学习——KNN模型评价

一、主要函数 sklearn.metrics.accuracy_score() 是 scikit-learn 中用于计算分类模型准确率的函数&#xff0c;适用于评估分类任务的整体性能。 1、核心功能 作用&#xff1a;计算模型预测的准确率&#xff0c;即正确分类的样本数占总样本数的比例。公式&#xff1a;Accurac…

美国国家数据浮标中心(NDBC)

No.大剑师精品GIS教程推荐0地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】 1Openlayers 【入门教程】 - 【源代码示例 300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3MapboxGL【入门教程】 - 【源代码图文示例150】 4Cesium 【入门教程】…

Qt调用Miniconda的python方法

1、 Win 64环境下载及安装 Miniconda 首先下载Windows 版Miniconda&#xff0c;https://docs.conda.io/en/latest/miniconda.html或 https://repo.anaconda.com/miniconda/ 安装界面及选择如下图所示&#xff1a; 安装完python3.12版报错如下。 说明&#xff1a;python3.11版…

Unity 与 JavaScript 的通信交互:实现跨平台的双向通信

前言 在现代游戏开发和 Web 应用中&#xff0c;Unity 和 JavaScript 的结合越来越常见。Unity 是一个强大的跨平台游戏引擎&#xff0c;而 JavaScript 是 Web 开发的核心技术之一。通过 Unity 和 JavaScript 的通信交互&#xff0c;开发者可以实现从 Unity 到 Web 页面的功能扩…