ROS launch啓動文件

啓動文件(launch)

下面的命令可以啓動單個節點(首先需要roscore運行節點管理器)

rosrun package_name executable_file_name 

但是如果是比較大型的項目需要啓動許多節點,使用rosrun命令顯然效率太低,幸好ros提供了同時啓動節點管理器(master)和多個節點的途徑。

創建測試實例

創建工作空間

mkdir -p ~/test/src    //工作區目錄
cd ~/test/src
catkin_init_workspace	//初始化工作區
cd ../
catkin_make

創建功能包( 在~/test/src文件夾下)

source ~/test/devel/setup.bash
catkin_create_pkg launch_test roscpp
cd launch_test
mkdir src

創建節點(存放在launch_test/src下)
launch_test_adv_node.cpp

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <string>
int main(int argc, char** argv){
	ros::init(argc,argv,"launch_test_adv_node");
	ros::NodeHandle nh;
	ros::Publisher launch_test_pub = nh.advertise<std_msgs::String>("launch_test",1000);
	std_msgs::String test;
	std::string o = "ros_launch_test: hello world, recieve count: ";
	int count = 1;
	ros::Rate rate(1);
	while(ros::ok){
		test.data = o + std::to_string(count++);
		launch_test_pub.publish(test);
		
		rate.sleep();
	}
	return 0;
}

launch_test_sub_node.cpp

#include <ros/ros.h>
#include <std_msgs/String.h>

void launch_sub_testCall(const std_msgs::String msg){
	ROS_INFO_STREAM(msg.data);
}
int main(int argc, char** argv){

	ros::init(argc,argv,"launch_test_sub_node");
	ros::NodeHandle nh;
	ros::Subscriber launch_test_sub = nh.subscribe<std_msgs::String>("launch_test",1000,launch_sub_testCall);	
	ros::spin();
	
	return 0;
}

創建啓動文件(.launch文件)

ros的launch文件是xml格式,裏面羅列了需要同時啓動的一組節點。其基本格式爲

<launch>
	<node pkg="" name="" type="">
	</node>
	...
</launch>

這是最基本啓動文件的格式,至少包含一個節點,並且節點至少有pkg,name,type三個屬性,關於launch文件中node標籤的具體屬性和子標籤,我們下面會介紹。
我們在launch_test功能包的根目錄下創建launch文件夾存放啓動文件,並在launch文件夾中創建名爲launce_test.launch的啓動文件,內容爲:

<launch>
	<node pkg="lanunch_test" type="launch_test_adv_node" name="launch_test_adv_node" />
	<node pkg="lanunch_test" type="launch_test_sub_node" name="launch_test_sub_node" />
</launch>

這樣我們通過運行,至於pkgtypetype內容爲什麼這麼寫,接下來介紹。

roslaunch launch_test launch_test.launch

便可以一次啓動兩個節點,其中中間的launch_test代表功能包名稱 launch_test.launch代表功能包下面的啓動文件的名稱。

node標籤的屬性

node標籤英文文檔介紹

pkg=“package_name”

節點所在的功能包名稱

type=“node_type”

節點所在的cpp文件對應的可執行文件名字。即在對應CMakeLists.txt中生成的對應可執行文件的名字:

add_executable(abc ABC.cpp)

如果節點所在的cpp文件生成的可執行文件名爲abc,則有type="abc".

name=“node_name”

name 屬性給節點指派了名稱, 它將覆蓋任何通過調用 ros::int來賦予節點的名稱,注意節點名稱不能有命名空間。可通過ns屬性賦值命名空間。

ns=“namespace” (可選)

設置命名空間可以避免節點使用默認命名空間。

output=“log|screen”(可選)

如果output="screen",則節點裏的stdout和stderr會被髮送到屏幕;
如果output="log",則stdout和stderr會被保存到$ROS_HOME/log/run_id/node_name-number-stout.log下的日誌文件,stderr同時會從屏幕輸出,默認爲"log"1.

respawn=“true”(可選, 默認: False)

如果節點退出自動重啓節點。

respawn_delay=“30” (可選, 默認0)

如果respawn是true,如果嘗試重啓節點失敗,等待respawn_delay秒之後重試

required=“true”(可選)

如果節點退出,結束整個roslaunch。

Launch-prefix=“command-prefix”

使用 roslaunch 的一個缺點是所有的節點共享一個終端,有時候我們需要單獨一個節點使用一個終端,這時候Launch-prefix屬性就發揮作用了。roslaunch 在啓動節點時的內部工作原理是調用相應的命令行工具,即 rosrun。啓動前綴的主要思想是在其命令行前面添加給出的命令行前綴。對節點元素使用啓動前綴,比如launch-prefix=”xterm -e”,在這個屬性的作用下,節點元素和在命令行中輸入下面的命令基本上是等價的:

