Robotics StackExchange | Archived questions

Issue with message_filters and rospy.spin() not running

I'm trying to create a subscriber for CameraInfo and /webcam/image_raw, which are rostopics being published for me. I tried doing by myself, then went back to the tutorials and still cant get anything to work. I'm using python to write my subscriber, but nothing seems to work, not even the tutorial version.

So whenever I try to subscribe to two topics with messagefilters, my programs stops at rospy.spin() doesn't go any further. It seems to be an issue with the CameraInfo topic I'm trying to subscribe to, as it doesn't seem to work with that. If I remove `infosubfrom themessage_filters.ApproximateTimeSynchronizer`, the program works. I've tried just about everything I could think of, and am at the point where I need to ask for help somewhere. Any help with what I could be doing wrong would be helpful.

#!/usr/bin/env python

# http://wiki.ros.org/cv_bridge/Tutorials

import rospy
import cv2
import numpy as np
#from std_msgs.msg import String
from sensor_msgs.m

sg import Image, CameraInfo
#from sensor_msgs.msg import Imu                                                                         
#from sensor_msgs.msg import Range                                                                       
# from sensor_msgs.msg import CameraInfo
# from gazebo_msgs.msg import ModelStates

from cv_bridge import CvBridge, CvBridgeError
import sys
import time                                                                                               
import message_filters                                                                                     
#import matplotlib.pyplot as plt
import pandas as pd                                                                                      d
import string

bridge = CvBridge()



# class listener:
#     def __init__(self):
#         self.image_sub = message_filters.Subscriber("/webcam/image_raw", Image)
#         self.caminfo_sub = message_filters.Subscriber("webcam/CameraInfo", CameraInfo)
#         self.ts = message_filters.ApproximateTimeSynchronizer([self.image_sub, self.caminfo_sub], 1, 1)
#         self.ts.registerCallback(self.callback)

#     def callback(self, ros_image, camera_info):
#         global bride
#         # here we convert ros_image into an opencv-compatible image
#         try:
#             print 'converting ROS image'
#             cv_image = bridge.imgmsg_to_cv2(ros_image, "bgr8")
#         except CvBridgeError as e:
#             print(e)
#         cv2.imshow("image", cv_image)
#         cv2.waitKey()

# def main(args):
#     rospy.init_node('listener', anonymous=True)
#     ls = listener()
#     print 'init node'
#     rospy.spin()
#     print 'rospy.spin()'
    # try:

    # except KeyboardInterrupt:
    #     print("Shutting down")
    # cv2.destroyAllWindows()




def callback(image, camera_info):
    print 'in callback'
    global bride
    # here we convert ros_image into an opencv-compatible image
    try:
        print 'converting ROS image'
        cv_image = bridge.imgmsg_to_cv2(image, "bgr8")
    except CvBridgeError as e:
        print(e)
    caminfo = msg
    print type(caminfo)


# def main(args):
print 'init node'
rospy.init_node('my_node', anonymous=True)
print 'image sub'
image_sub = message_filters.Subscriber('image', Image)
print 'info sub'

info_sub = message_filters.Subscriber('camera_info', CameraInfo)
print 'time'
ts = message_filters.ApproximateTimeSynchronizer([image_sub, info_sub], 1, 1)
ts.registerCallback(callback)
print 'rospy.spin()'
# rospy.spin()
print 'done'

# if __name__ == '__main__':
#     main(sys.argv)

Asked by Fizz on 2020-08-26 20:08:51 UTC

Comments

As I mentioned in my post, I've tried about everything I could think of. This is the reason I have a lot of the code commented out. Also, I'm converting the ros image into something I can use with OpenCV in python through CV_bridge.

Asked by Fizz on 2020-08-26 20:10:34 UTC

How do you determine that info_sub does not subscribe anything? I my opinion stopping at rospy.spin() is actually the normal behavior because "rospy.spin() simply keeps your node from exiting until the node has been shutdown"

Asked by rfn123 on 2020-08-27 03:49:34 UTC

When I include info_sub with the message_filters.ApproxomateTime..(etc) it just stops at rospy.spin() and doesn't seem to do anything. I've added print statements for debugging but it never gets into the callback. if I remove info_sub from it, and remove the camera_info as a variable in the callback then the program works. I guess i assumed the problem was rospy.spin since it wouldn't go any further than that.

Asked by Fizz on 2020-08-27 04:05:23 UTC

rospy.spin() is needed because without it the callbacks will never get called. Did you verify e.g. with rostopic echo that the topic /camera_info is not emtpy?

