# 3.3 Topic
## 3.3.1 簡介
ROS的通信方式是ROS最為核心的概念,ROS系統的精髓就在于它提供的通信架構。ROS的通信方式有以下四種:
* Topic 主題
* Service 服務
* Parameter Service 參數服務器
* Actionlib 動作庫
## 3.3.2 Topic
ROS中的通信方式中,topic是常用的一種。對于實時性、周期性的消息,使用topic來傳輸是最佳的選擇。topic是一種點對點的單向通信方式,這里的“點”指的是node,也就是說node之間可以通過topic方式來傳遞信息。topic要經歷下面幾步的初始化過程:首先,publisher節點和subscriber節點都要到節點管理器進行注冊,然后publisher會發布topic,subscriber在master的指揮下會訂閱該topic,從而建立起sub-pub之間的通信。注意整個過程是單向的。其結構示意圖如下:

Subscriber接收消息會進行處理,一般這個過程叫做**回調(Callback)**。所謂回調就是提前定義好了一個處理函數(寫在代碼中),當有消息來就會觸發這個處理函數,函數會對消息進行處理。
上圖就是ROS的topic通信方式的流程示意圖。topic通信屬于一種異步的通信方式。下面我們通過一個示例來了解下如何使用topic通信。
## 3.3.3 通信示例
參考下圖,我們以攝像頭畫面的發布、處理、顯示為例講講topic通信的流程。在機器人上的攝像頭拍攝程序是一個node(圓圈表示,我們記作node1),當node1運行啟動之后,它作為一個Publisher就開始發布topic。比如它發布了一個topic(方框表示),叫做`/camera_rgb`,是rgb顏色信息,即采集到的彩色圖像。同時,node2假如是圖像處理程序,它訂閱了`/camera_rgb`這個topic,經過節點管理器的介紹,它就能建立和攝像頭節點(node1)的連接。
那么怎么樣來理解**“異步”**這個概念呢?在node1每發布一次消息之后,就會繼續執行下一個動作,至于消息是什么狀態、被怎樣處理,它不需要了解;而對于node2圖像處理程序,它只管接收和處理`/camera_rgb`上的消息,至于是誰發來的,它不會關心。所以node1、node2兩者都是各司其責,不存在協同工作,我們稱這樣的通信方式是異步的。

ROS是一種分布式的架構,一個topic可以被多個節點同時發布,也可以同時被多個節點接收。比如在這個場景中用戶可以再加入一個圖像顯示的節點,我們在想看看攝像頭節點的畫面,則可以用自己的筆記本連接到機器人上的節點管理器,然后在自己的電腦上啟動圖像顯示節點。
這就體現了分布式系統通信的好處:擴展性好、軟件復用率高。
**總結三點**:
1. topic通信方式是異步的,發送時調用publish()方法,發送完成立即返回,不用等待反饋。
2. subscriber通過回調函數的方式來處理消息。
3. topic可以同時有多個subscribers,也可以同時有多個publishers。ROS中這樣的例子有:/rosout、/tf等等。
## 3.3.4 操作命令
在實際應用中,我們應該熟悉topic的幾種使用命令,下表詳細的列出了各自的命令及其作用。
| 命令 | 作用 |
| :------: | :------: |
| `rostopic list` | 列出當前所有的topic |
| `rostopic info topic_name` | 顯示某個topic的屬性信息 |
| `rostopic echo topic_name` | 顯示某個topic的內容 |
| `rostopic pub topic_name ...` | 向某個topic發布內容|
| `rostopic bw topic_name` | 查看某個topic的帶寬|
| `rostopic hz topic_name` | 查看某個topic的頻率|
| `rostopic find topic_type` | 查找某個類型的topic|
| `rostopic type topic_name` | 查看某個topic的類型(msg)|
如果你一時忘記了命令的寫法,可以通過`rostopic help`或`rostopic command -h`查看具體用法。
## 3.3.5 測試實例
1. 首先打開`ROS-Academy-for-Beginners`的模擬場景,輸入`roslaunch robot_sim_demo robot_spawn_launch`,看到我們仿真的模擬環境。該`launch`文件啟動了模擬場景、機器人。
2. 查看當前模擬器中存在的topic,輸入命令`rostopic list`。可以看到許多topic,它們可以視為模擬器與外界交互的接口。
3. 查詢topic`/camera/rgb/image_raw`的相關信息:`rostopic info /camera/rgb/image_raw`。則會顯示類型信息type,發布者和訂閱者的信息。
4. 上步我們在演示中可以得知,并沒有訂閱者訂閱該主題,我們指定`image_view`來接收這個消息,運行命令`rosrun image_view image_view image:=<image topic> [transport]`。我們可以看到message,即是上一步中的type。
5. 同理我們可以查詢攝像頭的深度信息depth圖像。
6. 在用鍵盤控制仿真機器人運動的時候,我們可以查看速度指令topic的內容`rostopic echo /cmd_vel` ,可以看到窗口顯示的各種坐標參數在不斷的變化。
通過這些實例的測試,幫助我們更快的掌握topic各種操作命令的使用,以及對topic通信的理解。
##小結
topic的通信方式是ROS中比較常見的單向異步通信方式,它在很多時候的通信是比較易用且高效的。但是有些需要交互的通信時該方式就顯露出自己的不足之處了,后續我們會介紹雙向同步的通信方式service。
- 前言
- 第一章 ROS簡介
- 機器人時代的到來
- ROS發展歷程
- 什么是ROS
- 安裝ROS
- 安裝ROS-Academy-for-Beginners教學包
- 二進制與源碼包
- 安裝RoboWare Studio
- 單元測試一
- 第二章 ROS文件系統
- Catkin編譯系統
- Catkin工作空間
- Package軟件包
- CMakeLists.txt
- package.xml
- Metapacakge軟件元包
- 其他常見文件類型
- 單元測試二
- 第三章 ROS通信架構(一)
- Node & Master
- Launch文件
- Topic
- Msg
- 常見msg類型
- 單元測試三
- 第四章 ROS通信架構(二)
- Service
- Srv
- Parameter server
- Action
- 常見srv類型
- 常見action類型
- 單元測試四
- 第五章 常用工具
- Gazebo
- RViz
- Rqt
- Rosbag
- Rosbridge
- moveit!
- 單元測試五
- 第六章 roscpp
- Client Library與roscpp
- 節點初始、關閉與NodeHandle
- Topic in roscpp
- Service in roscpp
- Param in roscpp
- 時鐘
- 日志與異常
- 第七章 rospy
- Rospy與主要接口
- Topic in rospy
- Service in rospy
- Param與Time
- 第八章 TF與URDF
- 認識TF
- TF消息
- tf in c++
- tf in python
- 統一機器人描述格式
- 附錄:TF數學基礎
- 三維空間剛體運動---旋轉矩陣
- 三維空間剛體運動---歐拉角
- 三維空間剛體運動---四元數
- 第九章 SLAM
- 地圖
- Gmapping
- Karto
- Hector
- 第十章 Navigation
- Navigation Stack
- move_base
- costmap
- Map_server & Amcl
- 附錄:Navigation工具包說明
- amcl
- local_base_planner
- carrot_planner
- clear_costmap_recovery
- costmap_2d
- dwa_local_planner
- fake_localization
- global_planner
- map_server
- move_base_msg
- move_base
- move_slow_and_clear
- navfn
- nav_core
- robot_pose_ekf
- rotate_recovery