技术分享 | ROS里多机通信配置太繁琐?带你换个方式来操作

Posted 阿木实验室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术分享 | ROS里多机通信配置太繁琐?带你换个方式来操作相关的知识,希望对你有一定的参考价值。

在ROS1当中,很多使用Qt开发无人机和无人车交互界面的多数都是使用ROS自带的通信机制多机通信机制,但是在ROS1当中使用这种机制就避免不了多机通信配置问题,操作起来也十分繁琐,为了避免这种问题所以采用了TCP/UDP通信机制来替代ROS多机通信机制,但是怎么样将ROS中msg数据打包传输给Qt交互界面呢?相信很多想更换通信机制的人都想过这个问题,所以这篇文件就带你实现使用序列化和反序列化进行msg数据的传输。分为两种情况,分别是Qt依赖ROS和Qt不依赖ROS。这两种情况都有着属于各自的优点。下面会分别介绍这两种情况。

Qt依赖ROS

这种情况的优点就是可以通过ROS自带的序列化进行传输,可以将订阅的话题数据全部序列化打包进行发送,在由Qt人机交互界面进行反序列化解析还原成话题数据。就比如rviz数据,如果使用TCP/UDP通信同时实现rviz显示可视化数据,则必须使用该方式,将空中端订阅到的rviz话题数据全部打包发送在还原,还原后再在Qt端进行发布话题给rviz订阅。

空中端代码简单示例:

#include <ros/serialization.h> #include "prometheus_msgs/DroneState.h" //DroneState.msg生成 //msg为进入回调后的 (const prometheus_msgs::DroneState::ConstPtr& msg) prometheus_msgs::DroneState drone = msg; //序列化 buffer为序列化后的数据 serial_size为序列化后的大小 namespace ser = ros::serialization; uint32_t serial_size = ros::serialization::serializationLength(drone); boost::shared_array buffer(new uint8_t[serial_size]); ser::OStream stream(buffer.get(), serial_size); ser::serialize(stream, drone); //将buffer存入 ,udp_send_bufbuff为要发送的数据 char *ptr = udp_send_buf; //首先存入msg序列化后的长度 *((int )ptr) = serial_size; ptr += sizeof(int); //存入序列化后的数据 for(int i = 0;i < serial_size;i++) ((uint8_t)ptr) = buffer[i]; ptr += sizeof(uint8_t); //发送数据

地面端(Qt)代码简单示例:

#include <ros/serialization.h> #include "WorkStation/DroneState.h" //DroneState.msg生成 //通过TCP/UDP接收到数据存入buff //首先拿到buffer长度 char ptr = buff; int serial_size = *((int *)ptr); ptr += sizeof(int); //根据buffer长度拿出buffer boost::shared_array buffer(new uint8_t[serial_size]); for(int i = 0;i < serial_size;i++) buffer[i] = *((uint8_t )ptr); ptr += sizeof(uint8_t); //将buffer反序列化给drone WorkStation::DroneState drone; namespace ser = ros::serialization; ser::IStream stream(buffer.get(),serial_size); ser::deserialize(stream,drone);

Qt不依赖ROS

这种情况的优点就是摆脱了ROS环境的影响,移植的时候也不用考虑ROS环境因素。同时在这种情况下我们就不能使用ROS自带的序列化了,同时我们也不能将msg话题数据打包进行发送,而是需要将msg转换为结构体或者类来进行发送。同时因为要将结构体或者类序列化所以采用boost序列化库(这只是其中一种方式,还有其他序列化方式)。

空中端代码简单示例:

#include #include #include // NULL #include #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/vector.hpp> //结构体 struct Book std::string bookname; int price; friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */) ar & bookname; ar & price; ; //temp为将book序列化后的数据 Book book; book.name = "序列化"; book.price = 10; std::ostringstream oss; boost::archive::text_oarchive oa(oss); oa<<test; std::string temp = oss.str(); //将temp通过TCP/UDP发送

地面端(Qt)代码简单示例:

#include #include #include // NULL #include #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/vector.hpp> //结构体 struct Book std::string bookname; int price; friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int /* file_version */) ar & bookname; ar & price; ; //通过TCP/UDP接收数据 //str为发送端发来的数据temp //将发送端发来的数据反序列化给b,b即为发送的结构体 Book b; std::istringstream iss(str); boost::archive::text_iarchive ia(iss); ia>>b;

结尾

以上操作只是简略的操作,省略了通信部分的代码,只写了序列化和反序列化的操作仅供参考。

  • End -

技术发展的日新月异,阿木实验室将紧跟技术的脚步,不断把机器人行业最新的技术和硬件推荐给大家。看到经过我们培训的学员在技术上突飞猛进,是我们培训最大的价值。如果你在机器人行业,就请关注我们的公众号,我们将持续发布机器人行业最有价值的信息和技术。
阿木实验室致力于为机器人研发提供开源软硬件工具和课程服务,让研发更高效!

以上是关于技术分享 | ROS里多机通信配置太繁琐?带你换个方式来操作的主要内容,如果未能解决你的问题,请参考以下文章

技术分享 | 4点带你快速理解ROS2通信

ROS1/2机器人多机网络通信配置-更新-2022

ROS1/2机器人多机网络通信配置-更新-2022

ROS分布式多机通信(主从机配置)

ROS1机器人多机网络通信案例turtlesim

ROS1机器人多机网络通信案例turtlesim