Commit b15eba77 authored by Don Gagne's avatar Don Gagne

New V2 mission file format

parent d663c932
...@@ -97,10 +97,12 @@ void JsonHelper::saveGeoCoordinate(const QGeoCoordinate& coordinate, ...@@ -97,10 +97,12 @@ void JsonHelper::saveGeoCoordinate(const QGeoCoordinate& coordinate,
bool JsonHelper::validateKeyTypes(const QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types, QString& errorString) bool JsonHelper::validateKeyTypes(const QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types, QString& errorString)
{ {
for (int i=0; i<keys.count(); i++) { for (int i=0; i<types.count(); i++) {
if (jsonObject.contains(keys[i])) { QString valueKey = keys[i];
if (jsonObject.value(keys[i]).type() != types[i]) { if (jsonObject.contains(valueKey)) {
errorString = QObject::tr("Incorrect type key:type:expected %1 %2 %3").arg(keys[i]).arg(jsonObject.value(keys[i]).type()).arg(types[i]); const QJsonValue& jsonValue = jsonObject[valueKey];
if (jsonValue.type() != types[i]) {
errorString = QObject::tr("Incorrect value type - key:type:expected %1:%2:%3").arg(valueKey).arg(_jsonValueTypeToString(jsonValue.type())).arg(_jsonValueTypeToString(types[i]));
return false; return false;
} }
} }
...@@ -141,14 +143,13 @@ bool JsonHelper::isJsonFile(const QByteArray& bytes, QJsonDocument& jsonDoc) ...@@ -141,14 +143,13 @@ bool JsonHelper::isJsonFile(const QByteArray& bytes, QJsonDocument& jsonDoc)
bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject, bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject,
const QString& expectedFileType, const QString& expectedFileType,
int supportedMajorVersion, int minSupportedVersion,
int supportedMinorVersion, int maxSupportedVersion,
int& fileMajorVersion, int& version,
int& fileMinorVersion,
QString& errorString) QString& errorString)
{ {
// Check for required keys // Check for required keys
QStringList requiredKeys = { jsonVersionKey, jsonFileTypeKey }; QStringList requiredKeys = { jsonFileTypeKey, jsonGroundStationKey, jsonVersionKey };
if (!validateRequiredKeys(jsonObject, requiredKeys, errorString)) { if (!validateRequiredKeys(jsonObject, requiredKeys, errorString)) {
return false; return false;
} }
...@@ -166,25 +167,24 @@ bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject, ...@@ -166,25 +167,24 @@ bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject,
return false; return false;
} }
// Parse and validate version // Check version - support both old style v1 string and new style integer
QString incorrectVersionFormatErrorString = QObject::tr("Incorrectly formatted version value"); QJsonValue versionValue = jsonObject[jsonVersionKey];
QRegularExpression versionRegExp("(\\d+).(\\d+)"); if (versionValue.type() == QJsonValue::String && versionValue.toString() == QStringLiteral("1.0")) {
QRegularExpressionMatch match = versionRegExp.match(jsonObject[jsonVersionKey].toString()); version = 1;
if (!match.hasMatch()) { } else {
errorString = incorrectVersionFormatErrorString; if (versionValue.type() != QJsonValue::Double) {
return false; errorString = QObject::tr("Incorrect type for version value, must be integer");
return false;
}
version = versionValue.toInt();
} }
QStringList versionParts = match.capturedTexts(); if (version < minSupportedVersion) {
if (versionParts.count() != 3) { errorString = QObject::tr("File version %1 is no longer supported").arg(version);
errorString = incorrectVersionFormatErrorString;
return false; return false;
} }
if (version > maxSupportedVersion) {
fileMajorVersion = versionParts[0].toInt(); errorString = QObject::tr("File version %1 is newer than current supported version %2").arg(version).arg(maxSupportedVersion);
fileMinorVersion = versionParts[0].toInt();
if (fileMajorVersion > supportedMajorVersion || (fileMajorVersion == supportedMajorVersion && fileMinorVersion > supportedMinorVersion)) {
errorString = QObject::tr("File version (%1.%2) is larger than current supported version (%3.%4)").arg(fileMajorVersion).arg(fileMinorVersion).arg(supportedMajorVersion).arg(supportedMinorVersion);
return false; return false;
} }
...@@ -284,3 +284,27 @@ bool JsonHelper::validateKeys(const QJsonObject& jsonObject, const QList<JsonHel ...@@ -284,3 +284,27 @@ bool JsonHelper::validateKeys(const QJsonObject& jsonObject, const QList<JsonHel
} }
return validateKeyTypes(jsonObject, keyList, typeList, errorString); return validateKeyTypes(jsonObject, keyList, typeList, errorString);
} }
QString JsonHelper::_jsonValueTypeToString(QJsonValue::Type type)
{
const struct {
QJsonValue::Type type;
const char* string;
} rgTypeToString[] = {
{ QJsonValue::Null, "NULL" },
{ QJsonValue::Bool, "Bool" },
{ QJsonValue::Double, "Double" },
{ QJsonValue::String, "String" },
{ QJsonValue::Array, "Array" },
{ QJsonValue::Object, "Object" },
{ QJsonValue::Undefined, "Undefined" },
};
for (size_t i=0; i<sizeof(rgTypeToString)/sizeof(rgTypeToString[0]); i++) {
if (type == rgTypeToString[i].type) {
return rgTypeToString[i].string;
}
}
return QObject::tr("Unknown type: %1").arg(type);
}
...@@ -25,13 +25,13 @@ public: ...@@ -25,13 +25,13 @@ public:
/// Validates the standard parts of a QGC json file: /// Validates the standard parts of a QGC json file:
/// jsonFileTypeKey - Required and checked to be equal to expectedFileType /// jsonFileTypeKey - Required and checked to be equal to expectedFileType
/// jsonVersionKey - Required and checked to be below supportedMajorVersion, supportedMinorVersion /// jsonVersionKey - Required and checked to be below supportedMajorVersion, supportedMinorVersion
/// jsonGroundStationKey - Required and checked to be string type
/// @return false: validation failed /// @return false: validation failed
static bool validateQGCJsonFile(const QJsonObject& jsonObject, ///< top level json object in file static bool validateQGCJsonFile(const QJsonObject& jsonObject, ///< root json object
const QString& expectedFileType, ///< correct file type for file const QString& expectedFileType, ///< correct file type for file
int supportedMajorVersion, ///< maximum supported major version int minSupportedVersion, ///< minimum supported version
int supportedMinorVersion, ///< maximum supported minor version int maxSupportedVersion, ///< maximum supported major version
int &fileMajorVersion, ///< returned file major version int &version, ///< returned file version
int &fileMinorVersion, ///< returned file minor version
QString& errorString); ///< returned error string if validation fails QString& errorString); ///< returned error string if validation fails
static bool validateRequiredKeys(const QJsonObject& jsonObject, const QStringList& keys, QString& errorString); static bool validateRequiredKeys(const QJsonObject& jsonObject, const QStringList& keys, QString& errorString);
...@@ -85,6 +85,8 @@ public: ...@@ -85,6 +85,8 @@ public:
static const char* jsonFileTypeKey; static const char* jsonFileTypeKey;
private: private:
static QString _jsonValueTypeToString(QJsonValue::Type type);
static const char* _enumStringsJsonKey; static const char* _enumStringsJsonKey;
static const char* _enumValuesJsonKey; static const char* _enumValuesJsonKey;
}; };
......
...@@ -7,9 +7,10 @@ ...@@ -7,9 +7,10 @@
* *
****************************************************************************/ ****************************************************************************/
#include "ComplexMissionItem.h" #include "ComplexMissionItem.h"
const char* ComplexMissionItem::jsonComplexItemTypeKey = "complexItemType";
ComplexMissionItem::ComplexMissionItem(Vehicle* vehicle, QObject* parent) ComplexMissionItem::ComplexMissionItem(Vehicle* vehicle, QObject* parent)
: VisualMissionItem(vehicle, parent) : VisualMissionItem(vehicle, parent)
{ {
......
...@@ -36,15 +36,19 @@ public: ...@@ -36,15 +36,19 @@ public:
/// Load the complex mission item from Json /// Load the complex mission item from Json
/// @param complexObject Complex mission item json object /// @param complexObject Complex mission item json object
/// @param sequenceNumber Sequence number for first MISSION_ITEM in survey
/// @param[out] errorString Error if load fails /// @param[out] errorString Error if load fails
/// @return true: load success, false: load failed, errorString set /// @return true: load success, false: load failed, errorString set
virtual bool load(const QJsonObject& complexObject, QString& errorString) = 0; virtual bool load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString) = 0;
/// Get the point of complex mission item furthest away from a coordinate /// Get the point of complex mission item furthest away from a coordinate
/// @param other QGeoCoordinate to which distance is calculated /// @param other QGeoCoordinate to which distance is calculated
/// @return the greatest distance from any point of the complex item to some coordinate /// @return the greatest distance from any point of the complex item to some coordinate
virtual double greatestDistanceTo(const QGeoCoordinate &other) const = 0; virtual double greatestDistanceTo(const QGeoCoordinate &other) const = 0;
/// This mission item attribute specifies the type of the complex item.
static const char* jsonComplexItemTypeKey;
signals: signals:
void lastSequenceNumberChanged (int lastSequenceNumber); void lastSequenceNumberChanged (int lastSequenceNumber);
void complexDistanceChanged (double complexDistance); void complexDistanceChanged (double complexDistance);
......
...@@ -103,27 +103,13 @@ bool GeoFenceController::_loadJsonFile(QJsonDocument& jsonDoc, QString& errorStr ...@@ -103,27 +103,13 @@ bool GeoFenceController::_loadJsonFile(QJsonDocument& jsonDoc, QString& errorStr
{ {
QJsonObject json = jsonDoc.object(); QJsonObject json = jsonDoc.object();
// Check for required keys int fileVersion;
QStringList requiredKeys; if (!JsonHelper::validateQGCJsonFile(json,
requiredKeys << JsonHelper::jsonVersionKey << JsonHelper::jsonFileTypeKey; _jsonFileTypeValue, // expected file type
if (!JsonHelper::validateRequiredKeys(json, requiredKeys, errorString)) { 1, // minimum supported version
return false; 1, // maximum supported version
} fileVersion,
errorString)) {
#if 0
// Validate base key types
QStringList keyList;
QList<QJsonValue::Type> typeList;
keyList << jsonSimpleItemsKey << _jsonVersionKey << _jsonGroundStationKey << _jsonMavAutopilotKey << _jsonComplexItemsKey << _jsonPlannedHomePositionKey;
typeList << QJsonValue::Array << QJsonValue::String << QJsonValue::String << QJsonValue::Double << QJsonValue::Array << QJsonValue::Object;
if (!JsonHelper::validateKeyTypes(json, keyList, typeList, errorString)) {
return false;
}
#endif
// Version check
if (json[JsonHelper::jsonVersionKey].toString() != "1.0") {
errorString = QStringLiteral("QGroundControl does not support this file version");
return false; return false;
} }
...@@ -269,7 +255,7 @@ void GeoFenceController::saveToFile(const QString& filename) ...@@ -269,7 +255,7 @@ void GeoFenceController::saveToFile(const QString& filename)
QJsonObject fenceFileObject; // top level json object QJsonObject fenceFileObject; // top level json object
fenceFileObject[JsonHelper::jsonFileTypeKey] = _jsonFileTypeValue; fenceFileObject[JsonHelper::jsonFileTypeKey] = _jsonFileTypeValue;
fenceFileObject[JsonHelper::jsonVersionKey] = QStringLiteral("1.0"); fenceFileObject[JsonHelper::jsonVersionKey] = 1;
fenceFileObject[JsonHelper::jsonGroundStationKey] = JsonHelper::jsonGroundStationValue; fenceFileObject[JsonHelper::jsonGroundStationKey] = JsonHelper::jsonGroundStationValue;
QStringList paramNames; QStringList paramNames;
......
This diff is collapsed.
...@@ -88,7 +88,6 @@ public: ...@@ -88,7 +88,6 @@ public:
void setCruiseDistance (double cruiseDistance ); void setCruiseDistance (double cruiseDistance );
void setHoverDistance (double hoverDistance ); void setHoverDistance (double hoverDistance );
static const char* jsonSimpleItemsKey; ///< Key for simple items in a json file
signals: signals:
void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition); void plannedHomePositionChanged(QGeoCoordinate plannedHomePosition);
...@@ -129,6 +128,8 @@ private: ...@@ -129,6 +128,8 @@ private:
double _normalizeLat(double lat); double _normalizeLat(double lat);
double _normalizeLon(double lon); double _normalizeLon(double lon);
bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString); bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadJsonMissionFileV1(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadJsonMissionFileV2(const QJsonObject& json, QmlObjectListModel* visualItems, QmlObjectListModel* complexItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString); bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* visualItems, QString& errorString);
int _nextSequenceNumber(void); int _nextSequenceNumber(void);
...@@ -150,9 +151,17 @@ private: ...@@ -150,9 +151,17 @@ private:
double _hoverDistance; double _hoverDistance;
static const char* _settingsGroup; static const char* _settingsGroup;
static const char* _jsonFileTypeValue;
static const char* _jsonFirmwareTypeKey;
static const char* _jsonItemsKey;
static const char* _jsonPlannedHomePositionKey;
static const char* _jsonParamsKey;
// Deprecated V1 format keys
static const char* _jsonMavAutopilotKey; static const char* _jsonMavAutopilotKey;
static const char* _jsonComplexItemsKey; static const char* _jsonComplexItemsKey;
static const char* _jsonPlannedHomePositionKey;
static const int _missionFileVersion;
}; };
#endif #endif
...@@ -15,22 +15,25 @@ ...@@ -15,22 +15,25 @@
#include "FirmwarePluginManager.h" #include "FirmwarePluginManager.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "JsonHelper.h" #include "JsonHelper.h"
#include "VisualMissionItem.h"
const char* MissionItem::_itemType = "missionItem";
const char* MissionItem::_jsonTypeKey = "type";
const char* MissionItem::_jsonIdKey = "id";
const char* MissionItem::_jsonFrameKey = "frame"; const char* MissionItem::_jsonFrameKey = "frame";
const char* MissionItem::_jsonCommandKey = "command"; const char* MissionItem::_jsonCommandKey = "command";
const char* MissionItem::_jsonAutoContinueKey = "autoContinue";
const char* MissionItem::_jsonCoordinateKey = "coordinate";
const char* MissionItem::_jsonParamsKey = "params";
const char* MissionItem::_jsonDoJumpIdKey = "doJumpId";
// Deprecated V1 format keys
const char* MissionItem::_jsonParam1Key = "param1"; const char* MissionItem::_jsonParam1Key = "param1";
const char* MissionItem::_jsonParam2Key = "param2"; const char* MissionItem::_jsonParam2Key = "param2";
const char* MissionItem::_jsonParam3Key = "param3"; const char* MissionItem::_jsonParam3Key = "param3";
const char* MissionItem::_jsonParam4Key = "param4"; const char* MissionItem::_jsonParam4Key = "param4";
const char* MissionItem::_jsonAutoContinueKey = "autoContinue";
const char* MissionItem::_jsonCoordinateKey = "coordinate";
MissionItem::MissionItem(QObject* parent) MissionItem::MissionItem(QObject* parent)
: QObject(parent) : QObject(parent)
, _sequenceNumber(0) , _sequenceNumber(0)
, _doJumpId(-1)
, _isCurrentItem(false) , _isCurrentItem(false)
, _autoContinueFact (0, "AutoContinue", FactMetaData::valueTypeUint32) , _autoContinueFact (0, "AutoContinue", FactMetaData::valueTypeUint32)
, _commandFact (0, "", FactMetaData::valueTypeUint32) , _commandFact (0, "", FactMetaData::valueTypeUint32)
...@@ -65,6 +68,7 @@ MissionItem::MissionItem(int sequenceNumber, ...@@ -65,6 +68,7 @@ MissionItem::MissionItem(int sequenceNumber,
QObject* parent) QObject* parent)
: QObject(parent) : QObject(parent)
, _sequenceNumber(sequenceNumber) , _sequenceNumber(sequenceNumber)
, _doJumpId(-1)
, _isCurrentItem(isCurrentItem) , _isCurrentItem(isCurrentItem)
, _commandFact (0, "", FactMetaData::valueTypeUint32) , _commandFact (0, "", FactMetaData::valueTypeUint32)
, _frameFact (0, "", FactMetaData::valueTypeUint32) , _frameFact (0, "", FactMetaData::valueTypeUint32)
...@@ -96,6 +100,7 @@ MissionItem::MissionItem(int sequenceNumber, ...@@ -96,6 +100,7 @@ MissionItem::MissionItem(int sequenceNumber,
MissionItem::MissionItem(const MissionItem& other, QObject* parent) MissionItem::MissionItem(const MissionItem& other, QObject* parent)
: QObject(parent) : QObject(parent)
, _sequenceNumber(0) , _sequenceNumber(0)
, _doJumpId(-1)
, _isCurrentItem(false) , _isCurrentItem(false)
, _commandFact (0, "", FactMetaData::valueTypeUint32) , _commandFact (0, "", FactMetaData::valueTypeUint32)
, _frameFact (0, "", FactMetaData::valueTypeUint32) , _frameFact (0, "", FactMetaData::valueTypeUint32)
...@@ -116,6 +121,8 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent) ...@@ -116,6 +121,8 @@ MissionItem::MissionItem(const MissionItem& other, QObject* parent)
const MissionItem& MissionItem::operator=(const MissionItem& other) const MissionItem& MissionItem::operator=(const MissionItem& other)
{ {
_doJumpId = other._doJumpId;
setCommand(other.command()); setCommand(other.command());
setFrame(other.frame()); setFrame(other.frame());
setSequenceNumber(other._sequenceNumber); setSequenceNumber(other._sequenceNumber);
...@@ -138,19 +145,18 @@ MissionItem::~MissionItem() ...@@ -138,19 +145,18 @@ MissionItem::~MissionItem()
void MissionItem::save(QJsonObject& json) const void MissionItem::save(QJsonObject& json) const
{ {
json[_jsonTypeKey] = _itemType; json[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeSimpleItemValue;
json[_jsonIdKey] = sequenceNumber();
json[_jsonFrameKey] = frame(); json[_jsonFrameKey] = frame();
json[_jsonCommandKey] = command(); json[_jsonCommandKey] = command();
json[_jsonParam1Key] = param1();
json[_jsonParam2Key] = param2();
json[_jsonParam3Key] = param3();
json[_jsonParam4Key] = param4();
json[_jsonAutoContinueKey] = autoContinue(); json[_jsonAutoContinueKey] = autoContinue();
json[_jsonDoJumpIdKey] = _sequenceNumber;
QJsonArray rgParams = { param1(), param2(), param3(), param4() };
json[_jsonParamsKey] = rgParams;
QJsonArray coordinateArray; QJsonValue coordinateValue;
coordinateArray << param5() << param6() << param7(); JsonHelper::saveGeoCoordinate(QGeoCoordinate(param5(), param6(), param7()), true /* writeAltitude */, coordinateValue);
json[_jsonCoordinateKey] = coordinateArray; json[_jsonCoordinateKey] = coordinateValue;
} }
bool MissionItem::load(QTextStream &loadStream) bool MissionItem::load(QTextStream &loadStream)
...@@ -175,41 +181,98 @@ bool MissionItem::load(QTextStream &loadStream) ...@@ -175,41 +181,98 @@ bool MissionItem::load(QTextStream &loadStream)
return false; return false;
} }
bool MissionItem::load(const QJsonObject& json, QString& errorString) bool MissionItem::_convertJsonV1ToV2(const QJsonObject& json, QJsonObject& v2Json, QString& errorString)
{
// V1 format type = "missionItem", V2 format type = "MissionItem"
// V1 format has params in separate param[1-n] keys
// V2 format has params in params array
v2Json = json;
if (json.contains(_jsonParamsKey)) {
// Already V2 format
return true;
}
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ VisualMissionItem::jsonTypeKey, QJsonValue::String, true },
{ _jsonParam1Key, QJsonValue::Double, true },
{ _jsonParam2Key, QJsonValue::Double, true },
{ _jsonParam3Key, QJsonValue::Double, true },
{ _jsonParam4Key, QJsonValue::Double, true },
};
if (!JsonHelper::validateKeys(json, keyInfoList, errorString)) {
return false;
}
if (v2Json[VisualMissionItem::jsonTypeKey].toString() == QStringLiteral("missionItem")) {
v2Json[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeSimpleItemValue;
}
QJsonArray rgParams = { json[_jsonParam1Key].toDouble(), json[_jsonParam2Key].toDouble(), json[_jsonParam3Key].toDouble(), json[_jsonParam4Key].toDouble() };
v2Json[_jsonParamsKey] = rgParams;
v2Json.remove(_jsonParam1Key);
v2Json.remove(_jsonParam2Key);
v2Json.remove(_jsonParam3Key);
v2Json.remove(_jsonParam4Key);
return true;
}
bool MissionItem::load(const QJsonObject& json, int sequenceNumber, QString& errorString)
{ {
QStringList requiredKeys; QJsonObject v2Json;
if (!_convertJsonV1ToV2(json, v2Json, errorString)) {
return false;
}
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ VisualMissionItem::jsonTypeKey, QJsonValue::String, true },
{ _jsonFrameKey, QJsonValue::Double, true },
{ _jsonCommandKey, QJsonValue::Double, true },
{ _jsonParamsKey, QJsonValue::Array, true },
{ _jsonAutoContinueKey, QJsonValue::Bool, true },
{ _jsonCoordinateKey, QJsonValue::Array, true },
{ _jsonDoJumpIdKey, QJsonValue::Double, false },
};
if (!JsonHelper::validateKeys(v2Json, keyInfoList, errorString)) {
return false;
}
requiredKeys << _jsonTypeKey << _jsonIdKey << _jsonFrameKey << _jsonCommandKey << if (v2Json[VisualMissionItem::jsonTypeKey] != VisualMissionItem::jsonTypeSimpleItemValue) {
_jsonParam1Key << _jsonParam2Key << _jsonParam3Key << _jsonParam4Key << errorString = tr("Type found: %1 must be: %2").arg(v2Json[VisualMissionItem::jsonTypeKey].toString()).arg(VisualMissionItem::jsonTypeSimpleItemValue);
_jsonAutoContinueKey << _jsonCoordinateKey;
if (!JsonHelper::validateRequiredKeys(json, requiredKeys, errorString)) {
return false; return false;
} }
if (json[_jsonTypeKey] != _itemType) { QJsonArray rgParams = v2Json[_jsonParamsKey].toArray();
errorString = QString("type found: %1 must be: %2").arg(json[_jsonTypeKey].toString()).arg(_itemType); if (rgParams.count() != 4) {
errorString = tr("%1 key must contains 4 values").arg(_jsonParamsKey);
return false; return false;
} }
// Make sure to set these first since they can signal other changes // Make sure to set these first since they can signal other changes
setFrame((MAV_FRAME)json[_jsonFrameKey].toInt()); setFrame((MAV_FRAME)v2Json[_jsonFrameKey].toInt());
setCommand((MAV_CMD)json[_jsonCommandKey].toInt()); setCommand((MAV_CMD)v2Json[_jsonCommandKey].toInt());
QGeoCoordinate coordinate; QGeoCoordinate coordinate;
if (!JsonHelper::loadGeoCoordinate(json[_jsonCoordinateKey], true /* altitudeRequired */, coordinate, errorString)) { if (!JsonHelper::loadGeoCoordinate(v2Json[_jsonCoordinateKey], true /* altitudeRequired */, coordinate, errorString)) {
return false; return false;
} }
setParam5(coordinate.latitude()); setParam5(coordinate.latitude());
setParam6(coordinate.longitude()); setParam6(coordinate.longitude());
setParam7(coordinate.altitude()); setParam7(coordinate.altitude());
_doJumpId = -1;
if (v2Json.contains(_jsonDoJumpIdKey)) {
_doJumpId = v2Json[_jsonDoJumpIdKey].toInt();
}
setIsCurrentItem(false); setIsCurrentItem(false);
setSequenceNumber(json[_jsonIdKey].toInt()); setSequenceNumber(sequenceNumber);
setParam1(json[_jsonParam1Key].toDouble()); setAutoContinue(v2Json[_jsonAutoContinueKey].toBool());
setParam2(json[_jsonParam2Key].toDouble());
setParam3(json[_jsonParam3Key].toDouble()); setParam1(rgParams[0].toDouble());
setParam4(json[_jsonParam4Key].toDouble()); setParam2(rgParams[1].toDouble());
setAutoContinue(json[_jsonAutoContinueKey].toBool()); setParam3(rgParams[2].toDouble());
setParam4(rgParams[3].toDouble());
return true; return true;
} }
......
...@@ -74,6 +74,7 @@ public: ...@@ -74,6 +74,7 @@ public:
double param6 (void) const { return _param6Fact.rawValue().toDouble(); } double param6 (void) const { return _param6Fact.rawValue().toDouble(); }
double param7 (void) const { return _param7Fact.rawValue().toDouble(); } double param7 (void) const { return _param7Fact.rawValue().toDouble(); }
QGeoCoordinate coordinate (void) const; QGeoCoordinate coordinate (void) const;
int doJumpId (void) const { return _doJumpId; }
void setCommand (MAV_CMD command); void setCommand (MAV_CMD command);
void setSequenceNumber (int sequenceNumber); void setSequenceNumber (int sequenceNumber);
...@@ -91,7 +92,7 @@ public: ...@@ -91,7 +92,7 @@ public:
void save(QJsonObject& json) const; void save(QJsonObject& json) const;
bool load(QTextStream &loadStream); bool load(QTextStream &loadStream);
bool load(const QJsonObject& json, QString& errorString); bool load(const QJsonObject& json, int sequenceNumber, QString& errorString);
bool relativeAltitude(void) const { return frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; } bool relativeAltitude(void) const { return frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; }
...@@ -100,8 +101,11 @@ signals: ...@@ -100,8 +101,11 @@ signals:
void sequenceNumberChanged (int sequenceNumber); void sequenceNumberChanged (int sequenceNumber);
private: private:
int _sequenceNumber; bool _convertJsonV1ToV2(const QJsonObject& json, QJsonObject& v2Json, QString& errorString);
bool _isCurrentItem;
int _sequenceNumber;
int _doJumpId;
bool _isCurrentItem;
Fact _autoContinueFact; Fact _autoContinueFact;
Fact _commandFact; Fact _commandFact;
...@@ -115,17 +119,18 @@ private: ...@@ -115,17 +119,18 @@ private:
Fact _param7Fact; Fact _param7Fact;
// Keys for Json save // Keys for Json save
static const char* _itemType;
static const char* _jsonTypeKey;
static const char* _jsonIdKey;
static const char* _jsonFrameKey; static const char* _jsonFrameKey;
static const char* _jsonCommandKey; static const char* _jsonCommandKey;
static const char* _jsonAutoContinueKey;
static const char* _jsonCoordinateKey;
static const char* _jsonParamsKey;
static const char* _jsonDoJumpIdKey;
// Deprecated V1 format keys
static const char* _jsonParam1Key; static const char* _jsonParam1Key;
static const char* _jsonParam2Key; static const char* _jsonParam2Key;
static const char* _jsonParam3Key; static const char* _jsonParam3Key;
static const char* _jsonParam4Key; static const char* _jsonParam4Key;
static const char* _jsonAutoContinueKey;
static const char* _jsonCoordinateKey;
friend class SurveyMissionItem; friend class SurveyMissionItem;
friend class SimpleMissionItem; friend class SimpleMissionItem;
......
This diff is collapsed.
...@@ -29,12 +29,15 @@ private slots: ...@@ -29,12 +29,15 @@ private slots:
void _testFactSignals(void); void _testFactSignals(void);
void _testLoadFromStream(void); void _testLoadFromStream(void);
void _testSimpleLoadFromStream(void); void _testSimpleLoadFromStream(void);
void _testLoadFromJson(void); void _testLoadFromJsonV1(void);
void _testLoadFromJsonV2(void);
void _testSimpleLoadFromJson(void); void _testSimpleLoadFromJson(void);
void _testSaveToJson(void); void _testSaveToJson(void);
private: private:
void _checkExpectedMissionItem(const MissionItem& missionItem); void _checkExpectedMissionItem(const MissionItem& missionItem);
int _seq = 10;
}; };
#endif #endif
...@@ -75,8 +75,13 @@ bool RallyPointController::_loadJsonFile(QJsonDocument& jsonDoc, QString& errorS ...@@ -75,8 +75,13 @@ bool RallyPointController::_loadJsonFile(QJsonDocument& jsonDoc, QString& errorS
{ {
QJsonObject json = jsonDoc.object(); QJsonObject json = jsonDoc.object();
int fileMajorVersion, fileMinorVersion; int fileVersion;
if (!JsonHelper::validateQGCJsonFile(json, _jsonFileTypeValue, 1 /* supportedMajorVersion */, 0 /* supportedMinorVersion */, fileMajorVersion, fileMinorVersion, errorString)) { if (!JsonHelper::validateQGCJsonFile(json,
_jsonFileTypeValue, // expected file type
1, // minimum supported version
1, // maximum supported version
fileVersion,
errorString)) {
return false; return false;
} }
...@@ -166,7 +171,7 @@ void RallyPointController::saveToFile(const QString& filename) ...@@ -166,7 +171,7 @@ void RallyPointController::saveToFile(const QString& filename)
QJsonObject jsonObject; QJsonObject jsonObject;
jsonObject[JsonHelper::jsonFileTypeKey] = _jsonFileTypeValue; jsonObject[JsonHelper::jsonFileTypeKey] = _jsonFileTypeValue;
jsonObject[JsonHelper::jsonVersionKey] = QStringLiteral("1.0"); jsonObject[JsonHelper::jsonVersionKey] = 1;
jsonObject[JsonHelper::jsonGroundStationKey] = JsonHelper::jsonGroundStationValue; jsonObject[JsonHelper::jsonGroundStationKey] = JsonHelper::jsonGroundStationValue;
QJsonArray rgPoints; QJsonArray rgPoints;
......
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
#include "MissionCommandTree.h" #include "MissionCommandTree.h"
#include "MissionCommandUIInfo.h" #include "MissionCommandUIInfo.h"
const double SimpleMissionItem::defaultAltitude = 50.0; const double SimpleMissionItem::defaultAltitude = 50.0;
FactMetaData* SimpleMissionItem::_altitudeMetaData = NULL; FactMetaData* SimpleMissionItem::_altitudeMetaData = NULL;
FactMetaData* SimpleMissionItem::_commandMetaData = NULL; FactMetaData* SimpleMissionItem::_commandMetaData = NULL;
FactMetaData* SimpleMissionItem::_defaultParamMetaData = NULL; FactMetaData* SimpleMissionItem::_defaultParamMetaData = NULL;
FactMetaData* SimpleMissionItem::_frameMetaData = NULL; FactMetaData* SimpleMissionItem::_frameMetaData = NULL;
FactMetaData* SimpleMissionItem::_latitudeMetaData = NULL; FactMetaData* SimpleMissionItem::_latitudeMetaData = NULL;
FactMetaData* SimpleMissionItem::_longitudeMetaData = NULL; FactMetaData* SimpleMissionItem::_longitudeMetaData = NULL;
struct EnumInfo_s { struct EnumInfo_s {
const char * label; const char * label;
...@@ -248,9 +248,9 @@ bool SimpleMissionItem::load(QTextStream &loadStream) ...@@ -248,9 +248,9 @@ bool SimpleMissionItem::load(QTextStream &loadStream)
return _missionItem.load(loadStream); return _missionItem.load(loadStream);
} }
bool SimpleMissionItem::load(const QJsonObject& json, QString& errorString) bool SimpleMissionItem::load(const QJsonObject& json, int sequenceNumber, QString& errorString)
{ {
return _missionItem.load(json, errorString); return _missionItem.load(json, sequenceNumber, errorString);
} }
bool SimpleMissionItem::isStandaloneCoordinate(void) const bool SimpleMissionItem::isStandaloneCoordinate(void) const
......
...@@ -71,7 +71,7 @@ public: ...@@ -71,7 +71,7 @@ public:
void setDistance (double distance); void setDistance (double distance);
bool load(QTextStream &loadStream); bool load(QTextStream &loadStream);
bool load(const QJsonObject& json, QString& errorString); bool load(const QJsonObject& json, int sequenceNumber, QString& errorString);
bool relativeAltitude(void) { return _missionItem.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; } bool relativeAltitude(void) { return _missionItem.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT; }
......
This diff is collapsed.
...@@ -78,7 +78,7 @@ public: ...@@ -78,7 +78,7 @@ public:
double complexDistance (void) const final { return _surveyDistance; } double complexDistance (void) const final { return _surveyDistance; }
int lastSequenceNumber (void) const final; int lastSequenceNumber (void) const final;
QmlObjectListModel* getMissionItems (void) const final; QmlObjectListModel* getMissionItems (void) const final;
bool load (const QJsonObject& complexObject, QString& errorString) final; bool load (const QJsonObject& complexObject, int sequenceNumber, QString& errorString) final;
double greatestDistanceTo (const QGeoCoordinate &other) const final; double greatestDistanceTo (const QGeoCoordinate &other) const final;
// Overrides from VisualMissionItem // Overrides from VisualMissionItem
...@@ -104,6 +104,8 @@ public: ...@@ -104,6 +104,8 @@ public:
void setTurnaroundDist (double dist) { _turnaroundDistFact.setRawValue(dist); } void setTurnaroundDist (double dist) { _turnaroundDistFact.setRawValue(dist); }
void save (QJsonObject& saveObject) const final; void save (QJsonObject& saveObject) const final;
static const char* jsonComplexItemTypeValue;
signals: signals:
void polygonPathChanged (void); void polygonPathChanged (void);
void altitudeChanged (double altitude); void altitudeChanged (double altitude);
...@@ -173,9 +175,7 @@ private: ...@@ -173,9 +175,7 @@ private:
static QMap<QString, FactMetaData*> _metaDataMap; static QMap<QString, FactMetaData*> _metaDataMap;
static const char* _jsonTypeKey;
static const char* _jsonPolygonObjectKey; static const char* _jsonPolygonObjectKey;
static const char* _jsonIdKey;
static const char* _jsonGridObjectKey; static const char* _jsonGridObjectKey;
static const char* _jsonGridAltitudeKey; static const char* _jsonGridAltitudeKey;
static const char* _jsonGridAltitudeRelativeKey; static const char* _jsonGridAltitudeRelativeKey;
...@@ -212,8 +212,6 @@ private: ...@@ -212,8 +212,6 @@ private:
static const char* _cameraResolutionWidthFactName; static const char* _cameraResolutionWidthFactName;
static const char* _cameraResolutionHeightFactName; static const char* _cameraResolutionHeightFactName;
static const char* _cameraFocalLengthFactName; static const char* _cameraFocalLengthFactName;
static const char* _complexType;
}; };
#endif #endif
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
#include "QGCApplication.h" #include "QGCApplication.h"
#include "JsonHelper.h" #include "JsonHelper.h"
const char* VisualMissionItem::jsonTypeKey = "type";
const char* VisualMissionItem::jsonTypeSimpleItemValue = "SimpleItem";
const char* VisualMissionItem::jsonTypeComplexItemValue = "ComplexItem";
VisualMissionItem::VisualMissionItem(Vehicle* vehicle, QObject* parent) VisualMissionItem::VisualMissionItem(Vehicle* vehicle, QObject* parent)
: QObject(parent) : QObject(parent)
, _vehicle(vehicle) , _vehicle(vehicle)
......
...@@ -123,6 +123,10 @@ public: ...@@ -123,6 +123,10 @@ public:
/// @param saveObject Save the item to this json object /// @param saveObject Save the item to this json object
virtual void save(QJsonObject& saveObject) const = 0; virtual void save(QJsonObject& saveObject) const = 0;
static const char* jsonTypeKey; ///< Json file attribute which specifies the item type
static const char* jsonTypeSimpleItemValue; ///< Item type is MISSION_ITEM
static const char* jsonTypeComplexItemValue; ///< Item type is Complex Item
signals: signals:
void altDifferenceChanged (double altDifference); void altDifferenceChanged (double altDifference);
void altPercentChanged (double altPercent); void altPercentChanged (double altPercent);
......
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