ROS探索總結(五十六)—— launch檔案
每當我們需要執行一個ROS節點或工具時,都需要開啟一個新的終端執行一個命令。當系統中的節點數量不斷增加時,每個節點一個終端的模式會變得非常麻煩。那麼有沒有一種方式可以一次性啟動所有節點呢?答案當然是肯定的。
啟動檔案(Launch File)便是ROS中一種同時啟動多個節點的途徑,還可以自動啟動ROSMaster節點管理器,而且可以實現每個節點的各種配置,為多個節點的操作提供了很大便利。
一、基本元素
首先來看一個簡單的launch檔案:
-
<launch>
-
<nodepkg="turtlesim"name="sim1" type="turtlesim_node"/>
-
<nodepkg="turtlesim"name="sim2" type="turtlesim_node"/>
-
</launch>
這是一個簡單而完整的launch檔案,採用XML的形式進行描述,包含一個根元素<launch>和兩個節點元素<node>。
1.<launch>
XML檔案必須要包含一個根元素,launch檔案中的根元素採用<launch>標籤定義,檔案中的其他內容都必須包含在這個標籤之中:
-
<launch>
-
......
-
</launch>
2. <node>
啟動檔案的核心是啟動ROS節點,採用<node>標籤定義,語法如下:
-
<node pkg="package-name"type="executable-name" name="node-name" />
從上邊的定義規則可以看出,在啟動檔案中啟動一個節點需要三個屬性:pkg、type和name。其中pkg定義節點所在的功能包名稱,type定義節點的可執行檔名稱,這兩個屬性等同於在終端中使用rosrun命令執行節點時的輸入引數。name屬性用來定義節點執行的名稱,將覆蓋節點中init()賦予節點的名稱。這是三個最常用的屬性,在某些情況下,我們還有可能用到以下屬性:
· output = "screen":將節點的標準輸出列印到終端螢幕,預設輸出為日誌文件;
· respawn = "true":復位屬性,該節點停止時,會自動重啟,預設為false;
· required = "true":必要節點,當該節點終止時,launch檔案中的其他節點也被終止;
· ns = "namespace":名稱空間,為節點內的相對名稱新增名稱空間字首;
· args = "arguments":節點需要的輸入引數。
實際應用中的launch檔案往往會更加複雜,使用的標籤也會更多,例如一個啟動機器人的launch檔案如下:
-
<launch>
-
<node pkg="mrobot_bringup" type="mrobot_bringup" name="mrobot_bringup" output="screen" />
-
<arg name="urdf_file" default="$(find xacro)/xacro --inorder '$(find mrobot_description)/urdf/mrobot_with_rplidar.urdf.xacro'" />
-
<param name="robot_description" command="$(arg urdf_file)" />
-
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
-
<node pkg="robot_state_publisher" type="robot_state_publisher" name="state_publisher">
-
<param name="publish_frequency" type="double" value="5.0" />
-
</node>
-
<node name="base2laser" pkg="tf" type="static_transform_publisher" args="0 0 0 0 0 0 1 /base_link /laser 50"/>
-
<node pkg="robot_pose_ekf" type="robot_pose_ekf" name="robot_pose_ekf">
-
<remap from="robot_pose_ekf/odom_combined" to="odom_combined"/>
-
<param name="freq" value="10.0"/>
-
<param name="sensor_timeout" value="1.0"/>
-
<param name="publish_tf" value="true"/>
-
<param name="odom_used" value="true"/>
-
<param name="imu_used" value="false"/>
-
<param name="vo_used" value="false"/>
-
<param name="output_frame" value="odom"/>
-
</node>
-
<include file="$(find mrobot_bringup)/launch/rplidar.launch" />
-
</launch>
目前,我們只關注其中的標籤元素,除了上邊介紹的<launch>和<node>,這裡還出現了<arg>、<param>、<remap>,這些都是常用的標籤元素。
二、引數設定
為了方便設定和修改,launch檔案支援引數設定的功能,類似於程式語言中的變數宣告。關於引數設定的標籤元素有兩個:<param>、<arg>,一個代表parameter,另一個代表argument。這兩個標籤元素翻譯成中文都是“引數”的意思,但是這兩個“引數”的意義是完全不同的。
1. <param>
parameter是ROS系統執行中的引數,儲存在引數伺服器中。在launch檔案中通過<param>元素載入parameter;launch檔案執行後,parameter就載入到ROS的引數伺服器上了。每個活躍的節點都可以通過 ros::param::get()介面來獲取parameter的值,使用者也可以在終端中通過rosparam命令獲得parameter的值。
<param>的使用方法如下:
-
<param name="output_frame" value="odom"/>
執行launch檔案後,output_frame這個parameter的值就設定為odom,並且載入到ROS引數伺服器上了。但是在很多複雜的系統中,引數的數量很多,如果這樣一個一個的設定會非常麻煩,ROS也為我們提供了另外一種類似的引數載入方式——<rosparam>:
-
<rosparamfile="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam>可以幫助我們將一個yaml格式檔案中的引數全部載入到ROS引數伺服器中,需要設定command屬性為“load”,還可以選擇設定名稱空間“ns”。
2. <arg>
argument是另外一個概念,類似於launch檔案內部的區域性變數,僅限於launch檔案使用,便於launch檔案的重構,和ROS節點內部的實現沒有關係。
設定argument使用<arg>標籤元素,語法如下:
-
<arg name=”arg-name” default=”arg-value”/>
launch檔案中需要使用到argument時,可以使用如下方式呼叫:
-
<paramname="foo" value="$(argarg-name)" />
-
<node name="node" pkg="package" type="type "args="$(arg arg-name)" />
三、重對映機制
ROS的設計目標是提高程式碼的複用率,所以ROS社群中的很多功能包我們都可以拿來直接使用,而不需要關注功能包的內部實現。那麼問題就來了,別人功能包的介面不一定和我們的系統相容呀?
ROS提供一種重對映的機制,簡單來說就是取別名,類似於C++中的別名機制,我們不需要修改別人功能包的介面,只需要將介面名稱重對映一下,取個別名,我們的系統就認識了(介面的資料型別必須相同)。launch檔案中的<remap>標籤可以幫我們實現這個重對映的功能。
比如turtlebot的鍵盤控制節點,釋出的速度控制指令話題可能是/turtlebot/cmd_vel,但是我們自己的機器人訂閱的速度控制話題是/cmd_vel,這個時候使用<remap>就可以輕鬆解決問題,將/turtlebot /cmd_vel重對映為/cmd_vel,我們的機器人就可以接收到速度控制指令了:
-
<remap from="/turtlebot/cmd_vel"to="/cmd_vel"/>
重對映機制在ROS中的使用非常廣泛,也非常重要,方法不止這一種,也可以在終端rosrun命令中實現重對映,大家一定要理解好這種機制。
四、巢狀複用
在複雜的系統當中,launch檔案往往有很多,這些launch檔案之間也會存在依賴關係。如果需要直接複用一個已有launch檔案中的內容,可以使用<include>標籤包含其他launch檔案,這和C語言中的include幾乎是一樣的。
-
<include file="$(dirname)/other.launch" />
總而言之,launch是ROS框架中非常實用、靈活的功能,它類似於一種高階程式語言,可以幫助我們管理啟動系統時的方方面面。在使用ROS的過程中,很多情況下我們並不需要編寫大量程式碼,僅需要使用已有的功能包,編輯一下launch檔案,就可以完成很多機器人功能。
這裡僅介紹了launch中最為常用的一些標籤元素,還有更多高階的標籤元素可以訪問wiki學習:
http://wiki.ros.org/roslaunch/XML。
本文連結地址:ofollow,noindex">ROS探索總結(五十六)—— launch檔案