|
|
@ -27,6 +27,10 @@ FactMetaData* SimpleMissionItem::_frameMetaData = NULL; |
|
|
|
FactMetaData* SimpleMissionItem::_latitudeMetaData = NULL; |
|
|
|
FactMetaData* SimpleMissionItem::_latitudeMetaData = NULL; |
|
|
|
FactMetaData* SimpleMissionItem::_longitudeMetaData = NULL; |
|
|
|
FactMetaData* SimpleMissionItem::_longitudeMetaData = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char* SimpleMissionItem::_jsonAltitudeModeKey = "AltitudeMode"; |
|
|
|
|
|
|
|
const char* SimpleMissionItem::_jsonAltitudeKey = "Altitude"; |
|
|
|
|
|
|
|
const char* SimpleMissionItem::_jsonAMSLAltAboveTerrainKey = "AMSLAltAboveTerrain"; |
|
|
|
|
|
|
|
|
|
|
|
struct EnumInfo_s { |
|
|
|
struct EnumInfo_s { |
|
|
|
const char * label; |
|
|
|
const char * label; |
|
|
|
MAV_FRAME frame; |
|
|
|
MAV_FRAME frame; |
|
|
@ -48,29 +52,28 @@ static const struct EnumInfo_s _rgMavFrameInfo[] = { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) |
|
|
|
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) |
|
|
|
: VisualMissionItem(vehicle, parent) |
|
|
|
: VisualMissionItem (vehicle, parent) |
|
|
|
, _rawEdit(false) |
|
|
|
, _rawEdit (false) |
|
|
|
, _dirty(false) |
|
|
|
, _dirty (false) |
|
|
|
, _ignoreDirtyChangeSignals(false) |
|
|
|
, _ignoreDirtyChangeSignals (false) |
|
|
|
, _speedSection(NULL) |
|
|
|
, _speedSection (NULL) |
|
|
|
, _cameraSection(NULL) |
|
|
|
, _cameraSection (NULL) |
|
|
|
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _commandTree (qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) |
|
|
|
|
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _param1MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeMode (AltitudeRelative) |
|
|
|
, _param2MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeFact (0, "Altitude", FactMetaData::valueTypeDouble) |
|
|
|
, _param3MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _amslAltAboveTerrainFact (0, "Alt above terrain", FactMetaData::valueTypeDouble) |
|
|
|
, _param4MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param1MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param5MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param2MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param6MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param3MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param7MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param4MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingAltitudeRelativeToHomeAndFrame (false) |
|
|
|
, _param5MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param6MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param7MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
|
|
|
|
|
|
|
|
_altitudeRelativeToHomeFact.setRawValue(true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_setupMetaData(); |
|
|
|
_setupMetaData(); |
|
|
|
_connectSignals(); |
|
|
|
_connectSignals(); |
|
|
|
_updateOptionalSections(); |
|
|
|
_updateOptionalSections(); |
|
|
@ -81,35 +84,37 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, QObject* parent) |
|
|
|
connect(&_missionItem, &MissionItem::specifiedFlightSpeedChanged, this, &SimpleMissionItem::specifiedFlightSpeedChanged); |
|
|
|
connect(&_missionItem, &MissionItem::specifiedFlightSpeedChanged, this, &SimpleMissionItem::specifiedFlightSpeedChanged); |
|
|
|
|
|
|
|
|
|
|
|
connect(this, &SimpleMissionItem::sequenceNumberChanged, this, &SimpleMissionItem::lastSequenceNumberChanged); |
|
|
|
connect(this, &SimpleMissionItem::sequenceNumberChanged, this, &SimpleMissionItem::lastSequenceNumberChanged); |
|
|
|
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_updateLastSequenceNumber); |
|
|
|
connect(this, &SimpleMissionItem::cameraSectionChanged, this, &SimpleMissionItem::_updateLastSequenceNumber); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, bool editMode, const MissionItem& missionItem, QObject* parent) |
|
|
|
SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, bool editMode, const MissionItem& missionItem, QObject* parent) |
|
|
|
: VisualMissionItem(vehicle, parent) |
|
|
|
: VisualMissionItem (vehicle, parent) |
|
|
|
, _missionItem(missionItem) |
|
|
|
, _missionItem (missionItem) |
|
|
|
, _rawEdit(false) |
|
|
|
, _rawEdit (false) |
|
|
|
, _dirty(false) |
|
|
|
, _dirty (false) |
|
|
|
, _ignoreDirtyChangeSignals(false) |
|
|
|
, _ignoreDirtyChangeSignals (false) |
|
|
|
, _speedSection(NULL) |
|
|
|
, _speedSection (NULL) |
|
|
|
, _cameraSection(NULL) |
|
|
|
, _cameraSection (NULL) |
|
|
|
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _commandTree (qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) |
|
|
|
|
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _param1MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeMode (missionItem.relativeAltitude() ? AltitudeRelative : AltitudeAMSL) |
|
|
|
, _param2MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeFact (0, "Altitude", FactMetaData::valueTypeDouble) |
|
|
|
, _param3MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _amslAltAboveTerrainFact (0, "Alt above terrain", FactMetaData::valueTypeDouble) |
|
|
|
, _param4MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param1MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param5MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param2MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param6MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param3MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _param7MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param4MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingAltitudeRelativeToHomeAndFrame (false) |
|
|
|
, _param5MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param6MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param7MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
|
|
|
|
|
|
|
|
_altitudeRelativeToHomeFact.setRawValue(true); |
|
|
|
|
|
|
|
_isCurrentItem = missionItem.isCurrentItem(); |
|
|
|
_isCurrentItem = missionItem.isCurrentItem(); |
|
|
|
|
|
|
|
_altitudeFact.setRawValue(specifiesCoordinate() ? _missionItem._param7Fact.rawValue() : qQNaN()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
|
|
|
|
// In !editMode we skip some of the intialization to save memory
|
|
|
|
// In !editMode we skip some of the intialization to save memory
|
|
|
|
if (editMode) { |
|
|
|
if (editMode) { |
|
|
@ -117,71 +122,62 @@ SimpleMissionItem::SimpleMissionItem(Vehicle* vehicle, bool editMode, const Miss |
|
|
|
} |
|
|
|
} |
|
|
|
_connectSignals(); |
|
|
|
_connectSignals(); |
|
|
|
_updateOptionalSections(); |
|
|
|
_updateOptionalSections(); |
|
|
|
_syncFrameToAltitudeRelativeToHome(); |
|
|
|
|
|
|
|
if (editMode) { |
|
|
|
if (editMode) { |
|
|
|
_rebuildFacts(); |
|
|
|
_rebuildFacts(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* parent) |
|
|
|
SimpleMissionItem::SimpleMissionItem(const SimpleMissionItem& other, QObject* parent) |
|
|
|
: VisualMissionItem(other, parent) |
|
|
|
: VisualMissionItem (other, parent) |
|
|
|
, _missionItem(other._vehicle) |
|
|
|
, _missionItem (other._vehicle) |
|
|
|
, _rawEdit(false) |
|
|
|
, _rawEdit (false) |
|
|
|
, _dirty(false) |
|
|
|
, _dirty (false) |
|
|
|
, _ignoreDirtyChangeSignals(false) |
|
|
|
, _ignoreDirtyChangeSignals (false) |
|
|
|
, _speedSection(NULL) |
|
|
|
, _speedSection (NULL) |
|
|
|
, _cameraSection(NULL) |
|
|
|
, _cameraSection (NULL) |
|
|
|
, _commandTree(qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _commandTree (qgcApp()->toolbox()->missionCommandTree()) |
|
|
|
, _altitudeRelativeToHomeFact (0, "Altitude is relative to home", FactMetaData::valueTypeUint32) |
|
|
|
|
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _supportedCommandFact (0, "Command:", FactMetaData::valueTypeUint32) |
|
|
|
, _param1MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeMode (other._altitudeMode) |
|
|
|
, _param2MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _altitudeFact (0, "Altitude", FactMetaData::valueTypeDouble) |
|
|
|
, _param3MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _amslAltAboveTerrainFact (qQNaN(), "Alt above terrain", FactMetaData::valueTypeDouble) |
|
|
|
, _param4MetaData(FactMetaData::valueTypeDouble) |
|
|
|
, _param1MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingAltitudeRelativeToHomeAndFrame (false) |
|
|
|
, _param2MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param3MetaData (FactMetaData::valueTypeDouble) |
|
|
|
|
|
|
|
, _param4MetaData (FactMetaData::valueTypeDouble) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
, _syncingHeadingDegreesAndParam4 (false) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
_editorQml = QStringLiteral("qrc:/qml/SimpleItemEditor.qml"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_altitudeFact.setRawValue(other._altitudeFact.rawValue()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(other._amslAltAboveTerrainFact.rawValue()); |
|
|
|
|
|
|
|
|
|
|
|
_setupMetaData(); |
|
|
|
_setupMetaData(); |
|
|
|
_connectSignals(); |
|
|
|
_connectSignals(); |
|
|
|
_updateOptionalSections(); |
|
|
|
_updateOptionalSections(); |
|
|
|
|
|
|
|
|
|
|
|
*this = other; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_rebuildFacts(); |
|
|
|
_rebuildFacts(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const SimpleMissionItem& SimpleMissionItem::operator=(const SimpleMissionItem& other) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
VisualMissionItem::operator=(other); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setRawEdit(other._rawEdit); |
|
|
|
|
|
|
|
setDirty(other._dirty); |
|
|
|
|
|
|
|
setHomePositionSpecialCase(other._homePositionSpecialCase); |
|
|
|
|
|
|
|
_syncFrameToAltitudeRelativeToHome(); |
|
|
|
|
|
|
|
_rebuildFacts(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_connectSignals(void) |
|
|
|
void SimpleMissionItem::_connectSignals(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Connect to change signals to track dirty state
|
|
|
|
// Connect to change signals to track dirty state
|
|
|
|
connect(&_missionItem._param1Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param1Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param2Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param2Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param3Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param3Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param4Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param4Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param5Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param5Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param6Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param6Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._param7Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._param7Fact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._frameFact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._frameFact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem._commandFact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem._commandFact, &Fact::valueChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
connect(&_missionItem, &MissionItem::sequenceNumberChanged, this, &SimpleMissionItem::_setDirtyFromSignal); |
|
|
|
connect(&_missionItem, &MissionItem::sequenceNumberChanged, this, &SimpleMissionItem::_setDirty); |
|
|
|
|
|
|
|
connect(this, &SimpleMissionItem::altitudeModeChanged,this, &SimpleMissionItem::_setDirty); |
|
|
|
// Values from these facts must propagate back and forth between the real object storage
|
|
|
|
|
|
|
|
connect(&_altitudeRelativeToHomeFact, &Fact::valueChanged, this, &SimpleMissionItem::_syncAltitudeRelativeToHomeToFrame); |
|
|
|
// These changes may need to trigger terrain queries
|
|
|
|
connect(&_missionItem._frameFact, &Fact::valueChanged, this, &SimpleMissionItem::_syncFrameToAltitudeRelativeToHome); |
|
|
|
connect(&_altitudeFact, &Fact::valueChanged, this, &SimpleMissionItem::_altitudeChanged); |
|
|
|
|
|
|
|
connect(this, &SimpleMissionItem::altitudeModeChanged,this, &SimpleMissionItem::_altitudeModeChanged); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connect(this, &SimpleMissionItem::terrainAltitudeChanged,this, &SimpleMissionItem::_terrainAltChanged); |
|
|
|
|
|
|
|
|
|
|
|
// These are coordinate parameters, they must emit coordinateChanged signal
|
|
|
|
// These are coordinate parameters, they must emit coordinateChanged signal
|
|
|
|
connect(&_missionItem._param5Fact, &Fact::valueChanged, this, &SimpleMissionItem::_sendCoordinateChanged); |
|
|
|
connect(&_missionItem._param5Fact, &Fact::valueChanged, this, &SimpleMissionItem::_sendCoordinateChanged); |
|
|
@ -208,7 +204,6 @@ void SimpleMissionItem::_connectSignals(void) |
|
|
|
|
|
|
|
|
|
|
|
// These fact signals must alway signal out through SimpleMissionItem signals
|
|
|
|
// These fact signals must alway signal out through SimpleMissionItem signals
|
|
|
|
connect(&_missionItem._commandFact, &Fact::valueChanged, this, &SimpleMissionItem::_sendCommandChanged); |
|
|
|
connect(&_missionItem._commandFact, &Fact::valueChanged, this, &SimpleMissionItem::_sendCommandChanged); |
|
|
|
connect(&_missionItem._frameFact, &Fact::valueChanged, this, &SimpleMissionItem::_sendFrameChanged); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Sequence number is kept in mission iteem, so we need to propagate signal up as well
|
|
|
|
// Sequence number is kept in mission iteem, so we need to propagate signal up as well
|
|
|
|
connect(&_missionItem, &MissionItem::sequenceNumberChanged, this, &SimpleMissionItem::sequenceNumberChanged); |
|
|
|
connect(&_missionItem, &MissionItem::sequenceNumberChanged, this, &SimpleMissionItem::sequenceNumberChanged); |
|
|
@ -260,6 +255,7 @@ void SimpleMissionItem::_setupMetaData(void) |
|
|
|
|
|
|
|
|
|
|
|
_missionItem._commandFact.setMetaData(_commandMetaData); |
|
|
|
_missionItem._commandFact.setMetaData(_commandMetaData); |
|
|
|
_missionItem._frameFact.setMetaData(_frameMetaData); |
|
|
|
_missionItem._frameFact.setMetaData(_frameMetaData); |
|
|
|
|
|
|
|
_altitudeFact.setMetaData(_altitudeMetaData); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SimpleMissionItem::~SimpleMissionItem() |
|
|
|
SimpleMissionItem::~SimpleMissionItem() |
|
|
@ -276,6 +272,14 @@ void SimpleMissionItem::save(QJsonArray& missionItems) |
|
|
|
MissionItem* item = items[i]; |
|
|
|
MissionItem* item = items[i]; |
|
|
|
QJsonObject saveObject; |
|
|
|
QJsonObject saveObject; |
|
|
|
item->save(saveObject); |
|
|
|
item->save(saveObject); |
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
|
|
// This is the main simple item, save the alt/terrain data
|
|
|
|
|
|
|
|
if (specifiesCoordinate()) { |
|
|
|
|
|
|
|
saveObject[_jsonAltitudeModeKey] = _altitudeMode; |
|
|
|
|
|
|
|
saveObject[_jsonAltitudeKey] = _altitudeFact.rawValue().toDouble(); |
|
|
|
|
|
|
|
saveObject[_jsonAMSLAltAboveTerrainKey] = _amslAltAboveTerrainFact.rawValue().toDouble(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
missionItems.append(saveObject); |
|
|
|
missionItems.append(saveObject); |
|
|
|
item->deleteLater(); |
|
|
|
item->deleteLater(); |
|
|
|
} |
|
|
|
} |
|
|
@ -285,6 +289,11 @@ bool SimpleMissionItem::load(QTextStream &loadStream) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool success; |
|
|
|
bool success; |
|
|
|
if ((success = _missionItem.load(loadStream))) { |
|
|
|
if ((success = _missionItem.load(loadStream))) { |
|
|
|
|
|
|
|
if (specifiesCoordinate()) { |
|
|
|
|
|
|
|
_altitudeMode = _missionItem.relativeAltitude() ? AltitudeRelative : AltitudeAMSL; |
|
|
|
|
|
|
|
_altitudeFact.setRawValue(_missionItem._param7Fact.rawValue()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
} |
|
|
|
_updateOptionalSections(); |
|
|
|
_updateOptionalSections(); |
|
|
|
} |
|
|
|
} |
|
|
|
return success; |
|
|
|
return success; |
|
|
@ -292,11 +301,34 @@ bool SimpleMissionItem::load(QTextStream &loadStream) |
|
|
|
|
|
|
|
|
|
|
|
bool SimpleMissionItem::load(const QJsonObject& json, int sequenceNumber, QString& errorString) |
|
|
|
bool SimpleMissionItem::load(const QJsonObject& json, int sequenceNumber, QString& errorString) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool success; |
|
|
|
if (!_missionItem.load(json, sequenceNumber, errorString)) { |
|
|
|
if ((success = _missionItem.load(json, sequenceNumber, errorString))) { |
|
|
|
return false; |
|
|
|
_updateOptionalSections(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return success; |
|
|
|
|
|
|
|
|
|
|
|
if (specifiesCoordinate()) { |
|
|
|
|
|
|
|
if (json.contains(_jsonAltitudeModeKey) || json.contains(_jsonAltitudeKey) || json.contains(_jsonAMSLAltAboveTerrainKey)) { |
|
|
|
|
|
|
|
QList<JsonHelper::KeyValidateInfo> keyInfoList = { |
|
|
|
|
|
|
|
{ _jsonAltitudeModeKey, QJsonValue::Double, true }, |
|
|
|
|
|
|
|
{ _jsonAltitudeKey, QJsonValue::Double, true }, |
|
|
|
|
|
|
|
{ _jsonAMSLAltAboveTerrainKey, QJsonValue::Double, true }, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
if (!JsonHelper::validateKeys(json, keyInfoList, errorString)) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_altitudeMode = (AltitudeMode)json[_jsonAltitudeModeKey].toDouble(); |
|
|
|
|
|
|
|
_altitudeFact.setRawValue(JsonHelper::possibleNaNJsonValue(json[_jsonAltitudeKey])); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(JsonHelper::possibleNaNJsonValue(json[_jsonAltitudeKey])); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
_altitudeMode = _missionItem.relativeAltitude() ? AltitudeRelative : AltitudeAMSL; |
|
|
|
|
|
|
|
_altitudeFact.setRawValue(_missionItem._param7Fact.rawValue()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_updateOptionalSections(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool SimpleMissionItem::isStandaloneCoordinate(void) const |
|
|
|
bool SimpleMissionItem::isStandaloneCoordinate(void) const |
|
|
@ -429,12 +461,6 @@ void SimpleMissionItem::_rebuildTextFieldFacts(void) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (uiInfo->specifiesCoordinate() || uiInfo->specifiesAltitudeOnly()) { |
|
|
|
|
|
|
|
_missionItem._param7Fact._setName("Altitude"); |
|
|
|
|
|
|
|
_missionItem._param7Fact.setMetaData(_altitudeMetaData); |
|
|
|
|
|
|
|
_textFieldFacts.append(&_missionItem._param7Fact); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_ignoreDirtyChangeSignals = false; |
|
|
|
_ignoreDirtyChangeSignals = false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -489,15 +515,9 @@ void SimpleMissionItem::_rebuildNaNFacts(void) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_rebuildCheckboxFacts(void) |
|
|
|
bool SimpleMissionItem::specifiesAltitude(void) const |
|
|
|
{ |
|
|
|
{ |
|
|
|
_checkboxFacts.clear(); |
|
|
|
return specifiesCoordinate() || specifiesAltitudeOnly(); |
|
|
|
|
|
|
|
|
|
|
|
if (rawEdit()) { |
|
|
|
|
|
|
|
_checkboxFacts.append(&_missionItem._autoContinueFact); |
|
|
|
|
|
|
|
} else if ((specifiesCoordinate() || specifiesAltitudeOnly()) && !_homePositionSpecialCase) { |
|
|
|
|
|
|
|
_checkboxFacts.append(&_altitudeRelativeToHomeFact); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_rebuildComboBoxFacts(void) |
|
|
|
void SimpleMissionItem::_rebuildComboBoxFacts(void) |
|
|
@ -541,7 +561,6 @@ void SimpleMissionItem::_rebuildFacts(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
_rebuildTextFieldFacts(); |
|
|
|
_rebuildTextFieldFacts(); |
|
|
|
_rebuildNaNFacts(); |
|
|
|
_rebuildNaNFacts(); |
|
|
|
_rebuildCheckboxFacts(); |
|
|
|
|
|
|
|
_rebuildComboBoxFacts(); |
|
|
|
_rebuildComboBoxFacts(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -597,7 +616,7 @@ void SimpleMissionItem::setDirty(bool dirty) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_setDirtyFromSignal(void) |
|
|
|
void SimpleMissionItem::_setDirty(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!_ignoreDirtyChangeSignals) { |
|
|
|
if (!_ignoreDirtyChangeSignals) { |
|
|
|
setDirty(true); |
|
|
|
setDirty(true); |
|
|
@ -609,30 +628,76 @@ void SimpleMissionItem::_sendCoordinateChanged(void) |
|
|
|
emit coordinateChanged(coordinate()); |
|
|
|
emit coordinateChanged(coordinate()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_syncAltitudeRelativeToHomeToFrame(const QVariant& value) |
|
|
|
void SimpleMissionItem::_altitudeModeChanged(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!_syncingAltitudeRelativeToHomeAndFrame) { |
|
|
|
switch (_altitudeMode) { |
|
|
|
_syncingAltitudeRelativeToHomeAndFrame = true; |
|
|
|
case AltitudeAboveTerrain: |
|
|
|
_missionItem.setFrame(value.toBool() ? MAV_FRAME_GLOBAL_RELATIVE_ALT : MAV_FRAME_GLOBAL); |
|
|
|
// Terrain altitudes are AMSL
|
|
|
|
emit coordinateHasRelativeAltitudeChanged(value.toBool()); |
|
|
|
_missionItem.setFrame(MAV_FRAME_GLOBAL); |
|
|
|
_syncingAltitudeRelativeToHomeAndFrame = false; |
|
|
|
// Clear any old values
|
|
|
|
|
|
|
|
_missionItem._param7Fact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
_altitudeChanged(); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case AltitudeAMSL: |
|
|
|
|
|
|
|
_missionItem.setFrame(MAV_FRAME_GLOBAL); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case AltitudeRelative: |
|
|
|
|
|
|
|
_missionItem.setFrame(MAV_FRAME_GLOBAL_RELATIVE_ALT); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
emit coordinateHasRelativeAltitudeChanged(_altitudeMode == AltitudeRelative); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_altitudeChanged(void) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!specifiesAltitude()) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_altitudeMode == AltitudeAboveTerrain) { |
|
|
|
|
|
|
|
_terrainAltChanged(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
_missionItem._param7Fact.setRawValue(_altitudeFact.rawValue()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_syncFrameToAltitudeRelativeToHome(void) |
|
|
|
void SimpleMissionItem::_terrainAltChanged(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!_syncingAltitudeRelativeToHomeAndFrame) { |
|
|
|
if (!specifiesAltitude() || _altitudeMode != AltitudeAboveTerrain) { |
|
|
|
_syncingAltitudeRelativeToHomeAndFrame = true; |
|
|
|
// We don't need terrain data
|
|
|
|
_altitudeRelativeToHomeFact.setRawValue(relativeAltitude()); |
|
|
|
return; |
|
|
|
emit coordinateHasRelativeAltitudeChanged(_altitudeRelativeToHomeFact.rawValue().toBool()); |
|
|
|
|
|
|
|
_syncingAltitudeRelativeToHomeAndFrame = false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!qIsNaN(_amslAltAboveTerrainFact.rawValue().toDouble())) { |
|
|
|
|
|
|
|
// We already have terrain values set. Don't do it again to prevent dirty bit changing.
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (qIsNaN(terrainAltitude())) { |
|
|
|
|
|
|
|
// Set NaNs to signal we are waiting on terrain data
|
|
|
|
|
|
|
|
_missionItem._param7Fact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
double aboveTerrain = terrainAltitude() + _altitudeFact.rawValue().toDouble(); |
|
|
|
|
|
|
|
_missionItem._param7Fact.setRawValue(aboveTerrain); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(aboveTerrain); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SimpleMissionItem::readyForSave(void) const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return !specifiesAltitude() || !qIsNaN(_missionItem._param7Fact.rawValue().toDouble()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::setDefaultsForCommand(void) |
|
|
|
void SimpleMissionItem::setDefaultsForCommand(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// We set these global defaults first, then if there are param defaults they will get reset
|
|
|
|
// We set these global defaults first, then if there are param defaults they will get reset
|
|
|
|
_missionItem.setParam7(qgcApp()->toolbox()->settingsManager()->appSettings()->defaultMissionItemAltitude()->rawValue().toDouble()); |
|
|
|
_altitudeMode = AltitudeRelative; |
|
|
|
|
|
|
|
double defaultAlt = qgcApp()->toolbox()->settingsManager()->appSettings()->defaultMissionItemAltitude()->rawValue().toDouble(); |
|
|
|
|
|
|
|
_altitudeFact.setRawValue(defaultAlt); |
|
|
|
|
|
|
|
_missionItem._param7Fact.setRawValue(defaultAlt); |
|
|
|
|
|
|
|
_amslAltAboveTerrainFact.setRawValue(qQNaN()); |
|
|
|
|
|
|
|
|
|
|
|
MAV_CMD command = (MAV_CMD)this->command(); |
|
|
|
MAV_CMD command = (MAV_CMD)this->command(); |
|
|
|
const MissionCommandUIInfo* uiInfo = _commandTree->getUIInfo(_vehicle, command); |
|
|
|
const MissionCommandUIInfo* uiInfo = _commandTree->getUIInfo(_vehicle, command); |
|
|
@ -667,11 +732,6 @@ void SimpleMissionItem::setDefaultsForCommand(void) |
|
|
|
setRawEdit(false); |
|
|
|
setRawEdit(false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_sendFrameChanged(void) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
emit frameChanged(_missionItem.frame()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::_sendCommandChanged(void) |
|
|
|
void SimpleMissionItem::_sendCommandChanged(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
emit commandChanged(command()); |
|
|
|
emit commandChanged(command()); |
|
|
@ -846,3 +906,11 @@ void SimpleMissionItem::setMissionFlightStatus(MissionController::MissionFlightS |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SimpleMissionItem::setAltitudeMode(AltitudeMode altitudeMode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (altitudeMode != _altitudeMode) { |
|
|
|
|
|
|
|
_altitudeMode = altitudeMode; |
|
|
|
|
|
|
|
emit altitudeModeChanged(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|