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

how can I register a Callback when using ros::spinOnce ?

asked 2013-01-10 08:35:33 -0500

dinamex gravatar image

updated 2013-01-10 08:50:10 -0500

Hi all I would like to control if I subscribe or unsubscribe to a topic via a key press. I Can see that the subscribtion works but the registered callback is never called when I use ros::spinOnce(). When I change to ros::spin() the callbacks works but not the key control because ros::spin leaves the main loop and doesn't come back unless the node isn't shutdown. Is there a way to control the subscriber status?

Here is my code:

using namespace sensor_msgs;
using namespace message_filters;
typedef sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;



image_transport::SubscriberFilter *webcam_sub = NULL;
image_transport::SubscriberFilter *rgb_sub = NULL;
bool subscribtion; 

void subscribe(ros::NodeHandle nh, image_transport::ImageTransport it){

      webcam_sub = new image_transport::SubscriberFilter (it, "/panda_cam/image_raw", 200);
      rgb_sub = new image_transport::SubscriberFilter (it, "/camera/rgb/image_color", 200);
      Synchronizer<MySyncPolicy> sync(MySyncPolicy(1000), *webcam_sub, *rgb_sub);
      sync.registerCallback(boost::bind(&sync_callback, _1, _2));

}

void unsubscribe(){

      webcam_sub->unsubscribe();
      rgb_sub->unsubscribe();

}



void sync_callback(const ImageConstPtr&  rgb_image,const ImageConstPtr&  webcam_image){

      ROS_INFO("CALLBACK");

}    

int main(int argc, char **argv){

      ros::init(argc, argv, "subscriber");
      ros::NodeHandle nh;
      image_transport::ImageTransport it (nh);
      ros::Rate rate(100);


      while(ros::ok()){
         rate.sleep();
         int key = kbhit();
           if (key == 122 && subscribtion == false){
             subscribtion = true;
             subscribe(nh,it);
             ROS_INFO("Ready to recieve messages");                                                    
          }
          else if (key == 122 && subscribtion == true){
             subscribtion = false;
             unsubscribe();
             ROS_INFO("unsibscribed to topics");                
          }

         ros::spinOnce();
      }
    return 0;
}
edit retag flag offensive close merge delete

Comments

Were you able to get something stable working? I'm also looking for a good way to switch a boolean message with a keystroke.

TFinleyosu gravatar image TFinleyosu  ( 2013-12-05 04:10:44 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
2

answered 2013-03-05 09:57:52 -0500

tfoote gravatar image

If you want an interactive keyboard interface you need to make sure it's in it's own thread not waiting for other activities. The spinOnce is doing all the ROS message passing and processing callbacks so you may miss the keystroke.

edit flag offensive delete link more
1

answered 2013-12-05 03:47:08 -0500

Bill Smart gravatar image

updated 2015-07-10 09:44:00 -0500

lucasw gravatar image

Another way to do it would be to split the GUI elements into their own node, which would publish control messages (or issue service calls) to the node that does the work. Since the GUI node wouldn't subscribe to anything, it wouldn't need a spin().

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-01-10 08:35:33 -0500

Seen: 1,551 times

Last updated: Jul 10 '15