這個教程就是為大型項目設計roslaunch文件的一些建議潜慎,使設計出來的文件能夠適用于更多的場景
1 介紹
一個大的應用一半有很多互相連接的node,每一個都有很多參數(shù)垒手。
一個roslaunch 文件,將會把所有能夠讓機器人正常運行的東西啟動驳遵,我們將會瀏覽一個launch文件。
2 頂級結構(Top-level organization)
這里是頂級啟動文件(在 "rospack find 2dnav_pr2/move_base/2dnav_pr2.launch")
<launch>
<group name="wg">
<include file="$(find pr2_alpha)/$(env ROBOT).machine" />
<include file="$(find 2dnav_pr2)/config/new_amcl_node.xml" />
<include file="$(find 2dnav_pr2)/config/base_odom_teleop.xml" />
<include file="$(find 2dnav_pr2)/config/lasers_and_filters.xml" />
<include file="$(find 2dnav_pr2)/config/map_server.xml" />
<include file="$(find 2dnav_pr2)/config/ground_plane.xml" />
<!-- The navigation stack and associated parameters -->
<include file="$(find 2dnav_pr2)/move_base/move_base.xml" />
</group>
</launch>
這個文件包含一組其他文件設置唆迁。每個 included files 包含了和系統(tǒng)某個部分有關的node和參數(shù)。比如位置唐责,傳感器進程和路徑規(guī)劃瘾带。
設計建議:Top-level啟動文件應該盡量短小一些鼠哥,并且包含其他程序的子組件看政,通常會改變ROS參數(shù)
這使它很容易交換系統(tǒng)的一部分,我們只會將會看到允蚣。
3 機器標簽和環(huán)境變量
我們希望能控制哪些node在哪些機器上運行,這是為了負載平衡和帶寬管理森渐。為了重用性,我們不希望硬編碼機器名字出現(xiàn)在roslaunch文件里冒晰。
第一個include是:
<include file="$(find pr2_alpha)/$(env ROBOT).machine" />
這個文件所做的第一件事中用env代替了環(huán)境變量ROBOT。例如耐齐,如果:
export ROBOT=pre
那么,launch文件會使pre.machine文件被包含埠况。
設計建議,使用env代替可以允許啟動文件的一部分根據(jù)環(huán)境變量的不同而不同
接下來恕出,我們來看一個machine文件(pre.machine in the pr2_alpha package):
<launch>
<machine name="c1" address="pre1" ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" default="true" />
<machine name="c2" address="pre2" ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" />
</launch>
這個文件設置了一個邏輯機名稱,如C1金蜀,C2和真實機主,如pre2的畴,的映射關系。它甚至可以允許控制你登陸的用戶护桦。
一旦映射關系建立,他就可以在node啟動時被使用二庵。例如贪染,在包含的文件config/new_amcl_node.xml 中包含了這樣一句:
<node pkg="amcl" type="amcl" name="amcl" machine="c1">
4 參數(shù)催享、命名空間和YAML文件
我們看一下move_base.xml文件的一部分:
<node pkg="move_base" type="move_base" name="move_base" machine="c2">
<remap from="odom" to="pr2_base_odometry/odom" />
<param name="controller_frequency" value="10.0" />
<param name="footprint_padding" value="0.015" />
<param name="controller_patience" value="15.0" />
<param name="clearing_radius" value="0.59" />
<rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find 2dnav_pr2)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find 2dnav_pr2)/move_base/local_costmap_params.yaml" command="load" />
<rosparam file="$(find 2dnav_pr2)/move_base/global_costmap_params.yaml" command="load" />
<rosparam file="$(find 2dnav_pr2)/move_base/navfn_params.yaml" command="load" />
<rosparam file="$(find 2dnav_pr2)/move_base/base_local_planner_params.yaml" command="load" />
</node>
這部分啟動文件負責啟動move_base node。首先被包含的是一個映射(remap)痰憎。Move_base被設計接收topic“odom”發(fā)送回來的路程數(shù)據(jù)攀涵。我們做了一個 pr2_base_odometry 到odom的映射。
后面的<param>在<node>標簽內(nèi)部以故,表示是私有參數(shù)。
再后面的<rosparam>是從yaml文件里讀取參數(shù)据德,yaml文件是一種可以讓人閱讀的文件,并且允許包含復雜的數(shù)據(jù)類型棘利。
下面是costmap_common_params.yaml 文件的一部分:
raytrace_range: 3.0
footprint: [[-0.325, -0.325], [-0.325, 0.325], [0.325, 0.325], [0.46, 0.0], [0.325, -0.325]]
inflation_radius: 0.55
# BEGIN VOXEL STUFF
observation_sources: base_scan_marking base_scan tilt_scan ground_object_cloud
base_scan_marking: {sensor_frame: base_laser, topic: /base_scan_marking, data_type: PointCloud, expected_update_rate: 0.2,
observation_persistence: 0.0, marking: true, clearing: false, min_obstacle_height: 0.08, max_obstacle_height: 2.0}
上面的ns即為namespace。
沒有標注ns的即包含在當前命名空間水援。
5 再利用已有的啟動文件
首先來看一個啟動文件,它換在Gazebo上運行蜗元,只需要改變map_server node。
<launch>
<include file="$(find pr2_alpha)/sim.machine" />
<include file="$(find 2dnav_pr2)/config/new_amcl_node.xml" />
<include file="$(find 2dnav_pr2)/config/base_odom_teleop.xml" />
<include file="$(find 2dnav_pr2)/config/lasers_and_filters.xml" />
<node name="map_server" pkg="map_server" type="map_server" args="$(find gazebo_worlds)/Media/materials/textures/map3.png 0.1" respawn="true" machine="c1" />
<include file="$(find 2dnav_pr2)/config/ground_plane.xml" />
<!-- The naviagtion stack and associated parameters -->
<include file="$(find 2dnav_pr2)/move_base/move_base.xml" />
</launch>
第一個不同就是系冗,因為我們知道我們在仿真奕扣,所以只需要用sim.machine文件而不是一個替代參數(shù),第二掌敬,這一行:
<include file="$(find 2dnav_pr2)/config/map_server.xml" />
被替換為
<node name="map_server" pkg="map_server" type="map_server" args="$(find gazebo_worlds)/Media/materials/textures/map3.png 0.1" respawn="true" machine="c1" />
包含的文件在第一種情況下只包含了一個node惯豆,而第二種情況則包含了一個映射文件。
6 參數(shù)覆蓋
上面的技巧有時候會很不方便使用奔害。假設我們想要使用2dnav_pr2楷兽,只改變本地分辨率參數(shù)到0.5.我們可以直接改變local_costmap_params.yaml。這是最簡單的臨時修改华临,但是這意味著我們沒辦法檢查修改后的文件芯杀,把它返回去。我們可以復制一個文件然后修改它。然后改變move_base.xml去包含它揭厚,然后把2dnav_pr2.launch 改變?yōu)樾薷暮蟮膍ove_base.xml却特,這樣做的好處是棋弥,如果我們使用了版本控制器诚欠,我們就不會發(fā)生源文件改變的錯誤了。
還有一個方法沒看懂粉寞,自己去官網(wǎng)看吧,說另一個:
我們可以使用roslaunch的重寫行為唧垦,參數(shù)是按照順序設置的液样。這樣,我們可以用后面的的top-level文件重寫源文件:
<launch>
<include file="$(find 2dnav_pr2)/move_base/2dnav_pr2.launch" />
<param name="move_base/local_costmap/resolution" value="0.5"/>
</launch>
這個方法的硬傷是坊秸,他會讓程序難以理解,想要知道一個東西確切的值褒搔,還需要遍歷整個啟動文件喷面,十分蛋疼。
7ROSlaunch 參數(shù)
roslaunch XML documentation
這是一個比起來重寫更加常用和清晰的改變東西的方法惧辈。一般首選這個。
看到這里看的累死了念逞,教程的語言越來越超出了我的英語能力范圍县昂,我要學點別的換換腦子。