ROS Learning-032 (提高篇-010 Launch)Launch 深入研究 --- (启动文件编程)ROS 的 XML语法简介...
ROS 提高篇 之 Launch 深入研究 - 01 — 啟動文件的編程 — ROS 的 XML語法簡介
我使用的虛擬機(jī)軟件:VMware Workstation 11
使用的Ubuntu系統(tǒng):Ubuntu 14.04.4 LTS
ROS 版本:ROS Indigo
注意:
1 . ROS 提高篇這個(gè)專欄的教學(xué)有門檻。
2 . 如果你沒有學(xué)習(xí)前面的教程,請想學(xué)習(xí)前面的 beginner_Tutorials 和 learning_tf 的ROS 相關(guān)教程。
1 . 前言
在之前的 beginner_Tutorials 教程里面,我們已經(jīng)初步學(xué)習(xí)了 Launch文件 要如何編寫。但是那篇博客只是簡單的講解了一些 Launch 文件里面比較常用的幾個(gè) 標(biāo)簽如何使用。
這一篇博客和接下來的幾篇博客,我們將詳細(xì)的講解 Launch 文件要如何編寫。
使用 launch文件,我們可以一次性配置并且運(yùn)行很多節(jié)點(diǎn)。
至今,如果你按照我們的教程(ROS Learning)學(xué)習(xí)到這里,想必你一定運(yùn)行了許多的例子。你可能會對在許多的終端中運(yùn)行不同的節(jié)點(diǎn)感到麻煩,并且你會因?yàn)椴涣私馕覀冞\(yùn)行過的例子中的 launch文件 都做了什么事情會感到困擾。我們在ROS Learning教程中 的 beginner_Tutorials 和 learning_tf 的ROS 相關(guān)教程 中已經(jīng)學(xué)習(xí)簡單的 launch啟動腳本 如何編寫,現(xiàn)在的你所知道的launch文件的編寫技巧已經(jīng)無法滿足你現(xiàn)在想編寫更復(fù)雜更大型的launch啟動腳本文件了。所以這一篇博客和接下來的幾篇博客,我們會詳細(xì)的講 launch文件 的技巧,當(dāng)你學(xué)完這幾篇的博客,你會具備編寫大型launch啟動腳本的能力。
說了一堆廢話,接下來進(jìn)入正題。
2 . 使用launch啟動腳本文件:
<launch><nodepkg="turtlesim"type="turtlesim_node "name="turtlesim "respawn="true "/><nodepkg="turtlesim"type="turtle_teleop_key "name="teleop_key"required="true"launch?prefix="xterm ?e"/><nodepkg="agitr"type="subpose"name="pose_subscriber"output="screen"/> </launch>roslaunch 是如何允許我們一次啟動多個(gè)節(jié)點(diǎn)”?
基本的實(shí)現(xiàn)思想是列表,在一個(gè)指定的XML格式,一組節(jié)點(diǎn)需要在同一時(shí)間被啟動。你會很熟悉下面的列表,它展示啟動了海龜(turtlesim)模擬器的一個(gè)簡單的launch文件。
再我們深入研究launch文件的格式的細(xì)節(jié)前,讓我們看看這些文件都是如何使用的:
roslaunch 命令的使用格式:
# roslaunch package-name launch-file-name在 編寫簡單的啟動腳本文件 的博客中最后的小練習(xí)中,我們自己編寫了一個(gè)launch文件,如果一切工作正常的話,這個(gè)命令將會啟動3個(gè)節(jié)點(diǎn)。在開始任何一個(gè)節(jié)點(diǎn)前,roslaunch 將會確定 roscore節(jié)點(diǎn) 是否已經(jīng)在運(yùn)行,如果沒有,自動啟動它。
注意: 要小心,不要與 rosrun命令 混淆,rosrun 只能啟動一個(gè)節(jié)點(diǎn)。roslaunch 命令可以同時(shí)啟動多個(gè)節(jié)點(diǎn)。
擴(kuò)展 :你也可以在使用 roslaunch 啟動launch文件的時(shí)候沒有package-name這部分。要想做到這一定,launch-file-name 文件需要寫成絕對路徑的形式。只要可以讓 roalaunch 命令找到唯一的一個(gè) launch 文件,你就可以不提供 package-name 部分。舉例:
$ roslaunch ~/catkin_ws/src/beginner_turtorls/launch/xxx.launch關(guān)于 roslaunch 的一個(gè)重要的事實(shí),這個(gè)事實(shí)很容易被忽略,就是在launch文件中的所有節(jié)點(diǎn)幾乎被同一時(shí)間啟動。結(jié)果,我們不能確定這些節(jié)點(diǎn)初始化的順序。好在 ROS節(jié)點(diǎn) 不關(guān)系彼此的啟動順序。
為什么?
這個(gè)行為體現(xiàn)了ROS哲學(xué):每一個(gè)節(jié)點(diǎn)與其他的節(jié)點(diǎn)都應(yīng)該盡可能的獨(dú)立、不相關(guān)。
如果你想請求 roslaunch命令 請求詳細(xì)輸出( Requesting verbosity )信息的話。就像其他的命令行工具一樣,roslaunch 也有請求詳細(xì)輸出的選項(xiàng)。在你進(jìn)行調(diào)試程序的時(shí)候,使用 -v 參數(shù)對你是有幫助的,你可以看到 roslaunch 是如何解讀你的 launch文件 的詳細(xì)解釋。
# roslaunch -v package-name launch-file-name3 . 創(chuàng)建launch啟動腳本文件:
3-1 . 基本的成分:
3-1-1 . <launch>
最簡單的啟動文件是由一個(gè)包含了幾個(gè)節(jié)點(diǎn)元素的根元素(root element)組成。
根元素:launch文件是XML文檔,每一個(gè)XML文檔必須有且只有一個(gè)跟元素(root element)。對于ROS launch文件,根元素(root element)是由一對 launch 標(biāo)簽定義的。
<launch>... </launch>其他的所有元素標(biāo)簽都要寫在 <launch>...</launch> 便簽之間。
3-1-2 . <node>
啟動的節(jié)點(diǎn):任何一個(gè)launch文件的重點(diǎn)都是:節(jié)點(diǎn)(node)元素的集合。啟動的每一個(gè)節(jié)點(diǎn)(node)都要有自己獨(dú)一無二的名字(name)。一個(gè)節(jié)點(diǎn)(node)元素看上去就像下面這個(gè)樣子:
<nodepkg="package-name"type="executable-name"name="node-name"/>注意: 在節(jié)點(diǎn)(node)標(biāo)簽的末尾加上’ / ‘斜杠是重要的,并且也容易被忘記。’ / ’ 表明:這里不會再有”</node>“出現(xiàn),并且node元素定義完成。
XML解析器非常嚴(yán)格,如果你忘記了加’ / ‘,你要對這樣的錯(cuò)誤做好準(zhǔn)備:
你也可以寫成顯式關(guān)閉標(biāo)簽的形式:
<node pkg=". . . " type=". . . " name=". . . "></node>事實(shí)上,如果node(節(jié)點(diǎn))元素有children,就需要顯式標(biāo)簽來定義,children比如是:remap 元素或者 param 元素。這些元素會在下面介紹。
3-1-2-1 . 一個(gè)node(節(jié)點(diǎn))元素必需的三個(gè)屬性:pkg 、 type 和 name 屬性:
pkg 和 type 屬性確定了:啟動此節(jié)點(diǎn),ROS應(yīng)該運(yùn)行哪個(gè)程序。它們與 rosrun 的兩個(gè)命令行參數(shù)一樣,它們分別是:程序包名字 和 可執(zhí)行文件的名字。
name 屬性指定了一個(gè)節(jié)點(diǎn)的名字。這個(gè)節(jié)點(diǎn)程序會調(diào)用 ros::init() 函數(shù)內(nèi)有一個(gè)這個(gè)節(jié)點(diǎn)的 name 參數(shù),導(dǎo)致這個(gè)節(jié)點(diǎn)的 name 被改寫,所以這個(gè) name 屬性容易被覆蓋。
擴(kuò)展: ros::init() 函數(shù) 提供的 name 信息將會全面的覆蓋命名信息(launch文件中<node>標(biāo)簽里面的name 屬性),就算這個(gè)節(jié)點(diǎn)已經(jīng)以匿名name被創(chuàng)建。如果你想在 launch文件 中使用匿名name,使用anon 屬性 來替代name 屬性:
name="$(anon base_name)"但是請注意,多次使用同樣的基本名稱,將生成同樣的匿名name。這意味著,(一)我們參考launch文件中其他部分的name,但(二)我們必須小心的為每一個(gè)我們想要匿名的節(jié)點(diǎn)使用不同的base names。
3-1-2-2 . 查找節(jié)點(diǎn)(node)的日志文件(log files):
使用 roslaunch 命令 和 使用 rosrun 命令 單獨(dú)運(yùn)行每個(gè)節(jié)點(diǎn) 之間的重要區(qū)別是:默認(rèn)情況下,roslaunch 命令 從啟動節(jié)點(diǎn)開始,標(biāo)準(zhǔn)輸出信息會重定向到一個(gè)日志文件中,而不會像 rosrun 命令那樣,將 log 信息顯示在終端(console)上。
日志文件所在路徑: ~/.ros/log/run_id/node_name-number-stdout.log
當(dāng)主機(jī)( master )被啟動,run_id 是被生成的唯一的標(biāo)識符。在log文件名中的number是一個(gè)小整數(shù),表示節(jié)點(diǎn)的數(shù)量。例如:運(yùn)行上面的launch文件,2個(gè)節(jié)點(diǎn)的標(biāo)準(zhǔn)輸出信息將會傳給這些節(jié)點(diǎn)的日志文件(log files):
turtlesim-1-stdout.log telep_key-3-stdout.log這些日志文件可以被任何的文本編輯器(比如:gedit、vim、cat)打開。
3-1-2-3 . 將標(biāo)準(zhǔn)輸出信息顯示在終端(console)上
Q: 如何將標(biāo)準(zhǔn)輸出信息顯示在終端(console)上?
A: 在 node 元素中使用 output 屬性:
帶這個(gè)屬性啟動的節(jié)點(diǎn)會將標(biāo)準(zhǔn)輸出信息顯示在終端的窗口中,而不會保存在日志文件中。這也解釋了為什么這個(gè)帶有output="screen"的節(jié)點(diǎn)(node) 的日志文件在上面日志文件列表中丟失的原因。
擴(kuò)展: node 元素的 output 屬性只能影響這個(gè)節(jié)點(diǎn)自己。除了 output 屬性,我們可以使用 roslaunch命令行工具的 --screen 命令行選項(xiàng)強(qiáng)制性的在終端的窗口中顯示所有節(jié)點(diǎn)的輸出信息。
roslaunch --screen package-name launch-file-name3-1-2-4 . 請求重生(respawning) :
啟動完所有請求啟動的節(jié)點(diǎn)之后,roslaunch 監(jiān)測每一個(gè)節(jié)點(diǎn),讓它們保持正常的運(yùn)行狀態(tài)。對于每一個(gè)節(jié)點(diǎn)(node),當(dāng)它終止( terminates)時(shí),我們可以要求 roslaunch 重新啟動它,這就是 respawn 屬性做的事情:
respawn="true" -- This can be useful, for example, for nodes that might terminate prematurely, due to software crashes, hardware problems, or other reasons. The respawn attribute is not really necessary in our example—All three programs are quite reliable—but we include it for the turtlesim_node to illustrate how respawning works. If you close the turtlesim window, the corresponding node will terminate. ROS quickly notices this and, since that node is marked as a respawn node, a new turtlesim node, with its accompanying window, appears to replace the previous one.3-1-2-5 . 必需節(jié)點(diǎn)(Requiring):
讓一個(gè)節(jié)點(diǎn)可以重生的另一種方法是:宣布這個(gè)節(jié)點(diǎn)是必需的(require):
required="true"當(dāng)一個(gè)必需的節(jié)點(diǎn)終止時(shí),roslaunch會做出響應(yīng),終止其他所有的節(jié)點(diǎn)并退出它自己。這種行為機(jī)制是有用的。例如,對于一些節(jié)點(diǎn)(一)它們非常的重要,如果它們失敗了它,那么整個(gè)會話應(yīng)該被放棄,或者這些節(jié)點(diǎn)(二)不能使用重生( respawn )屬性完美的重新啟動,在這些情況下,我們都需要對這個(gè) 節(jié)點(diǎn)(node)使用 required="true" 屬性。上面 roslaunch 例子文件中,我們給 turtle_teleop_key 節(jié)點(diǎn)使用了這個(gè) required 屬性。如果你關(guān)閉了運(yùn)行 teleoperation 節(jié)點(diǎn)的窗口,roslaunch 將會殺死其他的2個(gè)節(jié)點(diǎn)退出。
注意: 由于 required 屬性和 respawn 屬性的含義,所以如果你給單個(gè)的一個(gè)節(jié)點(diǎn)同時(shí)設(shè)置了這2個(gè)屬性,roslaunch 命令會抱怨。所以不要這樣設(shè)置。
3-1-2-6 . 讓每一個(gè)節(jié)點(diǎn)在單獨(dú)的終端窗口中啟動它們自己:
使用 roslaunch 命令 的一個(gè)潛在的缺點(diǎn):相比我們原來對每個(gè)節(jié)點(diǎn)在單獨(dú)的終端使用 rosrun 命令啟動的做法,roslaunch 則是讓所有的節(jié)點(diǎn)共享同一個(gè)終端。 那些只需要生產(chǎn)簡單的日志消息文件而不需要終端(console)輸入的節(jié)點(diǎn)是容易管理的,而那些依賴終端輸入的節(jié)點(diǎn),比如 turtle_teleop_key 節(jié)點(diǎn),它可能要優(yōu)先的保留在獨(dú)立的終端上。
慶幸的是,roslaunch 提供了一個(gè)簡單的屬性去實(shí)現(xiàn)這一點(diǎn),在 node 元素里使用 launch-prefix 屬性:
launch-prefix="command-prefix"在例子launch文件中,我們給 teleoperation 節(jié)點(diǎn)使用了這個(gè)屬性:
launch-prefix="xterm -e"因?yàn)檫@個(gè)屬性,啟動這個(gè) node 元素的 rosrun 命令大致相當(dāng)于:
xterm -e rosrun turtlesim turtle_teleop_key正如我們所知道的,xterm 命令會開一個(gè)新的終端窗口。 -e 參數(shù)告訴 xterm :執(zhí)行其命令行剩余部分(rosrun turtlesim turtle_teleop_key)。
擴(kuò)展: launch-prefix 屬性不是只能使用 xterm 。它還可以使用gdb 或者 valgrind 或者 nice 命令。
3-1-2-7 . 在一個(gè)命名空間內(nèi)啟動一個(gè)節(jié)點(diǎn):
<launch><nodename="turtlesim_node "pkg="turtlesim"type="turtlesim_node "ns="sim1"/><nodepkg="turtlesim"type="turtle_teleop_key "name="teleop_key"required="true"launch ?prefix="xterm ?e"ns="sim1"/><nodename="turtlesim_node "pkg="turtlesim"type="turtlesim_node "ns="sim2"/><nodepkg="a gitr "type="pubvel"name="velocity_publisher "ns="sim2"/> </launch>在 node 元素中指定 ns 屬性:
ns="namespace"在例子launch文件中,使用這個(gè)屬性創(chuàng)建了兩個(gè)無關(guān)的 turtlesim 模擬器。
turtlesim 話題名字(turtle1/cmd_vel、turtle1/color_sensor 和 turtle1/pose )被從全局命名空間移動到 /sim1 和 /sim2 的單獨(dú)命名空間里。
3-1-2-8 . 重映射名字:
在啟動一個(gè)節(jié)點(diǎn)的時(shí)候,有兩種方法創(chuàng)建重映射:
在終端命令行中啟動一個(gè)節(jié)點(diǎn)時(shí),要重新給這個(gè)節(jié)點(diǎn)命名:給出一個(gè)節(jié)點(diǎn)原來的名字和新的名字,中間用:=分開。
original-name:=new-name例如,在運(yùn)行turtlesim實(shí)例時(shí),我們現(xiàn)在想把發(fā)布姿態(tài)數(shù)據(jù)的話題/turtle1/pose名稱改為:/tim,那么命令就是這樣的:
rosrun turtlesim turtlesim_node turtle1/pose:=tim在launch文件中重新命名:使用 remap 元素:
<remap from="original-name" to="new-name" />如果這個(gè) remap 是 launch 元素的一個(gè)child(子類),與 node 元素同一層級, 并在 launch 元素內(nèi)的最頂層。那么這個(gè) remapping 將會作用于后續(xù)所有的節(jié)點(diǎn)。
這個(gè) remap 元素也可以作為 node 元素的一個(gè)child(子類)出現(xiàn)。下面這個(gè)就是使用模板:
<node node-attributes ><remap from="original-name" to="new-name" />. . .</node>例如:上面命令行命令如果在launch文件中,就是下面這個(gè)樣子的:
<node pkg="turtlesim" type="turtlesim_node"name="turtlesim" ><remap from="turtle1/pose" to="tim" /></node>3-2 . 其他launch文件元素:
這一節(jié)介紹幾個(gè)額外的 roslaunch 結(jié)構(gòu)元素。
3-2-1 . <include> 元素
3-2-1-1 . file 屬性
包含(including)其他文件:
<include file="path-to-launch-file" />這個(gè) file 屬性期望我們添加想要包含的文件的完整路徑。但是大多數(shù)時(shí)候,include 元素使用一個(gè) find 命令來搜索一個(gè)程序包,代替一個(gè)明確的完整路徑:
<include file="$(find package-name)/launch-file-name" /><launch><nodepkg="turtlesim"type="turtlesim_node "name="turtlesim "><remapfrom="turtle1 /cmd_vel"to="turtle1 /cmd_vel_reversed"/></node><nodepkg="turtlesim"type="turtle_teleop_key "name="teleop_key"launch?prefix="xterm ?e"/><nodepkg="a gitr "type="reverse_cmd_vel"name="reverse_velocity "/> </launch>
注意:roslaunch 命令 將會在程序包(package)的子目錄里搜索launch文件。 include 元素必須要指定文件的特定路徑,你可以使用 find 來找到這個(gè)程序包,但是卻不能在這個(gè)程序包目錄里面自動的找到某個(gè)子目錄里有l(wèi)aunch文件。舉例:
這樣做是正確的:<include file = "find learning_tutrols"/launch/start_demo.launch" / >
這樣做是錯(cuò)誤的:<include file = "find learning_tutrols"/start_demo.launch" />
你可以使用 roslaunch 命令:roslaunch learning_tutrols start_demo.launch ,這樣是可以成功運(yùn)行的。但是同樣的程序包名和launch文件名使用include元素就會失敗。
3-2-1-2 . ns 屬性
include 元素也支持 ns 屬性,可以讓這個(gè)文件里的內(nèi)容推送到一個(gè)命名空間里面:
<include file=". . . " ns="namespace" />一般我們都會給 include 元素設(shè)置一個(gè) ns 屬性。
3-2-2 . 啟動參數(shù)(Launch arguments)
為了幫助launch文件配置,roslaunch 支持 launch arguments(啟動參數(shù)),也叫做 arguments 或者 args。它的功能有點(diǎn)像一個(gè)可執(zhí)行程序的局部變量。它的優(yōu)點(diǎn)是,你可以通過編寫launch文件來避免編寫重復(fù)代碼。為少數(shù)的信息使用arguements,可以改變程序的運(yùn)行。
為了說明這個(gè)道理,我們的例子launch文件中使用了一個(gè)argument,叫做 use_sim3,目的是為了確定是否啟動了3個(gè)turtlesim副本或只有2個(gè)。
Z:盡管術(shù)語argument和parameter在許多計(jì)算機(jī)環(huán)境中稍微可以互換使用,它們的含義在ROS中有很大的不同。Parameters(參數(shù))在一個(gè)運(yùn)行的ROS系統(tǒng)中是變量(values),它被存儲在parameter服務(wù)器中,活動(或者叫:運(yùn)行)的節(jié)點(diǎn)通過ros::param::get()函數(shù)訪問它,并且用戶可以通過 rosparam 命令行工具使用它。
相比之下,arguments只有在launch文件里合法,它們的值不是直接提供給節(jié)點(diǎn)。
<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>
3-2-3 . Declaring arguments(聲明參數(shù))
在launch文件中,要聲明一個(gè)參數(shù)的存在,我們使用arg元素:
<arg name="arg-name" />聲明里面只有一個(gè) name 是起不上什么作用的,這就像是你在程序中定義了一個(gè) int 類型的變量,但是你并沒有使用它一樣。(你至少還需要給 arg 元素分配 default 屬性或 value 屬性,請看下面)
3-2-3-1 . Assigning argument values(分配argument的數(shù)值)
在launch文件中使用的每一個(gè)argument必須給它分配一個(gè) value(賦值)。有這么一下幾種方法來實(shí)現(xiàn)這一點(diǎn):
在命令行中你可以這樣做:給 roslaunch 提供一個(gè) value :
roslaunch package-name launch-file-name arg-name:=arg-value另外,在launch文件中,你可以提供一個(gè) value(賦值) 作為 arg 聲明的一部分,使用下面的兩種語法之一就可以:
<arg name="arg-name" default="arg-value" /> <arg name="arg-name" value="arg-value" />這兩種語法的唯一不同是:命令行是argument可以覆蓋default的值,但是不能覆蓋 value 。在例子launch文件中,use_sim3 節(jié)點(diǎn)的 default 值為 0,所以它可以通過命令行改變值,就像下面這樣:
roslaunch agitr triplesim.launch use_sim3:=1如果我們修改了這個(gè)例子launch文件:使用value替換default。那么上面這個(gè)命令執(zhí)行的時(shí)候會出現(xiàn)錯(cuò)誤,因?yàn)槭褂?value屬性 配置的argument的值是不允許改變的。
3-2-3-2 . Accessing argument values(獲取argument的數(shù)值)
一旦聲明了一個(gè)argument,并且使用 value 屬性給它分配值,你可以在程序中通過arg substitution來使用它的 value 屬性的值。像是這樣子:
$(arg arg-name)$() 這個(gè)符號出現(xiàn)的任何地方,roslaunch命令 都將會把它替換成給定argument 的值(value)。在例子launch文件中,我們使用 use_sim3 參數(shù)(argurnt),???????一個(gè) group 元素內(nèi)的 if 屬性。(下面我們將會簡短的介紹 if 和 group )
3-2-4 . Sending argument values to included launch files(給包含(included)的launch文件傳遞argument)
在argument的傳遞上有一個(gè)限制,就是argument不能傳遞給 include 元素里包含的子launch文件使用。這個(gè)問題非常重要,因?yàn)檫@個(gè) argument 就像是一個(gè)局部變量,它不能被包含的launch文件所 “繼承” 。
解決這個(gè)問題的方法:在 include 元素中插入 arg 元素作為 include 元素的子類(children),就像是這樣:
<include file="path-to-launch-file"><arg name="arg-name" value="arg-value"/>. . . </include>注意,這里的 arg 元素不同于我們已經(jīng)知道的 arg 聲明,在 inchude 標(biāo)簽內(nèi)的arguments是給包含(included) 的launch文件提供的arguments,不是為本launch文件提供的。
一種常見的情況是,被包含(included)的launch文件和本launch文件會有共同的參數(shù)。在這種情況下,我們希望這些值(values)永遠(yuǎn)不變。像這樣的元素,在這兩個(gè)地方使用相同的argument name(參數(shù)名),要這樣做:
<arg name="arg-name" value="$(arg arg-name)" />在這種情況下,第一個(gè) arg-name 和往常一樣。第二個(gè) arg-name 是launch文件中提供的。結(jié)果是,這兩個(gè)launch文件中給定的argument具有相同的值(value)。
3-2-5 . Creating groups (創(chuàng)建組)
最后一個(gè)要介紹的launch文件特性就是,再來說說:group 元素,它提供了一個(gè)方便的方法來在一個(gè)大型的launch文件中組織節(jié)點(diǎn)。group元素可以達(dá)到兩個(gè)目的:
1 . 組(group)可以把幾個(gè)節(jié)點(diǎn)推送到同一個(gè)命名空間中。
<group ns="namespace" />. . . </group>2 . 組(groups)里面的每一個(gè)節(jié)點(diǎn)在啟動的時(shí)候都會給定默認(rèn)的命名空間。
:如果一個(gè)已經(jīng)被分組的節(jié)點(diǎn)有自己的 ns 屬性,那么結(jié)果:被啟動的節(jié)點(diǎn)的命名空間會出現(xiàn)嵌套的關(guān)系: /group-namespace/ns-namespace/node-name 。
3 . 組(groups)可以通過 判別條件 來啟用或禁用節(jié)點(diǎn)(nodes):
<group if="0-or-1" />. . . </group>如果 if 屬性的值是 1 ,<group> 標(biāo)簽內(nèi)封閉的元素(elements)會被包含。如果 if 屬性 值是 0 ,則 <group> 標(biāo)簽內(nèi)包含的元素會被忽略。 unless 屬性的工作方式類似 if 屬性,但是含義顛倒:
<group unless="1-or-0" />. . . </group>當(dāng)然了,通常我們不會給這些屬性使用簡單的 0 或 1 這樣的幅值。建議:結(jié)合 arg 的 $() 技術(shù),它們會將你的launch文件的配置變得非常的強(qiáng)大。
注意: 注意 1 和 0 是唯一的合法值。具體來說,你通常會使用布爾(boolean)的 AND 和 OR 操作符,而不會直接使用 1 或 0 。
在例子launch文件中,有一個(gè)group元素具有ns 和 if 這兩屬性。這個(gè) group 元素的 ns 屬性:將這個(gè) group 元素內(nèi)的兩個(gè)節(jié)點(diǎn)推送到 sim3 命名空間。if 屬性:基于use_sim3 參數(shù)的值來落實(shí):是啟動還是禁止 group 元素內(nèi)包含的節(jié)點(diǎn)。
擴(kuò)展: 遺憾的是,只有這三個(gè)屬性( ns 、if 、unless )可以通過 group 元素向下傳遞給 group 元素內(nèi)包含的 node (節(jié)點(diǎn))元素。
例如,我們可能會想給 group 元素添加一個(gè) output="screen" 來讓這個(gè) group 元素內(nèi)的節(jié)點(diǎn)啟動后輸出的信息都顯示在終端窗口里,但是我們不可以這樣設(shè)置,我們必須要對每一個(gè) node 元素直接給予 output="screen" ,這樣才能達(dá)到我們的要求。
完
By The Way: 可能以后,這篇博客,我還會繼續(xù)完善。現(xiàn)在的這些關(guān)于:如何編寫Launch文件的語法 ,基本上介紹的差不多了。
轉(zhuǎn)載于:https://www.cnblogs.com/aobosir/p/5928530.html
總結(jié)
以上是生活随笔為你收集整理的ROS Learning-032 (提高篇-010 Launch)Launch 深入研究 --- (启动文件编程)ROS 的 XML语法简介...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习 Softmax classif
- 下一篇: 【Redis】Redis分布式集群几点说