ROS学习记录(一):话题通信的基本操作
话题通信的基本操作(C++)
需求:
1
编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。
分析:
在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
1.发布方
2.接收方
3.数据(此处为普通文本)
流程:
1.编写发布方实现;
2.编写订阅方实现;
3.编辑配置文件;
4.编译并执行。
1.发布方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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,"test_pub");
// 3.创建节点句柄
ros::NodeHandle nh;
// 4.创建发布对象
ros::Publisher pub = nh.advertise<std_msgs::String>("test_pubsub",10);
// 5.编写发布逻辑并发布数据
//先创建被发布的消息
std_msgs::String msg;
//发布频率
ros::Rate rate(10);
//设置编号
int count = 0;
//编写循环,循环中发布数据
while (ros::ok())
{
count++;
//实现字符串拼接数据
std::stringstream ss;
ss<< "hello ---> " << count;
msg.data = ss.str();
pub.publish(msg);
//添加日志
ROS_INFO("发布的数据是:%s",ss.str().c_str());
//休眠时间为1/f
rate.sleep();
}
return 0;
}
2.订阅方
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include"ros/ros.h"
#include"std_msgs/String.h"
/*
发布实现:
1.包含头文件
ROS下的文本类型 ---> std_msgs/String.h
2.初始ros节点
3.创建节点句柄
4.创建订阅对象
5.处理接收到的数据
6.spin()函数
*/
//编写回调函数
void test_sub_callback(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,"test_sub");
//3.创建节点句柄
ros::NodeHandle nh;
//4.创建订阅对象
ros::Subscriber sub = nh.subscribe("test_pubsub",10,test_sub_callback);
//5.处理订阅到的数据
ros::spin();
return 0;
}
3.配置 CMakeLists.txt
1
2
3
4
5
6
7
8
add_executable(test_pub src/test_pub.cpp)
add_executable(test_sub src/test_sub.cpp)
target_link_libraries(test_pub
${catkin_LIBRARIES}
)
target_link_libraries(test_sub
${catkin_LIBRARIES}
)
4.执行
1.启动 roscore;
2.启动发布节点;
3.启动订阅节点。
5.注意要点
补充1. vscode 中的 main 函数 声明 int main(int argc, char const *argv[]){},默认生成 argv 被 const 修饰,需要去除该修饰符
补充2. 订阅时,第一条数据丢失 原因: 发送第一条数据时, publisher 还未在 roscore 注册完毕 解决: 注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送
补充3. publisher与subscriber中的消息名称应当一样,且在ros网络中唯一。
本文由作者按照 CC BY 4.0 进行授权