2020年11月3日 星期二

[ROS] roslaunch: <remap> 標籤的用法

使用 <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 訂閱的主題改為 chatter1talker.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

 

沒有留言:

張貼留言

和我聯絡

名稱

以電子郵件傳送 *

訊息 *