I am having problems with a delay when a rospy subscriber listens to messages with images.
Overview:
I have a pink streaming image playback on / camera / image _raw with a frequency of 5 Hz. I also have an image_view node to display images for reference. This image_view shows them at a frequency of 5 Hz.
In my rospy subscriber (initialized queue = 1), I also show the image (for comparing the delay time with the image_view node image). Then, the subscriber performs some heavy processing.
Expected Result:
Since the queue size is 1, the subscriber must process the last frame and skip all other frames in the meantime. After processing is complete, it should go to the next last frame. There should be no queue in old frames. This will lead to intermittent but not lagged video (low fps, but no βdelayβ with the rosbag stream, if that makes sense)
Actual result:
The subscriber is behind the published stream. In particular, the image_view node displays images with a frequency of 5 Hz, and it seems that the subscriber queues all the images and processes them one by one, instead of just capturing the last image. Delay also increases over time. When I stop the rosbag stream, the subscriber continues to process the images in the queue (even if queue = 1).
Note that if I change the subscriber to a very large buffer size, as shown below, the expected behavior is expected:
self.subscriber = rospy.Subscriber("/camera/image_raw", Image, self.callback, queue_size = 1, buff_size=2**24)
However, this is not a clean solution.
This issue is also reported in the following links, where I found a buffer size solution. The official explanation suggests that the publisher may slow down, but this is not so, since the subscriber image_view displays images with a frequency of 5 Hz.
https://github.com/ros/ros_comm/issues/536 , Ros subscriber is not updated , http://answers.ros.org/question/50112/unexpected-delay-in-rospy-subscriber/
Any help is appreciated. Thanks!
Code:
def callback(self, msg): print "Processing frame | Delay:%6.3f" % (rospy.Time.now() - msg.header.stamp).to_sec() orig_image = self.bridge.imgmsg_to_cv2(msg, "rgb8") if (self.is_image_show_on): bgr_image = cv2.cvtColor(orig_image, cv2.COLOR_RGB2BGR) cv2.imshow("Image window", bgr_image) cv2.waitKey(1) result = process(orig_image)