1. 程式人生 > >ROS基礎內容2--通訊方式之Topic以及node、topic和message的關係

ROS基礎內容2--通訊方式之Topic以及node、topic和message的關係

本文參考了ROS_Kinetic_05 ROS基礎內容,在本人的計算機環境ubuntu16.04 64bit+kinetic基礎上進行實踐。

1. ROS節點node的基本概念和操作

涉及到的基本概念:

Nodes:節點,一個節點即為一個可執行檔案,節點之間通過ROS這個系統進行通訊。
Messages:訊息,訊息是一種ROS資料型別,用於主題的訂閱或釋出。
Topics:主題,節點可以釋出訊息到主題,也可以訂閱某些主題以接收這些主題的訊息。
Master:節點管理器,ROS名稱服務。(在ROS2中取消了Master節點)
rosout: ROS中相當於stdout/stderr。
roscore: 主機+ rosout + 引數伺服器。
rospy = python 客戶端庫
roscpp = c++ 客戶端庫

節點是ROS中最重要的概念之一。每個ROS執行例項被稱為節點。換句話說,每個ROS程式執行的程序,就是一個節點。每個機器人程式,可以有非常多個節點。我們也可以運行同一個程式的多個副本(但要確保每個副本使用不同節點名),則每個副本都被當作一個獨立節點。

節點(Node)可以用來提供某種資料或能力,比如讀取某Sensor資料。也可以是一個獲取這些資料並處理的節點(Node),例如從別的節點那拿到Sensor並處理。但他們之間如何知道對方存在與否呢?哪些node需要哪種資料呢?這就需要有個管理者,它就是NodeMaster/ Node Core。每個Node啟動時,需要向它註冊,申明自己提供什麼服務或需要什麼資料。

Node是ROS package中一個可執行檔案。ROS node利用ROS使用者庫去和其他node進行通訊。nodes也可以向topic發起釋出或者訂閱,nodes也可以提供或者使用一個service.

為何說Node是ROS核心,看看它通常被用來做什麼:

控制電機速度,獲取鐳射雷達資料,獲取Camera資料,利用以上資料定位,路徑規劃。

啟動一個Node

#rosrun package-name executable-name

兩個引數,引數1:功能包名。 引數2:可執行檔名。(見後面的例子)

檢視當前有哪些Node

#rosnode list

停止一個Node:

#rosnode kill node-name

雖然也可以ctrl-c停止,但此時Node master 可能會沒有及時登出此node.造成誤會。(當然這種情況可以:rosnode cleanup)

檢視當前執行的node的資訊:

#rosnode info Node_Name

--------------------------------------------------------------------------------------------------------------------------------------

1.1 例項

下面是一個執行node的例子

首先在一個terminal上啟動ros

~$ roscore

在另一個terminal上啟動一個turtlesim模擬器並啟動一個turtlesim_node節點

~$ rosrun turtlesim turtlesim_node

在另一個terminal上檢視節點列表

~$ rosnode list

如下圖所示:


此時只有rosout和turtlesim節點這兩個,其中turtlesim就是通過turtlesim啟動的那個節點,預設名字與模擬器相同。下面我們再啟動一個terminal並啟動一個turtlesim節點,並給它起個名字:

~$ rosrun turtlesim turtlesim_node __name:=kinetic_turtle


然後我們再用rosnode list命令檢視,發現多了一個叫kinetic_turtle節點。

如果啟動兩個同名的node,如下圖的test1,則也會只保留一個,第一個建立的會被強制關閉:


使用rosnode ping nodename可以測試能否ping通某個節點,


刪除節點:~$ rosnode kill nodename


~$ rosnode cleanup

關閉turtlesim_node,請按下“Ctrl-C” 。

檢視節點資訊:


這裡可以看到節點訂閱和釋出的訊息的型別。

-------------------------------------------------------------------------------------------------------------------------------------------

2. ROS中的主題topic

在開始topic相關討論之前,我們先看通過turtlesim中的那個turtlesim(小海龜)的例子來了解一下ros中的topic是怎麼一回事。

2.1 例項

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

(1)啟動小烏龜turtle

ROS的資料中提到一隻虛擬小烏龜:turtle,關於它的例子也十分簡單,比如啟動它

~$ roscore

在另一個terminal中啟動一個turtle節點

~$ rosrun turtlesim turtlesim_node

另開啟一個ternimal標籤

~$ rosrun turtlesim turtle_teleop_key

