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
128{
129 return _emptyCustomMapItems;
130}
131
132void QGCCorePlugin::adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
133{
134#ifdef Q_OS_ANDROID
135 // 3D view rendering is too flaky on Android GPUs/drivers; force the
136 // feature off. Hiding the setting also forces it to its default value
137 // (false) regardless of any previously saved user setting.
138 if ((settingsGroup == Viewer3DSettings::settingsGroup) && (metaData.name() == Viewer3DSettings::enabledName)) {
139 userVisible = false;
140 return;
141 }
142#endif
143
144 if (settingsGroup == AppSettings::settingsGroup) {
145 if (metaData.name() == AppSettings::indoorPaletteName) {
146 QVariant outdoorPalette;
147#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
148 outdoorPalette = 0;
149#else
150 outdoorPalette = 1;
151#endif
152 metaData.setRawDefaultValue(outdoorPalette);
153 return;
154 }
155#ifndef Q_OS_ANDROID
156 else if (metaData.name() == AppSettings::androidDontSaveToSDCardName) {
157 userVisible = false;
158 return;
159 }
160#endif
161 else if (metaData.name() == AppSettings::androidUsePosixSerialName) {
162#if defined(Q_OS_ANDROID) && !defined(QGC_NO_SERIAL_LINK)
163 // Only show when the device actually exposes accessible serial device nodes
165#else
166 userVisible = false;
167#endif
168 return;
169 }
170 }
171}
172
174{
175 return tr("WARNING: You are about to enter Advanced Mode. "
176 "If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
177 "You should do so only if instructed by customer support. "
178 "Are you sure you want to enable Advanced Mode?");
179}
180
185
187{
188 return true;
189}
190
192{
193#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
195#else
197#endif
198
199 if (factValueGrid->specificVehicleForCard()) {
200 bool includeFWValues = factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL || factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship;
201
202 factValueGrid->setFontSize(defaultFontSize);
203 factValueGrid->appendColumn();
204 factValueGrid->appendColumn();
205
206 int rowIndex = 0;
207 int colIndex = 0;
208
209 // first cell
210 QmlObjectListModel* column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
211 InstrumentValueData* value = column->value<InstrumentValueData*>(rowIndex);
212 value->setFact("Vehicle", "AltitudeRelative");
213 value->setIcon("arrow-thick-up.svg");
214 value->setText(value->fact()->shortDescription());
215 value->setShowUnits(true);
216
217 // second cell
218 column = factValueGrid->columns()->value<QmlObjectListModel*>(colIndex++);
219 value = column->value<InstrumentValueData*>(rowIndex);
220 if (includeFWValues) {
221 value->setFact("Vehicle", "AirSpeed");
222 value->setText("AirSpd");
223 value->setShowUnits(true);
224 } else {
225 value->setFact("Vehicle", "GroundSpeed");
226 value->setIcon("arrow-simple-right.svg");
227 value->setText(value->fact()->shortDescription());
228 value->setShowUnits(true);
229 }
230 } else {
231 const bool includeFWValues = ((factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassFixedWing) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassVTOL) || (factValueGrid->vehicleClass() == QGCMAVLink::VehicleClassAirship));
232
233 factValueGrid->setFontSize(defaultFontSize);
234
235 (void) factValueGrid->appendColumn();
236 (void) factValueGrid->appendColumn();
237 (void) factValueGrid->appendColumn();
238 if (includeFWValues) {
239 (void) factValueGrid->appendColumn();
240 }
241 factValueGrid->appendRow();
242
243 int rowIndex = 0;
244 QmlObjectListModel *column = factValueGrid->columns()->value<QmlObjectListModel*>(0);
245
246 InstrumentValueData *value = column->value<InstrumentValueData*>(rowIndex++);
247 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AltitudeRelative"));
248 value->setIcon(QStringLiteral("arrow-thick-up.svg"));
249 value->setText(value->fact()->shortDescription());
250 value->setShowUnits(true);
251
252 value = column->value<InstrumentValueData*>(rowIndex++);
253 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("DistanceToHome"));
254 value->setIcon(QStringLiteral("bookmark copy 3.svg"));
255 value->setText(value->fact()->shortDescription());
256 value->setShowUnits(true);
257
258 rowIndex = 0;
259 column = factValueGrid->columns()->value<QmlObjectListModel*>(1);
260
261 value = column->value<InstrumentValueData*>(rowIndex++);
262 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ClimbRate"));
263 value->setIcon(QStringLiteral("arrow-simple-up.svg"));
264 value->setText(value->fact()->shortDescription());
265 value->setShowUnits(true);
266
267 value = column->value<InstrumentValueData*>(rowIndex++);
268 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("GroundSpeed"));
269 value->setIcon(QStringLiteral("arrow-simple-right.svg"));
270 value->setText(value->fact()->shortDescription());
271 value->setShowUnits(true);
272
273 if (includeFWValues) {
274 rowIndex = 0;
275 column = factValueGrid->columns()->value<QmlObjectListModel*>(2);
276
277 value = column->value<InstrumentValueData*>(rowIndex++);
278 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("AirSpeed"));
279 value->setText(QStringLiteral("AirSpd"));
280 value->setShowUnits(true);
281
282 value = column->value<InstrumentValueData*>(rowIndex++);
283 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("ThrottlePct"));
284 value->setText(QStringLiteral("Thr"));
285 value->setShowUnits(true);
286 }
287
288 rowIndex = 0;
289 column = factValueGrid->columns()->value<QmlObjectListModel*>(includeFWValues ? 3 : 2);
290
291 value = column->value<InstrumentValueData*>(rowIndex++);
292 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightTime"));
293 value->setIcon(QStringLiteral("timer.svg"));
294 value->setText(value->fact()->shortDescription());
295 value->setShowUnits(false);
296
297 value = column->value<InstrumentValueData*>(rowIndex++);
298 value->setFact(QStringLiteral("Vehicle"), QStringLiteral("FlightDistance"));
299 value->setIcon(QStringLiteral("travel-walk.svg"));
300 value->setText(value->fact()->shortDescription());
301 value->setShowUnits(true);
302 }
303}
304
305QQmlApplicationEngine *QGCCorePlugin::createQmlApplicationEngine(QObject *parent)
306{
307 QQmlApplicationEngine *const qmlEngine = new QQmlApplicationEngine(parent);
308 qmlEngine->addImportPath(QStringLiteral("qrc:/qml"));
309 qmlEngine->rootContext()->setContextProperty(QStringLiteral("joystickManager"), JoystickManager::instance());
310 return qmlEngine;
311}
312
313void QGCCorePlugin::destroyQmlApplicationEngine(QQmlApplicationEngine *qmlEngine)
314{
315 delete qmlEngine;
316}
317
318void QGCCorePlugin::createRootWindow(QQmlApplicationEngine *qmlEngine)
319{
320 qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/QGroundControl/MainWindow.qml")));
321}
322
327
328void *QGCCorePlugin::createVideoSink(QQuickItem *widget, QObject *parent)
329{
330 return VideoBackend::createSink(widget, parent);
331}
332
334{
336}
337
339{
340 static const QVariantList toolBarIndicatorList = QVariantList({
341 QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/Toolbar/GPSIndicator.qml"))),
342 });
343
344 return toolBarIndicatorList;
345}
346
348{
350 return { kInitialSetupPromptId };
351 }
352
353 return {};
354}
355
357{
358 QList<int> rgIdsToShow;
359
360 rgIdsToShow.append(firstRunPromptStdIds());
361 rgIdsToShow.append(firstRunPromptCustomIds());
362
363 const QList<int> rgAlreadyShownIds = AppSettings::firstRunPromptsIdsVariantToList(SettingsManager::instance()->appSettings()->firstRunPromptIdsShown()->rawValue());
364 for (int idToRemove: rgAlreadyShownIds) {
365 (void) rgIdsToShow.removeOne(idToRemove);
366 }
367
368 QVariantList rgVarIdsToShow;
369 for (int id: rgIdsToShow) {
370 rgVarIdsToShow.append(id);
371 }
372
373 return rgVarIdsToShow;
374}
375
377{
378 switch (id) {
380 return QStringLiteral("/qml/QGroundControl/FirstRunPromptDialogs/InitialSetupPrompt.qml");
381 default:
382 return QString();
383 }
384}
385
386void QGCCorePlugin::_setShowTouchAreas(bool show)
387{
388 if (show != _showTouchAreas) {
389 _showTouchAreas = show;
390 emit showTouchAreasChanged(show);
391 }
392}
393
394void QGCCorePlugin::_setShowAdvancedUI(bool show)
395{
396 if (show != _showAdvancedUI) {
397 _showAdvancedUI = show;
398 emit showAdvancedUIChanged(show);
399 }
400}
401
403{
404 auto makeEntry = [](const char* canonical, const QString& translated) {
405 QVariantMap entry;
406 entry[QStringLiteral("canonicalName")] = QString(canonical);
407 entry[QStringLiteral("translatedName")] = translated;
408 return entry;
409 };
410
411 QVariantList items;
412 items.append(makeEntry(SurveyComplexItem::canonicalName, SurveyComplexItem::tr(SurveyComplexItem::canonicalName)));
413 items.append(makeEntry(CorridorScanComplexItem::canonicalName, CorridorScanComplexItem::tr(CorridorScanComplexItem::canonicalName)));
414 if (vehicle->multiRotor() || vehicle->vtol()) {
415 items.append(makeEntry(StructureScanComplexItem::canonicalName, StructureScanComplexItem::tr(StructureScanComplexItem::canonicalName)));
416 }
417 // Note: Landing pattern items are not added here — they have their own dedicated button
418 return items;
419}
420
421QList<PlanCreator*> QGCCorePlugin::planCreators(PlanMasterController *planMasterController)
422{
423 return {
424 new SurveyPlanCreator(planMasterController),
425 new CorridorScanPlanCreator(planMasterController),
426 new StructureScanPlanCreator(planMasterController),
427 new BlankPlanCreator(planMasterController),
428 };
429}
430
432 const QString &complexItemType,
433 PlanMasterController *masterController,
434 bool flyView,
435 const QString &kmlOrShpFile)
436{
437 if (complexItemType == SurveyComplexItem::canonicalName || complexItemType == SurveyComplexItem::jsonComplexItemTypeValue) {
438 return new SurveyComplexItem(masterController, flyView, kmlOrShpFile);
439 } else if (complexItemType == CorridorScanComplexItem::canonicalName || complexItemType == CorridorScanComplexItem::jsonComplexItemTypeValue) {
440 return new CorridorScanComplexItem(masterController, flyView, kmlOrShpFile);
441 } else if (complexItemType == StructureScanComplexItem::canonicalName || complexItemType == StructureScanComplexItem::jsonComplexItemTypeValue) {
442 return new StructureScanComplexItem(masterController, flyView, kmlOrShpFile);
444 return new FixedWingLandingComplexItem(masterController, flyView);
445 } else if (complexItemType == VTOLLandingComplexItem::canonicalName || complexItemType == VTOLLandingComplexItem::jsonComplexItemTypeValue) {
446 return new VTOLLandingComplexItem(masterController, flyView);
447 }
448
449 qCWarning(QGCCorePluginLog) << "QGCCorePlugin::createComplexMissionItem - Unknown complex item type:" << complexItemType;
450 return nullptr;
451}
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 const QmlObjectListModel * customGeoMapItems()
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:1780
bool multiRotor() const
Definition Vehicle.cc:1775
bool hasPosixSerialPorts()
void releaseSink(void *sink)
void * createSink(QQuickItem *widget, QObject *parent)
VideoReceiver * createReceiver(QObject *parent)