EasyFleet
A simple-by-default framework for multi-robot, multi-capability fleets built on ROS 2
Loading...
Searching...
No Matches
ActionServerBase< ActionT > Class Template Referenceabstract

Base class that hides the boilerplate of running a ROS 2 action server. More...

#include <action_server_base.hpp>

Public Types

using ActionType = ActionT
 The wrapped rclcpp_action action type.
using Goal = typename ActionT::Goal
 Goal type of the wrapped action.
using Feedback = typename ActionT::Feedback
 Feedback type of the wrapped action.
using Result = typename ActionT::Result
 Result type of the wrapped action.
using GoalHandle = rclcpp_action::ServerGoalHandle<ActionT>
 rclcpp_action server-side goal handle type of the wrapped action.
using GoalHandleSharedPtr = std::shared_ptr<GoalHandle>
 Shared pointer to a GoalHandle.
using SharedPtr = std::shared_ptr<ActionServerBase<ActionT>>
 Shared pointer to an ActionServerBase<ActionT>.

Public Member Functions

 ActionServerBase (const ActionServerBase &)=delete
ActionServerBase & operator= (const ActionServerBase &)=delete
const std::string & get_action_name () const noexcept
 Fully-qualified name of the action served by this instance.
bool is_active () const
 Whether a goal is currently executing.
bool is_preemptable () const noexcept
 Current value of the "allow_preemption" parameter for this action.

Protected Member Functions

template<typename NodeT>
 ActionServerBase (NodeT &node, const std::string &action_name, bool default_allow_preemption=true)
 Constructs the action server, attached to node under action_name.
virtual rclcpp_action::GoalResponse on_goal_received (const rclcpp_action::GoalUUID &uuid, std::shared_ptr< const Goal > goal)=0
 Validate an incoming goal.
virtual void on_execute (const GoalHandleSharedPtr goal_handle)=0
 Run an accepted goal to completion.
