ROS时间种类

谈及时间,有一个很重要的概念是ROS Time和Wall Time,两者是有区别的。它们两个的接口完全一样,数据类型也一样,但是ROS Time表示的是ROS网络中的时间。ROS网络中的时间是指,如果当时在非仿真环境里运行,那它就是当前的时间。但是假设去回放当时的情况,那就需要把当时的时间录下来。以控制为例,很多的数据处理需要知道当时某一个时刻发生了什么。Wall Time可以理解为墙上时间,墙上挂着的时间没有人改变的了,永远在往前走;ROS Time可以被人为修改,你可以暂停它,可以加速,可以减速,但是Wall Time不可以。

换言之ROS中有两种时间;
ROS::Time[/Duration/Rate]:ROS时间——来源可以被认为修改如加速/减速/暂停。
ROS::WallTime[WallDuration/WallRate]:ROS绝对时间——不可修改的”真实”时间。

一、ros::Time::now()解释

ros::Time t1 = ros::Time::now();
double t_cur = t1.toSec();//获取的是自1970年一月一日到现在时刻的秒数
printf("The time is: %16f\n",t_cur);//打印,%16f表示的是16位宽度的float类型的数字;
//注:%.2f是保留两位小数的意思
//若发布点云时,没有为每一帧点云打上时间戳,那么t_cur默认为0
void GridMap::cloudCallback(const sensor_msgs::PointCloud2ConstPtr &img)
{
  double t_cur = img->header.stamp.toSec();
  printf("cloudCallback_time: %16f\n",t_cur);
}

二、c++中sleep, usleep, ros中的ros::Duration

sleep(0.5) = sleep(0)//sleep()只接受整数
/* sleep.c:9:15: warning: implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0 [-Wliteral-conversion]
sleep(0.5); */
usleep(0.5*1000000)//usleep表示睡眠微秒,利用该函数可以实现延迟0.5s
ros::Duration(0.5).sleep()//该函数也可以实现延迟0.5s

三、参数use_sim_time介绍

这个参数当回放bag数据集是设置为true,此时说明系统使用的是仿真时间Time;如果设置为false,则系统使用walltime。(此参数可以通过launch文件中设置,或者通过节点设置)

1、launch文件设置:

<param name="/use_sim_time" value="true" />

2、通过节点设置:

rosparam set use_sim_time true

–clock相关使用介绍

在开启一个Node之前,当把use_sim_time设置为true时,这个节点会从clock Topic获得时间。所以操作这个clock的发布者,可以实现一个让Node中得到ROS Time暂停、加速、减速的效果。同时下面这些方面都是跟Node透明的,所以非常适合离线的调试方式。当把ROSbag记下来以后重新play出来时,加两个横杠,–clock,它就会发布出这个消息。

简而言之,因为ros有两种时间,所以所有的ros::node在启动时如果有设置[ros::param] \use_sim_time = true则节点的ROS::Time从/clock中获取,否则其值和ROS::WallTime一致。

ros::WallTime::now()为当前的真实时间,也就是墙上的挂钟时间,一直在走。
ros::Time::now()为rosbag当时的时间,是由bag中/clock获取的。是仿真时间。


当设置:\use_sim_time = true时, 在终端输入样式:rosbag play —clock XXX.bag
当设置:\use_sim_time = false时,在终端输入样式:rosbag play —clock XXX.bag或者去掉–clock

参考:
http://wiki.ros.org/Clock