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 <functional>
9 #include <px4_msgs/msg/mode_completed.hpp>
10 #include <px4_msgs/msg/vehicle_command.hpp>
11 #include <px4_msgs/msg/vehicle_command_ack.hpp>
12 #include <px4_msgs/msg/vehicle_status.hpp>
13 #include <px4_ros2/components/shared_subscription.hpp>
14 #include <rclcpp/rclcpp.hpp>
15 
16 #include "mode.hpp"
17 #include "overrides.hpp"
18 
19 class Registration;
20 
21 namespace px4_ros2 {
30  public:
31  using CompletedCallback = std::function<void(Result)>;
32 
33  struct Settings {
34  enum class Activation {
39  };
41 
42  Settings& activate(Activation activation_option)
43  {
44  activation = activation_option;
45  return *this;
46  }
47  };
48 
49  enum class DeactivateReason { FailsafeActivated, Other };
50 
51  ModeExecutorBase(const Settings& settings, ModeBase& owned_mode);
52  ModeExecutorBase(const ModeExecutorBase&) = delete;
53  virtual ~ModeExecutorBase();
54 
59  bool doRegister();
60 
64  virtual void onActivate() = 0;
65 
69  virtual void onDeactivate(DeactivateReason reason) = 0;
70 
75  virtual void onFailsafeDeferred() {}
76 
80  // NOLINTNEXTLINE(google-default-arguments)
81  virtual Result sendCommandSync(uint32_t command, float param1 = NAN, float param2 = NAN,
82  float param3 = NAN, float param4 = NAN, float param5 = NAN,
83  float param6 = NAN, float param7 = NAN);
84 
93  void scheduleMode(ModeBase::ModeID mode_id, const CompletedCallback& on_completed,
94  bool forced = false);
95 
102  void takeoff(const CompletedCallback& on_completed, float altitude = NAN, float heading = NAN);
103  void land(const CompletedCallback& on_completed);
104  void rtl(const CompletedCallback& on_completed);
105 
106  void arm(const CompletedCallback& on_completed, bool run_preflight_checks = true);
107  void disarm(const CompletedCallback& on_completed, bool forced = false);
108  void waitReadyToArm(const CompletedCallback& on_completed);
109  void waitUntilDisarmed(const CompletedCallback& on_completed);
110 
111  bool isInCharge() const { return _is_in_charge; }
112 
113  bool isArmed() const { return _is_armed; }
114 
115  ModeBase& ownedMode() { return _owned_mode; }
116 
117  int id() const;
118 
119  rclcpp::Node& node() { return _node; }
120 
121  ConfigOverrides& configOverrides() { return _config_overrides; }
122 
136  bool deferFailsafesSync(bool enabled, int timeout_s = 0);
137 
138  bool controlAutoSetHome(bool enabled);
139 
140  protected:
141  void setSkipMessageCompatibilityCheck() { _skip_message_compatibility_check = true; }
142  void overrideRegistration(const std::shared_ptr<Registration>& registration);
143 
144  private:
145  class ScheduledMode {
146  public:
147  ScheduledMode(rclcpp::Node& node, const std::string& topic_namespace_prefix);
148 
149  bool active() const { return _mode_id != ModeBase::kModeIDInvalid; }
150  void activate(ModeBase::ModeID mode_id, const CompletedCallback& on_completed);
151  void cancel();
152  ModeBase::ModeID modeId() const { return _mode_id; }
153 
154  private:
155  void reset() { _mode_id = ModeBase::kModeIDInvalid; }
156 
157  ModeBase::ModeID _mode_id{ModeBase::kModeIDInvalid};
158  CompletedCallback _on_completed_callback;
159  rclcpp::Subscription<px4_msgs::msg::ModeCompleted>::SharedPtr _mode_completed_sub;
160  };
161 
162  class WaitForVehicleStatusCondition {
163  public:
164  using RunCheckCallback =
165  std::function<bool(const px4_msgs::msg::VehicleStatus::UniquePtr& msg)>;
166  WaitForVehicleStatusCondition() = default;
167 
168  bool active() const { return _on_completed_callback != nullptr; }
169  void update(const px4_msgs::msg::VehicleStatus::UniquePtr& msg);
170 
171  void activate(const RunCheckCallback& run_check_callback,
172  const CompletedCallback& on_completed);
173  void cancel();
174 
175  private:
176  CompletedCallback _on_completed_callback;
177  RunCheckCallback _run_check_callback;
178  };
179 
180  void onRegistered();
181 
182  void callOnActivate();
183  void callOnDeactivate(DeactivateReason reason);
184 
185  void vehicleStatusUpdated(const px4_msgs::msg::VehicleStatus::UniquePtr& msg);
186 
187  void scheduleMode(ModeBase::ModeID mode_id, const px4_msgs::msg::VehicleCommand& cmd,
188  const ModeExecutorBase::CompletedCallback& on_completed, bool forced = false);
189 
190  rclcpp::Node& _node;
191  const std::string _topic_namespace_prefix;
192  const Settings _settings;
193  bool _skip_message_compatibility_check{false};
194  ModeBase& _owned_mode;
195 
196  std::shared_ptr<Registration> _registration;
197 
198  rclcpp::Publisher<px4_msgs::msg::VehicleCommand>::SharedPtr _vehicle_command_pub;
199 
200  SharedSubscriptionCallbackInstance _vehicle_status_sub_cb;
201 
202  ScheduledMode _current_scheduled_mode;
203  WaitForVehicleStatusCondition _current_wait_vehicle_status;
204 
205  bool _is_in_charge{false};
206  bool _is_armed{false};
207  bool _was_never_activated{true};
208  ModeBase::ModeID _prev_nav_state{ModeBase::kModeIDInvalid};
209  uint8_t _prev_failsafe_defer_state{px4_msgs::msg::VehicleStatus::FAILSAFE_DEFER_STATE_DISABLED};
210 
211  ConfigOverrides _config_overrides;
212 };
213 
215 } // namespace px4_ros2
uint8_t ModeID
Mode ID, corresponds to nav_state.
Definition: mode.hpp:75
Base class for a mode executor.
Definition: mode_executor.hpp:29
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:75
virtual void onActivate()=0
Result
Definition: mode.hpp:29
Definition: mode_executor.hpp:33
Activation
Definition: mode_executor.hpp:34
@ ActivateAlways
Allow the executor to always be activated (so it can arm the vehicle)
@ ActivateOnlyWhenArmed
Only activate the executor when armed (and selected)