mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-01 02:55:07 +08:00
mavsdk_tests: add VTOL mission tests
This adds VTOL mission tests to the CI integration tests. This depends on MAVSDK v0.38.0.
This commit is contained in:
@@ -27,6 +27,7 @@ if(MAVSDK_FOUND)
|
|||||||
MAVSDK::mavsdk_info
|
MAVSDK::mavsdk_info
|
||||||
MAVSDK::mavsdk_manual_control
|
MAVSDK::mavsdk_manual_control
|
||||||
MAVSDK::mavsdk_mission
|
MAVSDK::mavsdk_mission
|
||||||
|
MAVSDK::mavsdk_mission_raw
|
||||||
MAVSDK::mavsdk_offboard
|
MAVSDK::mavsdk_offboard
|
||||||
MAVSDK::mavsdk_param
|
MAVSDK::mavsdk_param
|
||||||
MAVSDK::mavsdk_telemetry
|
MAVSDK::mavsdk_telemetry
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
std::string connection_url {"udp://"};
|
std::string connection_url {"udp://"};
|
||||||
std::optional<float> speed_factor {std::nullopt};
|
std::optional<float> speed_factor {std::nullopt};
|
||||||
@@ -70,6 +71,7 @@ void AutopilotTester::connect(const std::string uri)
|
|||||||
_info.reset(new Info(system));
|
_info.reset(new Info(system));
|
||||||
_manual_control.reset(new ManualControl(system));
|
_manual_control.reset(new ManualControl(system));
|
||||||
_mission.reset(new Mission(system));
|
_mission.reset(new Mission(system));
|
||||||
|
_mission_raw.reset(new MissionRaw(system));
|
||||||
_offboard.reset(new Offboard(system));
|
_offboard.reset(new Offboard(system));
|
||||||
_param.reset(new Param(system));
|
_param.reset(new Param(system));
|
||||||
_telemetry.reset(new Telemetry(system));
|
_telemetry.reset(new Telemetry(system));
|
||||||
@@ -219,10 +221,7 @@ void AutopilotTester::execute_mission()
|
|||||||
std::promise<void> prom;
|
std::promise<void> prom;
|
||||||
auto fut = prom.get_future();
|
auto fut = prom.get_future();
|
||||||
|
|
||||||
_mission->start_mission_async([&prom](Mission::Result result) {
|
REQUIRE(_mission->start_mission() == Mission::Result::Success);
|
||||||
REQUIRE(Mission::Result::Success == result);
|
|
||||||
prom.set_value();
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Adapt time limit based on mission size, flight speed, sim speed factor, etc.
|
// 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;
|
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<void> 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()
|
void AutopilotTester::execute_rtl()
|
||||||
{
|
{
|
||||||
REQUIRE(Action::Result::Success == _action->return_to_launch());
|
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);
|
REQUIRE(fut.wait_for(timeout) == std::future_status::ready);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutopilotTester::wait_for_mission_raw_finished(std::chrono::seconds timeout)
|
||||||
|
{
|
||||||
|
auto prom = std::promise<void> {};
|
||||||
|
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()
|
void AutopilotTester::report_speed_factor()
|
||||||
{
|
{
|
||||||
// We check the exit flag more often than the speed factor.
|
// We check the exit flag more often than the speed factor.
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <mavsdk/plugins/info/info.h>
|
#include <mavsdk/plugins/info/info.h>
|
||||||
#include <mavsdk/plugins/manual_control/manual_control.h>
|
#include <mavsdk/plugins/manual_control/manual_control.h>
|
||||||
#include <mavsdk/plugins/mission/mission.h>
|
#include <mavsdk/plugins/mission/mission.h>
|
||||||
|
#include <mavsdk/plugins/mission_raw/mission_raw.h>
|
||||||
#include <mavsdk/plugins/offboard/offboard.h>
|
#include <mavsdk/plugins/offboard/offboard.h>
|
||||||
#include <mavsdk/plugins/telemetry/telemetry.h>
|
#include <mavsdk/plugins/telemetry/telemetry.h>
|
||||||
#include <mavsdk/plugins/param/param.h>
|
#include <mavsdk/plugins/param/param.h>
|
||||||
@@ -110,6 +111,8 @@ public:
|
|||||||
void execute_mission_and_get_mag_stuck();
|
void execute_mission_and_get_mag_stuck();
|
||||||
void execute_mission_and_lose_baro();
|
void execute_mission_and_lose_baro();
|
||||||
void execute_mission_and_get_baro_stuck();
|
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 execute_rtl();
|
||||||
void offboard_goto(const Offboard::PositionNedYaw &target, float acceptance_radius_m = 0.3f,
|
void offboard_goto(const Offboard::PositionNedYaw &target, float acceptance_radius_m = 0.3f,
|
||||||
std::chrono::seconds timeout_duration = std::chrono::seconds(60));
|
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_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_landed_state(Telemetry::LandedState landed_state, std::chrono::seconds timeout);
|
||||||
void wait_for_mission_finished(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();
|
void report_speed_factor();
|
||||||
|
|
||||||
@@ -219,6 +223,7 @@ private:
|
|||||||
std::unique_ptr<mavsdk::Info> _info{};
|
std::unique_ptr<mavsdk::Info> _info{};
|
||||||
std::unique_ptr<mavsdk::ManualControl> _manual_control{};
|
std::unique_ptr<mavsdk::ManualControl> _manual_control{};
|
||||||
std::unique_ptr<mavsdk::Mission> _mission{};
|
std::unique_ptr<mavsdk::Mission> _mission{};
|
||||||
|
std::unique_ptr<mavsdk::MissionRaw> _mission_raw{};
|
||||||
std::unique_ptr<mavsdk::Offboard> _offboard{};
|
std::unique_ptr<mavsdk::Offboard> _offboard{};
|
||||||
std::unique_ptr<mavsdk::Param> _param{};
|
std::unique_ptr<mavsdk::Param> _param{};
|
||||||
std::unique_ptr<mavsdk::Telemetry> _telemetry{};
|
std::unique_ptr<mavsdk::Telemetry> _telemetry{};
|
||||||
|
|||||||
@@ -13,13 +13,13 @@
|
|||||||
{
|
{
|
||||||
"model": "standard_vtol",
|
"model": "standard_vtol",
|
||||||
"vehicle": "standard_vtol",
|
"vehicle": "standard_vtol",
|
||||||
"test_filter": "[multicopter][vtol]",
|
"test_filter": "[vtol]",
|
||||||
"timeout_min": 10
|
"timeout_min": 10
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"model": "tailsitter",
|
"model": "tailsitter",
|
||||||
"vehicle": "tailsitter",
|
"vehicle": "tailsitter",
|
||||||
"test_filter": "[multicopter][vtol]",
|
"test_filter": "[vtol]",
|
||||||
"timeout_min": 10
|
"timeout_min": 10
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -34,15 +34,13 @@
|
|||||||
#include "autopilot_tester.h"
|
#include "autopilot_tester.h"
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("Takeoff and transition and RTL", "[vtol]")
|
TEST_CASE("Fly VTOL mission", "[vtol]")
|
||||||
{
|
{
|
||||||
AutopilotTester tester;
|
AutopilotTester tester;
|
||||||
tester.connect(connection_url);
|
tester.connect(connection_url);
|
||||||
|
tester.load_qgc_mission_raw("test/mavsdk_tests/vtol_mission_allmend.plan");
|
||||||
tester.wait_until_ready();
|
tester.wait_until_ready();
|
||||||
tester.arm();
|
tester.arm();
|
||||||
tester.takeoff();
|
tester.execute_mission_raw();
|
||||||
tester.wait_until_hovering();
|
|
||||||
tester.transition_to_fixedwing();
|
|
||||||
tester.execute_rtl();
|
|
||||||
tester.wait_until_disarmed();
|
tester.wait_until_disarmed();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user