EasyFleet
A simple-by-default framework for multi-robot, multi-capability fleets built on ROS 2
Loading...
Searching...
No Matches
capability.hpp
1// Copyright 2026 Intelligent Robotics Lab
2//
3// This file is part of the project EasyFleet
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#ifndef EASYFLEET_CORE__CAPABILITY_HPP_
17#define EASYFLEET_CORE__CAPABILITY_HPP_
18
19#include <memory>
20#include <string>
21
22#include "rclcpp/rclcpp.hpp"
23#include "rclcpp_lifecycle/lifecycle_node.hpp"
24#include "rclcpp_lifecycle/lifecycle_publisher.hpp"
25
26#include "easyfleet_core/action_server_base.hpp"
27#include "easyfleet_core/capability_node_base.hpp"
28#include "easyfleet_interfaces/msg/capability_description.hpp"
29#include "easyfleet_interfaces/msg/capability_status.hpp"
30
31namespace easyfleet_core
32{
33
35
63template<typename ActionServerT>
64class Capability : public rclcpp_lifecycle::LifecycleNode, public CapabilityNodeBase
65{
66public:
68 using CallbackReturn = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn;
71
76 explicit Capability(
77 const std::string & capability_name,
78 const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
79
80 ~Capability() override;
81
85 typename ActionServerBaseT::SharedPtr get_action_server() const noexcept;
86
90 const std::string & get_capability_name() const noexcept override;
91
96 const std::string & get_robot_name() const noexcept override;
97
102 const std::string & get_resolved_action_name() const noexcept;
103
104 // -- CapabilityNodeBase --
105 //
106 // Named *_node() (see capability_node_base.hpp) precisely so these don't
107 // collide with rclcpp_lifecycle::LifecycleNode's own same-purpose
108 // configure()/activate()/.../shutdown() member functions -- those keep
109 // working completely unchanged (e.g. test_capability.cpp's
110 // `capability_->configure(cb)` one-arg overload) since nothing here
111 // hides or shadows them. Each *_node() implementation (capability_impl.hpp)
112 // just calls the corresponding LifecycleNode transition and returns its
113 // CallbackReturn. get_node_base_interface() is the one exception: its
114 // name/signature/return type happen to exactly match LifecycleNode's own,
115 // so this override *does* hide that one -- harmlessly, since it forwards
116 // to it internally and nothing in this codebase calls it on a
117 // `Capability<T>` directly today.
119 CallbackReturn activate_node() override;
121 CallbackReturn cleanup_node() override;
122 CallbackReturn shutdown_node() override;
123 uint8_t get_current_state_id() const override;
124 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface() override;
125
126protected:
131 CallbackReturn on_configure(const rclcpp_lifecycle::State & previous_state) override;
136 CallbackReturn on_activate(const rclcpp_lifecycle::State & previous_state) override;
141 CallbackReturn on_deactivate(const rclcpp_lifecycle::State & previous_state) override;
146 CallbackReturn on_cleanup(const rclcpp_lifecycle::State & previous_state) override;
151 CallbackReturn on_shutdown(const rclcpp_lifecycle::State & previous_state) override;
152
153private:
154 void publish_heartbeat();
155 void stop_heartbeat();
156
157 std::string capability_name_;
158 std::string robot_name_;
159 std::string resolved_action_name_;
160 typename ActionServerBaseT::SharedPtr action_server_;
161
162 rclcpp_lifecycle::LifecyclePublisher<
163 easyfleet_interfaces::msg::CapabilityDescription>::SharedPtr capabilities_pub_;
164 rclcpp_lifecycle::LifecyclePublisher<
165 easyfleet_interfaces::msg::CapabilityStatus>::SharedPtr status_pub_;
166 rclcpp::TimerBase::SharedPtr heartbeat_timer_;
167};
168
169} // namespace easyfleet_core
170
171#include "easyfleet_core/detail/capability_impl.hpp"
172
173#endif // EASYFLEET_CORE__CAPABILITY_HPP_
Base class that hides the boilerplate of running a ROS 2 action server.
Definition action_server_base.hpp:66
std::shared_ptr< ActionServerBase< typename ActionServerT::ActionType > > SharedPtr
Definition action_server_base.hpp:81
Non-template handle to an already-constructed Capability<ActionServerT> instance, exposing exactly th...
Definition capability_node_base.hpp:41
std::shared_ptr< CapabilityNodeBase > SharedPtr
Shared pointer to a CapabilityNodeBase.
Definition capability_node_base.hpp:44
CallbackReturn activate_node() override
Drive the underlying lifecycle node from INACTIVE to ACTIVE.
Definition capability_impl.hpp:214
CallbackReturn on_configure(const rclcpp_lifecycle::State &previous_state) override
Reads capabilities_file and configures the contained ActionServerT.
Definition capability_impl.hpp:96
CallbackReturn on_shutdown(const rclcpp_lifecycle::State &previous_state) override
Stops the status heartbeat if still running.
Definition capability_impl.hpp:168
const std::string & get_resolved_action_name() const noexcept
Fully-qualified name of the action this capability exposes, e.g.
Definition capability_impl.hpp:89
CallbackReturn on_deactivate(const rclcpp_lifecycle::State &previous_state) override
Stops the status heartbeat.
Definition capability_impl.hpp:149
Capability(const std::string &capability_name, const rclcpp::NodeOptions &options=rclcpp::NodeOptions())
Constructs the capability node.
Definition capability_impl.hpp:42
CallbackReturn on_activate(const rclcpp_lifecycle::State &previous_state) override
Publishes the capability description and starts the status heartbeat.
Definition capability_impl.hpp:107
CallbackReturn on_cleanup(const rclcpp_lifecycle::State &previous_state) override
Releases the resources acquired in on_configure().
Definition capability_impl.hpp:158
ActionServerBaseT::SharedPtr get_action_server() const noexcept
The action server backing this capability.
Definition capability_impl.hpp:71
CallbackReturn shutdown_node() override
Drive the underlying lifecycle node to FINALIZED, from whatever state it is currently in.
Definition capability_impl.hpp:241
CallbackReturn cleanup_node() override
Drive the underlying lifecycle node from INACTIVE to UNCONFIGURED.
Definition capability_impl.hpp:232
rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn CallbackReturn
Lifecycle transition result type shared with rclcpp_lifecycle.
Definition capability.hpp:68
uint8_t get_current_state_id() const override
The underlying lifecycle node's current state id.
Definition capability_impl.hpp:249
CallbackReturn deactivate_node() override
Drive the underlying lifecycle node from ACTIVE to INACTIVE.
Definition capability_impl.hpp:223
ActionServerBase< typename ActionServerT::ActionType > ActionServerBaseT
The ActionServerBase<...> specialization backing this capability.
Definition capability.hpp:70
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr get_node_base_interface() override
So a Deployment can add the underlying node to its shared executor without knowing its concrete type.
Definition capability_impl.hpp:256
const std::string & get_capability_name() const noexcept override
The capability identity field published on /capabilities and /capabilities_status.
Definition capability_impl.hpp:77
CallbackReturn configure_node() override
Drive the underlying lifecycle node from UNCONFIGURED to INACTIVE.
Definition capability_impl.hpp:205
const std::string & get_robot_name() const noexcept override
This node's namespace, without the leading '/' (empty if none), e.g.
Definition capability_impl.hpp:83