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

SimpleActionClient callback for pre-empted goals

asked 2011-05-19 04:03:41 -0600

Daniel Stonier gravatar image

updated 2011-05-23 13:31:03 -0600

Given a simple action client and server pair, working in callback mode, I dont think it's possible to get the client to be aware of when goals are pre-empted. It would seem a fairly 'simple' thing to want to be aware of. Goals when they're preempted in the server, trigger the server's callback, but once you're inside that callback nothing can get through to the action client's callbacks (not setSucceeded, setFeedback or setCanceled). Nothing turns up at the client's end I think because it is triggering on transitions, and it isn't set up for these particular transitions.

Or is there a way to do this that I've missed? Right now I'm looking at having to set up a specific subscriber to the action server's result topic, which works around the client/server mechanisms. Either that or go the full action server. A bit overkill for what I'm trying.

I wrote a simplified package to demonstrate. To compile, download the tarball, or just to view the source:

Is there something awry in the server handling?

edit retag flag offensive close merge delete


Tried a simple server/full client with callbacks. It gave full feedback on current/past goals with a callback that could act on any transition. I'd recommend not being shy to go past the simple server/simple client pair if you need some extra functionality as it is also surprisingly 'simple'.
Daniel Stonier gravatar image Daniel Stonier  ( 2011-06-23 12:29:36 -0600 )edit

I know this was a long time ago, but any chance you could repost your code? I think it'll be very helpful for something I'm trying to put together. Thanks!

TheMilkman92 gravatar image TheMilkman92  ( 2021-03-24 20:41:47 -0600 )edit

4 Answers

Sort by ยป oldest newest most voted

answered 2011-05-24 05:52:32 -0600

vpradeep gravatar image

Hi Daniel,

After running your client and server programs (and triggering the counting on the /update topic), it looks like the doneCallback is being triggered correctly upon successful goal completion.

However, you are concerned about the fact that the doneCallback is not being triggered upon goal preemption. Your server app is actually dealing with the preemption correctly. However, it is the client which is ignoring the pre-emption. This is not a bug. As soon as you send a new goal with the SimpleActionClient, it disables the callbacks associated with the previous goal. Thus, you never hear about when the old goal got preempted.

This behavior is described deep in the actionlib docs at:

edit flag offensive delete link more


Of course! I just tried running the client twice in parallel (which is partially my use case) and it successfully calls the done callback on a goal pre-empted by a goal sent by another process. I feel a bit naive now :P Thanks for the clarification.
Daniel Stonier gravatar image Daniel Stonier  ( 2011-05-25 12:23:23 -0600 )edit

answered 2011-05-20 04:57:19 -0600

vpradeep gravatar image

Hi Daniel,

Assuming you registered a SimpleDoneCallback() when you call SimpleActionClient::sendGoal(), you should most definitely receive a callback when the goal goes into a PREEMPTED state on the server. However, I think you might be using the action server slightly incorrectly.

Please refer to the following state transition diagram, copied from actionlib/DetailedDescription: Server States Detailed

When someone cancels a goal, the server does not immediately transition into a PREEMPTED or RECALLED state. Instead, the goal goes to either RECALLING or PREEMPTING, and the action server's cancel callback is called. It is then the server implementer's responsibility to transition the goal into a terminal state by calling setCancelled(), setAborted(), or setSucceeded(). As soon as the goal is transitioned into a terminal state, the client's SimpleDoneCallback will get triggered.

edit flag offensive delete link more


Ok, I'll see if I can revisit things and induce my current state of affairs in a simple example and see where that gets me, cheers.
Daniel Stonier gravatar image Daniel Stonier  ( 2011-05-22 18:40:24 -0600 )edit

answered 2011-05-23 22:47:51 -0600

Lorenz gravatar image

updated 2011-05-24 21:51:54 -0600

As far as I can see, the server cancels your goal correctly. I see a result message on the result topic and the goal transitions to state PREEMPTED on the status topic. The problem lies in the client. You do not explicitly cancel the goal but just send another one. One implication of this is that the client stops tracking the old goal before the preemption could be received and starts tracking the new goal. If you explicitly cancel the goal and wait for a result before sending the new goal, the client's done callback is executed with status preempted.

edit flag offensive delete link more


waitForServer should actually terminate. When he constructs the action client, it defaults to starting it's own spin thread, which means that waitForServer will actually get the necessary callbacks to unblock.
vpradeep gravatar image vpradeep  ( 2011-05-24 05:55:27 -0600 )edit
You are right, Vijay. I've updated my answer. It was not terminating on the computer I tried out the program first though. No idea why.
Lorenz gravatar image Lorenz  ( 2011-05-24 21:51:36 -0600 )edit
I was going to mention the constructor defaults to startup with a spin thread but vpradeep beat me to it.
Daniel Stonier gravatar image Daniel Stonier  ( 2011-05-25 15:00:00 -0600 )edit
I hoped to avoid pre-emption management in the client (seems a bit redundant in both server and client?), but more importantly, we want to handle both cancelling and merging of goals differently in the server. Explicitly cancelling from the client doesn't allow for that. Need to rethink our design.
Daniel Stonier gravatar image Daniel Stonier  ( 2011-05-25 15:03:11 -0600 )edit
I think not using SimpleActionClient but the more complex ActionClient might work for you. It allows you to specify per-goal callbacks and isn't too hard to use either.
Lorenz gravatar image Lorenz  ( 2011-05-25 20:07:25 -0600 )edit
Yep - rewriting our joint trajectory controller/action servers tomorrow - thank you for the feedback!
Daniel Stonier gravatar image Daniel Stonier  ( 2011-05-25 20:12:37 -0600 )edit

answered 2011-05-19 23:08:45 -0600

Lorenz gravatar image

Preemption should trigger the done callback that you can pass to SimpleActionClient::sendGoal. In case of preemption, the callback gets a SimpleClientGoalState set to preempted. If that doesn't work for you, I suspect there is something wrong in the server. Did you try implementing it using the execute callback instead of using a goal and a preemption callback?

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2011-05-19 04:03:41 -0600

Seen: 5,618 times

Last updated: May 24 '11