將會得到藍色背景下隨機的一直小烏龜,並且可以使用方向鍵控制移動,但是turtle_teleop_key的節點系統裡是沒有原始碼的,只有一個能夠直接執行的檔案.

這裡寫圖片描述

另起一個terminal,開啟節點圖可以更直觀地看到這兩個節點間傳遞訊息的主題

~$ rqt_graph

這裡寫圖片描述

顯然,/teleop_turtle這個節點單向傳遞速度的控制資訊給turtlesim節點, 那麼完全可以按照程式的意願使小烏龜的執行處於離線執行狀態.

Node之間,是通過Message來傳遞訊息的,每個Message就是一個數據結構,如geonetry_msgs/Twist.msg.

 ROS學習 <wbr><二> <wbr>ROS基本概念

換句話說自己寫一個可釋出/turtle1/cmd_vel的程式.

我們必須知道/turtle1/cmd_vel裡釋出的msg是什麼樣的,執行如下命令,檢視傳遞的訊息:

~$ rostopic type /turtle1/cmd_vel | rosmsg show

geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z


可以看到msg為geometry_msgs/Vector3,這個訊息的原型在ROS中,/opt/ros/kinetic/share/geometry_msgs/Vector3 ,內容為

float64 x

float64 y

float64 z

(2)簡單的自轉

那麼接下來自己寫一個node,釋出它們就可以了.

在catkin中建立一個package,如toldturtle,並建立一個node.(下面標註的紅色的toldturtle和talk,也可以改成其他名稱,只要保證一致即可)

~$ cd ~/catkin_ws/src/

~$ catkin_create_pkg toldturtle roscpp std_msgs geometry_msgs

在該package的src下建立一個名為talk.cpp的node.

#include <ros/ros.h>#include <geometry_msgs/Twist.h>ros::Publisher cmdVelPub;int main(int argc, char **argv){ ros::init(argc, argv, "talk"); //"talk"必須是nodename std::string topic = "/turtle1/cmd_vel"; //topic name ros::NodeHandle n; cmdVelPub = n.advertise<geometry_msgs::Twist>(topic, 1); //第一個引數也可以寫成"/turtle1/cmd_vel"這樣的topic name //第二個引數是釋出的緩衝區大小,<geometry_msgs::Twist>是訊息型別 ros::Rate loopRate(2); //與Rate::sleep();配合指定自迴圈頻率 ROS_INFO("talk cpp start...");//輸出顯示資訊 geometry_msgs::Twist speed; // 控制訊號載體 Twist message while (ros::ok()){ speed.linear.x = 1; // 設定線速度為1m/s,正為前進,負為後退 speed.angular.z = 1; // 設定角速度為1rad/s,正為左轉,負為右轉 cmdVelPub.publish(speed); // 將剛才設定的指令傳送給機器人 ros::spinOnce(); loopRate.sleep();//按loopRate(2)設定的2HZ將程式掛起 } return 0;}

並且修改cmake程式碼,讓編譯系統明白如何編譯,這裡我的package為toldturtle,node為talk.cpp:

cmake_minimum_required(VERSION 2.8.3)project(toldturtle)find_package(catkin REQUIRED COMPONENTS geometry_msgs roscpp rospy std_msgs)catkin_package( CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs)include_directories( ${catkin_INCLUDE_DIRS})## Declare a C++ executable add_executable(talk src/talk.cpp)## Specify libraries to link a library or executable target against target_link_libraries(talk ${catkin_LIBRARIES} )

這樣在terminal裡編譯下整個catkin的package

~$ cd ~/catkin_ws/

~$ catkin_make

如果編譯成功,就可以看到提示了.


(3)效果

在終端執行寫的node

~$ rosrun toldturtle talk


此時,我們檢視ros中的節點,


這樣就通過編寫一個talk,來實現在ros中對turtle的控制.

此時,turtle也受前面的teleop_turtle控制,我們仍然可以通過鍵盤上的箭頭控制小烏龜,只不過它目前受兩個控制,在鍵盤箭頭控制的同時,仍然受talk的控制進行畫圓,即可以用方向鍵控制自旋轉的turtle.


此時檢視節點之間的關係,我們發現talk和teleop_turtle都可以傳遞訊息給turtlesim。


通過這個例子,結合訂閱/釋出訊息機制,我們可以認為turtlesim節點訂閱了turtle1/cmd_vel這個主題,而只要某個節點發布了這個主題的訊息,turtlesim節點都能接受並根據傳過來的訊息內容(即geometry_msgs/Vector3)更新烏龜的位置。

關於烏龜控制的例子,我們參考了:http://blog.csdn.net/under_maple/article/details/49430765

