launch

<source : unflash>

一、前言

隨著應用越來越進階,使用的節點數量也將隨之增加。若每次使用一個節點,就要開啟一個 terminal,對於開發者的操作而言,將是一件非常費時、麻煩的事。

而 Launch 檔的設計,解決了上述問題,只要一執行,就可以同時執行設定好的節點程式、參數,無須再一個一個打開 Terminal 來執行。更方便的是,ROS Master節點管理器也會被自動啟動。

啟動 Launch 檔案的指令為 "roslaunch"。開啟的方式有兩種,可以透過指定套件包名稱,或是指定路徑。範例如下 :

  • 指定套件包名稱 : roslaunch package_name launch_file
  • 指定路徑 : roslaunch ~/.../.../.../launch_file

那如何結束launch檔呢?只要在 terminal 中,輸入 " Ctrl + c " 的指令,就可以中止 launch 檔執行。

二、Launch 檔撰寫技巧與參數簡介

Launch 檔使用 一種特別的"XML"格式,附檔名為 ".launch"。Launch 檔可被放在套件包的任意位置中,但為了方便開發起見,大部份的開發者仍會在工作空間中創建一個名為 "launch"的資料夾,並將 launch 檔案放置其中。

在撰寫 Launch 檔上,其格式是用 launch 標籤的形式定義內容,換言之,所有內容都必須寫在 <launch> ... </launch> 中,請參考下列模板。


(二)、Launch檔模板

<launch>
        <arg name="launch檔中所需參數之名稱" default="" />
      <!-- 第一個節點設定 -->
<node pkg="套件名稱" type="可執行檔名稱" name="節點名稱" ns="husky"> <param name="port" value="$(arg port)" /> <rosparam> cmd_fill: True data: system_status: 10 safety_status: 10 encoders: 10 differential_speed: 10 differential_output: 10 power_status: 1 </rosparam> </node> <!-- 第二個節點設定 --> <node pkg="husky_base" name="husky_base_diagnostics" type="diagnostics_publisher" /> <!-- 第三個節點設定 --> <node pkg="husky_base" name="husky_basic_odom" type="basic_odom_publisher" /> <!-- 第四個節點與參數設定 --> <node pkg="diagnostic_aggregator" type="aggregator_node" name="diagnostic_aggregator"> <rosparam command="load" file="載入大量parameter.yaml"/> </node> </launch>


(二)、Launch檔元素解析

1.node

Launch 檔核心是啟動 ROS 節點,同樣使用標籤的形式撰寫。與法如下 :

<node pkg="套件名稱" type="可執行檔名稱" name="節點名稱" ns="husky">

pkg、type、name

必備的屬性。

  • pkg為套件包名稱。
  • type為可執行檔案名稱。
  • name為節點名稱,會覆蓋原本node程式中init()賦予的名稱,當名稱不同時。

另外,以下參數可依據實際開發情形,彈性使用。

output

output = “screen”:將節點輸出內容顯示在Terminal,默認輸出為 log 文件。

Respawn/Required :

"respawn" 和 "required"這兩個參數設定,只要選擇其中一個即可。更多關於選擇性參數使用,請見<ROS.org>
  • respawn = “true”:該節點被關閉時,會自動重啟,默認為 False。
  • required = “true”:當節點被關閉時,launch檔案中的其他節點也會被關閉。

ns

ns = “namespace”:命名空間。此參數設定可以在一個命名空間啟動一個節點。當要在一個節點中使用多個instances(實例),這種方式非常有用。只要利用 "ns" 這個參數來指出該命名空間即可。

args

args = “arguments”:節點需要的參數,也就是在 launch 檔中使用區域變數。


2.參數設定

<param>

parameter存在 parameter server (參數服務器)中,是ROS系統中運作的參數。在 launch檔案中,透過<param>載入parameter;launch檔案執行後,parameter就載入到 ROS 的參數服務器。每個啟動的節點,都可透過 ros::param::get() 來取得 parameter 的值,使用者也可在 terminal 中,透過 rosparam 指令取得 parameter 的值。使用方法如下 :

<param name="port" value="$(arg port)" />

執行 launch 檔後,port 這個 parameter 的值就設為 $(arg port) 並載入到參數服務器中。

