【Autolabor初级教程】ROS机器人入门 第 2 章 ROS通信机制 笔记
ROS 中的基本通信机制主要有如下三种实现策略:
- 话题通信(发布订阅模式)
- 服务通信(请求响应模式)
- 参数服务器(参数共享模式)
2.1 话题通信
概念:以发布订阅的方式实现不同节点之间数据交互的通信模式
作用:用于不断更新的、少逻辑处理的数据传输场景
适用场景:话题通信适用于不断更新的数据传输相关的应用场景
理论模型
参考链接:视频讲得很通透
038话题通信_理论模型_Chapter2-ROS通信机制_哔哩哔哩_bilibili

话题通信基本操作(C++)
-
发布方
// 1.包含头文件 #include "ros/ros.h" #include "std_msgs/String.h" // ros中文本类型 #include <sstream> int main(int argc, char *argv[]) { // 2.初始化ros节点 ros::init(argc,argv,"pub"); // 3.创建节点句柄 ros::NodeHandle nh; // 4.创建发布者对象 第一个参数为发布的话题 ros::Publisher pub = nh.advertise<std_msgs::String>("pos",10); // 5.编写发布逻辑并发布数据 // 要求以10hz的频率发布数据,并且文本后添加编号 // 先创建被发布消息 std_msgs::String msg; // 发布频率 ros::Rate rate(10); // 该参数为指定频率 // 设置编号 int count = 0; // 编写循环,循环中发布数据 while(ros::ok()) { // 输出中文 setlocale(LC_ALL,""); count++; // 实现字符串拼接数字 // msg.data = "here"; std::stringstream ss; ss << "hello ---> " << count; msg.data = ss.str(); pub.publish(msg); ROS_INFO("发布的数据是:%s",ss.str().c_str()); // 根据前面制定的发送频率自动休眠 休眠时间 = 1/频率; rate.sleep(); } return 0; }如果代码中无输出,验证此代码时,可以在新的终端输入
rostopic echo pos,屏幕中会显示数据
-
订阅方
// 1.包含头文件 #include "ros/ros.h" #include "std_msgs/String.h" // ros中文本类型 void domsg(const std_msgs::String::ConstPtr &msg) { // 通过msg获取并操作订阅到的数据 ROS_INFO("接受到的数据是:%s",msg->data.c_str()); } int main(int argc, char *argv[]) { setlocale(LC_ALL,""); // 2.初始化ros节点 ros::init(argc,argv,"sub"); // 3.创建节点句柄 ros::NodeHandle nh; // 4.创建订阅者对象 第一个参数为订阅的话题,domsg为所进行的操作 ros::Subscriber sub = nh.subscribe("pos",10,domsg); // 5.处理订阅到的数据 // 6.循环读取接收的数据,并调用回调函数处理 // 如果要用回调函数必须用spin ros::spin(); return 0; }同时执行两代码得到结果

可以发现,订阅者接收的信息有丢失(在launch文件中先开启的subscriber)
原因是在publisher发送信息的时候,还未在roscore注册完毕,导致数据丢失
解决方案:在循环前加入以下代码,延迟第一条信息的发送
// 程序休眠,防止节点还未在roscore中注册时就发送消息 ros::Duration(3).sleep();可以看到接收正常

程序运行时,可以新建终端输入指令rqt_graph,就可以看到计算图,帮助理解节点间关系

话题通信自定义msg
作用:类似于C语言的结构体
在自定义msg时,可以适用的字段类型有

话题通信自定义msg实现(C++)
-
自定义msg实现
-
功能包下新建
msg目录,添加文件xxx.msg(注意后缀) -
内容每行定义字段类型和字段名即可,回车换行
string name uint16 age float64 height -
修改
package.xml,添加以下内容
-
修改
CMakeLists.txt(没有的内容增加,被注释的解开)



-
编译
编译后会在devel/include生成对应的头文件

-
-
后续代码使用自定义msg的准备工作
配置
.vscode/c_cpp_properties.json将自定义msg的头文件所在路径添加到
"includePath"即可
-
发布者
// 1.包含头文件 #include "demo_pub_sub/person.h" #include "ros/ros.h" #include "demo_pub_sub/person.h" int main(int argc, char *argv[]) { setlocale(LC_ALL,""); // 2.初始化ros节点 ros::init

最低0.47元/天 解锁文章
1556

被折叠的 条评论
为什么被折叠?



