ROS学习八、ros中的时间Time,Duration,Timer和Rate(2)
概述
ROS中的时间包含time时刻和duration间隔两种,由roslib提供ros::Time和ros::Duration两个类
Time和Duration的数据类型相同:
int32 sec
int32 nsec
ros::Time与ros::Duration
这两个类提供了基本的计时方法
获得当前时间:
ros::Time start = ros::Time::now();
设置时刻:
# 第一个参数为s,第二个为ns
ros::Time t(10, 100000000) #1.1s
# 或者浮点数
ros::Time t(1.1) #1.1s
设置时间间隔:
# 第一个参数为s,第二个为ns
ros::Duration d(2, 500000000); # 2.5s
# 或者浮点数
ros::Duration d(2.5); # 2.5s
将时间转化为s或者ns:
ros::Time t(10, 100000000);
# 转为ms
ros::Time t_ms = t.toNSec();
# 转为s
ros::Time t_s = t.toSec();
时间运算:
ros的Time和Duration类重载了+、-、*、==、!=、>、<等符号,其中+、-的运算与现实时间的概念一样:
间隔 + 间隔 = 间隔
间隔 - 间隔 = 间隔
时刻 + 间隔 = 时刻
时刻 - 时刻 = 间隔
对照就是:
ros::Duration + ros::Duration = ros::Duration
ros::Duration - ros::Duration = ros::Duration
ros::Time + ros::Duration = ros::Time
ros::Time - ros::Time = ros::Duration
ros::Timer与ros::Rate
sleep函数
首先要说明一下ros中用于暂时休眠的sleep函数:
# 函数原型 ros::Duration::sleep()
# 使用方法:
ros::Duration(2.5).sleep();
ros::Rate 循环
ros中提供了一个用于固定频率循环的类ros::Rate:
# 10Hz
ros::Rate r(10);
while(ros::ok())
{
...
r.sleep();
}
Rate类对象的工作原理是,从上一次sleep结束后到下一次sleep开始时,如果经过的时间没有超过指定的频率时间,就通过sleep到指定频率时间。
比如指定Rate为10Hz(100ms),程序一次循环只用了10ms,那么sleep就会休眠90ms,然后进入下一次循环。
因此如果循环程序运行的时间大于指定Rate,那么这个Rate就失效了。
ros::Timer
ros::Timer是比Rate更灵活的计时循环器,通过类似subscriber+callback的方式进行:
ros::NodeHandle nh;
nh.createTimer(ros::Duration(2.5), timerCallback);
void timerCallback(const ros::TimerEvent& e);
其中ros::TimerEvent记录了定时器中的事件时间信息:
struct TimerEvent
{
Time last_expected; ///< In a perfect world, this is when the last callback should have happened
Time last_real; ///< When the last callback actually happened
Time current_expected; ///< In a perfect world, this is when the current callback should be happening
Time current_real; ///< This is when the current callback was actually called (Time::now() as of the beginning of the callback)
struct
{
WallDuration last_duration; ///< How long the last callback ran for, always in wall-clock time
} profile;
};