PX4 ROS 2 Interface Library
Library to interface with PX4 from a companion computer using ROS 2
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 
20 class Registration;
21 struct RegistrationSettings;
22 
23 namespace px4_ros2
24 {
29 enum class Result
30 {
31  Success = 0,
32  Rejected,
33  Interrupted,
34  Timeout,
35  Deactivated,
36 
37  // Mode-specific results
38  ModeFailureOther = 100,
39 };
40 
41 static_assert(
42  static_cast<int>(Result::ModeFailureOther) ==
43  static_cast<int>(px4_msgs::msg::ModeCompleted::RESULT_FAILURE_OTHER),
44  "definition mismatch");
45 
46 constexpr 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 
69 class ModeBase : public Context
70 {
71 public:
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
93  Settings(
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;
100  ModeID replace_internal_mode{kModeIDInvalid};
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 
113  bool doRegister();
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 
164 protected:
165  void setSkipMessageCompatibilityCheck() {_skip_message_compatibility_check = true;}
166  void overrideRegistration(const std::shared_ptr<Registration> & registration);
167 
168 private:
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