【ROS2原理19】定时器模型

发布于:2023-01-04 ⋅ 阅读:(665) ⋅ 点赞:(0)

目录

一、提要

二、时间(或叫时刻)和持续时间(或叫时间段)

2.1 获取当前时间

2.2 时间为零的特殊性

2.3、创建时间实例

2.4 转换时间和持续时间实例

2.5 时间和持续时间算术

三、睡眠和时长值

四、定时器


 

一、提要

        时间控制器:以单片微处理器为核心,配合电子电路等,组成的电源开关控制装置,能以天或星期,循环多时段的控制电器的开、关,也叫微电脑时开关。

        本文介绍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()。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到