12#include <QtCore/QJsonObject>
13#include <QtCore/QJsonParseError>
14#include <QtCore/QVariant>
15#include <QtGui/QCursor>
16#include <QtGui/QGuiApplication>
18QGC_LOGGING_CATEGORY(APMAirframeComponentControllerLog,
"AutoPilotPlugins.APMAirframeComponentController")
24 , _frameClassFact(getParameterFact(
ParameterManager::defaultComponentId, QStringLiteral("FRAME_CLASS"), false ))
25 , _frameTypeFact(getParameterFact(
ParameterManager::defaultComponentId, QStringLiteral("FRAME_TYPE"), false ))
38void APMAirframeComponentController::_fillFrameClasses()
42 if (qobject_cast<ArduCopterFirmwarePlugin*>(fwPlugin)) {
43 static const QList<int> frameTypeNotSupported = {
52 for (qsizetype i = 1; i < _frameClassFact->
enumStrings().count(); i++) {
53 const QString frameClassName = _frameClassFact->
enumStrings()[i];
54 const int frameClass = _frameClassFact->
enumValues()[i].toInt();
61 _frameClassModel->
append(
new APMFrameClass(frameClassName,
true , frameClass, _frameTypeFact, _frameClassModel));
63 }
else if (qobject_cast<ArduRoverFirmwarePlugin*>(fwPlugin)) {
64 for (qsizetype i = 1; i < _frameClassFact->
enumStrings().count(); i++) {
65 const QString frameClassName = _frameClassFact->
enumStrings()[i];
66 const int frameClass = _frameClassFact->
enumValues()[i].toInt();
67 _frameClassModel->
append(
new APMFrameClass(frameClassName,
false , frameClass, _frameTypeFact, _frameClassModel));
72void APMAirframeComponentController::_loadParametersFromDownloadFile(
const QString &downloadedParamFile)
74 QFile parametersFile(downloadedParamFile);
75 if (!parametersFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
76 qCWarning(APMAirframeComponentControllerLog) <<
"Unable to open downloaded parameter file" << downloadedParamFile << parametersFile.errorString();
77 QGuiApplication::restoreOverrideCursor();
81 QTextStream reader(¶metersFile);
82 while (!reader.atEnd()) {
83 const QString line = reader.readLine().trimmed();
84 if (line.isEmpty() || (line.at(0) == QChar(
'#'))) {
88 const QStringList aux = line.split(
',');
94 QGuiApplication::restoreOverrideCursor();
100 QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
104 (void) connect(downloader, &
QGCFileDownload::finished,
this, &APMAirframeComponentController::_githubJsonDownloadComplete);
105 const QString paramFileUrl = QStringLiteral(
"https://api.github.com/repos/ArduPilot/ardupilot/contents/Tools/Frame_params/%1?ref=master");
106 if (!downloader->
start(paramFileUrl.arg(paramFile))) {
108 QGuiApplication::restoreOverrideCursor();
109 downloader->deleteLater();
113void APMAirframeComponentController::_githubJsonDownloadComplete(
bool success,
const QString &localFile,
const QString &errorMsg)
116 QFile jsonFile(localFile);
117 if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
118 qCWarning(APMAirframeComponentControllerLog) <<
"Unable to open github json file" << localFile << jsonFile.errorString();
119 QGuiApplication::restoreOverrideCursor();
122 const QByteArray bytes = jsonFile.readAll();
125 QJsonParseError jsonParseError;
126 const QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError);
127 if (jsonParseError.error != QJsonParseError::NoError) {
128 qCWarning(APMAirframeComponentControllerLog) <<
"Unable to open json document" << localFile << jsonParseError.errorString();
129 QGuiApplication::restoreOverrideCursor();
135 (void) connect(downloader, &
QGCFileDownload::finished,
this, &APMAirframeComponentController::_paramFileDownloadComplete);
136 const QJsonObject json = doc.object();
137 if (!downloader->
start(json[QLatin1String(
"download_url")].toString())) {
139 QGuiApplication::restoreOverrideCursor();
140 downloader->deleteLater();
142 }
else if (!errorMsg.isEmpty()) {
144 QGuiApplication::restoreOverrideCursor();
148void APMAirframeComponentController::_paramFileDownloadComplete(
bool success,
const QString &localFile,
const QString &errorMsg)
151 _loadParametersFromDownloadFile(localFile);
152 }
else if (!errorMsg.isEmpty()) {
154 QGuiApplication::restoreOverrideCursor();
164 , _frameClass(frameClass)
165 , _frameTypeFact(frameTypeFact)
173 QList<int> rgSupportedFrameTypes;
175 for (
const FrameToImageInfo &pFrameToImageInfo : _rgFrameToImageCopter) {
176 if (pFrameToImageInfo.frameClass == frameClass) {
180 _imageResourceDefault = QStringLiteral(
"/qmlimages/Airframe/%1").arg(pFrameToImageInfo.imageResource);
183 if (pFrameToImageInfo.frameType != -1) {
185 rgSupportedFrameTypes.append(pFrameToImageInfo.frameType);
195 for (
const int frameType: rgSupportedFrameTypes) {
217 return _frameTypeFact->
rawValue().toInt();
231 return QStringLiteral(
"/qmlimages/Airframe/%1").arg(
imageResource);
235QString APMFrameClass::_findImageResourceCopter(
int frameClass,
int &frameType)
237 for (
const FrameToImageInfo &pFrameToImageInfo : _rgFrameToImageCopter) {
238 if (((pFrameToImageInfo.frameClass == frameClass) && (
frameType == -1)) ||
239 ((pFrameToImageInfo.frameClass == frameClass) && (pFrameToImageInfo.frameType ==
frameType))) {
241 return pFrameToImageInfo.imageResource;
245 return QStringLiteral(
"AirframeUnknown");
248QString APMFrameClass::_findImageResourceRover(
int frameClass,
int frameType)
252 static const QList<FrameToImageInfo> s_rgFrameToImageRover = {
257 for (
const FrameToImageInfo &pFrameToImageInfo : s_rgFrameToImageRover) {
258 if (pFrameToImageInfo.frameClass == frameClass) {
259 return pFrameToImageInfo.imageResource;
263 return QStringLiteral(
"AirframeUnknown");
#define FRAME_CLASS_BICOPTER
#define FRAME_CLASS_ROVER
#define FRAME_CLASS_COAXCOPTER
#define FRAME_CLASS_HELI_DUAL
#define FRAME_CLASS_HELIQUAD
#define FRAME_CLASS_SINGLECOPTER
Unified file download utility with decompression, verification, and QML support.
#define QGC_LOGGING_CATEGORY(name, categoryStr)
MVC Controller for APMAirframeComponent.qml.
Q_INVOKABLE void loadParameters(const QString ¶mFile)
~APMAirframeComponentController()
QString imageResource() const
void imageResourceChanged()
QString _imageResourceDefault
APMFrameClass(const QString &name, bool copter, int frameClass, Fact *frameTypeFact, QObject *parent=nullptr)
QVariantList _frameTypeEnumValues
QStringList _frameTypeEnumStrings
Used for handling missing Facts from C++ code.
Q_INVOKABLE Fact * getParameterFact(int componentId, const QString &name, bool reportMissing=true) const
Q_INVOKABLE bool parameterExists(int componentId, const QString &name) const
A Fact is used to hold a single value within the system.
QVariantList enumValues() const
void rawValueChanged(const QVariant &value)
void setRawValue(const QVariant &value)
QStringList enumStrings() const
QVariant rawValue() const
Value after translation.
The FirmwarePlugin class represents the methods and objects which are specific to a certain Firmware ...
void refreshAllParameters(uint8_t componentID)
Re-request the full set of parameters from the autopilot.
File download with progress, decompression, and hash verification.
void finished(bool success, const QString &localPath, const QString &errorMessage)
bool start(const QString &remoteUrl)
QString errorString() const
void append(QObject *object)
Caller maintains responsibility for object ownership and deletion.
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
ParameterManager * parameterManager()
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.