ROS-4 : ROS節點和主題
依照<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
ROS-4 : ROS節點和主題