Skip to content

Feature: Async/await API for action clients - #15

Closed
iv461 wants to merge 31 commits into
mainfrom
feature/actions
Closed

Feature: Async/await API for action clients#15
iv461 wants to merge 31 commits into
mainfrom
feature/actions

Conversation

@iv461

@iv461 iv461 commented Feb 5, 2026

Copy link
Copy Markdown
Owner

Work in progress: an async/await-based API for action clients that supports the following:

  • awaiting the result of setting a goal
  • receiving feedback
  • obtaining the final result
  • receiving feedback

I currently don't think I can finish this PR due to multiple bugs in rclcpp as well as the specification of the actions being implemented incorrectly:

auto maybe_goal_handle = co_await action_client.send_goal(goal, 2s);
if(maybe_goal_handle.has_value()) {
   auto goal_handle = maybe_goal_handle.value();
   for(auto fb: co_await goal_handle.get_result(20s)) {
       if(fb.is_feedback()) {
          
       } else {
            /// We got the final result
            auto result = fb.result();
            break;
       }
   }
} else {
   /// Goal request rejected
}

would have a race condition, although it adheres to the specification. Feedback messages may be received before the get_result function is called, meaning they may be lost. This issue has been discussed here, and a fix has been proposed.

  • An API for cancelling send_goal and cancel requests (similar to regular service calls) is missing. Currently, it is not possible to cancel callbacks or delete a pending goal request. If the server dies, the client leaks memory. This issue has not yet been resolved in the rolling version, as there is currently no way to delete items from the pimpl_->pending_goal_responses map added here. Fixing this may require a fix in rcl

Minor TODOs:

  • Workaround for coroutine-related GCC 11 bug (error: no suspend point info for ‘‘co_await’ not supported by dump_decl<declaration error>’ 134 | auto r2 = co_await f2;), for Humble

Ivo Ivanov added 30 commits January 28, 2026 16:36
… to the async await support for feedback: the feedback has to remain a callback, because otherwise we would need to buffer feedbacks received between the goal acceptance and the implicit feedback callback registration done by co_await feedback(). This buffering would be required to avoid a race.
…re it throws an exception if the action is already done.
…, because the async_goal_result API does not make sense. For this, we move the result promise inside the goalhandle, this leads to the goal handle not being copyable, so we return a shared pointer to the goal handle (like the original ROS API). I've also added three other useful methods from the GoalHandle base
…always launches an asynchronous operation, which in the case of actions API does not hold anymore
@iv461 iv461 changed the title Feature/actions Feature: Async/await API for action clients Feb 7, 2026
@iv461

iv461 commented Feb 17, 2026

Copy link
Copy Markdown
Owner Author

Closing in favor of #17 that pathes rclcpp to solve the above issues.

@iv461 iv461 closed this Feb 17, 2026
@iv461
iv461 deleted the feature/actions branch February 18, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant