SLAM+語音機器人DIY系列:(二)ROS入門——5.編寫簡單的消息發佈器和訂閱器

摘要                                          

ROS機器人操做系統在機器人應用領域很流行,依託代碼開源和模塊間協做等特性,給機器人開發者帶來了很大的方便。咱們的機器人「miiboo」中的大部分程序也採用ROS進行開發,因此本文就重點對ROS基礎知識進行詳細的講解,給不熟悉ROS的朋友起到一個拋磚引玉的做用。本章節主要內容:html

1.ROS是什麼node

2.ROS系統總體架構python

3.在ubuntu16.04中安裝ROS kineticnginx

4.如何編寫ROS的第一個程序hello_worlddjango

5.編寫簡單的消息發佈器和訂閱器編程

6.編寫簡單的service和clientubuntu

7.理解tf的原理centos

8.理解roslaunch在大型項目中的做用bash

9.熟練使用rviz網絡

10.在實際機器人上運行ROS高級功能預覽



5.編寫簡單的消息發佈器和訂閱器

經過上一節編寫ROS的第一個程序hello_world,咱們對ROS的整個編程開發過程有了基本的瞭解,如今咱們就來編寫真正意義上的使用ROS進行節點間通訊的程序。因爲以前已經建好了catkin_ws這樣一個工做空間,之後開發的功能包都將放在這裏面,這裏給新建的功能包取名爲topic_example,在這個功能包中分別編寫兩個節點程序publish_node.cppsubscribe_node.cpp,發佈節點(publish_node)向話題(chatter)發佈std_msgs::String類型的消息,訂閱節點(subscribe_node)從話題(chatter)訂閱std_msgs::String類型的消息,這裏消息傳遞的具體內容是一句問候語「how are you ...」,通訊網絡結構如圖16

16消息發佈與訂閱ROS通訊網絡結構圖

1)功能包的建立

catkin_ws/src/目錄下新建功能包topic_example,並在建立時顯式的指明依賴roscppstd_msgs。打開命令行終端,輸入命令:

cd ~/catkin_ws/src/

#建立功能包topic_example時,顯式的指明依賴roscpp和std_msgs,
#依賴會被默認寫到功能包的CMakeLists.txt和package.xml中
catkin_create_pkg topic_example roscpp std_msgs

2)功能包的源代碼編寫

功能包中須要編寫兩個獨立可執行的節點,一個節點用來發布消息,另外一個節點用來訂閱消息,因此須要在新建的功能包topic_example/src/目錄下新建兩個文件publish_node.cppsubscribe_node.cpp,並將下面的代碼分別填入。

首先,介紹發佈節點publish_node.cpp,代碼內容以下:

 

 1 #include "ros/ros.h" 
 2 #include "std_msgs/String.h" 
 3 
 4 #include <sstream>
 5 
 6 int main(int argc, char **argv) 
 7 {
 8   ros::init(argc, argv, "publish_node");
 9   ros::NodeHandle nh;
10 
11   ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 1000);
12   ros::Rate loop_rate(10);
13   int count = 0;
14 
15   while (ros::ok()) 
16   {
17     std_msgs::String msg;
18 
19     std::stringstream ss; 
20     ss << "how are you " << count; 
21     msg.data = ss.str();
22     ROS_INFO("%s", msg.data.c_str());
23   
24     chatter_pub.publish(msg);
25   
26     ros::spinOnce();
27     loop_rate.sleep();
28     ++count;
29   }
30 
31   return 0;
32 }

對發佈節點代碼進行解析。

#include "ros/ros.h"

這一句是包含頭文件ros/ros.h,這是ROS提供的C++客戶端庫,是必須包含的頭文件。

 

#include "std_msgs/String.h"

因爲代碼中須要使用ROS提供的標準消息類型std_msgs::String,因此須要包含此頭文件。

 

ros::init(argc, argv, "publish_node");

這一句是初始化ros節點並指明節點的名稱,這裏給節點取名爲publish_node,一旦程序運行後就能夠在ros的計算圖中被註冊爲publish_node名稱標識的節點。

 

ros::NodeHandle nh;

