0
$\begingroup$

Rosanswers logo

Hi, I built a node with a class in it, the class has two callbacks one is bind to dynamic reconfigure server, the other is bind to a service. Both callbacks are class member. So it is something like this:

class A 
{
   bool param;
   bool callback1 (node::service::Request &req, node::service::Response &res)
   {  
    //some long computations
    if (param)
    //do something
    else
    //do something else
   }
   
   void callback2 (node::nodeConfig &config, uint32_t level)
   {
    //updating parameters...
    param = config.param;
   }
}

The service callback has some internal loop that requires user input to continue, my idea was to let user (re)configure parameters while the service executes. However this is not working because callback2 does not interrupt callback1 and param is only set AFTER callback1 terminates.

What would be the correct way to achieve this ? How can i rewrite the class so that callback2 can interrupt callback1 ?

I thought that maybe this happens because both callbacks are class members, what if callback2 is a global function ?


Originally posted by Tabjones on ROS Answers with karma: 43 on 2015-03-23

Post score: 0


Original comments

Comment by dornhege on 2015-03-23:
This has nothing to do with callbacks being members or not. You need to do multi-threaded spinning if you want multiple callbacks to trigger. I'm not sure if just adding an AsyncSpinner is already sufficient.

Comment by dornhege on 2015-03-23:
If you are doing very lengthy computations, it might be a good idea to switch to actionlib.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

As @dornhege stated, this has nothing to do with your class structure. It depends on how the ros callbacks are managed. Typically it is configured such that only one callback can be called at a time. The callbacks can be called while your control loop is in ros::spin() or ros::spinOnce(). This default for you has the advantage that none of your code is executed in parallel, i. e. you do not have to worry about thread-safety, mutexes, race-conditions and so on...

Probably the best solution for your problem would be to switch from services to non-blocking actions in actionlib. http://wiki.ros.org/actionlib This is the preferred approach for long running calculations.

For having your callbacks executed in parallel, you wlll need an AsyncSpinner, see http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning#Multi-threaded_Spinning. This means you have to take care of thread-safety, mutexes, race-conditions and so on. Moreover, you will likely need a separated callback queue (ideally single threaded per queue) for both of your callbacks (http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning#Advanced:_Using_Different_Callback_Queues) because otherwise your not only your callbacks can be executed in parallel but also multiple calls into your callback functions at the same time are possible.


Originally posted by Wolf with karma: 7555 on 2015-03-23

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by Tabjones on 2015-03-23:
Thanks, this was very helpful.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.