ROS之launch文件解析

Launch 文件

1 使用launch文件

1.1 運行launch文件

$ roslaunch package_namelaunch_file_name

Eg: roslaunchturtlesim example.launch

(1)Tip1: rosrun只能運行一個nodes, roslaunch可以同時運行多個nodes.

Tip2: launch文件可以不被包含於package中。此時,只需指出該launch文件的絕對路徑,即可運行。

$ roslaunchcompletely_path

Eg:$ roslaunch~/opt/ros/indigo/share/turtlesim/launch/example.launch

Tip3: 爲便於執行,每個node最好是相互獨立的。

(2)詳細顯示(requestverbosity)

$ roslaunch -vpackage_name launch_file_name

(3) 結束launch文件

ctrl+c

2 創建launch文件

(1) launch文件一般以.launch後綴作爲文件名,放在packagelaunch文件夾下。最簡單的launch文件可以僅包含幾個nodes

(2) Launch文件是XML文件,每個XML文件必須有一個root element而launch文件的rootelement由一對launch 標籤定義。

<launch>

...

</launch>

Launch文件中的其他elements必須都在這一對tags之間。

(3) launch文件的核心是一系列nodeelements,每個node element啓動一個node。Node element看起來如下:

<node

  pkg=”package_name” type=”executable_name”name=”node_name”

/>

Tip1: 最後的“/”是必不可少的

Tip2: 也可以寫成<node pkg=.. type=... name=...></node>

如果該node中有其他tags,則必須使用這種形式。

(4) 一個node element包含三個必須的屬性:pkg, type, name.

pkg和type屬性指出ROS應該運行哪個pkg中的哪個node,注意:此處的type是可執行文件的名稱name則是可以任意給出的,它覆蓋了原有文件中ros::init指定的node name

(5) 使用匿名(anonymousname)

  name=”$(anon base_name)”

(6) node 日誌文件(log file)

運行roslaunch和用rosrun運行單個節點的區別之一是,默認情況下,roslaunch運行的nodes的標準輸出會重定向到logfile,不顯示在控制檯。   ??????????????

該日誌文件的位置和名稱如下:

~/.ros/log/run_id/node_name-number-stdout.log

其中,run_idmaster啓動後生成的特殊標識符,number是表示nodes數量的整數。如,turtlesim-1-stdout.log;teleop_key-3-stdout.log.

(7) 輸出到控制檯

output屬性, output=screen”;這種方法僅顯示一個node

若顯示所有nodes的輸出,用--screen命令行。

$ roslaunch--screen package_name launch_file_name

如果正在運行的文件沒有顯示想要對輸出,可以查看該node屬性集中是否有 output=screen.

(8) 要求重生(requestrespawning)

    開啓所有nodes後,roslaunch會監視每個node,記錄那些仍然活動的nodes。對於每個node,當其終止後,我們可以要求roslaunch重啓該node,通過使用respawn屬性。

    respawn=”true”

(10) 必需的nodes

required屬性與respawn相反,不能同時對同一個node使用。當一個必需的節點終止時,roslaunch會做出響應,終止其他所有的節點並退出它自己。所以如果你給單個的一個節點同時設置了這2個屬性,roslaunch 命令會抱怨

required=”true”

當一個required node終止後,所有其他的nodes都會終止,並退出。這種命令有時很有用。比如,當一個很重要的node失敗後,整個會話都會被扔掉,那些加上了respawn屬性的nodes也會停止。

(11) 在獨立的窗口運行各nodes

我們在各自的termin運行rosrun node_name;但是運行roslaunch時,所有的nodes共用一個相同的terminal,這對於那些需要從控制檯輸入的nodes很不方便。可以使用launch-prefix屬性。

launch-prefix=”command-prefix”

Eglaunch-prefix=xterm -e

等價於 xterm -e rosrunturtlesim turtle_teleop_key

xterm 命令表示新建一個terminal -e參數告訴xterm執行剩下的命令行。

