ROS學習之啟動文件
啟動文件就好比我們所有的嵌入式設備、系統等在開機啟動時首先要執行的文件。我們一般用啟動文件來執行一些准備工作。還有一個更好的功能是它可以同時執行多個節點。筆者通過學習對啟動文件做了簡要的總結。
0.1創建啟動文件
0.1.1結構
和其他 ROS 文件一樣,每一個啟動文件都應該和一個特定的功能包關聯起來。通常的命名方案是以.launch 作為啟動文件的后綴。最簡單的方法是把啟動文件直接存儲在功能包的根目錄中。當查找啟動文件的時候,roslaunch 工具會同時搜索每個功能包目錄的子目錄。包括 ROS 核心包在內的很多功能包都是利用這一特性,將所有啟動文件統一存放在一個子目錄中,該子目錄通常取名為 launch。具體的結構可以參考下面所示
0.1.2基本元素
最簡單的啟動文件由一個包含若干節點元素(node elements)的根元素(root element)組成。
啟動文件是 XML 文件,每個 XML 文件都必須要包插入根元素含一個根元素。對於 ROS 啟動文件,根元素由一對 launch 標簽定義:
<launch>
...
<launch>
每個啟動文件的其他元素都應該包含在這兩個標簽之內。啟動節點任何啟動文件的核心都是一系列的節點元素,每個節點元素指向一個需要啟動的節點。節點元素的形式為:
<node
pkg=”package-name”
type=”executable-name”
name=”node-name”
/>
參數解釋:
1)pkg給定的參數時程序包的名稱。
2)type類型給定的時程序報的類型,和第一個參數配合固定到某個程序
3)name節點名稱
4)output輸出形式
tips:查看節點日志文件使用roslaunch啟動一組節點與使用rosrun單獨啟動每個節點的一個重要不同點是,在默認狀態下,從啟動文件啟動節點的標准輸出被重定向到一個日志文件中,而不是在控制台顯示 * 。該日志文件的名稱是:~/.ros/log/run_id/node_name-number-stout.log在對於某個單獨的節點,只需在節點元素中配置 output 屬性就可以達到控制台中輸出信息該目的:output=”screen”
5)respawn請求復位參數
在啟動了啟動文件中所有的請求節點之后,roslaunch會監視每一個節點,記錄哪一個節點是活躍的。對於每個節點,我們可以設置 respawn 屬性為真,這樣當節點停止的時候,roslaunch 會重新啟動該節點。respawn=”true”這個功能是有意義的,比如在某個節點因為軟件崩潰或硬件故障以及其他原因導致過早退出系統的時候會起到作用。
6)必要節點(required)
復位之外的另一種策略是將一個節點聲明為必要節點。required=”true”當一個必要節點終止的時候,roslaunch 會終止所有其他活躍節點並退出。當出現(1)某個節點非常重要,此節點的故障會導致整個 ROS 會話的癱瘓; (2)節點即便設置了復位屬性也不能很好地重啟的時候,該需求屬性的作用就會體現出來。
0.2命名空間內啟動節點
間內啟動節點
在上一篇文章中,我們談到計算機圖源命名,我們看到 ROS 支持相對名稱,相對名稱用到了默認命名空間的概念。對一個節點設置默認命名空間——這個過程通常叫做壓入(pushing down)命名空間——的通常方法是使用一個啟動文件,並對其節點元素配置命名空間(ns)屬性,具體如下:
ns=”namespace”
<launch> <node name="turtlesim_node" pkg="turtlesim " type="turtlesim_node" ns="sim1" /> <node pkg="turtlesim " type="turtle_teleop_key" name="teleop_key" required="true " launch −prefix="xterm −e" ns="sim1" <node name="turtlesim_node" pkg="turtlesim " type="turtlesim_node" ns="sim2" /> </launch>
0.3啟動文件其他元素
0.3.1包含其他文件
如果想在啟動文件中包含其他啟動文件的內容(包括所有的節點和參數),可以使用包含(include)元素 9 :<include file=”path-to-launch-file”>此處 file 屬性的值應該是我們想包含的文件的完整路徑。由於直接輸入路徑信息很繁瑣且容易出錯,大多數包含元素都使用查找(find)命令搜索功能包的位置來替代直接輸入路徑:<include file=”$(find package-name)/launch-file-name”>
包含元素同樣支持命名空間屬性,可以將內容壓入一個指定的命名空間中去:<include file=”...” ns=”namespace”/>
0.3.2啟動參數
為了使啟動文件便於配置,roslaunch還支持啟動參數,有時也簡稱為參數甚至args,其功能有點像可執行程序中的局部變量。這樣做的優點是通過設置參數來描述節點在不同ROS會話中運行時可能需要改變的一小部分,從而避免代碼重復。
<arg name=”arg-name” default=”arg-value”/>
<arg name=”arg-name” value=”arg-value”/>
兩者的唯一區別在於命令行參數可以覆蓋默認值 default,但是不能覆蓋參數值 value。
獲取參數值 一旦參數值被聲明並且被賦值,你就可以利用下面的arg 替換(arg substitution)語法來使用該參數值了:$(arg arg-name)每個該替換出現的地方,roslaunch 都將它替換成參數值。在示例中,我們在 group 元素中的 if 屬性使用了一次 use_sim3 參數(稍后將會介紹 if 和 group)。
<launch> <include file ="$( find agitr )/doublesim . launch" /> <arg name="use_sim3" default ="0" /> <group ns="sim3" if ="$( arg use_sim3 )" > <node name="turtlesim_node" pkg="turtlesim " type="turtlesim_node" /> <node pkg="turtlesim " type="turtle_teleop_key" name="teleop_key" required="true " launch−prefix="xterm −e" /> </group> </launch>
0.3.3向包括的啟動文件中發送參數值
目前已介紹的參數設定技巧的局限在於,它並未提供任何方法將參數傳遞到通過包含元素導入的次級啟動文件中去。這一點很重要,因為像局部變量一樣,參數僅定義在對其進行聲明的啟動文件中,而不能被包含的啟動文件“繼承”。該問題的解決方案就是將 arg 元素為一個包含元素的子元素,如下所示:
<incluce file=”path–to-launch-file”>
<arg name=”arg-name” value=”arg-value”/>
...
</include>
請注意,該 arg 元素的用法和之前我們看到的 arg 聲明是不同的。在 include 標簽之間的參數是屬於被包含文件的,而不是它們出現的啟動文件。因為目的是為被包括的啟動文件設置響應的參數值,所以該處需要使用 value 屬性。一種常見的情況是兩個啟動文件(包含文件和被包含文件)有一些共同的參數,在這種情況下,我們希望參數在傳遞的時候不會改變。這樣的元素在兩個地方使用相同的參數名:
<arg name=”arg-name” value=”$(arg arg-name)”>