Commit 60ee7a78 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #5188 from DonLakeFlyer/HardenGuided

Better retries on arming, flight mode change and APM guided
parents 4423b2bf d7bb6d85
...@@ -162,35 +162,42 @@ bool ArduCopterFirmwarePlugin::isCapable(const Vehicle* vehicle, FirmwareCapabil ...@@ -162,35 +162,42 @@ bool ArduCopterFirmwarePlugin::isCapable(const Vehicle* vehicle, FirmwareCapabil
void ArduCopterFirmwarePlugin::guidedModeRTL(Vehicle* vehicle) void ArduCopterFirmwarePlugin::guidedModeRTL(Vehicle* vehicle)
{ {
vehicle->setFlightMode("RTL"); _setFlightModeAndValidate(vehicle, "RTL");
} }
void ArduCopterFirmwarePlugin::guidedModeLand(Vehicle* vehicle) void ArduCopterFirmwarePlugin::guidedModeLand(Vehicle* vehicle)
{ {
vehicle->setFlightMode("Land"); _setFlightModeAndValidate(vehicle, "Land");
} }
void ArduCopterFirmwarePlugin::guidedModeTakeoff(Vehicle* vehicle) void ArduCopterFirmwarePlugin::guidedModeTakeoff(Vehicle* vehicle)
{
_guidedModeTakeoff(vehicle);
}
bool ArduCopterFirmwarePlugin::_guidedModeTakeoff(Vehicle* vehicle)
{ {
QString takeoffAltParam("PILOT_TKOFF_ALT"); QString takeoffAltParam("PILOT_TKOFF_ALT");
if (!vehicle->parameterManager()->parameterExists(FactSystem::defaultComponentId, takeoffAltParam)) { float takeoffAlt = 0;
qgcApp()->showMessage(tr("Unable to takeoff, %1 parameter missing.").arg(takeoffAltParam)); if (vehicle->parameterManager()->parameterExists(FactSystem::defaultComponentId, takeoffAltParam)) {
return; Fact* takeoffAltFact = vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, takeoffAltParam);
takeoffAlt = takeoffAltFact->rawValue().toDouble();
} }
Fact* takeoffAltFact = vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, takeoffAltParam);
float takeoffAlt = takeoffAltFact->rawValue().toDouble();
if (takeoffAlt <= 0) { if (takeoffAlt <= 0) {
takeoffAlt = 2.5; takeoffAlt = 2.5;
} else { } else {
takeoffAlt /= 100; // centimeters -> meters takeoffAlt /= 100; // centimeters -> meters
} }
setGuidedMode(vehicle, true); if (!_setFlightModeAndValidate(vehicle, "Guided")) {
qgcApp()->showMessage(tr("Unable to takeoff: Vehicle failed to change to Guided mode."));
return false;
}
if (!_armVehicleAndValidate(vehicle)) { if (!_armVehicleAndValidate(vehicle)) {
qgcApp()->showMessage(tr("Unable to takeoff: Vehicle failed to arm.")); qgcApp()->showMessage(tr("Unable to takeoff: Vehicle failed to arm."));
return; return false;
} }
vehicle->sendMavCommand(vehicle->defaultComponentId(), vehicle->sendMavCommand(vehicle->defaultComponentId(),
...@@ -198,6 +205,8 @@ void ArduCopterFirmwarePlugin::guidedModeTakeoff(Vehicle* vehicle) ...@@ -198,6 +205,8 @@ void ArduCopterFirmwarePlugin::guidedModeTakeoff(Vehicle* vehicle)
true, // show error true, // show error
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
takeoffAlt); takeoffAlt);
return true;
} }
void ArduCopterFirmwarePlugin::guidedModeGotoLocation(Vehicle* vehicle, const QGeoCoordinate& gotoCoord) void ArduCopterFirmwarePlugin::guidedModeGotoLocation(Vehicle* vehicle, const QGeoCoordinate& gotoCoord)
...@@ -246,13 +255,13 @@ void ArduCopterFirmwarePlugin::guidedModeChangeAltitude(Vehicle* vehicle, double ...@@ -246,13 +255,13 @@ void ArduCopterFirmwarePlugin::guidedModeChangeAltitude(Vehicle* vehicle, double
void ArduCopterFirmwarePlugin::pauseVehicle(Vehicle* vehicle) void ArduCopterFirmwarePlugin::pauseVehicle(Vehicle* vehicle)
{ {
vehicle->setFlightMode("Brake"); _setFlightModeAndValidate(vehicle, "Brake");
} }
void ArduCopterFirmwarePlugin::setGuidedMode(Vehicle* vehicle, bool guidedMode) void ArduCopterFirmwarePlugin::setGuidedMode(Vehicle* vehicle, bool guidedMode)
{ {
if (guidedMode) { if (guidedMode) {
vehicle->setFlightMode("Guided"); _setFlightModeAndValidate(vehicle, "Guided");
} else { } else {
pauseVehicle(vehicle); pauseVehicle(vehicle);
} }
...@@ -293,25 +302,29 @@ void ArduCopterFirmwarePlugin::startMission(Vehicle* vehicle) ...@@ -293,25 +302,29 @@ void ArduCopterFirmwarePlugin::startMission(Vehicle* vehicle)
double currentAlt = vehicle->altitudeRelative()->rawValue().toDouble(); double currentAlt = vehicle->altitudeRelative()->rawValue().toDouble();
if (!vehicle->flying()) { if (!vehicle->flying()) {
guidedModeTakeoff(vehicle); if (_guidedModeTakeoff(vehicle)) {
// Wait for vehicle to get off ground before switching to auto // Wait for vehicle to get off ground before switching to auto (10 seconds)
bool didTakeoff = false; bool didTakeoff = false;
for (int i=0; i<50; i++) { for (int i=0; i<100; i++) {
if (vehicle->altitudeRelative()->rawValue().toDouble() >= currentAlt + 1.0) { if (vehicle->altitudeRelative()->rawValue().toDouble() >= currentAlt + 1.0) {
didTakeoff = true; didTakeoff = true;
break; break;
}
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
} }
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
}
if (!didTakeoff) { if (!didTakeoff) {
qgcApp()->showMessage(QStringLiteral("Unable to switch to Auto. Vehicle takeoff failed.")); qgcApp()->showMessage(QStringLiteral("Unable to start mission. Vehicle takeoff failed."));
return; return;
}
} }
} }
vehicle->setFlightMode(missionFlightMode()); if (!_setFlightModeAndValidate(vehicle, missionFlightMode())) {
qgcApp()->showMessage(QStringLiteral("Unable to start mission. Vehicle failed to change to auto."));
return;
}
} }
...@@ -81,6 +81,8 @@ public: ...@@ -81,6 +81,8 @@ public:
private: private:
static bool _remapParamNameIntialized; static bool _remapParamNameIntialized;
static FirmwarePlugin::remapParamNameMajorVersionMap_t _remapParamName; static FirmwarePlugin::remapParamNameMajorVersionMap_t _remapParamName;
bool _guidedModeTakeoff(Vehicle* vehicle);
}; };
#endif #endif
...@@ -437,21 +437,63 @@ bool FirmwarePlugin::vehicleYawsToNextWaypointInMission(const Vehicle* vehicle) ...@@ -437,21 +437,63 @@ bool FirmwarePlugin::vehicleYawsToNextWaypointInMission(const Vehicle* vehicle)
bool FirmwarePlugin::_armVehicleAndValidate(Vehicle* vehicle) bool FirmwarePlugin::_armVehicleAndValidate(Vehicle* vehicle)
{ {
if (!vehicle->armed()) { if (vehicle->armed()) {
return true;
}
bool armedChanged = false;
// We try arming 3 times
for (int retries=0; retries<3; retries++) {
vehicle->setArmed(true); vehicle->setArmed(true);
// Wait for vehicle to return armed state for 3 seconds
for (int i=0; i<30; i++) {
if (vehicle->armed()) {
armedChanged = true;
break;
}
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
}
if (armedChanged) {
break;
}
} }
// Wait for vehicle to return armed state for 2 seconds return armedChanged;
for (int i=0; i<20; i++) { }
if (vehicle->armed()) {
bool FirmwarePlugin::_setFlightModeAndValidate(Vehicle* vehicle, const QString& flightMode)
{
if (vehicle->flightMode() == flightMode) {
return true;
}
bool flightModeChanged = false;
// We try 3 times
for (int retries=0; retries<3; retries++) {
vehicle->setFlightMode(flightMode);
// Wait for vehicle to return flight mode
for (int i=0; i<30; i++) {
if (vehicle->flightMode() == flightMode) {
flightModeChanged = true;
break;
}
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
}
if (flightModeChanged) {
break; break;
} }
QGC::SLEEP::msleep(100);
qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents);
} }
return vehicle->armed();
return flightModeChanged;
} }
void FirmwarePlugin::batteryConsumptionData(Vehicle* vehicle, int& mAhBattery, double& hoverAmps, double& cruiseAmps) const void FirmwarePlugin::batteryConsumptionData(Vehicle* vehicle, int& mAhBattery, double& hoverAmps, double& cruiseAmps) const
{ {
Q_UNUSED(vehicle); Q_UNUSED(vehicle);
......
...@@ -296,10 +296,14 @@ public: ...@@ -296,10 +296,14 @@ public:
static const char* px4FollowMeFlightMode; static const char* px4FollowMeFlightMode;
protected: protected:
// Arms the vehicle, waiting for the arm state to change. // Arms the vehicle with validation and retries
// @return: true - vehicle armed, false - vehicle failed to arm // @return: true - vehicle armed, false - vehicle failed to arm
bool _armVehicleAndValidate(Vehicle* vehicle); bool _armVehicleAndValidate(Vehicle* vehicle);
// Sets the vehicle to the specified flight mode with validation and retries
// @return: true - vehicle in specified flight mode, false - flight mode change failed
bool _setFlightModeAndValidate(Vehicle* vehicle, const QString& flightMode);
private: private:
QVariantList _toolBarIndicatorList; QVariantList _toolBarIndicatorList;
static QVariantList _cameraList; ///< Standard QGC camera list static QVariantList _cameraList; ///< Standard QGC camera list
......
...@@ -331,12 +331,12 @@ void PX4FirmwarePlugin::pauseVehicle(Vehicle* vehicle) ...@@ -331,12 +331,12 @@ void PX4FirmwarePlugin::pauseVehicle(Vehicle* vehicle)
void PX4FirmwarePlugin::guidedModeRTL(Vehicle* vehicle) void PX4FirmwarePlugin::guidedModeRTL(Vehicle* vehicle)
{ {
vehicle->setFlightMode(_rtlFlightMode); _setFlightModeAndValidate(vehicle, _rtlFlightMode);
} }
void PX4FirmwarePlugin::guidedModeLand(Vehicle* vehicle) void PX4FirmwarePlugin::guidedModeLand(Vehicle* vehicle)
{ {
vehicle->setFlightMode(_landingFlightMode); _setFlightModeAndValidate(vehicle, _landingFlightMode);
} }
void PX4FirmwarePlugin::guidedModeOrbit(Vehicle* vehicle, const QGeoCoordinate& centerCoord, double radius, double velocity, double altitude) void PX4FirmwarePlugin::guidedModeOrbit(Vehicle* vehicle, const QGeoCoordinate& centerCoord, double radius, double velocity, double altitude)
...@@ -457,13 +457,13 @@ void PX4FirmwarePlugin::startMission(Vehicle* vehicle) ...@@ -457,13 +457,13 @@ void PX4FirmwarePlugin::startMission(Vehicle* vehicle)
return; return;
} }
vehicle->setFlightMode(missionFlightMode()); _setFlightModeAndValidate(vehicle, missionFlightMode());
} }
void PX4FirmwarePlugin::setGuidedMode(Vehicle* vehicle, bool guidedMode) void PX4FirmwarePlugin::setGuidedMode(Vehicle* vehicle, bool guidedMode)
{ {
if (guidedMode) { if (guidedMode) {
vehicle->setFlightMode(_holdFlightMode); _setFlightModeAndValidate(vehicle, _holdFlightMode);
} else { } else {
pauseVehicle(vehicle); pauseVehicle(vehicle);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment