AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
behavior_mode_executor.hpp
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <chrono>
18#include <functional>
19#include <map>
20#include <memory>
21#include <string>
22
23#include "auto_apms_behavior_tree/executor/generic_executor_node.hpp"
24#include "auto_apms_interfaces/action/start_tree_executor.hpp"
25#include "auto_apms_interfaces/srv/set_behavior.hpp"
26#include "auto_apms_px4/mode_registration.hpp"
27#include "auto_apms_px4/vehicle_command_client.hpp"
28#include "auto_apms_util/action_context.hpp"
29#include "px4_ros2/components/mode.hpp"
30#include "px4_ros2/components/mode_executor.hpp"
31#include "px4_ros2/control/setpoint_types/direct_actuators.hpp"
32#include "rclcpp/rclcpp.hpp"
33#include "rclcpp_action/rclcpp_action.hpp"
34
36{
37
46{
47 std::string build_request;
48 std::string build_handler;
49 std::string entry_point;
50 std::string node_manifest;
51};
52
65class BehaviorOwnedMode : public px4_ros2::ModeBase
66{
67public:
68 BehaviorOwnedMode(rclcpp::Node & node, const px4_ros2::ModeBase::Settings & settings);
69
70 void onActivate() override {}
71 void onDeactivate() override {}
72 void updateSetpoint(float dt_s) override;
73
78 void finish(px4_ros2::Result result) { completed(result); }
79
80private:
81 std::shared_ptr<px4_ros2::DirectActuatorsSetpointType> actuator_setpoint_ptr_;
82};
83
102class BehaviorModeExecutor : public px4_ros2::ModeExecutorBase
103{
104public:
106
117
118 struct Config
119 {
122 bool defer_failsafes{false};
123 };
124
126 static constexpr std::chrono::milliseconds DEFAULT_ACTIVATION_TIMEOUT{5000};
127
140 BehaviorOwnedMode & owned_mode, const px4_ros2::ModeExecutorBase::Settings & settings,
141 std::function<Config()> config_provider, BehaviorSpec initial_spec,
143
144 void onActivate() override;
145 void onDeactivate(DeactivateReason reason) override;
146
156 void prepareTree();
157
169 bool setBehavior(const BehaviorSpec & candidate, std::string & message);
170
181 bool requestAndVerifyActivation(std::chrono::milliseconds timeout = DEFAULT_ACTIVATION_TIMEOUT);
182
187 static CompletionReaction reactionFromString(const std::string & str);
188
196 void onExecutionResult(ExecutionResult result);
197
198private:
206 std::unique_ptr<auto_apms_behavior_tree::Tree> buildTree(const BehaviorSpec & spec);
207
208 void performReaction(CompletionReaction reaction, ExecutionResult result);
209
217 void scheduleLoiter();
218
219 rclcpp::Node & node_;
220 BehaviorOwnedMode & owned_mode_;
222 std::function<Config()> config_provider_;
223 Config config_;
224 BehaviorSpec current_spec_;
225 VehicleCommandClient vehicle_command_client_;
227 std::unique_ptr<auto_apms_behavior_tree::Tree> prepared_tree_ptr_;
228};
229
267class BehaviorModeExecutorNode : public auto_apms_behavior_tree::GenericTreeExecutorNode
268{
269public:
270 using StartAction = auto_apms_interfaces::action::StartTreeExecutor;
271 using StartActionContext = auto_apms_util::ActionContext<StartAction>;
272 using StartGoalHandle = rclcpp_action::ServerGoalHandle<StartAction>;
273 using SetBehaviorSrv = auto_apms_interfaces::srv::SetBehavior;
274
275 explicit BehaviorModeExecutorNode(const rclcpp::NodeOptions & options);
276
277protected:
278 void onTermination(const ExecutionResult & result) override;
279
280private:
281 static px4_ros2::ModeExecutorBase::Settings::Activation activationFromString(const std::string & str);
282
294 bool applyBehavior(BehaviorSpec candidate, std::string & message);
295
296 /* set_behavior service */
297 void handleSetBehavior(
298 const std::shared_ptr<SetBehaviorSrv::Request> request, std::shared_ptr<SetBehaviorSrv::Response> response);
299
300 /* StartTreeExecutor action */
301 rclcpp_action::GoalResponse handleStartGoal(
302 const rclcpp_action::GoalUUID & uuid, std::shared_ptr<const StartAction::Goal> goal_ptr);
303 rclcpp_action::CancelResponse handleStartCancel(std::shared_ptr<StartGoalHandle> goal_handle_ptr);
304 void handleStartAccept(std::shared_ptr<StartGoalHandle> goal_handle_ptr);
305
306 std::unique_ptr<BehaviorOwnedMode> owned_mode_ptr_;
307 std::unique_ptr<BehaviorModeExecutor> mode_executor_ptr_;
308 ModeRegistrationHandler registration_handler_;
309
310 rclcpp::Service<SetBehaviorSrv>::SharedPtr set_behavior_service_ptr_;
311 rclcpp_action::Server<StartAction>::SharedPtr start_action_ptr_;
312 StartActionContext start_action_context_;
314 std::map<rclcpp_action::GoalUUID, bool> pending_attach_;
315 std::map<rclcpp_action::GoalUUID, bool> pending_clear_blackboard_;
316};
317
318} // namespace auto_apms_px4
Flexible and configurable ROS 2 behavior tree executor node.
ExecutionResult
Enum representing possible behavior tree execution results.
static CompletionReaction reactionFromString(const std::string &str)
Parse a string into a CompletionReaction.
CompletionReaction
Reaction performed when a behavior terminates or fails, using the in-charge executor API.
@ HOLD
Schedule the owned mode (hold position) and stay in charge.
@ COMPLETE
Report the owned mode as completed to the FMU (relinquish charge).
void onExecutionResult(ExecutionResult result)
Handle the termination of the behavior running on the in-process executor.
bool requestAndVerifyActivation(std::chrono::milliseconds timeout=DEFAULT_ACTIVATION_TIMEOUT)
Request activation of the owned mode from ROS 2 and wait until it is confirmed in charge.
bool setBehavior(const BehaviorSpec &candidate, std::string &message)
Verify a candidate behavior and, if valid, make it the current behavior.
void prepareTree()
Build the current behavior tree and keep it detached, ready to be executed on the next activation.
BehaviorModeExecutor(BehaviorOwnedMode &owned_mode, const px4_ros2::ModeExecutorBase::Settings &settings, std::function< Config()> config_provider, BehaviorSpec initial_spec, auto_apms_behavior_tree::GenericTreeExecutorNode &engine)
Constructor.
static constexpr std::chrono::milliseconds DEFAULT_ACTIVATION_TIMEOUT
Default time to wait for the owned mode's nav_state to become active in requestAndVerifyActivation().
Registration placeholder PX4 mode owned by a BehaviorModeExecutor.
void finish(px4_ros2::Result result)
Report completion of the mode to the FMU. Only takes effect while the mode is active.
Handles the registration of a PX4 mode with the FMU and announces its dynamically assigned nav_state.
Client for sending requests to the PX4 autopilot using the VehicleCommand topic.
Helper class that stores contextual information related to a ROS 2 action.
Implementation of PX4 mode peers offered by px4_ros2_cpp enabling integration with AutoAPMS.
Which behavior to run and how to build it.
std::string build_handler
Fully qualified class name of the build handler plugin (empty keeps the current one).
std::string entry_point
Single point of entry for behavior execution.
std::string build_request
Behavior build request (e.g. a registered behavior resource identity or XML).
std::string node_manifest
Encoded node manifest specifying additional nodes to load.