ROS订阅者不是最新的

5

我已经编写了一个ROS订阅者来订阅图像话题之一,并使用以下方式将缓冲区设置为1:

subscriber =rospy.Subscriber("/camera/rgb/image_mono/compressed",CompressedImage, callback,  queue_size=1)

然而,我的订阅者仍然滞后。有什么想法可能导致这种情况?我是否正确设置了队列大小?
4个回答

8

我曾经也遇到过这个问题(不是帧率卡顿的问题,而是真正的延迟)。当我关闭发布图像源(rosbag、相机驱动等)时,我的节点仍然会处理 ~5-10帧的内容即使源已被关闭(而我确信我设置了queue_size=1)。

这是我在github上创建的问题,并得到了解决。事实证明,涉及到多个队列(不仅仅是你设置的大小为1的那个队列)。在我的情况下,默认的buff_size比我的图像小,因此我的节点无法快速地对其进行处理,总是有一些图像停留在某个队列中。

简而言之,增加订阅者的buff_size,就像我在这里做的那样。这对我很有效 :)


基本上,订阅者只能完全删除其缓冲区中已经存在的消息。如果缓冲区小于queue_size + 1,则不会丢失任何消息,并且TCP缓冲区正在缓冲您的消息。 - Dimitri Schachmann

3
队列用于排队处理传入的信息。这意味着,如果您的回调方法处理消息的时间比新消息到达的时间长,则仅保留"队列大小",其他消息不会被您的节点处理。
我建议在发布者节点发布消息之前打印一条消息,并在回调方法顶部打印一条消息。然后,您可以精确地测量ros处理消息所需的时间。所有其他的时间问题可能是由您的回调方法引起的。

1
我同意,但如果这些其他消息没有被处理,那么我的订阅者不就会处理最近的消息吗?因此,视频显示应该是断断续续的(由于跳帧),但不会滞后吗? - Sello Mkantjwa
好的,它应该会延迟直到您的回调方法处理完成。 - Steffen
我明白了!因为我会在收到每条消息后几秒钟才显示它。谢谢。 - Sello Mkantjwa

1

为什么buff_size很重要的补充说明
此外,官方文档还可以帮助解释从pub.publish的角度导致延迟的另一个原因。

在rospy中,默认情况下publish()是同步的(出于向后兼容性的考虑),这意味着调用是阻塞的,直到:

消息已经被序列化到缓冲区并且该缓冲区已经被写入到每个当前订阅者的传输中


-1

可见的延迟原因很可能是您的回调函数占用了大量时间。如果可能的话,请尝试修复它。将队列大小设置为1基本上意味着要求ROS处理它可以保留的任何帧。

将队列大小设置为更大的数字,比如5或10。这样,(希望处理延迟不会太大)所有的帧都将被处理,但它们将落后于时间。也就是说,视频处理将会滞后几步,但没有任何“抽搐”和中间缺失的帧。


我不介意画面有些卡顿。事实上,我更喜欢这种情况而不是延迟的情况。我使用队列大小为1的原因是在回调被调用时我拥有最新的信息。我不需要处理所有信息,只需要处理当前的信息。是的,我的回调函数所需时间比消息到达的速率还长(很难改变这一点)。 - Sello Mkantjwa
那么,在这种情况下,问题是什么?队列大小为1将确保只有一个。 - a-Jays

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接