目錄
啓動文件(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>
這樣我們通過運行,至於pkg
、type
和type
內容爲什麼這麼寫,接下來介紹。
roslaunch launch_test launch_test.launch
便可以一次啓動兩個節點,其中中間的launch_test
代表功能包名稱 launch_test.launch
代表功能包下面的啓動文件的名稱。
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
。該屬性也可以用來調試(通過gdb
或valgrind
)或降低一個進程的優先級(通過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 只在啓動文件內纔有意義;他們的值是不能被節點直接獲取的。
在當前版本的 roslaunch 中 ,標準錯誤(包括控制檯中的 ERROR 和 FATAL 級別的日誌消息)的輸出是顯示在控制檯上的,而不是在記錄文件中。然而, roslaunch 源代碼的註釋中標明將在今後對這一點做出改變。 ↩︎