這一句是聲明一個ros節點的句柄,初始化ros節點必須的。

 

ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("chatter", 1000);

這句話告訴ros節點管理器咱們將會在chatter這個話題上發佈std_msgs::String類型的消息。這裏的參數1000是表示發佈序列的大小,若是消息發佈的太快,緩衝區中的消息大於1000個的話就會開始丟棄先前發佈的消息。

 

ros::Rate loop_rate(10);

這句話是用來指定自循環的頻率,這裏的參數10 表示10Hz頻率,須要配合該對象的sleep()方法來使用。

 

while (ros::ok()) {...}

roscpp會默認安裝以SIGINT句柄,這句話就是用來處理由ctrl+c鍵盤操做、該節點被另外一同名節點踢出ROS網絡、ros::shutdown()被程序在某個地方調用、全部ros::NodeHandle句柄都被銷燬等觸發而使ros::ok()返回false值的狀況。

 

std_msgs::String msg;

定義了一個std_msgs::String消息類型的對象,該對象有一個數據成員data用於存放咱們即將發佈的數據。要發佈出去的數據將被填充到這個對象的data成員中。

 

chatter_pub.publish(msg);

利用定義好的發佈器對象將消息數據發佈出去,這一句執行後,ROS網絡中的其餘節點即可以收到此消息中的數據。

 

ros::spinOnce();

這一句是讓回調函數有機會被執行的聲明,這個程序裏面並無回調函數,因此這一句能夠不要,這裏只是爲了程序的完整規範性才放上來的。

 

loop_rate.sleep();

前面講過,這一句是經過休眠來控制自循環的頻率的。

 

接着,介紹訂閱節點subscribe_node.cpp,代碼內容以下:

 

 1 #include "ros/ros.h" 
 2 #include "std_msgs/String.h" 
 3 
 4 void chatterCallback(const std_msgs::String::ConstPtr& msg)
 5 {
 6   ROS_INFO("I heard: [%s]",msg->data.c_str());
 7 }
 8 
 9 int main(int argc, char **argv) 
10 {
11   ros::init(argc, argv, "subscribe_node");
12   ros::NodeHandle nh;
13 
14   ros::Subscriber chatter_sub = nh.subscribe("chatter", 1000,chatterCallback);
15 
16   ros::spin();
17 
18   return 0;
19 }

對訂閱節點代碼進行解析。

以前解釋過的相似的代碼就不作過多的解釋了,這裏重點解釋一下前面沒遇到過的代碼。

void chatterCallback(const std_msgs::String::ConstPtr& msg)

{

  ROS_INFO("I heard: [%s]",msg->data.c_str());

}

這是一個回調函數,當有消息到達chatter話題時會自動被調用一次,這個回調函數裏面就是一句話,用來打印從話題中訂閱的消息數據。

 

ros::Subscriber chatter_sub = nh.subscribe("chatter", 1000,chatterCallback);

這句話告訴ros節點管理器咱們將會從chatter這個話題中訂閱消息,當有消息到達時會自動調用這裏指定的chatterCallback回調函數。這裏的參數1000是表示訂閱序列的大小,若是消息處理的速度不夠快,緩衝區中的消息大於1000個的話就會開始丟棄先前接收的消息。

 

ros::spin();

這一句話讓程序進入自循環的掛起狀態,從而讓程序以最好的效率接收消息並調用回調函數。若是沒有消息到達,這句話不會佔用不少CPU資源,因此這句話能夠放心使用。一旦ros::ok()被觸發而返回falseros::spin()的掛起狀態將中止並自動跳出。簡單點說,程序執行到這一句,就在這裏不斷自循環,與此同時檢查是否有消息到達並決定是否調用回調函數。

3)功能包的編譯配置及編譯

建立功能包topic_example時,顯式的指明依賴roscppstd_msgs,依賴會被默認寫到功能包的CMakeLists.txtpackage.xml中,因此只須要在CMakeLists.txt文件的末尾行加入如下幾句用於聲明可執行文件就能夠了:

add_executable(publish_node src/publish_node.cpp)
target_link_libraries(publish_node ${catkin_LIBRARIES})

