AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
send_cmd_do_reposition.cpp
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#include <cmath>
16#include <cstdint>
17
18#include "auto_apms_px4/node/send_vehicle_command.hpp"
19
20#define INPUT_KEY_LATITUDE "latitude"
21#define INPUT_KEY_LONGITUDE "longitude"
22#define INPUT_KEY_ALTITUDE "altitude"
23#define INPUT_KEY_YAW "yaw"
24#define INPUT_KEY_GROUND_SPEED "ground_speed"
25
26namespace auto_apms_px4
27{
28
45class SendCmdDoReposition : public SendVehicleCommand
46{
47public:
48 using SendVehicleCommand::SendVehicleCommand;
49
50 static BT::PortsList providedPorts()
51 {
52 return {
53 BT::InputPort<double>(INPUT_KEY_LATITUDE, "Target latitude [°] (WGS84)."),
54 BT::InputPort<double>(INPUT_KEY_LONGITUDE, "Target longitude [°] (WGS84)."),
55 BT::InputPort<double>(INPUT_KEY_ALTITUDE, "Target altitude [m] (AMSL)."),
56 BT::InputPort<double>(
57 INPUT_KEY_YAW, "Desired yaw [°] clockwise from north. Leave empty to keep the current heading mode."),
58 BT::InputPort<double>(INPUT_KEY_GROUND_SPEED, -1.0, "Ground speed [m/s]. Negative selects the PX4 default."),
59 };
60 }
61
62 bool setMessage(px4_msgs::msg::VehicleCommand & msg) override final
63 {
64 const BT::Expected<double> expected_lat = getInput<double>(INPUT_KEY_LATITUDE);
65 const BT::Expected<double> expected_lon = getInput<double>(INPUT_KEY_LONGITUDE);
66 const BT::Expected<double> expected_alt = getInput<double>(INPUT_KEY_ALTITUDE);
67 if (!expected_lat) {
68 RCLCPP_ERROR(
69 logger_, "%s - Missing required input '%s': %s", context_.getFullyQualifiedTreeNodeName(this).c_str(),
70 INPUT_KEY_LATITUDE, expected_lat.error().c_str());
71 return false;
72 }
73 if (!expected_lon) {
74 RCLCPP_ERROR(
75 logger_, "%s - Missing required input '%s': %s", context_.getFullyQualifiedTreeNodeName(this).c_str(),
76 INPUT_KEY_LONGITUDE, expected_lon.error().c_str());
77 return false;
78 }
79 if (!expected_alt) {
80 RCLCPP_ERROR(
81 logger_, "%s - Missing required input '%s': %s", context_.getFullyQualifiedTreeNodeName(this).c_str(),
82 INPUT_KEY_ALTITUDE, expected_alt.error().c_str());
83 return false;
84 }
85
86 msg = px4_msgs::msg::VehicleCommand{};
87 msg.command = px4_msgs::msg::VehicleCommand::VEHICLE_CMD_DO_REPOSITION;
88 msg.param1 = static_cast<float>(getInput<double>(INPUT_KEY_GROUND_SPEED).value_or(-1.0)); // Ground speed [m/s].
89 msg.param2 = 1.0f; // MAV_DO_REPOSITION_FLAGS: bit 0 set -> switch to (guided) Reposition mode.
90 msg.param3 = 0.0f; // Loiter radius (planes only), unused for multicopters.
91
92 // Yaw is optional: an empty port leaves the heading unchanged (NaN tells PX4 to keep its current yaw mode).
93 const BT::Expected<double> expected_yaw = getInput<double>(INPUT_KEY_YAW);
94 msg.param4 = expected_yaw ? static_cast<float>(expected_yaw.value()) : std::numeric_limits<float>::quiet_NaN();
95
96 msg.param5 = expected_lat.value(); // Latitude [°] (float64, full precision).
97 msg.param6 = expected_lon.value(); // Longitude [°] (float64, full precision).
98 msg.param7 = static_cast<float>(expected_alt.value()); // Altitude [m] (AMSL).
99 msg.source_component = resolveSourceComponent();
100 msg.from_external = true;
101 msg.timestamp = 0; // Let PX4 set the timestamp.
102
103 RCLCPP_DEBUG(
104 logger_, "%s - Repositioning to (%.7f, %.7f, %.2f) (source_component %u).",
105 context_.getFullyQualifiedTreeNodeName(this).c_str(), msg.param5, msg.param6, static_cast<double>(msg.param7),
106 msg.source_component);
107 return true;
108 }
109};
110
111} // namespace auto_apms_px4
112
Behavior tree node that commands the vehicle to reposition to a global WGS84 location.
uint16_t resolveSourceComponent()
Transitively resolve the in-charge mode executor's source component from the global blackboard.
#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.