# Understanding actions

I've been using ROS services to ask a node to perform a long running (a few seconds) task and I want to switch to using ROS actions as recommended on http://wiki.ros.org/actionlib . The task is a call to a path-planning library that blocks until a path is found.

The documentation has me confused when it comes to blocking on the action server side in the goal callback. The fibonnacti example stays in the callback until the action is complete.

The under-the-hood description says:

Any actions taken in a callback received for a new goal should not be long running. The user may, of course, signal another thread to do work, but should not block.

1) Isn't that exactly the point of actions, that they are long running? Does that mean that the fibonnaci example is actually bad practice?

The under-the-hood description continues to say:

Upon construction of the simple action server, the user decides whether or not to spin up an extra thread to allow for taking long running actions in a goal callback.

2) I don't see this in the SimpleActionServer constructor. It has a boolean to choose autostarting, but nothing about spinning a separate thread.

This is an option in the SimpleActionClient, but its use is discouraged anyway.

3) So what is the recommended approach?

Should I only check for the legality of the goal and then setAccepted in the goal callback and then do the real work in my main thread (while(ros::ok() { ... }))? *

Or should/can I do the work in the goal callback (as the fibonnaci example does)? If I do that, will my feedback be sent and will I receive preemptions?

Thanks

EDIT: * I just noticed that setAccepted is not a member function of SimpleActionServer. This raises the question: Can I and do I have to mark a goal as accepted or is this done automatically when entering the goal callback with that goal?

edit retag close merge delete

Sort by » oldest newest most voted

SimpleActionServer and SimpleActionClient are designed to be 'simple' examples of how to do things. They are not designed to be a complete API reference.

Any actions taken in a callback received for a new goal should not be long running. The user may, of course, signal another thread to do work, but should not block.

Isn't that exactly the point of actions, that they are long running? Does that mean that the fibonnaci example is actually bad practice?

This approach will not support parallel evaluation because it does not delegate to another thread. But if we were to add that level of complexity it would start to no longer be a beginner tutorial. It's not the best, but in this case it's not going to hurt anything.

Defining long running is somewhat subjective. This example callback runs for a while but doesn't wait on external stimulus etc. Note that in some cases long running can refer to things that last hours.

Thanks for the detailed question but please separate your questions into different questions so that one does not need to try to answer 3 questions at once.

more

My long running task does not need external stimuli while in the callback and I don't need concurrent ones, but I do want to be able to preempt one and send feedback. So mirroring the fibonnaci callback example is ok?

Still unclear: Does SimpleActionServer spin up it's own thread? Cf. question 2).

( 2018-03-01 04:17:56 -0500 )edit

I'm not sure if I'm doing it correctly but so far this is what I've experienced:

I have some long running goal callbacks and I think the main downside is that I can't handle new goals because the callback will only run in the one thread, but in my architecture I prevent new goals while the first one is running or have the single goal setter first preempt. You have to consider whether there are threads to handle other things like receiving messages- the goal doesn't necessarily need to run in a separate thread, but you can have callbacks for subscriptions or whatever else run in extra threads. Or sleep occasionally to accommodate those, and continually check for preemption (also ros shutdown) throughout the long goal callback.

more