介绍 ROS 中的时刻、时间间隔、定时器的定义和应用。
ROS 中有 time 和 duration 两种类型,相应的有 ros::Time 和 ros::Duration 类。
其统一表示形式为:
int32 sec
int32 nsec
ROS 可以给节点提供一个模拟始时钟。不同于平台时间,你可以利用 roscpp 的时间例程来得到当前的时间,此时间能够和模拟时间、wall-clock 时间进行无缝连接。
ros::Time::now()
ros::Time begin = ros::Time::now();
时间计算起点
使用模拟时间时,当 /clock
节点接受到第一条消息时,now() 返回时刻 0,此时客户端还不知道时钟时间。
浮点数形式
ros::Time a_little_after_the_beginning(0.001);
ros::Duration five_seconds(5.0);
用两个整数表示
ros::Time a_little_after_the_beginning(0, 1000000);
ros::Duration five_seconds(5, 0);
double secs =ros::Time::now().toSec();
ros::Duration d(0.5);
secs = d.toSec();
时间和时刻的四则运算实例如下:
ros::Duration two_hours = ros::Duration(60*60) + ros::Duration(60*60);
ros::Duration one_hour = ros::Duration(2*60*60) - ros::Duration(60*60);
ros::Time tomorrow = ros::Time::now() + ros::Duration(24*60*60);
ros::Duration negative_one_day = ros::Time::now() - tomorrow;
bool ros::Duration::sleep()
睡眠 0.5s:
ros::Duration(0.5).sleep(); // sleep for half a second
ros::Rate
频率 10Hz:
ros::Rate r(10); // 10 hz
while (ros::ok())
{
... do some work ...
r.sleep();
}
Rate 和 Timer 的作用一样,最好用 Timer 来定时。
在模拟时,如果想要进入实际运行 wall-clock time ,可以用 ros::WallTime, ros::WallDuration, 和ros::WallRate,类似于 ros::Time, ros::Duration, 和 ros::Rate
定时器不能代替实时线程/内核,它们仅对没有硬实时要求的事物有用。
方法: ros::NodeHandle::createTimer()
ros::Timer timer = nh.createTimer(ros::Duration(0.1), timerCallback);
完整定义:
ros::Timer ros::NodeHandle::createTimer(ros::Duration period, , bool oneshot = false);
period:定时器回调函数之间的时间间隔
:定时器回调,函数、类方法或者函数子对象
oneshot:是否只定时一次。false,就是连续定时。
2、回调特征
void callback(const ros::TimerEvent&);
struct TimerEvent
{
Time last_expected; ///< 上一回调函数应该发生的时刻
Time last_real; ///< 上一回调函数实际发生的时刻
Time current_expected; ///< 当前回调函数应该发生的时刻
Time current_real; ///< 当前回调函数实际发生的时刻
struct
{
WallDuration last_duration; ///<包含上一回调的时间间隔(结束时间-开始时间),它始终在 `wall-clock time`
} profile;
};
functions
class methods
functor objects (including boost::function)
void callback(const ros::TimerEvent& event)
{
...
}
...
ros::Timer timer = nh.createTimer(ros::Duration(0.1), callback);
void Foo::callback(const ros::TimerEvent& event)
{
...
}
...
Foo foo_object;
ros::Timer timer = nh.createTimer(ros::Duration(0.1), &Foo::callback, &foo_object);
class Foo
{
public:
void operator()(const ros::TimerEvent& event)
{
...
}
};
...
ros::Timer timer = nh.createTimer(ros::Duration(0.1), Foo());
在仿真是利用 ROS Clock。
void callback(const ros::WallTimerEvent& event)
{
...
}
...
ros::WallTimer timer = nh.createWallTimer(ros::WallDuration(0.1), callback);
http://wiki.ros.org/roscpp/Overview/Time
http://wiki.ros.org/roscpp/Overview/Timers
http://wiki.ros.org/roscpp_tutorials/Tutorials/Timers