ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org
Ask Your Question
1

Easy way to cancel a ROS2 action

asked 2022-05-24 10:57:02 -0500

AndyZe gravatar image

updated 2022-08-31 12:09:40 -0500

For quick testing, what's the easiest way to cancel a ROS2 action? Preferably something that I can run external to my program, without having to hack its source code.

It looks like rclpydoes not have a way to cancel an action without having a goal handle. https://github.com/ros2/rclpy/blob/ma... So we can rule out Python.

I don't see a command line option.

The best I have so far is this C++ script. It goes with the examples here.

#include "example_interfaces/action/fibonacci.hpp"

#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"

namespace {
  using Fibonacci = example_interfaces::action::Fibonacci;
}

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::NodeOptions node_options;
  auto node = rclcpp::Node::make_shared("action_server_cancellation", "", node_options);

rclcpp_action::Client<Fibonacci>::SharedPtr client_ptr = rclcpp_action::create_client<Fibonacci>(node, "fibonacci");
  if (!client_ptr->wait_for_action_server(std::chrono::seconds(5))) {
    RCLCPP_ERROR(node->get_logger(), "Action server not available after waiting");
    rclcpp::shutdown();
  }
  client_ptr->async_cancel_all_goals();
  RCLCPP_ERROR(node->get_logger(), "Cancellation was requested.");

  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}
edit retag flag offensive close merge delete

Comments

So .. what's your question?

gvdhoorn gravatar image gvdhoorn  ( 2022-05-24 12:08:45 -0500 )edit

vaguely hoping there is an easier way while realizing that the ROS2 default implementation is a memory violation ;)

But maybe this will be useful to other people

AndyZe gravatar image AndyZe  ( 2022-05-24 12:11:22 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2022-05-24 12:29:16 -0500

gvdhoorn gravatar image

updated 2022-05-24 12:38:57 -0500

Tbh, personally I find it really weird a random client can cancel all goals currently being processed by an action server, but it appears it's part of the service spec (from here):

# Cancel one or more goals with the following policy:
#
# - If the goal ID is zero and timestamp is zero, cancel all goals.
# - If the goal ID is zero and timestamp is not zero, cancel all goals accepted
#   at or before the timestamp.
# - If the goal ID is not zero and timestamp is zero, cancel the goal with the
#   given ID regardless of the time it was accepted.
# - If the goal ID is not zero and timestamp is not zero, cancel the goal with
#   the given ID and all goals accepted at or before the timestamp.

I've not checked it, but from the documentation, it would appear submitting a new goal with ID 0 and stamp 0 would result in all goals getting cancelled (this is actually how async_cancel_all_goals(..) is implemented.

You might even be able to achieve the same thing by invoking the (hidden) service which is used to submit goals directly.

That should be doable using ros2 service ....

edit flag offensive delete link more

Comments

Thanks for the answer. I'll try it soon.

Tbh, personally I find it really weird a random client can cancel all goals

^I like this. It is nice for things like protective stops, where you just want to stop whatever's running.

AndyZe gravatar image AndyZe  ( 2022-05-24 14:34:51 -0500 )edit

Without any additional authentication or authorisation, this makes it trivial to implement a DoS attack against action servers, from any client (if it works as the documentation implies it does).

It is nice for things like protective stops, where you just want to stop whatever's running.

as long as you're not using it for actual safety-related purposes.

gvdhoorn gravatar image gvdhoorn  ( 2022-05-25 02:01:05 -0500 )edit

Did it work?

gvdhoorn gravatar image gvdhoorn  ( 2022-05-25 09:02:35 -0500 )edit
1

I haven't thoroughly tested it because filling out an action request from command line in ROS2 is burdensome. Tab-complete doesn't work. I'm sure it would work but the C++ executable is almost easier.

AndyZe gravatar image AndyZe  ( 2022-05-25 09:12:55 -0500 )edit

I'm confused. Action goals are submitted using a service.

The idea would be to invoke that service directly.

Not to construct a goal.

gvdhoorn gravatar image gvdhoorn  ( 2022-05-25 09:23:00 -0500 )edit
1

@AndyZe

To find your <service-name>: ros2 node info <your-action-server-node> --include-hidden

To cancel all goals: ros2 service call <service-name> action_msgs/srv/CancelGoal

The <service-name> should look something like that: <node-name>/_action/cancel_goal

tnajjar gravatar image tnajjar  ( 2022-08-29 08:00:37 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2022-05-24 10:57:02 -0500

Seen: 429 times

Last updated: Aug 31