开发背景
在ROS进行结构体消息收发时,经常用书写proto文件,然后将proto字段与结构体字段一一对应,额外需要写一个adaptor转换程序,如果想要发送n个结构体,那么要写n个proto以及n个adaptor。这样很繁琐,能否有一个通用的方法?
下面我将对我在这个过程中碰到的问题,以及自己解决问题的思路做一个梳理,希望能帮到你。
(下面是临时写的,大致框架,具体后面在补充cmake,以及完整的例子)
简短版本
利用std_msgs::String发送结构体(最终版)
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
#include <iostream>
#include <string>
/*
发布方实现:
1.包含头文件;
ROS中文本类型 ----> std_msgs/String.h
2.初始化ROS节点;
3.创建节点句柄;
4.创建发布者对象;
5.编写发布逻辑并发布数据v
*/
enum struct GradeClassification: uint8_t{
PASS = 0,
GOOD,
EXCELLENT,
};
struct Junior {
char name[32];
int height;
GradeClassification grade_classification;
};
int main(int argc, char *argv[]) {
const int rate_value = 20;
setlocale(LC_ALL,"");
// 2.初始化ROS节点;
ros::init(argc, argv,"string_ros_pub");
// 3.创建节点句柄;
ros::NodeHandle nh;
// 4.创建发布者对象;
ros::Publisher pub = nh.advertise<std_msgs::String>("/test_string",10);
// 5.编写发布逻辑并发布数据;
// (5.1) 先创建ROS标准消息std_msgs::String
std_msgs::String msg;
// (5.2) 创建结构体变量
Junior junior;
// 以 20HZ 的频率发布数据
ros::Rate rate(rate_value);
// 设置编号
int seq = 0;
// 休眠以防没注册完已发布数据
ros::Duration(3).sleep();
// 编写循环,循环中发布数据
while(ros::ok()) {
// (5.3) 给结构体变量赋值
junior.height = 178;
junior.grade_classification=GradeClassification::EXCELLENT;
// (5.4) 创建 std::string
std::string s_temp;
// 这一步非常重要!!!
s_temp.assign((char*)&junior, sizeof(Junior));
// (5.5) 将std::string 赋值给ROS标准消息std_msgs::String的data成员变量
msg.data = s_temp;
// (5.6) 将载有结构体变量junior数据的消息std_msgs::String 发送
pub.publish(msg