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
153 virtual void onFailsafeDeferred() {}
154
160 void setSetpointUpdateRate(float rate_hz);
161
162 virtual void updateSetpoint(float dt_s) {}
163
169 void completed(Result result);
170
171 // Properties & state
172
173 ModeID id() const;
174
175 bool isArmed() const { return _is_armed; }
176
177 bool isActive() const { return _is_active; }
178
179 ConfigOverrides& configOverrides() { return _config_overrides; }
180
199 void deferFailsafes(bool enabled, int timeout_s = 0);
200
205 RequirementFlags& modeRequirements() { return _health_and_arming_checks.modeRequirements(); }
206
207 protected:
208 void setSkipMessageCompatibilityCheck() { _skip_message_compatibility_check = true; }
209 void setSkipSetpointCheck() { _skip_setpoint_check = true; }
210 void overrideRegistration(const std::shared_ptr<Registration>& registration);
211
212 void disableWatchdogTimer() { _health_and_arming_checks.disableWatchdogTimer(); }
213
214 void setWatchdogTimeoutCallback(HealthAndArmingChecks::WatchdogTimeoutCallback callback)
215 {
216 _health_and_arming_checks.setWatchdogTimeoutCallback(std::move(callback));
217 }
218
219 bool defaultMessageCompatibilityCheck();
220
221 private:
222 void addSetpointType(SetpointBase* setpoint) override;
223 void setRequirement(const RequirementFlags& requirement_flags) override;
224
225 friend class ModeExecutorBase;
226 RegistrationSettings getRegistrationSettings() const;
227 void onAboutToRegister();
228 bool onRegistered();
229
230 void unsubscribeVehicleStatus();
231 void vehicleStatusUpdated(const px4_msgs::msg::VehicleStatus::UniquePtr& msg,
232 bool do_not_activate = false);
233
234 void callOnActivate();
235 void callOnDeactivate();
236
237 void updateSetpointUpdateTimer();
238
239 void checkSetpointCompatibilityAndRequirements();
240 void setSetpointUpdateRateFromSetpointTypes();
241 void activateSetpointType(const std::shared_ptr<SetpointBase>& setpoint);
242 void deactivateAllSetpointTypes();
243
244 std::shared_ptr<Registration> _registration;
245
246 const Settings _settings;
247 bool _skip_message_compatibility_check{false};
248 bool _skip_setpoint_check{false};
249
250 HealthAndArmingChecks _health_and_arming_checks;
251
252 rclcpp::Publisher<px4_msgs::msg::ModeCompleted>::SharedPtr _mode_completed_pub;
253 rclcpp::Publisher<px4_msgs::msg::SetpointConfig>::SharedPtr _setpoint_config_pub;
254 SharedSubscriptionCallbackInstance _setpoint_config_reply_sub_cb;
255
256 SharedSubscriptionCallbackInstance _vehicle_status_sub_cb;
257
258 bool _is_active{false};
259 bool _is_armed{false};
260 bool _completed{false};
261
262 float _setpoint_update_rate_hz{0.f};
263 rclcpp::TimerBase::SharedPtr _setpoint_update_timer;
264 rclcpp::Time _last_setpoint_update{};
265
266 ConfigOverrides _config_overrides;
267 uint8_t _prev_failsafe_defer_state{px4_msgs::msg::VehicleStatus::FAILSAFE_DEFER_STATE_DISABLED};
268
269 std::vector<std::shared_ptr<SetpointBase>> _setpoint_types;
270 std::vector<SetpointBase*>
271 _new_setpoint_types;
272 std::shared_ptr<SetpointBase> _current_activating_setpoint;
273};
274
276} // namespace px4_ros2
Definition context.hpp:18
Definition health_and_arming_checks.hpp:21
void setWatchdogTimeoutCallback(WatchdogTimeoutCallback callback)
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:205
void setSetpointUpdateRate(float rate_hz)
uint8_t ModeID
Mode ID, corresponds to nav_state.
Definition mode.hpp:76
void deferFailsafes(bool enabled, int timeout_s=0)
virtual void onFailsafeDeferred()
Definition mode.hpp:153
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