add_executable(subscribe_node src/subscribe_node.cpp)
target_link_libraries(subscribe_node ${catkin_LIBRARIES})

接下來,就能夠用下面的命令對功能包進行編譯了:

cd ~/catkin_ws/
catkin_make -DCATKIN_WHITELIST_PACKAGES="topic_example"

4)功能包的啓動運行

首先,須要用roscore命令來啓動ROS節點管理器,ROS節點管理器是全部節點運行的基礎。

打開命令行終端,輸入命令:

roscore

而後,用source devel/setup.bash激活catkin_ws工做空間,用rosrun <package_name> <node_name>啓動功能包中的發佈節點。

再打開一個命令行終端,分別輸入命令:

cd ~/catkin_ws/
source devel/setup.bash
rosrun topic_example publish_node 

看到有輸出how are you ...」,就說明發布節點已經正常啓動並開始不斷向chatter話題發佈消息數據,如圖17

(圖17)發佈節點已經正常啓動

最後,用source devel/setup.bash激活catkin_ws工做空間,用rosrun <package_name> <node_name>啓動功能包中的訂閱節點。

再打開一個命令行終端,分別輸入命令:

cd ~/catkin_ws/
source devel/setup.bash
rosrun topic_example subscribe_node 

看到有輸出I heard:[how are you ...]」,就說明訂閱節點已經正常啓動並開始不斷從chatter話題接收消息數據,如圖18

 

(圖18)訂閱節點已經正常啓動

到這裏,咱們編寫的消息發佈器和訂閱器就大功告成了,爲了加深對整個程序工做流程的理解,我再把消息發佈與訂閱的ROS通訊網絡結構圖拿出來,加深一下理解。

 

19消息發佈與訂閱ROS通訊網絡結構圖

後記                 

------SLAM+語音機器人DIY系列【目錄】快速導覽------

第1章:Linux基礎

1.Linux簡介

2.安裝Linux發行版ubuntu系統

3.Linux命令行基礎操做

第2章:ROS入門

1.ROS是什麼

2.ROS系統總體架構

3.在ubuntu16.04中安裝ROS kinetic

4.如何編寫ROS的第一個程序hello_world

5.編寫簡單的消息發佈器和訂閱器

6.編寫簡單的service和client

7.理解tf的原理

8.理解roslaunch在大型項目中的做用

9.熟練使用rviz

10.在實際機器人上運行ROS高級功能預覽

第3章:感知與大腦

1.ydlidar-x4激光雷達

2.帶自校準九軸數據融合IMU慣性傳感器

3.輪式里程計與運動控制

4.音響麥克風與攝像頭

5.機器人大腦嵌入式主板性能對比

6.作一個能走路和對話的機器人

第4章:差分底盤設計

1.stm32主控硬件設計

2.stm32主控軟件設計

3.底盤通訊協議

4.底盤ROS驅動開發

5.底盤PID控制參數整定

6.底盤裏程計標

第5章:樹莓派3開發環境搭建

1.安裝系統ubuntu_mate_16.04

2.安裝ros-kinetic

3.裝機後一些實用軟件安裝和系統設置

4.PC端與robot端ROS網絡通訊

5.Android手機端與robot端ROS網絡通訊

6.樹莓派USB與tty串口號綁定

7.開機自啓動ROS節點

第6章:SLAM建圖與自主避障導航

1.在機器人上使用傳感器

2.google-cartographer機器人SLAM建圖

3.ros-navigation機器人自主避障導航

4.多目標點導航及任務調度

5.機器人巡航與現場監控

第7章:語音交互與天然語言處理

1.語音交互相關技術

2.機器人語音交互實現

3.天然語言處理雲計算引擎

第8章:高階拓展

1.miiboo機器人安卓手機APP開發

2.centos7下部署Django(nginx+uwsgi+django+python3)

----------------文章將持續更新,敬請關注-----------------

 

若是你們對博文的相關類容感興趣,或有什麼技術疑問,歡迎加入下面的《SLAM+語音機器人DIY》QQ技術交流羣,一塊兒討論學習^_^

關於咱們:

視頻教程:

 

https://www.bilibili.com/video/av61448040

相關文章
相關標籤/搜索