From 5fec843af63ac432539358f6e95e450865792b3e Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 26 Jun 2019 10:16:37 -0700 Subject: [PATCH 1/8] Add .apj file picker support --- ChangeLog.md | 3 +++ src/VehicleSetup/FirmwareUpgradeController.cc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index cc95a44..aeccabe 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -8,6 +8,9 @@ Note: This file only contains high level features or important fixes. * Major rewrite and bug fix pass through Structure Scan. Previous version had such bad problems that it can no longer be supported. Plans with Structure Scan will need to be recreated. New QGC will not load old Structure Scan plans. +### 3.5.4 - Not yet released +* Add .apj file selection support to custom firmware flash + ### 3.5.3 - Stable * Change minimum RTK Survey-In limit to 0.01 meters * Change Windows driver detection logic diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index 3d189f4..5c27016 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -586,7 +586,7 @@ void FirmwareUpgradeController::_getFirmwareFile(FirmwareIdentifier firmwareId) _firmwareFilename = QGCQFileDialog::getOpenFileName(nullptr, // Parent to main window tr("Select Firmware File"), // Dialog Caption QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), // Initial directory - tr("Firmware Files (*.px4 *.bin *.ihx)")); // File filter + tr("Firmware Files (*.px4 *.apj *.bin *.ihx)")); // File filter } else { if (prgFirmware->contains(firmwareId)) { _firmwareFilename = prgFirmware->value(firmwareId); From 28ebe38a402fa38eacc2c39dff6e5beebcc0ef86 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 2 Jul 2019 11:49:51 -0700 Subject: [PATCH 2/8] Cherry pick live scrubbing from master --- src/comm/LogReplayLink.cc | 19 +++++++++++++++---- src/comm/LogReplayLink.h | 1 + src/ui/QGCMAVLinkLogPlayer.cc | 2 -- src/ui/QGCMAVLinkLogPlayer.ui | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/comm/LogReplayLink.cc b/src/comm/LogReplayLink.cc index f10ca07..c9da144 100644 --- a/src/comm/LogReplayLink.cc +++ b/src/comm/LogReplayLink.cc @@ -14,6 +14,7 @@ #include #include +#include const char* LogReplayLinkConfiguration::_logFilenameKey = "logFilename"; @@ -378,7 +379,7 @@ void LogReplayLink::_readNextLogEntry(void) timeToNextExecutionMSecs = desiredPacedTimeMSecs - currentTimeMSecs; } - emit currentLogTimeSecs((_logCurrentTimeUSecs - _logStartTimeUSecs) / 1000000); + _signalCurrentLogTimeSecs(); // And schedule the next execution of this function. _readTickTimer.start(timeToNextExecutionMSecs); @@ -460,8 +461,12 @@ void LogReplayLink::_resetPlaybackToBeginning(void) void LogReplayLink::movePlayhead(int percentComplete) { if (isPlaying()) { - qWarning() << "Should not move playhead while playing, pause first"; - return; + _pauseOnThread(); + QSignalSpy waitForPause(this, SIGNAL(playbackPaused)); + waitForPause.wait(); + if (_readTickTimer.isActive()) { + return; + } } if (percentComplete < 0 || percentComplete > 100) { @@ -505,7 +510,8 @@ void LogReplayLink::movePlayhead(int percentComplete) // And scan until we reach the start of a MAVLink message. We make sure to record this timestamp for // smooth jumping around the file. _logCurrentTimeUSecs = _seekToNextMavlinkMessage(&dummy); - + _signalCurrentLogTimeSecs(); + // Now update the UI with our actual final position. newRelativeTimeUSecs = (float)(_logCurrentTimeUSecs - _logStartTimeUSecs); percentComplete = (newRelativeTimeUSecs / _logDurationUSecs) * 100; @@ -571,3 +577,8 @@ void LogReplayLink::_playbackError(void) _logFile.close(); emit playbackError(); } + +void LogReplayLink::_signalCurrentLogTimeSecs(void) +{ + emit currentLogTimeSecs((_logCurrentTimeUSecs - _logStartTimeUSecs) / 1000000); +} diff --git a/src/comm/LogReplayLink.h b/src/comm/LogReplayLink.h index fecb77a..1b661fd 100644 --- a/src/comm/LogReplayLink.h +++ b/src/comm/LogReplayLink.h @@ -121,6 +121,7 @@ private: void _finishPlayback(void); void _playbackError(void); void _resetPlaybackToBeginning(void); + void _signalCurrentLogTimeSecs(void); // Virtuals from LinkInterface virtual bool _connect(void); diff --git a/src/ui/QGCMAVLinkLogPlayer.cc b/src/ui/QGCMAVLinkLogPlayer.cc index 6a7d83b..e28824f 100644 --- a/src/ui/QGCMAVLinkLogPlayer.cc +++ b/src/ui/QGCMAVLinkLogPlayer.cc @@ -142,7 +142,6 @@ void QGCMAVLinkLogPlayer::_playbackStarted(void) _enablePlaybackControls(true); _ui->playButton->setChecked(true); _ui->playButton->setIcon(QIcon(":/res/Pause")); - _ui->positionSlider->setEnabled(false); } /// Signalled from LogReplayLink when replay is paused @@ -150,7 +149,6 @@ void QGCMAVLinkLogPlayer::_playbackPaused(void) { _ui->playButton->setIcon(QIcon(":/res/Play")); _ui->playButton->setChecked(false); - _ui->positionSlider->setEnabled(true); } void QGCMAVLinkLogPlayer::_playbackPercentCompleteChanged(int percentComplete) diff --git a/src/ui/QGCMAVLinkLogPlayer.ui b/src/ui/QGCMAVLinkLogPlayer.ui index f80f6ac..2253c90 100644 --- a/src/ui/QGCMAVLinkLogPlayer.ui +++ b/src/ui/QGCMAVLinkLogPlayer.ui @@ -75,7 +75,7 @@ 100 - false + true Qt::Horizontal From 7ad9bfaae6bdcda63f14b6a8fadb774f87d2fff3 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 2 Jul 2019 12:17:19 -0700 Subject: [PATCH 3/8] Cherry pick full-width status bar from master --- src/ui/MainWindow.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 7a98324..6dc0e56 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -271,7 +271,7 @@ void MainWindow::_buildCommonWidgets(void) // Log player // TODO: Make this optional with a preferences setting or under a "View" menu logPlayer = new QGCMAVLinkLogPlayer(statusBar()); - statusBar()->addPermanentWidget(logPlayer); + statusBar()->addPermanentWidget(logPlayer, 1); // Populate widget menu for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) { From 1087c224f9e9629610e6a6c5aa1ccc41b1b71582 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 2 Jul 2019 16:08:37 -0700 Subject: [PATCH 4/8] Cherry-pick android joystick crash fixes from master --- android/src/org/mavlink/qgroundcontrol/QGCActivity.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/android/src/org/mavlink/qgroundcontrol/QGCActivity.java b/android/src/org/mavlink/qgroundcontrol/QGCActivity.java index 9923c8f..ea225c2 100644 --- a/android/src/org/mavlink/qgroundcontrol/QGCActivity.java +++ b/android/src/org/mavlink/qgroundcontrol/QGCActivity.java @@ -106,7 +106,7 @@ public class QGCActivity extends QtActivity String action = intent.getAction(); if (ACTION_USB_PERMISSION.equals(action)) { UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); - if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { + if (accessory != null && intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { openAccessory(accessory); } } else if( UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { @@ -710,6 +710,9 @@ public class QGCActivity extends QtActivity UsbAccessory[] accessories = _usbManager.getAccessoryList(); if (accessories != null) { for (UsbAccessory usbAccessory : accessories) { + if (usbAccessory == null) { + continue; + } if (_usbManager.hasPermission(usbAccessory)) { openAccessory(usbAccessory); } else { From 6870e299cbc33bad5420d58c8da285e7104e4878 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 16 Jul 2019 14:48:24 -0700 Subject: [PATCH 5/8] Guard against no geometry being set --- src/VideoStreaming/VideoItem.cc | 26 ++++++++++++++++++++------ src/VideoStreaming/VideoItem.h | 4 ++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/VideoStreaming/VideoItem.cc b/src/VideoStreaming/VideoItem.cc index 2a138cf..8a872c6 100644 --- a/src/VideoStreaming/VideoItem.cc +++ b/src/VideoStreaming/VideoItem.cc @@ -78,6 +78,17 @@ void VideoItem::setSurface(VideoSurface *surface) } #if defined(QGC_GST_STREAMING) +QSGGeometry* VideoItem::_createDefaultGeometry(QRectF& rectBound) +{ + QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); + geometry->vertexDataAsPoint2D()[0].set(rectBound.x(), rectBound.y()); + geometry->vertexDataAsPoint2D()[1].set(rectBound.x(), rectBound.height()); + geometry->vertexDataAsPoint2D()[2].set(rectBound.width(), rectBound.y()); + geometry->vertexDataAsPoint2D()[3].set(rectBound.width(), rectBound.height()); + + return geometry; +} + QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) { QRectF r = boundingRect(); @@ -103,19 +114,22 @@ QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) newNode = oldNode; } if (r != _data->targetArea) { - QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); - geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y()); - geometry->vertexDataAsPoint2D()[1].set(r.x(), r.height()); - geometry->vertexDataAsPoint2D()[2].set(r.width(), r.y()); - geometry->vertexDataAsPoint2D()[3].set(r.width(), r.height()); QSGGeometryNode *node = static_cast(newNode); - node->setGeometry(geometry); + node->setGeometry(_createDefaultGeometry(r)); _data->targetArea = r; } } else { g_signal_emit_by_name(_data->surface.data()->_data->videoSink, "update-node", (void*)oldNode, r.x(), r.y(), r.width(), r.height(), (void**)&newNode); } + // Sometimes we can still end up here with no geometry when gstreamer fails to create it for whatever reason. If that happens it can + // cause crashes. + QSGGeometryNode *node = static_cast(newNode); + if (node->geometry() == nullptr) { + qDebug() << "Creating default geom"; + node->setGeometry(_createDefaultGeometry(r)); + } + return newNode; } #endif diff --git a/src/VideoStreaming/VideoItem.h b/src/VideoStreaming/VideoItem.h index eeb1caa..5044604 100644 --- a/src/VideoStreaming/VideoItem.h +++ b/src/VideoStreaming/VideoItem.h @@ -19,6 +19,8 @@ #include #include "VideoSurface.h" +class QSGGeometry; + class VideoItem : public QQuickItem { Q_OBJECT @@ -40,6 +42,8 @@ protected: private: #if defined(QGC_GST_STREAMING) + QSGGeometry* _createDefaultGeometry(QRectF& rectBound); + struct Private; Private* const _data; #endif From bd8590de57bf94701e186056c2324af371490377 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 16 Jul 2019 14:49:25 -0700 Subject: [PATCH 6/8] Update --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index aeccabe..cdb34db 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,7 @@ Note: This file only contains high level features or important fixes. * Major rewrite and bug fix pass through Structure Scan. Previous version had such bad problems that it can no longer be supported. Plans with Structure Scan will need to be recreated. New QGC will not load old Structure Scan plans. ### 3.5.4 - Not yet released +* Guard against null geometry coming from gstreamer which can cause crashes * Add .apj file selection support to custom firmware flash ### 3.5.3 - Stable From 02bd3aebf67127fbe7ba4244620a025734dc3f1a Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Thu, 18 Jul 2019 10:02:00 -0700 Subject: [PATCH 7/8] Switch to 1.14.4 gstreamer --- .appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 8440d7a..f11b89f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -19,17 +19,17 @@ install: - mkdir %LOCALAPPDATA%\QtProject && copy test\qtlogging.ini %LOCALAPPDATA%\QtProject\ - ps: | Write-Host "Installing GStreamer..." -ForegroundColor Cyan - $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-x86-1.5.2.msi" + $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-x86-1.14.4.msi" Write-Host "Downloading..." - (New-Object Net.WebClient).DownloadFile('https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-x86-1.5.2.msi', $msiPath) + (New-Object Net.WebClient).DownloadFile('https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-x86-1.14.4.msi', $msiPath) Write-Host "Installing..." cmd /c start /wait msiexec /package $msiPath /passive ADDLOCAL=ALL Write-Host "Installed" -ForegroundColor Green - ps: | Write-Host "Installing GStreamer dev..." -ForegroundColor Cyan - $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-devel-x86-1.5.2.msi" + $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-devel-x86-1.14.4.msi" Write-Host "Downloading..." - (New-Object Net.WebClient).DownloadFile('https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-devel-x86-1.5.2.msi', $msiPath) + (New-Object Net.WebClient).DownloadFile('https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-devel-x86-1.14.4.msi', $msiPath) Write-Host "Installing..." cmd /c start /wait msiexec /package $msiPath /passive ADDLOCAL=ALL Write-Host "Installed" -ForegroundColor Green From 44b7818c5c0c6fa4432a49bd50ea3d974effdab6 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Fri, 19 Jul 2019 09:18:54 -0700 Subject: [PATCH 8/8] Fix merge screwup --- src/comm/LogReplayLink.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/comm/LogReplayLink.cc b/src/comm/LogReplayLink.cc index 8b1f486..a7be15b 100644 --- a/src/comm/LogReplayLink.cc +++ b/src/comm/LogReplayLink.cc @@ -686,8 +686,3 @@ QString LogReplayLinkController::_secondsToHMS(int seconds) return tr("%1h:%2m:%3s").arg(hoursPart, 2).arg(minutesPart, 2).arg(secondsPart, 2); } - -void LogReplayLink::_signalCurrentLogTimeSecs(void) -{ - emit currentLogTimeSecs((_logCurrentTimeUSecs - _logStartTimeUSecs) / 1000000); -}