当前位置 博文首页 > txr152111的博客:7th ROS通信之话题通信的实现(最通俗版本)(C+
机器人在执行导航功能,使用的传感器是激光雷达,机器人会采集激光雷达感知到的信息并计算,然后生成运动控制信息驱动机器人底盘运动。
一共有两次使用话题通信:
?话题通信适用于不断更新的数据传输相关的应用场景
概念
以发布订阅的方式实现不同节点之间数据交互的通信模式。
作用
用于不断更新的、少逻辑处理的数据传输场景。
核心要素
发布方、订阅方、话题
话题通信有三个角色:
管理者其实有点像媒婆的角色。下面就是大型ROS相亲现场:
RPC是远程调用,相当于手机号,TCP相当于微信,联系比较方便。
?基本流程(相亲流程):
无论是Listener还是Talker,都不能直接进行通信,需由ROS Master代发。Listener向ROS Master询问(专业点称作订阅 subscribe)叫bar的话题(topic),若存在发布该话题的Talker,ROS Master响应给Listener,Listener与Talker建立TCP连接并通信。
注意事项:
在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有四个:
编写代码(测试版):
#include<ros/ros.h>
#include<std_msgs/String.h>
/*
该文件是发布方实现:
1.包含头文件
ROS的文本类型----->std_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建发布者对象
5.编写发布逻辑并发布数据
*/
int main(int argc,char *argv[])
{
//2.初始化ROS节点
ros::init(argc,argv,"ErGouZi");
// 3.创建节点句柄
ros::NodeHandle nh;
//4.创建发布者对象
ros::Publisher pub= nh.advertise<std_msgs::String>("FangZi",10);
// 5.编写发布逻辑并发布数据
//先创建发布的消息
std_msgs::String msg;
//再编写一个循环
while(ros::ok()) //ros::ok()要是这个节点活着就为真
{
msg.data = "hello";
pub.publish(msg);
}
return 0;
}
配置编译文件(CMakeLists.txt文件中):
注意:这里面后面是没有分号的。
add_executable(demo01_pub src/demo01_pub.cpp)
target_link_libraries(demo01_pub
${catkin_LIBRARIES}
)
?编译运行后发现没有显示什么,那就对了。只发布了,并没有接受。
完整版代码:
#include<ros/ros.h>
#include<std_msgs/String.h>
#include<sstream>
/*
该文件是发布方实现:
1.包含头文件
ROS的文本类型----->std_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建发布者对象
5.编写发布逻辑并发布数据
*/
int main(int argc,char *argv[])
{
setlocale(LC_ALL,"");
//2.初始化ROS节点
ros::init(argc,argv,"ErGouZi");
// 3.创建节点句柄
ros::NodeHandle nh;
//4.创建发布者对象
ros::Publisher pub= nh.advertise<std_msgs::String>("FangZi",10);
// 5.编写发布逻辑并发布数据
//要求以10Hz的频率发布数据,并且,文本后添加编号
//先创建发布的消息
std_msgs::String msg;
//发布频率
ros::Rate rate(10);
//设置编号
int count = 0;
//再编写一个循环
while(ros::ok()) //ros::ok()要是这个节点活着就为真
{
count++;
//msg.data = "hello";
//实现字符串拼接
std::stringstream ss;
ss<<"hello --->"<<count;
msg.data = ss.str();
pub.publish(msg);
//添加日志
ROS_INFO("发布的数据是:%s",ss.str().c_str() );
rate.sleep();
}
return 0;
}
订阅者的代码:
#include<ros/ros.h>
#include<std_msgs/String.h>
/*
该文件是订阅方实现:
1.包含头文件
ROS的文本类型----->std_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建订阅者对象
5.处理订阅的数据
6.spin()函数
*/
void doMsg(const std_msgs::String::ConstPtr &msg)
{
//通过msg获取并操作订阅到的数据
ROS_INFO("翠花订阅到的数据为:%s",msg->data.c_str() );
}
int main(int argc,char *argv[])
{
// 2.初始化ros节点
ros::init(argc,argv,"CuiHua");
// 3.创建节点句柄
ros::NodeHandle nh;
// 4.创建订阅者对象
ros::Subscriber sub = nh.subscribe("fang",10,doMsg);
//subscribe(话题,存储的数,回调函数);
// 5.处理订阅的数据
ros::spin();
return 0;
}
CMakeLists.txt文件:
add_executable(demo02_sub src/demo02_sub.cpp)
target_link_libraries(demo02_sub
${catkin_LIBRARIES}
)
在新的终端运行:
rqt_graph? ?查看计算图:
参考文章:
https://blog.csdn.net/ck784101777/article/details/106183819/
cs