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#include <px4_msgs/msg/mode_completed.hpp>
10#include <px4_msgs/msg/setpoint_config.hpp>
11#include <px4_msgs/msg/setpoint_config_reply.hpp>
12#include <px4_msgs/msg/vehicle_status.hpp>
13#include <px4_ros2/common/context.hpp>
14#include <px4_ros2/common/setpoint_base.hpp>
15#include <px4_ros2/components/shared_subscription.hpp>
16#include <rclcpp/rclcpp.hpp>
17
18#include "health_and_arming_checks.hpp"
19#include "manual_control_input.hpp"
20#include "overrides.hpp"
21
22class Registration;
23struct RegistrationSettings;
24
25namespace px4_ros2 {
30enum class Result {
31 Success = 0,
32 Rejected,
34 Timeout,
36
37 // Mode-specific results
38 ModeFailureOther = 100,
39};
40
41static_assert(static_cast<int>(Result::ModeFailureOther) ==
42 static_cast<int>(px4_msgs::msg::ModeCompleted::RESULT_FAILURE_OTHER),
43 "definition mismatch");
44
45constexpr inline const char* resultToString(Result result) noexcept
46{
47 switch (result) {
48 case Result::Success:
49 return "Success";
50
52 return "Rejected";
53
55 return "Interrupted";
56
57 case Result::Timeout:
58 return "Timeout";
59
61 return "Deactivated";
62
63 case Result::ModeFailureOther:
64 return "Mode Failure (generic)";
65 }
66
67 return "Unknown";
68}
69
74class ModeBase : public Context {
75 public:
76 using ModeID = uint8_t;
77 static constexpr ModeID kModeIDInvalid = 0xff;
78
79 static constexpr ModeID kModeIDPosctl = px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_POSCTL;
80 static constexpr ModeID kModeIDTakeoff =
81 px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_TAKEOFF;
82 static constexpr ModeID kModeIDDescend = px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_DESCEND;
83 static constexpr ModeID kModeIDLand = px4_msgs::msg::VehicleStatus::NAVIGATION_STATE_AUTO_LAND;
84 static constexpr ModeID kModeIDRtl = 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 // NOLINTNEXTLINE allow implicit conversion
92 Settings(std::string mode_name) : name(std::move(mode_name)) {}
93
94 const std::string name;
97 ModeID replace_internal_mode{kModeIDInvalid};
98 bool prevent_arming{false};
99 bool user_selectable{true};
100
101 Settings& activateEvenWhileDisarmed(bool activate)
102 {
104 return *this;
105 }
106 Settings& replaceInternalMode(ModeID mode)
107 {
109 return *this;
110 }
111 Settings& preventArming(bool prevent)
112 {
113 prevent_arming = prevent;
114 return *this;
115 }
116 Settings& userSelectable(bool selectable)
117 {
118 user_selectable = selectable;
119 return *this;
120 }
121 };
122
123 ModeBase(rclcpp::Node& node, Settings settings, const std::string& topic_namespace_prefix = "");
124 ModeBase(const ModeBase&) = delete;
125 virtual ~ModeBase();
126
133
138
142 virtual void onActivate() {}
143
147 virtual void onDeactivate() {}
148
154 void setSetpointUpdateRate(float rate_hz);
155
156 virtual void updateSetpoint(float dt_s) {}
157
163 void completed(Result result);
164
165 // Properties & state
166
167 ModeID id() const;
168
169 bool isArmed() const { return _is_armed; }
170
171 bool isActive() const { return _is_active; }
172
173 ConfigOverrides& configOverrides() { return _config_overrides; }
174
179 RequirementFlags& modeRequirements() { return _health_and_arming_checks.modeRequirements(); }
180
181 protected:
182 void setSkipMessageCompatibilityCheck() { _skip_message_compatibility_check = true; }
183 void setSkipSetpointCheck() { _skip_setpoint_check = true; }
184 void overrideRegistration(const std::shared_ptr<Registration>& registration);
185
186 void disableWatchdogTimer() { _health_and_arming_checks.disableWatchdogTimer(); }
187
188 bool defaultMessageCompatibilityCheck();
189
190 private:
191 void addSetpointType(SetpointBase* setpoint) override;
192 void setRequirement(const RequirementFlags& requirement_flags) override;
193
194 friend class ModeExecutorBase;
195 RegistrationSettings getRegistrationSettings() const;
196 void onAboutToRegister();
197 bool onRegistered();
198
199 void unsubscribeVehicleStatus();
200 void vehicleStatusUpdated(const px4_msgs::msg::VehicleStatus::UniquePtr& msg,
201 bool do_not_activate = false);
202
203 void callOnActivate();
204 void callOnDeactivate();
205
206 void updateSetpointUpdateTimer();
207
208 void checkSetpointCompatibilityAndRequirements();
209 void setSetpointUpdateRateFromSetpointTypes();
210 void activateSetpointType(const std::shared_ptr<SetpointBase>& setpoint);
211 void deactivateAllSetpointTypes();
212
213 std::shared_ptr<Registration> _registration;
214
215 const Settings _settings;
216 bool _skip_message_compatibility_check{false};
217 bool _skip_setpoint_check{false};
218
219 HealthAndArmingChecks _health_and_arming_checks;
220
221 rclcpp::Publisher<px4_msgs::msg::ModeCompleted>::SharedPtr _mode_completed_pub;
222 rclcpp::Publisher<px4_msgs::msg::SetpointConfig>::SharedPtr _setpoint_config_pub;
223 SharedSubscriptionCallbackInstance _setpoint_config_reply_sub_cb;
224
225 SharedSubscriptionCallbackInstance _vehicle_status_sub_cb;
226
227 bool _is_active{false};
228 bool _is_armed{false};
229 bool _completed{false};
230
231 float _setpoint_update_rate_hz{0.f};
232 rclcpp::TimerBase::SharedPtr _setpoint_update_timer;
233 rclcpp::Time _last_setpoint_update{};
234
235 ConfigOverrides _config_overrides;
236
237 std::vector<std::shared_ptr<SetpointBase>> _setpoint_types;
238 std::vector<SetpointBase*>
239 _new_setpoint_types;
240 std::shared_ptr<SetpointBase> _current_activating_setpoint;
241};
242
244} // namespace px4_ros2
Definition context.hpp:18
Definition health_and_arming_checks.hpp:21
Base class for a mode.
Definition mode.hpp:74
virtual void checkArmingAndRunConditions(HealthAndArmingCheckReporter &reporter)
Definition mode.hpp:137
virtual void onDeactivate()
Definition mode.hpp:147
RequirementFlags & modeRequirements()
Definition mode.hpp:179
void setSetpointUpdateRate(float rate_hz)
uint8_t ModeID
Mode ID, corresponds to nav_state.
Definition mode.hpp:76
virtual void onActivate()
Definition mode.hpp:142
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:90
bool user_selectable
If true, the mode is selectable by the user.
Definition mode.hpp:99
bool activate_even_while_disarmed
If true, the mode is also activated while disarmed if selected.
Definition mode.hpp:95
const std::string name
Name of the mode with length < 25 characters.
Definition mode.hpp:94
bool prevent_arming
Prevent arming while in this mode.
Definition mode.hpp:98
ModeID replace_internal_mode
Can be used to replace an fmu-internal mode.
Definition mode.hpp:97
Requirement flags used by modes.
Definition requirement_flags.hpp:15