參考博客:
(1) 史上最全的launch的解析來啦,木有之一歐
1 ROS工作空間簡介
2 元功能包
src目錄下可以包含多個功能包,假設需要使用機器人導航模塊,但是這個模塊中包含著地圖、定位、路徑規劃等不同的功能包,它們的邏輯關系如下:
在Linux系統中為了更方便的組織工程項目(這里針對的是項目文件,即功能包),出現了“元功能包”的概念。這個是一個“虛包”,就是這個功能包的src目錄下沒有源文件,因此自身不會實現專屬功能,其功能的實現完全依賴于其他的功能包,起到一個組織功能包的作用。
以導航模塊中的元功能包為例:
navigation功能包為元功能包(metapackage),元功能包中由于沒有src目錄因此無需添加任何依賴項,因為這個功能包沒有自己的專屬功能,它的功能是借助其他的功能包的功能來實現的。元功能包有兩個文件即可:一個是package.xml文件:用于聲明元功能包所依賴的其他功能包;另一個是CMakelist.txt文件:用于指定功能包之間的依賴關系。
CMakelist.txt
cmake_minimum_required(VERSION 3.0.2)
project(navigation)
find_package(catkin REQUIRED)
catkin_metapackage() // 只需添加此條內容即可
package.xml
<exec_depend>amcl</exec_depend>
<exec_depend>base_local_planner</exec_depend>
<exec_depend>carrot_planner</exec_depend>
<exec_depend>clear_costmap_recovery</exec_depend>
<exec_depend>costmap_2d</exec_depend>
<exec_depend>dwa_local_planner</exec_depend>
<exec_depend>fake_localization</exec_depend>
<exec_depend>global_planner</exec_depend>
<exec_depend>map_server</exec_depend>
<exec_depend>move_base</exec_depend>
<exec_depend>move_base_msgs</exec_depend>
<exec_depend>move_slow_and_clear</exec_depend>
<exec_depend>navfn</exec_depend>
<exec_depend>nav_core</exec_depend>
<exec_depend>rotate_recovery</exec_depend>
<exec_depend>voxel_grid</exec_depend> <export> <metapackage/> // 表征:這個功能包為元功能包
</export>
3 Launch文件
Launch文件:源文件的組織者
① 節點啟動標簽
<launch> <node pkg = "turtlesim" type = "turtlesim_node" name = "my_node"/> <node pkg = "turtlesim" type = "turtle_teleop_key" name = "my_key"/>
</launch>
Tip:因為ROS中采用多線程,因此節點的運行不會按照節點在launch中排列順序進行。
pkg:功能包的名稱
type:節點本來的名稱,這個名稱和節點所在.cpp源文件的文件名一致
name:節點重映射的名稱,相當于在系統中給節點所在源文件改了個名字
launch標簽有一個子級標簽deprecated,用于文本說明:
<launch deprecated="this vision is out-of-date!">
</launch>
如果認為給很多節點取名太麻煩,可以使用name=”$(anon node_name)”標簽在節點node_name名稱之后加一些隨機數,使得該節點名稱在整個catkin編譯項目中唯一:
<launch deprecated="this vision is out-of-date!"> <!-- the topic of turtlesim_node is /turtle1/cmd_vel --> <node pkg="turtlesim" type="turtlesim_node" name="$(anon my_node)"/> <!-- the topic of turtle_teleop_key is /turtle1/cmd_vel --> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"/>
</launch>
意外關閉后自動啟動的子級標簽
respawn = true|false 表示:如果節點意外關閉是否重新啟動
<launch> <node pkg="turtlesim" type="turtlesim_node" name="my_node" respawn="true"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" respawn="true"/>
</launch>
節點延遲啟動的子級標簽,一般結合節點重啟動是使能標簽respawn(如果節點異常退出運行,那么該節點會被重新啟動)一起使用
<launch> <node pkg="turtlesim" type="turtlesim_node" name="my_node" respawn="true" respawn_delay="10"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" respawn="true" respawn_delay="10"/>
</launch>
如果XXX節點結束運行(XXX節點被殺死),則所有節點都停止運行
<launch> <node pkg="turtlesim" type="turtlesim_node" name="my_node" required="true"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" />
</launch>
給節點名稱添加前綴(給節點添加命名空間)的子級標簽
<launch> <node pkg="turtlesim" type="turtlesim_node" name="my_node" ns="hello"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key"/>
</launch>
② 參數設置標簽
設置global全局參數
<launch><param name="var" type="int" value="10"/>
</launch>
結合標簽設置帶有命名空間的私有參數
<launch><node pkg="turtlesim" type="turtlesim_node" name="my_node"/><node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"><param name="var1" type="int" value="20"/></node>
</launch>
③ 參數打包輸入輸出刪除的標簽
從.yaml文件中讀取參數:
<launch><rosparam command="load" file="$(find test01)/launch/params.yaml"/><node pkg="turtlesim" type="turtlesim_node" name="my_node"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"/> <param name="var" type="int" value="10"/>
</launch>
將.yaml參數文件中的參數導入參數服務器時,我們還可以給這些參數添加namespace命名空間:
<launch> <node pkg="turtlesim" type="turtlesim_node" name="my_node"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"/> <param name="var" type="int" value="10"/> <rosparam command="load" file="$(find test01)/launch/params.yaml" ns="hello"/>
</launch>
將參數打包輸入進.yaml文件中,這樣做啥變量都沒導進去:
<launch> <rosparam command="dump" file="$(find test01)/launch/input.yaml"/> <node pkg="turtlesim" type="turtlesim_node" name="my_node"/> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"/> <param name="var" type="int" value="10"/>
</launch>
我們要想導入參數必須另建一個.launch文件,在使用上述launch文件啟動完所有節點之后,在另一個launch文件中執行該功能包參數的導出操作:
<launch><rosparam command="dump" file="$(find test01)/launch/input.yaml" />
</launch>
<launch> <rosparam command="dump" file="$(find test01)/launch/input.yaml"/> <rosparam command="delete" param="/hello/n1"/>
</launch>
④ 參數統一管理的標簽
<launch> <arg name="car_width" default="[1,2,3,4]" doc="the width of car"/> <rosparam param="a_list">$(arg car_width)</rosparam> <rosparam> Name: a: 9 b: "hello" c: $(arg car_width) </rosparam>
</launch>
⑤ 改topic名稱的標簽
<launch> <!-- the topic of turtlesim_node is /turtle1/cmd_vel --> <node pkg="turtlesim" type="turtlesim_node" name="my_node"/> <remap from="/turtle1/cmd_vel" to="new_topic"/>
</launch>
⑥ 節點組織標簽
就是給被<group>…</group>
包含的所有參數、節點的屬性加上了namespace
<launch deprecated="this vision is out-of-date!"> <group ns="family"> <!-- the topic of turtlesim_node is /turtle1/cmd_vel --> <node pkg="turtlesim" type="turtlesim_node" name="my_node"/> <!-- the topic of turtle_teleop_key is /turtle1/cmd_vel --> <node pkg="turtlesim" type="turtle_teleop_key" name="my_key" output="screen"/> <rosparam command="load" file="$(find test01)/launch/params.yaml" ns="hello"/> <arg name="car_width" default="[1,2,3,4]" doc="the width of car"/> <rosparam param="a_list" value="$(arg car_width)"/> <rosparam> Name: a: 9 b: "hello" c: [1,2,3,4] </rosparam> <param name="var" type="int" value="$(arg car_width)"/> </group>
</launch>
⑦ 啟動其他launch文件的標簽
<launch> <include file="$(find test01)/launch/test01_launch.launch"> <arg name="car_width" default="10"/> </include>
</launch>
4 功能包/源文件/launch文件組織工具
文件組織形式如下所示:
5 功能包絕對路徑替換標簽
標簽格式:$(find package_name)
使用示例:
<launch> <include file="$(find tf2_turtle)/launch/setupGUI.launch"/>
</launch>
6 工作空間下絕對路徑替換標簽
下面是test1.launch調用setupGUI.launch文件的代碼,并且兩個launch文件在一個文件夾之中:
<launch> <include file="$(dirname)/setupGUI.launch"/>
</launch>
$(dirname)代表“test1.launch文件所在工作空間的絕對地址
7 Launch文件
列出幾個Launch文件自測一下學習成果
<?xml version="1.0"?>
<launch><!-- 加載車模型 --><include file="$(find vehicle_description)/launch/estima_black.launch" /><!-- --><node pkg="car_simulation" type="car_model_node" name="car_simulation" output="screen" />
</launch>
<launch><include file="$(find global_routing)/launch/global_routing.launch"/><!-- 車輛仿真 --><include file="$(find car_simulation)/launch/car_simulation.launch" /><!-- rviz --><node pkg="rviz" type="rviz" name="rviz" args="-d $(find global_routing)/config/planning_demo.rviz"/>
</launch>
<?xml version="1.0"?>
<launch><!-- 其他launch文件傳入的參數 --><arg name="is_planner"/><arg name="is_lateral_optimization"/><arg name="is_change_lane"/><arg name="is_carla_simulation"/><arg name="ego_vehicle_name"/><arg name="is_parking"/><arg name="is_goal"/><!-- 模擬動態障礙物的加載文件,這些都是錄好的軌跡點,播放這個文件就可以實現障礙物移動 --><param name="obstacle_test_path" value="$(find dynamic_routing)/obstacle_files"/><!-- 加載存儲的其他參考線數據 --><param name="referenceline_path" value="$(find dynamic_routing)/other_referenceline_files"/><!-- yaml文件 --><param name="yaml_path" value="$(find dynamic_routing)/config"/><!-- 規劃算法選擇 --><param name="use_what_planner" value="$(arg is_planner)"/><!-- 變道決策是否開啟 --><param name="change_lane" value="$(arg is_change_lane)"/><!-- 是否使用二次規劃,選擇了lattice規劃,選擇這個才有效果 --><param name="use_lateral_optimization" value="$(arg is_lateral_optimization)"/><!-- 是否選擇carla聯合仿真 --><param name="carla_simulation" value="$(arg is_carla_simulation)"/><!-- role_name --><param name="role_name" value="$(arg ego_vehicle_name)"/><!-- carla 停車場景 --><param name="parking_mode" value="$(arg is_parking)"/><!-- 在frenet規劃下的參數設置,lattice規劃不用這些 --><!-- COLLISION_CHECK_THRESHOLD 距離障礙物的最短距離 --><param name="COLLISION_CHECK_THRESHOLD" type="double" value="2" /><!-- 調整軌跡的長度 --><param name="MaxT" type="double" value="11" /><param name="MinT" type="double" value="9" /><!-- 判斷與終點的停車距離閾值 --><param name="goal_distanse" type="double" value="$(arg is_goal)"/><!-- 打開 Hybrid_a_star 的測試圖 --><!-- mapserver提供了一個ROS節點,該節點通過一個ROS Service來提供地圖數據 --><node name="map_server" pkg="map_server" type="map_server" args="$(find dynamic_routing)/maps/map.yaml" ><param name="frame_id" value="map" /></node><!--Open palnner的launch參數,順便加載dynamic節點 --><include file="$(find dynamic_routing)/launch/op_common_params.launch" /><!-- DWA --><arg name="dwa_params" default="$(find dynamic_routing)/config/dwa_params.yaml"/><rosparam command="load" file="$(arg dwa_params)"/>
</launch>
<?xml version="1.0"?>
<launch><!-- 是否使用carla聯合仿真 --><arg name="carla" default="false"/> <arg name="ego_vehicle_name" default="ego_vehicle"/> <param name="carla_simulation" value="$(arg carla)"/><param name="role_name" value="$(arg ego_vehicle_name)"/><!-- 不能改這里的參數 --><arg name="parking" default="false"/><param name="parking_mode" value="$(arg parking)"/><!-- ros單獨仿真下的controller,carla不適用: 1 stanley 2 lqr 3 pure_pursuit4 pid 5 mpc --><arg name="control" value="2"/> <param name="use_what_controller" value="$(arg control)"/><!-- planner: 1是純frenet規劃2是lattice規劃3是em_palnner規劃4是混合A*規劃5是op_planner規劃6是DWA規劃7是Teb規劃8是simple_em(EM的簡化版本,待更新)--><arg name="planner" value="7"/> <param name="use_what_planner" value="$(arg planner)"/><!-- 是否使用二次規劃,選擇了lattice規劃,選擇這個才有效果 --><!-- false:lattice 采樣規劃,true:lattice 二次規劃 --><arg name="use_lateral_optimization" default="false"/> <!-- 是否開啟變道決策,變道選擇的是Lattce采樣規劃,其他方法不使用 --><arg name="change_lane" default="false"/> <!-- 參考線平滑的方式選擇: true:CosThetaSmoother false:FemPosSmooth--><arg name="which_smoother" default="false"/> <param name="which_smoothers" value="$(arg which_smoother)"/><!-- 判斷與終點的停車距離閾值 --><arg name="goal_dis" value="0.5"/> <param name="goal_distanse" type="double" value="$(arg goal_dis)"/><!-- 局部規劃 --><include file="$(find dynamic_routing)/launch/dynamic_routing.launch" ><arg name="is_planner" value="$(arg planner)" /><arg name="is_lateral_optimization" value="$(arg use_lateral_optimization)" /><arg name="is_change_lane" value="$(arg change_lane)" /><arg name="is_carla_simulation" value="$(arg carla)" /><arg name="ego_vehicle_name" value="$(arg ego_vehicle_name)" /><arg name="is_parking" value="$(arg parking)"/><arg name="is_goal" value="$(arg goal_dis)"/></include><!-- carla聯合仿真下的控制方法和參數 --><!-- LQR_dynamics LQR_kinematics Stanley PurePursuit --><param name="control_method" value='LQR_kinematics'/> <!-- "PurePursuit"增益系數 --><param name="k_pure" type="double" value="0.3" /> <!-- "Stanley"增益系數 --><param name="k_cte" type="double" value="100" /> <param name="kp" value="0.5" /><param name="ki" type="double" value="0.02" /><param name="kd" type="double" value="0.05" /><!-- LQR Q R矩陣參數 --><param name="Q_ed" type="double" value="20.0" /><param name="Q_ed_dot" type="double" value="1.0" /><param name="Q_ephi" type="double" value="10.0" /><param name="Q_ephi_dot" type="double" value="1.0" /><param name="R_value" type="double" value="40.0" /><!-- --><param name="Q_ex_k" type="double" value="3.0" /><param name="Q_ed_k" type="double" value="3.0" /><param name="Q_ephi_k" type="double" value="1.5" /><param name="R_value_k" type="double" value="4.0" /><!-- 全局規劃 --><node pkg="global_routing" type="global_routing_node" name="global_routing" output="screen" /></launch>