clock
1. 介绍
通常,ROS 客户端库将使用您计算机的系统时钟作为时间源,也称为“wall-clock”或“wall-time”(就像您实验室墙上的时钟)。**但是,当您运行模拟或回放记录的数据时,通常需要让系统使用模拟时钟,以便您可以加速、减慢或逐步控制系统的感知时间。**例如,如果您正在将传感器数据回放到您的系统中,您可能希望您的时间与传感器数据的时间戳相对应。
为了支持这一点,ROS 客户端库可以监听用于发布“模拟时间”的 /clock
话题。
为了让您的代码利用 ROS 模拟时间,重要的是所有代码都使用适当的 ROS 客户端库时间 API 来访问时间和睡眠,而不是使用语言本机例程。这将使您的系统无论是使用挂钟还是模拟时钟,都可以进行一致的时间测量。下面简要介绍了这些 API,但您应该熟悉您选择的客户端库以了解更多详细信息。
在多台机器上使用挂钟时间时,同步它们之间的时间很重要。 ROS 不提供此功能,因为已经有完善的方法(例如 ntp
,我们推荐的同步工具是 chrony
)可以执行此操作。如果您不同步多台机器的挂钟,它们将不会就时间计算达成一致,例如 tf
.
注意:这不是实时系统的 API!
2. 使用 /clock
主题中的模拟时间
为了让 ROS 节点根据 /clock 话题使用模拟时间,必须在节点初始化之前将 /use_sim_time
参数设置为 true。这可以在启动文件或命令行中完成。
如果设置了 /use_sim_time
参数,ROS 时间 API 将返回 time=0
,直到它从 /clock 主题收到一个值。然后,时间只会在收到来自 /clock 主题的消息时更新,并且在更新之间保持不变。
对于使用模拟时间计算持续时间,客户端应始终等到第一个非零时间值在开始之前收到,因为来自 /clock 主题的第一个模拟时间值可能是一个高值。
注意:在 ROS C Turtle
之前,节点会自动订阅 /clock
主题,如果有任何内容发布到 /clock
话题,则会使用模拟时间。
3. 运行时钟服务器
时钟服务器是发布到 /clock 话题的任何节点,并且在单个 ROS 网络中运行的服务器不应超过一个。在大多数情况下,时钟服务器要么是一个模拟器,要么是一个日志回放工具。
为了解决启动顺序的任何问题,重要的是在使用时钟服务器的任何launch文件中将 /use_sim_time 参数设置为 true。如果您正在使用 rosbag play 播放包文件,则使用 --clock 选项将在播放包文件时运行时钟服务器。
注意:
ROS时间和时间戳stamp对有些rosnode
来说至关重要:
- 比如rviz和tf会将
msg
的header/stamp
与rosnode
当前时间对比来抛弃无效数据(OLD_DATA)。 - ActionClient会自动添加当前时间到stamp中发送给ActionServer,而ActionSerer会对比新的
msg
与历史msg
的stamp来决定是否是合法数据。
在录制rosbag
的时候msg/header/stamp
时间戳是录制时刻的值。可能导致当前ROS时间 和时间戳不匹配导致:抛出异常,更有甚者直接功能不正常。
我们可以设置use_sim_time
再启动节点,改变ROS时间源。并通过对rosbag ... --clock
参数让rosbag发布/clock
驱动ROS时间
总结:
1.use_sim_time
设置为true,系统使用的是仿真模拟时间,如果设置为false,系统使用的是“wall-clock”或“wall-time”时间;
2.当运行模拟或回放记录的数据时,通常需要让系统使用模拟时钟,以便您可以加速、减慢或逐步控制系统的感知时间;
3.时钟服务器是发布到 /clock
话题的任何节点,并且在单个 ROS 网络中运行的服务器不应超过一个。在大多数情况下,时钟服务器要么是一个模拟器,要么是一个日志回放工具。在launch文件中将 /use_sim_time
参数设置为 true,如<arg name="use_sim_time" default="true"/>
或通过节点设置 rosparam set use_sim_time true
;
4.如果您正在使用 rosbag play
播放包文件,则使用 --clock
选项将在播放包文件时运行时钟服务器。
参考文献:
http://wiki.ros.org/Clock
https://zhuanlan.zhihu.com/p/353772463