PX4 ROS 2 Interface Library
Library to interface with PX4 from a companion computer using ROS 2
Loading...
Searching...
No Matches
mode.hpp
1/****************************************************************************
2 * Copyright (c) 2023 PX4 Development Team.
3 * SPDX-License-Identifier: BSD-3-Clause
4 ****************************************************************************/
5
6#pragma once
7
8#include <cstdint>
9
10#include <rclcpp/rclcpp.hpp>
11#include <px4_msgs/msg/mode_completed.hpp>
12#include <px4_msgs/msg/vehicle_control_mode.hpp>
13#include <px4_msgs/msg/vehicle_status.hpp>
14#include "health_and_arming_checks.hpp"
15#include "overrides.hpp"
16#include "manual_control_input.hpp"
17#include <px4_ros2/common/setpoint_base.hpp>
18#include <px4_ros2/common/context.hpp>
19
20class Registration;
21struct RegistrationSettings;
22
23namespace px4_ros2
24{
29enum class Result
30{
31 Success = 0,
32 Rejected,
34 Timeout,
36
37 // Mode-specific results
38 ModeFailureOther = 100,
39};
40
41static_assert(
42 static_cast<int>(Result::ModeFailureOther) ==
43 static_cast<int>(px4_msgs::msg::ModeCompleted::RESULT_FAILURE_OTHER),
44 "definition mismatch");
45
46constexpr inline const char * resultToString(Result result) noexcept
47{
48 switch (result) {
49 case Result::Success: return "Success";
50
51 case Result::Rejected: return "Rejected";
52
53 case Result::Interrupted: return "Interrupted";
54
55 case Result::Timeout: return "Timeout";
56
57 case Result::Deactivated: return "Deactivated";
58
59 case Result::ModeFailureOther: return "Mode Failure (generic)";
60 }
61
62 return "Unknown";
63}
64
69class ModeBase : public Context
70{
71public:
72 using ModeID = uint8_t;
73 static constexpr ModeID kModeIDInvalid = 0xff;
74
75 static constexpr ModeID kModeIDPosctl =
76 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_POSCTL;
77 static constexpr ModeID kModeIDTakeoff =
78 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_TAKEOFF;
79 static constexpr ModeID kModeIDDescend =
80 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_DESCEND;
81 static constexpr ModeID kModeIDLand =
82 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_LAND;
83 static constexpr ModeID kModeIDRtl =
84 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_RTL;
85 static constexpr ModeID kModeIDPrecisionLand =
86 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_PRECLAND;
87 static constexpr ModeID kModeIDLoiter =
88 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_LOITER;
89
90 struct Settings
91 {
92 // NOLINTNEXTLINE allow implicit conversion
94 std::string mode_name, bool want_activate_even_while_disarmed = false,
95 ModeID request_replace_internal_mode = kModeIDInvalid)
96 : name(std::move(mode_name)), activate_even_while_disarmed(want_activate_even_while_disarmed),
97 replace_internal_mode(request_replace_internal_mode) {}
98 std::string name;
101 };
102
103 ModeBase(
104 rclcpp::Node & node, Settings settings,
105 const std::string & topic_namespace_prefix = "");
106 ModeBase(const ModeBase &) = delete;
107 virtual ~ModeBase() = default;
108
114
115
120
124 virtual void onActivate() = 0;
125
129 virtual void onDeactivate() = 0;
130
136 void setSetpointUpdateRate(float rate_hz);
137
138 virtual void updateSetpoint(float dt_s) {}
139
145 void completed(Result result);
146
147
148 // Properties & state
149
150 ModeID id() const;
151
152 bool isArmed() const {return _is_armed;}
153
154 bool isActive() const {return _is_active;}
155
156 ConfigOverrides & configOverrides() {return _config_overrides;}
157
162 RequirementFlags & modeRequirements() {return _health_and_arming_checks.modeRequirements();}
163
164protected:
165 void setSkipMessageCompatibilityCheck() {_skip_message_compatibility_check = true;}
166 void overrideRegistration(const std::shared_ptr<Registration> & registration);
167
168private:
169 void addSetpointType(SetpointBase * setpoint) override;
170 void setRequirement(const RequirementFlags & requirement_flags) override;
171
172 friend class ModeExecutorBase;
173 RegistrationSettings getRegistrationSettings() const;
174 void onAboutToRegister();
175 bool onRegistered();
176
177 void unsubscribeVehicleStatus();
178 void vehicleStatusUpdated(
179 const px4_msgs::msg::VehicleStatus::UniquePtr & msg,
180 bool do_not_activate = false);
181
182 void callOnActivate();
183 void callOnDeactivate();
184
185 void updateSetpointUpdateTimer();
186
187 void updateModeRequirementsFromSetpoints();
188 void setSetpointUpdateRateFromSetpointTypes();
189 void activateSetpointType(SetpointBase & setpoint);
190
191 std::shared_ptr<Registration> _registration;
192
193 const Settings _settings;
194 bool _skip_message_compatibility_check{false};
195
196 HealthAndArmingChecks _health_and_arming_checks;
197
198 rclcpp::Subscription<px4_msgs::msg::VehicleStatus>::SharedPtr _vehicle_status_sub;
199 rclcpp::Publisher<px4_msgs::msg::ModeCompleted>::SharedPtr _mode_completed_pub;
200 rclcpp::Publisher<px4_msgs::msg::VehicleControlMode>::SharedPtr _config_control_setpoints_pub;
201
202 bool _is_active{false};
203 bool _is_armed{false};
204 bool _completed{false};
205
206 float _setpoint_update_rate_hz{0.f};
207 rclcpp::TimerBase::SharedPtr _setpoint_update_timer;
208 rclcpp::Time _last_setpoint_update{};
209
210 ConfigOverrides _config_overrides;
211
212 std::vector<std::shared_ptr<SetpointBase>> _setpoint_types;
213 std::vector<SetpointBase *> _new_setpoint_types;
214};
215
217} // namespace px4_ros2
Definition context.hpp:20
Definition health_and_arming_checks.hpp:24
Base class for a mode.
Definition mode.hpp:70
virtual void checkArmingAndRunConditions(HealthAndArmingCheckReporter &reporter)
Definition mode.hpp:119
RequirementFlags & modeRequirements()
Definition mode.hpp:162
void setSetpointUpdateRate(float rate_hz)
uint8_t ModeID
Mode ID, corresponds to nav_state.
Definition mode.hpp:72
virtual void onDeactivate()=0
virtual void onActivate()=0
void completed(Result result)
Result
Definition mode.hpp:30
@ Interrupted
Ctrl-C or another error (from ROS)
@ Deactivated
Mode or executor got deactivated.
@ Rejected
The request was rejected.
Definition mode.hpp:91
std::string name
Name of the mode with length < 25 characters.
Definition mode.hpp:98
bool activate_even_while_disarmed
If true, the mode is also activated while disarmed if selected.
Definition mode.hpp:99
ModeID replace_internal_mode
Can be used to replace an fmu-internal mode.
Definition mode.hpp:100
Requirement flags used by modes.
Definition requirement_flags.hpp:17