使用 <remap> 標籤可以對一個名稱進行重新映射 (remapping),有點像是把一個名稱改為另外一個名稱,在某些情況下是很方便的小技巧。舉例來說,有一個節點訂閱或發佈一個主題,但是簡單的透過 <remap> 標籤的設定,就可以讓這個節點實際訂閱或發佈到另外一個主題。
標籤說明
- <remap>
此標籤用來對主題名稱 (Topic Name) 進行重新映射 (remapping),有下列屬性可以使用:
from="original-name" : 原本的名稱,也就是將被重新映射的主題名稱。
to="new-name" : 新的名稱,也就是原本的主題名稱將被重新映射到這個新的名稱。
當你設定了一個從主題 A 到主題 B 的重新映射,若有一個節點訂閱主題 A,則它實際上會訂閱到主題 B。所以,若任何節點發佈訊息到主題 B,則訊息也會傳送到自認為訂閱主題 A 的節點。
注意事項:
- 此 <remap> 標籤的設定只對宣告在其後的節點發生作用,對宣告在其之前的節點沒有效果。
- 若 <remap> 標籤嵌在 <group> 或 <node> 標籤內,則此 <remap> 標籤僅在該 <group> 或 <node> 標籤範圍內有作用。
實例說明
在 mypackage 套件裡面的 launch 目錄,新增一個簡單的 launch 文件來做測試。另外,在 script 目錄則是新增兩個簡短的 Python 程式,一個節點作為訂閱者,一個節點作為發佈者。
下面兩個 Python 程式:listener.py 和 talker.py,取自官網的範例《Writing a Simple Publisher and Subscriber (Python)》。並且,把 listener.py 訂閱的主題改為 chatter1,talker.py 發佈的主題改為 chatter2。然後在 launch 文件中,透過 <remap> 標籤將 chatter1 重新映射為 chatter2。
-- listener.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("chatter1", String, callback)
# spin() simply keeps python from exiting until this node is stopped rospy.spin()
if __name__ == '__main__': listener() |
-- talker.py
#!/usr/bin/env python # license removed for brevity import rospy from std_msgs.msg import String
def talker(): pub = rospy.Publisher('chatter2', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz while not rospy.is_shutdown(): hello_str = "hello world %s" % rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep()
if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass |
-- remap.launch
<launch> <remap from="chatter1" to="chatter2" /> <node pkg="mypackage" type="listener.py" name="listener" output="screen" /> <node pkg="mypackage" type="talker.py" name="talker" output="screen" /> </launch> |
執行 roslaunch mypackage remap.launch 之後,可以看到螢幕顯示如下訊息:
[INFO] [1604371890.720107]: hello world 1604371890.72
[INFO] [1604371890.721206]: /listenerI heard hello world 1604371890.72
[INFO] [1604371890.820239]: hello world 1604371890.82
[INFO] [1604371890.821398]: /listenerI heard hello world 1604371890.82
[INFO] [1604371890.920269]: hello world 1604371890.92
表示 listener 雖然訂閱 chatter1,但是可以接收到 talker 發佈到 chatter2 的訊息,這是因為 <remap> 標籤將 chatter1 重新映射到 chatter2 的關係。
如果使用 rostopic list 指令查看,就會發現沒有名為 chatter1 的主題,只有名為 chatter2 的主題。若是把 <remap> 標籤拿掉,則 chatter1 和 chatter2 兩個主題都會出現,但此時 listener 就無法接收到 talker 發佈的訊息了。
參考資料
- roslaunch: <remap> tag
http://wiki.ros.org/roslaunch/XML/remap
- Writing a Simple Publisher and Subscriber (Python)
http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28python%29
沒有留言:
張貼留言