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後綴作爲文件名,放在package的launch文件夾下。最簡單的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_id是master啓動後生成的特殊標識符,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”
Eg:launch-prefix=”xterm -e”
等價於 xterm -e rosrunturtlesim turtle_teleop_key
xterm 命令表示新建一個terminal; -e參數告訴xterm執行剩下的命令行。
當然,launch-prefix屬性不僅僅限於xterm。它可用於調試(通過gdb或valgrind),或用於降低進程的執行順序(通過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 names是relative names。同一個launch文件中,允許不同namespace中出現相同的node names。Roslaunch要求node names必須是base names——不指定任何namespaces的relative names;如果node element中出現node name爲global name,則會報錯。
4 重映射names(remappingnames)
除了解析relative names和private names,ROS也支持重映射,用於修改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,包括original和new 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,類似於局部變量。
注意:儘管argument和parameter有時可互換,但他們在ROS中的意義完全不同。Parameters是ROS系統使用的數值,存在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表示(included)launch文件中的argument,第二個arg_name表示launch文件中的argument.其結果是指定的argument在launch文件及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)。
argument和parameter有區別
儘管術語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,那麼該node的namespace是其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>
注意,這些屬性的合法值只有0和1.
另外,group element中只能使用ns,if,unless這三個屬性。
當然了,通常我們不會給這些屬性使用簡單的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文件教程: