网站首页 > 技术文章 正文
在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<uint8_t> 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<uint8_t> 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 <vector>
#include <fstream>
#include <cstddef> // NULL
#include <iomanip>
#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<class Archive>
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 <vector>
#include <fstream>
#include <cstddef> // NULL
#include <iomanip>
#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<class Archive>
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 -
技术发展的日新月异,阿木实验室将紧跟技术的脚步,不断把机器人行业最新的技术和硬件推荐给大家。看到经过我们培训的学员在技术上突飞猛进,是我们培训最大的价值。如果你在机器人行业,就请关注我们的公众号,我们将持续发布机器人行业最有价值的信息和技术。
猜你喜欢
- 2025-05-21 关于 synchronized,这儿比你想知道的还要多
- 2025-05-21 STM32F4 HAL库学习笔记之串口通讯 2
- 2025-05-21 高并发服务器epoll接口、epoll Reactor(反应堆)模型详解
- 2025-05-21 写一个Nginx的模块没有那么难
- 2025-05-21 浅析weak指针的实现
- 2025-05-21 Objective-C的本质
- 2025-05-21 PhantomReference 和 WeakReference 究竟有何不同
- 2025-05-21 NVME CLI源码之:error-log源码学习
- 2025-05-21 为什么使用binder机制作为IPC通信方式
- 2025-05-21 Linux的epoll使用LT+非阻塞IO和ET+非阻塞IO有效率上的区别吗?
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)