83 const uint8_t mode_id_;
84 bool deactivate_before_completion_;
85 rclcpp::Subscription<px4_msgs::msg::VehicleStatus>::SharedPtr vehicle_status_sub_ptr_;
86 rclcpp::Subscription<px4_msgs::msg::ModeCompleted>::SharedPtr mode_completed_sub_ptr_;
87 px4_msgs::msg::VehicleStatus::SharedPtr last_vehicle_status_ptr_;
88 bool mode_completed_{
false };
89 bool deactivation_command_sent_{
false };
90 State state_{ State::REQUEST_ACTIVATION };
93template <
class ActionT>
95 std::shared_ptr<ActionContextType> action_context_ptr, uint8_t mode_id,
96 bool deactivate_before_completion, std::chrono::milliseconds execution_interval,
97 std::chrono::milliseconds feedback_interval)
98 :
auto_apms_core::Task<ActionT>{ name, node_ptr, action_context_ptr, execution_interval, feedback_interval }
99 , vehicle_command_client_{ *node_ptr }
100 , mode_id_{ mode_id }
101 , deactivate_before_completion_{ deactivate_before_completion }
106template <
class ActionT>
108 bool deactivate_before_completion, std::chrono::milliseconds execution_interval,
109 std::chrono::milliseconds feedback_interval)
110 :
auto_apms_core::Task<ActionT>{ name, options, execution_interval, feedback_interval }
111 , vehicle_command_client_{ *this->node_ptr_ }
112 , mode_id_{ mode_id }
113 , deactivate_before_completion_{ deactivate_before_completion }
118template <
class ActionT>
120 bool deactivate_before_completion, std::chrono::milliseconds execution_interval,
121 std::chrono::milliseconds feedback_interval)
124 static_cast<uint8_t
>(flight_mode),
125 deactivate_before_completion,
131template <
class ActionT>
132void ModeExecutor<ActionT>::setUp()
134 vehicle_status_sub_ptr_ = this->node_ptr_->template create_subscription<px4_msgs::msg::VehicleStatus>(
135 "/fmu/out/vehicle_status", rclcpp::QoS(1).best_effort(),
136 [
this](px4_msgs::msg::VehicleStatus::UniquePtr msg) { last_vehicle_status_ptr_ = std::move(msg); });
138 mode_completed_sub_ptr_ = this->node_ptr_->template create_subscription<px4_msgs::msg::ModeCompleted>(
139 "/fmu/out/mode_completed", rclcpp::QoS(1).best_effort(), [
this](px4_msgs::msg::ModeCompleted::UniquePtr msg) {
140 if (msg->nav_state == mode_id_)
142 if (msg->result == px4_msgs::msg::ModeCompleted::RESULT_SUCCESS)
144 this->mode_completed_ =
true;
148 RCLCPP_ERROR(this->node_ptr_->get_logger(),
"Flight mode %i failed to execute. Aborting...",
150 this->action_context_ptr_->abort();
157template <
class ActionT>
163 bool is_holding = isCurrentNavState(
static_cast<uint8_t
>(FlightMode::Hold));
164 if (state_ == State::WAIT_FOR_ACTIVATION)
168 auto& clock = *this->node_ptr_->get_clock();
169 RCLCPP_DEBUG_THROTTLE(this->node_ptr_->get_logger(), clock, 200,
170 "Waiting for flight mode %i to become active before deactivating...", mode_id_);
171 return TaskStatus::RUNNING;
175 state_ = State::COMPLETE;
181 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
"Deactivated flight mode successfully (HOLD is active)");
182 return TaskStatus::SUCCESS;
187 if (!deactivation_command_sent_)
189 if (!vehicle_command_client_.SyncActivateFlightMode(FlightMode::Hold))
191 RCLCPP_ERROR(this->node_ptr_->get_logger(),
"Failed to send command to activate HOLD");
192 return TaskStatus::FAILURE;
195 last_vehicle_status_ptr_ =
nullptr;
196 deactivation_command_sent_ =
true;
200 return TaskStatus::RUNNING;
203template <
class ActionT>
204bool ModeExecutor<ActionT>::onGoalRequest(
const std::shared_ptr<const Goal> goal_ptr)
207 state_ = State::REQUEST_ACTIVATION;
208 deactivation_command_sent_ =
false;
209 mode_completed_ =
false;
213template <
class ActionT>
214bool ModeExecutor<ActionT>::onCancelRequest(std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Result> result_ptr)
218 if (deactivate_before_completion_)
221 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
222 "Cancelation requested! Will deactivate before termination (Enter HOLD)...");
226 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
"Cancelation requested!");
231template <
class ActionT>
233 std::shared_ptr<Result> result_ptr)
237 if (deactivate_before_completion_)
239 return asyncDeactivateFlightMode();
241 return TaskStatus::SUCCESS;
244template <
class ActionT>
247 if (last_vehicle_status_ptr_ && last_vehicle_status_ptr_->nav_state == nav_state)
254template <
class ActionT>
256 std::shared_ptr<Feedback> feedback_ptr,
257 std::shared_ptr<Result> result_ptr)
264 case State::REQUEST_ACTIVATION:
265 if (!sendActivationCommand(vehicle_command_client_, goal_ptr))
267 RCLCPP_ERROR(this->node_ptr_->get_logger(),
"Failed to send activation command for flight mode %i. Aborting...",
269 return TaskStatus::FAILURE;
272 last_vehicle_status_ptr_ =
nullptr;
273 state_ = State::WAIT_FOR_ACTIVATION;
275 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
"Activation command for flight mode %i was sent successfully",
277 return TaskStatus::RUNNING;
278 case State::WAIT_FOR_ACTIVATION:
279 if (isCurrentNavState(mode_id_))
281 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
"Flight mode %i is active", mode_id_);
282 state_ = State::WAIT_FOR_COMPLETION_SIGNAL;
284 return TaskStatus::RUNNING;
285 case State::WAIT_FOR_COMPLETION_SIGNAL:
287 setFeedback(feedback_ptr, *last_vehicle_status_ptr_);
290 if (isCompleted(goal_ptr, *last_vehicle_status_ptr_))
292 state_ = State::COMPLETE;
293 if (deactivate_before_completion_)
296 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
297 "Flight mode %i complete! Will deactivate before termination (Enter HOLD)...", mode_id_);
301 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
302 "Flight mode %i complete! Will leave current navigation state as is. User is "
303 "responsible for initiating the next flight mode...",
311 if (!isCurrentNavState(mode_id_))
313 RCLCPP_WARN(this->node_ptr_->get_logger(),
"Flight mode %i was deactivated externally. Aborting...", mode_id_);
314 return TaskStatus::FAILURE;
316 return TaskStatus::RUNNING;
317 case State::COMPLETE:
321 if (deactivate_before_completion_)
323 const auto deactivation_state = asyncDeactivateFlightMode();
324 if (deactivation_state != TaskStatus::SUCCESS)
326 return deactivation_state;
331 RCLCPP_DEBUG(this->node_ptr_->get_logger(),
"Flight mode %i execution termination", mode_id_);
332 return TaskStatus::SUCCESS;
335template <
class ActionT>
337 std::shared_ptr<const Goal> goal_ptr)
343template <
class ActionT>
345 const px4_msgs::msg::VehicleStatus& vehicle_status)
348 (void)vehicle_status;
349 return mode_completed_;
352template <
class ActionT>
354 const px4_msgs::msg::VehicleStatus& vehicle_status)
357 (void)vehicle_status;
361template <
class ActionT>