PX4 ROS 2 Interface Library
Library to interface with PX4 from a companion computer using ROS 2
mode_executor.hpp
1 /****************************************************************************
2  * Copyright (c) 2023 PX4 Development Team.
3  * SPDX-License-Identifier: BSD-3-Clause
4  ****************************************************************************/
5 
6 #pragma once
7 
8 #include "mode.hpp"
9 #include "overrides.hpp"
10 
11 #include <rclcpp/rclcpp.hpp>
12 #include <px4_msgs/msg/vehicle_status.hpp>
13 #include <px4_msgs/msg/vehicle_command.hpp>
14 #include <px4_msgs/msg/vehicle_command_ack.hpp>
15 #include <px4_msgs/msg/mode_completed.hpp>
16 #include <px4_ros2/components/shared_subscription.hpp>
17 
18 #include <functional>
19 
20 class Registration;
21 
22 namespace px4_ros2
23 {
32 {
33 public:
34  using CompletedCallback = std::function<void (Result)>;
35 
36  struct Settings
37  {
38  enum class Activation
39  {
43  };
45 
46  Settings & activate(Activation activation_option)
47  {
48  activation = activation_option;
49  return *this;
50  }
51  };
52 
53  enum class DeactivateReason
54  {
55  FailsafeActivated,
56  Other
57  };
58 
59  ModeExecutorBase(const Settings & settings, ModeBase & owned_mode);
60  ModeExecutorBase(const ModeExecutorBase &) = delete;
61  virtual ~ModeExecutorBase();
62 
67  bool doRegister();
68 
69 
73  virtual void onActivate() = 0;
74 
78  virtual void onDeactivate(DeactivateReason reason) = 0;
79 
84  virtual void onFailsafeDeferred() {}
85 
89  // NOLINTNEXTLINE(google-default-arguments)
91  uint32_t command, float param1 = NAN, float param2 = NAN, float param3 = NAN,
92  float param4 = NAN,
93  float param5 = NAN, float param6 = NAN, float param7 = NAN);
94 
103  ModeBase::ModeID mode_id, const CompletedCallback & on_completed,
104  bool forced = false);
105 
112  void takeoff(const CompletedCallback & on_completed, float altitude = NAN, float heading = NAN);
113  void land(const CompletedCallback & on_completed);
114  void rtl(const CompletedCallback & on_completed);
115 
116  void arm(const CompletedCallback & on_completed, bool run_preflight_checks = true);
117  void disarm(const CompletedCallback & on_completed, bool forced = false);
118  void waitReadyToArm(const CompletedCallback & on_completed);
119  void waitUntilDisarmed(const CompletedCallback & on_completed);
120 
121  bool isInCharge() const {return _is_in_charge;}
122 
123  bool isArmed() const {return _is_armed;}
124 
125  ModeBase & ownedMode() {return _owned_mode;}
126 
127  int id() const;
128 
129  rclcpp::Node & node() {return _node;}
130 
131  ConfigOverrides & configOverrides() {return _config_overrides;}
132 
145  bool deferFailsafesSync(bool enabled, int timeout_s = 0);
146 
147  bool controlAutoSetHome(bool enabled);
148 
149 protected:
150  void setSkipMessageCompatibilityCheck() {_skip_message_compatibility_check = true;}
151  void overrideRegistration(const std::shared_ptr<Registration> & registration);
152 
153 private:
154  class ScheduledMode
155  {
156 public:
157  ScheduledMode(rclcpp::Node & node, const std::string & topic_namespace_prefix);
158 
159  bool active() const {return _mode_id != ModeBase::kModeIDInvalid;}
160  void activate(ModeBase::ModeID mode_id, const CompletedCallback & on_completed);
161  void cancel();
162  ModeBase::ModeID modeId() const {return _mode_id;}
163 
164 private:
165  void reset() {_mode_id = ModeBase::kModeIDInvalid;}
166 
167  ModeBase::ModeID _mode_id{ModeBase::kModeIDInvalid};
168  CompletedCallback _on_completed_callback;
169  rclcpp::Subscription<px4_msgs::msg::ModeCompleted>::SharedPtr _mode_completed_sub;
170  };
171 
172  class WaitForVehicleStatusCondition
173  {
174 public:
175  using RunCheckCallback =
176  std::function<bool (const px4_msgs::msg::VehicleStatus::UniquePtr & msg)>;
177  WaitForVehicleStatusCondition() = default;
178 
179  bool active() const {return _on_completed_callback != nullptr;}
180  void update(const px4_msgs::msg::VehicleStatus::UniquePtr & msg);
181 
182  void activate(
183  const RunCheckCallback & run_check_callback,
184  const CompletedCallback & on_completed);
185  void cancel();
186 
187 private:
188  CompletedCallback _on_completed_callback;
189  RunCheckCallback _run_check_callback;
190  };
191 
192  void onRegistered();
193 
194  void callOnActivate();
195  void callOnDeactivate(DeactivateReason reason);
196 
197  void vehicleStatusUpdated(const px4_msgs::msg::VehicleStatus::UniquePtr & msg);
198 
199  void scheduleMode(
200  ModeBase::ModeID mode_id, const px4_msgs::msg::VehicleCommand & cmd,
201  const ModeExecutorBase::CompletedCallback & on_completed, bool forced = false);
202 
203  rclcpp::Node & _node;
204  const std::string _topic_namespace_prefix;
205  const Settings _settings;
206  bool _skip_message_compatibility_check{false};
207  ModeBase & _owned_mode;
208 
209  std::shared_ptr<Registration> _registration;
210 
211  rclcpp::Publisher<px4_msgs::msg::VehicleCommand>::SharedPtr _vehicle_command_pub;
212 
213  SharedSubscriptionCallbackInstance _vehicle_status_sub_cb;
214 
215  ScheduledMode _current_scheduled_mode;
216  WaitForVehicleStatusCondition _current_wait_vehicle_status;
217 
218  bool _is_in_charge{false};
219  bool _is_armed{false};
220  bool _was_never_activated{true};
221  ModeBase::ModeID _prev_nav_state{ModeBase::kModeIDInvalid};
222  uint8_t _prev_failsafe_defer_state{px4_msgs::msg::VehicleStatus::FAILSAFE_DEFER_STATE_DISABLED};
223 
224  ConfigOverrides _config_overrides;
225 };
226 
228 } // namespace px4_ros2
uint8_t ModeID
Mode ID, corresponds to nav_state.
Definition: mode.hpp:73
Base class for a mode executor.
Definition: mode_executor.hpp:32
virtual Result sendCommandSync(uint32_t command, float param1=NAN, float param2=NAN, float param3=NAN, float param4=NAN, float param5=NAN, float param6=NAN, float param7=NAN)
virtual void onDeactivate(DeactivateReason reason)=0
bool deferFailsafesSync(bool enabled, int timeout_s=0)
void takeoff(const CompletedCallback &on_completed, float altitude=NAN, float heading=NAN)
Trigger a takeoff.
void scheduleMode(ModeBase::ModeID mode_id, const CompletedCallback &on_completed, bool forced=false)
virtual void onFailsafeDeferred()
Definition: mode_executor.hpp:84
virtual void onActivate()=0
Result
Definition: mode.hpp:31
Definition: mode_executor.hpp:37
Activation
Definition: mode_executor.hpp:39
@ ActivateAlways
Allow the executor to always be activated (so it can arm the vehicle)
@ ActivateOnlyWhenArmed
Only activate the executor when armed (and selected)
@ ActivateImmediately
Activate the mode and executor immediately after registration. Only use this for fully autonomous exe...