virtual rclcpp_action::CancelResponse on_cancel_requested (const GoalHandleSharedPtr goal_handle)
 Decide whether a cancel request (via the action's cancel service) should be accepted.
virtual void on_preempted (const GoalHandleSharedPtr &preempted_goal_handle)
 Optional hook invoked (from the accepting thread, not the worker thread) when a new goal is about to preempt the currently running one.
bool is_preempt_requested () const noexcept
 Whether a newer goal has been accepted and is waiting to replace the one currently executing.
bool is_shutdown_requested () const noexcept
 Whether this object is being destroyed.
rclcpp::Logger logger () const
 Logger of the node hosting this action server.

Detailed Description

template<typename ActionT>
class easyfleet_core::ActionServerBase< ActionT >

Base class that hides the boilerplate of running a ROS 2 action server.

A node exposes an action by inheriting from ActionServerBase<ActionT> and implementing three hooks: on_goal_received(), on_execute() and, optionally, on_cancel_requested(). Everything else – wiring the rclcpp_action::Server, running goals on a dedicated worker thread, transitioning the goal state machine, and deciding whether an incoming goal is allowed to preempt the one currently running – is handled here.

Preemption is governed by a boolean ROS 2 parameter named "<action_name>.allow_preemption" (with '/' in the action name mapped to '.'), so it can be set at startup and changed at runtime. Only one goal is ever executed at a time:

  • If preemption is disallowed and a goal is active, new goals are rejected outright.
  • If preemption is allowed, a new goal is accepted immediately and is_preempt_requested() starts returning true for the running goal. A long-running on_execute() implementation is expected to poll it (and is_shutdown_requested()) and return promptly, having settled the goal handle (succeeded/aborted/canceled).

This class is not copyable and does not itself derive from rclcpp::Node, so a node can inherit from several ActionServerBase<ActionT> (one per action) without any diamond-inheritance issues.

It attaches to any node type exposing the standard rclcpp node interfaces (get_node_base_interface(), get_node_clock_interface(), get_node_logging_interface(), get_node_parameters_interface(), get_node_waitables_interface()), which covers both rclcpp::Node and rclcpp_lifecycle::LifecycleNode.

Constructor & Destructor Documentation

◆ ActionServerBase()

template<typename ActionT>
template<typename NodeT>
ActionServerBase ( NodeT & node,
const std::string & action_name,
bool default_allow_preemption = true )
inlineexplicitprotected

Constructs the action server, attached to node under action_name.

Parameters
nodeNode (or lifecycle node) that will host the action server. Only used here, to extract its interfaces below (each kept as its own SharedPtr member) – not stored itself, so a reference (never null, unlike a pointer) is all this needs; must outlive this object.
action_nameName under which the action is advertised.
default_allow_preemptionInitial value of the preemption parameter, used only if the parameter has not already been declared/set (e.g. from a YAML params file or the command line).

Member Function Documentation

◆ get_action_name()

template<typename ActionT>
const std::string & get_action_name ( ) const
noexcept

Fully-qualified name of the action served by this instance.

Returns
Fully-qualified name of the action served by this instance.

◆ is_active()

template<typename ActionT>
bool is_active ( ) const

Whether a goal is currently executing.

Returns
Whether a goal is currently executing.

◆ is_preempt_requested()

template<typename ActionT>
bool is_preempt_requested ( ) const
protectednoexcept

Whether a newer goal has been accepted and is waiting to replace the one currently executing.

Returns
Whether a newer goal has been accepted and is waiting to replace the one currently executing. Only meaningful from within on_execute().

◆ is_preemptable()

template<typename ActionT>
bool is_preemptable ( ) const
noexcept

Current value of the "allow_preemption" parameter for this action.

Returns
Current value of the "allow_preemption" parameter for this action.

◆ is_shutdown_requested()

template<typename ActionT>
bool is_shutdown_requested ( ) const
protectednoexcept

Whether this object is being destroyed.

Returns
Whether this object is being destroyed. Long-running on_execute() implementations should treat this the same as a preemption request.

◆ logger()

template<typename ActionT>
rclcpp::Logger logger ( ) const
protected

Logger of the node hosting this action server.

Named without the usual get_ prefix to avoid an ambiguous lookup in classes that also inherit from rclcpp::Node or rclcpp_lifecycle::LifecycleNode, both of which already declare a get_logger() of their own.

Returns
The hosting node's logger.

◆ on_cancel_requested()

template<typename ActionT>
rclcpp_action::CancelResponse on_cancel_requested ( const GoalHandleSharedPtr goal_handle)
protectedvirtual

Decide whether a cancel request (via the action's cancel service) should be accepted.

Unrelated to preemption. Defaults to always accepting.

Parameters
goal_handleHandle of the goal a cancellation was requested for.
Returns
Whether the cancel request is accepted.

◆ on_execute()

template<typename ActionT>
virtual void on_execute ( const GoalHandleSharedPtr goal_handle)
protectedpure virtual

Run an accepted goal to completion.

Must leave the goal handle in a terminal state (succeed(), abort() or canceled()) before returning. Long-running implementations should periodically check is_preempt_requested(), goal_handle->is_canceling() and is_shutdown_requested() and return promptly when any of them is true. Only settle the goal with canceled() when goal_handle->is_canceling() is true (a client asked for it, so rcl_action has already transitioned the goal to CANCELING); for preemption or shutdown, which happen while the goal is still EXECUTING, use abort() instead – canceled() from EXECUTING is an invalid state transition.

Parameters
goal_handleHandle of the accepted goal to run to completion.

Implemented in ManipulationFakeActionServer, PerceptionFakeActionServer, and EasynavNavigationActionServer.

◆ on_goal_received()

template<typename ActionT>
virtual rclcpp_action::GoalResponse on_goal_received ( const rclcpp_action::GoalUUID & uuid,
std::shared_ptr< const Goal > goal )
protectedpure virtual

Validate an incoming goal.

Return ACCEPT_AND_EXECUTE or REJECT. Preemption bookkeeping is applied automatically after this returns ACCEPT_AND_EXECUTE, so implementations only need to worry about whether the content of the goal is valid.

Parameters
uuidId of the incoming goal.
goalGoal content to validate.
Returns
ACCEPT_AND_EXECUTE or REJECT.

◆ on_preempted()

template<typename ActionT>
void on_preempted ( const GoalHandleSharedPtr & preempted_goal_handle)
protectedvirtual

Optional hook invoked (from the accepting thread, not the worker thread) when a new goal is about to preempt the currently running one.

Parameters
preempted_goal_handleHandle of the goal being preempted.

The documentation for this class was generated from the following files: