diff --git a/test/mavsdk_tests/CMakeLists.txt b/test/mavsdk_tests/CMakeLists.txt index 98a52eaafd..230df43026 100644 --- a/test/mavsdk_tests/CMakeLists.txt +++ b/test/mavsdk_tests/CMakeLists.txt @@ -27,6 +27,7 @@ if(MAVSDK_FOUND) MAVSDK::mavsdk_info MAVSDK::mavsdk_manual_control MAVSDK::mavsdk_mission + MAVSDK::mavsdk_mission_raw MAVSDK::mavsdk_offboard MAVSDK::mavsdk_param MAVSDK::mavsdk_telemetry diff --git a/test/mavsdk_tests/autopilot_tester.cpp b/test/mavsdk_tests/autopilot_tester.cpp index 6e57fb2adb..82b6a27d27 100644 --- a/test/mavsdk_tests/autopilot_tester.cpp +++ b/test/mavsdk_tests/autopilot_tester.cpp @@ -36,6 +36,7 @@ #include #include #include +#include std::string connection_url {"udp://"}; std::optional speed_factor {std::nullopt}; @@ -70,6 +71,7 @@ void AutopilotTester::connect(const std::string uri) _info.reset(new Info(system)); _manual_control.reset(new ManualControl(system)); _mission.reset(new Mission(system)); + _mission_raw.reset(new MissionRaw(system)); _offboard.reset(new Offboard(system)); _param.reset(new Param(system)); _telemetry.reset(new Telemetry(system)); @@ -219,10 +221,7 @@ void AutopilotTester::execute_mission() std::promise prom; auto fut = prom.get_future(); - _mission->start_mission_async([&prom](Mission::Result result) { - REQUIRE(Mission::Result::Success == result); - prom.set_value(); - }); + REQUIRE(_mission->start_mission() == Mission::Result::Success); // TODO: Adapt time limit based on mission size, flight speed, sim speed factor, etc. @@ -327,6 +326,26 @@ Mission::MissionItem AutopilotTester::create_mission_item( return mission_item; } +void AutopilotTester::load_qgc_mission_raw(const std::string &plan_file) +{ + const auto import_result = _mission_raw->import_qgroundcontrol_mission(plan_file); + REQUIRE(import_result.first == MissionRaw::Result::Success); + + REQUIRE(_mission_raw->upload_mission(import_result.second.mission_items) == MissionRaw::Result::Success); +} + +void AutopilotTester::execute_mission_raw() +{ + std::promise prom; + auto fut = prom.get_future(); + + REQUIRE(_mission->start_mission() == Mission::Result::Success); + + // TODO: Adapt time limit based on mission size, flight speed, sim speed factor, etc. + + wait_for_mission_raw_finished(std::chrono::seconds(60)); +} + void AutopilotTester::execute_rtl() { REQUIRE(Action::Result::Success == _action->return_to_launch()); @@ -620,6 +639,21 @@ void AutopilotTester::wait_for_mission_finished(std::chrono::seconds timeout) REQUIRE(fut.wait_for(timeout) == std::future_status::ready); } +void AutopilotTester::wait_for_mission_raw_finished(std::chrono::seconds timeout) +{ + auto prom = std::promise {}; + auto fut = prom.get_future(); + + _mission_raw->subscribe_mission_progress([&prom, this](MissionRaw::MissionProgress progress) { + if (progress.current == progress.total) { + _mission_raw->subscribe_mission_progress(nullptr); + prom.set_value(); + } + }); + + REQUIRE(fut.wait_for(timeout) == std::future_status::ready); +} + void AutopilotTester::report_speed_factor() { // We check the exit flag more often than the speed factor. diff --git a/test/mavsdk_tests/autopilot_tester.h b/test/mavsdk_tests/autopilot_tester.h index 65aa0e7ef2..2f5d1a8832 100644 --- a/test/mavsdk_tests/autopilot_tester.h +++ b/test/mavsdk_tests/autopilot_tester.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,8 @@ public: void execute_mission_and_get_mag_stuck(); void execute_mission_and_lose_baro(); void execute_mission_and_get_baro_stuck(); + void load_qgc_mission_raw(const std::string &plan_file); + void execute_mission_raw(); void execute_rtl(); void offboard_goto(const Offboard::PositionNedYaw &target, float acceptance_radius_m = 0.3f, std::chrono::seconds timeout_duration = std::chrono::seconds(60)); @@ -136,6 +139,7 @@ private: void wait_for_flight_mode(Telemetry::FlightMode flight_mode, std::chrono::seconds timeout); void wait_for_landed_state(Telemetry::LandedState landed_state, std::chrono::seconds timeout); void wait_for_mission_finished(std::chrono::seconds timeout); + void wait_for_mission_raw_finished(std::chrono::seconds timeout); void report_speed_factor(); @@ -219,6 +223,7 @@ private: std::unique_ptr _info{}; std::unique_ptr _manual_control{}; std::unique_ptr _mission{}; + std::unique_ptr _mission_raw{}; std::unique_ptr _offboard{}; std::unique_ptr _param{}; std::unique_ptr _telemetry{}; diff --git a/test/mavsdk_tests/configs/sitl.json b/test/mavsdk_tests/configs/sitl.json index 4ce89401fc..50b7eeadbc 100644 --- a/test/mavsdk_tests/configs/sitl.json +++ b/test/mavsdk_tests/configs/sitl.json @@ -13,13 +13,13 @@ { "model": "standard_vtol", "vehicle": "standard_vtol", - "test_filter": "[multicopter][vtol]", + "test_filter": "[vtol]", "timeout_min": 10 }, { "model": "tailsitter", "vehicle": "tailsitter", - "test_filter": "[multicopter][vtol]", + "test_filter": "[vtol]", "timeout_min": 10 } ] diff --git a/test/mavsdk_tests/test_vtol_mission.cpp b/test/mavsdk_tests/test_vtol_mission.cpp index 30838f9ae4..53a15ceb17 100644 --- a/test/mavsdk_tests/test_vtol_mission.cpp +++ b/test/mavsdk_tests/test_vtol_mission.cpp @@ -34,15 +34,13 @@ #include "autopilot_tester.h" -TEST_CASE("Takeoff and transition and RTL", "[vtol]") +TEST_CASE("Fly VTOL mission", "[vtol]") { AutopilotTester tester; tester.connect(connection_url); + tester.load_qgc_mission_raw("test/mavsdk_tests/vtol_mission_allmend.plan"); tester.wait_until_ready(); tester.arm(); - tester.takeoff(); - tester.wait_until_hovering(); - tester.transition_to_fixedwing(); - tester.execute_rtl(); + tester.execute_mission_raw(); tester.wait_until_disarmed(); } diff --git a/test/mavsdk_tests/vtol_mission_allmend.plan b/test/mavsdk_tests/vtol_mission_allmend.plan new file mode 100644 index 0000000000..7bede674b0 --- /dev/null +++ b/test/mavsdk_tests/vtol_mission_allmend.plan @@ -0,0 +1,203 @@ +{ + "fileType": "Plan", + "geoFence": { + "circles": [ + ], + "polygons": [ + ], + "version": 2 + }, + "groundStation": "QGroundControl", + "mission": { + "cruiseSpeed": 15, + "firmwareType": 12, + "globalPlanAltitudeMode": 1, + "hoverSpeed": 5, + "items": [ + { + "AMSLAltAboveTerrain": null, + "Altitude": 20, + "AltitudeMode": 1, + "autoContinue": true, + "command": 84, + "doJumpId": 1, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35575503646861, + 8.52080660767436, + 20 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 20, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 2, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35537212, + 8.52207767, + 20 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 30, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 3, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35349688, + 8.52355825, + 30 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 30, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 4, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.3528936, + 8.52294671, + 30 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 30, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 5, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35230484, + 8.52030742, + 30 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 30, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 6, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35294448, + 8.51882684, + 30 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 30, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 7, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35375855, + 8.52002847, + 30 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 20, + "AltitudeMode": 1, + "autoContinue": true, + "command": 16, + "doJumpId": 8, + "frame": 3, + "params": [ + 0, + 0, + 0, + null, + 47.35552475934091, + 8.51881610700002, + 20 + ], + "type": "SimpleItem" + }, + { + "AMSLAltAboveTerrain": null, + "Altitude": 0, + "AltitudeMode": 1, + "autoContinue": true, + "command": 85, + "doJumpId": 9, + "frame": 3, + "params": [ + 0, + 0, + 20, + null, + 47.3557210047974, + 8.518762469830165, + 0 + ], + "type": "SimpleItem" + } + ], + "plannedHomePosition": [ + 47.3557317, + 8.5187574, + 419.8934400000014 + ], + "vehicleType": 20, + "version": 2 + }, + "rallyPoints": { + "points": [ + ], + "version": 2 + }, + "version": 1 +}