话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式,即:一个节点发布消息,另一个节点订阅该消息。
概念:
master--->管理者(媒婆) talker--->发布者(男方) listener--->订阅者(女方)
master可以根据话题建立发布者和订阅者之间的连接。
注意:
此通信使用两种协议,RPC和TCP。
talker和listener都可以存在多个。
talker和listener建立连接后,master就可以关闭了。
上述流程已经封装了,后期直接调用即可。
话题通信应用时的关注点:大部分实现已经被封装了,需要关注话题设置、发布者实现、订阅者实现、消息载体。
流程:
编写发布方实现;
编写订阅方实现;
编写配置文件;
编译并执行;
发布者
#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[])
{
/* code */
//日志输出中文
setlocale(LC_ALL,"");
//2.初始化ROS节点
ros::init(argc,argv,"erGouZi");
//3.创建节点句柄
ros::NodeHandle nh;
// 4.创建发布者对象
ros::Publisher pub=nh.advertise<std_msgs::String>("fang",10);
ros::Duration(3.0).sleep();
// 5.编写发布逻辑并发布数据
//要求以10HZ的频率发布数据,并且文本后添加编号
//先创建被发布的消息
std_msgs::String msg;
//发布频率
ros::Rate rate(10);
//编写循环,循环中发布数据
//设置编号
int count=0;
while (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();
ros::spinOnce();//官方建议,运行一次回调函数
}
return 0;
}
运行后,命令行输入如下命令即可显示发布信息。
$rostopic echo 话题名称(fang)
订阅者
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
订阅方实现:
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[])
{
/* code */
//日志输出中文
setlocale(LC_ALL,"");
// 2.初始化ROS节点
ros::init(argc,argv,"cuiHua");
// 3.创建节点句柄
ros::NodeHandle nh;
// 4.创建订阅者对象
ros::Subscriber sub=nh.subscribe("fang",10,doMsg);
// 5.处理订阅到的数据
ros::spin();
return 0;
}
运行效果:
注意:
订阅时,发布者发布的前几条数据可能会丢失。因为publisher还未在roscore注册完毕。
解决:注册后,加入休眠ros::Duration(3.0).sleep();延迟数据发送