1. 程式人生 > >ROS-4 : ROS節點和主題 ROS-3 : Catkin工作空間和ROS功能包

ROS-4 : ROS節點和主題 ROS-3 : Catkin工作空間和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節點包括以下幾個步驟:

  1. 在功能包的src下編寫節點的原始檔,即.cpp檔案
  2. 編輯功能包的CMakeLists.txt檔案,新增編譯和構建節點所需的內容;
  3. 構建功能包。

二、執行節點

  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模式通訊的節點的過程如下:

  1. 在一個終端上執行roscore;
  2. 在另一個終端上執行主題釋出者節點;
  3. 在另一個終端上執行主題訂閱者節點。

  在終端中輸入rqt_graph,可看到上述兩個節點間的通訊關係:

$ rqt_graph