AutoAPMS
Resilient Robot Mission Management
Loading...
Searching...
No Matches
px4_takeoff_land.cpp
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// http://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#include "auto_apms_interfaces/action/land.hpp"
17#include "auto_apms_interfaces/action/takeoff.hpp"
18#include "auto_apms_util/action_client_wrapper.hpp"
19
20using namespace std::chrono_literals;
21using ArmDisarmAction = auto_apms_interfaces::action::ArmDisarm;
22using TakeoffAction = auto_apms_interfaces::action::Takeoff;
23using LandAction = auto_apms_interfaces::action::Land;
24
25int main(int argc, char * argv[])
26{
27 rclcpp::init(argc, argv);
28
29 // Create vehicle_command_client
30 auto node_ptr = std::make_shared<rclcpp::Node>(std::string(EXAMPLE_NAME) + "_node");
31
32 RCLCPP_INFO(node_ptr->get_logger(), "Running example '%s' ...", EXAMPLE_NAME);
33
34 auto arm_disarm_client = auto_apms_util::ActionClientWrapper<ArmDisarmAction>(node_ptr, "arm_disarm");
35 auto takeoff_client = auto_apms_util::ActionClientWrapper<TakeoffAction>(node_ptr, "takeoff");
36 auto land_client = auto_apms_util::ActionClientWrapper<LandAction>(node_ptr, "land");
37
38 RCLCPP_INFO(node_ptr->get_logger(), "Arming ...");
39
40 ArmDisarmAction::Goal arm_goal;
41 arm_goal.arming_state = arm_goal.ARMING_STATE_ARM;
42 auto arm_future = arm_disarm_client.syncSendGoal(arm_goal);
43
44 if (arm_future.wait_for(0s) == std::future_status::ready && !arm_future.get()) {
45 std::cerr << "Arming goal was rejected\n";
46 rclcpp::shutdown();
47 return EXIT_FAILURE;
48 }
49
50 while (rclcpp::spin_until_future_complete(node_ptr, arm_future, 1s) != rclcpp::FutureReturnCode::SUCCESS) {
51 RCLCPP_INFO(node_ptr->get_logger(), "Waiting for the vehicle to be armed");
52 if (!rclcpp::ok()) {
53 rclcpp::shutdown();
54 return EXIT_FAILURE;
55 }
56 }
57
58 auto arm_result = arm_future.get();
59
60 if (!arm_result) {
61 std::cerr << "Arm result is nullptr\n";
62 rclcpp::shutdown();
63 return EXIT_FAILURE;
64 }
65
66 if ((*arm_result).code == rclcpp_action::ResultCode::SUCCEEDED) {
67 RCLCPP_INFO(node_ptr->get_logger(), "Arming succeeded");
68 } else {
69 std::cerr << "Arming did not succeed\n";
70 rclcpp::shutdown();
71 return EXIT_FAILURE;
72 }
73
74 RCLCPP_INFO(node_ptr->get_logger(), "Taking off ...");
75
76 TakeoffAction::Goal takeoff_goal;
77 takeoff_goal.altitude_amsl_m = 1e9;
78 auto takeoff_future = takeoff_client.syncSendGoal(takeoff_goal);
79
80 if (takeoff_future.wait_for(0s) == std::future_status::ready && !takeoff_future.get()) {
81 std::cerr << "Takeoff goal was rejected\n";
82 rclcpp::shutdown();
83 return EXIT_FAILURE;
84 }
85
86 // Wait for a few seconds here before aborting the takeoff task
87 rclcpp::sleep_for(5s);
88
89 RCLCPP_INFO(node_ptr->get_logger(), "Canceling takeoff ...");
90
91 if (!takeoff_client.syncCancelLastGoal()) {
92 std::cerr << "Cancellation of takeoff was rejected\n";
93 rclcpp::shutdown();
94 return EXIT_FAILURE;
95 }
96
97 RCLCPP_INFO(node_ptr->get_logger(), "Landing ...");
98
99 auto land_future = land_client.syncSendGoal();
100
101 if (land_future.wait_for(0s) == std::future_status::ready && !land_future.get()) {
102 std::cerr << "Landing goal was rejected\n";
103 rclcpp::shutdown();
104 return EXIT_FAILURE;
105 }
106
107 while (rclcpp::spin_until_future_complete(node_ptr, land_future, 1s) != rclcpp::FutureReturnCode::SUCCESS) {
108 RCLCPP_INFO(node_ptr->get_logger(), "Waiting for landing");
109 if (!rclcpp::ok()) {
110 rclcpp::shutdown();
111 return EXIT_FAILURE;
112 }
113 }
114
115 auto land_result = land_future.get();
116
117 if (!land_result) {
118 std::cerr << "Land result is nullptr\n";
119 rclcpp::shutdown();
120 return EXIT_FAILURE;
121 }
122
123 if ((*land_result).code == rclcpp_action::ResultCode::SUCCEEDED) {
124 RCLCPP_INFO(node_ptr->get_logger(), "Landing succeeded");
125 } else {
126 std::cerr << "Landing did not succeed\n";
127 rclcpp::shutdown();
128 return EXIT_FAILURE;
129 }
130
131 rclcpp::shutdown();
132 return EXIT_SUCCESS;
133}
Convenience wrapper for a rclcpp_action::Client that introduces synchronous goal handling functions.