AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
set_actuators.cpp
1// Copyright 2026 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#include "auto_apms_px4_interfaces/action/set_actuators.hpp"
16
17#include "auto_apms_behavior_tree_core/node.hpp"
18
19#define INPUT_KEY_MOTOR_COMMANDS "motor_commands"
20#define INPUT_KEY_SERVO_COMMANDS "servo_commands"
21#define INPUT_KEY_HOLD_PERIOD_MS "hold_period_ms"
22
23namespace auto_apms_px4
24{
25
26class SetActuatorsAction
27: public auto_apms_behavior_tree::core::RosActionNode<auto_apms_px4_interfaces::action::SetActuators>
28{
29public:
30 using RosActionNode::RosActionNode;
31
32 static BT::PortsList providedPorts()
33 {
34 return {
35 BT::InputPort<std::vector<float>>(
36 INPUT_KEY_MOTOR_COMMANDS,
37 "Motor commands as a semicolon-separated list. Range: [-1, 1], 'nan'|'NaN'|'NAN' = disarmed"),
38 BT::InputPort<std::vector<float>>(
39 INPUT_KEY_SERVO_COMMANDS,
40 "Servo commands as a semicolon-separated list. Range: [-1, 1], 'nan'|'NaN'|'NAN' = disarmed"),
41 BT::InputPort<uint32_t>(
42 INPUT_KEY_HOLD_PERIOD_MS, static_cast<uint32_t>(0),
43 "Hold the commands for this duration [ms] before stopping. 0 = send once then stop immediately")};
44 }
45
46 bool setGoal(Goal & goal)
47 {
48 auto read_vector = [this](const char * key, std::vector<float> & out) -> bool {
49 BT::PortsRemapping::iterator it = config().input_ports.find(key);
50 if (it == config().input_ports.end() || it->second.empty()) {
51 return true; // optional port — leave empty
52 }
53 if (const BT::Expected<std::vector<float>> expected = getInput<std::vector<float>>(key)) {
54 out = expected.value();
55 } else {
56 RCLCPP_ERROR(
57 logger_, "%s - %s", context_.getFullyQualifiedTreeNodeName(this).c_str(), expected.error().c_str());
58 return false;
59 }
60 return true;
61 };
62
63 if (!read_vector(INPUT_KEY_MOTOR_COMMANDS, goal.motor_commands)) return false;
64 if (!read_vector(INPUT_KEY_SERVO_COMMANDS, goal.servo_commands)) return false;
65
66 if (const BT::Expected<uint32_t> expected = getInput<uint32_t>(INPUT_KEY_HOLD_PERIOD_MS)) {
67 goal.hold_period_ms = expected.value();
68 } else {
69 RCLCPP_ERROR(logger_, "%s - %s", context_.getFullyQualifiedTreeNodeName(this).c_str(), expected.error().c_str());
70 return false;
71 }
72
73 return true;
74 }
75};
76
77} // namespace auto_apms_px4
78
79AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(auto_apms_px4::SetActuatorsAction)
#define AUTO_APMS_BEHAVIOR_TREE_REGISTER_NODE(type)
Macro for registering a behavior tree node plugin.
Definition node.hpp:50
Implementation of PX4 mode peers offered by px4_ros2_cpp enabling integration with AutoAPMS.