此外,如果在複雜系統中有很多參數,可透過<rosparam>來快速設置。

<rosparam command="load" file="$(find husky_base)/config/diagnostics.yaml"/>

<rosparam>可幫我們將一個 yaml 格式檔案中的參數全部載入到ROS參數服務器中。 command 屬性需設為 "load"。若有需要,還可選擇設置命名空間 "ns"。


<arg>

arg,即 argument。可看作 launch 檔案內的區域變數,僅限於 launch 檔使用,和 ROS節點內部的執行無關。語法如下 :

<arg name=”arg-name” default=”arg-value”/>

本例為
<arg name="port" default="$(optenv HUSKY_PORT /dev/prolific)" />

若 launch 檔案中需要使用 argument 時,可使用以下語法 :

<paramname="foo" value="$(argarg-name)" />
<node name="node" pkg="package" type="type "args="$(arg arg-name)" />



三、Launch檔實例解析

<launch>
        <arg name="port" default="$(optenv HUSKY_PORT /dev/prolific)" />

        <node pkg="clearpath_base" type="kinematic_node" name="husky_kinematic" ns="husky">
                <param name="port" value="$(arg port)" />
                <rosparam>
                        cmd_fill: True
                        data:
                                system_status: 10
                                safety_status: 10
                                encoders: 10
                        differential_speed: 10
                        differential_output: 10
                                power_status: 1
                                </rosparam>
                        </node>

        <!-- Publish diagnostics information from low-level MCU outputs -->
        <node pkg="husky_base" name="husky_base_diagnostics" type="diagnostics_publisher" />

        <!-- Publish wheel odometry from MCU encoder data -->
        <node pkg="husky_base" name="husky_basic_odom" type="basic_odom_publisher" />

        <!-- Diagnostic Aggregator -->

        <node pkg="diagnostic_aggregator" type="aggregator_node" name="diagnostic_aggregator">
        <rosparam command="load" file="$(find husky_base)/config/diagnostics.yaml"/>
        </node>
</launch>

首先要注意地方為該Launch檔是否以 <launch>...</launch>包住。

接下來要注意的是Husky連接到哪個port(連接埠) : default="$(optenv HUSKY_PORT /dev/prolific)"

將該連接埠存到變數"port" : arg name="port"


<node pkg="clearpath_base" type="kinematic_node" name="husky_kinematic" ns="husky">
此行表示,在"clearpath_base"套件包裡的"kinematic_node"節點,會在 "husky" 命名中被啟動。

在 node 標籤中的參數對於命名空間是屬於 "private"等級。其他變數使用YAML格式。 

伴隨 "kinematic_node" 節點,這個launch檔會一起啟動 "husky_base_diagnositcs" 節點和 "husky_base_odom"節點。在 "diagnostics_aggregator"節點中,則會看到載入 YAML 檔案。

若想了解更多關於 launch 檔的內容,可見 <ROS.org>

四、remap重映射機制與直接套用 launch的方法

(一)、重映射機制

ROS的設計核心就是提高程式碼的反覆使用率。而當我們下載其他開發的的套件,相關接口可能會我們的系統不相容。

幸運地,ROS提供一種叫做 "重映射" 的機制,簡言之,就是取別名。只要將接口取的別名,我們的系統就認識了,但要注意到,接口的資料型態必須相同。<remap>標籤可幫助我們輕鬆達到此目的。

以 turtlebot 的鍵盤控制節點為例,發佈的速度控制指令話題可能是 /turtlebot/cmd_vel,但是我們的機器人訂閱的速度控制話題是 /cmd_vel,這個時候使用<remap>就可以輕鬆解決問題,將 /turtlebot /cmd_vel 重映射為 /cmd_vel,我們的機器人就可以接收到速度控制指令了:

<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>


(二)、直接套用 launch 的方法

在複雜系統中,多個 launch 檔間存在依賴關係。如果需要直接複製一個已有 launch 檔中的內容,可以使用<include>標籤包含其他launch檔,用法和C語言中的include相似。

<include file="$(dirname)/other.launch" />

launch 在 ROS框架中非常實用、靈活的工具,幫助我們縮短啟動各個所需節點的時間,無須編寫大量程式碼,就可以實現許多機器人功能。


---
參考資料 :

#launch #roslaunch  #respawn #required

0 留言