ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Create a subscriber to an Image topic

asked 2018-05-09 10:00:20 -0500

erivera1802 gravatar image

Hi, Im trying to wrtie a node that subscribes to a image topic, however, after almost copying the ros tutorial, I keep getting an error. The relevant parts of my code are:

ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Subscriber sub;
sub=it.subscribe("/sensors/camera/top/image_raw",1, Imtest::callbackSubscriber);

And my callback is:

void Imtest::callbackSubscriber(const sensor_msgs::ImageConstPtr& msg)

The error I get is:

/home/kal3-5/workspaces/my_first_ws/src/imtest_ros_tool/src/imtest/imtest.cpp:41:83: error: invalid use of non-static member function
     sub=it.subscribe("/sensors/camera/top/image_raw",1, Imtest::callbackSubscriber);

My version of ROS is Kinetic, Ubuntu 16.04

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted

answered 2018-05-09 11:22:38 -0500

updated 2018-05-09 17:02:40 -0500

The problem here is at the subscriber attribution, you must pass a function pointer to it using the '&' before the method name. If you replace the subscriber attribution line for the following, it may solves your problem:

sub=it.subscribe("/sensors/camera/top/image_raw",1, &Imtest::callbackSubscriber, this);

Waiting for reply.

edit flag offensive delete link more


In c++ a function name without parentheses () decomposes to a function pointer, there is no need for the & operator. The problem the OP is having is caused because they are trying to use a method of a class without a pointer to the instance of that class.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-05-09 19:00:28 -0500 )edit

It was really funny, because a tried this solution at first, and it didnt work, but when I write the new node to show you guys the error, it worked! Thanks a lot!

erivera1802 gravatar image erivera1802  ( 2018-05-10 09:41:15 -0500 )edit

answered 2018-05-09 12:47:45 -0500

The difference between your code and the example tutorial here is that the tutorial is using a plain function as the callback handler, where you are trying to use a class method. Therefore to call the callback method ROS needs to know the method to call and a pointer to an instance of the object.

Now there are two ways you can use a class method as a callback function:

1) Make the method static so that no object pointer is needed to call it. This may not be appropriate in your case.

2) Subscribe to the camera topic using a ptr to the object instance that you want to receive the callback AND a pointer to the method within that object that will actually handle the callback. Here is a code snippet of this:

// instance of the imtest object to handle image callbacks.
Imtest imtestInstance;

ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Subscriber sub;

// Subscribe to the topic using instance pointer and method pointer.
sub=it.subscribe("/sensors/camera/top/image_raw",1, Imtest::callbackSubscriber, &imtestInstance);

Hope this helps.

edit flag offensive delete link more

answered 2018-05-10 09:42:29 -0500

erivera1802 gravatar image

I have not only used the accepted solution, but change the susbscriber type:

subscriber_=it.subscribeCamera("/sensors/camera/top/image_raw",1, &ImageReader::callbackSubscriber, this);
    publisher_ = it.advertiseCamera("camera/image", 1,false);

And my callback is now:

void ImageReader::callbackSubscriber(const sensor_msgs::Image::ConstPtr& msg,
                                     const sensor_msgs::CameraInfo::ConstPtr& camera_info)
edit flag offensive delete link more

Question Tools



Asked: 2018-05-09 10:00:20 -0500

Seen: 4,698 times

Last updated: May 10 '18