如何将 ROS 主题延迟一定时间



实际问题:

我有一个订阅 2 个主题并发布到 1 个主题的控制器节点。尽管在仿真中一切似乎都按预期工作,但在实际硬件中,性能会下降。我怀疑问题是两个输入主题中的一个比另一个滞后了很长时间。

问题:

我想在仿真中重新创建这种行为,以测试控制器的鲁棒性。因此,我需要将其中一个主题延迟一定时间 - 理想情况下,这应该是可配置的参数。我可以编写一个具有FIFO内存缓冲区的节点,并通过监视主题的频率来调整延迟时间。在我这样做之前,是否有我可以使用的命令行工具或任何其他快速实现方法?

附言我使用的是 Ubuntu 16.04 和 ROS-Kinetic。

我不知道有任何开箱即用的解决方案可以完全按照您在这里描述的内容进行操作。

为了快速破解,如果您的主题没有时间戳,并且节点只是在消息到达时接收消息,最简单的方法是录制一个包并从两个不同的rosbag play实例中播放两个主题。像这样:

first terminal
rosbag play mybag.bag --clock --topics /my/topic
second terminal started some amount of time later
rosbag play mybag.bag --topics /my/other_topic

不确定--clock标志,是否需要它主要取决于您所说的模拟是什么意思。如果你想控制时差而不是在两个不同的终端中按回车键,你可以编写一个小的bash脚本来启动它们。


另一个仍然涉及袋子的选项,但可以让您更好地控制消息延迟的确切时间,方法是编辑袋子,使消息已经具有正确的延迟。可以通过修改 rosbag 食谱中的第一个示例相对容易地完成:

import rosbag
with rosbag.Bag('output.bag', 'w') as outbag:
for topic, msg, t in rosbag.Bag('input.bag').read_messages():
# This also replaces tf timestamps under the assumption 
# that all transforms in the message share the same timestamp
if topic == "/tf" and msg.transforms:
outbag.write(topic, msg, msg.transforms[0].header.stamp)
else:
outbag.write(topic, msg, msg.header.stamp if msg._has_header else t)

将 if else 替换为:

...
import rospy
...
if topic == "/my/other_topic":
outbag.write(topic, msg, t + rospy.Duration.from_sec(0.5))
else:
outbag.write(topic, msg, t)

应该让你大部分时间到达那里。


除此之外,如果您认为该节点将来会很有用,或者您希望它也能处理实时数据,那么您需要使用一些队列实现您描述的节点。你可以从中寻找灵感的一件事可能是主题工具,git for topic tools source。

最新更新