話題的釋出與訂閱
阿新 • • 發佈:2019-01-27
用RoboWare Studio建立好工作區和package後,在src下新建兩個cpp檔案,一個做話題的釋出者,另一個做話題的訂閱者,然後編譯下就可以測試運行了,不過RoboWare只能除錯執行一個節點,另一個可以用自帶的整合終端(ctrl+`)或者新開一個終端執行,當然也可以寫一個launch啟動檔案。
釋出者:
//ros/ros.h是一個實用的標頭檔案,它引用了ROS系統中大部分常用的標頭檔案 #include "ros/ros.h" //std_msgs/String存放在std_msgs package裡,由String.msg檔案自動生成的標頭檔案 #include "std_msgs/String.h" #include <sstream> int main(int argc, char **argv) { //初始化ROS,注意:名稱必須唯一 ros::init(argc,argv,"example1_a"); //設定節點程序控制代碼 ros::NodeHandle n; //告訴master我們將要在message topic上釋出一個std_msgs/String的訊息 //引數一為釋出的話題的名稱; //引數二為緩衝區大小,如果我們釋出的訊息太快,緩衝區中的訊息在大於1000個的時候就會開始丟棄先前釋出的訊息 //NodeHandle::advertise() 返回一個 ros::Publisher物件,它有兩個作用: //1) 它有一個publish()成員函式可以讓你在topic上釋出訊息; 2) 如果訊息型別不對,它會拒絕釋出 ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message",1000); //設定傳送頻率10Hz //ros::Rate物件可以允許你指定自迴圈的頻率,自上一次呼叫Rate::sleep()後時間的流逝,並休眠直到一個頻率週期的時間 ros::Rate loop_rate(10); //ros::ok()返回false,如果下列條件之一發生: //1、SIGINT接收到(Ctrl-C) //2、被另一同名節點踢出ROS網路 //3、ros::shutdown()被程式的另一部分呼叫 //4、所有的ros::NodeHandles都已經被銷燬 while(ros::ok()) { //建立訊息變數 std_msgs::String msg; std::stringstream ss; ss << "Talker node sending message!"; msg.data=ss.str(); //ROS_INFO("%s",msg.data.c_str()); 類似printf,輸出檢驗 //釋出訊息 chatter_pub.publish(msg); //如果出現一個訂閱者,ROS就會更新並讀取所有主題 //ROS訊息回撥處理函式ros::spin() 和 ros::spinOnce(),兩者區別在於 //前者呼叫後不會再返回,也就是你的主程式到這兒就不往下執行了,而後者在呼叫後還可以繼續執行之後的程式 ros::spinOnce(); //休眠 loop_rate.sleep(); } return 0; }
訂閱者:
#include "ros/ros.h" //ros/ros.h是一個實用的標頭檔案,它引用了ROS系統中大部分常用的標頭檔案 #include "std_msgs/String.h" //std_msgs/String存放在std_msgs package裡,由String.msg檔案自動生成的標頭檔案 //回撥函式,當message topic訊息到達後會呼叫此函式 void sub_callback(const std_msgs::String::ConstPtr& msg) { ROS_INFO("I hear: [%s]",msg->data.c_str()); } int main(int argc, char **argv) { //初始化ROS,注意:名稱必須唯一 ros::init(argc, argv, "example1_b"); //設定節點程序控制代碼 ros::NodeHandle n; //引數一為訂閱的話題名稱(message); //引數二是訊息快取佇列,這裡設定為1000,即快取了1000個訊息後,如果由新的訊息到達,則開始丟棄先前接收的訊息; //引數三為當收到訊息後呼叫的函式名稱(sub_callback) ros::Subscriber sub = n.subscribe("message", 1000, sub_callback); //ros::spin()進入自迴圈,可以儘可能快的呼叫訊息回撥函式 ros::spin(); return 0; }
launch啟動檔案
<?xml version="1.0"?>
<launch>
<node name = "example1_a" pkg = "chapter2_tutorials" type = "example1_a"/>
<node name = "example1_b" pkg = "chapter2_tutorials" type = "example1_b"/>
</launch>
節點名、package包名字對應自己建立的進行更改,我的工作區東西比較多就不用tree列出來了。
將兩個節點跑起來後,可以在終端輸入rostopic echo /message 來檢視話題釋出的內容(message是我的話題名,可以根據自己的程式碼修改)。
圖1、釋出者
圖2、訂閱者
圖3、工作區結構