ROS中rosserial通讯协议初探

2023-05-16


ROS中rosserial通讯协议初探

串行的通讯,我们用串口模拟下通讯图

 

官方

http://wiki.ros.org/rosserial
rosserial
 

1概述


标准ROS序列化message的协议,可以让一个字符设备(单片机)通过串口或者网口就能实现多topics和services的功能。
1.1客户端库很多
1.2ROS端可以python也可以c++
1.3举例


2限制

2.1Message 最大size ,发布和订阅数量
AVR Model | Input/Output buffer sizes | Publishers/Subscribers

ATMEGA168 | 150/150 bytes | 6/6
ATMEGA328P | 280/280 bytes | 25/25
All others | 512/512 bytes | 25/25
可以自定义大小
2.2~2.4
float string array的数类型

3协议

协议就是在往串口发送的数据的基础上加上包头包尾,
并允许多个topics同时共享一个串口

3.1Packet Format

  1st Byte - Sync Flag (Value: 0xff)
  2nd Byte - Sync Flag / Protocol version  0xff on ROS Groovy, 0xfe on ROS Hydro, Indigo, and Jade.
  3rd Byte - Message Length (N) - Low Byte
  4th Byte - Message Length (N) - High Byte
  5th Byte - Checksum over message length
  6th Byte - Topic ID - Low Byte
  7th Byte - Topic ID - High Byte
  x Bytes  - Serialized Message Data
  Byte x+1 - Checksum over Topic ID and Message Data

横过来看
起始1  /  版本号1  /  内容长度L、H 2  /  内容长度校验1  / Topic ID L、H 2  /  内容x  /   内容校验1

校验算法
 

Message Length Checksum = 255 - ((Message Length High Byte + 
                                   Message Length Low Byte) % 256 )

Message Data Checksum = 255 - ((Topic ID Low Byte +
                                Topic ID High Byte + 
                                Data byte values) % 256)

由此校验算法上可见 Topic ID两个字节是作为校验数据的一部分,数据包长度这两个字节不算在内。


说Topics ID 0-100 系统保留 

如http://docs.ros.org/api/rosserial_msgs/html/msg/TopicInfo.html

uint16 ID_PUBLISHER=0
uint16 ID_SUBSCRIBER=1
uint16 ID_SERVICE_SERVER=2
uint16 ID_SERVICE_CLIENT=4
uint16 ID_PARAMETER_REQUEST=6
uint16 ID_LOG=7
uint16 ID_TIME=10
uint16 ID_TX_STOP=11
uint16 topic_id
string topic_name
string message_type
string md5sum
int32 buffer_size

此处的Topic ID的称谓值得注意,我觉得理解为 Topic类别ID 更好,他区分了这个数据包话题是发布、订阅或service服务端客户端等等

3.2话题协商 Topic Negotiation

在开始数据传输之前,上位机必须向嵌入式设备查询将要发布或订阅的主题的名称和类型。
主题协商包括对主题的查询、对主题数量的响应以及定义每个主题的数据包。对主题的请求使用主题ID 0。


主题请求时 Topic ID设置0

开始/版本号/长度/长度校验/Topic ID/内容校验

0xFF/0xFE/0x00/0x00/0xFF/0x00/0x00/0xFF

会话结束 topic_id = ID_TX_STOP=11(0x0B)

开始/版本号/长度/长度校验/Topic ID/内容校验

0xFF/0xFE/0x00/0x00/0xFF/0x0B/0x00/0xE3

上位机发过来的时钟/同步帧,(ID_TIME=10)
0xFF/0xFE/0x08/0x00/CHK/0x0A/0x00/8个bytes/CHK


