Browse Source
These Custom Actions are defined in a JSON file, and define MAVLink messages to send to the current active vehicle. These Custom Actions will be added to the Fly View.QGC4.4
6 changed files with 220 additions and 0 deletions
@ -0,0 +1,58 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* |
||||||
|
* (c) 2009-2023 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
* |
||||||
|
* QGroundControl is licensed according to the terms in the file |
||||||
|
* COPYING.md in the root of the source code directory. |
||||||
|
* |
||||||
|
****************************************************************************/ |
||||||
|
|
||||||
|
#include <QObject> |
||||||
|
|
||||||
|
#include "MAVLinkProtocol.h" |
||||||
|
#include "Vehicle.h" |
||||||
|
|
||||||
|
class CustomAction: public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
Q_PROPERTY(QString label READ label CONSTANT) |
||||||
|
|
||||||
|
|
||||||
|
public: |
||||||
|
CustomAction() { CustomAction("", MAV_CMD(0)); } // this is required for QML reflection
|
||||||
|
CustomAction( |
||||||
|
QString label, |
||||||
|
MAV_CMD mavCmd, |
||||||
|
MAV_COMPONENT compId = MAV_COMP_ID_AUTOPILOT1, |
||||||
|
float param1 = 0.0f, |
||||||
|
float param2 = 0.0f, |
||||||
|
float param3 = 0.0f, |
||||||
|
float param4 = 0.0f, |
||||||
|
float param5 = 0.0f, |
||||||
|
float param6 = 0.0f, |
||||||
|
float param7 = 0.0f |
||||||
|
): |
||||||
|
_label(label), |
||||||
|
_mavCmd(mavCmd), |
||||||
|
_compId(compId), |
||||||
|
_params{ param1, param2, param3, param4, param5, param6, param7 } |
||||||
|
{}; |
||||||
|
|
||||||
|
Q_INVOKABLE void sendTo(Vehicle* vehicle) { |
||||||
|
if (vehicle) { |
||||||
|
const bool showError = true; |
||||||
|
vehicle->sendMavCommand(_compId, _mavCmd, showError, _params[0], _params[1], _params[2], _params[3], _params[4], _params[5], _params[6]); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
private: |
||||||
|
QString label() const { return _label; } |
||||||
|
|
||||||
|
QString _label; |
||||||
|
MAV_CMD _mavCmd; |
||||||
|
MAV_COMPONENT _compId; |
||||||
|
float _params[7]; |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,96 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* |
||||||
|
* (c) 2009-2023 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
* |
||||||
|
* QGroundControl is licensed according to the terms in the file |
||||||
|
* COPYING.md in the root of the source code directory. |
||||||
|
* |
||||||
|
****************************************************************************/ |
||||||
|
|
||||||
|
#include <QQmlEngine> |
||||||
|
|
||||||
|
#include "CustomActionManager.h" |
||||||
|
#include "CustomAction.h" |
||||||
|
#include "JsonHelper.h" |
||||||
|
#include "QGCApplication.h" |
||||||
|
#include "SettingsManager.h" |
||||||
|
|
||||||
|
CustomActionManager::CustomActionManager(void) { |
||||||
|
auto flyViewSettings = qgcApp()->toolbox()->settingsManager()->flyViewSettings(); |
||||||
|
Fact* customActionsFact = flyViewSettings->customActionDefinitions(); |
||||||
|
|
||||||
|
connect(customActionsFact, &Fact::valueChanged, this, &CustomActionManager::_loadFromJson); |
||||||
|
_loadFromJson(customActionsFact->rawValue()); |
||||||
|
} |
||||||
|
|
||||||
|
void CustomActionManager::_loadFromJson(QVariant fact) { |
||||||
|
QString path = fact.toString(); |
||||||
|
|
||||||
|
const char* kQgcFileType = "CustomActions"; |
||||||
|
const char* kActionListKey = "actions"; |
||||||
|
|
||||||
|
_actions.clearAndDeleteContents(); |
||||||
|
|
||||||
|
QString errorString; |
||||||
|
int version; |
||||||
|
QJsonObject jsonObject = JsonHelper::openInternalQGCJsonFile(path, kQgcFileType, 1, 1, version, errorString); |
||||||
|
if (!errorString.isEmpty()) { |
||||||
|
qWarning() << "Custom Actions Internal Error: " << errorString; |
||||||
|
emit actionsChanged(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
QList<JsonHelper::KeyValidateInfo> keyInfoList = { |
||||||
|
{ kActionListKey, QJsonValue::Array, /* required= */ true }, |
||||||
|
}; |
||||||
|
if (!JsonHelper::validateKeys(jsonObject, keyInfoList, errorString)) { |
||||||
|
qWarning() << "Custom Actions JSON document incorrect format:" << errorString; |
||||||
|
emit actionsChanged(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
QJsonArray actionList = jsonObject[kActionListKey].toArray(); |
||||||
|
for (auto actionJson: actionList) { |
||||||
|
if (!actionJson.isObject()) { |
||||||
|
qWarning() << "Custom Actions JsonValue not an object: " << actionJson; |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
auto actionObj = actionJson.toObject(); |
||||||
|
|
||||||
|
QList<JsonHelper::KeyValidateInfo> actionKeyInfoList = { |
||||||
|
{ "label", QJsonValue::String, /* required= */ true }, |
||||||
|
{ "mavCmd", QJsonValue::Double, /* required= */ true }, |
||||||
|
|
||||||
|
{ "compId", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param1", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param2", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param3", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param4", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param5", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param6", QJsonValue::Double, /* required= */ false }, |
||||||
|
{ "param7", QJsonValue::Double, /* required= */ false }, |
||||||
|
}; |
||||||
|
if (!JsonHelper::validateKeys(actionObj, actionKeyInfoList, errorString)) { |
||||||
|
qWarning() << "Custom Actions JSON document incorrect format:" << errorString; |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
auto label = actionObj["label"].toString(); |
||||||
|
auto mavCmd = (MAV_CMD)actionObj["mavCmd"].toInt(); |
||||||
|
auto compId = (MAV_COMPONENT)actionObj["compId"].toInt(MAV_COMP_ID_AUTOPILOT1); |
||||||
|
auto param1 = actionObj["param1"].toDouble(0.0); |
||||||
|
auto param2 = actionObj["param2"].toDouble(0.0); |
||||||
|
auto param3 = actionObj["param3"].toDouble(0.0); |
||||||
|
auto param4 = actionObj["param4"].toDouble(0.0); |
||||||
|
auto param5 = actionObj["param5"].toDouble(0.0); |
||||||
|
auto param6 = actionObj["param6"].toDouble(0.0); |
||||||
|
auto param7 = actionObj["param7"].toDouble(0.0); |
||||||
|
|
||||||
|
CustomAction* action = new CustomAction(label, mavCmd, compId, param1, param2, param3, param4, param5, param6, param7); |
||||||
|
QQmlEngine::setObjectOwnership(action, QQmlEngine::CppOwnership); |
||||||
|
_actions.append(action); |
||||||
|
} |
||||||
|
|
||||||
|
emit actionsChanged(); |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/****************************************************************************
|
||||||
|
* |
||||||
|
* (c) 2009-2023 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
* |
||||||
|
* QGroundControl is licensed according to the terms in the file |
||||||
|
* COPYING.md in the root of the source code directory. |
||||||
|
* |
||||||
|
****************************************************************************/ |
||||||
|
|
||||||
|
#include <QObject> |
||||||
|
#include <QmlObjectListModel.h> |
||||||
|
|
||||||
|
|
||||||
|
class CustomActionManager : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
Q_PROPERTY(QmlObjectListModel* actions READ actions NOTIFY actionsChanged) |
||||||
|
Q_PROPERTY(bool hasActions READ hasActions NOTIFY actionsChanged) |
||||||
|
|
||||||
|
public: |
||||||
|
CustomActionManager(void); |
||||||
|
|
||||||
|
QmlObjectListModel* actions(void) { return &_actions; } |
||||||
|
bool hasActions(void) { return _actions.count() > 0; } |
||||||
|
|
||||||
|
signals: |
||||||
|
void actionsChanged(); |
||||||
|
|
||||||
|
private slots: |
||||||
|
void _loadFromJson(QVariant path); |
||||||
|
|
||||||
|
private: |
||||||
|
QmlObjectListModel _actions; |
||||||
|
bool _hasActions; |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,22 @@ |
|||||||
|
{ |
||||||
|
"version": 1, |
||||||
|
"fileType": "CustomActions", |
||||||
|
"actions": [ |
||||||
|
{ |
||||||
|
"label": "Image Start Capture", |
||||||
|
"mavCmd": 2000, |
||||||
|
"compId": 1, |
||||||
|
"param1": 0, |
||||||
|
"param2": 0, |
||||||
|
"param3": 0, |
||||||
|
"param4": 0, |
||||||
|
"param5": 0, |
||||||
|
"param6": 0, |
||||||
|
"param7": 0 |
||||||
|
}, |
||||||
|
{ |
||||||
|
"label": "Image Stop Capture", |
||||||
|
"mavCmd": 2001 |
||||||
|
} |
||||||
|
] |
||||||
|
} |
Loading…
Reference in new issue