ROS入门学习5-0:理解话题中Publier与Subscriber(C++)

  本例程节点放在ros_learning功能包src文件夹下,新建ros_learning功能包(如果已创建则跳过):

$ cs
$ catkin_create_pkg ros_learning std_msgs rospy roscpp
$ cm

话题程序编写

创建发布者(Publier)

talker_c.cpp
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
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

/***
第一行:ros/ros.h是一个实用的头文件,它引用了ROS系统中大部分常用的头文件,使用它会使得编程很简便。
第二行:引用了std_msgs/String 消息, 它存放在std_msgs package里,是由String.msg文件自动生成的头文件。
***/

int main(int argc, char **argv)
{
// 创建并初始化节点talker_c;注意节点的名称必须唯一。
ros::init(argc, argv, "talker_c");
// 为这个进程的节点创建一个句柄n。
ros::NodeHandle n;

// 告诉master我们将要在chatter_c topic上发布一个std_msgs/String的消息;这样master就会告诉所有订阅了chatter_c topic的节点,将要有数据发布。
// 第二个参数是发布序列的大小;如果我们发布的消息太快,缓冲区中的消息在大于1000个的时候就会开始丢弃先前发布的消息。
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter_c", 1000);
// 指定自循环的频率10Hz
ros::Rate loop_rate(10);

int count = 0;
while (ros::ok())
{
// 创建字符串消息数据msg.data
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();

// ROS_INFO和类似的函数用来替代printf/cout,发送到终端显示
ROS_INFO("%s", msg.data.c_str());
// 发布话题消息msg
chatter_pub.publish(msg);
// 调用一次回调函数,这个例程没有用的,但如需扩展程序,最好保留。
ros::spinOnce();
// 调用ros::Rate对象来休眠一段时间以使得发布频率为10hz
loop_rate.sleep();
++count;
}

return 0;
}

创建订阅者(Subscriber)

listener_c.cpp
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
#include "ros/ros.h"
#include "std_msgs/String.h"

// 回调函数,当消息到达chatter topic的时候就会被调用
// 消息是以 boost shared_ptr指针的形式传输,这就意味着你可以存储它而又不需要复制数据
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}


int main(int argc, char **argv)
{
// 创建并初始化节点listener_c;注意节点的名称必须唯一。
ros::init(argc, argv, "listener_c");
// 为这个进程的节点创建一个句柄n。
ros::NodeHandle n;

//同样告诉master我们要订阅chatter_c topic上的消息;当有消息到达topic时,ROS就会调用chatterCallback()函数。
ros::Subscriber sub = n.subscribe("chatter_c", 1000, chatterCallback);

// 进入自循环,可以尽可能快的调用消息回调函数
ros::spin();
return 0;
}

添加配置

方法一:可执行文件添加到CMakeLists.txt末尾位置

CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
add_executable(talker_c
src/talker_c.cpp
)
add_dependencies(talker_c ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(talker_c
${catkin_LIBRARIES}
)

add_executable(listener_c
src/listener_c.cpp
)
add_dependencies(listener_c ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(listener_c
${catkin_LIBRARIES}
)

方法二:使用Roboware软件自动创建

   右键src文件夹选择新建cpp源文件,然后输入文件名(如listener_c.cpp),再选择加入新的可执行文件中。可到CMakeLists.txt文件中查看创建结果。

(图)Roboware软件自动创建

程序运行

  • 打开新终端,编译功能包,启动ROS:
$ cm
$ roscore
  • 打开新终端,运行订阅者,此时发布者还没发送消息:再运行发布者节点:
$ rosrun ros_learning listener_c
$ rosrun ros_learning talker_c
(图)节点运行
  • 查看节点关系
$ rqt_graph
(图)查看节点关系
+