當然,launch-prefix屬性不僅僅限於xterm。它可用於調試(通過gdbvalgrind),或用於降低進程的執行順序(通過nice.

 roslaunch 命令 的一個潛在的缺點:相比我們原來對每個節點在單獨的終端使用 rosrun 命令啓動的做法,roslaunch 則是讓所有的節點共享同一個終端。那些只需要生產簡單的日誌消息文件而不需要終端(console)輸入的節點是容易管理的,而那些依賴終端輸入的節點,比如 turtle_teleop_key 節點,它可能要優先的保留在獨立的終端上。

在例子launch文件中,我們給teleoperation 節點使用了這個屬性:launch-prefix=”xterm -e”.因爲這個屬性,啓動這個 node 元素的 rosrun 命令大致相當於:xterm -e rosrun turtlesim turtle_teleop_key.

xterm 命令會開一個新的終端窗口。-e 參數告訴 xterm :執行其命令行剩餘部分(rosrun turtlesim turtle_teleop_key)。

3 在namespace中執行nodes

爲node設置默認的namespace的常用方法——被稱爲“pushingdown into a namespace”的進程,用於launch文件,並在其node element中指定ns屬性。

ns=”namespace”

launch文件中的node namesrelative names。同一個launch文件中,允許不同namespace中出現相同的node namesRoslaunch要求node names必須是base names——不指定任何namespacesrelative names;如果node element中出現node nameglobal name,則會報錯。

4 重映射names(remappingnames)

除了解析relative namesprivate namesROS也支持重映射,用於修改nodes當前使用的名稱。

重映射相當於換名,每次重映射需提供一個originalname和一個new name。每次node使用它的original name, ROS client library都會將其替換爲remapping name。

創建remapping name兩種方法:

1. 對於單個node,在命令行進行remapping(remap對象可以是node,topic等)。

   original-name:=new-name

Eg: $ rosrunturtlesim turtlesim_node turtle1/pose:=tim

2. launch文件內remap names,使用remapelement

  <remap from=”original_name” to“new_name”>

如果remap出現在launch文件開頭,作爲launch文件的子元素,則該remapping將被用於隨後所有的nodes。如果remap作爲某個node的子元素,則只用於該節點。

Eg:<nodepkg=”turtlesim” type=”turtlesim_node” name=”turtle1”>

    <remap from =”turtle1/pose” to “tim”>

</node>

注意:在ROS進行remapping之前,remaping的所有name,包括originalnew names,都將被解析爲global names。所以,remapping之後所有的名字通常都是relative names

5 其他的launch elements

5.1 including其他文件

爲包含其他launch文件,包括這些launch文件的所有nodes和parameters,用includeelement。

<includefile=”path-to-launch-file”>

這種情況下,file屬性必須寫出該launch文件的全部路徑名稱,顯得很繁瑣。因此,常用

<includefile=”$(find package_name)/launch_file_name”/>

注意,執行該launch文件時,roslaunch會搜索該package下的所有子目錄;因此,必須給出package_name。此外,include也支持ns屬性,將它的內容放進指定的namespace

<include file=”...” ns=”namespace_name”/>

這樣做是正確的: <includefile = "find learning_tutrols"/launch/start_demo.launch"/ >

這樣做是錯誤的: <includefile = "find learning_tutrols"/start_demo.launch"/>

5.2 Launcharguments

爲便於launch文件重構,roslaunch支持launcharguments,也成爲arguments或者args,類似於局部變量

注意:儘管argumentparameter有時可互換,但他們在ROS中的意義完全不同。ParametersROS系統使用的數值,存在parameter server上,nodes可通過ros::param::get函數編程得到,用戶可通過rosparam獲取。與之不同,arguments僅在launch文件內部有意義,nodes不能直接獲取它們的值。

(1)聲明argument

<argname=”arg_name”>

(2)指定argument的值

Launch文件中的每個argument都必須有指定值。賦值方法有好幾種。

第一種,在命令行賦值

$ roslaunchpackage_name launch_file_name arg-name:=arg_value

第二種,在聲明argument時賦值

<argname=”arg_name” default=”arg_name”/>

<argname=”arg_name” value=”arg_name”/>

上面兩行的區別在於,命令行參數可以覆蓋default,但是不能重寫value的值。

在例子launch文件 中,use_sim3 節點的 default 值爲 0,所以它可以通過命令行改變值,就像下面這樣:

$ roslaunchagitr triplesim.launch use_sim3:=1

如果我們修改了這個例子launch文件:使用value替換default。那麼上面這個命令執行的時候會出 現錯誤,因爲使用value屬性配置的argument的值是不允許改變的。

 (3)獲取變量值

一旦聲明某個argument並賦值後,我們可以通過arg使用該argument.

$(arg arg-name)

如果該行出現,roslaunch將會用給定arg-name的值替換其左邊的值。

 (4)argument值傳給included launch文件

在argument的傳遞上有一個限制,就是argument不能傳遞給 include元素裏包含的子launch文件使用。這個問題非常重要,因爲這個 argument 就像是一個局部變量,它不能被包含的launch文件所 “繼承” 。

解決這個問題的方法:在 include 元素中插入 arg 元素作爲 include 元素的子類(children),就像是這樣:

<includefile=”path-to-file”>

<argname=”arg_name” value=”arg_value”/>

......

</include>

若在launch文件中,launch文件及其包含的launch文件出現相同的arguments,則需在launch文件及included launch文件中同時寫:

<argname=”arg_name” value=”$(arg arg_name)”/>

第一個arg_name表示(includedlaunch文件中的argument,第二個arg_name表示launch文件中的argument.其結果是指定的argumentlaunch文件及included launch文件中都有相同的值。

注意,這裏的 arg 元素不同於我們已經知道的arg 聲明,在 inchude 標籤內的arguments是給包含 (included) 的launch文件提供的arguments,不是爲本launch文件提供的。

一種常見的情況是,被包含(included)的launch文件和本launch文件會有共同的參數。在這種情況下,我們希望這些值(values)永遠不變。像這樣的元素,在這兩個地方使用相同的argument name (參數名),要這樣做:

<argname="arg-name" value="$(arg arg-name)" />

在這種情況下,第一個 arg-name 和往常一樣。第二個arg-name 是launch文件中提供的。結果是,這兩個launch文件中給定的argument具有相同的值(value)。

argumentparameter有區別

儘管術語argument和parameter在許多計算機環境中稍微可以互換使用,它們的含義在ROS中有很大的不同。Parameters(參數)在一個運行的ROS系統中是變量(values),它被存儲在parameter服務器中,活動(或者叫:運行)的節點通過ros::param::get()函數訪問它,並且用戶可以通過 rosparam 命令行工具使用它。相比之下,arguments只有在launch文件裏合法,它們的值不是直接提供給節點。

5.3 創建groups

Group element可以再大型的launch文件中將指定的nodes組織起來。它有兩個用處:

其一,group可以將幾個nodes放進同一個namespace

<groupns=”namespace”>

<nodepkg=”..” .../>

<nodepkg=”..” .../>

......

</group>

注意,如果grouped node已經有它自己的namespace,並且是relative name,那麼該nodenamespace是其relative name,並以group namespace爲後綴。

其二,group可以同時啓動或者終止一組nodes

<group if=”0or 1”>

......

</group>

如果該屬性的值是1,一切正常;如果該屬性的值爲0,那麼group內所有的nodes都不會運行。

同理,除了if,還有unless unless 屬性的工作方式類似 if 屬性,但是含義顛倒。

<groupunless=”1 o r 0”>

......

</group>

注意,這些屬性的合法值只有01.

另外,group element中只能使用nsifunless這三個屬性

當然了,通常我們不會給這些屬性使用簡單的0 或 1 這樣的賦值。建議:結合 arg 的 $() 技術,它們會將你的launch文件的配置變得非常的強大

依賴包,

$ catkin_create_pkg beginner_tutorialsstd_msgs rospy roscpp

# catkin_create_pkg <package_name>[depend1] [depend2] [depend3]

每個程序包創建時可以生成一些依賴包(就是引用的文件)如上代碼就引用了std_msgs rospy roscpp這三個依賴包,可以在生成的pack.xml文件中找到,

$ rospack depends1 beginner_tutorials  //列出beginner_tutorials中的一級依賴包,

 

https://www.cnblogs.com/CZM-/p/5943821.html

launch

在ROS應用中,每個節點通常有許多參數需要設置,爲了方便高效操作多個節點,可以編寫launch文件,然後用roslaunch命令運行

roslaunch: roslaunch [options] [package]<filename> [arg_name:=value...]

                    roslaunch [options]<filename> [<filename>...] [arg_name:=value...]

launch文件的一般格式,參數:

<launch>

   <node .../>

   <rosparam ..../>

   <param .../>

   <include .../>

   <env .../>

   <remap .../>

   <arg.../>

</launch>

參數說明

<node >要啓動的node參數

name=''nodename''  //該節點的名字,相當於代碼中ros::int的命名信息,有了它代碼中的名稱會被覆蓋。

pkg=''mypackage''   //該節點屬於哪個包,相當於rosrun命令後面的第一個參數

type=''nodetype''   //可執行文件的名字,rosrun命令的第二個參數

以上每個節點元素由三個必須的屬性:

    args=''arg1....''(可選)

   respawn=''ture''(可選)如果節點停止,自動重啓節點 //請求復位,當該屬性的值爲respawn="true"時,roslaunch會在該節點崩潰時重新啓動該節點

   ns=''foo''(可選)在foo命名空間啓動節點//在命名空間中啓動節點。

output=''log|screen''(可選)    //將標準輸出顯示在屏幕上而不是記錄在日誌中

required //必要節點,當該值爲required="true"時,roslaunch會在該節點終止時終止其他活躍節點

啓動前綴:在啓動命令加上前綴。例如當其設置爲launch-prefix="xterm -e"時,效果類似於xterm -erosrun X X。也就是爲該節點保留獨立的終端

remap重映射:使用方法remapfrom="original-name(turtle/pose)"to"new-name(tim)"

<rosparam>操作yaml文件參數

include包含其他文件include file="path to launch file"

在啓動文件中包含其他啓動文件的內容(包括所有的節點和參數),可使用如下命令使路徑更爲簡單include file="($find package-name)/launch-file-name"

 

 

 

   command=''load|dump|delete''(默認load)

   file=''$(find pkg-name)/path/foo.yaml''(load或dump命令)yaml文件的名字

   param=''param-name''參數名

<param>定義一個設置在參數服務器的參數,它可以添加到<node>中

   name=''namespace/name''

   value=''value''(可選)如果省略這個參數,則應指定一個文件(binfile/textfile)或命令

   type=''str|int|double|boot''(可選)指定參數的類型

   textfile=''$(find pkg-name)/path/file''(可選)  

 

   binfile=''$(find pkg-name)/path/file''()

   command=''(find pkg-name)/exe '$(find pkg-name)/arg.txt' ''(可選)exe是可執行文件(cpp、py),arg.txt是參        數文件

<include>在當前launch文件中調用另一個launch文件

   file=''$(find pkg-name)/path/launch-file.launch''   

<env>設置節點的環境變量

   name=''environment-variable-name''

   value=''environment-variable-value''   

<remap>將一個參數名映射爲另一個名字

   from=''original-name''

   to=''new-name''   

<arg>定義一個局部參數,該參數只能在一個launch文件中使用

   <arg name=''foo''/>聲明一個參數foo,後面需要給它賦值

   <arg name=''foo'' default=''1''/>聲明一個參數foo,如不賦值取默認值

<argname=''foo'' value=''bar''/>聲明一常量foo,它的值不能修改

http://blog.csdn.net/seawolfe/article/details/69525113

roslaunch工具是ros中python實現的程序啓動工具,通過讀取launch文件中的參數配置、屬性配置等來啓動一系列節點;

很多ROS包或源碼包中都有launch文件,一般爲該程序包能夠運行起來的基本demo配置,運行下面指令自動補全會提示該包現有的launch文件:

$roslaunch  package_name file.launch

launch文件的位置並不是很重要,如果放在任意一個位置,可以運行下面指令:

$roslaunch  path-to-where/file.launch

 

launch文件是XML格式標記文本,後綴名無關緊要,一般爲.launch/.xml/.test/無後綴

最簡單的配置如下:

<launch>

  <nodename="you_define_node_name" pkg="package_name"type="exe_name" />

</launch>

啓動上面的launch文件就會啓動package_name包下的exe_name執行文件,you_define_node_name自定義的node_name

一個複雜的配置:

<launch>

    <!-- comment註釋  -->

   

    <!-- top-level arg must be set from  command line:roslaunch file.launcharg_1:=value -->

    <arg name="arg_1" />

    <!--pass arg to param-->

    <param name="param_1" value="$(argarg_1)"/>

   

    <!-- arg can be set from high level likethis  -->

    <!-- this is the include launch filecontent:

        <launch>

          <!-- declare arg to be passed in-->

          <arg name="arg_2" />

 

          <!-- read value of arg -->

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

        </launch>

    -->

    <include file="$(findpkg_name)/path-to/included.launch" ns="namespace">  

        <!-- pass value from high level toincluded.launch -->

        <arg name="arg_2"  value="value" />

    </include>

   

    <arg name="arg_3"  default="value" />

    <arg name="arg_4"  value="value" />

   

    <node pkg="pkg_name"type="exe_name" name="node_name1" args="arg1 arg2arg3" respawn="true" output="screen"> 

     

        <param name="name1"type="double" value="10.0"/>

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

        <param name="name3"value="$(env ENVIRONMENT_VARIABLE_NAME)"/>

        <param name="name4"command="$(find pkg_name)/path-to/exe '$(findpkg_name)/path-to/arg.txt'"/>

 

 

        <remap from="laser_topic"to="/scan"/>

        <remap from="base_link"to="$(arg arg_1)"/>

 

        <rosparam command="load"file="$(find pkg_name)/example.yaml"/>

 

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

    </node>  

    <node pkg="pkg_name"type="exe_name" name="node_name2" args="arg1 arg2arg3" respawn="true" output="screen"> 

     

        <param name="name1"type="double" value="10.0"/>

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

        <param name="name3"value="$(env ENVIRONMENT_VARIABLE_NAME)"/>

        <param name="name4"command="$(find pkg_name)/path-to/exe '$(findpkg_name)/path-to/arg.txt'"/>

 

 

        <remap from="laser_topic"to="/scan"/>

        <remap from="base_link" to="$(argarg_1)"/>

 

        <rosparam command="load"file="$(find pkg_name)/example.yaml"/>

 

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

    </node>

    <node pkg="pkg2_name"type="exe_name" name="node_name3" args="arg1 arg2arg3" respawn="true" output="screen"> 

     

        <param name="name1"type="double" value="10.0"/>

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

        <param name="name3"value="$(env ENVIRONMENT_VARIABLE_NAME)"/>

        <param name="name4"command="$(find pkg_name)/path-to/exe '$(findpkg_name)/path-to/arg.txt'"/>

    </node>   

    <group if="$(arguse_rviz)">

      <node pkg="rviz"type="rviz" name="rviz"

            args="-d $(findpkg_name)/launch/VLP16_2D.rviz"/>

    </group>

</launch>

上面的launch文件首先聲明瞭一些參數,之後include另一個launch文件,included.launch文件中的節點會按深度優先執行配置和啓動;

之後該launch文件啓動3個節點,前兩個節點來自同一個包的同一個可執行文件,節點命名不能相同,每個節點可以進行自己的參數配置;

之後該launch文件啓動rviz節點,參數傳遞 rviz的配置文件,不同配置用於顯示不同的信息

<group>可以作爲一組標籤的容器,從而使該組有獨立的名稱空間

所以標籤可使用 if/unless屬性,如果條件成立則包含標籤

 

launch常用標籤tag:

<arg> 參數聲明,arg_1 通過命令行傳遞,arg_2 傳遞到included.launch arg_3 默認值可以被重寫覆蓋,agr_4不能被重寫   ????

 

<include> 包含其他文件,包含文件中定義的參數、變量、節點都會按深度優先遍歷依次執行生效

 

<param>:設置變量到參數服務器,參數服務器的概念看roswiki

 

<rosparam>:dump/load、delete parameters from/to Parameter Server,常用來加載程序的參數配置文件到參數服務器,然後程序從參數服務器取得參數值;

 

<remap>:名稱映射 from:被映射名稱 to:目標名稱,名稱映射的概念看roswiki

 

<node> 啓動節點,

    <node>常用屬性tag:

    pkg:"pkg_name"  包名

    type:"exe_name"  節點類型,即編譯生成的可執行文件

    name:"node_name" 節點名稱,自定義但不能重複

    args:"arg1 ..."  傳遞節點的參數列表

    respawn:"true" 如果節點退出自動重啓default:false

    output:"screen" 標準輸出/標準錯誤輸出重定向屏幕,log重定向log文件,default:log

    required:"true" 如果節點退出,殺死全部launch進程

    launch-prefix:"prefix arguments" 前置的參數,可以使用其他工具如gdb,valgrind等

 

    <node>常用標籤tag:

    param

    remap

    rosparam

 

    lannch機制不保證節點的啓動順序,雖然launch文件是順序分析,但節點初始化的時間長度不一,啓動時間不一

</node>

 

http://blog.csdn.net/rosjjfdfd/article/details/49781295

.launch文件分析

  在我們的功能包中可以看到launch文件夾下有很多的.launch文件,這些文件​寫入了我們想要同時運行的節點,當我們需要有很多節點同時啓動時,一個個啓動它們會費時費力,這時我們可以寫一個.launch文件把這些節點都包括進去,這樣可以通過roslaunch命令來把這些節點都啓動了。

       到這裏假設我們都已經知道怎樣使用roslaunch命令了,這次重先簡單介紹一下.launch文件的結構,然後重點說一下.launch文件中的重映射(remap)。

1 .launch文件的結構

            <launch>

                       <nodename="talker"pkg="rospy_tutorials" type="talker">

                        </node>

            </launch>

      上面是.launch文件的最小例子。.launch文件開頭是以<launch>​爲標籤,讓我們知道這是一個.launch文件,以</launch>爲結尾。而中間就是寫自己要啓動的節點,是以<node> 開始,</node>結束,其中pkg="rospy_tutorials",這是自己要啓動的節點所在的包;type="talker",這是自己寫的節點.cpp程序通過編譯生產的可執行文件的名字,你最初編譯.cpp程序的時候要在CMakeLists.txt添加cpp程序編譯的設置,這個可執行文件的名字在CMakeLists.txt中就可以找到;name="talker",這是節點的名字。

2.Roslaunch/XML/remap     ​

 1. 元素

<node> 啓動一個節點.

<param> 設置參數服務器上的參數

<remap> 聲明一個名稱的映射,允許你通過名稱映射參數到ROS 節點(通過更結構化的方式而不是直接設置節點參數屬性來啓動的節點)。

<machine> 聲明啓動要使用的機器.

<rosparam>使用rosparam 文件設置啓動要用的ROS 參數

<include> 包含roslaunch 文件.

<env> 制定啓動節點的環境變量

<test> 啓動一個測試節點seerostest).

<arg> 聲明參數

<group> 共享一個命名空間或映射的封閉的元素組。

2 .launch文件的重映射(remap

       據我理解,重映射就是甲節點得到相關的信息,通過重映射使乙節點得到甲節點一樣的信息,從而使得乙節點模仿甲節點做出相應的響應。

<remap>標籤適用於在其範圍內隨後的所有聲明(<launch>, <node> or<group>)。

 

其他較好的launch文件教程:

http://blog.csdn.net/zqxf123456789/article/details/52497833

http://blog.csdn.net/qq_33444963/article/details/77893881

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章