AutoAPMS
Resilient Robot Mission Management
Loading...
Searching...
No Matches
arm_disarm.cpp
Go to the documentation of this file.
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "auto_apms_interfaces/action/arm_disarm.hpp"
16
20#include "px4_msgs/msg/vehicle_status.hpp"
21
22namespace auto_apms_px4
23{
24
25class ArmDisarmTask : public auto_apms_core::Task<auto_apms_interfaces::action::ArmDisarm>
26{
27 enum State
28 {
29 WAIT_FOR_READY_TO_ARM,
30 SEND_COMMAND,
31 WAIT_FOR_ARMING_STATE_REACHED
32 };
33
34 rclcpp::Subscription<px4_msgs::msg::VehicleStatus>::SharedPtr vehicle_status_sub_ptr_;
35 State state_;
36 bool ready_to_arm_{ false };
37 bool is_armed_{ false };
38 std::function<bool()> is_arming_state_reached_check__;
39 std::function<bool()> send_command_callback_;
40 const VehicleCommandClient vehicle_command_client_;
41
42public:
43 explicit ArmDisarmTask(const rclcpp::NodeOptions& options)
44 : Task{ ARM_DISARM_TASK_NAME, options }, vehicle_command_client_{ *this->node_ptr_ }
45 {
46 vehicle_status_sub_ptr_ = this->node_ptr_->create_subscription<px4_msgs::msg::VehicleStatus>(
47 "/fmu/out/vehicle_status", rclcpp::QoS(1).best_effort(), [this](px4_msgs::msg::VehicleStatus::UniquePtr msg) {
48 is_armed_ = msg->arming_state == px4_msgs::msg::VehicleStatus::ARMING_STATE_ARMED;
49 ready_to_arm_ = msg->pre_flight_checks_pass;
50 });
51 }
52
53private:
54 bool onGoalRequest(std::shared_ptr<const Goal> goal_ptr) override final
55 {
56 // Reject goal if goal wants to arm, but UAV is not ready to arm and it is not requested to wait for ready to
57 // arm
58 if (goal_ptr->arming_state == Goal::ARMING_STATE_ARM && !goal_ptr->wait_until_ready_to_arm && !ready_to_arm_)
59 {
60 RCLCPP_ERROR(this->node_ptr_->get_logger(),
61 "UAV can currently not be armed and wait_until_ready_to_arm is false.");
62 return false;
63 }
64
65 if (goal_ptr->arming_state == Goal::ARMING_STATE_ARM)
66 {
67 // If goal is to arm
68 state_ = ready_to_arm_ ? SEND_COMMAND : WAIT_FOR_READY_TO_ARM;
69 is_arming_state_reached_check__ = [this]() { return is_armed_; };
70 send_command_callback_ = [this]() { return vehicle_command_client_.Arm(); };
71 }
72 else
73 {
74 // If goal is to disarm
75 state_ = SEND_COMMAND;
76 is_arming_state_reached_check__ = [this]() { return !is_armed_; };
77 send_command_callback_ = [this]() { return vehicle_command_client_.Disarm(); };
78 }
79
80 // Succeed directly if arming state is already reached
81 if ((goal_ptr->arming_state == Goal::ARMING_STATE_ARM && is_armed_) ||
82 (goal_ptr->arming_state == Goal::ARMING_STATE_DISARM && !is_armed_))
83 {
84 state_ = WAIT_FOR_ARMING_STATE_REACHED;
85 }
86
87 return true;
88 }
89
90 Status executeGoal(std::shared_ptr<const Goal> goal_ptr, std::shared_ptr<Feedback> feedback_ptr,
91 std::shared_ptr<Result> result_ptr) override final
92 {
93 (void)goal_ptr;
94 (void)feedback_ptr;
95
96 switch (state_)
97 {
98 case WAIT_FOR_READY_TO_ARM:
99 if (ready_to_arm_)
100 {
101 state_ = SEND_COMMAND;
102 }
103 break;
104 case SEND_COMMAND:
105 if (send_command_callback_())
106 {
107 state_ = WAIT_FOR_ARMING_STATE_REACHED;
108 }
109 else
110 {
111 RCLCPP_ERROR(this->node_ptr_->get_logger(), "Couldn't send arm/disarm command. Aborting...");
112 result_ptr->state_changed = false;
113 return Status::FAILURE;
114 }
115 break;
116 case WAIT_FOR_ARMING_STATE_REACHED:
117 if (is_arming_state_reached_check__())
118 {
119 result_ptr->state_changed = true;
120 return Status::SUCCESS;
121 }
122 break;
123 }
124
125 return Status::RUNNING;
126 }
127};
128
129} // namespace auto_apms_px4
130
131#include "rclcpp_components/register_node_macro.hpp"
132RCLCPP_COMPONENTS_REGISTER_NODE(auto_apms_px4::ArmDisarmTask)
Generic base class for robot actions.
Definition task.hpp:52
Task(const std::string &name, rclcpp::Node::SharedPtr node_ptr, std::shared_ptr< ActionContextType > action_context_ptr, std::chrono::milliseconds execution_interval=DEFAULT_VALUE_EXECUTION_INTERVAL, std::chrono::milliseconds feedback_interval=DEFAULT_VALUE_FEEDBACK_INTERVAL)
Definition task.hpp:117
const char ARM_DISARM_TASK_NAME[]
Definition constants.hpp:21