目录
一、提要
时间控制器:以单片微处理器为核心,配合电子电路等,组成的电源开关控制装置,能以天或星期,循环多时段的控制电器的开、关,也叫微电脑时控开关。
本文介绍ros如何实现定时控制的机理。
二、时间(或叫时刻)和持续时间(或叫时间段)
ROS 有内置的时间和持续时间原始类型,rospy 分别提供了 rospy.Time 和 rospy.Duration 类。时间是特定时刻(例如“今天下午 5 点”),而持续时间是一段时间(例如“5 小时”)。持续时间可以是负数。
时间和持续时间具有相同的表示:
int32 secs
int32 nsecs
ROS 能够为节点设置模拟时钟。您应该使用 rospy 的时间例程来访问当前时间,而不是使用 Python 的 time.time 模块,这将与模拟时钟时间以及挂钟时间无缝协作。
2.1 获取当前时间
rospy.Time.now(), rospy.get_rostime()
获取当前时间作为 rospy.Time 实例。 rospy.Time.now() 和 rospy.get_rostime() 是等价的。
now = rospy.get_rostime()
rospy.loginfo("Current time %i %i", now.secs, now.nsecs)
rospy.get_time()
以浮点秒为单位获取当前时间。
2.2 时间为零的特殊性
当使用模拟时钟时间时,get_rostime() 返回时间 0,直到在 /clock 上收到第一条消息,所以 0 本质上意味着客户端还不知道时钟时间。因此,值 0 应该被区别对待,例如循环 get_rostime() 直到返回非零。
2.3、创建时间实例
除了上述获取当前时间的方法外,还有多种方法可以创建新的 Time 实例。
rospy.Time(secs=0, nsecs=0)
创建一个新的时间实例。 secs 和 nsecs 是可选的,默认为零。
epoch = rospy.Time() # secs=nsecs=0
t = rospy.Time(10) # t.secs=10
t = rospy.Time(12345, 6789)
rospy.Time.from_sec(float_secs)
从浮点秒值创建一个新的 Time 实例(与 Python 的 time.time() 表示相同)。
t = rospy.Time.from_sec(123456.789)
2.4 转换时间和持续时间实例
Time 和 Duration 实例可以转换为秒和纳秒,以便与非 ROS 库一起使用。
1 t = rospy.Time.from_sec(time.time())
2 seconds = t.to_sec() #floating point
3 nanoseconds = t.to_nsec()
4
5 d = rospy.Duration.from_sec(60.1) # One minute and one tenth of a second
6 seconds = d.to_sec() #floating point
7 nanoseconds = d.to_nsec()
2.5 时间和持续时间算术
与其他原始类型一样,您可以对时间和持续时间执行算术运算。人们最初常常对这些实例的算术是什么样的感到困惑,所以最好看一些例子:
1 hour + 1 hour = 2 hours (duration + duration = duration)
2 hours - 1 hour = 1 hour (duration - duration = duration)
Today + 1 day = tomorrow (time + duration = time)
Today - tomorrow = -1 day (time - time = duration)
Today + tomorrow = error (time + time is undefined)
具有 Time 和 Duration 实例的算术与上述示例类似:
1 two_hours = rospy.Duration(60*60) + rospy.Duration(60*60)
2 one_hour = rospy.Duration(2*60*60) - rospy.Duration(60*60)
3 tomorrow = rospy.Time.now() + rospy.Duration(24*60*60)
4 negative_one_day = rospy.Time.now() - tomorrow
三、睡眠和时长值
rospy.sleep(持续时间)
duration 可以是 rospy.Duration 或 seconds (float)。 ROS 将休眠指定的时间。如果发生诸如节点关闭之类的终端条件,sleep() 将引发 rospy.ROSInterruptException。
切换行号显示
1 # sleep for 10 seconds
2 rospy.sleep(10.)
3
4 # sleep for duration
5 d = rospy.Duration(10, 0)
6 rospy.sleep(d)
rospy.Rate(赫兹)
rospy 提供了一个 rospy.Rate 便利类,它尽最大努力保持循环的特定速率。例如:
1 r = rospy.Rate(10) # 10hz
2 while not rospy.is_shutdown():
3 pub.publish("hello")
4 r.sleep()
在上面的示例中,Rate 实例将通过考虑循环期间任何操作使用的时间来尝试将循环保持在 10hz。如果睡眠被关机中断,Rate.sleep() 可以抛出 rospy.ROSInterruptException。
四、定时器
rospy.Timer(period, callback, oneshot=False)
ROS 1.5+ 的新功能 rospy.Timer(周期,回调,oneshot=False) 在 ROS 1.5 中引入,rospy 提供了一个 rospy.Timer 便利类,它定期调用回调。 Timer 类似于 roscpp 的 Timer 类。构造函数的参数是:
- 周期(pierod) 这是调用计时器回调之间的时间段。例如,如果这是 rospy.Duration(0.1),则每 1/10 秒将安排一次回调。
- 回调(callback) 这是要调用的函数。该函数被传递一个 TimerEvent 实例,下面将对此进行解释。
- 单发 (oneshot)指定计时器是否为一次性计时器。如果是这样,它只会触发一次。否则会不断地重新调度,直到停止。 例如:
切换行号显示
1 def my_callback(event):
2 print 'Timer called at ' + str(event.current_real)
3
4 rospy.Timer(rospy.Duration(2), my_callback)
在上面的示例中,Timer 实例将尝试每 2 秒调用一次回调。 回调传递一个 TimerEvent 对象,其中包括以下字段:
rospy.TimerEvent
last_expected
在一个完美的世界里,这是之前的回调应该发生的时间。
last_real
这是最后一次回调实际发生的时间。
current_expected
在一个完美的世界中,这是应该调用当前回调的时间。
current_real
当当前回调实际被调用时(rospy.Time.now() 就在调用回调之前。)
last_duration
包含上次回调的持续时间(结束时间减去开始时间),以秒为单位。请注意,这始终是挂钟时间。
要停止计时器触发,请调用 shutdown()。