依照<ROS-3 : Catkin工作空间和ROS功能包>,创建catkin工作空间,并在起src下创建功能包ros_demo_pkg,依赖项为roscpp、std_msgs、actionlib、actionlib_msgs,并构建该空功能包。ROS中节点间的基本通讯方式是topic,即publish/subscribe模式。以下介绍如何创建两个两个节点分别发布和订阅一个主题。
一、创建节点
1、创建发布者节点topic_publisher
首先在功能包ros_demo_pkg下的src下创建第一个节点文件topic_publisher.cpp。该节点在主题/numbers上发布一个整数,其代码和详解如下:
1 //roscpp client APIs的核心头文件 2 #include "ros/ros.h" 3 //标准消息类型Int32的头文件 4 #include "std_msgs/Int32.h" 5 #include <iostream> 6 7 int main(int argc, char **argv) 8 9 { 10 11 //初始化ROS node--topic_publisher 12 ros::init(argc, argv,"topic_publisher"); 13 14 //创建一个节点句柄对象,用于和ROS系统通讯 15 ros::NodeHandle node_obj; 16 17 //创建一个主题发布者对象,设定主题名、消息类型和缓冲区大小 18 ros::Publisher number_publisher = node_obj.advertise<std_msgs::Int32>("/numbers",10); 19 20 //设定发送数据的频率 21 ros::Rate loop_rate(10); 22 23 int number_count = 0; 24 25 //开启while循环,递增一个数值,并发布到topic /numbers 26 while (ros::ok()) 27 { 28 29 //创建 Int32型消息对象 30 std_msgs::Int32 msg; 31 32 //设置消息值 33 msg.data = number_count; 34 35 //打印消息数据 36 ROS_INFO("%d",msg.data); 37 38 //将消息发布到主题 39 number_publisher.publish(msg); 40 41 //读取并更新所有的topics 42 ros::spinOnce(); 43 44 //实现数据发布频率 45 loop_rate.sleep(); 46 47 ++number_count; 48 } 49 50 return 0; 51 }
2、创建订阅者节点topic_subscriber
接下来在功能包ros_demo_pkg下的src下创建第二个节点文件topic_subscriber.cpp。该节点订阅主题/numbers,接收该主题的消息,其代码和详解如下:
1 #include "ros/ros.h" 2 #include "std_msgs/Int32.h" 3 #include <iostream> 4 5 //Callback 函数,当有数据被发布到主题/numbers时会调用该函数 6 void number_callback(const std_msgs::Int32::ConstPtr& msg) 7 { 8 ROS_INFO("Recieved [%d]",msg->data); 9 } 10 11 int main(int argc, char **argv) 12 { 13 14 //初始化ROS node --topic_subscriber 15 ros::init(argc, argv,"topic_subscriber"); 16 ros::NodeHandle node_obj; 17 //创建一个订阅者对象,设定主题名、缓冲区大小和callback函数 18 ros::Subscriber number_subscriber = node_obj.subscribe("/numbers",10,number_callback); 19 //Spinning the node 20 ros::spin(); 21 return 0; 22 }
3、构建节点
为编译并构建上述节点的源代码,必须编辑功能包中的CMakeLists.txt文件。
$ cd ~/catkin_ws/src/ros_demo_pkg $ gedit CMakeList.txt
在已有的CMakeLists.txt文件中加入以下代码:
## 指定头文件的位置 include_directories( include ${catkin_INCLUDE_DIRS} ) ## 声明一个C++可执行文件 ## add_executable(node_name src/node_source_file.cpp) add_executable(topic_publisher src/topic_publisher.cpp) add_executable(topic_subscriber src/topic_subscriber.cpp) ## 添加可执行文件所需的cmake target dependencies ## add_dependencies(node_name {package_name}_generate_messages_cpp) add_dependencies(topic_publisher ros_demo_pkg_generate_messages_cpp) add_dependencies(topic_subscriber ros_demo_pkg_generate_messages_cpp) ## 指定链接 a library 或 executable target所需的libraries # target_link_libraries(node_name ${catkin_LIBRARIES} ) target_link_libraries(demo_topic_publisher ${catkin_LIBRARIES}) target_link_libraries(demo_topic_subscriber ${catkin_LIBRARIES})
然后就可以编译上述节点并构建该功能包:切换到catkin工作空间再进行构建。
$ cd ~/catkin_ws $ catkin_make
以上即为构建成功。
综上,创建ROS节点包括以下几个步骤:
- 在功能包的src下编写节点的源文件,即.cpp文件
- 编辑功能包的CMakeLists.txt文件,添加编译和构建节点所需的内容;
- 构建功能包。
二、执行节点
ROS系统中运行任何节点前都必须先运行roscore。roscore将启动ROS Master、ROS paramter和rosout logging nodes。
$ roscore
再在另两个终端中分别运行上述两个节点。先运行发布者节点topic_publisher:
$ rosrun ros_demo_pkg topic_publisher
再运行订阅者节点topic_subscriber:
$ rosrun ros_demo_pkg topic_subscriber
可看到两个节点的运行结果如下图:
综上,运行以topic模式通讯的节点的过程如下:
- 在一个终端上运行roscore;
- 在另一个终端上运行主题发布者节点;
- 在另一个终端上运行主题订阅者节点。
在终端中输入rqt_graph,可看到上述两个节点间的通讯关系:
$ rqt_graph
原文地址:https://www.cnblogs.com/yanqingyang/p/9823424.html