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

How to kill a callback?

asked 2015-06-10 16:49:02 -0600

ishareef gravatar image

I'm having some trouble with killing my callback function properly.

I have a main node (with its own ros::NodeHandle nh) which calls a class which initializes the following Subscriber with a ("/camera/image_raw"):

ros::NodeHandle nh;
int num = 0;
image_transport::ImageTransport it(nh);
image_transport::Subscriber sub = it.subscribe(topic,  1, imageCallback,this);
ros::spin();

The callback function in question is approximately as follows:

void imageCallback()
{
      num++; //increments the global variable num
      if(num < 10)
      {
           cv::imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
           // ... do some processing using cv_bridge and write to a folder directory 
          cv::imwrite(name,cv_bridge::toCvShare(msg, "bgr8")->image);
          // ... the intention is that only 9 processed images are stored in this folder
          //       under the given name

      }else if(num >= 10)
     {
           sub.shutdown();  //  Intended to kill the subscriber once the 9th iteration is completed. 

     }
     cv::waitKey(30);
}

My problem is that once the value of num reaches 10, the main thread appears to halt and ROS ceases to print anything to the console.

However, if I were to remove the line sub.shutdown() , then we are still stuck inside the callback forever and we have no way of returning back to the program-flow of the main node.

How can we effectively "kill" the callback loop at its nth iteration and return back to the original node which called it?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2015-06-10 17:40:38 -0600

ahendrix gravatar image

ros::spin() is an infinite loop; it continues until your process is killed, and it's the reason that your constructor is hanging; this happens regardless of whether you have any active subscribers or callbacks.

If this is inside of an object, you can repeatedly call ros::SpinOnce() until the member variable that counts frames has reached the appropriate value. (This works because ros::SpinOnce() does not block forever)

edit flag offensive delete link more

Comments

Thanks for the answer. But we did try ros::spinOnce(). Only when we did, we completely skipped even entering the body of the callback.

After some tinkering, we did manage to fix it, however. We used:

while(num < 10)
       ros::spinOnce();

And it appears to work.

ishareef gravatar image ishareef  ( 2015-06-11 17:53:24 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-06-10 16:45:13 -0600

Seen: 1,776 times

Last updated: Jun 10 '15