QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
QGCCorePlugin.cc
Go to the documentation of this file.
1#include "QGCCorePlugin.h"
2#include "AppSettings.h"
3#ifdef Q_OS_ANDROID
4#include "Viewer3DSettings.h"
5#ifndef QGC_NO_SERIAL_LINK
6#include "AndroidSerial.h"
7#endif
8#endif
9#include "FactMetaData.h"
11#include "QGCMAVLink.h"
13#include "InstrumentValueData.h"
14#include "JoystickManager.h"
15#include "QGCLoggingCategory.h"
16#include "QGCOptions.h"
17#include "QmlComponentInfo.h"
18#include "QmlObjectListModel.h"
19#include "SettingsManager.h"
20#include "VideoReceiver.h"
21#include "VideoBackend.h"
22#include "SurveyPlanCreator.h"
25#include "SurveyComplexItem.h"
30#include "Vehicle.h"
31#include "BlankPlanCreator.h"
32#include "ComplexMissionItem.h"
34
35#ifdef QGC_CUSTOM_BUILD
36#include CUSTOMHEADER
37#endif
38
39#include <QtCore/QApplicationStatic>
40#include <QtCore/QFile>
41#include <QtQml/QQmlApplicationEngine>
42#include <QtQml/QQmlContext>
43#include <QtQuick/QQuickItem>
44
45QGC_LOGGING_CATEGORY(QGCCorePluginLog, "API.QGCCorePlugin");
46
47#ifndef QGC_CUSTOM_BUILD
48Q_APPLICATION_STATIC(QGCCorePlugin, _qgcCorePluginInstance);
49#endif
50
52 : QObject(parent)
53 , _defaultOptions(new QGCOptions(this))
54 , _emptyCustomMapItems(new QmlObjectListModel(this))
55{
56 qCDebug(QGCCorePluginLog) << this;
57}
58
60{
61 qCDebug(QGCCorePluginLog) << this;
62}
63
65{
66#ifndef QGC_CUSTOM_BUILD
67 return _qgcCorePluginInstance();
68#else
69 return CUSTOMCLASS::instance();
70#endif
71}
72
73const QVariantList &QGCCorePlugin::analyzePages()
74{
75 // Log Viewer is excluded on mobile (Android/iOS) because parsing large log files
76 // (e.g. 900 MB ULog files with 1000+ fields) exhausts the mobile heap, causing
77 // OOM crashes. Proper mobile support requires time-bucketed downsampling and will
78 // be addressed in a future major release.
79#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
80 static const QVariantList analyzeList = {
81#else
82 static const QVariantList analyzeList = {
83 QVariant::fromValue(new QmlComponentInfo(
84 tr("Log Viewer"),
85 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/LogViewer/LogViewerPage.qml")),
86 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")))),
87#endif
88 QVariant::fromValue(new QmlComponentInfo(
89 tr("Onboard Logs"),
90 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/OnboardLogs/OnboardLogPage.qml")),
91 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/OnboardLogIcon.svg")),
92 nullptr, true /* requiresVehicle */)),
93 QVariant::fromValue(new QmlComponentInfo(
94 tr("GeoTag Images"),
95 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagPage.qml")),
96 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/GeoTag/GeoTagIcon.svg")))),
97 QVariant::fromValue(new QmlComponentInfo(
98 tr("MAVLink Console"),
99 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkConsole/MAVLinkConsolePage.qml")),
100 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkConsoleIcon.svg")),
101 nullptr, true /* requiresVehicle */)),
102 QVariant::fromValue(new QmlComponentInfo(
103 tr("MAVLink Inspector"),
104 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/MAVLinkInspector/MAVLinkInspectorPage.qml")),
105 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/MAVLinkInspector.svg")),
106 nullptr, true /* requiresVehicle */)),
107 QVariant::fromValue(new QmlComponentInfo(
108 tr("Vibration"),
109 QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Vibration/VibrationPage.qml")),
110 QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/VibrationPageIcon")),
111 nullptr, true /* requiresVehicle */)),
112 };
113
114 return analyzeList;
115}
116
118{
119 return _defaultOptions;
120}
121
123{
124 return _emptyCustomMapItems;
125}
126
127void QGCCorePlugin::adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
128{
129#ifdef Q_OS_ANDROID
130 // 3D view rendering is too flaky on Android GPUs/drivers; force the
131 // feature off. Hiding the setting also forces it to its default value
132 // (false) regardless of any previously saved user setting.
133 if ((settingsGroup == Viewer3DSettings::settingsGroup) && (metaData.name() == Viewer3DSettings::enabledName)) {
134 userVisible = false;
135 return;
136 }
137#endif
138
139 if (settingsGroup == AppSettings::settingsGroup) {
140 if (metaData.name() == AppSettings::indoorPaletteName) {
141 QVariant outdoorPalette;
142#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
143 outdoorPalette = 0;
144#else
145 outdoorPalette = 1;
146#endif
147 metaData.setRawDefaultValue(outdoorPalette);
148 return;
149 }
150#ifndef Q_OS_ANDROID
151 else if (metaData.name() == AppSettings::androidDontSaveToSDCardName) {
152 userVisible = false;
153 return;
154 }
155#endif
156 else if (metaData.name() == AppSettings::androidUsePosixSerialName) {
157#if defined(Q_OS_ANDROID) && !defined(QGC_NO_SERIAL_LINK)
158 // Only show when the device actually exposes accessible serial device nodes
160#else
161 userVisible = false;
162#endif
163 return;
164 }
165 }
166}
167
169{
170 return tr("WARNING: You are about to enter Advanced Mode. "
171 "If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
172 "You should do so only if instructed by customer support. "
173 "Are you sure you want to enable Advanced Mode?");
174}
175
180
182{
183 return true;
184}
185
187{
188#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
190#else
192#endif
193
194 if (factValueGrid->specificVehicleForCard()) {
195 bool includeFWValues = factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship;
196
197 factValueGrid->setFontSize(defaultFontSize);
198 factValueGrid->appendColumn();
199 factValueGrid->appendColumn();
200
201 int rowIndex = 0;
202 int colIndex = 0;
203
204 // first cell
205 QmlObjectListModel* column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
206 InstrumentValueData* value = column->value<InstrumentValueData*>(rowIndex);
207 value->setFact("Vehicle", "AltitudeRelative");
208 value->setIcon("arrow-thick-up.svg");
209 value->setText(value->fact()->shortDescription());
210 value->setShowUnits(true);
211
212 // second cell
213 column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
214 value = column->value<InstrumentValueData*>(rowIndex);
215 if (includeFWValues) {
216 value->setFact("Vehicle", "AirSpeed");
217 value->setText("AirSpd");
218 value->setShowUnits(true);
219 } else {
220 value->setFact("Vehicle", "GroundSpeed");
221 value->setIcon("arrow-simple-right.svg");
222 value->setText(value->fact()->shortDescription());
223 value->setShowUnits(true);
224 }
225 } else {
226 const bool includeFWValues = ((factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship));
227
228 factValueGrid->setFontSize(defaultFontSize);
229
230 (void) factValueGrid->appendColumn();
231 (void) factValueGrid->appendColumn();
232 (void) factValueGrid->appendColumn();
233 if (includeFWValues) {
234 (void) factValueGrid->appendColumn();
235 }
236 factValueGrid->appendRow();
237
238 int rowIndex = 0;
239 QmlObjectListModel *column = factValueGrid->columns()->value<QmlObjectListModel*>(0);
240
241 InstrumentValueData *value = column->value<InstrumentValueData*>(rowIndex++);
242 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AltitudeRelative"));
243 value->setIcon(QStringLiteral("arrow-thick-up.svg"));
244 value->setText(value->fact()->shortDescription());
245 value->setShowUnits(true);
246
247 value = column->value<InstrumentValueData*>(rowIndex++);
248 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("DistanceToHome"));
249 value->setIcon(QStringLiteral("bookmark copy 3.svg"));
250 value->setText(value->fact()->shortDescription());
251 value->setShowUnits(true);
252
253 rowIndex = 0;
254 column = factValueGrid->columns()->value<QmlObjectListModel*>(1);
255
256 value = column->value<InstrumentValueData*>(rowIndex++);
257 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ClimbRate"));
258 value->setIcon(QStringLiteral("arrow-simple-up.svg"));
259 value->setText(value->fact()->shortDescription());
260 value->setShowUnits(true);
261
262 value = column->value<InstrumentValueData*>(rowIndex++);
263 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("GroundSpeed"));
264 value->setIcon(QStringLiteral("arrow-simple-right.svg"));
265 value->setText(value->fact()->shortDescription());
266 value->setShowUnits(true);
267
268 if (includeFWValues) {
269 rowIndex = 0;
270 column = factValueGrid->columns()->value<QmlObjectListModel*>(2);
271
272 value = column->value<InstrumentValueData*>(rowIndex++);
273 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AirSpeed"));
274 value->setText(QStringLiteral("AirSpd"));
275 value->setShowUnits(true);
276
277 value = column->value<InstrumentValueData*>(rowIndex++);
278 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ThrottlePct"));
279 value->setText(QStringLiteral("Thr"));
280 value->setShowUnits(true);
281 }
282
283 rowIndex = 0;
284 column = factValueGrid->columns()->value<QmlObjectListModel*>(includeFWValues ? 3 : 2);
285
286 value = column->value<InstrumentValueData*>(rowIndex++);
287 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightTime"));
288 value->setIcon(QStringLiteral("timer.svg"));
289 value->setText(value->fact()->shortDescription());
290 value->setShowUnits(false);
291
292 value = column->value<InstrumentValueData*>(rowIndex++);
293 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightDistance"));
294 value->setIcon(QStringLiteral("travel-walk.svg"));
295 value->setText(value->fact()->shortDescription());
296 value->setShowUnits(true);
297 }
298}
299
300QQmlApplicationEngine *QGCCorePlugin::createQmlApplicationEngine(QObject *parent)
301{
302 QQmlApplicationEngine *const qmlEngine = new QQmlApplicationEngine(parent);
303 qmlEngine->addImportPath(QStringLiteral("qrc:/qml"));
304 qmlEngine->rootContext()->setContextProperty(QStringLiteral("joystickManager"), JoystickManager::instance());
305 return qmlEngine;
306}
307
308void QGCCorePlugin::destroyQmlApplicationEngine(QQmlApplicationEngine *qmlEngine)
309{
310 delete qmlEngine;
311}
312
313void QGCCorePlugin::createRootWindow(QQmlApplicationEngine *qmlEngine)
314{
315 qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/QGroundControl/MainWindow.qml")));
316}
317
322
323void *QGCCorePlugin::createVideoSink(QQuickItem *widget, QObject *parent)
324{
325 return VideoBackend::createSink(widget, parent);
326}
327
329{
331}
332
334{
335 static const QVariantList toolBarIndicatorList = QVariantList(
336 {
337 QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/Toolbar/RTKGPSIndicator.qml"))),
338 }
339 );
340
341 return toolBarIndicatorList;
342}
343
345{
347 return { kInitialSetupPromptId };
348 }
349
350 return {};
351}
352
354{
355 QList<int> rgIdsToShow;
356
357 rgIdsToShow.append(firstRunPromptStdIds());
358 rgIdsToShow.append(firstRunPromptCustomIds());
359
360 const QList<int> rgAlreadyShownIds = AppSettings::firstRunPromptsIdsVariantToList(SettingsManager::instance()->appSettings()->firstRunPromptIdsShown()->rawValue());
361 for (int idToRemove: rgAlreadyShownIds) {
362 (void) rgIdsToShow.removeOne(idToRemove);
363 }
364
365 QVariantList rgVarIdsToShow;
366 for (int id: rgIdsToShow) {
367 rgVarIdsToShow.append(id);
368 }
369
370 return rgVarIdsToShow;
371}
372
374{
375 switch (id) {
377 return QStringLiteral("/qml/QGroundControl/FirstRunPromptDialogs/InitialSetupPrompt.qml");
378 default:
379 return QString();
380 }
381}
382
383void QGCCorePlugin::_setShowTouchAreas(bool show)
384{
385 if (show != _showTouchAreas) {
386 _showTouchAreas = show;
387 emit showTouchAreasChanged(show);
388 }
389}
390
391void QGCCorePlugin::_setShowAdvancedUI(bool show)
392{
393 if (show != _showAdvancedUI) {
394 _showAdvancedUI = show;
395 emit showAdvancedUIChanged(show);
396 }
397}
398
400{
401 auto makeEntry = [](const char* canonical, const QString& translated) {
402 QVariantMap entry;
403 entry[QStringLiteral("canonicalName")] = QString(canonical);
404 entry[QStringLiteral("translatedName")] = translated;
405 return entry;
406 };
407
408 QVariantList items;
409 items.append(makeEntry(SurveyComplexItem::canonicalName, SurveyComplexItem::tr(SurveyComplexItem::canonicalName)));
410 items.append(makeEntry(CorridorScanComplexItem::canonicalName, CorridorScanComplexItem::tr(CorridorScanComplexItem::canonicalName)));
411 if (vehicle->multiRotor() || vehicle->vtol()) {
412 items.append(makeEntry(StructureScanComplexItem::canonicalName, StructureScanComplexItem::tr(StructureScanComplexItem::canonicalName)));
413 }
414 // Note: Landing pattern items are not added here — they have their own dedicated button
415 return items;
416}
417
418QList<PlanCreator*> QGCCorePlugin::planCreators(PlanMasterController *planMasterController)
419{
420 return {
421 new SurveyPlanCreator(planMasterController),
422 new CorridorScanPlanCreator(planMasterController),
423 new StructureScanPlanCreator(planMasterController),
424 new BlankPlanCreator(planMasterController),
425 };
426}
427
429 const QString &complexItemType,
430 PlanMasterController *masterController,
431 bool flyView,
432 const QString &kmlOrShpFile)
433{
434 if (complexItemType == SurveyComplexItem::canonicalName || complexItemType == SurveyComplexItem::jsonComplexItemTypeValue) {
435 return new SurveyComplexItem(masterController, flyView, kmlOrShpFile);
436 } else if (complexItemType == CorridorScanComplexItem::canonicalName || complexItemType == CorridorScanComplexItem::jsonComplexItemTypeValue) {
437 return new CorridorScanComplexItem(masterController, flyView, kmlOrShpFile);
438 } else if (complexItemType == StructureScanComplexItem::canonicalName || complexItemType == StructureScanComplexItem::jsonComplexItemTypeValue) {
439 return new StructureScanComplexItem(masterController, flyView, kmlOrShpFile);
441 return new FixedWingLandingComplexItem(masterController, flyView);
442 } else if (complexItemType == VTOLLandingComplexItem::canonicalName || complexItemType == VTOLLandingComplexItem::jsonComplexItemTypeValue) {
443 return new VTOLLandingComplexItem(masterController, flyView);
444 }
445
446 qCWarning(QGCCorePluginLog) << "QGCCorePlugin::createComplexMissionItem - Unknown complex item type:" << complexItemType;
447 return nullptr;
448}
Q_APPLICATION_STATIC(QGCCorePlugin, _qgcCorePluginInstance)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
static QList< int > firstRunPromptsIdsVariantToList(const QVariant &firstRunPromptIds)
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
Holds the meta data associated with a Fact.
void setRawDefaultValue(const QVariant &rawDefaultValue)
QString name() const
QmlObjectListModel * columns(void) const
void setFontSize(FontSize fontSize)
Q_INVOKABLE QmlObjectListModel * appendColumn(void)
Vehicle * specificVehicleForCard(void) const
QGCMAVLinkTypes::VehicleClass_t vehicleClass(void) const
Q_INVOKABLE void appendRow(void)
bool singleVehicleSupport()
Returns true if the system supports only a single firmware class with a single vehicle type.
static FirmwarePluginManager * instance()
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * canonicalName
Q_INVOKABLE void setFact(const QString &factGroupName, const QString &factName)
static JoystickManager * instance()
Master controller for mission, fence, rally.
Extension mechanism for generic, non-firmware-specific customization of QGC.
virtual ComplexMissionItem * createComplexMissionItem(const QString &complexItemType, PlanMasterController *masterController, bool flyView, const QString &kmlOrShpFile=QString())
virtual QList< int > firstRunPromptStdIds()
QGCCorePlugin(QObject *parent=nullptr)
virtual QVariantList complexMissionItemNames(Vehicle *vehicle)
void showTouchAreasChanged(bool showTouchAreas)
virtual ~QGCCorePlugin()
virtual void * createVideoSink(QQuickItem *widget, QObject *parent)
Allows the plugin to override the creation of VideoSink.
virtual void factValueGridCreateDefaultSettings(FactValueGrid *factValueGrid)
void showAdvancedUIChanged(bool showAdvancedUI)
virtual const QVariantList & toolBarIndicators()
virtual QList< int > firstRunPromptCustomIds()
virtual Q_INVOKABLE QString firstRunPromptResource(int id) const
Returns the resource which contains the specified first run prompt for display.
static constexpr int kInitialSetupPromptId
virtual QGCOptions * options()
virtual QQmlApplicationEngine * createQmlApplicationEngine(QObject *parent)
virtual bool showInitialSetupMeasurementUnits() const
virtual const QVariantList & analyzePages()
virtual bool showInitialSetupVehiclePreferences() const
virtual QString showAdvancedUIMessage() const
virtual void createRootWindow(QQmlApplicationEngine *qmlEngine)
Allows the plugin to override the creation of the root (native) window.
virtual VideoReceiver * createVideoReceiver(QObject *parent)
Allows the plugin to override the creation of VideoReceiver.
virtual void releaseVideoSink(void *sink)
Allows the plugin to override the release of VideoSink.
Q_INVOKABLE QVariantList firstRunPromptsToShow()
Returns the list of first run prompt ids which need to be displayed according to current settings.
virtual const QmlObjectListModel * customMapItems()
Allows custom builds to add custom items to the FlightMap. Objects put into QmlObjectListModel should...
virtual QList< PlanCreator * > planCreators(PlanMasterController *planMasterController)
virtual void adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
virtual void destroyQmlApplicationEngine(QQmlApplicationEngine *qmlEngine)
static QGCCorePlugin * instance()
Represents a Qml component which can be loaded from a resource.
T value(int index) const
QString settingsGroup() const
static SettingsManager * instance()
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * jsonComplexItemTypeValue
static constexpr const char * canonicalName
static constexpr const char * canonicalName
static constexpr const char * jsonComplexItemTypeValue
bool vtol() const
Definition Vehicle.cc:1763
bool multiRotor() const
Definition Vehicle.cc:1758
bool hasPosixSerialPorts()
void releaseSink(void *sink)
void * createSink(QQuickItem *widget, QObject *parent)
VideoReceiver * createReceiver(QObject *parent)