功能包的launch 写法
launch文件位于功能包内部:
①写法一(注意斜杠)
<launch>
<node pkg=”package-name” type=”executable-name” name=”node-name”/>
</launch>
②写法二
<launch>
<node pkg=”package-name” type=”executable-name” name=”node-name”>
</node>
</launch>
launch文件位于功能包外部:
<launch>
<include file="$(dirname)/other.launch"/>
</launch>
或者写成
<launch>
<include file="$(dirname)/other.launch">
</include>
</launch>
多个launch写入一个launch启动文件:
创建功能包xxlaunch,在功能包内进入launch文件夹,创建.launch文件,,将其他launch文件写入该文件写法为
<launch>
<include file="$(dirname)/other.launch"/>
<include file="$(dirname)/other.launch"/>
...
</launch>
roslaunch参数写入及读取:
写入单个参数到参数服务器 <param>
<!--直接定义参数并赋值-->
<param name="velodyne_frame_id" type="string" value="velodyne"/>
<!--定义参数并通过arg给参数赋值-->
<arg name="velodyne_frame_id" default="velodyne"/>
<param name="velodyne_frame_id" type="string" value="$(arg velodyne_frame_id)"/>
从.yaml文件批量写入参数到参数服务器 <rosparam>
<!--从../config/params.yaml文件中加载参数 -->
<rosparam command="load" file="$(find *package_name)/config/params.yaml" />
将上述param写入launch如下:
<launch>
<include file="$(dirname)/other.launch"/>
<param name="velodyne_frame_id" type="string" value="velodyne"/>
</launch>
同一功能包内代码中读取:
nh.getParam("param_2", node_param);
不同功能包读取 :
nh.getParam("/功能包名/param_2", node_param);
获取功能包绝对路径:
std::string ros::package::getPath (const std::string &package_name)
头文件增加:#include <ros/package.h>
cmakelist增加roslib:
find_package(catkin REQUIRED COMPONENTS roscpp rospy roslib )
packagexml:
<build_depend>roslib</build_depend>
<exec_depend>roslib</exec_depend>
代码行:
#include <ros/package.h>
std::string path = ros::package::getPath("my_package");
ROS时间种类
ROS中有两种时间:
- ROS::Time[/Duration/Rate]:ROS时间——来源可以被认为修改如加速/减速/暂停。
- ROS::WallTime[WallDuration/WallRate]:ROS绝对时间——不可修改的"真实"时间。
所有的ros::noed
在启动时如果有设置[ros::param] \use_sim_time = true
则节点的ROS::Time
从/clock
中获取,否则其值和ROS::WallTime
一致。
ROS时间和时间戳stamp对有些rosnode
来说至关重要:rosnode
- 比如rviz和tf会将
msg
的header/stamp
与rosnode
当前时间对比来抛弃无效数据(OLD_DATA)。 - ActionClient会自动添加当前时间到stamp中发送给ActionServer,而ActionSerer会对比新的
msg
与历史msg
的stamp来决定是否是合法数据。
在录制rosbag
的时候msg/header/stamp
时间戳是录制时刻的值。可能导致当前ROS时间 和时间戳不匹配导致:抛出异常,更有甚者直接功能不正常。
ros:time::now()输出值为0?
ROS设置了一个模拟时钟的节点,使用模拟时钟的时候,now()返回时间0直到第一条消息在/clock已经收到,所以当客户端不知道时钟时间时ros:time::now()输出为0。
ros:time::now()输出的值与参数use_sim_time有关。
use_sim_time为true时,ros:time::now()输出系统时间;
use_sim_time为false时,ros:time::now()输出输出仿真时间,如果回放bag则是bag的时间。
查看当前use_sim_time状态:rosparam get use_sim_time
设置当前use_sim_time状态:rosparam set use_sim_time true(or false)
launch设置use_sim_time参数:<param name="use_sim_time" value="false" />
如何直接使用系统时间?
使用 ros::WallTime::now()
播放rosbag时,若参数/use_sim_time 为true,则此时
- ros::WallTime::now()为当前的真实时间,也就是墙上的挂钟时间,一直在走。
- ros::Time::now()为rosbag当时的时间,是由bag中/clock获取的。是仿真时间。
参考链接