Image subscriber lag (despite queue = 1) not resolved by big buff_size
Hello all,
I have a very similar problem as described here, however setting a very high value for buff_size
does not solve it. Also, in my case, instead of doing the task with a high computational cost, I just want to wait a second. If I don't wait this second, I don't have a problem, but this is necessary in my case. My code looks something like this:
class ImageCallback:
def __init__(self):
self.bridge = CvBridge()
def callback_image(self, data):
image = self.bridge.imgmsg_to_cv2(data)
print "Delay:%6.3f" % (rospy.Time.now() - data.header.stamp).to_sec()
cv2.imshow("Window", image)
cv2.waitKey(1)
rospy.sleep(1)
def main():
rospy.init_node('video')
callback_class = ImageCallback()
rospy.Subscriber("cam_vo/image_raw", Image, callback_class.callback_image, queue_size=1,
buff_size=2 ** 31 - 1)
rospy.spin()
When I run this, images are displayed to me every second as desired, but the delay initially increases to six seconds and stabilizes there. And when I pause the bag the images are coming from, the display of the images continues for some time, with the delay increasing further. The images are about 2 MB in size and were taken at 25 Hz, so the buffsize
should definitely be enough. I also tried using 2^21 as buffsize
, but that doesn't change anything.
I'm using ROS melodic with Python 2.7 on a machine running Ubuntu 18.04, as well as opencv-python in version 4.2.0.32. I appreciate any support, especially the increase of the delay to six seconds is what bothers me the most, as this causes the displayed image to not be live.
Asked by jan2453 on 2021-08-18 10:47:43 UTC
Answers
You have to structure the code differently than you have it now.
You must not wait or sleep or do anything time-consuming inside a Subscriber callback. You need to quickly save the callback message into a variable or a queue, and return from the callback as quickly as possible.
Then, in either your main() thread or in a background thread, you use a loop to process each message from the queue. Inside this loop it is ok to use rospy.sleep(d) or rate.sleep(), but make sure you call rospy.is_shutdown() pretty frequently and exit the loop once it returns true.
In this particular case, if images are arriving faster than you display them, you'll need to do something about that.
Asked by Mike Scheutzow on 2021-08-18 18:30:39 UTC
Comments