xterm –e rosrun turtlesim turtle_teleop_key

xterm 命令將打開一個簡單終端窗口。參數-e告訴 xterm 在新打開的終端中執行該命令行的剩餘部分。
啓動前綴屬性並不只侷限於xtrem。該屬性也可以用來調試(通過gdbvalgrind)或降低一個進程的優先級(通過nice) 。

node標籤的元素

remap

每個重映射包含一個原始名稱和一個新名稱。每當節點使用重映射中的原始名稱時,ROS客戶端庫就會將它默默地替換成其對應的新名稱。
在啓動文件內使用重映射(remap):

<remap from=”original-name”to ”new-name”/>

如果該屬性在頂層,即作爲 launch 元素的子元素出現,重映射將會應用到所有的後續節點。這些重映射元素也可以作爲一個節點元素的子元素,如:

<launch>
	<arg name="namespace" default="a4zhangfei" />
	<node pkg="lanunch_test" type="launch_test_adv_node" name="launch_test_adv_node" ns="sim1" output="screen">
		<remap from="launch_test" to="$(arg namespace)/launch_test" />
	</node>
	<node pkg="lanunch_test" type="launch_test_sub_node" name="launch_test_sub_node" ns="sim1" output="screen" />
</launch>

launch_test_adv_node節點內會將launch_test映射爲/sim1/a4zhangfei/launch_test

param

見下,參數服務器

啓動參數(argument)

啓動參數有兩種形式:

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

兩者的唯一區別在於命令行參數可以覆蓋默認值 default,但是不能覆蓋參數值 value。
命令行參數

roslaunch package-name launch-file-name arg-name:=arg-value

獲取啓動參數:

$(arg arg-name)

每個該替換出現的地方,roslaunch 都將它替換成參數值。

參數服務器(parameter)

參數服務器( parameter server )維護一個變量集的值,包括整數、浮點數、字符串以及其他數據類型,每一個變量用一個較短的字符串標識 。由於允許節點主動查詢其感興趣的參數的值,它們適用於配置那些不會隨時間頻繁變更的信息。需要銘記的是,所有的參數都屬於參數服務器而不是任何特定的節點。這意味着參數——即使是由節點創建的——在節點終止時仍將繼續存在。
查看參數列表

rosparm list

查詢參數

rosparam get parameter_name

查詢某個命名空間下的參數

rosparam get namespace

命令行設置參數

rosparam set parameter_name parameter_value

創建和加載參數文件
爲了以 YAML 文件的形式存儲命名空間中的所有參數,可以使用 rosparam dump 命令:

rosparam dump filename namespace

與 dump 相反的命令是 load,它從一個文件中讀取參數,並將它們添加到參數服務器:

rosparam load filename namespace

在啓動文件中設置參數

<param name="param-name" type="" value="param-value" />

其中type可填內容爲

"str|int|double|bool|yaml"(可選)

c++獲取參數 (param)

void ros::param::set(parameter_name, input_value);
bool ros::param::get(parameter_name, output_value);

設置私有參數
另一個可選方法是在節點元素中包含 param 元素:

<node ...>
	<param name="param-name" type="param-type" value="param-value" />
		...
</node>

在該結構下,參數名將被當做該節點的私有名稱。
在文件中讀取參數
啓動文件也支持 與rosparam load等價的命令,可以一次性從文件中加載多個參數:

<rosparam command="load" file="path-to-param-file" />

這裏列出的參數文件通常是通過 rosparam dump 命令創建的。使用查找替換來指定功能包的相對路徑是常見做法:

<rosparam command="load" file="$(find package-name)/param-file" />

盡 管 在 計 算 機 領 域 術 語 中 很 多 情 況 下 prarmeter 和argument 都是可以互換的,但是在 ROS 中,二者的含義是非常不同的。parameter 是運行中的 ROS 系統使用的數值,存儲在參數服務器(parameter server)中,每個活躍的節點都可以通過 ros::param::get 函數來獲取 parameter 的值,用戶也可以通過 rosparam 來獲得 parameter 的值。而 argument 只在啓動文件內纔有意義;他們的值是不能被節點直接獲取的。


  1. 在當前版本的 roslaunch 中 ,標準錯誤(包括控制檯中的 ERROR 和 FATAL 級別的日誌消息)的輸出是顯示在控制檯上的,而不是在記錄文件中。然而, roslaunch 源代碼的註釋中標明將在今後對這一點做出改變。 ↩︎

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