Unverified Commit cad17026 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #7156 from DonLakeFlyer/FWLanding2

Replacement for #7152
parents b8a4746d 0e3addac
......@@ -7,12 +7,7 @@
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FACTSYSTEM_H
#define FACTSYSTEM_H
#pragma once
#include "Fact.h"
#include "FactMetaData.h"
......@@ -26,7 +21,6 @@ class FactSystem : public QGCTool
Q_OBJECT
public:
/// All access to FactSystem is through FactSystem::instance, so constructor is private
FactSystem(QGCApplication* app, QGCToolbox* toolbox);
// Override from QGCTool
......@@ -41,5 +35,3 @@ public:
private:
static const char* _factSystemQmlUri; ///< URI for FactSystem QML imports
};
#endif
......@@ -325,16 +325,20 @@ void APMFirmwarePlugin::_handleOutgoingParamSet(Vehicle* vehicle, LinkInterface*
mavlink_msg_param_set_encode_chan(message->sysid, message->compid, outgoingLink->mavlinkChannel(), message, &paramSet);
}
bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_message_t* message)
bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_message_t* message, bool longVersion)
{
QString messageText;
APMFirmwarePluginInstanceData* instanceData = qobject_cast<APMFirmwarePluginInstanceData*>(vehicle->firmwarePluginInstanceData());
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
int severity;
if (longVersion) {
severity = mavlink_msg_statustext_long_get_severity(message);
} else {
severity = mavlink_msg_statustext_get_severity(message);
}
if (vehicle->firmwareMajorVersion() == Vehicle::versionNotSetValue || statusText.severity < MAV_SEVERITY_NOTICE) {
messageText = _getMessageText(message);
if (vehicle->firmwareMajorVersion() == Vehicle::versionNotSetValue || severity < MAV_SEVERITY_NOTICE) {
messageText = _getMessageText(message, longVersion);
qCDebug(APMFirmwarePluginLog) << messageText;
if (!messageText.contains(APM_SOLO_REXP)) {
......@@ -400,14 +404,14 @@ bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_mess
}
if (messageText.isEmpty()) {
messageText = _getMessageText(message);
messageText = _getMessageText(message, longVersion);
}
// The following messages are incorrectly labeled as warning message.
// Fixed in newer firmware (unreleased at this point), but still in older firmware.
if (messageText.contains(APM_COPTER_REXP) || messageText.contains(APM_PLANE_REXP) || messageText.contains(APM_ROVER_REXP) || messageText.contains(APM_SUB_REXP) ||
messageText.contains(APM_PX4NUTTX_REXP) || messageText.contains(APM_FRAME_REXP) || messageText.contains(APM_SYSID_REXP)) {
_setInfoSeverity(message);
_setInfoSeverity(message, longVersion);
}
if (messageText.contains(APM_SOLO_REXP)) {
......@@ -415,7 +419,7 @@ bool APMFirmwarePlugin::_handleIncomingStatusText(Vehicle* vehicle, mavlink_mess
vehicle->setSoloFirmware(true);
// Fix up severity
_setInfoSeverity(message);
_setInfoSeverity(message, longVersion);
// Start TCP video handshake with ARTOO
_soloVideoHandshake(vehicle, true /* originalSoloFirmware */);
......@@ -465,7 +469,9 @@ bool APMFirmwarePlugin::adjustIncomingMavlinkMessage(Vehicle* vehicle, mavlink_m
_handleIncomingParamValue(vehicle, message);
break;
case MAVLINK_MSG_ID_STATUSTEXT:
return _handleIncomingStatusText(vehicle, message);
return _handleIncomingStatusText(vehicle, message, false /* longVersion */);
case MAVLINK_MSG_ID_STATUSTEXT_LONG:
return _handleIncomingStatusText(vehicle, message, true /* longVersion */);
case MAVLINK_MSG_ID_HEARTBEAT:
_handleIncomingHeartbeat(vehicle, message);
break;
......@@ -494,12 +500,17 @@ void APMFirmwarePlugin::adjustOutgoingMavlinkMessage(Vehicle* vehicle, LinkInter
}
}
QString APMFirmwarePlugin::_getMessageText(mavlink_message_t* message) const
QString APMFirmwarePlugin::_getMessageText(mavlink_message_t* message, bool longVersion) const
{
QByteArray b;
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_get_text(message, b.data());
if (longVersion) {
b.resize(MAVLINK_MSG_STATUSTEXT_LONG_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_long_get_text(message, b.data());
} else {
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_get_text(message, b.data());
}
// Ensure NUL-termination
b[b.length()-1] = '\0';
......@@ -561,20 +572,33 @@ void APMFirmwarePlugin::_adjustSeverity(mavlink_message_t* message) const
&statusText);
}
void APMFirmwarePlugin::_setInfoSeverity(mavlink_message_t* message) const
void APMFirmwarePlugin::_setInfoSeverity(mavlink_message_t* message, bool longVersion) const
{
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
// Re-Encoding is always done using mavlink 1.0
mavlink_status_t* mavlinkStatusReEncode = mavlink_get_channel_status(0);
mavlinkStatusReEncode->flags |= MAVLINK_STATUS_FLAG_IN_MAVLINK1;
statusText.severity = MAV_SEVERITY_INFO;
mavlink_msg_statustext_encode_chan(message->sysid,
message->compid,
0, // Re-encoding uses reserved channel 0
message,
&statusText);
if (longVersion) {
mavlink_statustext_long_t statusTextLong;
mavlink_msg_statustext_long_decode(message, &statusTextLong);
statusTextLong.severity = MAV_SEVERITY_INFO;
mavlink_msg_statustext_long_encode_chan(message->sysid,
message->compid,
0, // Re-encoding uses reserved channel 0
message,
&statusTextLong);
} else {
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
statusText.severity = MAV_SEVERITY_INFO;
mavlink_msg_statustext_encode_chan(message->sysid,
message->compid,
0, // Re-encoding uses reserved channel 0
message,
&statusText);
}
}
void APMFirmwarePlugin::_adjustCalibrationMessageSeverity(mavlink_message_t* message) const
......
......@@ -119,10 +119,10 @@ private:
void _adjustSeverity(mavlink_message_t* message) const;
void _adjustCalibrationMessageSeverity(mavlink_message_t* message) const;
static bool _isTextSeverityAdjustmentNeeded(const APMFirmwareVersion& firmwareVersion);
void _setInfoSeverity(mavlink_message_t* message) const;
QString _getMessageText(mavlink_message_t* message) const;
void _setInfoSeverity(mavlink_message_t* message, bool longVersion) const;
QString _getMessageText(mavlink_message_t* message, bool longVersion) const;
void _handleIncomingParamValue(Vehicle* vehicle, mavlink_message_t* message);
bool _handleIncomingStatusText(Vehicle* vehicle, mavlink_message_t* message);
bool _handleIncomingStatusText(Vehicle* vehicle, mavlink_message_t* message, bool longVersion);
void _handleIncomingHeartbeat(Vehicle* vehicle, mavlink_message_t* message);
void _handleOutgoingParamSet(Vehicle* vehicle, LinkInterface* outgoingLink, mavlink_message_t* message);
void _soloVideoHandshake(Vehicle* vehicle, bool originalSoloFirmware);
......
......@@ -425,7 +425,7 @@ void PX4FirmwarePlugin::guidedModeGotoLocation(Vehicle* vehicle, const QGeoCoord
return;
}
if (vehicle->capabilityBits() && MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
if (vehicle->capabilityBits() & MAV_PROTOCOL_CAPABILITY_COMMAND_INT) {
vehicle->sendMavCommandInt(vehicle->defaultComponentId(),
MAV_CMD_DO_REPOSITION,
MAV_FRAME_GLOBAL,
......
......@@ -51,7 +51,13 @@
"min": 0.1,
"max": 90,
"decimalPlaces": 1,
"defaultValue": 12.0
"defaultValue": 6.0
},
{
"name": "ValueSetIsDistance",
"shortDescription": "Value controller loiter point is distance",
"type": "bool",
"defaultValue": false
},
{
"name": "StopTakingPhotos",
......
......@@ -149,7 +149,8 @@ void FWLandingPatternTest::_testDirty(void)
<< _fwItem->landingDistance()
<< _fwItem->glideSlope()
<< _fwItem->stopTakingPhotos()
<< _fwItem->stopTakingVideo();
<< _fwItem->stopTakingVideo()
<< _fwItem->valueSetIsDistance();
for(Fact* fact: rgFacts) {
qDebug() << fact->name();
QVERIFY(!_fwItem->dirty());
......@@ -167,8 +168,7 @@ void FWLandingPatternTest::_testDirty(void)
// These bool properties should set dirty when changed
QList<const char*> rgBoolNames;
rgBoolNames << "valueSetIsDistance"
<< "loiterClockwise"
rgBoolNames << "loiterClockwise"
<< "altitudesAreRelative";
const QMetaObject* metaObject = _fwItem->metaObject();
for(const char* boolName: rgBoolNames) {
......@@ -223,16 +223,16 @@ void FWLandingPatternTest::_validateItem(FixedWingLandingComplexItem* newItem)
QVERIFY(fuzzyCompareLatLon(newItem->loiterTangentCoordinate(), _fwItem->loiterTangentCoordinate()));
QVERIFY(fuzzyCompareLatLon(newItem->landingCoordinate(), _fwItem->landingCoordinate()));
QCOMPARE(newItem->stopTakingPhotos()->rawValue().toBool(), _fwItem->stopTakingPhotos()->rawValue().toBool());
QCOMPARE(newItem->stopTakingVideo()->rawValue().toBool(), _fwItem->stopTakingVideo()->rawValue().toBool());
QCOMPARE(newItem->loiterAltitude()->rawValue().toInt(), _fwItem->loiterAltitude()->rawValue().toInt());
QCOMPARE(newItem->loiterRadius()->rawValue().toInt(), _fwItem->loiterRadius()->rawValue().toInt());
QCOMPARE(newItem->landingAltitude()->rawValue().toInt(), _fwItem->landingAltitude()->rawValue().toInt());
QCOMPARE(newItem->landingHeading()->rawValue().toInt(), _fwItem->landingHeading()->rawValue().toInt());
QCOMPARE(newItem->landingDistance()->rawValue().toInt(), _fwItem->landingDistance()->rawValue().toInt());
QCOMPARE(newItem->glideSlope()->rawValue().toInt(), _fwItem->glideSlope()->rawValue().toInt());
QCOMPARE(newItem->_valueSetIsDistance, _fwItem->_valueSetIsDistance);
QCOMPARE(newItem->_loiterClockwise, _fwItem->_loiterClockwise);
QCOMPARE(newItem->_altitudesAreRelative, _fwItem->_altitudesAreRelative);
QCOMPARE(newItem->_landingCoordSet, _fwItem->_landingCoordSet);
QCOMPARE(newItem->stopTakingPhotos()->rawValue().toBool(), _fwItem->stopTakingPhotos()->rawValue().toBool());
QCOMPARE(newItem->stopTakingVideo()->rawValue().toBool(), _fwItem->stopTakingVideo()->rawValue().toBool());
QCOMPARE(newItem->loiterAltitude()->rawValue().toInt(), _fwItem->loiterAltitude()->rawValue().toInt());
QCOMPARE(newItem->loiterRadius()->rawValue().toInt(), _fwItem->loiterRadius()->rawValue().toInt());
QCOMPARE(newItem->landingAltitude()->rawValue().toInt(), _fwItem->landingAltitude()->rawValue().toInt());
QCOMPARE(newItem->landingHeading()->rawValue().toInt(), _fwItem->landingHeading()->rawValue().toInt());
QCOMPARE(newItem->landingDistance()->rawValue().toInt(), _fwItem->landingDistance()->rawValue().toInt());
QCOMPARE(newItem->glideSlope()->rawValue().toInt(), _fwItem->glideSlope()->rawValue().toInt());
QCOMPARE(newItem->valueSetIsDistance()->rawValue().toBool(), _fwItem->valueSetIsDistance()->rawValue().toBool());
QCOMPARE(newItem->_loiterClockwise, _fwItem->_loiterClockwise);
QCOMPARE(newItem->_altitudesAreRelative, _fwItem->_altitudesAreRelative);
QCOMPARE(newItem->_landingCoordSet, _fwItem->_landingCoordSet);
}
......@@ -29,6 +29,7 @@ const char* FixedWingLandingComplexItem::landingAltitudeName = "LandingAlti
const char* FixedWingLandingComplexItem::glideSlopeName = "GlideSlope";
const char* FixedWingLandingComplexItem::stopTakingPhotosName = "StopTakingPhotos";
const char* FixedWingLandingComplexItem::stopTakingVideoName = "StopTakingVideo";
const char* FixedWingLandingComplexItem::valueSetIsDistanceName = "ValueSetIsDistance";
const char* FixedWingLandingComplexItem::_jsonLoiterCoordinateKey = "loiterCoordinate";
const char* FixedWingLandingComplexItem::_jsonLoiterRadiusKey = "loiterRadius";
......@@ -59,9 +60,9 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, bool
, _glideSlopeFact (settingsGroup, _metaDataMap[glideSlopeName])
, _stopTakingPhotosFact (settingsGroup, _metaDataMap[stopTakingPhotosName])
, _stopTakingVideoFact (settingsGroup, _metaDataMap[stopTakingVideoName])
, _valueSetIsDistanceFact (settingsGroup, _metaDataMap[valueSetIsDistanceName])
, _loiterClockwise (true)
, _altitudesAreRelative (true)
, _valueSetIsDistance (true)
{
_editorQml = "qrc:/qml/FWLandingPatternEditor.qml";
......@@ -89,6 +90,7 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, bool
connect(&_loiterRadiusFact, &Fact::valueChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(&_stopTakingPhotosFact, &Fact::valueChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(&_stopTakingVideoFact, &Fact::valueChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(&_valueSetIsDistanceFact, &Fact::valueChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(this, &FixedWingLandingComplexItem::loiterCoordinateChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(this, &FixedWingLandingComplexItem::landingCoordinateChanged, this, &FixedWingLandingComplexItem::_setDirty);
connect(this, &FixedWingLandingComplexItem::loiterClockwiseChanged, this, &FixedWingLandingComplexItem::_setDirty);
......@@ -97,6 +99,13 @@ FixedWingLandingComplexItem::FixedWingLandingComplexItem(Vehicle* vehicle, bool
connect(this, &FixedWingLandingComplexItem::altitudesAreRelativeChanged, this, &FixedWingLandingComplexItem::coordinateHasRelativeAltitudeChanged);
connect(this, &FixedWingLandingComplexItem::altitudesAreRelativeChanged, this, &FixedWingLandingComplexItem::exitCoordinateHasRelativeAltitudeChanged);
if (_valueSetIsDistanceFact.rawValue().toBool()) {
_recalcFromHeadingAndDistanceChange();
} else {
_glideSlopeChanged();
}
setDirty(false);
}
int FixedWingLandingComplexItem::lastSequenceNumber(void) const
......@@ -142,7 +151,7 @@ void FixedWingLandingComplexItem::save(QJsonArray& missionItems)
saveObject[_jsonStopTakingVideoKey] = _stopTakingVideoFact.rawValue().toBool();
saveObject[_jsonLoiterClockwiseKey] = _loiterClockwise;
saveObject[_jsonAltitudesAreRelativeKey] = _altitudesAreRelative;
saveObject[_jsonValueSetIsDistanceKey] = _valueSetIsDistance;
saveObject[_jsonValueSetIsDistanceKey] = _valueSetIsDistanceFact.rawValue().toBool();
missionItems.append(saveObject);
}
......@@ -204,7 +213,7 @@ bool FixedWingLandingComplexItem::load(const QJsonObject& complexObject, int seq
} else {
_altitudesAreRelative = loiterAltitudeRelative;
}
_valueSetIsDistance = true;
_valueSetIsDistanceFact.setRawValue(true);
} else if (version == 2) {
QList<JsonHelper::KeyValidateInfo> v2KeyInfoList = {
{ _jsonAltitudesAreRelativeKey, QJsonValue::Bool, true },
......@@ -216,7 +225,7 @@ bool FixedWingLandingComplexItem::load(const QJsonObject& complexObject, int seq
}
_altitudesAreRelative = complexObject[_jsonAltitudesAreRelativeKey].toBool();
_valueSetIsDistance = complexObject[_jsonValueSetIsDistanceKey].toBool();
_valueSetIsDistanceFact.setRawValue(complexObject[_jsonValueSetIsDistanceKey].toBool());
} else {
errorString = tr("%1 complex item version %2 not supported").arg(jsonComplexItemTypeValue).arg(version);
_ignoreRecalcSignals = false;
......
......@@ -30,7 +30,7 @@ public:
Q_PROPERTY(Fact* loiterRadius READ loiterRadius CONSTANT)
Q_PROPERTY(Fact* landingAltitude READ landingAltitude CONSTANT)
Q_PROPERTY(Fact* landingHeading READ landingHeading CONSTANT)
Q_PROPERTY(bool valueSetIsDistance MEMBER _valueSetIsDistance NOTIFY valueSetIsDistanceChanged)
Q_PROPERTY(Fact* valueSetIsDistance READ valueSetIsDistance CONSTANT)
Q_PROPERTY(Fact* landingDistance READ landingDistance CONSTANT)
Q_PROPERTY(Fact* glideSlope READ glideSlope CONSTANT)
Q_PROPERTY(bool loiterClockwise MEMBER _loiterClockwise NOTIFY loiterClockwiseChanged)
......@@ -50,6 +50,7 @@ public:
Fact* glideSlope (void) { return &_glideSlopeFact; }
Fact* stopTakingPhotos (void) { return &_stopTakingPhotosFact; }
Fact* stopTakingVideo (void) { return &_stopTakingVideoFact; }
Fact* valueSetIsDistance (void) { return &_valueSetIsDistanceFact; }
QGeoCoordinate landingCoordinate (void) const { return _landingCoordinate; }
QGeoCoordinate loiterCoordinate (void) const { return _loiterCoordinate; }
QGeoCoordinate loiterTangentCoordinate (void) const { return _loiterTangentCoordinate; }
......@@ -110,6 +111,7 @@ public:
static const char* glideSlopeName;
static const char* stopTakingPhotosName;
static const char* stopTakingVideoName;
static const char* valueSetIsDistanceName;
signals:
void loiterCoordinateChanged (QGeoCoordinate coordinate);
......@@ -154,10 +156,10 @@ private:
Fact _glideSlopeFact;
Fact _stopTakingPhotosFact;
Fact _stopTakingVideoFact;
Fact _valueSetIsDistanceFact;
bool _loiterClockwise;
bool _altitudesAreRelative;
bool _valueSetIsDistance;
static const char* settingsGroup;
static const char* _jsonLoiterCoordinateKey;
......
......@@ -119,9 +119,9 @@ Rectangle {
QGCRadioButton {
id: specifyLandingDistance
text: qsTr("Landing Dist")
checked: missionItem.valueSetIsDistance
checked: missionItem.valueSetIsDistance.rawValue
exclusiveGroup: distanceGlideGroup
onClicked: missionItem.valueSetIsDistance = checked
onClicked: missionItem.valueSetIsDistance.rawValue = checked
Layout.fillWidth: true
}
......@@ -134,9 +134,9 @@ Rectangle {
QGCRadioButton {
id: specifyGlideSlope
text: qsTr("Glide Slope")
checked: !missionItem.valueSetIsDistance
checked: !missionItem.valueSetIsDistance.rawValue
exclusiveGroup: distanceGlideGroup
onClicked: missionItem.valueSetIsDistance = !checked
onClicked: missionItem.valueSetIsDistance.rawValue = !checked
Layout.fillWidth: true
}
......
......@@ -783,7 +783,10 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes
_handleEstimatorStatus(message);
break;
case MAVLINK_MSG_ID_STATUSTEXT:
_handleStatusText(message);
_handleStatusText(message, false /* longVersion */);
break;
case MAVLINK_MSG_ID_STATUSTEXT_LONG:
_handleStatusText(message, true /* longVersion */);
break;
case MAVLINK_MSG_ID_ORBIT_EXECUTION_STATUS:
_handleOrbitExecutionStatus(message);
......@@ -881,15 +884,23 @@ void Vehicle::_handleCameraImageCaptured(const mavlink_message_t& message)
}
}
void Vehicle::_handleStatusText(mavlink_message_t& message)
void Vehicle::_handleStatusText(mavlink_message_t& message, bool longVersion)
{
QByteArray b;
QByteArray b;
QString messageText;
int severity;
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_get_text(&message, b.data());
if (longVersion) {
b.resize(MAVLINK_MSG_STATUSTEXT_LONG_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_long_get_text(&message, b.data());
severity = mavlink_msg_statustext_long_get_severity(&message);
} else {
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_get_text(&message, b.data());
severity = mavlink_msg_statustext_get_severity(&message);
}
b[b.length()-1] = '\0';
QString messageText = QString(b);
int severity = mavlink_msg_statustext_get_severity(&message);
messageText = QString(b);
bool skipSpoken = false;
bool ardupilotPrearm = messageText.startsWith(QStringLiteral("PreArm"));
......
......@@ -1255,7 +1255,7 @@ private:
void _handleAttitudeTarget(mavlink_message_t& message);
void _handleDistanceSensor(mavlink_message_t& message);
void _handleEstimatorStatus(mavlink_message_t& message);
void _handleStatusText(mavlink_message_t& message);
void _handleStatusText(mavlink_message_t& message, bool longVersion);
void _handleOrbitExecutionStatus(const mavlink_message_t& message);
// ArduPilot dialect messages
#if !defined(NO_ARDUPILOT_DIALECT)
......
......@@ -1065,6 +1065,14 @@ void MockLink::_sendStatusTextMessages(void)
status->severity,
status->msg);
respondWithMavlinkMessage(msg);
mavlink_msg_statustext_long_pack_chan(_vehicleSystemId,
_vehicleComponentId,
_mavlinkChannel,
&msg,
status->severity,
status->msg);
respondWithMavlinkMessage(msg);
}
}
......
......@@ -15,6 +15,7 @@ MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol) :
// messageFilter.insert(MAVLINK_MSG_ID_HEARTBEAT, false);
// messageFilter.insert(MAVLINK_MSG_ID_SYS_STATUS, false);
messageFilter.insert(MAVLINK_MSG_ID_STATUSTEXT, false);
messageFilter.insert(MAVLINK_MSG_ID_STATUSTEXT_LONG, false);
messageFilter.insert(MAVLINK_MSG_ID_COMMAND_LONG, false);
messageFilter.insert(MAVLINK_MSG_ID_COMMAND_ACK, false);
messageFilter.insert(MAVLINK_MSG_ID_PARAM_SET, false);
......
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