在上一篇文章中,咱們實現了第一個ROS程序—發佈器(publisher),然而在上一篇文章的最後咱們也注意到,儘管咱們的程序很是小,但佔據的CPU資源卻很是多。node
這是由於在發佈器的while
循環裏沒有執行必要的sleep
操做,使得發佈器一直以最高速率運行,長時間佔用CPU。c++
本篇文章分爲如下兩部分:bash
sleep
調用使發佈器的頻率穩定在1Hz sleep
事實上,咱們所須要作的只有兩行工做,首先建立一個ros::Rate
對象,而後在while
循環裏調用該對象的.sleep()
函數便可。ide
修改後完整的代碼以下:函數
#include <ros/ros.h> #include <std_msgs/Float64.h> int main(int argc, char **argv) { ros::init(argc, argv, "minimal_publisher"); // 初始化節點名 ros::NodeHandle n; // // ++++ ros::Rate s_timer(1.0); // 參數1.0表明發佈頻率即1.0Hz // ++++ ros::Publisher my_publisher_object = n.advertise<std_msgs::Float64>("topic1", 1); // 建立一個發佈器,調用advertise通知ROS Master話題名稱以及話題類型 //"topic1" 是話題名 // 參數 "1" 是queue_size,表示緩衝區大小 std_msgs::Float64 input_float; // 建立一個發佈器將要使用的消息變量 // 該消息定義在: /opt/ros/indigo/share/std_msgs // 在ROS中發佈的消息都應該提早定義,以便訂閱者接收到消息後該如何解讀 // Float64消息的定義以下,其中包含一個數據字段data: // float64 data input_float.data = 0.0; // 設置數據字段 // 程序所要作的工做將在下面的循環裏完成 while (ros::ok()) { // 該循環沒有sleep,所以將一直處於運行狀態,不斷消耗CPU資源 input_float.data = input_float.data + 0.001; //每循環一次+0.01 my_publisher_object.publish(input_float); // 發佈消息到對應的話題 // ++++ s_timer.sleep(); // 在這裏調用sleep函數可讓程序在這裏 // 中止一段時間以便達到要求的發佈頻率 // ++++ } }
將修改後的發佈器從新進行編譯,而後按照和上篇文章同樣依次運行:post
roscore
再打開一個終端,運行spa
rosrun my_minimal_node my_minimal_publisher # 啓動發佈器
檢查發佈頻率,運行3d
rostopic hz /topic1
能夠看到此時發佈器的發佈頻率已經基本穩定在1Hz
了。而後檢查系統監視器的狀態:code
也一樣能夠看到此時CPU的佔用率已經降下來了。視頻
首先將咱們提早修改好的訂閱器代碼複製到src
目錄下,代碼以下:
#include<ros/ros.h> #include<std_msgs/Float64.h> void myCallback(const std_msgs::Float64& message_holder) { // 打印出咱們接收到的值 ROS_INFO("received value is: %f",message_holder.data); } int main(int argc, char **argv) { ros::init(argc,argv,"minimal_subscriber"); //初始化節點 // 節點名定義爲 minimal_subscriber ros::NodeHandle n; // 節點句柄,用來建立訂閱器 // 訂閱話題'topic1' // subscribe中的mycallback是回調函數,每當有新數據到來時,該函數 // 便會被調用 // 實際的工做是在回調函數中完成的 ros::Subscriber my_subscriber_object= n.subscribe("topic1",1,myCallback); ros::spin(); // 相似於 `while(1)`語句,可是當有新消息到來時,會調用回調函數 return 0; }
而後和上篇文章同樣,爲了編譯咱們剛寫的訂閱器,咱們還須要修改CMakeLists.txt
文件,以便讓編譯器知道應該編譯咱們新增的文件。類比上篇文章的發佈器,咱們在CMakeLists.txt
文件中加入以下兩行:
add_executable(my_minimal_subscriber src/minimal_subscriber .cpp) # 第一個參數是生成後的可執行文件名 第二個參數 # 是源文件路徑名 target_link_libraries(my_minimal_subscriber ${catkin_LIBRARIES}) # 連接庫
打開終端,導航到工做區目錄下~/catkin_ws
,而後執行命令
catkin_make
等待編譯完成後,依次執行命令(這些命令都是在不一樣的終端下輸入)
roscore rosrun my_minimal_node my_minimal_publisher rosrun my_minimal_node my_minimal_subscriber
而後在訂閱器的終端下就能夠看出輸出
運行命令rosnode list
檢查節點
最後,能夠運行命令
rqt_graph
來顯示一個圖形化的節點-話題鏈接圖:
由上面的直觀展現能夠看出,消息由發佈器流出到話題topic1
而後再流向訂閱器。
以上全部過程我錄製了一個視頻,在瀏覽文章過程當中若是遇到問題,您能夠查看視頻來看看我是怎麼作的。