parent
16db2ead30
commit
9f3203ed4d
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,422 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "QGCApplication.h"
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
class QDomNode;
|
||||||
|
class QDomNodeList;
|
||||||
|
class QGCCameraParamIO;
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(CameraControlLog)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(CameraControlVerboseLog)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// Video Stream Info
|
||||||
|
/// Encapsulates the contents of a [VIDEO_STREAM_INFORMATION](https://mavlink.io/en/messages/common.html#VIDEO_STREAM_INFORMATION) message
|
||||||
|
class QGCVideoStreamInfo : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCVideoStreamInfo(QObject* parent, const mavlink_video_stream_information_t* si);
|
||||||
|
|
||||||
|
Q_PROPERTY(QString uri READ uri NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QString name READ name NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(int streamID READ streamID NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(int type READ type NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(qreal aspectRatio READ aspectRatio NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(qreal hfov READ hfov NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool isThermal READ isThermal NOTIFY infoChanged)
|
||||||
|
|
||||||
|
QString uri () { return QString(_streamInfo.uri); }
|
||||||
|
QString name () { return QString(_streamInfo.name); }
|
||||||
|
qreal aspectRatio () const;
|
||||||
|
qreal hfov () const{ return _streamInfo.hfov; }
|
||||||
|
int type () const{ return _streamInfo.type; }
|
||||||
|
int streamID () const{ return _streamInfo.stream_id; }
|
||||||
|
bool isThermal () const{ return _streamInfo.flags & VIDEO_STREAM_STATUS_FLAGS_THERMAL; }
|
||||||
|
|
||||||
|
bool update (const mavlink_video_stream_status_t* vs);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void infoChanged ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
mavlink_video_stream_information_t _streamInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// Camera option exclusions
|
||||||
|
class QGCCameraOptionExclusion : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QGCCameraOptionExclusion(QObject* parent, QString param_, QString value_, QStringList exclusions_);
|
||||||
|
QString param;
|
||||||
|
QString value;
|
||||||
|
QStringList exclusions;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// Camera option ranges
|
||||||
|
class QGCCameraOptionRange : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QGCCameraOptionRange(QObject* parent, QString param_, QString value_, QString targetParam_, QString condition_, QStringList optNames_, QStringList optValues_);
|
||||||
|
QString param;
|
||||||
|
QString value;
|
||||||
|
QString targetParam;
|
||||||
|
QString condition;
|
||||||
|
QStringList optNames;
|
||||||
|
QStringList optValues;
|
||||||
|
QVariantList optVariants;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// MAVLink Camera API controller
|
||||||
|
class QGCCameraControl : public FactGroup
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class QGCCameraParamIO;
|
||||||
|
public:
|
||||||
|
QGCCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr);
|
||||||
|
virtual ~QGCCameraControl();
|
||||||
|
|
||||||
|
//-- cam_mode
|
||||||
|
enum CameraMode {
|
||||||
|
CAM_MODE_UNDEFINED = -1,
|
||||||
|
CAM_MODE_PHOTO = 0,
|
||||||
|
CAM_MODE_VIDEO = 1,
|
||||||
|
CAM_MODE_SURVEY = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
//-- Video Capture Status
|
||||||
|
enum VideoStatus {
|
||||||
|
VIDEO_CAPTURE_STATUS_STOPPED = 0,
|
||||||
|
VIDEO_CAPTURE_STATUS_RUNNING,
|
||||||
|
VIDEO_CAPTURE_STATUS_LAST,
|
||||||
|
VIDEO_CAPTURE_STATUS_UNDEFINED = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
//-- Photo Capture Status
|
||||||
|
enum PhotoStatus {
|
||||||
|
PHOTO_CAPTURE_IDLE = 0,
|
||||||
|
PHOTO_CAPTURE_IN_PROGRESS,
|
||||||
|
PHOTO_CAPTURE_INTERVAL_IDLE,
|
||||||
|
PHOTO_CAPTURE_INTERVAL_IN_PROGRESS,
|
||||||
|
PHOTO_CAPTURE_LAST,
|
||||||
|
PHOTO_CAPTURE_STATUS_UNDEFINED = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
//-- Photo Capture Modes
|
||||||
|
enum PhotoMode {
|
||||||
|
PHOTO_CAPTURE_SINGLE = 0,
|
||||||
|
PHOTO_CAPTURE_TIMELAPSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
//-- Storage Status
|
||||||
|
enum StorageStatus {
|
||||||
|
STORAGE_EMPTY = STORAGE_STATUS_EMPTY,
|
||||||
|
STORAGE_UNFORMATTED = STORAGE_STATUS_UNFORMATTED,
|
||||||
|
STORAGE_READY = STORAGE_STATUS_READY,
|
||||||
|
STORAGE_NOT_SUPPORTED = STORAGE_STATUS_NOT_SUPPORTED
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ThermalViewMode {
|
||||||
|
THERMAL_OFF = 0,
|
||||||
|
THERMAL_BLEND,
|
||||||
|
THERMAL_FULL,
|
||||||
|
THERMAL_PIP,
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(CameraMode)
|
||||||
|
Q_ENUM(VideoStatus)
|
||||||
|
Q_ENUM(PhotoStatus)
|
||||||
|
Q_ENUM(PhotoMode)
|
||||||
|
Q_ENUM(StorageStatus)
|
||||||
|
Q_ENUM(ThermalViewMode)
|
||||||
|
|
||||||
|
Q_PROPERTY(int version READ version NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QString modelName READ modelName NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QString vendor READ vendor NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QString firmwareVersion READ firmwareVersion NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(qreal focalLength READ focalLength NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QSizeF sensorSize READ sensorSize NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QSize resolution READ resolution NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool capturesVideo READ capturesVideo NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool capturesPhotos READ capturesPhotos NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool hasModes READ hasModes NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool hasZoom READ hasZoom NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool hasFocus READ hasFocus NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool hasVideoStream READ hasVideoStream NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool photosInVideoMode READ photosInVideoMode NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool videoInPhotoMode READ videoInPhotoMode NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool isBasic READ isBasic NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(quint32 storageFree READ storageFree NOTIFY storageFreeChanged)
|
||||||
|
Q_PROPERTY(QString storageFreeStr READ storageFreeStr NOTIFY storageFreeChanged)
|
||||||
|
Q_PROPERTY(quint32 storageTotal READ storageTotal NOTIFY storageTotalChanged)
|
||||||
|
Q_PROPERTY(int batteryRemaining READ batteryRemaining NOTIFY batteryRemainingChanged)
|
||||||
|
Q_PROPERTY(QString batteryRemainingStr READ batteryRemainingStr NOTIFY batteryRemainingChanged)
|
||||||
|
Q_PROPERTY(bool paramComplete READ paramComplete NOTIFY parametersReady)
|
||||||
|
|
||||||
|
Q_PROPERTY(qreal zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
|
||||||
|
Q_PROPERTY(qreal focusLevel READ focusLevel WRITE setFocusLevel NOTIFY focusLevelChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(Fact* exposureMode READ exposureMode NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* ev READ ev NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* iso READ iso NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* shutterSpeed READ shutterSpeed NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* aperture READ aperture NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* wb READ wb NOTIFY parametersReady)
|
||||||
|
Q_PROPERTY(Fact* mode READ mode NOTIFY parametersReady)
|
||||||
|
|
||||||
|
Q_PROPERTY(QStringList activeSettings READ activeSettings NOTIFY activeSettingsChanged)
|
||||||
|
Q_PROPERTY(VideoStatus videoStatus READ videoStatus NOTIFY videoStatusChanged)
|
||||||
|
Q_PROPERTY(PhotoStatus photoStatus READ photoStatus NOTIFY photoStatusChanged)
|
||||||
|
Q_PROPERTY(CameraMode cameraMode READ cameraMode WRITE setCameraMode NOTIFY cameraModeChanged)
|
||||||
|
Q_PROPERTY(StorageStatus storageStatus READ storageStatus NOTIFY storageStatusChanged)
|
||||||
|
Q_PROPERTY(qreal photoLapse READ photoLapse WRITE setPhotoLapse NOTIFY photoLapseChanged)
|
||||||
|
Q_PROPERTY(int photoLapseCount READ photoLapseCount WRITE setPhotoLapseCount NOTIFY photoLapseCountChanged)
|
||||||
|
Q_PROPERTY(PhotoMode photoMode READ photoMode WRITE setPhotoMode NOTIFY photoModeChanged)
|
||||||
|
Q_PROPERTY(int currentStream READ currentStream WRITE setCurrentStream NOTIFY currentStreamChanged)
|
||||||
|
Q_PROPERTY(bool autoStream READ autoStream NOTIFY autoStreamChanged)
|
||||||
|
Q_PROPERTY(QmlObjectListModel* streams READ streams NOTIFY streamsChanged)
|
||||||
|
Q_PROPERTY(QGCVideoStreamInfo* currentStreamInstance READ currentStreamInstance NOTIFY currentStreamChanged)
|
||||||
|
Q_PROPERTY(QGCVideoStreamInfo* thermalStreamInstance READ thermalStreamInstance NOTIFY thermalStreamChanged)
|
||||||
|
Q_PROPERTY(quint32 recordTime READ recordTime NOTIFY recordTimeChanged)
|
||||||
|
Q_PROPERTY(QString recordTimeStr READ recordTimeStr NOTIFY recordTimeChanged)
|
||||||
|
Q_PROPERTY(QStringList streamLabels READ streamLabels NOTIFY streamLabelsChanged)
|
||||||
|
Q_PROPERTY(ThermalViewMode thermalMode READ thermalMode WRITE setThermalMode NOTIFY thermalModeChanged)
|
||||||
|
Q_PROPERTY(double thermalOpacity READ thermalOpacity WRITE setThermalOpacity NOTIFY thermalOpacityChanged)
|
||||||
|
|
||||||
|
Q_INVOKABLE virtual void setVideoMode ();
|
||||||
|
Q_INVOKABLE virtual void setPhotoMode ();
|
||||||
|
Q_INVOKABLE virtual void toggleMode ();
|
||||||
|
Q_INVOKABLE virtual bool takePhoto ();
|
||||||
|
Q_INVOKABLE virtual bool stopTakePhoto ();
|
||||||
|
Q_INVOKABLE virtual bool startVideo ();
|
||||||
|
Q_INVOKABLE virtual bool stopVideo ();
|
||||||
|
Q_INVOKABLE virtual bool toggleVideo ();
|
||||||
|
Q_INVOKABLE virtual void resetSettings ();
|
||||||
|
Q_INVOKABLE virtual void formatCard (int id = 1);
|
||||||
|
Q_INVOKABLE virtual void stepZoom (int direction);
|
||||||
|
Q_INVOKABLE virtual void startZoom (int direction);
|
||||||
|
Q_INVOKABLE virtual void stopZoom ();
|
||||||
|
Q_INVOKABLE virtual void stopStream ();
|
||||||
|
Q_INVOKABLE virtual void resumeStream ();
|
||||||
|
|
||||||
|
virtual int version () { return _version; }
|
||||||
|
virtual QString modelName () { return _modelName; }
|
||||||
|
virtual QString vendor () { return _vendor; }
|
||||||
|
virtual QString firmwareVersion ();
|
||||||
|
virtual qreal focalLength () { return static_cast<qreal>(_info.focal_length); }
|
||||||
|
virtual QSizeF sensorSize () { return QSizeF(static_cast<qreal>(_info.sensor_size_h), static_cast<qreal>(_info.sensor_size_v)); }
|
||||||
|
virtual QSize resolution () { return QSize(_info.resolution_h, _info.resolution_v); }
|
||||||
|
virtual bool capturesVideo () { return _info.flags & CAMERA_CAP_FLAGS_CAPTURE_VIDEO; }
|
||||||
|
virtual bool capturesPhotos () { return _info.flags & CAMERA_CAP_FLAGS_CAPTURE_IMAGE; }
|
||||||
|
virtual bool hasModes () { return _info.flags & CAMERA_CAP_FLAGS_HAS_MODES; }
|
||||||
|
virtual bool hasZoom () { return _info.flags & CAMERA_CAP_FLAGS_HAS_BASIC_ZOOM; }
|
||||||
|
virtual bool hasFocus () { return _info.flags & CAMERA_CAP_FLAGS_HAS_BASIC_FOCUS; }
|
||||||
|
virtual bool hasVideoStream () { return _info.flags & CAMERA_CAP_FLAGS_HAS_VIDEO_STREAM; }
|
||||||
|
virtual bool photosInVideoMode () { return _info.flags & CAMERA_CAP_FLAGS_CAN_CAPTURE_IMAGE_IN_VIDEO_MODE; }
|
||||||
|
virtual bool videoInPhotoMode () { return _info.flags & CAMERA_CAP_FLAGS_CAN_CAPTURE_VIDEO_IN_IMAGE_MODE; }
|
||||||
|
|
||||||
|
virtual int compID () { return _compID; }
|
||||||
|
virtual bool isBasic () { return _settings.size() == 0; }
|
||||||
|
virtual VideoStatus videoStatus ();
|
||||||
|
virtual PhotoStatus photoStatus ();
|
||||||
|
virtual PhotoMode photoMode () { return _photoMode; }
|
||||||
|
virtual qreal photoLapse () { return _photoLapse; }
|
||||||
|
virtual int photoLapseCount () { return _photoLapseCount; }
|
||||||
|
virtual CameraMode cameraMode () { return _cameraMode; }
|
||||||
|
virtual StorageStatus storageStatus () { return _storageStatus; }
|
||||||
|
virtual QStringList activeSettings ();
|
||||||
|
virtual quint32 storageFree () { return _storageFree; }
|
||||||
|
virtual QString storageFreeStr ();
|
||||||
|
virtual quint32 storageTotal () { return _storageTotal; }
|
||||||
|
virtual int batteryRemaining () { return _batteryRemaining; }
|
||||||
|
virtual QString batteryRemainingStr ();
|
||||||
|
virtual bool paramComplete () { return _paramComplete; }
|
||||||
|
virtual qreal zoomLevel () { return _zoomLevel; }
|
||||||
|
virtual qreal focusLevel () { return _focusLevel; }
|
||||||
|
|
||||||
|
virtual QmlObjectListModel* streams () { return &_streams; }
|
||||||
|
virtual QGCVideoStreamInfo* currentStreamInstance();
|
||||||
|
virtual QGCVideoStreamInfo* thermalStreamInstance();
|
||||||
|
virtual int currentStream () { return _currentStream; }
|
||||||
|
virtual void setCurrentStream (int stream);
|
||||||
|
virtual bool autoStream ();
|
||||||
|
virtual quint32 recordTime () { return _recordTime; }
|
||||||
|
virtual QString recordTimeStr ();
|
||||||
|
|
||||||
|
virtual Fact* exposureMode ();
|
||||||
|
virtual Fact* ev ();
|
||||||
|
virtual Fact* iso ();
|
||||||
|
virtual Fact* shutterSpeed ();
|
||||||
|
virtual Fact* aperture ();
|
||||||
|
virtual Fact* wb ();
|
||||||
|
virtual Fact* mode ();
|
||||||
|
|
||||||
|
/// Stream names to show the user (for selection)
|
||||||
|
virtual QStringList streamLabels () { return _streamLabels; }
|
||||||
|
|
||||||
|
virtual ThermalViewMode thermalMode () { return _thermalMode; }
|
||||||
|
virtual void setThermalMode (ThermalViewMode mode);
|
||||||
|
virtual double thermalOpacity () { return _thermalOpacity; }
|
||||||
|
virtual void setThermalOpacity (double val);
|
||||||
|
|
||||||
|
virtual void setZoomLevel (qreal level);
|
||||||
|
virtual void setFocusLevel (qreal level);
|
||||||
|
virtual void setCameraMode (CameraMode mode);
|
||||||
|
virtual void setPhotoMode (PhotoMode mode);
|
||||||
|
virtual void setPhotoLapse (qreal interval);
|
||||||
|
virtual void setPhotoLapseCount (int count);
|
||||||
|
|
||||||
|
virtual void handleSettings (const mavlink_camera_settings_t& settings);
|
||||||
|
virtual void handleCaptureStatus (const mavlink_camera_capture_status_t& capStatus);
|
||||||
|
virtual void handleParamAck (const mavlink_param_ext_ack_t& ack);
|
||||||
|
virtual void handleParamValue (const mavlink_param_ext_value_t& value);
|
||||||
|
virtual void handleStorageInfo (const mavlink_storage_information_t& st);
|
||||||
|
virtual void handleBatteryStatus (const mavlink_battery_status_t& bs);
|
||||||
|
virtual void handleVideoInfo (const mavlink_video_stream_information_t *vi);
|
||||||
|
virtual void handleVideoStatus (const mavlink_video_stream_status_t *vs);
|
||||||
|
|
||||||
|
/// Notify controller a parameter has changed
|
||||||
|
virtual void factChanged (Fact* pFact);
|
||||||
|
/// Allow controller to modify or invalidate incoming parameter
|
||||||
|
virtual bool incomingParameter (Fact* pFact, QVariant& newValue);
|
||||||
|
/// Allow controller to modify or invalidate parameter change
|
||||||
|
virtual bool validateParameter (Fact* pFact, QVariant& newValue);
|
||||||
|
|
||||||
|
// Known Parameters
|
||||||
|
static const char* kCAM_EV;
|
||||||
|
static const char* kCAM_EXPMODE;
|
||||||
|
static const char* kCAM_ISO;
|
||||||
|
static const char* kCAM_SHUTTERSPD;
|
||||||
|
static const char* kCAM_APERTURE;
|
||||||
|
static const char* kCAM_WBMODE;
|
||||||
|
static const char* kCAM_MODE;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void infoChanged ();
|
||||||
|
void videoStatusChanged ();
|
||||||
|
void photoStatusChanged ();
|
||||||
|
void photoModeChanged ();
|
||||||
|
void photoLapseChanged ();
|
||||||
|
void photoLapseCountChanged ();
|
||||||
|
void cameraModeChanged ();
|
||||||
|
void activeSettingsChanged ();
|
||||||
|
void storageFreeChanged ();
|
||||||
|
void storageTotalChanged ();
|
||||||
|
void batteryRemainingChanged ();
|
||||||
|
void dataReady (QByteArray data);
|
||||||
|
void parametersReady ();
|
||||||
|
void zoomLevelChanged ();
|
||||||
|
void focusLevelChanged ();
|
||||||
|
void streamsChanged ();
|
||||||
|
void currentStreamChanged ();
|
||||||
|
void thermalStreamChanged ();
|
||||||
|
void autoStreamChanged ();
|
||||||
|
void recordTimeChanged ();
|
||||||
|
void streamLabelsChanged ();
|
||||||
|
void thermalModeChanged ();
|
||||||
|
void thermalOpacityChanged ();
|
||||||
|
void storageStatusChanged ();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _setVideoStatus (VideoStatus status);
|
||||||
|
virtual void _setPhotoStatus (PhotoStatus status);
|
||||||
|
virtual void _setCameraMode (CameraMode mode);
|
||||||
|
virtual void _requestStreamInfo (uint8_t streamID);
|
||||||
|
virtual void _requestStreamStatus (uint8_t streamID);
|
||||||
|
virtual QGCVideoStreamInfo* _findStream (uint8_t streamID, bool report = true);
|
||||||
|
virtual QGCVideoStreamInfo* _findStream (const QString name);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
virtual void _initWhenReady ();
|
||||||
|
virtual void _requestCameraSettings ();
|
||||||
|
virtual void _requestAllParameters ();
|
||||||
|
virtual void _requestParamUpdates ();
|
||||||
|
virtual void _requestCaptureStatus ();
|
||||||
|
virtual void _requestStorageInfo ();
|
||||||
|
virtual void _downloadFinished ();
|
||||||
|
virtual void _mavCommandResult (int vehicleId, int component, int command, int result, bool noReponseFromVehicle);
|
||||||
|
virtual void _dataReady (QByteArray data);
|
||||||
|
virtual void _paramDone ();
|
||||||
|
virtual void _streamTimeout ();
|
||||||
|
virtual void _streamStatusTimeout ();
|
||||||
|
virtual void _recTimerHandler ();
|
||||||
|
virtual void _checkForVideoStreams ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _handleLocalization (QByteArray& bytes);
|
||||||
|
bool _replaceLocaleStrings (const QDomNode node, QByteArray& bytes);
|
||||||
|
bool _loadCameraDefinitionFile (QByteArray& bytes);
|
||||||
|
bool _loadConstants (const QDomNodeList nodeList);
|
||||||
|
bool _loadSettings (const QDomNodeList nodeList);
|
||||||
|
void _processRanges ();
|
||||||
|
bool _processCondition (const QString condition);
|
||||||
|
bool _processConditionTest (const QString conditionTest);
|
||||||
|
bool _loadNameValue (QDomNode option, const QString factName, FactMetaData* metaData, QString& optName, QString& optValue, QVariant& optVariant);
|
||||||
|
bool _loadRanges (QDomNode option, const QString factName, QString paramValue);
|
||||||
|
void _updateActiveList ();
|
||||||
|
void _updateRanges (Fact* pFact);
|
||||||
|
void _httpRequest (const QString& url);
|
||||||
|
void _handleDefinitionFile (const QString& url);
|
||||||
|
void _ftpDownloadComplete (const QString& fileName, const QString& errorMsg);
|
||||||
|
|
||||||
|
QStringList _loadExclusions (QDomNode option);
|
||||||
|
QStringList _loadUpdates (QDomNode option);
|
||||||
|
QString _getParamName (const char* param_id);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vehicle* _vehicle = nullptr;
|
||||||
|
int _compID = 0;
|
||||||
|
mavlink_camera_information_t _info;
|
||||||
|
int _version = 0;
|
||||||
|
bool _cached = false;
|
||||||
|
bool _paramComplete = false;
|
||||||
|
qreal _zoomLevel = 0.0;
|
||||||
|
qreal _focusLevel = 0.0;
|
||||||
|
uint32_t _storageFree = 0;
|
||||||
|
uint32_t _storageTotal = 0;
|
||||||
|
int _batteryRemaining = -1;
|
||||||
|
QNetworkAccessManager* _netManager = nullptr;
|
||||||
|
QString _modelName;
|
||||||
|
QString _vendor;
|
||||||
|
QString _cacheFile;
|
||||||
|
CameraMode _cameraMode = CAM_MODE_UNDEFINED;
|
||||||
|
StorageStatus _storageStatus = STORAGE_NOT_SUPPORTED;
|
||||||
|
PhotoMode _photoMode = PHOTO_CAPTURE_SINGLE;
|
||||||
|
qreal _photoLapse = 1.0;
|
||||||
|
int _photoLapseCount = 0;
|
||||||
|
VideoStatus _video_status = VIDEO_CAPTURE_STATUS_UNDEFINED;
|
||||||
|
PhotoStatus _photo_status = PHOTO_CAPTURE_STATUS_UNDEFINED;
|
||||||
|
QStringList _activeSettings;
|
||||||
|
QStringList _settings;
|
||||||
|
QTimer _captureStatusTimer;
|
||||||
|
QList<QGCCameraOptionExclusion*> _valueExclusions;
|
||||||
|
QList<QGCCameraOptionRange*> _optionRanges;
|
||||||
|
QMap<QString, QStringList> _originalOptNames;
|
||||||
|
QMap<QString, QVariantList> _originalOptValues;
|
||||||
|
QMap<QString, QGCCameraParamIO*> _paramIO;
|
||||||
|
int _storageInfoRetries = 0;
|
||||||
|
int _captureInfoRetries = 0;
|
||||||
|
bool _resetting = false;
|
||||||
|
QTimer _recTimer;
|
||||||
|
QTime _recTime;
|
||||||
|
uint32_t _recordTime = 0;
|
||||||
|
//-- Parameters that require a full update
|
||||||
|
QMap<QString, QStringList> _requestUpdates;
|
||||||
|
QStringList _updatesToRequest;
|
||||||
|
//-- Video Streams
|
||||||
|
int _requestCount = 0;
|
||||||
|
int _currentStream = 0;
|
||||||
|
int _expectedCount = 1;
|
||||||
|
QTimer _streamInfoTimer;
|
||||||
|
QTimer _streamStatusTimer;
|
||||||
|
QmlObjectListModel _streams;
|
||||||
|
QStringList _streamLabels;
|
||||||
|
ThermalViewMode _thermalMode = THERMAL_BLEND;
|
||||||
|
double _thermalOpacity = 85.0;
|
||||||
|
};
|
@ -0,0 +1,372 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "QGCCameraControl.h"
|
||||||
|
#include "QGCCameraIO.h"
|
||||||
|
|
||||||
|
QGC_LOGGING_CATEGORY(CameraIOLog, "CameraIOLog")
|
||||||
|
QGC_LOGGING_CATEGORY(CameraIOLogVerbose, "CameraIOLogVerbose")
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraParamIO::QGCCameraParamIO(QGCCameraControl *control, Fact* fact, Vehicle *vehicle)
|
||||||
|
: QObject(control)
|
||||||
|
, _control(control)
|
||||||
|
, _fact(fact)
|
||||||
|
, _vehicle(vehicle)
|
||||||
|
, _sentRetries(0)
|
||||||
|
, _requestRetries(0)
|
||||||
|
, _done(false)
|
||||||
|
, _updateOnSet(false)
|
||||||
|
, _forceUIUpdate(false)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
_paramWriteTimer.setSingleShot(true);
|
||||||
|
_paramWriteTimer.setInterval(3000);
|
||||||
|
_paramRequestTimer.setSingleShot(true);
|
||||||
|
_paramRequestTimer.setInterval(3500);
|
||||||
|
if(_fact->writeOnly()) {
|
||||||
|
//-- Write mode is always "done" as it won't ever read
|
||||||
|
_done = true;
|
||||||
|
} else {
|
||||||
|
connect(&_paramRequestTimer, &QTimer::timeout, this, &QGCCameraParamIO::_paramRequestTimeout);
|
||||||
|
}
|
||||||
|
connect(&_paramWriteTimer, &QTimer::timeout, this, &QGCCameraParamIO::_paramWriteTimeout);
|
||||||
|
connect(_fact, &Fact::rawValueChanged, this, &QGCCameraParamIO::_factChanged);
|
||||||
|
connect(_fact, &Fact::_containerRawValueChanged, this, &QGCCameraParamIO::_containerRawValueChanged);
|
||||||
|
_pMavlink = qgcApp()->toolbox()->mavlinkProtocol();
|
||||||
|
//-- TODO: Even though we don't use anything larger than 32-bit, this should
|
||||||
|
// probably be updated.
|
||||||
|
switch (_fact->type()) {
|
||||||
|
case FactMetaData::valueTypeUint8:
|
||||||
|
case FactMetaData::valueTypeBool:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_UINT8;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt8:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_INT8;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint16:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_UINT16;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt16:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_INT16;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint32:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_UINT32;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint64:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_UINT64;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt64:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_INT64;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeFloat:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_REAL32;
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeDouble:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_REAL64;
|
||||||
|
break;
|
||||||
|
//-- String and custom are the same for now
|
||||||
|
case FactMetaData::valueTypeString:
|
||||||
|
case FactMetaData::valueTypeCustom:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_CUSTOM;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qWarning() << "Unsupported fact type" << _fact->type() << "for" << _fact->name();
|
||||||
|
case FactMetaData::valueTypeInt32:
|
||||||
|
_mavParamType = MAV_PARAM_EXT_TYPE_INT32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::setParamRequest()
|
||||||
|
{
|
||||||
|
if(!_fact->writeOnly()) {
|
||||||
|
_paramRequestReceived = false;
|
||||||
|
_requestRetries = 0;
|
||||||
|
_paramRequestTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::_factChanged(QVariant value)
|
||||||
|
{
|
||||||
|
if(!_forceUIUpdate) {
|
||||||
|
Q_UNUSED(value);
|
||||||
|
qCDebug(CameraIOLog) << "UI Fact" << _fact->name() << "changed to" << value;
|
||||||
|
_control->factChanged(_fact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::_containerRawValueChanged(const QVariant value)
|
||||||
|
{
|
||||||
|
if(!_fact->readOnly()) {
|
||||||
|
Q_UNUSED(value);
|
||||||
|
qCDebug(CameraIOLog) << "Update Fact from camera" << _fact->name();
|
||||||
|
_sentRetries = 0;
|
||||||
|
_sendParameter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::sendParameter(bool updateUI)
|
||||||
|
{
|
||||||
|
qCDebug(CameraIOLog) << "Send Fact" << _fact->name();
|
||||||
|
_sentRetries = 0;
|
||||||
|
_updateOnSet = updateUI;
|
||||||
|
_sendParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::_sendParameter()
|
||||||
|
{
|
||||||
|
WeakLinkInterfacePtr weakLink = _vehicle->vehicleLinkManager()->primaryLink();
|
||||||
|
if (!weakLink.expired()) {
|
||||||
|
SharedLinkInterfacePtr sharedLink = weakLink.lock();
|
||||||
|
|
||||||
|
mavlink_param_ext_set_t p;
|
||||||
|
memset(&p, 0, sizeof(mavlink_param_ext_set_t));
|
||||||
|
param_ext_union_t union_value;
|
||||||
|
mavlink_message_t msg;
|
||||||
|
FactMetaData::ValueType_t factType = _fact->type();
|
||||||
|
p.param_type = _mavParamType;
|
||||||
|
switch (factType) {
|
||||||
|
case FactMetaData::valueTypeUint8:
|
||||||
|
case FactMetaData::valueTypeBool:
|
||||||
|
union_value.param_uint8 = static_cast<uint8_t>(_fact->rawValue().toUInt());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt8:
|
||||||
|
union_value.param_int8 = static_cast<int8_t>(_fact->rawValue().toInt());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint16:
|
||||||
|
union_value.param_uint16 = static_cast<uint16_t>(_fact->rawValue().toUInt());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt16:
|
||||||
|
union_value.param_int16 = static_cast<int16_t>(_fact->rawValue().toInt());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint32:
|
||||||
|
union_value.param_uint32 = static_cast<uint32_t>(_fact->rawValue().toUInt());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeInt64:
|
||||||
|
union_value.param_int64 = static_cast<int64_t>(_fact->rawValue().toLongLong());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeUint64:
|
||||||
|
union_value.param_uint64 = static_cast<uint64_t>(_fact->rawValue().toULongLong());
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeFloat:
|
||||||
|
union_value.param_float = _fact->rawValue().toFloat();
|
||||||
|
break;
|
||||||
|
case FactMetaData::valueTypeDouble:
|
||||||
|
union_value.param_double = _fact->rawValue().toDouble();
|
||||||
|
break;
|
||||||
|
//-- String and custom are the same for now
|
||||||
|
case FactMetaData::valueTypeString:
|
||||||
|
case FactMetaData::valueTypeCustom:
|
||||||
|
{
|
||||||
|
QByteArray custom = _fact->rawValue().toByteArray();
|
||||||
|
memcpy(union_value.bytes, custom.data(), static_cast<size_t>(std::max(custom.size(), static_cast<qsizetype>(MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_VALUE_LEN))));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qCritical() << "Unsupported fact type" << factType << "for" << _fact->name();
|
||||||
|
case FactMetaData::valueTypeInt32:
|
||||||
|
union_value.param_int32 = static_cast<int32_t>(_fact->rawValue().toInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(&p.param_value[0], &union_value.bytes[0], MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_VALUE_LEN);
|
||||||
|
p.target_system = static_cast<uint8_t>(_vehicle->id());
|
||||||
|
p.target_component = static_cast<uint8_t>(_control->compID());
|
||||||
|
strncpy(p.param_id, _fact->name().toStdString().c_str(), MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_ID_LEN);
|
||||||
|
mavlink_msg_param_ext_set_encode_chan(
|
||||||
|
static_cast<uint8_t>(_pMavlink->getSystemId()),
|
||||||
|
static_cast<uint8_t>(_pMavlink->getComponentId()),
|
||||||
|
sharedLink->mavlinkChannel(),
|
||||||
|
&msg,
|
||||||
|
&p);
|
||||||
|
_vehicle->sendMessageOnLinkThreadSafe(sharedLink.get(), msg);
|
||||||
|
}
|
||||||
|
_paramWriteTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::_paramWriteTimeout()
|
||||||
|
{
|
||||||
|
if(++_sentRetries > 3) {
|
||||||
|
qCWarning(CameraIOLog) << "No response for param set:" << _fact->name();
|
||||||
|
_updateOnSet = false;
|
||||||
|
} else {
|
||||||
|
//-- Send it again
|
||||||
|
qCDebug(CameraIOLog) << "Param set retry:" << _fact->name() << _sentRetries;
|
||||||
|
_sendParameter();
|
||||||
|
_paramWriteTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::handleParamAck(const mavlink_param_ext_ack_t& ack)
|
||||||
|
{
|
||||||
|
_paramWriteTimer.stop();
|
||||||
|
if(ack.param_result == PARAM_ACK_ACCEPTED) {
|
||||||
|
QVariant val = _valueFromMessage(ack.param_value, ack.param_type);
|
||||||
|
if(_fact->rawValue() != val) {
|
||||||
|
_fact->_containerSetRawValue(val);
|
||||||
|
if(_updateOnSet) {
|
||||||
|
_updateOnSet = false;
|
||||||
|
_control->factChanged(_fact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(ack.param_result == PARAM_ACK_IN_PROGRESS) {
|
||||||
|
//-- Wait a bit longer for this one
|
||||||
|
qCDebug(CameraIOLogVerbose) << "Param set in progress:" << _fact->name();
|
||||||
|
_paramWriteTimer.start();
|
||||||
|
} else {
|
||||||
|
if(ack.param_result == PARAM_ACK_FAILED) {
|
||||||
|
if(++_sentRetries < 3) {
|
||||||
|
//-- Try again
|
||||||
|
qCWarning(CameraIOLog) << "Param set failed:" << _fact->name() << _sentRetries;
|
||||||
|
_paramWriteTimer.start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if(ack.param_result == PARAM_ACK_VALUE_UNSUPPORTED) {
|
||||||
|
qCWarning(CameraIOLog) << "Param set unsuported:" << _fact->name();
|
||||||
|
}
|
||||||
|
//-- If UI changed and value was not set, restore UI
|
||||||
|
QVariant val = _valueFromMessage(ack.param_value, ack.param_type);
|
||||||
|
if(_fact->rawValue() != val) {
|
||||||
|
if(_control->validateParameter(_fact, val)) {
|
||||||
|
_fact->_containerSetRawValue(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::handleParamValue(const mavlink_param_ext_value_t& value)
|
||||||
|
{
|
||||||
|
_paramRequestTimer.stop();
|
||||||
|
QVariant newValue = _valueFromMessage(value.param_value, value.param_type);
|
||||||
|
if(_control->incomingParameter(_fact, newValue)) {
|
||||||
|
_fact->_containerSetRawValue(newValue);
|
||||||
|
}
|
||||||
|
_paramRequestReceived = true;
|
||||||
|
if(_forceUIUpdate) {
|
||||||
|
emit _fact->rawValueChanged(_fact->rawValue());
|
||||||
|
emit _fact->valueChanged(_fact->rawValue());
|
||||||
|
_forceUIUpdate = false;
|
||||||
|
}
|
||||||
|
if(!_done) {
|
||||||
|
_done = true;
|
||||||
|
_control->_paramDone();
|
||||||
|
}
|
||||||
|
qCDebug(CameraIOLog) << QString("handleParamValue() %1 %2").arg(_fact->name()).arg(_fact->rawValueString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QVariant
|
||||||
|
QGCCameraParamIO::_valueFromMessage(const char* value, uint8_t param_type)
|
||||||
|
{
|
||||||
|
QVariant var;
|
||||||
|
param_ext_union_t u;
|
||||||
|
memcpy(u.bytes, value, MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_VALUE_LEN);
|
||||||
|
switch (param_type) {
|
||||||
|
case MAV_PARAM_EXT_TYPE_REAL32:
|
||||||
|
var = QVariant(u.param_float);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_UINT8:
|
||||||
|
var = QVariant(u.param_uint8);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_INT8:
|
||||||
|
var = QVariant(u.param_int8);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_UINT16:
|
||||||
|
var = QVariant(u.param_uint16);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_INT16:
|
||||||
|
var = QVariant(u.param_int16);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_UINT32:
|
||||||
|
var = QVariant(u.param_uint32);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_INT32:
|
||||||
|
var = QVariant(u.param_int32);
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_UINT64:
|
||||||
|
var = QVariant(static_cast<qulonglong>(u.param_uint64));
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_INT64:
|
||||||
|
var = QVariant(static_cast<qulonglong>(u.param_int64));
|
||||||
|
break;
|
||||||
|
case MAV_PARAM_EXT_TYPE_CUSTOM:
|
||||||
|
var = QVariant(QByteArray(value, MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_VALUE_LEN));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
var = QVariant(0);
|
||||||
|
qCritical() << "Invalid param_type used for camera setting:" << param_type;
|
||||||
|
}
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::_paramRequestTimeout()
|
||||||
|
{
|
||||||
|
if(++_requestRetries > 3) {
|
||||||
|
qCWarning(CameraIOLog) << "No response for param request:" << _fact->name();
|
||||||
|
if(!_done) {
|
||||||
|
_done = true;
|
||||||
|
_control->_paramDone();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//-- Request it again
|
||||||
|
qCDebug(CameraIOLog) << "Param request retry:" << _fact->name();
|
||||||
|
paramRequest(false);
|
||||||
|
_paramRequestTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraParamIO::paramRequest(bool reset)
|
||||||
|
{
|
||||||
|
//-- If it's write only, we don't request it.
|
||||||
|
if(_fact->writeOnly()) {
|
||||||
|
if(!_done) {
|
||||||
|
_done = true;
|
||||||
|
_control->_paramDone();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(reset) {
|
||||||
|
_requestRetries = 0;
|
||||||
|
_forceUIUpdate = true;
|
||||||
|
}
|
||||||
|
qCDebug(CameraIOLog) << "Request parameter:" << _fact->name();
|
||||||
|
WeakLinkInterfacePtr weakLink = _vehicle->vehicleLinkManager()->primaryLink();
|
||||||
|
if (!weakLink.expired()) {
|
||||||
|
SharedLinkInterfacePtr sharedLink = weakLink.lock();
|
||||||
|
|
||||||
|
char param_id[MAVLINK_MSG_PARAM_EXT_REQUEST_READ_FIELD_PARAM_ID_LEN + 1];
|
||||||
|
memset(param_id, 0, sizeof(param_id));
|
||||||
|
strncpy(param_id, _fact->name().toStdString().c_str(), MAVLINK_MSG_PARAM_EXT_REQUEST_READ_FIELD_PARAM_ID_LEN);
|
||||||
|
mavlink_message_t msg;
|
||||||
|
mavlink_msg_param_ext_request_read_pack_chan(
|
||||||
|
static_cast<uint8_t>(_pMavlink->getSystemId()),
|
||||||
|
static_cast<uint8_t>(_pMavlink->getComponentId()),
|
||||||
|
sharedLink->mavlinkChannel(),
|
||||||
|
&msg,
|
||||||
|
static_cast<uint8_t>(_vehicle->id()),
|
||||||
|
static_cast<uint8_t>(_control->compID()),
|
||||||
|
param_id,
|
||||||
|
-1);
|
||||||
|
_vehicle->sendMessageOnLinkThreadSafe(sharedLink.get(), msg);
|
||||||
|
}
|
||||||
|
_paramRequestTimer.start();
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "QGCApplication.h"
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
class QGCCameraControl;
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(CameraIOLog)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(CameraIOLogVerbose)
|
||||||
|
|
||||||
|
MAVPACKED(
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
float param_float;
|
||||||
|
double param_double;
|
||||||
|
int64_t param_int64;
|
||||||
|
uint64_t param_uint64;
|
||||||
|
int32_t param_int32;
|
||||||
|
uint32_t param_uint32;
|
||||||
|
int16_t param_int16;
|
||||||
|
uint16_t param_uint16;
|
||||||
|
int8_t param_int8;
|
||||||
|
uint8_t param_uint8;
|
||||||
|
uint8_t bytes[MAVLINK_MSG_PARAM_EXT_SET_FIELD_PARAM_VALUE_LEN];
|
||||||
|
};
|
||||||
|
uint8_t type;
|
||||||
|
}) param_ext_union_t;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// Camera parameter handler.
|
||||||
|
class QGCCameraParamIO : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QGCCameraParamIO(QGCCameraControl* control, Fact* fact, Vehicle* vehicle);
|
||||||
|
|
||||||
|
void handleParamAck (const mavlink_param_ext_ack_t& ack);
|
||||||
|
void handleParamValue (const mavlink_param_ext_value_t& value);
|
||||||
|
void setParamRequest ();
|
||||||
|
bool paramDone () const { return _done; }
|
||||||
|
void paramRequest (bool reset = true);
|
||||||
|
void sendParameter (bool updateUI = false);
|
||||||
|
|
||||||
|
QStringList optNames;
|
||||||
|
QVariantList optVariants;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void _paramWriteTimeout ();
|
||||||
|
void _paramRequestTimeout ();
|
||||||
|
void _factChanged (QVariant value);
|
||||||
|
void _containerRawValueChanged (const QVariant value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _sendParameter ();
|
||||||
|
QVariant _valueFromMessage (const char* value, uint8_t param_type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QGCCameraControl* _control;
|
||||||
|
Fact* _fact;
|
||||||
|
Vehicle* _vehicle;
|
||||||
|
int _sentRetries;
|
||||||
|
int _requestRetries;
|
||||||
|
bool _paramRequestReceived;
|
||||||
|
QTimer _paramWriteTimer;
|
||||||
|
QTimer _paramRequestTimer;
|
||||||
|
bool _done;
|
||||||
|
bool _updateOnSet;
|
||||||
|
MAV_PARAM_EXT_TYPE _mavParamType;
|
||||||
|
MAVLinkProtocol* _pMavlink;
|
||||||
|
bool _forceUIUpdate;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,518 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include "QGCApplication.h"
|
||||||
|
#include "QGCCameraManager.h"
|
||||||
|
#include "JoystickManager.h"
|
||||||
|
|
||||||
|
QGC_LOGGING_CATEGORY(CameraManagerLog, "CameraManagerLog")
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraManager::CameraStruct::CameraStruct(QObject* parent, uint8_t compID_)
|
||||||
|
: QObject(parent)
|
||||||
|
, compID(compID_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraManager::QGCCameraManager(Vehicle *vehicle)
|
||||||
|
: _vehicle(vehicle)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
qCDebug(CameraManagerLog) << "QGCCameraManager Created";
|
||||||
|
connect(qgcApp()->toolbox()->multiVehicleManager(), &MultiVehicleManager::parameterReadyVehicleAvailableChanged, this, &QGCCameraManager::_vehicleReady);
|
||||||
|
connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &QGCCameraManager::_mavlinkMessageReceived);
|
||||||
|
connect(&_cameraTimer, &QTimer::timeout, this, &QGCCameraManager::_cameraTimeout);
|
||||||
|
_cameraTimer.setSingleShot(false);
|
||||||
|
_lastZoomChange.start();
|
||||||
|
_lastCameraChange.start();
|
||||||
|
_cameraTimer.start(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraManager::~QGCCameraManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::setCurrentCamera(int sel)
|
||||||
|
{
|
||||||
|
if(sel != _currentCamera && sel >= 0 && sel < _cameras.count()) {
|
||||||
|
_currentCamera = sel;
|
||||||
|
emit currentCameraChanged();
|
||||||
|
emit streamChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_vehicleReady(bool ready)
|
||||||
|
{
|
||||||
|
qCDebug(CameraManagerLog) << "_vehicleReady(" << ready << ")";
|
||||||
|
if(ready) {
|
||||||
|
if(qgcApp()->toolbox()->multiVehicleManager()->activeVehicle() == _vehicle) {
|
||||||
|
_vehicleReadyState = true;
|
||||||
|
JoystickManager *pJoyMgr = qgcApp()->toolbox()->joystickManager();
|
||||||
|
_activeJoystickChanged(pJoyMgr->activeJoystick());
|
||||||
|
connect(pJoyMgr, &JoystickManager::activeJoystickChanged, this, &QGCCameraManager::_activeJoystickChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_mavlinkMessageReceived(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
//-- Only pay attention to camera components, as identified by their compId
|
||||||
|
if(message.sysid == _vehicle->id() && (message.compid >= MAV_COMP_ID_CAMERA && message.compid <= MAV_COMP_ID_CAMERA6)) {
|
||||||
|
switch (message.msgid) {
|
||||||
|
case MAVLINK_MSG_ID_CAMERA_CAPTURE_STATUS:
|
||||||
|
_handleCaptureStatus(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_STORAGE_INFORMATION:
|
||||||
|
_handleStorageInfo(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_HEARTBEAT:
|
||||||
|
_handleHeartbeat(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_CAMERA_INFORMATION:
|
||||||
|
_handleCameraInfo(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_CAMERA_SETTINGS:
|
||||||
|
_handleCameraSettings(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_PARAM_EXT_ACK:
|
||||||
|
_handleParamAck(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_PARAM_EXT_VALUE:
|
||||||
|
_handleParamValue(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_VIDEO_STREAM_INFORMATION:
|
||||||
|
_handleVideoStreamInfo(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_VIDEO_STREAM_STATUS:
|
||||||
|
_handleVideoStreamStatus(message);
|
||||||
|
break;
|
||||||
|
case MAVLINK_MSG_ID_BATTERY_STATUS:
|
||||||
|
_handleBatteryStatus(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleHeartbeat(const mavlink_message_t &message)
|
||||||
|
{
|
||||||
|
//-- First time hearing from this one?
|
||||||
|
QString sCompID = QString::number(message.compid);
|
||||||
|
if(!_cameraInfoRequest.contains(sCompID)) {
|
||||||
|
qCDebug(CameraManagerLog) << "Hearbeat from " << message.compid;
|
||||||
|
CameraStruct* pInfo = new CameraStruct(this, message.compid);
|
||||||
|
pInfo->lastHeartbeat.start();
|
||||||
|
_cameraInfoRequest[sCompID] = pInfo;
|
||||||
|
//-- Request camera info
|
||||||
|
_requestCameraInfo(message.compid);
|
||||||
|
} else {
|
||||||
|
if(_cameraInfoRequest[sCompID]) {
|
||||||
|
CameraStruct* pInfo = _cameraInfoRequest[sCompID];
|
||||||
|
//-- Check if we have indeed received the camera info
|
||||||
|
if(pInfo->infoReceived) {
|
||||||
|
//-- We have it. Just update the heartbeat timeout
|
||||||
|
pInfo->lastHeartbeat.start();
|
||||||
|
} else {
|
||||||
|
//-- Try again. Maybe.
|
||||||
|
if(pInfo->lastHeartbeat.elapsed() > 2000) {
|
||||||
|
if(pInfo->tryCount > 10) {
|
||||||
|
if(!pInfo->gaveUp) {
|
||||||
|
pInfo->gaveUp = true;
|
||||||
|
qWarning() << "Giving up requesting camera info from" << _vehicle->id() << message.compid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pInfo->tryCount++;
|
||||||
|
//-- Request camera info again.
|
||||||
|
_requestCameraInfo(message.compid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "_cameraInfoRequest[" << sCompID << "] is null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraControl*
|
||||||
|
QGCCameraManager::currentCameraInstance()
|
||||||
|
{
|
||||||
|
if(_currentCamera < _cameras.count() && _cameras.count()) {
|
||||||
|
QGCCameraControl* pCamera = qobject_cast<QGCCameraControl*>(_cameras[_currentCamera]);
|
||||||
|
return pCamera;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCVideoStreamInfo*
|
||||||
|
QGCCameraManager::currentStreamInstance()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
QGCVideoStreamInfo* pInfo = pCamera->currentStreamInstance();
|
||||||
|
return pInfo;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCVideoStreamInfo*
|
||||||
|
QGCCameraManager::thermalStreamInstance()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
QGCVideoStreamInfo* pInfo = pCamera->thermalStreamInstance();
|
||||||
|
return pInfo;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
QGCCameraControl*
|
||||||
|
QGCCameraManager::_findCamera(int id)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < _cameras.count(); i++) {
|
||||||
|
if(_cameras[i]) {
|
||||||
|
QGCCameraControl* pCamera = qobject_cast<QGCCameraControl*>(_cameras[i]);
|
||||||
|
if(pCamera) {
|
||||||
|
if(pCamera->compID() == id) {
|
||||||
|
return pCamera;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCritical() << "Null QGCCameraControl instance";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//qWarning() << "Camera component id not found:" << id;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
//-- Have we requested it?
|
||||||
|
QString sCompID = QString::number(message.compid);
|
||||||
|
if(_cameraInfoRequest.contains(sCompID) && !_cameraInfoRequest[sCompID]->infoReceived) {
|
||||||
|
//-- Flag it as done
|
||||||
|
_cameraInfoRequest[sCompID]->infoReceived = true;
|
||||||
|
mavlink_camera_information_t info;
|
||||||
|
mavlink_msg_camera_information_decode(&message, &info);
|
||||||
|
qCDebug(CameraManagerLog) << "_handleCameraInfo:" << reinterpret_cast<const char*>(info.model_name) << reinterpret_cast<const char*>(info.vendor_name) << "Comp ID:" << message.compid;
|
||||||
|
QGCCameraControl* pCamera = _vehicle->firmwarePlugin()->createCameraControl(&info, _vehicle, message.compid, this);
|
||||||
|
if(pCamera) {
|
||||||
|
QQmlEngine::setObjectOwnership(pCamera, QQmlEngine::CppOwnership);
|
||||||
|
_cameras.append(pCamera);
|
||||||
|
_cameraLabels << pCamera->modelName();
|
||||||
|
emit camerasChanged();
|
||||||
|
emit cameraLabelsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_cameraTimeout()
|
||||||
|
{
|
||||||
|
//-- Iterate cameras
|
||||||
|
foreach(QString sCompID, _cameraInfoRequest.keys()) {
|
||||||
|
if(_cameraInfoRequest[sCompID]) {
|
||||||
|
CameraStruct* pInfo = _cameraInfoRequest[sCompID];
|
||||||
|
//-- Have we received a camera info message?
|
||||||
|
if(pInfo->infoReceived) {
|
||||||
|
//-- Has the camera stopped talking to us?
|
||||||
|
if(pInfo->lastHeartbeat.elapsed() > 5000) {
|
||||||
|
//-- Camera is gone. Remove it.
|
||||||
|
bool autoStream = false;
|
||||||
|
QGCCameraControl* pCamera = _findCamera(pInfo->compID);
|
||||||
|
if(pCamera) {
|
||||||
|
qWarning() << "Camera" << pCamera->modelName() << "stopped transmitting. Removing from list.";
|
||||||
|
int idx = _cameraLabels.indexOf(pCamera->modelName());
|
||||||
|
if(idx >= 0) {
|
||||||
|
_cameraLabels.removeAt(idx);
|
||||||
|
}
|
||||||
|
idx = _cameras.indexOf(pCamera);
|
||||||
|
if(idx >= 0) {
|
||||||
|
_cameras.removeAt(idx);
|
||||||
|
}
|
||||||
|
autoStream = pCamera->autoStream();
|
||||||
|
pCamera->deleteLater();
|
||||||
|
delete pInfo;
|
||||||
|
}
|
||||||
|
_cameraInfoRequest.remove(sCompID);
|
||||||
|
emit cameraLabelsChanged();
|
||||||
|
//-- If we have another camera, switch current camera.
|
||||||
|
if(_cameras.count()) {
|
||||||
|
setCurrentCamera(0);
|
||||||
|
} else {
|
||||||
|
//-- We're out of cameras
|
||||||
|
emit camerasChanged();
|
||||||
|
if(autoStream) {
|
||||||
|
emit streamChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-- Exit loop.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleCaptureStatus(const mavlink_message_t &message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_camera_capture_status_t cap;
|
||||||
|
mavlink_msg_camera_capture_status_decode(&message, &cap);
|
||||||
|
pCamera->handleCaptureStatus(cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleStorageInfo(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_storage_information_t st;
|
||||||
|
mavlink_msg_storage_information_decode(&message, &st);
|
||||||
|
pCamera->handleStorageInfo(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleCameraSettings(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_camera_settings_t settings;
|
||||||
|
mavlink_msg_camera_settings_decode(&message, &settings);
|
||||||
|
pCamera->handleSettings(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleParamAck(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_param_ext_ack_t ack;
|
||||||
|
mavlink_msg_param_ext_ack_decode(&message, &ack);
|
||||||
|
pCamera->handleParamAck(ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleParamValue(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_param_ext_value_t value;
|
||||||
|
mavlink_msg_param_ext_value_decode(&message, &value);
|
||||||
|
pCamera->handleParamValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleVideoStreamInfo(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_video_stream_information_t streamInfo;
|
||||||
|
mavlink_msg_video_stream_information_decode(&message, &streamInfo);
|
||||||
|
pCamera->handleVideoInfo(&streamInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleVideoStreamStatus(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_video_stream_status_t streamStatus;
|
||||||
|
mavlink_msg_video_stream_status_decode(&message, &streamStatus);
|
||||||
|
pCamera->handleVideoStatus(&streamStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_handleBatteryStatus(const mavlink_message_t& message)
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = _findCamera(message.compid);
|
||||||
|
if(pCamera) {
|
||||||
|
mavlink_battery_status_t batteryStatus;
|
||||||
|
mavlink_msg_battery_status_decode(&message, &batteryStatus);
|
||||||
|
pCamera->handleBatteryStatus(batteryStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_requestCameraInfo(int compID)
|
||||||
|
{
|
||||||
|
qCDebug(CameraManagerLog) << "_requestCameraInfo(" << compID << ")";
|
||||||
|
if(_vehicle) {
|
||||||
|
_vehicle->sendMavCommand(
|
||||||
|
compID, // target component
|
||||||
|
MAV_CMD_REQUEST_CAMERA_INFORMATION, // command id
|
||||||
|
false, // showError
|
||||||
|
1); // Do Request
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_activeJoystickChanged(Joystick* joystick)
|
||||||
|
{
|
||||||
|
qCDebug(CameraManagerLog) << "Joystick changed";
|
||||||
|
if(_activeJoystick) {
|
||||||
|
disconnect(_activeJoystick, &Joystick::stepZoom, this, &QGCCameraManager::_stepZoom);
|
||||||
|
disconnect(_activeJoystick, &Joystick::startContinuousZoom, this, &QGCCameraManager::_startZoom);
|
||||||
|
disconnect(_activeJoystick, &Joystick::stopContinuousZoom, this, &QGCCameraManager::_stopZoom);
|
||||||
|
disconnect(_activeJoystick, &Joystick::stepCamera, this, &QGCCameraManager::_stepCamera);
|
||||||
|
disconnect(_activeJoystick, &Joystick::stepStream, this, &QGCCameraManager::_stepStream);
|
||||||
|
disconnect(_activeJoystick, &Joystick::triggerCamera, this, &QGCCameraManager::_triggerCamera);
|
||||||
|
disconnect(_activeJoystick, &Joystick::startVideoRecord, this, &QGCCameraManager::_startVideoRecording);
|
||||||
|
disconnect(_activeJoystick, &Joystick::stopVideoRecord, this, &QGCCameraManager::_stopVideoRecording);
|
||||||
|
disconnect(_activeJoystick, &Joystick::toggleVideoRecord, this, &QGCCameraManager::_toggleVideoRecording);
|
||||||
|
}
|
||||||
|
_activeJoystick = joystick;
|
||||||
|
if(_activeJoystick) {
|
||||||
|
connect(_activeJoystick, &Joystick::stepZoom, this, &QGCCameraManager::_stepZoom);
|
||||||
|
connect(_activeJoystick, &Joystick::startContinuousZoom, this, &QGCCameraManager::_startZoom);
|
||||||
|
connect(_activeJoystick, &Joystick::stopContinuousZoom, this, &QGCCameraManager::_stopZoom);
|
||||||
|
connect(_activeJoystick, &Joystick::stepCamera, this, &QGCCameraManager::_stepCamera);
|
||||||
|
connect(_activeJoystick, &Joystick::stepStream, this, &QGCCameraManager::_stepStream);
|
||||||
|
connect(_activeJoystick, &Joystick::triggerCamera, this, &QGCCameraManager::_triggerCamera);
|
||||||
|
connect(_activeJoystick, &Joystick::startVideoRecord, this, &QGCCameraManager::_startVideoRecording);
|
||||||
|
connect(_activeJoystick, &Joystick::stopVideoRecord, this, &QGCCameraManager::_stopVideoRecording);
|
||||||
|
connect(_activeJoystick, &Joystick::toggleVideoRecord, this, &QGCCameraManager::_toggleVideoRecording);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_triggerCamera()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->takePhoto();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_startVideoRecording()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->startVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_stopVideoRecording()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->stopVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_toggleVideoRecording()
|
||||||
|
{
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->toggleVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_stepZoom(int direction)
|
||||||
|
{
|
||||||
|
if(_lastZoomChange.elapsed() > 40) {
|
||||||
|
_lastZoomChange.start();
|
||||||
|
qCDebug(CameraManagerLog) << "Step Camera Zoom" << direction;
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->stepZoom(direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_startZoom(int direction)
|
||||||
|
{
|
||||||
|
qCDebug(CameraManagerLog) << "Start Camera Zoom" << direction;
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->startZoom(direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_stopZoom()
|
||||||
|
{
|
||||||
|
qCDebug(CameraManagerLog) << "Stop Camera Zoom";
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
pCamera->stopZoom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_stepCamera(int direction)
|
||||||
|
{
|
||||||
|
if(_lastCameraChange.elapsed() > 1000) {
|
||||||
|
_lastCameraChange.start();
|
||||||
|
qCDebug(CameraManagerLog) << "Step Camera" << direction;
|
||||||
|
int c = _currentCamera + direction;
|
||||||
|
if(c < 0) c = _cameras.count() - 1;
|
||||||
|
if(c >= _cameras.count()) c = 0;
|
||||||
|
setCurrentCamera(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
QGCCameraManager::_stepStream(int direction)
|
||||||
|
{
|
||||||
|
if(_lastCameraChange.elapsed() > 1000) {
|
||||||
|
_lastCameraChange.start();
|
||||||
|
QGCCameraControl* pCamera = currentCameraInstance();
|
||||||
|
if(pCamera) {
|
||||||
|
qCDebug(CameraManagerLog) << "Step Camera Stream" << direction;
|
||||||
|
int c = pCamera->currentStream() + direction;
|
||||||
|
if(c < 0) c = pCamera->streams()->count() - 1;
|
||||||
|
if(c >= pCamera->streams()->count()) c = 0;
|
||||||
|
pCamera->setCurrentStream(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,112 @@
|
|||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Camera Controller
|
||||||
|
* @author Gus Grubba <gus@auterion.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief MAVLink Camera API. Camera Manager.
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "QGCApplication.h"
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#include "QmlObjectListModel.h"
|
||||||
|
#include "QGCCameraControl.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(CameraManagerLog)
|
||||||
|
|
||||||
|
class Joystick;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// Camera Manager
|
||||||
|
class QGCCameraManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCCameraManager(Vehicle* vehicle);
|
||||||
|
virtual ~QGCCameraManager();
|
||||||
|
|
||||||
|
Q_PROPERTY(QmlObjectListModel* cameras READ cameras NOTIFY camerasChanged)
|
||||||
|
Q_PROPERTY(QStringList cameraLabels READ cameraLabels NOTIFY cameraLabelsChanged)
|
||||||
|
Q_PROPERTY(QGCCameraControl* currentCameraInstance READ currentCameraInstance NOTIFY currentCameraChanged)
|
||||||
|
Q_PROPERTY(int currentCamera READ currentCamera WRITE setCurrentCamera NOTIFY currentCameraChanged)
|
||||||
|
|
||||||
|
//-- Return a list of cameras provided by this vehicle
|
||||||
|
virtual QmlObjectListModel* cameras () { return &_cameras; }
|
||||||
|
//-- Camera names to show the user (for selection)
|
||||||
|
virtual QStringList cameraLabels () { return _cameraLabels; }
|
||||||
|
//-- Current selected camera
|
||||||
|
virtual int currentCamera () { return _currentCamera; }
|
||||||
|
virtual QGCCameraControl* currentCameraInstance();
|
||||||
|
//-- Set current camera
|
||||||
|
virtual void setCurrentCamera (int sel);
|
||||||
|
//-- Current stream
|
||||||
|
virtual QGCVideoStreamInfo* currentStreamInstance();
|
||||||
|
//-- Current thermal stream
|
||||||
|
virtual QGCVideoStreamInfo* thermalStreamInstance();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void camerasChanged ();
|
||||||
|
void cameraLabelsChanged ();
|
||||||
|
void currentCameraChanged ();
|
||||||
|
void streamChanged ();
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
virtual void _vehicleReady (bool ready);
|
||||||
|
virtual void _mavlinkMessageReceived (const mavlink_message_t& message);
|
||||||
|
virtual void _activeJoystickChanged (Joystick* joystick);
|
||||||
|
virtual void _stepZoom (int direction);
|
||||||
|
virtual void _startZoom (int direction);
|
||||||
|
virtual void _stopZoom ();
|
||||||
|
virtual void _stepCamera (int direction);
|
||||||
|
virtual void _stepStream (int direction);
|
||||||
|
virtual void _cameraTimeout ();
|
||||||
|
virtual void _triggerCamera ();
|
||||||
|
virtual void _startVideoRecording ();
|
||||||
|
virtual void _stopVideoRecording ();
|
||||||
|
virtual void _toggleVideoRecording ();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QGCCameraControl* _findCamera (int id);
|
||||||
|
virtual void _requestCameraInfo (int compID);
|
||||||
|
virtual void _handleHeartbeat (const mavlink_message_t& message);
|
||||||
|
virtual void _handleCameraInfo (const mavlink_message_t& message);
|
||||||
|
virtual void _handleStorageInfo (const mavlink_message_t& message);
|
||||||
|
virtual void _handleCameraSettings (const mavlink_message_t& message);
|
||||||
|
virtual void _handleParamAck (const mavlink_message_t& message);
|
||||||
|
virtual void _handleParamValue (const mavlink_message_t& message);
|
||||||
|
virtual void _handleCaptureStatus (const mavlink_message_t& message);
|
||||||
|
virtual void _handleVideoStreamInfo (const mavlink_message_t& message);
|
||||||
|
virtual void _handleVideoStreamStatus(const mavlink_message_t& message);
|
||||||
|
virtual void _handleBatteryStatus (const mavlink_message_t& message);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
class CameraStruct : public QObject {
|
||||||
|
public:
|
||||||
|
CameraStruct(QObject* parent, uint8_t compID_);
|
||||||
|
QElapsedTimer lastHeartbeat;
|
||||||
|
bool infoReceived = false;
|
||||||
|
bool gaveUp = false;
|
||||||
|
int tryCount = 0;
|
||||||
|
uint8_t compID = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vehicle* _vehicle = nullptr;
|
||||||
|
Joystick* _activeJoystick = nullptr;
|
||||||
|
bool _vehicleReadyState = false;
|
||||||
|
int _currentTask = 0;
|
||||||
|
QmlObjectListModel _cameras;
|
||||||
|
QStringList _cameraLabels;
|
||||||
|
int _currentCamera = 0;
|
||||||
|
QElapsedTimer _lastZoomChange;
|
||||||
|
QElapsedTimer _lastCameraChange;
|
||||||
|
QTimer _cameraTimer;
|
||||||
|
QMap<QString, CameraStruct*> _cameraInfoRequest;
|
||||||
|
};
|
@ -0,0 +1,502 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "QGCApplication.h"
|
||||||
|
#include "QGCCorePlugin.h"
|
||||||
|
#include "QGCOptions.h"
|
||||||
|
#include "QmlComponentInfo.h"
|
||||||
|
#include "FactMetaData.h"
|
||||||
|
#include "SettingsManager.h"
|
||||||
|
#include "AppMessages.h"
|
||||||
|
#include "QmlObjectListModel.h"
|
||||||
|
#include "VideoManager.h"
|
||||||
|
#if defined(QGC_GST_STREAMING)
|
||||||
|
#include "GStreamer.h"
|
||||||
|
#include "VideoReceiver.h"
|
||||||
|
#endif
|
||||||
|
#include "QGCLoggingCategory.h"
|
||||||
|
#include "QGCCameraManager.h"
|
||||||
|
#include "HorizontalFactValueGrid.h"
|
||||||
|
#include "InstrumentValueData.h"
|
||||||
|
|
||||||
|
#include <QtQml>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief Core Plugin Interface for QGroundControl - Default Implementation
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
class QGCCorePlugin_p
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QGCCorePlugin_p()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~QGCCorePlugin_p()
|
||||||
|
{
|
||||||
|
if(pGeneral)
|
||||||
|
delete pGeneral;
|
||||||
|
if(pCommLinks)
|
||||||
|
delete pCommLinks;
|
||||||
|
if(pOfflineMaps)
|
||||||
|
delete pOfflineMaps;
|
||||||
|
#if defined(QGC_GST_TAISYNC_ENABLED)
|
||||||
|
if(pTaisync)
|
||||||
|
delete pTaisync;
|
||||||
|
#endif
|
||||||
|
#if defined(QGC_GST_MICROHARD_ENABLED)
|
||||||
|
if(pMicrohard)
|
||||||
|
delete pMicrohard;
|
||||||
|
#endif
|
||||||
|
if(pMAVLink)
|
||||||
|
delete pMAVLink;
|
||||||
|
if(pConsole)
|
||||||
|
delete pConsole;
|
||||||
|
#if defined(QT_DEBUG)
|
||||||
|
if(pMockLink)
|
||||||
|
delete pMockLink;
|
||||||
|
if(pDebug)
|
||||||
|
delete pDebug;
|
||||||
|
if(pQmlTest)
|
||||||
|
delete pQmlTest;
|
||||||
|
#endif
|
||||||
|
if(pRemoteID)
|
||||||
|
delete pRemoteID;
|
||||||
|
if(defaultOptions)
|
||||||
|
delete defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlComponentInfo* pGeneral = nullptr;
|
||||||
|
QmlComponentInfo* pCommLinks = nullptr;
|
||||||
|
QmlComponentInfo* pOfflineMaps = nullptr;
|
||||||
|
#if defined(QGC_GST_TAISYNC_ENABLED)
|
||||||
|
QmlComponentInfo* pTaisync = nullptr;
|
||||||
|
#endif
|
||||||
|
#if defined(QGC_GST_MICROHARD_ENABLED)
|
||||||
|
QmlComponentInfo* pMicrohard = nullptr;
|
||||||
|
#endif
|
||||||
|
QmlComponentInfo* pMAVLink = nullptr;
|
||||||
|
QmlComponentInfo* pConsole = nullptr;
|
||||||
|
QmlComponentInfo* pHelp = nullptr;
|
||||||
|
#if defined(QT_DEBUG)
|
||||||
|
QmlComponentInfo* pMockLink = nullptr;
|
||||||
|
QmlComponentInfo* pDebug = nullptr;
|
||||||
|
QmlComponentInfo* pQmlTest = nullptr;
|
||||||
|
#endif
|
||||||
|
QmlComponentInfo* pRemoteID = nullptr;
|
||||||
|
|
||||||
|
QGCOptions* defaultOptions = nullptr;
|
||||||
|
QVariantList settingsList;
|
||||||
|
QVariantList analyzeList;
|
||||||
|
|
||||||
|
QmlObjectListModel _emptyCustomMapItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
QGCCorePlugin::~QGCCorePlugin()
|
||||||
|
{
|
||||||
|
if(_p) {
|
||||||
|
delete _p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QGCCorePlugin::QGCCorePlugin(QGCApplication *app, QGCToolbox* toolbox)
|
||||||
|
: QGCTool(app, toolbox)
|
||||||
|
, _showTouchAreas(false)
|
||||||
|
, _showAdvancedUI(true)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
_p = new QGCCorePlugin_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::setToolbox(QGCToolbox *toolbox)
|
||||||
|
{
|
||||||
|
QGCTool::setToolbox(toolbox);
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType<QGCCorePlugin> ("QGroundControl", 1, 0, "QGCCorePlugin", "Reference only");
|
||||||
|
qmlRegisterUncreatableType<QGCOptions> ("QGroundControl", 1, 0, "QGCOptions", "Reference only");
|
||||||
|
qmlRegisterUncreatableType<QGCFlyViewOptions> ("QGroundControl", 1, 0, "QGCFlyViewOptions", "Reference only");
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList &QGCCorePlugin::settingsPages()
|
||||||
|
{
|
||||||
|
if(!_p->pGeneral) {
|
||||||
|
_p->pGeneral = new QmlComponentInfo(tr("General"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/GeneralSettings.qml"),
|
||||||
|
QUrl::fromUserInput("qrc:/res/gear-white.svg"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pGeneral)));
|
||||||
|
_p->pCommLinks = new QmlComponentInfo(tr("Comm Links"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/LinkSettings.qml"),
|
||||||
|
QUrl::fromUserInput("qrc:/res/waves.svg"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pCommLinks)));
|
||||||
|
_p->pOfflineMaps = new QmlComponentInfo(tr("Offline Maps"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/OfflineMap.qml"),
|
||||||
|
QUrl::fromUserInput("qrc:/res/waves.svg"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pOfflineMaps)));
|
||||||
|
#if defined(QGC_GST_TAISYNC_ENABLED)
|
||||||
|
_p->pTaisync = new QmlComponentInfo(tr("Taisync"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/TaisyncSettings.qml"),
|
||||||
|
QUrl::fromUserInput(""));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pTaisync)));
|
||||||
|
#endif
|
||||||
|
#if defined(QGC_GST_MICROHARD_ENABLED)
|
||||||
|
_p->pMicrohard = new QmlComponentInfo(tr("Microhard"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/MicrohardSettings.qml"),
|
||||||
|
QUrl::fromUserInput(""));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMicrohard)));
|
||||||
|
#endif
|
||||||
|
_p->pMAVLink = new QmlComponentInfo(tr("MAVLink"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/MavlinkSettings.qml"),
|
||||||
|
QUrl::fromUserInput("qrc:/res/waves.svg"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMAVLink)));
|
||||||
|
_p->pRemoteID = new QmlComponentInfo(tr("Remote ID"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/RemoteIDSettings.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pRemoteID)));
|
||||||
|
_p->pConsole = new QmlComponentInfo(tr("Console"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/QGroundControl/Controls/AppMessages.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pConsole)));
|
||||||
|
_p->pHelp = new QmlComponentInfo(tr("Help"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/HelpSettings.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pHelp)));
|
||||||
|
#if defined(QT_DEBUG)
|
||||||
|
//-- These are always present on Debug builds
|
||||||
|
_p->pMockLink = new QmlComponentInfo(tr("Mock Link"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/MockLink.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pMockLink)));
|
||||||
|
_p->pDebug = new QmlComponentInfo(tr("Debug"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/DebugWindow.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pDebug)));
|
||||||
|
_p->pQmlTest = new QmlComponentInfo(tr("Palette Test"),
|
||||||
|
QUrl::fromUserInput("qrc:/qml/QmlTest.qml"));
|
||||||
|
_p->settingsList.append(QVariant::fromValue(reinterpret_cast<QmlComponentInfo*>(_p->pQmlTest)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return _p->settingsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList& QGCCorePlugin::analyzePages()
|
||||||
|
{
|
||||||
|
if (!_p->analyzeList.count()) {
|
||||||
|
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("Log Download"), QUrl::fromUserInput("qrc:/qml/LogDownloadPage.qml"), QUrl::fromUserInput("qrc:/qmlimages/LogDownloadIcon"))));
|
||||||
|
#if !defined(__mobile__)
|
||||||
|
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("GeoTag Images"), QUrl::fromUserInput("qrc:/qml/GeoTagPage.qml"), QUrl::fromUserInput("qrc:/qmlimages/GeoTagIcon"))));
|
||||||
|
#endif
|
||||||
|
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("MAVLink Console"), QUrl::fromUserInput("qrc:/qml/MavlinkConsolePage.qml"), QUrl::fromUserInput("qrc:/qmlimages/MavlinkConsoleIcon"))));
|
||||||
|
#if !defined(QGC_DISABLE_MAVLINK_INSPECTOR)
|
||||||
|
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("MAVLink Inspector"),QUrl::fromUserInput("qrc:/qml/MAVLinkInspectorPage.qml"), QUrl::fromUserInput("qrc:/qmlimages/MAVLinkInspector"))));
|
||||||
|
#endif
|
||||||
|
_p->analyzeList.append(QVariant::fromValue(new QmlComponentInfo(tr("Vibration"), QUrl::fromUserInput("qrc:/qml/VibrationPage.qml"), QUrl::fromUserInput("qrc:/qmlimages/VibrationPageIcon"))));
|
||||||
|
}
|
||||||
|
return _p->analyzeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QGCCorePlugin::defaultSettings()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGCOptions* QGCCorePlugin::options()
|
||||||
|
{
|
||||||
|
if (!_p->defaultOptions) {
|
||||||
|
_p->defaultOptions = new QGCOptions(this);
|
||||||
|
}
|
||||||
|
return _p->defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGCCorePlugin::overrideSettingsGroupVisibility(QString name)
|
||||||
|
{
|
||||||
|
Q_UNUSED(name);
|
||||||
|
|
||||||
|
// Always show all
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGCCorePlugin::adjustSettingMetaData(const QString& settingsGroup, FactMetaData& metaData)
|
||||||
|
{
|
||||||
|
if (settingsGroup == AppSettings::settingsGroup) {
|
||||||
|
#if !defined(QGC_ENABLE_PAIRING)
|
||||||
|
//-- If we don't support pairing, disable it.
|
||||||
|
if (metaData.name() == AppSettings::usePairingName) {
|
||||||
|
metaData.setRawDefaultValue(false);
|
||||||
|
//-- And hide the option
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-- Default Palette
|
||||||
|
if (metaData.name() == AppSettings::indoorPaletteName) {
|
||||||
|
QVariant outdoorPalette;
|
||||||
|
#if defined (__mobile__)
|
||||||
|
outdoorPalette = 0;
|
||||||
|
#else
|
||||||
|
outdoorPalette = 1;
|
||||||
|
#endif
|
||||||
|
metaData.setRawDefaultValue(outdoorPalette);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__mobile__)
|
||||||
|
if (metaData.name() == AppSettings::telemetrySaveName) {
|
||||||
|
// Mobile devices have limited storage so don't turn on telemtry saving by default
|
||||||
|
metaData.setRawDefaultValue(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __android__
|
||||||
|
if (metaData.name() == AppSettings::androidSaveToSDCardName) {
|
||||||
|
// This only shows on android builds
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Show setting in ui
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::setShowTouchAreas(bool show)
|
||||||
|
{
|
||||||
|
if (show != _showTouchAreas) {
|
||||||
|
_showTouchAreas = show;
|
||||||
|
emit showTouchAreasChanged(show);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::setShowAdvancedUI(bool show)
|
||||||
|
{
|
||||||
|
if (show != _showAdvancedUI) {
|
||||||
|
_showAdvancedUI = show;
|
||||||
|
emit showAdvancedUIChanged(show);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::paletteOverride(QString /*colorName*/, QGCPalette::PaletteColorInfo_t& /*colorInfo*/)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QGCCorePlugin::showAdvancedUIMessage() const
|
||||||
|
{
|
||||||
|
return tr("WARNING: You are about to enter Advanced Mode. "
|
||||||
|
"If used incorrectly, this may cause your vehicle to malfunction thus voiding your warranty. "
|
||||||
|
"You should do so only if instructed by customer support. "
|
||||||
|
"Are you sure you want to enable Advanced Mode?");
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::factValueGridCreateDefaultSettings(const QString& defaultSettingsGroup)
|
||||||
|
{
|
||||||
|
HorizontalFactValueGrid factValueGrid(defaultSettingsGroup);
|
||||||
|
|
||||||
|
bool includeFWValues = factValueGrid.vehicleClass() == QGCMAVLink::VehicleClassFixedWing || factValueGrid.vehicleClass() == QGCMAVLink::VehicleClassVTOL || factValueGrid.vehicleClass() == QGCMAVLink::VehicleClassAirship;
|
||||||
|
|
||||||
|
factValueGrid.setFontSize(FactValueGrid::LargeFontSize);
|
||||||
|
|
||||||
|
factValueGrid.appendColumn();
|
||||||
|
factValueGrid.appendColumn();
|
||||||
|
factValueGrid.appendColumn();
|
||||||
|
if (includeFWValues) {
|
||||||
|
factValueGrid.appendColumn();
|
||||||
|
}
|
||||||
|
factValueGrid.appendRow();
|
||||||
|
|
||||||
|
int rowIndex = 0;
|
||||||
|
QmlObjectListModel* column = factValueGrid.columns()->value<QmlObjectListModel*>(0);
|
||||||
|
|
||||||
|
InstrumentValueData* value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "AltitudeRelative");
|
||||||
|
value->setIcon("arrow-thick-up.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(true);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "DistanceToHome");
|
||||||
|
value->setIcon("bookmark copy 3.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(true);
|
||||||
|
|
||||||
|
rowIndex = 0;
|
||||||
|
column = factValueGrid.columns()->value<QmlObjectListModel*>(1);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "ClimbRate");
|
||||||
|
value->setIcon("arrow-simple-up.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(true);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "GroundSpeed");
|
||||||
|
value->setIcon("arrow-simple-right.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(true);
|
||||||
|
|
||||||
|
|
||||||
|
if (includeFWValues) {
|
||||||
|
rowIndex = 0;
|
||||||
|
column = factValueGrid.columns()->value<QmlObjectListModel*>(2);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "AirSpeed");
|
||||||
|
value->setText("AirSpd");
|
||||||
|
value->setShowUnits(true);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "ThrottlePct");
|
||||||
|
value->setText("Thr");
|
||||||
|
value->setShowUnits(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowIndex = 0;
|
||||||
|
column = factValueGrid.columns()->value<QmlObjectListModel*>(includeFWValues ? 3 : 2);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "FlightTime");
|
||||||
|
value->setIcon("timer.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(false);
|
||||||
|
|
||||||
|
value = column->value<InstrumentValueData*>(rowIndex++);
|
||||||
|
value->setFact("Vehicle", "FlightDistance");
|
||||||
|
value->setIcon("travel-walk.svg");
|
||||||
|
value->setText(value->fact()->shortDescription());
|
||||||
|
value->setShowUnits(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlApplicationEngine* QGCCorePlugin::createQmlApplicationEngine(QObject* parent)
|
||||||
|
{
|
||||||
|
QQmlApplicationEngine* qmlEngine = new QQmlApplicationEngine(parent);
|
||||||
|
qmlEngine->addImportPath("qrc:/qml");
|
||||||
|
qmlEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
|
||||||
|
qmlEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
|
||||||
|
return qmlEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::createRootWindow(QQmlApplicationEngine* qmlEngine)
|
||||||
|
{
|
||||||
|
qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGCCorePlugin::mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message)
|
||||||
|
{
|
||||||
|
Q_UNUSED(vehicle);
|
||||||
|
Q_UNUSED(link);
|
||||||
|
Q_UNUSED(message);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlObjectListModel* QGCCorePlugin::customMapItems()
|
||||||
|
{
|
||||||
|
return &_p->_emptyCustomMapItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoManager* QGCCorePlugin::createVideoManager(QGCApplication *app, QGCToolbox *toolbox)
|
||||||
|
{
|
||||||
|
return new VideoManager(app, toolbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoReceiver* QGCCorePlugin::createVideoReceiver(QObject* parent)
|
||||||
|
{
|
||||||
|
#if defined(QGC_GST_STREAMING)
|
||||||
|
return GStreamer::createVideoReceiver(parent);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void* QGCCorePlugin::createVideoSink(QObject* parent, QQuickItem* widget)
|
||||||
|
{
|
||||||
|
#if defined(QGC_GST_STREAMING)
|
||||||
|
return GStreamer::createVideoSink(parent, widget);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
Q_UNUSED(widget)
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGCCorePlugin::releaseVideoSink(void* sink)
|
||||||
|
{
|
||||||
|
#if defined(QGC_GST_STREAMING)
|
||||||
|
GStreamer::releaseVideoSink(sink);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(sink)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGCCorePlugin::guidedActionsControllerLogging() const
|
||||||
|
{
|
||||||
|
return GuidedActionsControllerLog().isDebugEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QGCCorePlugin::stableVersionCheckFileUrl() const
|
||||||
|
{
|
||||||
|
#ifdef QGC_CUSTOM_BUILD
|
||||||
|
// Custom builds must override to turn on and provide their own location
|
||||||
|
return QString();
|
||||||
|
#else
|
||||||
|
return QString("https://s3-us-west-2.amazonaws.com/qgroundcontrol/latest/QGC.version.txt");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVariantList& QGCCorePlugin::toolBarIndicators(void)
|
||||||
|
{
|
||||||
|
//-- Default list of indicators for all vehicles.
|
||||||
|
if(_toolBarIndicatorList.size() == 0) {
|
||||||
|
_toolBarIndicatorList = QVariantList({
|
||||||
|
QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSRTKIndicator.qml")),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return _toolBarIndicatorList;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> QGCCorePlugin::firstRunPromptStdIds(void)
|
||||||
|
{
|
||||||
|
QList<int> rgStdIds = { unitsFirstRunPromptId, offlineVehicleFirstRunPromptId };
|
||||||
|
return rgStdIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> QGCCorePlugin::firstRunPromptCustomIds(void)
|
||||||
|
{
|
||||||
|
return QList<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList QGCCorePlugin::firstRunPromptsToShow(void)
|
||||||
|
{
|
||||||
|
QList<int> rgIdsToShow;
|
||||||
|
|
||||||
|
rgIdsToShow.append(firstRunPromptStdIds());
|
||||||
|
rgIdsToShow.append(firstRunPromptCustomIds());
|
||||||
|
|
||||||
|
QList<int> rgAlreadyShownIds = AppSettings::firstRunPromptsIdsVariantToList(_toolbox->settingsManager()->appSettings()->firstRunPromptIdsShown()->rawValue());
|
||||||
|
|
||||||
|
for (int idToRemove: rgAlreadyShownIds) {
|
||||||
|
rgIdsToShow.removeOne(idToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList rgVarIdsToShow;
|
||||||
|
for (int id: rgIdsToShow) {
|
||||||
|
rgVarIdsToShow.append(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rgVarIdsToShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QGCCorePlugin::firstRunPromptResource(int id)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
case unitsFirstRunPromptId:
|
||||||
|
return "/FirstRunPromptDialogs/UnitsFirstRunPrompt.qml";
|
||||||
|
case offlineVehicleFirstRunPromptId:
|
||||||
|
return "/FirstRunPromptDialogs/OfflineVehicleFirstRunPrompt.qml";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
@ -0,0 +1,222 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "QGCToolbox.h"
|
||||||
|
#include "QGCPalette.h"
|
||||||
|
#include "QGCMAVLink.h"
|
||||||
|
#include "QmlObjectListModel.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QVariantList>
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief Core Plugin Interface for QGroundControl
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
class QGCApplication;
|
||||||
|
class QGCOptions;
|
||||||
|
class QGCSettings;
|
||||||
|
class QGCCorePlugin_p;
|
||||||
|
class FactMetaData;
|
||||||
|
class QGeoPositionInfoSource;
|
||||||
|
class QQmlApplicationEngine;
|
||||||
|
class Vehicle;
|
||||||
|
class LinkInterface;
|
||||||
|
class QmlObjectListModel;
|
||||||
|
class VideoReceiver;
|
||||||
|
class VideoSink;
|
||||||
|
class PlanMasterController;
|
||||||
|
class QGCCameraManager;
|
||||||
|
class QGCCameraControl;
|
||||||
|
class QQuickItem;
|
||||||
|
class InstrumentValueAreaController;
|
||||||
|
|
||||||
|
#ifndef OPAQUE_PTR_QGCCorePlugin
|
||||||
|
#define OPAQUE_PTR_QGCCorePlugin
|
||||||
|
Q_DECLARE_OPAQUE_POINTER(QGCOptions*)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QGCCorePlugin : public QGCTool
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCCorePlugin(QGCApplication* app, QGCToolbox* toolbox);
|
||||||
|
~QGCCorePlugin();
|
||||||
|
|
||||||
|
Q_PROPERTY(QVariantList settingsPages READ settingsPages NOTIFY settingsPagesChanged)
|
||||||
|
Q_PROPERTY(QVariantList analyzePages READ analyzePages NOTIFY analyzePagesChanged)
|
||||||
|
Q_PROPERTY(int defaultSettings READ defaultSettings CONSTANT)
|
||||||
|
Q_PROPERTY(QGCOptions* options READ options CONSTANT)
|
||||||
|
Q_PROPERTY(bool showTouchAreas READ showTouchAreas WRITE setShowTouchAreas NOTIFY showTouchAreasChanged)
|
||||||
|
Q_PROPERTY(bool showAdvancedUI READ showAdvancedUI WRITE setShowAdvancedUI NOTIFY showAdvancedUIChanged)
|
||||||
|
Q_PROPERTY(QString showAdvancedUIMessage READ showAdvancedUIMessage CONSTANT)
|
||||||
|
Q_PROPERTY(QString brandImageIndoor READ brandImageIndoor CONSTANT)
|
||||||
|
Q_PROPERTY(QString brandImageOutdoor READ brandImageOutdoor CONSTANT)
|
||||||
|
Q_PROPERTY(QmlObjectListModel* customMapItems READ customMapItems CONSTANT)
|
||||||
|
Q_PROPERTY(QVariantList toolBarIndicators READ toolBarIndicators NOTIFY toolBarIndicatorsChanged)
|
||||||
|
Q_PROPERTY(int unitsFirstRunPromptId MEMBER unitsFirstRunPromptId CONSTANT)
|
||||||
|
Q_PROPERTY(int offlineVehicleFirstRunPromptId MEMBER offlineVehicleFirstRunPromptId CONSTANT)
|
||||||
|
|
||||||
|
Q_INVOKABLE bool guidedActionsControllerLogging() const;
|
||||||
|
|
||||||
|
/// The list of settings under the Settings Menu
|
||||||
|
/// @return A list of QGCSettings
|
||||||
|
virtual QVariantList& settingsPages();
|
||||||
|
|
||||||
|
/// The list of pages/buttons under the Analyze Menu
|
||||||
|
/// @return A list of QmlPageInfo
|
||||||
|
virtual QVariantList& analyzePages();
|
||||||
|
|
||||||
|
/// The default settings panel to show
|
||||||
|
/// @return The settings index
|
||||||
|
virtual int defaultSettings();
|
||||||
|
|
||||||
|
/// Global options
|
||||||
|
/// @return An instance of QGCOptions
|
||||||
|
virtual QGCOptions* options();
|
||||||
|
|
||||||
|
/// Allows the core plugin to override the visibility for a settings group
|
||||||
|
/// @param name - SettingsGroup name
|
||||||
|
/// @return true: Show settings ui, false: Hide settings ui
|
||||||
|
virtual bool overrideSettingsGroupVisibility(QString name);
|
||||||
|
|
||||||
|
/// Allows the core plugin to override the setting meta data before the setting fact is created.
|
||||||
|
/// @param settingsGroup - QSettings group which contains this item
|
||||||
|
/// @param metaData - MetaData for setting fact
|
||||||
|
/// @return true: Setting should be visible in ui, false: Setting should not be shown in ui
|
||||||
|
virtual bool adjustSettingMetaData(const QString& settingsGroup, FactMetaData& metaData);
|
||||||
|
|
||||||
|
/// Return the resource file which contains the brand image for for Indoor theme.
|
||||||
|
virtual QString brandImageIndoor() const { return QString(); }
|
||||||
|
|
||||||
|
/// Return the resource file which contains the brand image for for Outdoor theme.
|
||||||
|
virtual QString brandImageOutdoor() const { return QString(); }
|
||||||
|
|
||||||
|
/// @return The message to show to the user when they a re prompted to confirm turning on advanced ui.
|
||||||
|
virtual QString showAdvancedUIMessage() const;
|
||||||
|
|
||||||
|
/// @return An instance of an alternate position source (or NULL if not available)
|
||||||
|
virtual QGeoPositionInfoSource* createPositionSource(QObject* /*parent*/) { return nullptr; }
|
||||||
|
|
||||||
|
/// Allows a plugin to override the specified color name from the palette
|
||||||
|
virtual void paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo);
|
||||||
|
|
||||||
|
virtual void factValueGridCreateDefaultSettings(const QString& defaultSettingsGroup);
|
||||||
|
|
||||||
|
/// Allows the plugin to override or get access to the QmlApplicationEngine to do things like add import
|
||||||
|
/// path or stuff things into the context prior to window creation.
|
||||||
|
virtual QQmlApplicationEngine* createQmlApplicationEngine(QObject* parent);
|
||||||
|
|
||||||
|
/// Allows the plugin to override the creation of the root (native) window.
|
||||||
|
virtual void createRootWindow(QQmlApplicationEngine* qmlEngine);
|
||||||
|
|
||||||
|
/// Allows the plugin to override the creation of VideoManager.
|
||||||
|
virtual VideoManager* createVideoManager(QGCApplication* app, QGCToolbox* toolbox);
|
||||||
|
/// Allows the plugin to override the creation of VideoReceiver.
|
||||||
|
virtual VideoReceiver* createVideoReceiver(QObject* parent);
|
||||||
|
/// Allows the plugin to override the creation of VideoSink.
|
||||||
|
virtual void* createVideoSink(QObject* parent, QQuickItem* widget);
|
||||||
|
/// Allows the plugin to override the release of VideoSink.
|
||||||
|
virtual void releaseVideoSink(void* sink);
|
||||||
|
|
||||||
|
/// Allows the plugin to see all mavlink traffic to a vehicle
|
||||||
|
/// @return true: Allow vehicle to continue processing, false: Vehicle should not process message
|
||||||
|
virtual bool mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message);
|
||||||
|
|
||||||
|
/// Allows custom builds to add custom items to the FlightMap. Objects put into QmlObjectListModel should derive from QmlComponentInfo and set the url property.
|
||||||
|
virtual QmlObjectListModel* customMapItems();
|
||||||
|
|
||||||
|
/// Allows custom builds to add custom items to the plan file before the document is created.
|
||||||
|
virtual void preSaveToJson (PlanMasterController* /*pController*/, QJsonObject& /*json*/) {}
|
||||||
|
/// Allows custom builds to add custom items to the plan file after the document is created.
|
||||||
|
virtual void postSaveToJson (PlanMasterController* /*pController*/, QJsonObject& /*json*/) {}
|
||||||
|
|
||||||
|
/// Allows custom builds to add custom items to the mission section of the plan file before the item is created.
|
||||||
|
virtual void preSaveToMissionJson (PlanMasterController* /*pController*/, QJsonObject& /*missionJson*/) {}
|
||||||
|
/// Allows custom builds to add custom items to the mission section of the plan file after the item is created.
|
||||||
|
virtual void postSaveToMissionJson (PlanMasterController* /*pController*/, QJsonObject& /*missionJson*/) {}
|
||||||
|
|
||||||
|
/// Allows custom builds to load custom items from the plan file before the document is parsed.
|
||||||
|
virtual void preLoadFromJson (PlanMasterController* /*pController*/, QJsonObject& /*json*/) {}
|
||||||
|
/// Allows custom builds to load custom items from the plan file after the document is parsed.
|
||||||
|
virtual void postLoadFromJson (PlanMasterController* /*pController*/, QJsonObject& /*json*/) {}
|
||||||
|
|
||||||
|
/// Returns the url to download the stable version check file. Return QString() to indicate no version check should be performed.
|
||||||
|
/// Default QGC mainline implemenentation returns QGC Stable file location. Default QGC custom build code returns QString().
|
||||||
|
/// Custom builds can override to turn on and provide their own location.
|
||||||
|
/// The contents of this file should be a single line in the form:
|
||||||
|
/// v3.4.4
|
||||||
|
/// This indicates the latest stable version number.
|
||||||
|
virtual QString stableVersionCheckFileUrl() const;
|
||||||
|
|
||||||
|
/// Returns the user visible url to show user where to download new stable builds from.
|
||||||
|
/// Custom builds must override to provide their own location.
|
||||||
|
virtual QString stableDownloadLocation() const { return QString("qgroundcontrol.com"); }
|
||||||
|
|
||||||
|
/// Returns the complex mission items to display in the Plan UI
|
||||||
|
/// @param complexMissionItemNames Default set of complex items
|
||||||
|
/// @return Complex items to be made available to user
|
||||||
|
virtual QStringList complexMissionItemNames(Vehicle* /*vehicle*/, const QStringList& complexMissionItemNames) { return complexMissionItemNames; }
|
||||||
|
|
||||||
|
/// Returns the standard list of first run prompt ids for possible display. Actual display is based on the
|
||||||
|
/// current AppSettings::firstRunPromptIds value. The order of this list also determines the order the prompts
|
||||||
|
/// will be displayed in.
|
||||||
|
virtual QList<int> firstRunPromptStdIds(void);
|
||||||
|
|
||||||
|
/// Returns the custom build list of first run prompt ids for possible display. Actual display is based on the
|
||||||
|
/// current AppSettings::firstRunPromptIds value. The order of this list also determines the order the prompts
|
||||||
|
/// will be displayed in.
|
||||||
|
virtual QList<int> firstRunPromptCustomIds(void);
|
||||||
|
|
||||||
|
/// Returns the resource which contains the specified first run prompt for display
|
||||||
|
Q_INVOKABLE virtual QString firstRunPromptResource(int id);
|
||||||
|
|
||||||
|
/// Returns the list of toolbar indicators which are not related to a vehicle
|
||||||
|
/// signals toolbarIndicatorsChanged
|
||||||
|
/// @return A list of QUrl with the indicators
|
||||||
|
virtual const QVariantList& toolBarIndicators(void);
|
||||||
|
|
||||||
|
/// Returns the list of first run prompt ids which need to be displayed according to current settings
|
||||||
|
Q_INVOKABLE QVariantList firstRunPromptsToShow(void);
|
||||||
|
|
||||||
|
bool showTouchAreas() const { return _showTouchAreas; }
|
||||||
|
bool showAdvancedUI() const { return _showAdvancedUI; }
|
||||||
|
void setShowTouchAreas(bool show);
|
||||||
|
void setShowAdvancedUI(bool show);
|
||||||
|
|
||||||
|
// Override from QGCTool
|
||||||
|
void setToolbox (QGCToolbox* toolbox);
|
||||||
|
|
||||||
|
// Standard first run prompt ids
|
||||||
|
static const int unitsFirstRunPromptId = 1;
|
||||||
|
static const int offlineVehicleFirstRunPromptId = 2;
|
||||||
|
|
||||||
|
// Custom builds can start there first run prompt ids from here
|
||||||
|
static const int firstRunPromptIdsFirstCustomId = 10000;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void settingsPagesChanged ();
|
||||||
|
void analyzePagesChanged ();
|
||||||
|
void showTouchAreasChanged (bool showTouchAreas);
|
||||||
|
void showAdvancedUIChanged (bool showAdvancedUI);
|
||||||
|
void toolBarIndicatorsChanged ();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _showTouchAreas;
|
||||||
|
bool _showAdvancedUI;
|
||||||
|
Vehicle* _activeVehicle = nullptr;
|
||||||
|
QGCCameraManager* _cameraManager = nullptr;
|
||||||
|
QGCCameraControl* _currentCamera = nullptr;
|
||||||
|
QVariantList _toolBarIndicatorList;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QGCCorePlugin_p* _p;
|
||||||
|
};
|
@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "QGCOptions.h"
|
||||||
|
|
||||||
|
#include <QtQml>
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief Core Plugin Interface for QGroundControl - Application Options
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
QGCOptions::QGCOptions(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor QGCOptions::toolbarBackgroundLight() const
|
||||||
|
{
|
||||||
|
return QColor(255,255,255);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor QGCOptions::toolbarBackgroundDark() const
|
||||||
|
{
|
||||||
|
return QColor(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGCFlyViewOptions* QGCOptions::flyViewOptions(void)
|
||||||
|
{
|
||||||
|
if (!_defaultFlyViewOptions) {
|
||||||
|
_defaultFlyViewOptions = new QGCFlyViewOptions(this);
|
||||||
|
}
|
||||||
|
return _defaultFlyViewOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGCFlyViewOptions::QGCFlyViewOptions(QGCOptions* options, QObject* parent)
|
||||||
|
: QObject (parent)
|
||||||
|
, _options (options)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
class QGCOptions;
|
||||||
|
|
||||||
|
class QGCFlyViewOptions : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCFlyViewOptions(QGCOptions* options, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Q_PROPERTY(bool showMultiVehicleList READ showMultiVehicleList CONSTANT)
|
||||||
|
Q_PROPERTY(bool showInstrumentPanel READ showInstrumentPanel CONSTANT)
|
||||||
|
Q_PROPERTY(bool showMapScale READ showMapScale CONSTANT)
|
||||||
|
Q_PROPERTY(bool guidedBarShowEmergencyStop READ guidedBarShowEmergencyStop NOTIFY guidedBarShowEmergencyStopChanged)
|
||||||
|
Q_PROPERTY(bool guidedBarShowOrbit READ guidedBarShowOrbit NOTIFY guidedBarShowOrbitChanged)
|
||||||
|
Q_PROPERTY(bool guidedBarShowROI READ guidedBarShowROI NOTIFY guidedBarShowROIChanged)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool showMultiVehicleList () const { return true; }
|
||||||
|
virtual bool showMapScale () const { return true; }
|
||||||
|
virtual bool showInstrumentPanel () const { return true; }
|
||||||
|
virtual bool guidedBarShowEmergencyStop () const { return true; }
|
||||||
|
virtual bool guidedBarShowOrbit () const { return true; }
|
||||||
|
virtual bool guidedBarShowROI () const { return true; }
|
||||||
|
|
||||||
|
QGCOptions* _options;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void guidedBarShowEmergencyStopChanged (bool show);
|
||||||
|
void guidedBarShowOrbitChanged (bool show);
|
||||||
|
void guidedBarShowROIChanged (bool show);
|
||||||
|
};
|
||||||
|
|
||||||
|
class QGCOptions : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCOptions(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Q_PROPERTY(bool combineSettingsAndSetup READ combineSettingsAndSetup CONSTANT)
|
||||||
|
Q_PROPERTY(double toolbarHeightMultiplier READ toolbarHeightMultiplier CONSTANT)
|
||||||
|
Q_PROPERTY(bool enablePlanViewSelector READ enablePlanViewSelector CONSTANT)
|
||||||
|
Q_PROPERTY(QUrl preFlightChecklistUrl READ preFlightChecklistUrl CONSTANT)
|
||||||
|
Q_PROPERTY(bool showSensorCalibrationCompass READ showSensorCalibrationCompass NOTIFY showSensorCalibrationCompassChanged)
|
||||||
|
Q_PROPERTY(bool showSensorCalibrationGyro READ showSensorCalibrationGyro NOTIFY showSensorCalibrationGyroChanged)
|
||||||
|
Q_PROPERTY(bool showSensorCalibrationAccel READ showSensorCalibrationAccel NOTIFY showSensorCalibrationAccelChanged)
|
||||||
|
Q_PROPERTY(bool showSensorCalibrationLevel READ showSensorCalibrationLevel NOTIFY showSensorCalibrationLevelChanged)
|
||||||
|
Q_PROPERTY(bool showSensorCalibrationAirspeed READ showSensorCalibrationAirspeed NOTIFY showSensorCalibrationAirspeedChanged)
|
||||||
|
Q_PROPERTY(bool sensorsHaveFixedOrientation READ sensorsHaveFixedOrientation CONSTANT)
|
||||||
|
Q_PROPERTY(bool wifiReliableForCalibration READ wifiReliableForCalibration CONSTANT)
|
||||||
|
Q_PROPERTY(bool showFirmwareUpgrade READ showFirmwareUpgrade NOTIFY showFirmwareUpgradeChanged)
|
||||||
|
Q_PROPERTY(QString firmwareUpgradeSingleURL READ firmwareUpgradeSingleURL CONSTANT)
|
||||||
|
Q_PROPERTY(bool missionWaypointsOnly READ missionWaypointsOnly NOTIFY missionWaypointsOnlyChanged)
|
||||||
|
Q_PROPERTY(bool multiVehicleEnabled READ multiVehicleEnabled NOTIFY multiVehicleEnabledChanged)
|
||||||
|
Q_PROPERTY(bool showOfflineMapExport READ showOfflineMapExport NOTIFY showOfflineMapExportChanged)
|
||||||
|
Q_PROPERTY(bool showOfflineMapImport READ showOfflineMapImport NOTIFY showOfflineMapImportChanged)
|
||||||
|
Q_PROPERTY(bool useMobileFileDialog READ useMobileFileDialog CONSTANT)
|
||||||
|
Q_PROPERTY(bool showMissionStatus READ showMissionStatus CONSTANT)
|
||||||
|
Q_PROPERTY(bool guidedActionsRequireRCRSSI READ guidedActionsRequireRCRSSI CONSTANT)
|
||||||
|
Q_PROPERTY(bool showMissionAbsoluteAltitude READ showMissionAbsoluteAltitude NOTIFY showMissionAbsoluteAltitudeChanged)
|
||||||
|
Q_PROPERTY(bool showSimpleMissionStart READ showSimpleMissionStart NOTIFY showSimpleMissionStartChanged)
|
||||||
|
Q_PROPERTY(bool disableVehicleConnection READ disableVehicleConnection CONSTANT)
|
||||||
|
Q_PROPERTY(float devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
|
||||||
|
Q_PROPERTY(float devicePixelDensity READ devicePixelDensity NOTIFY devicePixelDensityChanged)
|
||||||
|
Q_PROPERTY(bool checkFirmwareVersion READ checkFirmwareVersion CONSTANT)
|
||||||
|
Q_PROPERTY(bool showMavlinkLogOptions READ showMavlinkLogOptions CONSTANT)
|
||||||
|
Q_PROPERTY(bool enableSaveMainWindowPosition READ enableSaveMainWindowPosition CONSTANT)
|
||||||
|
Q_PROPERTY(QStringList surveyBuiltInPresetNames READ surveyBuiltInPresetNames CONSTANT)
|
||||||
|
Q_PROPERTY(bool allowJoystickSelection READ allowJoystickSelection NOTIFY allowJoystickSelectionChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QGCFlyViewOptions* flyView READ flyViewOptions CONSTANT)
|
||||||
|
|
||||||
|
/// Should QGC hide its settings menu and colapse it into one single menu (Settings and Vehicle Setup)?
|
||||||
|
/// @return true if QGC should consolidate both menus into one.
|
||||||
|
virtual bool combineSettingsAndSetup () { return false; }
|
||||||
|
|
||||||
|
/// Main ToolBar Multiplier.
|
||||||
|
/// @return Factor to use when computing toolbar height
|
||||||
|
virtual double toolbarHeightMultiplier () { return 1.0; }
|
||||||
|
|
||||||
|
/// Enable Plan View Selector (Mission, Fence or Rally)
|
||||||
|
/// @return True or false
|
||||||
|
virtual bool enablePlanViewSelector () { return true; }
|
||||||
|
|
||||||
|
/// Should the mission status indicator (Plan View) be shown?
|
||||||
|
/// @return Yes or no
|
||||||
|
virtual bool showMissionStatus () { return true; }
|
||||||
|
|
||||||
|
/// Provides an optional, custom preflight checklist
|
||||||
|
virtual QUrl preFlightChecklistUrl () const { return QUrl::fromUserInput("qrc:/qml/PreFlightCheckList.qml"); }
|
||||||
|
|
||||||
|
/// Allows replacing the toolbar Light Theme color
|
||||||
|
virtual QColor toolbarBackgroundLight () const;
|
||||||
|
/// Allows replacing the toolbar Dark Theme color
|
||||||
|
virtual QColor toolbarBackgroundDark () const;
|
||||||
|
/// By returning false you can hide the following sensor calibration pages
|
||||||
|
virtual bool showSensorCalibrationCompass () const { return true; }
|
||||||
|
virtual bool showSensorCalibrationGyro () const { return true; }
|
||||||
|
virtual bool showSensorCalibrationAccel () const { return true; }
|
||||||
|
virtual bool showSensorCalibrationLevel () const { return true; }
|
||||||
|
virtual bool showSensorCalibrationAirspeed () const { return true; }
|
||||||
|
virtual bool wifiReliableForCalibration () const { return false; }
|
||||||
|
virtual bool sensorsHaveFixedOrientation () const { return false; }
|
||||||
|
virtual bool showFirmwareUpgrade () const { return true; }
|
||||||
|
virtual bool missionWaypointsOnly () const { return false; } ///< true: Only allow waypoints and complex items in Plan
|
||||||
|
virtual bool multiVehicleEnabled () const { return true; } ///< false: multi vehicle support is disabled
|
||||||
|
virtual bool guidedActionsRequireRCRSSI () const { return false; } ///< true: Guided actions will be disabled is there is no RC RSSI
|
||||||
|
virtual bool showOfflineMapExport () const { return true; }
|
||||||
|
virtual bool showOfflineMapImport () const { return true; }
|
||||||
|
virtual bool showMissionAbsoluteAltitude () const { return true; }
|
||||||
|
virtual bool showSimpleMissionStart () const { return false; }
|
||||||
|
virtual bool disableVehicleConnection () const { return false; } ///< true: vehicle connection is disabled
|
||||||
|
virtual bool checkFirmwareVersion () const { return true; }
|
||||||
|
virtual bool showMavlinkLogOptions () const { return true; }
|
||||||
|
virtual bool allowJoystickSelection () const { return true; } ///< false: custom build has automatically enabled a specific joystick
|
||||||
|
/// Desktop builds save the main application size and position on close (and restore it on open)
|
||||||
|
virtual bool enableSaveMainWindowPosition () const { return true; }
|
||||||
|
virtual QStringList surveyBuiltInPresetNames () const { return QStringList(); } // Built in presets cannot be deleted
|
||||||
|
|
||||||
|
#if defined(__mobile__)
|
||||||
|
virtual bool useMobileFileDialog () const { return true;}
|
||||||
|
#else
|
||||||
|
virtual bool useMobileFileDialog () const { return false;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// If returned QString in non-empty it means that firmware upgrade will run in a mode which only
|
||||||
|
/// supports downloading a single firmware file from the URL. It also supports custom install through
|
||||||
|
/// the Advanced options.
|
||||||
|
virtual QString firmwareUpgradeSingleURL () const { return QString(); }
|
||||||
|
|
||||||
|
/// Device specific pixel ratio/density (for when Qt doesn't properly read it from the hardware)
|
||||||
|
virtual float devicePixelRatio () const { return 0.0f; }
|
||||||
|
virtual float devicePixelDensity () const { return 0.0f; }
|
||||||
|
|
||||||
|
virtual QGCFlyViewOptions* flyViewOptions ();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void showSensorCalibrationCompassChanged (bool show);
|
||||||
|
void showSensorCalibrationGyroChanged (bool show);
|
||||||
|
void showSensorCalibrationAccelChanged (bool show);
|
||||||
|
void showSensorCalibrationLevelChanged (bool show);
|
||||||
|
void showSensorCalibrationAirspeedChanged (bool show);
|
||||||
|
void showFirmwareUpgradeChanged (bool show);
|
||||||
|
void missionWaypointsOnlyChanged (bool missionWaypointsOnly);
|
||||||
|
void multiVehicleEnabledChanged (bool multiVehicleEnabled);
|
||||||
|
void allowJoystickSelectionChanged (bool allow);
|
||||||
|
void showOfflineMapExportChanged ();
|
||||||
|
void showOfflineMapImportChanged ();
|
||||||
|
void showMissionAbsoluteAltitudeChanged ();
|
||||||
|
void showSimpleMissionStartChanged ();
|
||||||
|
void devicePixelRatioChanged ();
|
||||||
|
void devicePixelDensityChanged ();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QGCFlyViewOptions* _defaultFlyViewOptions = nullptr;
|
||||||
|
};
|
@ -0,0 +1,21 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "QGCSettings.h"
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief Core Plugin Interface for QGroundControl. Settings element.
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
QGCSettings::QGCSettings(QString title, QUrl url, QUrl icon)
|
||||||
|
: _title(title)
|
||||||
|
, _url(url)
|
||||||
|
, _icon(icon)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @brief Core Plugin Interface for QGroundControl. Settings element.
|
||||||
|
/// @author Gus Grubba <gus@auterion.com>
|
||||||
|
|
||||||
|
class QGCSettings : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QGCSettings(QString title, QUrl url, QUrl icon = QUrl());
|
||||||
|
|
||||||
|
Q_PROPERTY(QString title READ title CONSTANT)
|
||||||
|
Q_PROPERTY(QUrl url READ url CONSTANT)
|
||||||
|
Q_PROPERTY(QUrl icon READ icon CONSTANT)
|
||||||
|
|
||||||
|
virtual QString title () { return _title; }
|
||||||
|
virtual QUrl url () { return _url; }
|
||||||
|
virtual QUrl icon () { return _icon; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString _title;
|
||||||
|
QUrl _url;
|
||||||
|
QUrl _icon;
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "QmlComponentInfo.h"
|
||||||
|
|
||||||
|
QmlComponentInfo::QmlComponentInfo(QString title, QUrl url, QUrl icon, QObject* parent)
|
||||||
|
: QObject (parent)
|
||||||
|
, _title (title)
|
||||||
|
, _url (url)
|
||||||
|
, _icon (icon)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||||
|
*
|
||||||
|
* QGroundControl is licensed according to the terms in the file
|
||||||
|
* COPYING.md in the root of the source code directory.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
/// Represents a Qml component which can be loaded from a resource.
|
||||||
|
class QmlComponentInfo : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlComponentInfo(QString title, QUrl url, QUrl icon = QUrl(), QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Q_PROPERTY(QString title READ title CONSTANT) ///< Title for page
|
||||||
|
Q_PROPERTY(QUrl url READ url CONSTANT) ///< Qml source code
|
||||||
|
Q_PROPERTY(QUrl icon READ icon CONSTANT) ///< Icon for page
|
||||||
|
|
||||||
|
virtual QString title () { return _title; }
|
||||||
|
virtual QUrl url () { return _url; }
|
||||||
|
virtual QUrl icon () { return _icon; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString _title;
|
||||||
|
QUrl _url;
|
||||||
|
QUrl _icon;
|
||||||
|
};
|
Loading…
Reference in new issue