(4)通過rostopic命令釋出topic訊息來控制小烏龜

除了上面的方式,寫一個package來實現對小烏龜的控制外,還有更方面的一種方式來實現對小烏龜的控制,就是在命令列裡,藉助rostopic命令,釋出一條小烏龜控制所需要的訊息

rostopic pub [topic] [msg_type] [args

~$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'

publishing and latching message for 3.0 seconds

上面的命令告訴小海龜按照線速度2角速度1.8進行移動,時間為3s,如下圖所示(忘記截圖了,此圖來源於http://blog.csdn.net/bobsweetie/article/details/43638797):

小烏龜移動3s後停止了,我們可以用rostopic pub -r命令釋出一個穩定的命令流。

~$ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]


~$ rostopic hz /turtle1/pose

subscribed to [/turtle1/pose]
average rate: 124.817
    min: 0.006s max: 0.010s std dev: 0.00141s window: 118
average rate: 125.015
    min: 0.006s max: 0.010s std dev: 0.00142s window: 243
average rate: 124.968
    min: 0.006s max: 0.010s std dev: 0.00142s window: 368
average rate: 125.009
    min: 0.006s max: 0.010s std dev: 0.00141s window: 493

~$ rostopic type /turtle1/cmd_vel | rosmsg show

~$ rosrun rqt_plot rqt_plot

rostopic命令相關的內容,可以參考:http://blog.csdn.net/bobsweetie/article/details/43638797

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2.2 ROS中的topic的理解(三種主要通訊方式中的一種)

下面我們正式開始ros中的topic主題部分的理解。

ROS Node之間通訊方式主要依靠的就是主題(Topic)和服務(Service), 引數(parameter) 三種Message就是放在Topic中。這裡需要注意,Topic只是ROS中的一種通訊方式,而不是唯一的通訊方式。

 Message傳遞的的理念

當一個節點想要分享資訊時,它就會發布(publish)訊息到對應的一個或多個Topic(主題);當一個節點想要接收訊息時,它就會訂閱(Subscribe)它所需要的一個或多個Topic。

ROS Topic: 

主題是由ROS網路對訊息進行路由,對訊息進行管理的資料匯流排。每一條訊息都要釋出到相應的主題上。當一個節點發送資料時,我們就說這個節點向某個主題釋出了訊息。

節點可以通過訂閱某個主題,接受別的節點發布的訊息。

ROS Master負責確保釋出主題的Node和訂閱主題的Node能找到對方。而Message是直接從釋出Node傳遞到訂閱Node.並不需要經過Node Master。

A:訊息以一種publish/subscribe的方式傳遞。

B:節點可以在給定的主題中釋出/訂閱訊息。

C:一個節點可以訂閱/釋出多個不同主題。

D:允許多個Node訂閱/釋出同一個主題。

E:訂閱節點和釋出節點並不知道相互之間的存在。

 Message註冊和訂閱過程:

ROS學習 <wbr><二> <wbr>ROS基本概念

Talker這個Node,啟動後註冊了一個Topic,名為bar, 並告知Node Master,接收埠為:1234。

Listener這個Node啟動後訂閱了一個Topic,名為bar.

Node Master告知Listener,主題的埠為1234。

Listener去連線1234埠,Talker監聽到有人連線。就告知對方,資料介面是2345。

於是兩個Node就連通起來了。

同一個時刻,只有一個Node Master。所以可以共享資料。

ROS學習 <wbr><二> <wbr>ROS基本概念

我們繼續用上面的程式來檢視Topic.

#roscore

#rosrun turtlesim turtlesim_node

#rosrun turtlesim turtlesim_node __name:=turtle2

#rosrun turtlesim turtle_teleop_key

1. 運行了roscore,

2. 運行了turtlesim包內的turtlesim_node這node兩次,使用不同的node_Name.

3. 運行了turtlesim包內的turtle_teleop_key.

turtlesim_node和turtle_teleop_keynode之間用topic交流通訊.

turtle_teleop_key在這個topic上釋出按鍵敲擊,而turtlesim訂閱同樣的topic接受按鍵敲擊.

可以使用視覺化工具檢視Topic的資料傳輸。

#rosrun rqt_graph rqt_graph

圖示:

這個和我們原來研究的zeromq差不錯,都是基於訂閱/釋出模式的訊息傳遞機制。

3. 總結

要理解ROS topics、ROS nodes、ROS Messages之間的關係。目前個人的理解是:ROS topics是ROS nodes之間進行通訊的樞紐,ROS messages是ROS nodes訂閱和釋出資料的載體。兩個ROS nodes欲實現通訊,則其中一個節點向ROS topic釋出ROS messages,另一節點則通過訂閱此topic來接收messages,兩者的message型別一定要相同,而message的型別由主題確定,通過rostopic type命令可以檢視topic的資料型別。

然後就是輔助檢視ROS中節點關係和資料的工具:rqt_graph和rqt_plot,兩者都是針對ROS型別的,其中rqt_graph工具會自動搜尋系統中正在執行的節點和主題,並動態繪製出關系圖,rqt_plot則是繪製釋出到topic上的資料的圖形,因此兩者使用的前提是有ROS的程序在執行。

執行節點:roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
檢視節點關係圖:rosrun rqt_graph rqt_graph

顯示topic1上所釋出的資料:rostopic echo topic1
列出當前處於啟用狀態的topic列表:rostopic list -v
顯示topic1的資料型別:rostopic type topic1
顯示型別更加詳細的資訊:rosmsg show type1
直接向主題topic1釋出資料:rostopic pub [topic1] [msg_type] [args]
顯示主題topic1上資料的釋出速率:rostopic hz [topic1]

相關推薦

ROS基礎內容2--通訊方式Topic以及nodetopicmessage關係

本文參考了ROS_Kinetic_05 ROS基礎內容,在本人的計算機環境ubuntu16.04 64bit+kinetic基礎上進行實踐。1. ROS節點node的基本概念和操作涉及到的基本概念:Nodes:節點,一個節點即為一個可執行檔案,節點之間通過ROS這個系統進行通

ubuntu16.04下ROS作業系統學習(四 / 三)ROS基礎-實現分散式通訊

ROS是分散式的節點,這樣的話我們就可以將程式執行上的節點放到大型機器上面,分擔機器人執行的壓力。接下來我們來看一下怎麼實現分散式通訊,怎麼在多機上執行統一的程式。 ROS是一種分散式軟體框架,節點之間通過鬆耦合的方式進行組合。 那麼我們如何來實現分散式多機通訊呢: 設定IP地址,

React】歸納篇(十)元件間通訊方式Redux | UI元件AntDesign | Redux-react

react-router4 react-router概覽 1、react的一個外掛庫 2、專門用於實現一個SPA應用 3、基於react的專案都會用到該庫 SPA 1、點選頁面中的連結不會重新整理頁面,本身也不會向伺服器傳送請求 2、點選路由連結時,只會發

系統間通訊方式(ActiveMQ的使用效能優化冰火兩重天5)(十六)

7、ActiveMQ的持久訊息儲存方案 前文已經講過,當ActiveMQ接收到PERSISTENT Message訊息後就需要藉助持久化方案來完成PERSISTENT Message的儲存。這個介質可以是磁碟檔案系統、可以是ActiveMQ的內建資料庫,還可以是某種外部提供的關係型資料庫。本節筆者將向讀

系統間通訊方式(ActiveMQ的叢集方案介紹結束)(十八)

3、ActiveMQ熱備方案 ActiveMQ熱備方案,主要保證ActiveMQ的高可用性。這種方案並不像上節中我們主要討論的ActiveMQ高效能方案那樣,同時有多個節點都處於工作狀態,也就是說這種方案並不提高ActiveMQ叢集的效能;而是從叢集中的多個節點選擇一個,讓其處於工作狀態,叢集中其它節點

系統間通訊方式(Kafka的實際使用場景使用方案)(二十三)

5、場景應用——電商平臺:瀏覽記錄收集功能 事件/日誌收集系統是大中型軟體不得不面對的話題。目前第三方業務系統對 事件/日誌收集系統 的整合思路主要有兩大類:侵入式收集方案和非侵入式收集方案。侵入式收集方案,是指任何需要使用事件/日誌收集系統的第三方系統,都需要做有針對的編碼工作,這個編碼工作或

IPC通訊方式LocalSocket

人生有八苦:生,老,病,死,愛別離,怨長久,求不得,放不下。 LocalSocket是什麼 在弄清LocalSocket是什麼之前,有必要先了解下Socket是什麼。Socket通常翻譯為套接字,它是為了方便讓兩臺機器能互相通訊的一套技術,該套

系統間通訊方式(RPC的基本概念)(十)

1、概述 經過了詳細的資訊格式、網路IO模型的講解,並且通過JAVA RMI的講解進行了預熱。從這篇文章開始我們將進入這個系列博文的另一個重點知識體系的講解:RPC。在後續的幾篇文章中,我們首先講解RPC的基本概念,一個具體的RPC實現會有哪些基本要素構成,然後我們詳細介紹一款典型的RPC框架:Apac

系統間通訊方式(JavaRMI初步使用詳解)(八)

1、概述 在概述了資料描述格式的基本知識、IO通訊模型的基本知識後。我們終於可以進入這個系列博文的重點:系統間通訊管理。在這個章節我將通過對RMI的詳細介紹,引出一個重要的系統間通訊的管理規範RPC,並且繼續討論一些RPC的實現;再通過分析PRC的技術特點,引出另一種系統間通訊的管理規範ESB,並介紹E

Linux下程序間通訊方式管道訊號共享記憶體訊息佇列訊號量套接字

/* 1,程序間通訊 (IPC ) Inter-Process Communication   比較好理解概念的就是程序間通訊就是在不同程序之間傳播或交換資訊。 2,linux下IPC機制的分類:管道、訊號、共享記憶體、訊息佇列、訊號量、套接字 3,這篇主要說說管

JS基礎5-流程控制語句條件(ifswitch)

float font 標準 先生 oda AD ida tel 周四 一、if語句 正如中文翻譯一樣,如果...則...。 <script type="text/javascript"> //只有兩種情況下 if(條件){ 要執行的語

c#基礎學習(0724)可變參數refout

col ram test 不為 外部 rri money 改變 end params可變參數,無論有幾個參數,必須出現在參數列表的最後,可以為可變參數直接傳遞一個對應類型的數組 #region 可變參數 //1.如果方法有多個參數,可變參數可以作為最後一個參數 //2.可

angular2 2方式----獲取子元件的類屬性類方法

1)-------方法-----父html檔案<button (click)="onclickchildfun()">通過@ViewChild呼叫子元件方法</button>----父tsimport { Component, OnInit, ViewChild } from '@an

Java基礎知識回顧四 ----- 集合ListMapSet

linked 訪問速度 因此 比較 foreach循環 代碼示例 的區別 不同的 寫法 前言 在上一篇中回顧了Java的三大特性:封裝、繼承和多態。本篇則來介紹下集合。 集合介紹 我們在進行Java程序開發的時候,除了最常用的基礎數據類型和String對象外,也經常會用到集

Linux程序間通訊訊號量(semaphore)訊息佇列(Message Queue)共享記憶體(Share Memory)

System V 程序通訊方式:訊號量(semaphore)、訊息佇列(Message Queue)和共享記憶體(Share Memory) 訊號量 訊號量(semaphore)實際是一個整數,它的值由多個程序進行測試(test)和設定(set)。就每個程序所關心的測試和

HTTP提交方式PUT詳細介紹及POSTPUT的區別

POST是用來提交資料的。提交的資料放在HTTP請求的正文裡,目的在於提交資料並用於伺服器端的儲存,而不允許使用者過多的更改相應資料(主要是相對於在url 修改要麻煩很多)。PUT操作是冪等的。所謂冪等是指不管進行多少次操作,結果都一樣。比如我用PUT修改一篇文章,然後在做同

Unity/C#基礎複習(5) 淺析觀察者中介者模式在遊戲中的應用與delegate原理

參考資料 【1】 《Unity 3D指令碼程式設計 使用C#語言開發跨平臺遊戲》陳嘉棟著 【2】 @張子陽【C#中的委託和事件 - Part.1】 http://www.tracefact.net/tech/009.html 【3】 @張子陽【C#中的委託和事件 - Part.2】 http://www.t

Linux學習使用者切換su su - exit的不同

Linux命令列下切換使用者: su username su - username 還可以用exit退出,再次登入,例 [[email protected] pratice]$ su - root Password: Last login: Thu Aug 23 08

走進以太坊技術路:瓶頸困境方案

一、以太坊目前存在的技術瓶頸 以太坊網路目前存在的主要問題是:可擴充套件性、智慧合約的安全性、共識協議與隱私性。 1. 可擴充套件性困境 2017年的以太坊養貓遊戲中,佔到整個以太坊16%的交易量,導致以太坊網路大面積擁堵。網路擁堵問題暴露出了以太坊區塊鏈亟需擴容的現狀。以太坊被設計成為一個

整合學習boosting,AdaboostGBDT xgboost(二)

AdaBoost 演算法的訓練誤差分析 AdaBoost最基本的性質是它能在學習過程中不斷減少訓練誤差,即在訓練資料集上的分類誤差率。 定理:AdaBoost的訓練誤差界: 1