I'm controlling a mobile robot and I'd like to set up an action (call it back_and_forth) that commands the robot to move forward 1 meter, then move backwards one meter. The interface that I'm using (iRobot create3 ROS 2 API) uses actions to handle movement commands, so I need to call one action (move forward 1m), wait for it to complete, and call another action (move backwards 1m) inside the callback of my own action back_and_forth.
I have found reference to a few approaches for doing this, but none of them seem to work:
- Use ActionClient.send_goal() to send the move forwards and backwards actions. If I do this, the node gets stuck on that line and never continues to the move backwards action.
- Use ActionClient.send_goal_async(), followed by rclpy.spin_until_future_complete(). But as the documentation says, the future resolves "when the goal request has been accepted or rejected", not when the action completes. So it doesn't wait for the forward action to complete before moving onto the next one.
Something like this answer may work, but seems extremely convoluted and hacky for what should be a simple functionality.
This whole thing begs a broader question: if we can't wait for things (i.e. rclpy.spin) inside a callback, how are we supposed to write a meaningful action server that calls other services, actions, etc. to get things done, and only returns success once they are done?