当上位机发送主题请求后
0xff 0xfe 0x00 0x00 0xff 0x00 0x00 0xff
下位机应该发送
一系列响应包(消息类型rosserial-msgs/TopicInfo,每个包都包含有关特定主题的信息,用以下数据代替序列化的消息:

uint16 topic_id
  string topic_name
  string message_type
  string md5sum
  int32 buffer_size
注意这里又有一个topic_id,这个topic_id是运行程序中类实例的id,不能与 Topic ID混淆。
这五个数据合在一起是数据包的内容部分。

用单片机实现一个publisher,下面是实验数据分析

[20:46:35.143]发→◇FF FE 00 00 FF 00 00 FF □
[20:46:35.399]收←◆
FF FE 08 00 F7 
0A 00 ----------------------------0x000A=Topic ID  (ID_TIME=10)
00 00 00 00 00 00 00 00 
F5 --------------------------------0xf5包校验0xff-((0x0A+0x00+0+0+0+0+0+0+0+0)%0x100)


FF FE 48 00 B7 -------------------0x0048=72 包数据长度 0xb7=0xff-((0x48+0x00)%0x100)
00 00 -----------------------------0x0000= Topic ID(ID_PUBLISHER=0)
7D 00 -----------------------------0x7D=125 topic_id (publisher ID)
07 00 00 00 ----------------------0x0007=7,数据长度 topic_name="chatter"
63 68 61 74 74 65 72 
0F 00 00 00 ----------------------0x000f=15,数据长度 message_type ="std_msgs/String"
73 74 64 5F 6D 73 67 73 2F 53 
74 72 69 6E 67 
20 00 00 00 ----------------------0x0020=32,数据长度 md5sum="992ce8a1687cec8c8bd883ec73ca41d1"
39 39 32 63 65 38 61 31 36 38 
37 63 65 63 38 63 38 62 64 38 
38 33 65 63 37 33 63 61 34 31 
64 31 
18 01 00 00 ----------------------0x0118=280,是atmage328p的buffer_size  (看2.1)
0C --------------------------------0x0C 包校验

[20:46:36.404]收←◆
FF FE 10 00 EF 
7D 00 
0C 00 00 00 
68 65 6C 6C 6F 20 77 6F 72 6C 64 21 
F9 

[20:46:37.404]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:38.404]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 

FF FE 08 00 F7 
0A 00 
00 00 00 00 00 00 00 00 F5 

[20:46:39.402]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:40.403]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:41.402]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 FF FE 08 00 F7 0A 00 00 00 00 00 00 00 00 00 F5 
[20:46:42.402]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:43.401]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:44.401]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 FF FE 08 00 F7 0A 00 00 00 00 00 00 00 00 00 F5 
[20:46:45.401]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 
[20:46:46.400]收←◆FF FE 10 00 EF 7D 00 0C 00 00 00 68 65 6C 6C 6F 20 77 6F 72 6C 64 21 F9 

上个标记好的图吧

 

消息类型MD5的对应举例

https://github.com/frankjoshua/rosserial_arduino_lib/blob/master/src/std_msgs/Byte.h

"std_msgs/Byte"
MD5("byte data")="ad736a2e8818154c487bb80fe42ce43b"
"std_msgs/Bool"
MD5("bool data")="8b94c1b53db61fb6aed406028ad6332a"
"std_msgs/String"
MD5("string data")="992ce8a1687cec8c8bd883ec73ca41d1"


关于publisher的ID
https://github.com/frankjoshua/rosserial_arduino_lib/blob/master/src/ros/node_handle.h

void negotiateTopics()
      {
        rosserial_msgs::TopicInfo ti;
        int i;
    
        for(i = 0; i < MAX_PUBLISHERS; i++)
        {
          if(publishers[i] != 0) // non-empty slot
          {
        ReadBuffer buffer;
        
        ti.topic_id = publishers[i]->id_;
        ti.topic_name = (char *) buffer.readTopicName( publishers[i] );
        ti.message_type = (char *) buffer.readMsgInfo( publishers[i]->msg_->getType() );
        ti.md5sum = (char *) buffer.readMsgInfo( publishers[i]->msg_->getMD5() );
        ti.buffer_size = OUTPUT_SIZE;
        publish( publishers[i]->getEndpointType(), &ti );
....

3.3时间

通过向每个方向发送std_msg::Time来处理时间同步。嵌入式设备可以通过发送空时间消息从PC/平板电脑请求当前时间。返回的时间用于查找时钟偏移量。

4 Report a Bug

 

 

 

arduino测试源码


#include <ros.h>
#include <std_msgs/String.h>
#include <std_msgs/UInt16.h>
ros::NodeHandle  nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
std_msgs::String str_msg2;
ros::Publisher chatter2("chatter2", &str_msg2);
 
char hello[13] = "hello world!";
char hello2[13] = "hello hello!";



void servo_cb( const std_msgs::UInt16& cmd_msg){
  //servo.write(cmd_msg.data); //set servo angle, should be from 0-180  
  digitalWrite(13, HIGH-digitalRead(13));  //toggle led  
}


ros::Subscriber<std_msgs::UInt16> sub("servo", servo_cb);


void setup()
{
  pinMode(13, OUTPUT);
  //servo.attach(9); //attach it to pin 9
  nh.initNode();
  nh.advertise(chatter);
  nh.advertise(chatter2);
  nh.subscribe(sub);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  str_msg2.data = hello2;
  chatter2.publish( &str_msg2 );
  nh.spinOnce();
  delay(1000);
}

参考
rosserial_python serial_node.py分析
https://www.cnblogs.com/Montauk/p/7158597.html

rosserial_python serial_node.py分析--补遗
https://www.cnblogs.com/Montauk/p/7161927.html
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS中rosserial通讯协议初探 的相关文章

  • ros 样例代码和教程

    中国大学MOOC 机器人操作系统入门 课程代码示例 代码 https github com DroidAITech ROS Academy for Beginners 书 https legacy gitbook com book sych
  • Python 实现 Dijkstar 路径规划算法

    Dijstar 最短路径算法 用于计算起始点到最终点的最短路径 一般采用的是贪心算法策略 原理可以参考 图解 Open list 和 close list 环境 Terminal 需要预先安装两个库 matplotlib 和 math pi
  • 使用WTGAHRS2(JY-GPSIMU)在ROS中读取数据并发布话题

    目录 IMU简介 驱动程序 IMU串口通信协议 程序 效果 IMU简介 十轴惯性导航传感器WTGAHRS2传感器集成高精度的陀螺仪 加速度计 地磁场传感器 GPS 模块 采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法 能够快速求
  • ROS与navigation教程——ACML参数配置

  • 无人飞行器智能感知竞赛--模拟器安装

    开发环境 win11 wsl2 注意事项 请配合视频使用 如果不看视频会对下面的配置过程迷惑 因为一开始我是想安装在ubuntu18 04的 中途发现ubuntu18 04没有ros noetic 所以转入ubuntu20 04配置 视频链
  • ROS turtlebot_follower :让机器人跟随我们移动

    ROS turtlebot follower 学习 首先在catkin ws src目录下载源码 地址 https github com turtlebot turtlebot apps git 了解代码见注释 其中有些地方我也不是很明白
  • ROS 笔记(01)— Ubuntu 20.04 ROS 环境搭建

    ROS 官网 https www ros org ROS 中文官网 http wiki ros org cn 1 系统和 ROS 版本 不同的 ROS 版本所需的 ubuntu 版本不同 每一版 ROS 都有其对应版本的 Ubuntu 切记
  • Ubuntu18.04配置Seetaface6

    目录 一 下载安装Qt软件 1 安装包下载 2 安装Qt 3 配置 二 下载源码 三 编译工具 四 编译 1 编译OpenRoleZoo 2 编译SeetaAuthorize 3 编译TenniS 五 运行 1 修改lib路径 2 buil
  • 解决ros安装 使用roscore命令测试问题

    本人安装教程完成ROS的安装后 在进行测试如图1命令 出现 解决办法输入完命令1后要输入命令2才行 即可测试成功 测试成功的界面如下
  • ROS 第四天 ROS中的关键组件

    1 Launch文件 通过XML文件实现多节点的配置和启动 可自动启动ROS Master
  • 【ROS】usb_cam相机标定

    1 唠叨两句 当我们要用相机做测量用途时 就需要做相机标定了 不然得到的计算结果会有很大误差 标定的内容包括三部分 内参 外参还有畸变参数 所以标定的过程就是要求得上面这些参数 以前弄这个事估计挺麻烦 需要做实验和计算才能得到 现在通过ro
  • (ros/qt报错) FATAL: ROS_MASTER_URI is not defined in the environment

    安装qt之后 明明打开roscore但是qt运行跟ros有关的节点时报错 FATAL 1450943695 306401842 ROS MASTER URI is not defined in the environment Either
  • ubuntu18.04命令安装ros2

    ROS2官方文档 本教程为apt get命令安装方式 官网教程有点问题 借鉴一下大佬的安装方式 文章目录 1 安装ROS2 1 1 安装秘钥相关指令 1 2 授权秘钥 1 3 添加ROS2软件源 1 4 安装 2 设置环境 可选但是推荐 2
  • ROS AsyncSpinner 的多线程行为

    我试图了解 ROS 中的 AsyncSpinner 是如何工作的 因为我可能有一些误解 你可以找到类似的问题here As seen here它的定义提到 异步旋转器 产生几个线程 可配置 将并行执行回调 同时不会阻塞执行该操作的线程 叫它
  • 将 CUDA 添加到 ROS 包

    我想在 ros 包中使用 cuda 有人给我一个简单的例子吗 我尝试使用 cuda 函数构建一个静态库并将该库添加到我的包中 但总是出现链接错误 未定义的引用 cuda 我已经构建了一个可执行文件而不是库并且它可以工作 请帮忙 我自己找到了
  • 我的代码的 Boost 更新问题

    我最近将 boost 更新到 1 59 并安装在 usr local 中 我的系统默认安装在 usr 并且是1 46 我使用的是ubuntu 12 04 我的代码库使用 ROS Hydro 机器人操作系统 我有一个相当大的代码库 在更新之前
  • catkin_make 编译报错 Unable to find either executable ‘empy‘ or Python module ‘em‘...

    文章目录 写在前面 一 问题描述 二 解决方法 参考链接 写在前面 自己的测试环境 Ubuntu20 04 一 问题描述 自己安装完 anaconda 后 再次执行 catkin make 遇到如下问题 CMake Error at opt
  • ROS 问题:libQt5Core.so.5:无法打开共享对象文件:没有这样的文件或目录

    当我跑步时 rosrun turtlesim turtlesim node 在 Ubuntu 上 我收到以下消息 opt ros noetic lib turtlesim turtlesim node 加载共享库时出错 libQt5Core
  • 如何使用一个凉亭同时创建两个地图?

    如下图所示 现在我的gazebo正在运行2个slam gmapping包 首先是 turtlebot slam gmapping 发布到 map 主题 第二个是 slam gmapping 发布到与第一个相同的 map 主题 我想创建一个新
  • 安装 ROS 时 Cmake 未检测到 boost-python

    我一直在尝试在我的 Mac 上安装 ROS 并根据不同版本的 boost 使用不同的库解决了错误 然而 似乎有一个库甚至没有检测到 boost python 这是我得到的错误 CMake Error at usr local share c

随机推荐

  • RS485知识点

    为什么RS485空闲时的电平要求大于 43 200mv 这不是很容易被接收端接收吗 xff1f a 其实 xff0c 如果RS485的AB线空闲电平如果小于 43 200mv xff0c 485芯片的输出不定 xff0c 有些芯片会输出高
  • 两种点云地面去除方法

    目录 1 基于角度分割的地面 非地面分割 1 1 PCL基本入门 1 1 1 在ROS项目中引入PCL库 1 2 编写节点进行Voxel Grid Filter 1 2 1 验证效果 1 3 点云地面过滤 1 3 1 点云剪裁和过滤 去除过
  • ROS面试题汇总

    1 ROS中订阅 xff08 Subscribe xff09 最新消息以及消息队列相关问题 机器人应用中难免会遇到运算起来很费时间的操作 xff0c 比如图像的特征提取 点云的匹配等等 有时候 xff0c 不可避免地 xff0c 我们需要在
  • VINS-Mono后端知识点汇总

    processImage xff1a 每帧都干了什么 谁是Featureanager xff1a 维护路标点与图像 后端干了啥 xff1a 详解因子图 xff08 视觉的因子图 IMU的因子图 因子图和Hessian矩阵的关系 xff09
  • VINS-Mono学习(二)——松耦合初始化

    初始化 xff1a 如何当好一个红娘 xff1f 图解SfM 视觉和IMU的羁绊 怎么知道发生了闭环 xff1f 位姿图优化与滑窗优化都为哪般 xff1f 闭环优化 xff1a 拉扯橡皮条 整体初始化流程如下 xff1a 1 SFM纯视觉估
  • VINS知识点汇总

    0 总体框架 包括5个部分 xff1a 数据预处理 初始化 后端非线性优化 闭环检测 位姿图优化 图片来自大佬博客 xff1a https blog csdn net try again later article details 1048
  • 语义SLAM综述

    1 摘要 SLAM技术在计算机视觉和机器人领域中占有重要低位 传统的SLAM框架采用了较强的静态世界假设 xff0c 便于分析 大多基于小区域静态环境 在大规模的动态环境下 xff0c 它们大多难以获得较好的性能 xff0c 系统的准确性
  • VINS-Mono学习(三)——基于滑动窗口的VIO紧耦合后端非线性优化

    nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 初始化后 采用基于滑动窗口的紧耦合单目VIO进行状态估计 首先来看VINS Mono后端的整体思路 nbsp nbsp nbsp nbsp nbsp nbsp
  • VINS-Mono学习(五)——闭环优化4DoF

    这里再重写一边VINS开启的新线程 xff1a 前端图像跟踪后端非线性优化闭环检测闭环优化 闭环优化是跟在闭环检测之后步骤 首先回顾闭环检测的过程 xff1a 1 pose graph node cpp开启process闭环检测线程 xff
  • C语言预定义跟踪调试

    标准C语言预处理要求定义某些对象宏 xff0c 每个预定义宏的名称一两个下划线字符开头和结尾 xff0c 这些预定义宏不能被取消定义 xff08 undef xff09 或由编程人员重新定义 下面预定义宏表 xff0c 被我抄了下来 LIN
  • 链式存储

    1 特点 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素 xff0c 这组存储单元可以是连续的 xff0c 也可以是不连续的这就意味着 xff0c 这些数据元素可以存在内存未被占用的任意位置 2 结点是什么 在数据结构
  • ROS驱动包无法连接A2M7雷达解决办法

    我在使用A2M7雷达时 xff0c 波特率是256000 xff0c 之前驱动跑A2M6和A2M8雷达时 xff0c 波特率115200 xff0c 都可以使用 xff0c 现在跑M7就不行 xff0c 显示无法绑定到串口 xff0c 刚开
  • FreeRTOS prvTaskExitError 创建任务错误

    文件port c prvTaskExitError 任务退出错误 xff0c 一个可能在任务里面写了return xff0c 另一个可能任务切换退出问题 xff0c 入栈和出栈的时候出了问题 1 static void prvTaskExi
  • Ubuntu18.04下VSCode环境编写Linux相关驱动程序时出现未定义标识符问题

    Ubuntu18 04下VSCode环境编写Linux相关驱动程序时出现未定义标识符问题 编译Linux相关驱动程序时 xff0c 出现未定义标识符问题 但是ctrl 43 鼠标左键可以找到相关定义 这是因为没有加载对应Linux内核中头文
  • postman基础使用教程

    Postman教程大全 简书 推荐一款接口测试工具 xff01 POSTMAN xff01 简单来说 xff0c 四个词 xff0c 简单实用大方美观 xff01 Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插
  • Make、Makefile、CMake和CMakeLists

    一 Make 在 认识编译器和C C 43 43 编译 一文中介绍过 xff0c 一个 c cpp 文件从源文件到目标文件的过程叫做编译 xff0c 但是一个项目中不可能只存在一个文件 xff0c 这就涉及到多个文件的编译问题 xff0c
  • C++将类写在头文件中

    比如有个类ABC要在main cpp内使用 xff0c 创建两个文件 ABC h xff0c ABC cpp 把类的声明都写在h里面 xff0c 方法的实现写在cpp里面 xff0c 然后在main cpp内 include ABC h x
  • ubuntu搭建一个简单的http服务器

    使用ubuntu搭建一个简单的http服务器 安装apache2 1 sudo apt get update 2 sudo apt get install apache2 安装成功后 xff0c 再 etc apache2目录可见其配置文件
  • Postman操作基本教程

    一 xff1a 基本介绍 xff1a Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 Postman背景介绍 用户在开发或者调试网络程序或者是网页B S模式的程序的时候是需要一些方法来跟踪网页请求的 xff0
  • ROS中rosserial通讯协议初探

    ROS中rosserial通讯协议初探 串行的通讯 xff0c 我们用串口模拟下通讯图 官方 http wiki ros org rosserial rosserial 1概述 标准ROS序列化message的协议 xff0c 可以让一个字