Asked by rfn123 on 2020-08-27 04:27:01 UTC

Yup, it is outputing with rostopic and is not empty.

Asked by Fizz on 2020-08-27 04:48:13 UTC

Calling ros::spin actually put your program into internal ros event loop, so you have to uncomment it anyway. Another suggestion is to increase queue size in ApproximateTimeSynchronizer parameters from 1 to at least 5. Other stuff looks ok. If you can't get it work you can upload your bag file somewhere and provide link here. It will help us run your code and debug.

Asked by dtyugin on 2020-08-27 16:26:16 UTC

Answers

Lol, a huge face palm. Make sure you have the right rostopic when you initialize your program lol. I had edited the program a bit, but the topic I had incorrect when editing was /webcam/camera_info. I had set it /webcam/camerainfo, and that was why is was not working.

#!/usr/bin/env python

# http://wiki.ros.org/cv_bridge/Tutorials

import rospy
import cv2
import numpy as np
#from std_msgs.msg import String
from sensor_msgs.msg import Image, CameraInfo
#from sensor_msgs.msg import Imu                                                                             #7/14/2020 NJL added
#from sensor_msgs.msg import Range                                                                           #7/15/2020 NJL added
# from sensor_msgs.msg import CameraInfo
# from gazebo_msgs.msg import ModelStates
from cv_bridge import CvBridge, CvBridgeError
import sys
import time                                                                                                 #7/14/2020 NJL added
import message_filters                                                                                      #7/16/2020 NJL added
#import matplotlib.pyplot as plt
import pandas as pd                                                                                         #7/21/2020 NJL addded
import string

bridge = CvBridge()



# class listener:
#     def __init__(self):
#         self.image_sub = message_filters.Subscriber("/webcam/image_raw", Image)
#         self.caminfo_sub = message_filters.Subscriber("webcam/CameraInfo", CameraInfo)
#         self.ts = message_filters.ApproximateTimeSynchronizer([self.image_sub, self.caminfo_sub], 1, 1)
#         self.ts.registerCallback(self.callback)

#     def callback(self, ros_image, camera_info):
#         global bride
#         # here we convert ros_image into an opencv-compatible image
#         try:
#             print 'converting ROS image'
#             cv_image = bridge.imgmsg_to_cv2(ros_image, "bgr8")
#         except CvBridgeError as e:
#             print(e)
#         cv2.imshow("image", cv_image)
#         cv2.waitKey()


# def main(args):
#     rospy.init_node('listener', anonymous=True)
#     ls = listener()
#     print 'init node'
#     rospy.spin()
#     print 'rospy.spin()'
    # try:

    # except KeyboardInterrupt:
    #     print("Shutting down")
    # cv2.destroyAllWindows()




def callback(image, camera_info):
    print 'in callback'
    global bride
    # here we convert ros_image into an opencv-compatible image
    try:
        print 'converting ROS image'
        cv_image = bridge.imgmsg_to_cv2(image, "bgr8")
    except CvBridgeError as e:
        print(e)

    R = camera_info.R
    print R
    cv2.imshow("image", cv_image)
    cv2.waitKey()


def main(args):
    print 'init node'
    rospy.init_node('my_node', anonymous=True)
    print 'image sub'
    image_sub = message_filters.Subscriber('/webcam/image_raw', Image)
    print 'info sub'
    info_sub = message_filters.Subscriber('/webcam/camera_info', CameraInfo)
    print 'time'
    ts = message_filters.ApproximateTimeSynchronizer([image_sub, info_sub], 1, 1)
    ts.registerCallback(callback)
    print 'rospy.spin()'
    rospy.spin()
    print 'done'

if __name__ == '__main__':
    main(sys.argv)

Asked by Fizz on 2020-08-27 18:17:11 UTC

Comments

is there a reason that when I dsiplay the iimage in imshow, that it freezes?

Asked by Fizz on 2020-08-27 20:42:54 UTC

You defined cv2.waitKey() without parameter, this means it blocks the process and will wait indefinitely for a key press before continuing the program.

Asked by rfn123 on 2020-08-28 10:21:56 UTC

I've been able to just press my space bar for the image to update, and left it like that since I was doing some image processing in a different program and having it run continuously wasn't good for me to analyze. Basically this is me trying to implement something before integrating it into my bigger chunk of code I've written. But regardless of what value I stick into waitKey(), it stops after a couple seconds of displaying the image.

Asked by Fizz on 2020-08-28 15:19:31 UTC