diff --git a/custom-example/qgroundcontrol.qrc b/custom-example/qgroundcontrol.qrc
index aaa0b962bbc..0f249c9d16d 100644
--- a/custom-example/qgroundcontrol.qrc
+++ b/custom-example/qgroundcontrol.qrc
@@ -76,7 +76,7 @@
../src/UI/preferences/PlanViewSettings.qml
../src/UI/toolbar/PlanViewToolBar.qml
../src/FlightDisplay/PreFlightCheckList.qml
- ../src/VehicleSetup/PX4FlowSensor.qml
+ ../src/VehicleSetup/OpticalFlowSensor.qml
../src/FlightMap/Widgets/VerticalCompassAttitude.qml
../src/FlightMap/Widgets/HorizontalCompassAttitude.qml
../src/AnalyzeView/AnalyzePage.qml
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 26d342e63a7..61516930996 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -76,7 +76,7 @@
src/UI/preferences/PlanViewSettings.qml
src/UI/toolbar/PlanViewToolBar.qml
src/FlightDisplay/PreFlightCheckList.qml
- src/VehicleSetup/PX4FlowSensor.qml
+ src/VehicleSetup/OpticalFlowSensor.qml
src/FlightMap/Widgets/VerticalCompassAttitude.qml
src/FlightMap/Widgets/HorizontalCompassAttitude.qml
src/AnalyzeView/AnalyzePage.qml
diff --git a/src/Comms/LinkInterface.cc b/src/Comms/LinkInterface.cc
index 55d651908ea..fb1391c3ab3 100644
--- a/src/Comms/LinkInterface.cc
+++ b/src/Comms/LinkInterface.cc
@@ -23,10 +23,9 @@
QGC_LOGGING_CATEGORY(LinkInterfaceLog, "LinkInterfaceLog")
-LinkInterface::LinkInterface(SharedLinkConfigurationPtr &config, bool isPX4Flow, QObject *parent)
+LinkInterface::LinkInterface(SharedLinkConfigurationPtr &config, QObject *parent)
: QThread(parent)
, _config(config)
- , _isPX4Flow(isPX4Flow)
{
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
diff --git a/src/Comms/LinkInterface.h b/src/Comms/LinkInterface.h
index 41fce26a01b..9407140ad5c 100644
--- a/src/Comms/LinkInterface.h
+++ b/src/Comms/LinkInterface.h
@@ -23,8 +23,6 @@ class LinkInterface : public QThread
{
Q_OBJECT
- Q_PROPERTY(bool isPX4Flow READ isPX4Flow CONSTANT)
-
friend class LinkManager;
public:
@@ -40,7 +38,6 @@ class LinkInterface : public QThread
const SharedLinkConfigurationPtr linkConfiguration() const { return _config; }
uint8_t mavlinkChannel() const;
bool mavlinkChannelIsSet() const;
- bool isPX4Flow() const { return _isPX4Flow; }
bool decodedFirstMavlinkPacket(void) const { return _decodedFirstMavlinkPacket; }
void setDecodedFirstMavlinkPacket(bool decodedFirstMavlinkPacket) { _decodedFirstMavlinkPacket = decodedFirstMavlinkPacket; }
void writeBytesThreadSafe(const char *bytes, int length);
@@ -58,7 +55,7 @@ class LinkInterface : public QThread
protected:
/// Links are only created by LinkManager so constructor is not public
- LinkInterface(SharedLinkConfigurationPtr &config, bool isPX4Flow = false, QObject *parent = nullptr);
+ LinkInterface(SharedLinkConfigurationPtr &config, QObject *parent = nullptr);
/// Called by the LinkManager during LinkInterface construction instructing the link to setup channels.
/// Default implementation allocates a single channel. But some link types (such as MockLink) need more than one.
@@ -80,7 +77,6 @@ private slots:
uint8_t _mavlinkChannel = std::numeric_limits::max();
bool _decodedFirstMavlinkPacket = false;
- bool _isPX4Flow = false;
int _vehicleReferenceCount = 0;
bool _signingSignatureFailure = false;
};
diff --git a/src/Comms/LinkManager.cc b/src/Comms/LinkManager.cc
index f0852863f7c..43df54e8d38 100644
--- a/src/Comms/LinkManager.cc
+++ b/src/Comms/LinkManager.cc
@@ -109,17 +109,15 @@ void LinkManager::createConnectedLink(const LinkConfiguration *config)
}
}
-bool LinkManager::createConnectedLink(SharedLinkConfigurationPtr &config, bool isPX4Flow)
+bool LinkManager::createConnectedLink(SharedLinkConfigurationPtr &config)
{
SharedLinkInterfacePtr link = nullptr;
switch(config->type()) {
#ifndef NO_SERIAL_LINK
case LinkConfiguration::TypeSerial:
- link = std::make_shared(config, isPX4Flow);
+ link = std::make_shared(config);
break;
-#else
- Q_UNUSED(isPX4Flow)
#endif
case LinkConfiguration::TypeUdp:
link = std::make_shared(config);
@@ -845,9 +843,6 @@ void LinkManager::_addSerialAutoConnectLink()
pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName, portInfo.portName().trimmed()));
pSerialConfig->setUsbDirect(true);
break;
- case QGCSerialPortInfo::BoardTypePX4Flow:
- pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName, portInfo.portName().trimmed()));
- break;
case QGCSerialPortInfo::BoardTypeSiKRadio:
pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName, portInfo.portName().trimmed()));
break;
@@ -872,7 +867,7 @@ void LinkManager::_addSerialAutoConnectLink()
pSerialConfig->setAutoConnect(true);
SharedLinkConfigurationPtr sharedConfig(pSerialConfig);
- createConnectedLink(sharedConfig, boardType == QGCSerialPortInfo::BoardTypePX4Flow);
+ createConnectedLink(sharedConfig);
}
}
}
@@ -894,11 +889,6 @@ bool LinkManager::_allowAutoConnectToBoard(QGCSerialPortInfo::BoardType_t boardT
return true;
}
break;
- case QGCSerialPortInfo::BoardTypePX4Flow:
- if (_autoConnectSettings->autoConnectPX4Flow()->rawValue().toBool()) {
- return true;
- }
- break;
case QGCSerialPortInfo::BoardTypeSiKRadio:
if (_autoConnectSettings->autoConnectSiKRadio()->rawValue().toBool()) {
return true;
diff --git a/src/Comms/LinkManager.h b/src/Comms/LinkManager.h
index 3e67279b7b0..59359d7a69d 100644
--- a/src/Comms/LinkManager.h
+++ b/src/Comms/LinkManager.h
@@ -87,7 +87,7 @@ class LinkManager : public QGCTool
void setConnectionsAllowed() { _connectionsSuspended = false; }
/// Creates, connects (and adds) a link based on the given configuration instance.
- bool createConnectedLink(SharedLinkConfigurationPtr &config, bool isPX4Flow = false);
+ bool createConnectedLink(SharedLinkConfigurationPtr &config);
/// Returns pointer to the mavlink forwarding link, or nullptr if it does not exist
SharedLinkInterfacePtr mavlinkForwardingLink();
diff --git a/src/Comms/MockLink/MockLink.Parameter.MetaData.json b/src/Comms/MockLink/MockLink.Parameter.MetaData.json
index a3301a6e374..070777ce995 100644
--- a/src/Comms/MockLink/MockLink.Parameter.MetaData.json
+++ b/src/Comms/MockLink/MockLink.Parameter.MetaData.json
@@ -18198,49 +18198,6 @@
"shortDesc": "External I2C probe",
"longDesc": "Probe for optional external I2C devices."
},
- {
- "name": "SENS_FLOW_ROT",
- "type": "Int32",
- "default": 6,
- "group": "Sensors",
- "shortDesc": "PX4Flow board rotation",
- "longDesc": "This parameter defines the yaw rotation of the PX4FLOW board relative to the vehicle body frame. Zero rotation is defined as X on flow board pointing towards front of vehicle. The recommneded installation default for the PX4FLOW board is with the Y axis forward (270 deg yaw).",
- "rebootRequired": true,
- "values": [
- {
- "value": 0,
- "description": "No rotation"
- },
- {
- "value": 1,
- "description": "Yaw 45\u00b0"
- },
- {
- "value": 2,
- "description": "Yaw 90\u00b0"
- },
- {
- "value": 3,
- "description": "Yaw 135\u00b0"
- },
- {
- "value": 4,
- "description": "Yaw 180\u00b0"
- },
- {
- "value": 5,
- "description": "Yaw 225\u00b0"
- },
- {
- "value": 6,
- "description": "Yaw 270\u00b0"
- },
- {
- "value": 7,
- "description": "Yaw 315\u00b0"
- }
- ]
- },
{
"name": "SENS_GPS_MASK",
"type": "Int32",
diff --git a/src/Comms/QGCSerialPortInfo.cc b/src/Comms/QGCSerialPortInfo.cc
index 5855b250d6f..ac21695ab93 100644
--- a/src/Comms/QGCSerialPortInfo.cc
+++ b/src/Comms/QGCSerialPortInfo.cc
@@ -237,8 +237,6 @@ QString QGCSerialPortInfo::_boardTypeToString(BoardType_t boardType)
return QStringLiteral("Pixhawk");
case BoardTypeSiKRadio:
return QStringLiteral("SiK Radio");
- case BoardTypePX4Flow:
- return QStringLiteral("PX4 Flow");
case BoardTypeOpenPilot:
return QStringLiteral("OpenPilot");
case BoardTypeRTKGPS:
@@ -305,7 +303,6 @@ bool QGCSerialPortInfo::canFlash() const
if (getBoardInfo(boardType, name)) {
switch(boardType) {
case QGCSerialPortInfo::BoardTypePixhawk:
- case QGCSerialPortInfo::BoardTypePX4Flow:
case QGCSerialPortInfo::BoardTypeSiKRadio:
return true;
default:
diff --git a/src/Comms/QGCSerialPortInfo.h b/src/Comms/QGCSerialPortInfo.h
index 9749b14795e..652d6bcae8c 100644
--- a/src/Comms/QGCSerialPortInfo.h
+++ b/src/Comms/QGCSerialPortInfo.h
@@ -35,7 +35,6 @@ class QGCSerialPortInfo : public QSerialPortInfo
enum BoardType_t {
BoardTypePixhawk,
BoardTypeSiKRadio,
- BoardTypePX4Flow,
BoardTypeOpenPilot,
BoardTypeRTKGPS,
BoardTypeUnknown
@@ -68,7 +67,6 @@ class QGCSerialPortInfo : public QSerialPortInfo
};
static constexpr const BoardClassString2BoardType_t _rgBoardClass2BoardType[BoardTypeUnknown] = {
{ "Pixhawk", QGCSerialPortInfo::BoardTypePixhawk },
- { "PX4 Flow", QGCSerialPortInfo::BoardTypePX4Flow },
{ "RTK GPS", QGCSerialPortInfo::BoardTypeRTKGPS },
{ "SiK Radio", QGCSerialPortInfo::BoardTypeSiKRadio },
{ "OpenPilot", QGCSerialPortInfo::BoardTypeOpenPilot },
diff --git a/src/Comms/SerialLink.cc b/src/Comms/SerialLink.cc
index 8af332f7be7..eecad92fbd9 100644
--- a/src/Comms/SerialLink.cc
+++ b/src/Comms/SerialLink.cc
@@ -22,8 +22,8 @@
QGC_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog")
-SerialLink::SerialLink(SharedLinkConfigurationPtr& config, bool isPX4Flow)
- : LinkInterface(config, isPX4Flow)
+SerialLink::SerialLink(SharedLinkConfigurationPtr& config)
+ : LinkInterface(config)
, _serialConfig(qobject_cast(config.get()))
{
qRegisterMetaType();
diff --git a/src/Comms/SerialLink.h b/src/Comms/SerialLink.h
index b2cd9e1cc1f..3f4e4ef066e 100644
--- a/src/Comms/SerialLink.h
+++ b/src/Comms/SerialLink.h
@@ -104,7 +104,7 @@ class SerialLink : public LinkInterface
Q_OBJECT
public:
- SerialLink(SharedLinkConfigurationPtr& config, bool isPX4Flow = false);
+ SerialLink(SharedLinkConfigurationPtr& config);
virtual ~SerialLink();
// LinkInterface overrides
diff --git a/src/Comms/USBBoardInfo.json b/src/Comms/USBBoardInfo.json
index 780b5d9e72a..e3b3925bd2f 100644
--- a/src/Comms/USBBoardInfo.json
+++ b/src/Comms/USBBoardInfo.json
@@ -45,8 +45,6 @@
{ "vendorID": 13735, "productID": 1, "boardClass": "Pixhawk", "name": "ThePeach FCC-K1" },
{ "vendorID": 13735, "productID": 2, "boardClass": "Pixhawk", "name": "ThePeach FCC-R1" },
- { "vendorID": 9900, "productID": 21, "boardClass": "PX4 Flow", "name": "PX4 Flow" },
-
{ "vendorID": 1027, "productID": 24597, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "3DR Radio" },
{ "vendorID": 1027, "productID": 24577, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "3DR Radio on FTDI" },
{ "vendorID": 4292, "productID": 60000, "boardClass": "SiK Radio", "name": "SiK Radio", "comment": "SILabs Radio" },
@@ -96,7 +94,6 @@
{ "regExp": "^mRoControlZeroF7", "boardClass": "Pixhawk" },
{ "regExp": "^ARK FMU v6X.x$", "boardClass": "Pixhawk" },
{ "regExp": "^ARK BL FMU v6X.x$", "boardClass": "Pixhawk" },
- { "regExp": "PX4.*Flow", "boardClass": "PX4 Flow" },
{ "regExp": "^FT231X USB UART$", "boardClass": "SiK Radio" },
{ "regExp": "USB UART$", "boardClass": "SiK Radio", "androidOnly": true, "comment": "Very broad fallback, too dangerous for non-android" }
],
diff --git a/src/MAVLink/ImageProtocolManager.cc b/src/MAVLink/ImageProtocolManager.cc
index 19d99a90c2c..08f700139c1 100644
--- a/src/MAVLink/ImageProtocolManager.cc
+++ b/src/MAVLink/ImageProtocolManager.cc
@@ -10,27 +10,56 @@
#include "ImageProtocolManager.h"
#include "QGCLoggingCategory.h"
-QGC_LOGGING_CATEGORY(ImageProtocolManagerLog, "ImageProtocolManagerLog")
+QGC_LOGGING_CATEGORY(ImageProtocolManagerLog, "qgc.mavlink.imageprotocolmanager")
-ImageProtocolManager::ImageProtocolManager(void)
+ImageProtocolManager::ImageProtocolManager(QObject *parent)
+ : QObject(parent)
{
- memset(&_imageHandshake, 0, sizeof(_imageHandshake));
+ // qCDebug(ImageProtocolManagerLog) << Q_FUNC_INFO << this;
}
-void ImageProtocolManager::mavlinkMessageReceived(const mavlink_message_t& message)
+ImageProtocolManager::~ImageProtocolManager()
+{
+ // qCDebug(ImageProtocolManagerLog) << Q_FUNC_INFO << this;
+}
+
+bool ImageProtocolManager::requestImage(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t &message)
+{
+ // Check if there is already an image transmission going on
+ if (_imageHandshake.packets != 0) {
+ return false;
+ }
+
+ constexpr mavlink_data_transmission_handshake_t data = {
+ 0, 0, 0, 0,
+ MAVLINK_DATA_STREAM_IMG_JPEG,
+ 0,
+ 50
+ };
+ (void) mavlink_msg_data_transmission_handshake_encode_chan(system_id, component_id, chan, &message, &data);
+
+ return true;
+}
+
+void ImageProtocolManager::cancelRequest(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t &message)
+{
+ constexpr mavlink_data_transmission_handshake_t data{0};
+ (void) mavlink_msg_data_transmission_handshake_encode_chan(system_id, component_id, chan, &message, &data);
+}
+
+void ImageProtocolManager::mavlinkMessageReceived(const mavlink_message_t &message)
{
switch (message.msgid) {
case MAVLINK_MSG_ID_DATA_TRANSMISSION_HANDSHAKE:
{
- if (_imageHandshake.packets) {
+ if (_imageHandshake.packets > 0) {
qCWarning(ImageProtocolManagerLog) << "DATA_TRANSMISSION_HANDSHAKE: Previous image transmission incomplete.";
}
_imageBytes.clear();
mavlink_msg_data_transmission_handshake_decode(&message, &_imageHandshake);
qCDebug(ImageProtocolManagerLog) << QStringLiteral("DATA_TRANSMISSION_HANDSHAKE: type(%1) width(%2) height (%3)").arg(_imageHandshake.type).arg(_imageHandshake.width).arg(_imageHandshake.height);
- }
break;
-
+ }
case MAVLINK_MSG_ID_ENCAPSULATED_DATA:
{
if (_imageHandshake.packets == 0) {
@@ -41,71 +70,74 @@ void ImageProtocolManager::mavlinkMessageReceived(const mavlink_message_t& messa
mavlink_encapsulated_data_t encapsulatedData;
mavlink_msg_encapsulated_data_decode(&message, &encapsulatedData);
- int bytePosition = encapsulatedData.seqnr * _imageHandshake.payload;
- if (bytePosition >= static_cast(_imageHandshake.size)) {
- qCWarning(ImageProtocolManagerLog) << "ENCAPSULATED_DATA: seqnr is past end of image size. seqnr:" << encapsulatedData.seqnr << "_imageHandshake.size" << _imageHandshake.size;
+ uint32_t bytePosition = encapsulatedData.seqnr * _imageHandshake.payload;
+ if (bytePosition >= _imageHandshake.size) {
+ qCWarning(ImageProtocolManagerLog) << "ENCAPSULATED_DATA: seqnr is past end of image size. seqnr:" << encapsulatedData.seqnr << "_imageHandshake.size:" << _imageHandshake.size;
break;
}
- for (uint8_t i=0; i<_imageHandshake.payload; i++) {
+ for (uint8_t i = 0; i < _imageHandshake.payload; i++) {
_imageBytes[bytePosition] = encapsulatedData.data[i];
bytePosition++;
}
// We use the packets field to track completion
_imageHandshake.packets--;
-
if (_imageHandshake.packets == 0) {
// We have all the packets
- emit imageReady();
+ emit imageReady(_getImage());
+
+ _flowImageIndex++;
+ emit flowImageIndexChanged(_flowImageIndex);
}
- }
break;
-
+ }
default:
break;
}
}
-QImage ImageProtocolManager::getImage(void)
+QImage ImageProtocolManager::_getImage()
{
QImage image;
if (_imageBytes.isEmpty()) {
- qCWarning(ImageProtocolManagerLog) << "getImage: Called when no image available";
- } else if (_imageHandshake.packets) {
- qCWarning(ImageProtocolManagerLog) << "getImage: Called when image is imcomplete. _imageHandshake.packets:" << _imageHandshake.packets;
- } else {
- switch (_imageHandshake.type) {
- case MAVLINK_DATA_STREAM_IMG_RAW8U:
- case MAVLINK_DATA_STREAM_IMG_RAW32U:
- {
- // Construct PGM header
- QString header("P5\n%1 %2\n%3\n");
- header = header.arg(_imageHandshake.width).arg(_imageHandshake.height).arg(255 /* image colors */);
-
- QByteArray tmpImage(header.toStdString().c_str(), header.length());
- tmpImage.append(_imageBytes);
-
- if (!image.loadFromData(tmpImage, "PGM")) {
- qCWarning(ImageProtocolManagerLog) << "getImage: IMG_RAW8U QImage::loadFromData failed";
- }
- }
- break;
+ qCWarning(ImageProtocolManagerLog) << Q_FUNC_INFO << "Called when no image available";
+ return image;
+ }
- case MAVLINK_DATA_STREAM_IMG_BMP:
- case MAVLINK_DATA_STREAM_IMG_JPEG:
- case MAVLINK_DATA_STREAM_IMG_PGM:
- case MAVLINK_DATA_STREAM_IMG_PNG:
- if (!image.loadFromData(_imageBytes)) {
- qCWarning(ImageProtocolManagerLog) << "getImage: Known header QImage::loadFromData failed";
- }
- break;
+ if (_imageHandshake.packets > 0) {
+ qCWarning(ImageProtocolManagerLog) << Q_FUNC_INFO << "Called when image is imcomplete. _imageHandshake.packets:" << _imageHandshake.packets;
+ return image;
+ }
- default:
- qCWarning(ImageProtocolManagerLog) << "getImage: Unsupported image type:" << _imageHandshake.type;
- break;
+ switch (_imageHandshake.type) {
+ case MAVLINK_DATA_STREAM_IMG_RAW8U:
+ case MAVLINK_DATA_STREAM_IMG_RAW32U:
+ {
+ // Construct PGM header
+ const QString header = QStringLiteral("P5\n%1 %2\n255\n").arg(_imageHandshake.width).arg(_imageHandshake.height);
+
+ QByteArray tempImage(header.toStdString().c_str(), header.length());
+ (void) tempImage.append(_imageBytes);
+
+ if (!image.loadFromData(tempImage, "PGM")) {
+ qCWarning(ImageProtocolManagerLog) << Q_FUNC_INFO << "IMG_RAW8U QImage::loadFromData failed";
+ }
+ break;
+ }
+ case MAVLINK_DATA_STREAM_IMG_BMP:
+ case MAVLINK_DATA_STREAM_IMG_JPEG:
+ case MAVLINK_DATA_STREAM_IMG_PGM:
+ case MAVLINK_DATA_STREAM_IMG_PNG:
+ if (!image.loadFromData(_imageBytes)) {
+ qCWarning(ImageProtocolManagerLog) << Q_FUNC_INFO << "Known header QImage::loadFromData failed";
}
+ break;
+
+ default:
+ qCWarning(ImageProtocolManagerLog) << Q_FUNC_INFO << "Unsupported image type:" << _imageHandshake.type;
+ break;
}
return image;
diff --git a/src/MAVLink/ImageProtocolManager.h b/src/MAVLink/ImageProtocolManager.h
index 26214187d72..1a4a7994bd8 100644
--- a/src/MAVLink/ImageProtocolManager.h
+++ b/src/MAVLink/ImageProtocolManager.h
@@ -11,30 +11,39 @@
#include "MAVLinkLib.h"
-#include
#include
#include
+#include
#include
Q_DECLARE_LOGGING_CATEGORY(ImageProtocolManagerLog)
-// Supports the Mavlink image transmission protocol (https://mavlink.io/en/services/image_transmission.html).
-// Mainly used by optical flow cameras.
+/// Supports the Mavlink image transmission protocol (https://mavlink.io/en/services/image_transmission.html).
+/// Mainly used by optical flow cameras.
class ImageProtocolManager : public QObject
{
Q_OBJECT
-
+
public:
- ImageProtocolManager(void);
+ ImageProtocolManager(QObject *parent = nullptr);
+ ~ImageProtocolManager();
- void mavlinkMessageReceived (const mavlink_message_t& message);
- QImage getImage (void);
+ uint32_t flowImageIndex() const { return _flowImageIndex; }
+
+ bool requestImage(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t &message);
+ void cancelRequest(uint8_t system_id, uint8_t component_id, uint8_t chan, mavlink_message_t &message);
signals:
- void imageReady(void);
+ void imageReady(const QImage &image);
+ void flowImageIndexChanged(uint32_t index);
+
+public slots:
+ void mavlinkMessageReceived(const mavlink_message_t &message);
private:
- mavlink_data_transmission_handshake_t _imageHandshake;
- QByteArray _imageBytes;
+ QImage _getImage();
+ mavlink_data_transmission_handshake_t _imageHandshake{0};
+ QByteArray _imageBytes;
+ uint32_t _flowImageIndex = 0;
};
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index 41fb1467590..fbdb956f99d 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -420,7 +420,7 @@ void QGCApplication::_initForNormalAppBoot()
AudioOutput::instance()->init(_toolbox->settingsManager()->appSettings()->audioMuted());
FollowMe::instance()->init();
- // Image provider for PX4 Flow
+ // Image provider for Optical Flow
_qmlAppEngine->addImageProvider(qgcImageProviderId, new QGCImageProvider());
QQuickWindow* rootWindow = mainRootWindow();
diff --git a/src/QmlControls/QGCImageProvider.cc b/src/QmlControls/QGCImageProvider.cc
index 86d878e15f6..33afe65eb0b 100644
--- a/src/QmlControls/QGCImageProvider.cc
+++ b/src/QmlControls/QGCImageProvider.cc
@@ -14,54 +14,63 @@
QGCImageProvider::QGCImageProvider(QQmlImageProviderBase::ImageType imageType)
: QQuickImageProvider(imageType)
+ , _dummy(320, 240, QImage::Format_RGBA8888)
{
- //-- Dummy temporary image until something comes along
- m_image = QImage(320, 240, QImage::Format_RGBA8888);
- m_image.fill(Qt::black);
- QPainter painter(&m_image);
- QFont f = painter.font();
- f.setPixelSize(20);
- painter.setFont(f);
- painter.setPen(Qt::white);
- painter.drawText(QRectF(0, 0, 320, 240), Qt::AlignCenter, "Waiting...");
+ // qCDebug(ImageProtocolManagerLog) << Q_FUNC_INFO << this;
+
+ Q_ASSERT(imageType == QQmlImageProviderBase::ImageType::Image);
+
+ // Dummy temporary image until something comes along
+ _dummy.fill(Qt::black);
+ QPainter painter(&_dummy);
+ QFont f = painter.font();
+ f.setPixelSize(20);
+ painter.setFont(f);
+ painter.setPen(Qt::white);
+ painter.drawText(QRectF(0, 0, _dummy.width(), _dummy.height()), Qt::AlignCenter, QStringLiteral("Waiting..."));
+ _images[0] = _dummy;
}
QGCImageProvider::~QGCImageProvider()
{
-
+ // qCDebug(ImageProtocolManagerLog) << Q_FUNC_INFO << this;
}
-QImage QGCImageProvider::requestImage(const QString & /* image url with vehicle id*/, QSize *, const QSize &)
+QImage QGCImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
-/*
- The QML side will request an image using a special URL, which we've registered as QGCImages.
- The URL follows this format (or anything you want to make out of it after the "QGCImages" part):
+ Q_UNUSED(requestedSize);
- "image://QGCImages/vvv/iii"
+ if (id.isEmpty()) {
+ return _dummy;
+ }
- Where:
- vvv: Some vehicle id
- iii: An auto incremented index (which forces the Item to reload the image)
+ if (!id.contains("/")) {
+ return _dummy;
+ }
- The image index is incremented each time a new image arrives. A signal is emitted and the QML side
- updates its contents automatically.
+ const QStringList url = id.split('/', Qt::SkipEmptyParts);
+ if (url.size() != 2) {
+ return _dummy;
+ }
- Image {
- source: "image://QGCImages/" + _activeVehicle.id + "/" + _activeVehicle.flowImageIndex
- width: parent.width * 0.5
- height: width * 0.75
- cache: false
- anchors.centerIn: parent
- fillMode: Image.PreserveAspectFit
- }
+ bool ok = false;
+ const uint8_t vehicleId = url[0].toUInt(&ok);
+ if (!ok) {
+ return _dummy;
+ }
- For now, we don't even look at the URL. This will have to be fixed if we're to support multiple
- vehicles transmitting flow images.
-*/
- return m_image;
-}
+ const uint8_t index = url[1].toUInt(&ok);
+ if (!ok) {
+ return _dummy;
+ }
-void QGCImageProvider::setImage(QImage* pImage, int /* vehicle id*/)
-{
- m_image = pImage->mirrored();
+ if (!_images.contains(vehicleId)) {
+ return _dummy;
+ }
+
+ const QImage image = _images[vehicleId];
+ // image->scaled(requestedSize);
+ *size = image.size();
+
+ return image;
}
diff --git a/src/QmlControls/QGCImageProvider.h b/src/QmlControls/QGCImageProvider.h
index 23ea49f7544..f5feb75dbb1 100644
--- a/src/QmlControls/QGCImageProvider.h
+++ b/src/QmlControls/QGCImageProvider.h
@@ -10,23 +10,20 @@
#pragma once
#include
+#include
#include
-// This is used to expose images from ImageProtocolHandler
+/// This is used to expose images from ImageProtocolHandler
class QGCImageProvider : public QQuickImageProvider
{
public:
QGCImageProvider(QQmlImageProviderBase::ImageType type = QQmlImageProviderBase::ImageType::Image);
~QGCImageProvider();
- void setImage(QImage* pImage, int id = 0);
-
- QImage requestImage(const QString& id, QSize* size, const QSize& requestedSize) override;
+ QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) final;
+ void setImage(const QImage &image, uint8_t vehicleId = 0) { _images[vehicleId] = image.mirrored(); }
private:
- //-- TODO: For now this is holding a single image. If you happen to have two
- // or more vehicles with flow, it will not work. To properly manage that condition
- // this should be a map between each vehicle and its image. The URL provided
- // for the image request would contain the vehicle identification.
- QImage m_image;
+ QMap _images;
+ QImage _dummy;
};
diff --git a/src/Settings/AutoConnect.SettingsGroup.json b/src/Settings/AutoConnect.SettingsGroup.json
index eef97e9ea3a..cb733bf99b7 100644
--- a/src/Settings/AutoConnect.SettingsGroup.json
+++ b/src/Settings/AutoConnect.SettingsGroup.json
@@ -24,13 +24,6 @@
"type": "bool",
"default": true
},
-{
- "name": "autoConnectPX4Flow",
- "shortDesc": "Automatically connect to a P4 Flow",
- "longDesc": "If this option is enabled GroundControl will automatically connect to a PX4 Flow board which is connected via USB.",
- "type": "bool",
- "default": true
-},
{
"name": "autoConnectRTKGPS",
"shortDesc": "Automatically connect to an RTK GPS",
diff --git a/src/Settings/AutoConnectSettings.cc b/src/Settings/AutoConnectSettings.cc
index ccd115ea362..0a2aac4c68a 100644
--- a/src/Settings/AutoConnectSettings.cc
+++ b/src/Settings/AutoConnectSettings.cc
@@ -45,17 +45,6 @@ DECLARE_SETTINGSFACT_NO_FUNC(AutoConnectSettings, autoConnectSiKRadio)
return _autoConnectSiKRadioFact;
}
-DECLARE_SETTINGSFACT_NO_FUNC(AutoConnectSettings, autoConnectPX4Flow)
-{
- if (!_autoConnectPX4FlowFact) {
- _autoConnectPX4FlowFact = _createSettingsFact(autoConnectPX4FlowName);
-#ifdef Q_OS_IOS
- _autoConnectPX4FlowFact->setVisible(false);
-#endif
- }
- return _autoConnectPX4FlowFact;
-}
-
DECLARE_SETTINGSFACT_NO_FUNC(AutoConnectSettings, autoConnectRTKGPS)
{
if (!_autoConnectRTKGPSFact) {
diff --git a/src/Settings/AutoConnectSettings.h b/src/Settings/AutoConnectSettings.h
index 9753465f4f5..709d401b097 100644
--- a/src/Settings/AutoConnectSettings.h
+++ b/src/Settings/AutoConnectSettings.h
@@ -28,7 +28,6 @@ class AutoConnectSettings : public SettingsGroup
DEFINE_SETTINGFACT(autoConnectUDP)
DEFINE_SETTINGFACT(autoConnectPixhawk)
DEFINE_SETTINGFACT(autoConnectSiKRadio)
- DEFINE_SETTINGFACT(autoConnectPX4Flow)
DEFINE_SETTINGFACT(autoConnectRTKGPS)
DEFINE_SETTINGFACT(autoConnectLibrePilot)
DEFINE_SETTINGFACT(autoConnectNmeaPort)
diff --git a/src/UI/preferences/LinkSettings.qml b/src/UI/preferences/LinkSettings.qml
index cc21d3aabc0..d1a0f82f17b 100644
--- a/src/UI/preferences/LinkSettings.qml
+++ b/src/UI/preferences/LinkSettings.qml
@@ -29,17 +29,16 @@ SettingsPage {
Repeater {
id: autoConnectRepeater
- model: [
+ model: [
_autoConnectSettings.autoConnectPixhawk,
_autoConnectSettings.autoConnectSiKRadio,
- _autoConnectSettings.autoConnectPX4Flow,
_autoConnectSettings.autoConnectLibrePilot,
_autoConnectSettings.autoConnectUDP,
_autoConnectSettings.autoConnectZeroConf,
_autoConnectSettings.autoConnectRTKGPS,
]
- property var names: [ qsTr("Pixhawk"), qsTr("SiK Radio"), qsTr("PX4 Flow"), qsTr("LibrePilot"), qsTr("UDP"), qsTr("Zero-Conf"), qsTr("RTK") ]
+ property var names: [ qsTr("Pixhawk"), qsTr("SiK Radio"), qsTr("LibrePilot"), qsTr("UDP"), qsTr("Zero-Conf"), qsTr("RTK") ]
FactCheckBoxSlider {
Layout.fillWidth: true
@@ -223,4 +222,4 @@ SettingsPage {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/UI/toolbar/MainStatusIndicatorOfflinePage.qml b/src/UI/toolbar/MainStatusIndicatorOfflinePage.qml
index 11c937208ff..de6ddb387d3 100644
--- a/src/UI/toolbar/MainStatusIndicatorOfflinePage.qml
+++ b/src/UI/toolbar/MainStatusIndicatorOfflinePage.qml
@@ -89,17 +89,16 @@ ToolIndicatorPage {
Repeater {
id: autoConnectRepeater
- model: [
+ model: [
autoConnectSettings.autoConnectPixhawk,
autoConnectSettings.autoConnectSiKRadio,
- autoConnectSettings.autoConnectPX4Flow,
autoConnectSettings.autoConnectLibrePilot,
autoConnectSettings.autoConnectUDP,
autoConnectSettings.autoConnectZeroConf,
autoConnectSettings.autoConnectRTKGPS,
]
- property var names: [ qsTr("Pixhawk"), qsTr("SiK Radio"), qsTr("PX4 Flow"), qsTr("LibrePilot"), qsTr("UDP"), qsTr("Zero-Conf"), qsTr("RTK") ]
+ property var names: [ qsTr("Pixhawk"), qsTr("SiK Radio"), qsTr("LibrePilot"), qsTr("UDP"), qsTr("Zero-Conf"), qsTr("RTK") ]
FactCheckBoxSlider {
Layout.fillWidth: true
diff --git a/src/Vehicle/Components/ComponentInformationManager.cc b/src/Vehicle/Components/ComponentInformationManager.cc
index 21a3eadbdc4..40999d782c9 100644
--- a/src/Vehicle/Components/ComponentInformationManager.cc
+++ b/src/Vehicle/Components/ComponentInformationManager.cc
@@ -262,7 +262,7 @@ void RequestMetaDataTypeStateMachine::_stateRequestCompInfo(StateMachine* stateM
SharedLinkInterfacePtr sharedLink = vehicle->vehicleLinkManager()->primaryLink().lock();
if (sharedLink) {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(ComponentInformationManagerLog) << QStringLiteral("_stateRequestCompInfo Skipping component information %1 request due to link type").arg(requestMachine->typeToString());
stateMachine->advance();
} else {
@@ -296,7 +296,7 @@ void RequestMetaDataTypeStateMachine::_stateRequestCompInfoDeprecated(StateMachi
SharedLinkInterfacePtr sharedLink = vehicle->vehicleLinkManager()->primaryLink().lock();
if (sharedLink) {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(ComponentInformationManagerLog) << QStringLiteral("_stateRequestCompInfo Skipping component information %1 request due to link type").arg(requestMachine->typeToString());
stateMachine->advance();
} else {
diff --git a/src/Vehicle/InitialConnectStateMachine.cc b/src/Vehicle/InitialConnectStateMachine.cc
index 2197263f2da..8751517b465 100644
--- a/src/Vehicle/InitialConnectStateMachine.cc
+++ b/src/Vehicle/InitialConnectStateMachine.cc
@@ -80,7 +80,7 @@ void InitialConnectStateMachine::_stateRequestAutopilotVersion(StateMachine* sta
qCDebug(InitialConnectStateMachineLog) << "Skipping REQUEST_MESSAGE:AUTOPILOT_VERSION request due to no primary link";
connectMachine->advance();
} else {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(InitialConnectStateMachineLog) << "Skipping REQUEST_MESSAGE:AUTOPILOT_VERSION request due to link type";
connectMachine->advance();
} else {
@@ -192,7 +192,7 @@ void InitialConnectStateMachine::_stateRequestProtocolVersion(StateMachine* stat
qCDebug(InitialConnectStateMachineLog) << "Skipping REQUEST_MESSAGE:PROTOCOL_VERSION request due to no primary link";
connectMachine->advance();
} else {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(InitialConnectStateMachineLog) << "Skipping REQUEST_MESSAGE:PROTOCOL_VERSION request due to link type";
connectMachine->advance();
} else if (vehicle->apmFirmware()) {
@@ -312,7 +312,7 @@ void InitialConnectStateMachine::_stateRequestMission(StateMachine* stateMachine
qCDebug(InitialConnectStateMachineLog) << "_stateRequestMission: Skipping first mission load request due to no primary link";
connectMachine->advance();
} else {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(InitialConnectStateMachineLog) << "_stateRequestMission: Skipping first mission load request due to link type";
vehicle->_firstMissionLoadComplete();
} else {
@@ -337,7 +337,7 @@ void InitialConnectStateMachine::_stateRequestGeoFence(StateMachine* stateMachin
qCDebug(InitialConnectStateMachineLog) << "_stateRequestGeoFence: Skipping first geofence load request due to no primary link";
connectMachine->advance();
} else {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(InitialConnectStateMachineLog) << "_stateRequestGeoFence: Skipping first geofence load request due to link type";
vehicle->_firstGeoFenceLoadComplete();
} else {
@@ -367,7 +367,7 @@ void InitialConnectStateMachine::_stateRequestRallyPoints(StateMachine* stateMac
qCDebug(InitialConnectStateMachineLog) << "_stateRequestRallyPoints: Skipping first rally point load request due to no primary link";
connectMachine->advance();
} else {
- if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isPX4Flow() || sharedLink->isLogReplay()) {
+ if (sharedLink->linkConfiguration()->isHighLatency() || sharedLink->isLogReplay()) {
qCDebug(InitialConnectStateMachineLog) << "_stateRequestRallyPoints: Skipping first rally point load request due to link type";
vehicle->_firstRallyPointLoadComplete();
} else {
diff --git a/src/Vehicle/MultiVehicleManager.cc b/src/Vehicle/MultiVehicleManager.cc
index aca33655189..d5bbb22046d 100644
--- a/src/Vehicle/MultiVehicleManager.cc
+++ b/src/Vehicle/MultiVehicleManager.cc
@@ -69,26 +69,15 @@ void MultiVehicleManager::setToolbox(QGCToolbox *toolbox)
void MultiVehicleManager::_vehicleHeartbeatInfo(LinkInterface* link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType)
{
- // Special case PX4 Flow since depending on firmware it can have different settings. We force to the PX4 Firmware settings.
- if (link->isPX4Flow()) {
- vehicleId = 81;
- componentId = 50;//MAV_COMP_ID_AUTOPILOT1;
- vehicleFirmwareType = MAV_AUTOPILOT_GENERIC;
- vehicleType = 0;
- }
-
if (componentId != MAV_COMP_ID_AUTOPILOT1) {
- // Special case for PX4 Flow
- if (vehicleId != 81 || componentId != 50) {
- // Don't create vehicles for components other than the autopilot
- qCDebug(MultiVehicleManagerLog()) << "Ignoring heartbeat from unknown component port:vehicleId:componentId:fwType:vehicleType"
- << link->linkConfiguration()->name()
- << vehicleId
- << componentId
- << vehicleFirmwareType
- << vehicleType;
- return;
- }
+ // Don't create vehicles for components other than the autopilot
+ qCDebug(MultiVehicleManagerLog()) << "Ignoring heartbeat from unknown component port:vehicleId:componentId:fwType:vehicleType"
+ << link->linkConfiguration()->name()
+ << vehicleId
+ << componentId
+ << vehicleFirmwareType
+ << vehicleType;
+ return;
}
#if !defined(NO_ARDUPILOT_DIALECT)
diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc
index 9920684792f..27145ba2df8 100644
--- a/src/Vehicle/Vehicle.cc
+++ b/src/Vehicle/Vehicle.cc
@@ -293,7 +293,7 @@ void Vehicle::_commonInit()
_componentInformationManager = new ComponentInformationManager (this);
_initialConnectStateMachine = new InitialConnectStateMachine (this);
_ftpManager = new FTPManager (this);
- _imageProtocolManager = new ImageProtocolManager ();
+
_vehicleLinkManager = new VehicleLinkManager (this);
connect(_standardModes, &StandardModes::modesUpdated, this, &Vehicle::flightModesChanged);
@@ -325,8 +325,7 @@ void Vehicle::_commonInit()
// Flight modes can differ based on advanced mode
connect(_toolbox->corePlugin(), &QGCCorePlugin::showAdvancedUIChanged, this, &Vehicle::flightModesChanged);
- connect(_imageProtocolManager, &ImageProtocolManager::imageReady, this, &Vehicle::_imageProtocolImageReady);
-
+ _createImageProtocolManager();
_createStatusTextHandler();
// _addFactGroup(_vehicleFactGroup, _vehicleFactGroupName);
@@ -530,7 +529,7 @@ void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t mes
}
_ftpManager->_mavlinkMessageReceived(message);
_parameterManager->mavlinkMessageReceived(message);
- _imageProtocolManager->mavlinkMessageReceived(message);
+ (void) QMetaObject::invokeMethod(_imageProtocolManager, "mavlinkMessageReceived", Qt::AutoConnection, message);
_remoteIDManager->mavlinkMessageReceived(message);
_waitForMavlinkMessageMessageReceivedHandler(message);
@@ -1879,14 +1878,6 @@ void Vehicle::_sendQGCTimeToVehicle()
sendMessageOnLinkThreadSafe(sharedLink.get(), msg);
}
-void Vehicle::_imageProtocolImageReady(void)
-{
- QImage img = _imageProtocolManager->getImage();
- qgcApp()->qgcImageProvider()->setImage(&img, _id);
- _flowImageIndex++;
- emit flowImageIndexChanged();
-}
-
void Vehicle::_remoteControlRSSIChanged(uint8_t rssi)
{
//-- 0 <= rssi <= 100 - 255 means "invalid/unknown"
@@ -4099,3 +4090,22 @@ void Vehicle::sendSetupSigning()
}
/*---------------------------------------------------------------------------*/
+/*===========================================================================*/
+/* Image Protocol Manager */
+/*===========================================================================*/
+
+void Vehicle::_createImageProtocolManager()
+{
+ _imageProtocolManager = new ImageProtocolManager(this);
+ (void) connect(_imageProtocolManager, &ImageProtocolManager::flowImageIndexChanged, this, &Vehicle::flowImageIndexChanged);
+ (void) connect(_imageProtocolManager, &ImageProtocolManager::imageReady, this, [this](const QImage &image) {
+ qgcApp()->qgcImageProvider()->setImage(image, _id);
+ });
+}
+
+uint32_t Vehicle::flowImageIndex() const
+{
+ return (_imageProtocolManager ? _imageProtocolManager->flowImageIndex() : 0);
+}
+
+/*---------------------------------------------------------------------------*/
diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h
index 844470594c4..23f65549eb6 100644
--- a/src/Vehicle/Vehicle.h
+++ b/src/Vehicle/Vehicle.h
@@ -158,7 +158,6 @@ class Vehicle : public VehicleFactGroup
Q_PROPERTY(float latitude READ latitude NOTIFY coordinateChanged)
Q_PROPERTY(float longitude READ longitude NOTIFY coordinateChanged)
Q_PROPERTY(bool joystickEnabled READ joystickEnabled WRITE setJoystickEnabled NOTIFY joystickEnabledChanged)
- Q_PROPERTY(int flowImageIndex READ flowImageIndex NOTIFY flowImageIndexChanged)
Q_PROPERTY(int rcRSSI READ rcRSSI NOTIFY rcRSSIChanged)
Q_PROPERTY(bool px4Firmware READ px4Firmware NOTIFY firmwareTypeChanged)
Q_PROPERTY(bool apmFirmware READ apmFirmware NOTIFY firmwareTypeChanged)
@@ -518,8 +517,6 @@ class Vehicle : public VehicleFactGroup
QmlObjectListModel* cameraTriggerPoints () { return &_cameraTriggerPoints; }
- int flowImageIndex() const{ return _flowImageIndex; }
-
//-- Mavlink Logging
void startMavlinkLog();
void stopMavlinkLog();
@@ -847,7 +844,6 @@ public slots:
void checkListStateChanged ();
void longitudeChanged ();
void currentConfigChanged ();
- void flowImageIndexChanged ();
void rcRSSIChanged (int rcRSSI);
void telemetryRRSSIChanged (int value);
void telemetryLRSSIChanged (int value);
@@ -921,7 +917,6 @@ private slots:
void _announceArmedChanged (bool armed);
void _offlineCruiseSpeedSettingChanged (QVariant value);
void _offlineHoverSpeedSettingChanged (QVariant value);
- void _imageProtocolImageReady (void);
void _prearmErrorTimeout ();
void _firstMissionLoadComplete ();
void _firstGeoFenceLoadComplete ();
@@ -1106,8 +1101,6 @@ private slots:
// Toolbox references
- int _flowImageIndex = 0;
-
bool _allLinksRemovedSent = false; ///< true: allLinkRemoved signal already sent one time
uint _messagesReceived = 0;
@@ -1282,7 +1275,6 @@ private slots:
RallyPointManager* _rallyPointManager = nullptr;
VehicleLinkManager* _vehicleLinkManager = nullptr;
FTPManager* _ftpManager = nullptr;
- ImageProtocolManager* _imageProtocolManager = nullptr;
InitialConnectStateMachine* _initialConnectStateMachine = nullptr;
Actuators* _actuators = nullptr;
RemoteIDManager* _remoteIDManager = nullptr;
@@ -1368,6 +1360,23 @@ private slots:
StatusTextHandler *m_statusTextHandler = nullptr;
/*---------------------------------------------------------------------------*/
+/*===========================================================================*/
+/* Image Protocol Manager */
+/*===========================================================================*/
+private:
+ Q_PROPERTY(uint flowImageIndex READ flowImageIndex NOTIFY flowImageIndexChanged)
+
+public:
+ uint32_t flowImageIndex() const;
+
+signals:
+ void flowImageIndexChanged();
+
+private:
+ void _createImageProtocolManager();
+
+ ImageProtocolManager *_imageProtocolManager = nullptr;
};
+/*---------------------------------------------------------------------------*/
Q_DECLARE_METATYPE(Vehicle::MavCmdResultFailureCode_t)
diff --git a/src/Vehicle/VehicleLinkManager.cc b/src/Vehicle/VehicleLinkManager.cc
index 63cf460b95f..1f18e5a4154 100644
--- a/src/Vehicle/VehicleLinkManager.cc
+++ b/src/Vehicle/VehicleLinkManager.cc
@@ -391,13 +391,3 @@ QStringList VehicleLinkManager::linkStatuses(void) const
return rgStatuses;
}
-
-bool VehicleLinkManager::primaryLinkIsPX4Flow(void) const
-{
- SharedLinkInterfacePtr sharedLink = _primaryLink.lock();
- if (!sharedLink) {
- return false;
- } else {
- return sharedLink->isPX4Flow();
- }
-}
diff --git a/src/Vehicle/VehicleLinkManager.h b/src/Vehicle/VehicleLinkManager.h
index 1926005d72a..10ff37df23e 100644
--- a/src/Vehicle/VehicleLinkManager.h
+++ b/src/Vehicle/VehicleLinkManager.h
@@ -33,7 +33,6 @@ class VehicleLinkManager : public QObject
public:
VehicleLinkManager(Vehicle* vehicle);
- Q_PROPERTY(bool primaryLinkIsPX4Flow READ primaryLinkIsPX4Flow NOTIFY primaryLinkChanged)
Q_PROPERTY(QString primaryLinkName READ primaryLinkName WRITE setPrimaryLinkByName NOTIFY primaryLinkChanged)
Q_PROPERTY(QStringList linkNames READ linkNames NOTIFY linkNamesChanged)
Q_PROPERTY(QStringList linkStatuses READ linkStatuses NOTIFY linkStatusesChanged)
@@ -41,7 +40,6 @@ class VehicleLinkManager : public QObject
Q_PROPERTY(bool communicationLostEnabled READ communicationLostEnabled WRITE setCommunicationLostEnabled NOTIFY communicationLostEnabledChanged)
Q_PROPERTY(bool autoDisconnect MEMBER _autoDisconnect NOTIFY autoDisconnectChanged)
- bool primaryLinkIsPX4Flow (void) const;
void mavlinkMessageReceived (LinkInterface* link, mavlink_message_t message);
bool containsLink (LinkInterface* link);
WeakLinkInterfacePtr primaryLink (void) { return _primaryLink; }
diff --git a/src/VehicleSetup/Bootloader.h b/src/VehicleSetup/Bootloader.h
index b1b4897c298..72ba9e1e037 100644
--- a/src/VehicleSetup/Bootloader.h
+++ b/src/VehicleSetup/Bootloader.h
@@ -36,7 +36,6 @@ class Bootloader : public QObject
bool verify (const FirmwareImage* image);
bool reboot (void);
- static const int boardIDPX4Flow = 6; ///< PX4 Flow board, as from USB PID
static const int boardIDSiKRadio1000 = 78; ///< Original radio based on SI1000 chip
static const int boardIDSiKRadio1060 = 80; ///< Newer radio based on SI1060 chip
diff --git a/src/VehicleSetup/CMakeLists.txt b/src/VehicleSetup/CMakeLists.txt
index 4b3f270d198..2ce3abb4134 100644
--- a/src/VehicleSetup/CMakeLists.txt
+++ b/src/VehicleSetup/CMakeLists.txt
@@ -58,7 +58,7 @@ endif()
# JoystickConfigButtons.qml
# JoystickConfigCalibration.qml
# JoystickConfigGeneral.qml
-# PX4FlowSensor.qml
+# OpticalFlowSensor.qml
# SetupParameterEditor.qml
# SetupView.qml
# VehicleSummary.qml
diff --git a/src/VehicleSetup/FirmwareUpgrade.qml b/src/VehicleSetup/FirmwareUpgrade.qml
index 6c7287901cd..56ca4143270 100644
--- a/src/VehicleSetup/FirmwareUpgrade.qml
+++ b/src/VehicleSetup/FirmwareUpgrade.qml
@@ -43,7 +43,7 @@ SetupPage {
readonly property string title: qsTr("Firmware Setup") // Popup dialog title
readonly property string highlightPrefix: ""
readonly property string highlightSuffix: ""
- readonly property string welcomeText: qsTr("%1 can upgrade the firmware on Pixhawk devices, SiK Radios and PX4 Flow Smart Cameras.").arg(QGroundControl.appName)
+ readonly property string welcomeText: qsTr("%1 can upgrade the firmware on Pixhawk devices and SiK Radios.").arg(QGroundControl.appName)
readonly property string welcomeTextSingle: qsTr("Update the autopilot firmware to the latest version")
readonly property string plugInText: "" + highlightPrefix + qsTr("Plug in your device") + highlightSuffix + qsTr(" via USB to ") + highlightPrefix + qsTr("start") + highlightSuffix + qsTr(" firmware upgrade.") + ""
readonly property string flashFailText: qsTr("If upgrade failed, make sure to connect ") + highlightPrefix + qsTr("directly") + highlightSuffix + qsTr(" to a powered USB port on your computer, not through a USB hub. ") +
@@ -141,7 +141,6 @@ SetupPage {
buttons: Dialog.Ok | Dialog.Cancel
property bool showFirmwareTypeSelection: _advanced.checked
- property bool px4Flow: controller.px4FlowBoard
function firmwareVersionChanged(model) {
firmwareWarningMessageVisible = false
@@ -187,40 +186,34 @@ SetupPage {
if (_singleFirmwareMode) {
controller.flashSingleFirmwareMode(controller.selectedFirmwareBuildType)
} else {
- var stack
var firmwareBuildType = firmwareBuildTypeCombo.model.get(firmwareBuildTypeCombo.currentIndex).firmwareType
var vehicleType = FirmwareUpgradeController.DefaultVehicleFirmware
- if (px4Flow) {
- stack = px4FlowTypeSelectionCombo.model.get(px4FlowTypeSelectionCombo.currentIndex).stackType
- vehicleType = FirmwareUpgradeController.DefaultVehicleFirmware
- } else {
- stack = apmFlightStack.checked ? FirmwareUpgradeController.AutoPilotStackAPM : FirmwareUpgradeController.AutoPilotStackPX4
- if (apmFlightStack.checked) {
- if (firmwareBuildType === FirmwareUpgradeController.CustomFirmware) {
- vehicleType = apmVehicleTypeCombo.currentIndex
- } else {
- if (controller.apmFirmwareNames.length === 0) {
- // Not ready yet, or no firmware available
- mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("Either firmware list is still downloading, or no firmware is available for current selection."))
- firmwareSelectDialog.preventClose = true
- return
- }
- if (ardupilotFirmwareSelectionCombo.currentIndex == -1) {
- mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("You must choose a board type."))
- firmwareSelectDialog.preventClose = true
- return
- }
-
- var firmwareUrl = controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex]
- if (firmwareUrl == "") {
- mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("No firmware was found for the current selection."))
- firmwareSelectDialog.preventClose = true
- return
- }
- controller.flashFirmwareUrl(controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex])
+ var stack = apmFlightStack.checked ? FirmwareUpgradeController.AutoPilotStackAPM : FirmwareUpgradeController.AutoPilotStackPX4
+ if (apmFlightStack.checked) {
+ if (firmwareBuildType === FirmwareUpgradeController.CustomFirmware) {
+ vehicleType = apmVehicleTypeCombo.currentIndex
+ } else {
+ if (controller.apmFirmwareNames.length === 0) {
+ // Not ready yet, or no firmware available
+ mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("Either firmware list is still downloading, or no firmware is available for current selection."))
+ firmwareSelectDialog.preventClose = true
+ return
+ }
+ if (ardupilotFirmwareSelectionCombo.currentIndex == -1) {
+ mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("You must choose a board type."))
+ firmwareSelectDialog.preventClose = true
return
}
+
+ var firmwareUrl = controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex]
+ if (firmwareUrl == "") {
+ mainWindow.showMessageDialog(firmwareSelectDialog.title, qsTr("No firmware was found for the current selection."))
+ firmwareSelectDialog.preventClose = true
+ return
+ }
+ controller.flashFirmwareUrl(controller.apmFirmwareUrls[ardupilotFirmwareSelectionCombo.currentIndex])
+ return
}
}
//-- If custom, get file path
@@ -260,32 +253,6 @@ SetupPage {
}
}
- ListModel {
- id: px4FlowFirmwareList
-
- ListElement {
- text: qsTr("PX4 Pro")
- stackType: FirmwareUpgradeController.PX4FlowPX4
- }
- ListElement {
- text: qsTr("ArduPilot")
- stackType: FirmwareUpgradeController.PX4FlowAPM
- }
- }
-
- ListModel {
- id: px4FlowTypeList
-
- ListElement {
- text: qsTr("Standard Version (stable)")
- firmwareType: FirmwareUpgradeController.StableFirmware
- }
- ListElement {
- text: qsTr("Custom firmware file...")
- firmwareType: FirmwareUpgradeController.CustomFirmware
- }
- }
-
ListModel {
id: singleFirmwareModeTypeList
@@ -306,9 +273,8 @@ SetupPage {
QGCLabel {
Layout.fillWidth: true
wrapMode: Text.WordWrap
- text: (_singleFirmwareMode || !QGroundControl.apmFirmwareSupported) ? _singleFirmwareLabel : (px4Flow ? _px4FlowLabel : _pixhawkLabel)
+ text: (_singleFirmwareMode || !QGroundControl.apmFirmwareSupported) ? _singleFirmwareLabel : _pixhawkLabel
- readonly property string _px4FlowLabel: qsTr("Detected PX4 Flow board. The firmware you use on the PX4 Flow must match the AutoPilot firmware type you are using on the vehicle:")
readonly property string _pixhawkLabel: qsTr("Detected Pixhawk board. You can select from the following flight stacks:")
readonly property string _singleFirmwareLabel: qsTr("Press Ok to upgrade your vehicle.")
}
@@ -317,7 +283,7 @@ SetupPage {
id: firmwareRadiosColumn
spacing: 0
- visible: !_singleFirmwareMode && !px4Flow && QGroundControl.apmFirmwareSupported
+ visible: !_singleFirmwareMode && QGroundControl.apmFirmwareSupported
Component.onCompleted: {
if(!QGroundControl.apmFirmwareSupported) {
@@ -353,7 +319,7 @@ SetupPage {
FactComboBox {
Layout.fillWidth: true
- visible: !px4Flow && apmFlightStack.checked
+ visible: apmFlightStack.checked
fact: _firmwareUpgradeSettings.apmChibiOS
indexModel: false
}
@@ -361,7 +327,7 @@ SetupPage {
FactComboBox {
id: apmVehicleTypeCombo
Layout.fillWidth: true
- visible: !px4Flow && apmFlightStack.checked
+ visible: apmFlightStack.checked
fact: _firmwareUpgradeSettings.apmVehicleType
indexModel: false
}
@@ -369,7 +335,7 @@ SetupPage {
QGCComboBox {
id: ardupilotFirmwareSelectionCombo
Layout.fillWidth: true
- visible: !px4Flow && apmFlightStack.checked && !controller.downloadingFirmwareList && controller.apmFirmwareNames.length !== 0
+ visible: apmFlightStack.checked && !controller.downloadingFirmwareList && controller.apmFirmwareNames.length !== 0
model: controller.apmFirmwareNames
onModelChanged: currentIndex = controller.apmFirmwareNamesBestIndex
}
@@ -388,20 +354,10 @@ SetupPage {
visible: !controller.downloadingFirmwareList && (QGroundControl.apmFirmwareSupported && controller.apmFirmwareNames.length === 0)
}
- QGCComboBox {
- id: px4FlowTypeSelectionCombo
- Layout.fillWidth: true
- visible: px4Flow
- model: px4FlowFirmwareList
- textRole: "text"
- currentIndex: _defaultFirmwareIsPX4 ? 0 : 1
- }
-
QGCCheckBox {
id: _advanced
text: qsTr("Advanced settings")
- checked: px4Flow ? true : false
- visible: !px4Flow
+ checked: false
onClicked: {
firmwareBuildTypeCombo.currentIndex = 0
@@ -415,8 +371,7 @@ SetupPage {
wrapMode: Text.WordWrap
visible: showFirmwareTypeSelection
text: _singleFirmwareMode ? qsTr("Select the standard version or one from the file system (previously downloaded):") :
- (px4Flow ? qsTr("Select which version of the firmware you would like to install:") :
- qsTr("Select which version of the above flight stack you would like to install:"))
+ qsTr("Select which version of the above flight stack you would like to install:")
}
QGCComboBox {
@@ -424,7 +379,7 @@ SetupPage {
Layout.fillWidth: true
visible: showFirmwareTypeSelection
textRole: "text"
- model: _singleFirmwareMode ? singleFirmwareModeTypeList : (px4Flow ? px4FlowTypeList : firmwareBuildTypeList)
+ model: _singleFirmwareMode ? singleFirmwareModeTypeList : firmwareBuildTypeList
onActivated: (index) => {
controller.selectedFirmwareBuildType = model.get(index).firmwareType
diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc
index a3429bee1b8..72fbc50f68f 100644
--- a/src/VehicleSetup/FirmwareUpgradeController.cc
+++ b/src/VehicleSetup/FirmwareUpgradeController.cc
@@ -142,7 +142,6 @@ FirmwareUpgradeController::FirmwareUpgradeController(void)
connect(_apmVehicleTypeSetting, &Fact::rawValueChanged, this, &FirmwareUpgradeController::_buildAPMFirmwareNames);
#endif
- _initFirmwareHash();
_determinePX4StableVersion();
#if !defined(NO_ARDUPILOT_DIALECT)
@@ -292,31 +291,6 @@ void FirmwareUpgradeController::_foundBoardInfo(int bootloaderVersion, int board
}
}
-
-/// @brief intializes the firmware hashes with proper urls.
-/// This happens only once for a class instance first time when it is needed.
-void FirmwareUpgradeController::_initFirmwareHash()
-{
- // indirect check whether this function has been called before or not
- // may have to be modified if _rgPX4FMUV2Firmware disappears
- if (!_rgPX4FLowFirmware.isEmpty()) {
- return;
- }
-
- /////////////////////////////// px4flow firmwares ///////////////////////////////////////
- FirmwareToUrlElement_t rgPX4FLowFirmwareArray[] = {
- { PX4FlowPX4, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/Flow/master/px4flow.px4" },
- #if !defined(NO_ARDUPILOT_DIALECT)
- { PX4FlowAPM, StableFirmware, DefaultVehicleFirmware, "http://firmware.ardupilot.org/Tools/PX4Flow/px4flow-klt-latest.px4" },
- #endif
- };
-
- // We build the maps for PX4 firmwares dynamically using the data below
- for (auto& element : rgPX4FLowFirmwareArray) {
- _rgPX4FLowFirmware.insert(FirmwareIdentifier(element.stackType, element.firmwareType, element.vehicleType), element.url);
- }
-}
-
/// @brief Called when the findBootloader process is unable to sync to the bootloader. Moves the state
/// machine to the appropriate error state.
void FirmwareUpgradeController::_bootloaderSyncFailed(void)
@@ -329,9 +303,6 @@ QHash* FirmwareUpgradeCo
_rgFirmwareDynamic.clear();
switch (boardId) {
- case Bootloader::boardIDPX4Flow:
- _rgFirmwareDynamic = _rgPX4FLowFirmware;
- break;
case Bootloader::boardIDSiKRadio1000:
{
FirmwareToUrlElement_t element = { SiKRadio, StableFirmware, DefaultVehicleFirmware, "http://px4-travis.s3.amazonaws.com/SiK/stable/radio~hm_trp.ihx" };
@@ -550,10 +521,6 @@ void FirmwareUpgradeController::_buildAPMFirmwareNames(void)
quint16 boardPID = _boardInfo.productIdentifier();
uint32_t rawBoardId = _bootloaderBoardID == Bootloader::boardIDPX4FMUV3 ? Bootloader::boardIDPX4FMUV2 : _bootloaderBoardID;
- if (_boardType == QGCSerialPortInfo::BoardTypePX4Flow) {
- return;
- }
-
qCDebug(FirmwareUpgradeLog) << QStringLiteral("_buildAPMFirmwareNames description(%1) vid(%2/0x%3) pid(%4/0x%5)").arg(boardDescription).arg(boardVID).arg(boardVID, 1, 16).arg(boardPID).arg(boardPID, 1, 16);
_apmFirmwareNames.clear();
diff --git a/src/VehicleSetup/FirmwareUpgradeController.h b/src/VehicleSetup/FirmwareUpgradeController.h
index fd5a1763096..f86f67d0c63 100644
--- a/src/VehicleSetup/FirmwareUpgradeController.h
+++ b/src/VehicleSetup/FirmwareUpgradeController.h
@@ -37,8 +37,6 @@ class FirmwareUpgradeController : public QObject
typedef enum {
AutoPilotStackPX4 = 0,
AutoPilotStackAPM,
- PX4FlowPX4,
- PX4FlowAPM,
SiKRadio,
SingleFirmwareMode
} AutoPilotStackType_t;
@@ -92,7 +90,6 @@ class FirmwareUpgradeController : public QObject
Q_PROPERTY(QString boardDescription READ boardDescription NOTIFY boardFound)
Q_PROPERTY(QString boardType MEMBER _boardTypeName NOTIFY boardFound)
Q_PROPERTY(bool pixhawkBoard READ pixhawkBoard NOTIFY boardFound)
- Q_PROPERTY(bool px4FlowBoard READ px4FlowBoard NOTIFY boardFound)
Q_PROPERTY(FirmwareBuildType_t selectedFirmwareBuildType READ selectedFirmwareBuildType WRITE setSelectedFirmwareBuildType NOTIFY selectedFirmwareBuildTypeChanged)
Q_PROPERTY(QStringList apmFirmwareNames MEMBER _apmFirmwareNames NOTIFY apmFirmwareNamesChanged)
Q_PROPERTY(int apmFirmwareNamesBestIndex MEMBER _apmFirmwareNamesBestIndex NOTIFY apmFirmwareNamesChanged)
@@ -146,7 +143,6 @@ class FirmwareUpgradeController : public QObject
QString px4BetaVersion (void) { return _px4BetaVersion; }
bool pixhawkBoard(void) const { return _boardType == QGCSerialPortInfo::BoardTypePixhawk; }
- bool px4FlowBoard(void) const { return _boardType == QGCSerialPortInfo::BoardTypePX4Flow; }
/**
* @brief Return a human friendly string of available boards
@@ -191,7 +187,6 @@ private slots:
private:
QHash* _firmwareHashForBoardId(int boardId);
void _getFirmwareFile (FirmwareIdentifier firmwareId);
- void _initFirmwareHash (void);
void _downloadFirmware (void);
void _appendStatusLog (const QString& text, bool critical = false);
void _errorCancel (const QString& msg);
@@ -205,7 +200,6 @@ private slots:
QString _portDescription;
// Firmware hashes
- QHash _rgPX4FLowFirmware;
QHash _rgSiKRadioFirmware;
// Hash map for ArduPilot ChibiOS lookup by board name
diff --git a/src/VehicleSetup/PX4FlowSensor.qml b/src/VehicleSetup/OpticalFlowSensor.qml
similarity index 58%
rename from src/VehicleSetup/PX4FlowSensor.qml
rename to src/VehicleSetup/OpticalFlowSensor.qml
index f31295fbccd..4ac5b6f2415 100644
--- a/src/VehicleSetup/PX4FlowSensor.qml
+++ b/src/VehicleSetup/OpticalFlowSensor.qml
@@ -18,16 +18,16 @@ import QGroundControl.ScreenTools
Item {
QGCLabel {
- id: titleLabel
- text: qsTr("PX4Flow Camera")
- font.bold: true
+ text: qsTr("Optical Flow Camera")
+ font.bold: true
}
+
Image {
- source: globals.activeVehicle ? "image://QGCImages/" + globals.activeVehicle.id + "/" + globals.activeVehicle.flowImageIndex : ""
- width: parent.width * 0.5
- height: width * 0.75
- cache: false
- fillMode: Image.PreserveAspectFit
+ source: globals.activeVehicle ? "image://QGCImages/" + globals.activeVehicle.id + "/" + globals.activeVehicle.flowImageIndex : ""
+ width: parent.width * 0.5
+ height: width * 0.75
+ cache: false
+ fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
}
diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml
index 77b3295ba6e..cc5f5d853cc 100644
--- a/src/VehicleSetup/SetupView.qml
+++ b/src/VehicleSetup/SetupView.qml
@@ -249,13 +249,12 @@ Rectangle {
}
SubMenuButton {
- id: px4FlowButton
- buttonGroup: setupButtonGroup
- visible: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.vehicleLinkManager.primaryLinkIsPX4Flow : false
+ buttonGroup: setupButtonGroup
+ visible: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.flowImageIndex > 0 : false
setupIndicator: false
- text: qsTr("PX4Flow")
+ text: qsTr("Optical Flow")
Layout.fillWidth: true
- onClicked: showPanel(this, "PX4FlowSensor.qml")
+ onClicked: showPanel(this, "OpticalFlowSensor.qml")
}
SubMenuButton {