iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0

前言

昨天我們介紹了建置 Publisher 的寫法,但除了 Publisher 之外我們還需要一個 Subscriber 才能夠完成 data 的交流,因此今天將介紹以 Python 撰寫 Subscriber 的方法,並實際執行這兩個 Node,以下進入正題:

使用 Python 撰寫 Subscriber

同樣的,在 beginner_tutorial/src/ 當中建立新檔案 listener.py

roscd beginner_tutorial/src/
touch talker.py

並輸入以下程式碼:

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
  rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
  
def listener():

  # In ROS, nodes are uniquely named. If two nodes with the same
  # name are launched, the previous one is kicked off. The
  # anonymous=True flag means that rospy will choose a unique
  # name for our 'listener' node so that multiple listeners can
  # run simultaneously.
  
  rospy.init_node('listener', anonymous=True)
  rospy.Subscriber("chatter", String, callback)
  
  # spin() simply keeps python from exiting until this node is stopped
  rospy.spin()
  
if __name__ == '__main__':
listener()

詳細解析一下程式碼:在此與 Publisher 重複的部分就省略了。

def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)

第1行定義了 callback(data) 這個函式,每當接收到 data 時,就執行下一行的 rospy. rospy.loginfo()rospy.get_caller_id 就是找出發佈訊息到主題的 Node名稱。

def listener():

  # In ROS, nodes are uniquely named. If two nodes with the same
  # name are launched, the previous one is kicked off. The
  # anonymous=True flag means that rospy will choose a unique
  # name for our 'listener' node so that multiple listeners can
  # run simultaneously.
  
  rospy.init_node('listener', anonymous=True)
  rospy.Subscriber("chatter", String, callback)

第一行為定義 listener 這個函式,基本上註釋的部分就是昨天介紹 Publisher 時所提到的 anonymous 的功用,這邊就不再重複解釋。
最後一行 rospy.Subscriber 與 Publisher 當中的 rospy.Publisher 很類似,但這邊原函式定義為 rospy.Subscriber(topic_name, msg_type, function_name),表示該 Node 訂閱了名稱為 [topic_name] 的 Topic,格式為 [msg_type][function_name] 則表示當接收到 Topic 上的 Message 時就呼叫該函式。

  # spin() simply keeps python from exiting until this node is stopped
  rospy.spin()

第二行為直到我們將 Node 關閉前,避免 Node 被系統關閉掉,也就是說讓 listener 這個 Node 可以持續訂閱 Topic。

以上就是使用 Python 撰寫 Subscriber 的方法,接著,讓我們來實際執行自己所撰寫的 Publisher 與 Subscriber 吧!

執行 Publisher 與 Subscriber

為了方便起見,讓我們先更改 talker.pylistener.py 的權限:

chmod +x talker.py
chmod +x listener.py

首先開啟 roscore,並且執行 talker.pylistener.py
https://ithelp.ithome.com.tw/upload/images/20200927/20129807Cvh6qwOpFK.png
再來我們就來看看 Topic 的詳細資訊,使用 rostopic list 確認 Topic 名稱,並以 rostopic info [topic_name] 查看有哪些 Nodes 發布或訂閱這個 Topic:
https://ithelp.ithome.com.tw/upload/images/20200927/20129807Ag0AxmL3pX.png

可以看到我們所建立的 Publisher 以及 Subscriber 中有我們所建立的 talker 與 listener,而其後的亂數就是當初設定 anonymous=True 時所產生,避免有相同名稱的 Node 被建立;若設定 anonymous=False 則只會顯示 talker 與 listener。

最後我們再利用 rqt_graph 來清楚顯示當前的 ROS 架構:
https://ithelp.ithome.com.tw/upload/images/20200927/20129807pdR0SJ0T81.png

結語

這兩天介紹了 Publisher 以及 Subscriber 的撰寫與執行,基本上在撰寫 Publisher 與 Subscriber 時最關鍵的就是掌握 rospy.Publisher()rospy.Subscriber() 的用法,以及根據需求引用相關模組 (rospy、 time、 math等等)、 設定 rospy.Rate() 等等參數以及釐清 Node 應該傳送什麼樣的 Message 與其格式。
經過這幾天對ROS基礎架構的詳細說明,相信大家都有理解了吧,沒有理解的話就再多看幾遍又會懂了XD。接著會大致介紹ROS架構中的 Serivces 和 Parameters ,詳細內容就請期待明天的文章吧。大家明天見~
https://ithelp.ithome.com.tw/upload/images/20200927/20129807sDN92hXKfH.png


上一篇
[DAY 11] Publisher && subscriber 的應用 1
下一篇
[DAY 13] ROS Services & Parameters 的介紹
系列文
ROS系統控制自走車搭配點雲雷達(隧道檢測裝置)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言