一、需求与分析
编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。
在模型实现中,ROS Master(管理者)不需要实现,而连接的建立也被封装好了,所以需要关注的点主要是Talker(发布方)、Listener(订阅方)以及数据(文本)的实现。
二、发布方的实现
需求:发布方要求循环发布消息hello,后缀数字编号。
1.创建文件
1) 在src目录下添加包,plumbing_pub_sub,并添加依赖 roscpp rospy std_msgs
2)创建发布者源文件,在plumbing_pub_sub文件夹下的src(不是第一步的src)创建文件demo01_pub.cpp
3)修改配置文件,打开与demo01_pub.cpp同级的CMakeLists.txt,配置137行的
add_executable(demo01_pub src/demo01_pub.cpp)
以及156行的
target_link_libraries(demo01_pub
${catkin_LIBRARIES}
)
2.编写代码
代码实现流程:
1.包含头文件
2.初始化ros节点(节点名称唯一)
3.创建ros句柄
4.创建发布者对象
5.组织发布数据、编写发布逻辑并发布数据
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
发布方实现:
1.包含头文件
2.初始化ros节点
3.创建节点句柄
4.创建发布者对象
5.编写发布者逻辑并发布数据
*/
int main(int argc, char *argv[])
{ //编码
setlocale(LC_ALL,"");
//初始化ros节点
ros::init(argc,argv,"erGouZi");
//创建节点句柄
ros::NodeHandle nh;
//创建发布者对象
ros::Publisher pub=nh.advertise<std_msgs::String>("fang",10);
//发布逻辑和发布(先创建被发布的消息,再编写一个循环发布数据)
std_msgs::String msg;//创建
ros::Rate rate(1);//发布频率
int count =0;//设计编号
ros::Duration(3).sleep();//休眠
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;
}
三、订阅方的实现
需求:订阅话题并打印接收到的信息
1.创建文件
1)创建发布者源文件,在plumbing_pub_sub文件夹下的src(不是第一步的src)创建文件demo02_sub.cpp
2)修改配置文件,打开与demo02_sub.cpp同级的CMakeLists.txt,配置137行的
add_executable(demo02_sub src/demo02_sub.cpp)
以及第156行
target_link_libraries(demo02_sub
${catkin_LIBRARIES}
)
2.编写代码
#include "ros/ros.h"
#include "std_msgs/String.h"
/*
订阅方式实现
1.包含头文件
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[])
{ 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;
}
四、运行
1.启动roscore
2.启动发布者
3.启动订阅者
五、注意事项
订阅时,前几条条数据丢失
原因: 发送第一条数据时, publisher 还未在 roscore 注册完毕
解决: 注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送