Commit 91673ba1 authored by Gus Grubba's avatar Gus Grubba

Merge branch 'cameraControl' into camControl

* cameraControl: (51 commits)
  Debug info
  Adding support for custom value.
  Parse min, max, step and unit off camera definition file Ignore Fact index if there are no enums (avoid adding an "Unknown" entry) Add function to convert and clamp a (Fact) value.
  Adding support for booleans Adding some more logging
  Keep asking for capture status while camera is not idle.
  Define how long to wait for RTSP frame before deciding the link is gone.
  Toggle video stream full screen
  Enable/Disable Offline maps import/export.
  Vehicle UID
  Handle capture status retries when capturing images. Allow plugin to validate parameter setting.
  Keep track of photo status (image capture) Don't allow "Take Photo" is status is not idle. Handle In Progress response (basically, do nothing) Request capture status when stopping video recording.
  For whatever reason, showing the dialog through a function causes a crash in QML (undebugable--new word!)
  Revert "Build fix due to MAVLink update."
  Revert "MAVLink signing (WIP)"
  Make custom dialog into a function Internet available now has a signal
  Wait a bit between reset and request parameters
  Build fix due to MAVLink update.
  MAVLink signing (WIP)
  Fixing uninitialized variable warning.
  Make slots protected instead of private.
  ...

# Conflicts:
#	src/FirmwarePlugin/FirmwarePlugin.cc
#	src/FlightDisplay/FlightDisplayView.qml
#	src/FlightDisplay/FlightDisplayViewVideo.qml
#	src/MissionManager/MissionManager.cc
#	src/Vehicle/Vehicle.cc
#	src/Vehicle/Vehicle.h
#	src/api/QGCCorePlugin.h
parents b93d3944 e2a03fe8
...@@ -92,46 +92,6 @@ MacBuild { ...@@ -92,46 +92,6 @@ MacBuild {
-lSDL2 -lSDL2
} }
##
# [OPTIONAL] Speech synthesis library support.
# Can be forcibly disabled by adding a `DEFINES+=DISABLE_SPEECH` argument to qmake.
# Linux support requires the eSpeak speech synthesizer (espeak).
# Mac support is provided in Snow Leopard and newer (10.6+)
# Windows is supported as of Windows 7
#
contains (DEFINES, DISABLE_SPEECH) {
message("Skipping support for speech output (manual override from command line)")
DEFINES -= DISABLE_SPEECH
# Otherwise the user can still disable this feature in the user_config.pri file.
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, DISABLE_SPEECH) {
message("Skipping support for speech output (manual override from user_config.pri)")
} else:LinuxBuild {
exists(/usr/include/espeak) | exists(/usr/local/include/espeak) {
message("Including support for speech output")
DEFINES += QGC_SPEECH_ENABLED
LIBS += \
-lespeak
} else {
warning("Skipping support for speech output (missing libraries, see README)")
}
}
# Mac support is built into OS 10.6+.
else:MacBuild|iOSBuild {
message("Including support for speech output")
DEFINES += QGC_SPEECH_ENABLED
}
# Windows supports speech through native API.
else:WindowsBuild {
message("Including support for speech output")
DEFINES += QGC_SPEECH_ENABLED
LIBS += -lOle32
}
# Android supports speech through native (Java) API.
else:AndroidBuild {
message("Including support for speech output")
DEFINES += QGC_SPEECH_ENABLED
}
# #
# [OPTIONAL] Zeroconf for UDP links # [OPTIONAL] Zeroconf for UDP links
# #
......
...@@ -45,15 +45,13 @@ import android.widget.Toast; ...@@ -45,15 +45,13 @@ import android.widget.Toast;
import android.util.Log; import android.util.Log;
import android.os.PowerManager; import android.os.PowerManager;
import android.view.WindowManager; import android.view.WindowManager;
//-- Text To Speech
import android.os.Bundle; import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import com.hoho.android.usbserial.driver.*; import com.hoho.android.usbserial.driver.*;
import org.qtproject.qt5.android.bindings.QtActivity; import org.qtproject.qt5.android.bindings.QtActivity;
import org.qtproject.qt5.android.bindings.QtApplication; import org.qtproject.qt5.android.bindings.QtApplication;
public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListener public class QGCActivity extends QtActivity
{ {
public static int BAD_PORT = 0; public static int BAD_PORT = 0;
private static QGCActivity m_instance; private static QGCActivity m_instance;
...@@ -66,7 +64,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen ...@@ -66,7 +64,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen
private BroadcastReceiver m_UsbReceiver = null; private BroadcastReceiver m_UsbReceiver = null;
private final static ExecutorService m_Executor = Executors.newSingleThreadExecutor(); private final static ExecutorService m_Executor = Executors.newSingleThreadExecutor();
private static final String TAG = "QGC_QGCActivity"; private static final String TAG = "QGC_QGCActivity";
private static TextToSpeech m_tts;
private static PowerManager.WakeLock m_wl; private static PowerManager.WakeLock m_wl;
public static Context m_context; public static Context m_context;
...@@ -111,17 +108,9 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen ...@@ -111,17 +108,9 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen
Log.i(TAG, "Instance created"); Log.i(TAG, "Instance created");
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Text To Speech
// Pigback a ride for providing TTS to QGC
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
m_tts = new TextToSpeech(this,this);
PowerManager pm = (PowerManager)m_instance.getSystemService(Context.POWER_SERVICE); PowerManager pm = (PowerManager)m_instance.getSystemService(Context.POWER_SERVICE);
m_wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "QGroundControl"); m_wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "QGroundControl");
if(m_wl != null) { if(m_wl != null) {
...@@ -140,7 +129,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen ...@@ -140,7 +129,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen
m_wl.release(); m_wl.release();
Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK released."); Log.i(TAG, "SCREEN_BRIGHT_WAKE_LOCK released.");
} }
m_tts.shutdown();
} catch(Exception e) { } catch(Exception e) {
Log.e(TAG, "Exception onDestroy()"); Log.e(TAG, "Exception onDestroy()");
} }
...@@ -150,12 +138,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen ...@@ -150,12 +138,6 @@ public class QGCActivity extends QtActivity implements TextToSpeech.OnInitListen
public void onInit(int status) { public void onInit(int status) {
} }
public static void say(String msg)
{
Log.i(TAG, "Say: " + msg);
m_tts.speak(msg, TextToSpeech.QUEUE_FLUSH, null);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Find all current devices that match the device filter described in the androidmanifest.xml and the // Find all current devices that match the device filter described in the androidmanifest.xml and the
......
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
<file alias="wifi.svg">src/AutoPilotPlugins/Common/Images/wifi.svg</file> <file alias="wifi.svg">src/AutoPilotPlugins/Common/Images/wifi.svg</file>
<file alias="arrow-down.png">src/QmlControls/arrow-down.png</file> <file alias="arrow-down.png">src/QmlControls/arrow-down.png</file>
<file alias="camera.svg">resources/camera.svg</file> <file alias="camera.svg">resources/camera.svg</file>
<file alias="camera_photo.svg">src/Camera/images/camera_photo.svg</file>
<file alias="camera_settings.svg">src/Camera/images/camera_settings.svg</file>
<file alias="camera_video.svg">src/Camera/images/camera_video.svg</file>
<file alias="check.png">src/QmlControls/check.png</file> <file alias="check.png">src/QmlControls/check.png</file>
<file alias="FirmwareUpgradeIcon.png">src/VehicleSetup/FirmwareUpgradeIcon.png</file> <file alias="FirmwareUpgradeIcon.png">src/VehicleSetup/FirmwareUpgradeIcon.png</file>
<file alias="FlightModesComponentIcon.png">src/AutoPilotPlugins/PX4/Images/FlightModesComponentIcon.png</file> <file alias="FlightModesComponentIcon.png">src/AutoPilotPlugins/PX4/Images/FlightModesComponentIcon.png</file>
......
...@@ -224,7 +224,8 @@ QT += \ ...@@ -224,7 +224,8 @@ QT += \
sql \ sql \
svg \ svg \
widgets \ widgets \
xml xml \
texttospeech
# Multimedia only used if QVC is enabled # Multimedia only used if QVC is enabled
!contains (DEFINES, QGC_DISABLE_UVC) { !contains (DEFINES, QGC_DISABLE_UVC) {
...@@ -333,6 +334,7 @@ INCLUDEPATH += \ ...@@ -333,6 +334,7 @@ INCLUDEPATH += \
src \ src \
src/api \ src/api \
src/AnalyzeView \ src/AnalyzeView \
src/Camera \
src/AutoPilotPlugins \ src/AutoPilotPlugins \
src/FlightDisplay \ src/FlightDisplay \
src/FlightMap \ src/FlightMap \
...@@ -485,6 +487,9 @@ HEADERS += \ ...@@ -485,6 +487,9 @@ HEADERS += \
src/AnalyzeView/ExifParser.h \ src/AnalyzeView/ExifParser.h \
src/AnalyzeView/ULogParser.h \ src/AnalyzeView/ULogParser.h \
src/AnalyzeView/PX4LogParser.h \ src/AnalyzeView/PX4LogParser.h \
src/Camera/QGCCameraControl.h \
src/Camera/QGCCameraIO.h \
src/Camera/QGCCameraManager.h \
src/CmdLineOptParser.h \ src/CmdLineOptParser.h \
src/FirmwarePlugin/PX4/px4_custom_mode.h \ src/FirmwarePlugin/PX4/px4_custom_mode.h \
src/FlightDisplay/VideoManager.h \ src/FlightDisplay/VideoManager.h \
...@@ -565,7 +570,6 @@ HEADERS += \ ...@@ -565,7 +570,6 @@ HEADERS += \
src/Terrain.h \ src/Terrain.h \
src/Vehicle/MAVLinkLogManager.h \ src/Vehicle/MAVLinkLogManager.h \
src/VehicleSetup/JoystickConfigController.h \ src/VehicleSetup/JoystickConfigController.h \
src/audio/QGCAudioWorker.h \
src/comm/LinkConfiguration.h \ src/comm/LinkConfiguration.h \
src/comm/LinkInterface.h \ src/comm/LinkInterface.h \
src/comm/LinkManager.h \ src/comm/LinkManager.h \
...@@ -660,7 +664,6 @@ HEADERS += \ ...@@ -660,7 +664,6 @@ HEADERS += \
iOSBuild { iOSBuild {
OBJECTIVE_SOURCES += \ OBJECTIVE_SOURCES += \
src/audio/QGCAudioWorker_iOS.mm \
src/MobileScreenMgr.mm \ src/MobileScreenMgr.mm \
} }
...@@ -673,6 +676,9 @@ SOURCES += \ ...@@ -673,6 +676,9 @@ SOURCES += \
src/AnalyzeView/ExifParser.cc \ src/AnalyzeView/ExifParser.cc \
src/AnalyzeView/ULogParser.cc \ src/AnalyzeView/ULogParser.cc \
src/AnalyzeView/PX4LogParser.cc \ src/AnalyzeView/PX4LogParser.cc \
src/Camera/QGCCameraControl.cc \
src/Camera/QGCCameraIO.cc \
src/Camera/QGCCameraManager.cc \
src/CmdLineOptParser.cc \ src/CmdLineOptParser.cc \
src/FlightDisplay/VideoManager.cc \ src/FlightDisplay/VideoManager.cc \
src/FlightMap/Widgets/ValuesWidgetController.cc \ src/FlightMap/Widgets/ValuesWidgetController.cc \
...@@ -748,7 +754,6 @@ SOURCES += \ ...@@ -748,7 +754,6 @@ SOURCES += \
src/Terrain.cc \ src/Terrain.cc \
src/Vehicle/MAVLinkLogManager.cc \ src/Vehicle/MAVLinkLogManager.cc \
src/VehicleSetup/JoystickConfigController.cc \ src/VehicleSetup/JoystickConfigController.cc \
src/audio/QGCAudioWorker.cpp \
src/comm/LinkConfiguration.cc \ src/comm/LinkConfiguration.cc \
src/comm/LinkInterface.cc \ src/comm/LinkInterface.cc \
src/comm/LinkManager.cc \ src/comm/LinkManager.cc \
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
<file alias="BluetoothSettings.qml">src/ui/preferences/BluetoothSettings.qml</file> <file alias="BluetoothSettings.qml">src/ui/preferences/BluetoothSettings.qml</file>
<file alias="CameraComponent.qml">src/AutoPilotPlugins/PX4/CameraComponent.qml</file> <file alias="CameraComponent.qml">src/AutoPilotPlugins/PX4/CameraComponent.qml</file>
<file alias="CameraComponentSummary.qml">src/AutoPilotPlugins/PX4/CameraComponentSummary.qml</file> <file alias="CameraComponentSummary.qml">src/AutoPilotPlugins/PX4/CameraComponentSummary.qml</file>
<file alias="CameraControl.qml">src/Camera/CameraControl.qml</file>
<file alias="CustomCommandWidget.qml">src/ViewWidgets/CustomCommandWidget.qml</file> <file alias="CustomCommandWidget.qml">src/ViewWidgets/CustomCommandWidget.qml</file>
<file alias="DebugWindow.qml">src/ui/preferences/DebugWindow.qml</file> <file alias="DebugWindow.qml">src/ui/preferences/DebugWindow.qml</file>
<file alias="ESP8266Component.qml">src/AutoPilotPlugins/Common/ESP8266Component.qml</file> <file alias="ESP8266Component.qml">src/AutoPilotPlugins/Common/ESP8266Component.qml</file>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*!
* @file
* @brief Camera Controller
* @author Gus Grubba <mavlink@grubba.com>
*
*/
#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;
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;
//-----------------------------------------------------------------------------
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 () { 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_TYPE _mavParamType;
MAVLinkProtocol* _pMavlink;
bool _forceUIUpdate;
};
/*!
* @file
* @brief Camera Controller
* @author Gus Grubba <mavlink@grubba.com>
*
*/
#include "QGCApplication.h"
#include "QGCCameraManager.h"
QGC_LOGGING_CATEGORY(CameraManagerLog, "CameraManagerLog")
//-----------------------------------------------------------------------------
QGCCameraManager::QGCCameraManager(Vehicle *vehicle)
: _vehicle(vehicle)
, _vehicleReadyState(false)
, _currentTask(0)
{
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);
}
//-----------------------------------------------------------------------------
QGCCameraManager::~QGCCameraManager()
{
}
//-----------------------------------------------------------------------------
QString
QGCCameraManager::controllerSource()
{
return QStringLiteral("/qml/CameraControl.qml");
}
//-----------------------------------------------------------------------------
void
QGCCameraManager::_vehicleReady(bool ready)
{
qCDebug(CameraManagerLog) << "_vehicleReady(" << ready << ")";
if(ready) {
if(qgcApp()->toolbox()->multiVehicleManager()->activeVehicle() == _vehicle) {
_vehicleReadyState = true;
}
}
}
//-----------------------------------------------------------------------------
void
QGCCameraManager::_mavlinkMessageReceived(const mavlink_message_t& message)
{
if(message.sysid == _vehicle->id()) {
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;
}
}
}
//-----------------------------------------------------------------------------
void
QGCCameraManager::_handleHeartbeat(const mavlink_message_t &message)
{
mavlink_heartbeat_t heartbeat;
mavlink_msg_heartbeat_decode(&message, &heartbeat);
//-- If this heartbeat is from a different node within the vehicle
if(_vehicleReadyState && _vehicle->id() == message.sysid && _vehicle->defaultComponentId() != message.compid) {
if(!_cameraInfoRequested[message.compid]) {
_cameraInfoRequested[message.compid] = true;
//-- Request camera info
_requestCameraInfo(message.compid);
}
}
}
//-----------------------------------------------------------------------------
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 NULL;
}
//-----------------------------------------------------------------------------
void
QGCCameraManager::_handleCameraInfo(const mavlink_message_t& message)
{
mavlink_camera_information_t info;
mavlink_msg_camera_information_decode(&message, &info);
qCDebug(CameraManagerLog) << "_handleCameraInfo:" << (const char*)(void*)&info.model_name[0] << (const char*)(void*)&info.vendor_name[0];
QGCCameraControl* pCamera = _vehicle->firmwarePlugin()->createCameraControl(&info, _vehicle, message.compid, this);
if(pCamera) {
QQmlEngine::setObjectOwnership(pCamera, QQmlEngine::CppOwnership);
_cameras.append(pCamera);
emit camerasChanged();
}
}
//-----------------------------------------------------------------------------
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::_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
}
}
/*!
* @file
* @brief Camera Controller
* @author Gus Grubba <mavlink@grubba.com>
*
*/
#pragma once
#include "QGCApplication.h"
#include <QLoggingCategory>
#include "QmlObjectListModel.h"
#include "QGCCameraControl.h"
#include <QObject>
#include <QTimer>
Q_DECLARE_LOGGING_CATEGORY(CameraManagerLog)
//-----------------------------------------------------------------------------
class QGCCameraManager : public QObject
{
Q_OBJECT
public:
QGCCameraManager(Vehicle* vehicle);
virtual ~QGCCameraManager();
Q_PROPERTY(QmlObjectListModel* cameras READ cameras NOTIFY camerasChanged)
Q_PROPERTY(QString controllerSource READ controllerSource NOTIFY controllerSourceChanged)
//-- Return a list of cameras provided by this vehicle
virtual QmlObjectListModel* cameras () { return &_cameras; }
//-- Camera controller source (QML)
virtual QString controllerSource ();
signals:
void camerasChanged ();
void controllerSourceChanged ();
protected slots:
void _vehicleReady (bool ready);
void _mavlinkMessageReceived (const mavlink_message_t& message);
protected:
QGCCameraControl* _findCamera (int id);
void _requestCameraInfo (int compID);
void _handleHeartbeat (const mavlink_message_t& message);
void _handleCameraInfo (const mavlink_message_t& message);
void _handleStorageInfo (const mavlink_message_t& message);
void _handleCameraSettings (const mavlink_message_t& message);
void _handleParamAck (const mavlink_message_t& message);
void _handleParamValue (const mavlink_message_t& message);
void _handleCaptureStatus (const mavlink_message_t& message);
protected:
Vehicle* _vehicle;
bool _vehicleReadyState;
int _currentTask;
QmlObjectListModel _cameras;
QMap<int, bool> _cameraInfoRequested;
};
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="72px" height="72px" viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M63.4,16H51.6l-4.6-6c-0.3-0.3-0.7-0.5-1.1-0.5H26.7c-0.4,0-0.8,0.2-1.1,0.6L21.3,16H8.6c-2.8,0-5,2.2-5,5
v36.5c0,2.8,2.2,5,5,5h54.9c2.8,0,5-2.2,5-5V21C68.4,18.3,66.2,16,63.4,16L63.4,16L63.4,16z M36.7,54.8c-8.4,0-15.3-6.9-15.3-15.3
s6.9-15.3,15.3-15.3S52,31,52,39.5S45.1,54.8,36.7,54.8L36.7,54.8L36.7,54.8z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="72px" height="72px" viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{display:none;}
.st1{display:inline;}
.st2{display:inline;stroke:#FFFFFF;stroke-width:1.1959;stroke-miterlimit:10;}
.st3{display:inline;fill:none;stroke:#FFFFFF;stroke-width:9.567;stroke-miterlimit:10;}
.st4{display:inline;stroke:#FFFFFF;stroke-width:0.9229;stroke-miterlimit:10;}
.st5{display:inline;fill:none;stroke:#FFFFFF;stroke-width:9.2289;stroke-miterlimit:10;}
.st6{display:inline;stroke:#FFFFFF;stroke-width:1.3383;stroke-miterlimit:10;}
.st7{display:inline;fill:#FFFFFF;}
.st8{display:inline;opacity:0.7;stroke:#FFFFFF;stroke-width:1.494;stroke-miterlimit:10;enable-background:new ;}
.st9{display:inline;opacity:0.7;stroke:#FFFFFF;stroke-width:0.9492;stroke-miterlimit:10;enable-background:new ;}
.st10{display:inline;fill:none;stroke:#000000;stroke-width:23.0795;stroke-miterlimit:10;}
.st11{enable-background:new ;}
.st12{fill:none;stroke:#000000;stroke-miterlimit:10;}
.st13{display:inline;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
.st14{display:inline;stroke:#000000;stroke-width:19.9759;stroke-miterlimit:10;}
.st15{display:inline;stroke:#000000;stroke-width:20.4762;stroke-miterlimit:10;}
.st16{display:inline;stroke:#000000;stroke-miterlimit:10;}
.st17{fill:#FFFFFF;}
</style>
<g id="Media_play_icon" class="st0">
<polygon class="st1" points="275.5,-149.9 24.1,-4.8 24.1,-295 "/>
</g>
<g id="Document_icon" class="st0">
<rect x="39.8" y="-291.1" class="st2" width="219.9" height="282.3"/>
<line class="st3" x1="80.1" y1="-249.2" x2="220" y2="-249.2"/>
<line class="st3" x1="80.1" y1="-223.2" x2="183.3" y2="-223.2"/>
<line class="st3" x1="80.1" y1="-197.2" x2="196.8" y2="-197.2"/>
<line class="st3" x1="80.1" y1="-171.1" x2="220" y2="-171.1"/>
<line class="st3" x1="80.1" y1="-145.1" x2="138.4" y2="-145.1"/>
<line class="st3" x1="80.1" y1="-119" x2="183.3" y2="-119"/>
<line class="st3" x1="80.1" y1="-93" x2="196.8" y2="-93"/>
</g>
<g id="Contact_icon" class="st0">
<rect x="7.1" y="-258.8" class="st4" width="285.8" height="217.9"/>
<polyline class="st5" points="281.7,-248.9 150,-146.2 19,-248.9 "/>
</g>
<g id="Image_icon" class="st0">
<rect x="12.4" y="-291.4" class="st6" width="274.7" height="283"/>
<rect x="39" y="-262.5" class="st7" width="220.5" height="220.5"/>
<polygon class="st8" points="185.9,-55.5 48.5,-55.7 117.4,-174.6 "/>
<polygon class="st9" points="238.6,-56.1 151.3,-56.2 195,-131.8 "/>
<circle class="st9" cx="182.9" cy="-198.5" r="23.9"/>
</g>
<g id="Map_icon" class="st0">
<circle class="st1" cx="149.8" cy="-196.1" r="99.2"/>
<polygon class="st1" points="149.8,-4 77.3,-129.6 222.3,-129.6 "/>
<circle class="st7" cx="149.8" cy="-197" r="34.3"/>
</g>
<g id="Calendar_icon" class="st0">
<rect x="29.3" y="-268.8" class="st10" width="241.3" height="248.6"/>
<text transform="matrix(1 0 0 1 50.4731 -72.7944)" class="st1" style="font-family:'Futura-Medium'; font-size:172.5264px;">31</text>
<text transform="matrix(1 0 0 1 50.4731 -72.7944)" style="display:inline;fill:none;stroke:#000000;stroke-miterlimit:10; font-family:'Futura-Medium'; font-size:172.5264px;">31</text>
<polyline class="st1" points="192.1,-38.2 250.8,-38.2 250.8,-96.9 "/>
<rect x="18" y="-291" class="st1" width="263.7" height="66.4"/>
<circle class="st13" cx="98.4" cy="-256" r="11.9"/>
<circle class="st13" cx="199.1" cy="-257.8" r="11.9"/>
</g>
<g id="Company_icon" class="st0">
<circle class="st14" cx="149.8" cy="-221.3" r="51.5"/>
<path class="st15" d="M59.4-13.1c0-81.1,40.5-146.9,90.4-146.9s90.4,65.8,90.4,146.9"/>
<polygon class="st16" points="88.7,-12.9 102.3,-12.8 95.9,-69.5 "/>
<polygon class="st16" points="201.6,-12.8 215.2,-12.7 208.7,-69.3 "/>
</g>
<g id="Layer_8">
<g id="BOOUm1.tif">
<g>
<path class="st17" d="M27,18.4c1.5,0,3,0,4.5,0c1,0.8,1.5,1.9,1.7,3.2c0.2,1.2,0.9,1.9,2,2.4c0.8,0.3,1.6,0.6,2.3,1
c1.8,1.1,3.5,0.6,5.2-0.4c1.7-1,2.2-1,3.6,0.4c0.4,0.4,0.7,0.7,1.1,1.1c1.5,1.5,1.6,2.5,0.4,4.3c-0.5,0.7-1,1.4-0.8,2.2
c0.5,1.9,1.1,3.8,2.2,5.4c0.8,1.1,2.2,1.3,3.5,1.6c1.4,0.3,1.8,1.4,1.7,2.6c-0.1,1.7,0.7,3.8-1.3,5c-0.3,0.2-0.7,0.2-1.1,0.3
c-1,0.3-2,0.6-2.8,1.3c-2,2.1-2.4,5.8-0.8,8.3c0.7,1.1,0.6,2-0.2,2.9c-0.4,0.5-0.8,0.9-1.3,1.3c-1.7,1.7-2.6,1.8-4.6,0.5
c-1.2-0.8-2.3-0.9-3.6-0.3c-0.6,0.3-1.2,0.6-1.8,0.7c-2.3,0.6-3.4,2.1-3.7,4.3c-0.2,1.3-1,1.9-2.3,2c-0.6,0-1.1,0-1.7,0
c-2.5,0-3.3-0.6-3.7-3c-0.1-0.7-0.3-1.3-0.9-1.7c-1.6-1.2-3.6-1.9-5.5-2.4c-1.3-0.3-2.4,0.6-3.5,1.3c-1,0.7-1.9,0.5-2.8-0.2
c-0.5-0.4-0.9-0.8-1.3-1.3c-1.8-1.8-1.9-2.6-0.5-4.7c0.7-1.1,0.8-2.2,0.4-3.3c-0.3-0.7-0.6-1.4-0.8-2.1c-0.6-2.3-2.2-3.3-4.3-3.7
c-0.6-0.1-1.2-0.3-1.5-0.9c-1.5-2.4-0.2-6.1,2.6-6.8c1.3-0.3,2.2-1,2.6-2.3c0.2-0.6,0.4-1.3,0.8-1.8c1.2-2,0.9-3.9-0.5-5.8
c-0.8-1.1-0.6-2,0.2-2.9c0.4-0.5,0.8-0.9,1.3-1.3c1.7-1.6,2.6-1.8,4.6-0.5c1.1,0.8,2.2,0.9,3.4,0.4c0.7-0.3,1.4-0.7,2.1-0.8
c2.2-0.5,3.2-2.1,3.6-4.2C25.6,19.4,26.1,18.8,27,18.4z M29.3,52.2c5,0,8.9-3.9,8.9-8.9c0-4.8-4.1-8.8-8.9-8.8
c-4.8,0-8.7,4-8.7,8.8C20.6,48.3,24.4,52.2,29.3,52.2z"/>
</g>
</g>
<g id="BOOUm1.tif_1_">
<g>
<path class="st17" d="M51.6,4.3c0.7-0.2,1.3-0.5,2-0.7c0.6,0.2,1,0.6,1.2,1.1c0.3,0.5,0.7,0.7,1.2,0.7c0.4,0,0.8,0,1.2,0
c1,0.2,1.6-0.3,2.2-1C60,3.7,60.2,3.7,61,4c0.2,0.1,0.4,0.2,0.7,0.3c0.9,0.4,1.1,0.8,0.9,1.8c-0.1,0.4-0.2,0.8,0,1.1
c0.5,0.8,1.1,1.5,1.9,2c0.5,0.4,1.2,0.2,1.8,0.1c0.6-0.1,1,0.3,1.2,0.8c0.2,0.8,0.9,1.5,0.2,2.4c-0.1,0.1-0.3,0.2-0.4,0.3
c-0.4,0.3-0.8,0.6-1,1c-0.5,1.2-0.1,2.9,1,3.7c0.5,0.4,0.6,0.8,0.4,1.3c-0.1,0.3-0.2,0.5-0.3,0.8c-0.5,1-0.8,1.2-1.9,1
c-0.6-0.1-1.2,0-1.6,0.4c-0.2,0.2-0.4,0.4-0.7,0.6c-0.9,0.6-1.1,1.4-0.9,2.5c0.1,0.6-0.1,1-0.7,1.2c-0.2,0.1-0.5,0.2-0.7,0.3
c-1.1,0.4-1.5,0.3-2.1-0.7c-0.2-0.3-0.4-0.5-0.7-0.6c-0.9-0.3-1.9-0.3-2.8-0.1c-0.6,0.1-1,0.6-1.3,1.1c-0.3,0.5-0.8,0.5-1.3,0.4
c-0.3-0.1-0.5-0.2-0.8-0.3c-1.1-0.5-1.2-0.8-1-1.9c0.1-0.6,0-1.1-0.4-1.5c-0.2-0.3-0.5-0.5-0.7-0.8c-0.6-0.9-1.5-1.1-2.5-0.9
c-0.3,0.1-0.6,0.1-0.8-0.1c-1.1-0.8-1.1-2.6,0-3.4c0.5-0.3,0.8-0.8,0.8-1.4c0-0.3,0-0.6,0-0.9c0.2-1.1-0.3-1.9-1.1-2.4
c-0.5-0.3-0.6-0.8-0.4-1.3c0.1-0.3,0.2-0.5,0.3-0.8C46.6,9,47,8.7,48.1,9c0.6,0.1,1.1,0,1.6-0.4c0.2-0.2,0.5-0.5,0.8-0.7
c0.9-0.6,1.1-1.5,0.8-2.4C51.2,5,51.3,4.7,51.6,4.3z M58.1,18.6c2.1-0.8,3.2-3.2,2.4-5.3c-0.8-2.1-3.2-3.1-5.3-2.3
c-2.1,0.8-3.1,3.1-2.3,5.3C53.7,18.4,56,19.4,58.1,18.6z"/>
</g>
</g>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="72px" height="72px" viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M44,17.1c-5.8,0-11.7,0-17.5,0c-5.8,0-11.6,0-17.4,0c-0.4,0-0.8,0-1.2,0.1c-2.4,0.4-4.2,2.5-4.2,4.9
c0,9.3,0,18.6,0,27.8c0,0.8,0.2,1.6,0.6,2.3C5.3,54,6.9,54.9,9,54.9c11.7,0,23.3,0,35,0c3,0,5.5-2.5,5.5-5.5c0-8.9,0-17.8,0-26.8
C49.5,19.6,47,17.1,44,17.1z"/>
<path class="st0" d="M68.1,22.5c-0.7,0-1.4,0-2.1,0c-0.2,0-0.4,0.1-0.5,0.1c-4.4,2.6-8.7,5.2-13.1,7.8c-0.2,0.1-0.2,0.2-0.2,0.4
c0,3.4,0,6.8,0,10.3c0,0.2,0.1,0.3,0.2,0.4c4.2,2.5,8.5,5.1,12.7,7.6c0.4,0.2,0.8,0.4,1.3,0.4c0.7,0,1.3,0,2,0c0-9,0-18,0-27
C68.3,22.5,68.2,22.5,68.1,22.5z"/>
</g>
</svg>
This diff is collapsed.
...@@ -41,9 +41,9 @@ public: ...@@ -41,9 +41,9 @@ public:
Q_PROPERTY(QString defaultValueString READ cookedDefaultValueString CONSTANT) Q_PROPERTY(QString defaultValueString READ cookedDefaultValueString CONSTANT)
Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT) Q_PROPERTY(bool defaultValueAvailable READ defaultValueAvailable CONSTANT)
Q_PROPERTY(int enumIndex READ enumIndex WRITE setEnumIndex NOTIFY valueChanged) Q_PROPERTY(int enumIndex READ enumIndex WRITE setEnumIndex NOTIFY valueChanged)
Q_PROPERTY(QStringList enumStrings READ enumStrings NOTIFY enumStringsChanged) Q_PROPERTY(QStringList enumStrings READ enumStrings NOTIFY enumsChanged)
Q_PROPERTY(QString enumStringValue READ enumStringValue WRITE setEnumStringValue NOTIFY valueChanged) Q_PROPERTY(QString enumStringValue READ enumStringValue WRITE setEnumStringValue NOTIFY valueChanged)
Q_PROPERTY(QVariantList enumValues READ enumValues NOTIFY enumValuesChanged) Q_PROPERTY(QVariantList enumValues READ enumValues NOTIFY enumsChanged)
Q_PROPERTY(QString group READ group CONSTANT) Q_PROPERTY(QString group READ group CONSTANT)
Q_PROPERTY(QString longDescription READ longDescription CONSTANT) Q_PROPERTY(QString longDescription READ longDescription CONSTANT)
Q_PROPERTY(QVariant max READ cookedMax CONSTANT) Q_PROPERTY(QVariant max READ cookedMax CONSTANT)
...@@ -64,10 +64,14 @@ public: ...@@ -64,10 +64,14 @@ public:
Q_PROPERTY(double increment READ increment CONSTANT) Q_PROPERTY(double increment READ increment CONSTANT)
Q_PROPERTY(bool typeIsString READ typeIsString CONSTANT) Q_PROPERTY(bool typeIsString READ typeIsString CONSTANT)
Q_PROPERTY(bool typeIsBool READ typeIsBool CONSTANT) Q_PROPERTY(bool typeIsBool READ typeIsBool CONSTANT)
Q_PROPERTY(bool hasControl READ hasControl CONSTANT)
Q_PROPERTY(bool readOnly READ readOnly CONSTANT)
/// Convert and validate value /// Convert and validate value
/// @param convertOnly true: validate type conversion only, false: validate against meta data as well /// @param convertOnly true: validate type conversion only, false: validate against meta data as well
Q_INVOKABLE QString validate(const QString& cookedValue, bool convertOnly); Q_INVOKABLE QString validate(const QString& cookedValue, bool convertOnly);
/// Convert and clamp value
Q_INVOKABLE QVariant clamp(const QString& cookedValue);
QVariant cookedValue (void) const; /// Value after translation QVariant cookedValue (void) const; /// Value after translation
QVariant rawValue (void) const { return _rawValue; } /// value prior to translation, careful QVariant rawValue (void) const { return _rawValue; } /// value prior to translation, careful
...@@ -106,6 +110,8 @@ public: ...@@ -106,6 +110,8 @@ public:
double increment (void) const; double increment (void) const;
bool typeIsString (void) const { return type() == FactMetaData::valueTypeString; } bool typeIsString (void) const { return type() == FactMetaData::valueTypeString; }
bool typeIsBool (void) const { return type() == FactMetaData::valueTypeBool; } bool typeIsBool (void) const { return type() == FactMetaData::valueTypeBool; }
bool hasControl (void) const;
bool readOnly (void) const;
/// Returns the values as a string with full 18 digit precision if float/double. /// Returns the values as a string with full 18 digit precision if float/double.
QString rawValueStringFullPrecision(void) const; QString rawValueStringFullPrecision(void) const;
...@@ -132,17 +138,21 @@ public: ...@@ -132,17 +138,21 @@ public:
/// Sets the meta data associated with the Fact. /// Sets the meta data associated with the Fact.
void setMetaData(FactMetaData* metaData); void setMetaData(FactMetaData* metaData);
FactMetaData* metaData() { return _metaData; }
//-- Value coming from Vehicle. This does NOT send a _containerRawValueChanged signal.
void _containerSetRawValue(const QVariant& value); void _containerSetRawValue(const QVariant& value);
/// Generally you should not change the name of a fact. But if you know what you are doing, you can. /// Generally you should not change the name of a fact. But if you know what you are doing, you can.
void _setName(const QString& name) { _name = name; } void _setName(const QString& name) { _name = name; }
/// Generally this is done during parsing. But if you know what you are doing, you can.
void setEnumInfo(const QStringList& strings, const QVariantList& values);
signals: signals:
void bitmaskStringsChanged(void); void bitmaskStringsChanged(void);
void bitmaskValuesChanged(void); void bitmaskValuesChanged(void);
void enumStringsChanged(void); void enumsChanged(void);
void enumValuesChanged(void);
void sendValueChangedSignalsChanged(bool sendValueChangedSignals); void sendValueChangedSignalsChanged(bool sendValueChangedSignals);
/// QObject Property System signal for value property changes /// QObject Property System signal for value property changes
...@@ -156,7 +166,7 @@ signals: ...@@ -156,7 +166,7 @@ signals:
/// Signalled when property has been changed by a call to the property write accessor /// Signalled when property has been changed by a call to the property write accessor
/// ///
/// This signal is meant for use by Fact container implementations. /// This signal is meant for use by Fact container implementations. Used to send changed values to vehicle.
void _containerRawValueChanged(const QVariant& value); void _containerRawValueChanged(const QVariant& value);
protected: protected:
......
...@@ -23,14 +23,30 @@ QGC_LOGGING_CATEGORY(FactGroupLog, "FactGroupLog") ...@@ -23,14 +23,30 @@ QGC_LOGGING_CATEGORY(FactGroupLog, "FactGroupLog")
FactGroup::FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent) FactGroup::FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent)
: QObject(parent) : QObject(parent)
, _updateRateMSecs(updateRateMsecs) , _updateRateMSecs(updateRateMsecs)
{
_setupTimer();
_nameToFactMetaDataMap = FactMetaData::createMapFromJsonFile(metaDataFile, this);
}
FactGroup::FactGroup(int updateRateMsecs, QObject* parent)
: QObject(parent)
, _updateRateMSecs(updateRateMsecs)
{
_setupTimer();
}
void FactGroup::_loadFromJsonArray(const QJsonArray jsonArray)
{
_nameToFactMetaDataMap = FactMetaData::createMapFromJsonArray(jsonArray, this);
}
void FactGroup::_setupTimer()
{ {
if (_updateRateMSecs > 0) { if (_updateRateMSecs > 0) {
connect(&_updateTimer, &QTimer::timeout, this, &FactGroup::_updateAllValues); connect(&_updateTimer, &QTimer::timeout, this, &FactGroup::_updateAllValues);
_updateTimer.setSingleShot(false); _updateTimer.setSingleShot(false);
_updateTimer.start(_updateRateMSecs); _updateTimer.start(_updateRateMSecs);
} }
_loadMetaData(metaDataFile);
} }
Fact* FactGroup::getFact(const QString& name) Fact* FactGroup::getFact(const QString& name)
...@@ -107,8 +123,3 @@ void FactGroup::_updateAllValues(void) ...@@ -107,8 +123,3 @@ void FactGroup::_updateAllValues(void)
fact->sendDeferredValueChangedSignal(); fact->sendDeferredValueChangedSignal();
} }
} }
void FactGroup::_loadMetaData(const QString& jsonFilename)
{
_nameToFactMetaDataMap = FactMetaData::createMapFromJsonFile(jsonFilename, this);
}
...@@ -27,6 +27,7 @@ class FactGroup : public QObject ...@@ -27,6 +27,7 @@ class FactGroup : public QObject
public: public:
FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent = NULL); FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent = NULL);
FactGroup(int updateRateMsecs, QObject* parent = NULL);
Q_PROPERTY(QStringList factNames READ factNames CONSTANT) Q_PROPERTY(QStringList factNames READ factNames CONSTANT)
Q_PROPERTY(QStringList factGroupNames READ factGroupNames CONSTANT) Q_PROPERTY(QStringList factGroupNames READ factGroupNames CONSTANT)
...@@ -39,10 +40,11 @@ public: ...@@ -39,10 +40,11 @@ public:
QStringList factNames(void) const { return _nameToFactMap.keys(); } QStringList factNames(void) const { return _nameToFactMap.keys(); }
QStringList factGroupNames(void) const { return _nameToFactGroupMap.keys(); } QStringList factGroupNames(void) const { return _nameToFactGroupMap.keys(); }
protected: protected:
void _addFact(Fact* fact, const QString& name); void _addFact(Fact* fact, const QString& name);
void _addFactGroup(FactGroup* factGroup, const QString& name); void _addFactGroup(FactGroup* factGroup, const QString& name);
void _loadFromJsonArray(const QJsonArray jsonArray);
int _updateRateMSecs; ///< Update rate for Fact::valueChanged signals, 0: immediate update int _updateRateMSecs; ///< Update rate for Fact::valueChanged signals, 0: immediate update
...@@ -50,13 +52,14 @@ private slots: ...@@ -50,13 +52,14 @@ private slots:
void _updateAllValues(void); void _updateAllValues(void);
private: private:
void _loadMetaData(const QString& filename); void _setupTimer();
QTimer _updateTimer;
protected:
QMap<QString, Fact*> _nameToFactMap; QMap<QString, Fact*> _nameToFactMap;
QMap<QString, FactGroup*> _nameToFactGroupMap; QMap<QString, FactGroup*> _nameToFactGroupMap;
QMap<QString, FactMetaData*> _nameToFactMetaDataMap; QMap<QString, FactMetaData*> _nameToFactMetaDataMap;
QTimer _updateTimer;
}; };
#endif #endif
This diff is collapsed.
...@@ -41,15 +41,18 @@ public: ...@@ -41,15 +41,18 @@ public:
valueTypeString, valueTypeString,
valueTypeBool, valueTypeBool,
valueTypeElapsedTimeInSeconds, // Internally stored as double, valueString displays as HH:MM:SS valueTypeElapsedTimeInSeconds, // Internally stored as double, valueString displays as HH:MM:SS
valueTypeCustom, // Internally stored as a QByteArray
} ValueType_t; } ValueType_t;
typedef QVariant (*Translator)(const QVariant& from); typedef QVariant (*Translator)(const QVariant& from);
FactMetaData(QObject* parent = NULL); FactMetaData(QObject* parent = NULL);
FactMetaData(ValueType_t type, QObject* parent = NULL); FactMetaData(ValueType_t type, QObject* parent = NULL);
FactMetaData(ValueType_t type, const QString name, QObject* parent = NULL);
FactMetaData(const FactMetaData& other, QObject* parent = NULL); FactMetaData(const FactMetaData& other, QObject* parent = NULL);
static QMap<QString, FactMetaData*> createMapFromJsonFile(const QString& jsonFilename, QObject* metaDataParent); static QMap<QString, FactMetaData*> createMapFromJsonFile(const QString& jsonFilename, QObject* metaDataParent);
static QMap<QString, FactMetaData*> createMapFromJsonArray(const QJsonArray jsonArray, QObject* metaDataParent);
static FactMetaData* createFromJsonObject(const QJsonObject& json, QObject* metaDataParent); static FactMetaData* createFromJsonObject(const QJsonObject& json, QObject* metaDataParent);
...@@ -95,6 +98,8 @@ public: ...@@ -95,6 +98,8 @@ public:
QString rawUnits (void) const { return _rawUnits; } QString rawUnits (void) const { return _rawUnits; }
QString cookedUnits (void) const { return _cookedUnits; } QString cookedUnits (void) const { return _cookedUnits; }
bool rebootRequired (void) const { return _rebootRequired; } bool rebootRequired (void) const { return _rebootRequired; }
bool hasControl (void) const { return _hasControl; }
bool readOnly (void) const { return _readOnly; }
/// Amount to increment value when used in controls such as spin button or slider with detents. /// Amount to increment value when used in controls such as spin button or slider with detents.
/// NaN for no increment available. /// NaN for no increment available.
...@@ -122,6 +127,8 @@ public: ...@@ -122,6 +127,8 @@ public:
void setRawUnits (const QString& rawUnits); void setRawUnits (const QString& rawUnits);
void setRebootRequired (bool rebootRequired) { _rebootRequired = rebootRequired; } void setRebootRequired (bool rebootRequired) { _rebootRequired = rebootRequired; }
void setIncrement (double increment) { _increment = increment; } void setIncrement (double increment) { _increment = increment; }
void setHasControl (bool bValue) { _hasControl = bValue; }
void setReadOnly (bool bValue) { _readOnly = bValue; }
void setTranslators(Translator rawTranslator, Translator cookedTranslator); void setTranslators(Translator rawTranslator, Translator cookedTranslator);
...@@ -139,6 +146,12 @@ public: ...@@ -139,6 +146,12 @@ public:
/// Same as convertAndValidateRaw except for cookedValue input /// Same as convertAndValidateRaw except for cookedValue input
bool convertAndValidateCooked(const QVariant& cookedValue, bool convertOnly, QVariant& typedValue, QString& errorString); bool convertAndValidateCooked(const QVariant& cookedValue, bool convertOnly, QVariant& typedValue, QString& errorString);
/// Converts the specified cooked value and clamps it (max/min)
/// @param cookedValue Value to convert, can be string
/// @param typeValue Converted value, correctly typed and clamped
/// @returns false: Convertion failed
bool clampValue(const QVariant& cookedValue, QVariant& typedValue);
static const int defaultDecimalPlaces = 3; ///< Default value for decimal places if not specified/known static const int defaultDecimalPlaces = 3; ///< Default value for decimal places if not specified/known
static const int unknownDecimalPlaces = -1; ///< Number of decimal places to specify is not known static const int unknownDecimalPlaces = -1; ///< Number of decimal places to specify is not known
...@@ -216,6 +229,8 @@ private: ...@@ -216,6 +229,8 @@ private:
Translator _cookedTranslator; Translator _cookedTranslator;
bool _rebootRequired; bool _rebootRequired;
double _increment; double _increment;
bool _hasControl;
bool _readOnly;
// Exact conversion constants // Exact conversion constants
static const struct UnitConsts_s { static const struct UnitConsts_s {
...@@ -247,6 +262,7 @@ private: ...@@ -247,6 +262,7 @@ private:
static const char* _defaultValueJsonKey; static const char* _defaultValueJsonKey;
static const char* _minJsonKey; static const char* _minJsonKey;
static const char* _maxJsonKey; static const char* _maxJsonKey;
static const char* _hasControlJsonKey;
}; };
#endif #endif
...@@ -393,6 +393,7 @@ const QVariantList& FirmwarePlugin::cameraList(const Vehicle* vehicle) ...@@ -393,6 +393,7 @@ const QVariantList& FirmwarePlugin::cameraList(const Vehicle* vehicle)
false, false,
0, 0,
this); this);
_cameraList.append(QVariant::fromValue(metaData));
metaData = new CameraMetaData(tr("Canon EOS-M 22mm"), metaData = new CameraMetaData(tr("Canon EOS-M 22mm"),
22.3, 22.3,
...@@ -541,3 +542,20 @@ bool FirmwarePlugin::isVtol(const Vehicle* vehicle) const ...@@ -541,3 +542,20 @@ bool FirmwarePlugin::isVtol(const Vehicle* vehicle) const
return false; return false;
} }
} }
QGCCameraManager* FirmwarePlugin::createCameraManager(Vehicle* vehicle)
{
Q_UNUSED(vehicle);
return NULL;
}
QGCCameraControl* FirmwarePlugin::createCameraControl(const mavlink_camera_information_t *info, Vehicle *vehicle, int compID, QObject* parent)
{
Q_UNUSED(info);
Q_UNUSED(vehicle);
Q_UNUSED(compID);
Q_UNUSED(parent);
return NULL;
}
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <QVariantList> #include <QVariantList>
class Vehicle; class Vehicle;
class QGCCameraControl;
class QGCCameraManager;
/// This is the base class for Firmware specific plugins /// This is the base class for Firmware specific plugins
/// ///
...@@ -259,8 +261,15 @@ public: ...@@ -259,8 +261,15 @@ public:
virtual const QVariantList& toolBarIndicators(const Vehicle* vehicle); virtual const QVariantList& toolBarIndicators(const Vehicle* vehicle);
/// Returns a list of CameraMetaData objects for available cameras on the vehicle. /// Returns a list of CameraMetaData objects for available cameras on the vehicle.
/// TODO: This should go into QGCCameraManager
virtual const QVariantList& cameraList(const Vehicle* vehicle); virtual const QVariantList& cameraList(const Vehicle* vehicle);
/// Creates vehicle camera manager. Returns NULL if not supported.
virtual QGCCameraManager* createCameraManager(Vehicle *vehicle);
/// Camera control. Returns NULL if not supported.
virtual QGCCameraControl* createCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = NULL);
/// Returns a pointer to a dictionary of firmware-specific FactGroups /// Returns a pointer to a dictionary of firmware-specific FactGroups
virtual QMap<QString, FactGroup*>* factGroups(void); virtual QMap<QString, FactGroup*>* factGroups(void);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "SensorsComponentController.h" #include "SensorsComponentController.h"
#include "PowerComponentController.h" #include "PowerComponentController.h"
#include "RadioComponentController.h" #include "RadioComponentController.h"
#include "QGCCameraManager.h"
#include <QDebug> #include <QDebug>
...@@ -125,6 +126,10 @@ PX4FirmwarePlugin::PX4FirmwarePlugin(void) ...@@ -125,6 +126,10 @@ PX4FirmwarePlugin::PX4FirmwarePlugin(void)
} }
} }
PX4FirmwarePlugin::~PX4FirmwarePlugin()
{
}
AutoPilotPlugin* PX4FirmwarePlugin::autopilotPlugin(Vehicle* vehicle) AutoPilotPlugin* PX4FirmwarePlugin::autopilotPlugin(Vehicle* vehicle)
{ {
return new PX4AutoPilotPlugin(vehicle, vehicle); return new PX4AutoPilotPlugin(vehicle, vehicle);
...@@ -546,3 +551,15 @@ bool PX4FirmwarePlugin::vehicleYawsToNextWaypointInMission(const Vehicle* vehicl ...@@ -546,3 +551,15 @@ bool PX4FirmwarePlugin::vehicleYawsToNextWaypointInMission(const Vehicle* vehicl
} }
return true; return true;
} }
QGCCameraManager* PX4FirmwarePlugin::createCameraManager(Vehicle* vehicle)
{
return new QGCCameraManager(vehicle);
}
QGCCameraControl* PX4FirmwarePlugin::createCameraControl(const mavlink_camera_information_t* info, Vehicle *vehicle, int compID, QObject* parent)
{
return new QGCCameraControl(info, vehicle, compID, parent);
}
...@@ -24,6 +24,7 @@ class PX4FirmwarePlugin : public FirmwarePlugin ...@@ -24,6 +24,7 @@ class PX4FirmwarePlugin : public FirmwarePlugin
public: public:
PX4FirmwarePlugin(void); PX4FirmwarePlugin(void);
~PX4FirmwarePlugin();
// Overrides from FirmwarePlugin // Overrides from FirmwarePlugin
...@@ -65,6 +66,8 @@ public: ...@@ -65,6 +66,8 @@ public:
QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/PX4/BrandImage"); } QString brandImageOutdoor (const Vehicle* vehicle) const override { Q_UNUSED(vehicle); return QStringLiteral("/qmlimages/PX4/BrandImage"); }
bool vehicleYawsToNextWaypointInMission(const Vehicle* vehicle) const override; bool vehicleYawsToNextWaypointInMission(const Vehicle* vehicle) const override;
QString autoDisarmParameter (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QStringLiteral("COM_DISARM_LAND"); } QString autoDisarmParameter (Vehicle* vehicle) override { Q_UNUSED(vehicle); return QStringLiteral("COM_DISARM_LAND"); }
QGCCameraManager* createCameraManager (Vehicle* vehicle) override;
QGCCameraControl* createCameraControl (const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = NULL) override;
protected: protected:
typedef struct { typedef struct {
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <QDir> #include <QDir>
#include <QDebug> #include <QDebug>
static const char* kInvalidConverstion = "Internal Error: No support for string parameters";
QGC_LOGGING_CATEGORY(PX4ParameterMetaDataLog, "PX4ParameterMetaDataLog") QGC_LOGGING_CATEGORY(PX4ParameterMetaDataLog, "PX4ParameterMetaDataLog")
PX4ParameterMetaData::PX4ParameterMetaData(void) PX4ParameterMetaData::PX4ParameterMetaData(void)
...@@ -57,13 +59,17 @@ QVariant PX4ParameterMetaData::_stringToTypedVariant(const QString& string, Fact ...@@ -57,13 +59,17 @@ QVariant PX4ParameterMetaData::_stringToTypedVariant(const QString& string, Fact
convertTo = QVariant::Double; convertTo = QVariant::Double;
break; break;
case FactMetaData::valueTypeString: case FactMetaData::valueTypeString:
qWarning() << "Internal Error: No support for string parameters"; qWarning() << kInvalidConverstion;
convertTo = QVariant::String; convertTo = QVariant::String;
break; break;
case FactMetaData::valueTypeBool: case FactMetaData::valueTypeBool:
qWarning() << "Internal Error: No support for string parameters"; qWarning() << kInvalidConverstion;
convertTo = QVariant::Bool; convertTo = QVariant::Bool;
break; break;
case FactMetaData::valueTypeCustom:
qWarning() << kInvalidConverstion;
convertTo = QVariant::ByteArray;
break;
} }
*convertOk = var.convert(convertTo); *convertOk = var.convert(convertTo);
......
...@@ -54,6 +54,8 @@ QGCView { ...@@ -54,6 +54,8 @@ QGCView {
property alias _altitudeSlider: altitudeSlider property alias _altitudeSlider: altitudeSlider
readonly property var _dynamicCameras: _activeVehicle ? _activeVehicle.dynamicCameras : null
readonly property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false
readonly property bool isBackgroundDark: _mainIsMap ? (_flightMap ? _flightMap.isSatelliteMap : true) : true readonly property bool isBackgroundDark: _mainIsMap ? (_flightMap ? _flightMap.isSatelliteMap : true) : true
readonly property real _defaultRoll: 0 readonly property real _defaultRoll: 0
readonly property real _defaultPitch: 0 readonly property real _defaultPitch: 0
...@@ -196,7 +198,7 @@ QGCView { ...@@ -196,7 +198,7 @@ QGCView {
z: _mainIsMap ? _panel.z + 1 : _panel.z + 2 z: _mainIsMap ? _panel.z + 1 : _panel.z + 2
anchors.left: _panel.left anchors.left: _panel.left
anchors.bottom: _panel.bottom anchors.bottom: _panel.bottom
visible: _mainIsMap || _isPipVisible visible: _mainIsMap || _isPipVisible && !QGroundControl.videoManager.fullScreen
width: _mainIsMap ? _panel.width : _pipSize width: _mainIsMap ? _panel.width : _pipSize
height: _mainIsMap ? _panel.height : _pipSize * (9/16) height: _mainIsMap ? _panel.height : _pipSize * (9/16)
states: [ states: [
...@@ -275,7 +277,7 @@ QGCView { ...@@ -275,7 +277,7 @@ QGCView {
anchors.left: _panel.left anchors.left: _panel.left
anchors.bottom: _panel.bottom anchors.bottom: _panel.bottom
anchors.margins: ScreenTools.defaultFontPixelHeight anchors.margins: ScreenTools.defaultFontPixelHeight
visible: QGroundControl.videoManager.hasVideo visible: QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen
isHidden: !_isPipVisible isHidden: !_isPipVisible
isDark: isBackgroundDark isDark: isBackgroundDark
onActivated: { onActivated: {
...@@ -324,7 +326,7 @@ QGCView { ...@@ -324,7 +326,7 @@ QGCView {
qgcView: root qgcView: root
useLightColors: isBackgroundDark useLightColors: isBackgroundDark
missionController: _missionController missionController: _missionController
visible: singleVehicleView.checked visible: singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
...@@ -332,6 +334,7 @@ QGCView { ...@@ -332,6 +334,7 @@ QGCView {
Loader { Loader {
id: flyViewOverlay id: flyViewOverlay
z: flightDisplayViewWidgets.z + 1 z: flightDisplayViewWidgets.z + 1
visible: !QGroundControl.videoManager.fullScreen
height: ScreenTools.availableHeight height: ScreenTools.availableHeight
anchors.left: parent.left anchors.left: parent.left
anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right anchors.right: altitudeSlider.visible ? altitudeSlider.left : parent.right
...@@ -348,7 +351,7 @@ QGCView { ...@@ -348,7 +351,7 @@ QGCView {
anchors.right: _flightVideo.right anchors.right: _flightVideo.right
height: ScreenTools.defaultFontPixelHeight * 2 height: ScreenTools.defaultFontPixelHeight * 2
width: height width: height
visible: _videoReceiver && _videoReceiver.videoRunning && QGroundControl.settingsManager.videoSettings.showRecControl.rawValue && _flightVideo.visible visible: _videoReceiver && _videoReceiver.videoRunning && QGroundControl.settingsManager.videoSettings.showRecControl.rawValue && _flightVideo.visible && !_isCamera && !QGroundControl.videoManager.fullScreen
opacity: 0.75 opacity: 0.75
readonly property string recordBtnBackground: "BackgroundName" readonly property string recordBtnBackground: "BackgroundName"
...@@ -398,14 +401,13 @@ QGCView { ...@@ -398,14 +401,13 @@ QGCView {
} }
MultiVehicleList { MultiVehicleList {
anchors.margins: _margins anchors.margins: _margins
anchors.top: singleMultiSelector.bottom anchors.top: singleMultiSelector.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: ScreenTools.defaultFontPixelWidth * 30 width: ScreenTools.defaultFontPixelWidth * 30
visible: !singleVehicleView.checked visible: !singleVehicleView.checked && !QGroundControl.videoManager.fullScreen
z: _panel.z + 4 z: _panel.z + 4
guidedActionsController: _guidedController
} }
//-- Virtual Joystick //-- Virtual Joystick
...@@ -414,7 +416,7 @@ QGCView { ...@@ -414,7 +416,7 @@ QGCView {
z: _panel.z + 5 z: _panel.z + 5
width: parent.width - (_flightVideoPipControl.width / 2) width: parent.width - (_flightVideoPipControl.width / 2)
height: Math.min(ScreenTools.availableHeight * 0.25, ScreenTools.defaultFontPixelWidth * 16) height: Math.min(ScreenTools.availableHeight * 0.25, ScreenTools.defaultFontPixelWidth * 16)
visible: _virtualJoystick ? _virtualJoystick.value : false visible: (_virtualJoystick ? _virtualJoystick.value : false) && !QGroundControl.videoManager.fullScreen
anchors.bottom: _flightVideoPipControl.top anchors.bottom: _flightVideoPipControl.top
anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2 anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2
anchors.horizontalCenter: flightDisplayViewWidgets.horizontalCenter anchors.horizontalCenter: flightDisplayViewWidgets.horizontalCenter
...@@ -427,7 +429,7 @@ QGCView { ...@@ -427,7 +429,7 @@ QGCView {
} }
ToolStrip { ToolStrip {
visible: _activeVehicle ? _activeVehicle.guidedModeSupported : true visible: (_activeVehicle ? _activeVehicle.guidedModeSupported : true) && !QGroundControl.videoManager.fullScreen
id: toolStrip id: toolStrip
anchors.leftMargin: ScreenTools.defaultFontPixelWidth anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.left: _panel.left anchors.left: _panel.left
...@@ -569,6 +571,7 @@ QGCView { ...@@ -569,6 +571,7 @@ QGCView {
/// Close all dialogs /// Close all dialogs
function closeAll() { function closeAll() {
mainWindow.enableToolbar()
rootLoader.sourceComponent = null rootLoader.sourceComponent = null
guidedActionConfirm.visible = false guidedActionConfirm.visible = false
guidedActionList.visible = false guidedActionList.visible = false
......
...@@ -8,25 +8,26 @@ ...@@ -8,25 +8,26 @@
****************************************************************************/ ****************************************************************************/
import QtQuick 2.3 import QtQuick 2.3
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QGroundControl 1.0
import QGroundControl.FlightDisplay 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Controllers 1.0
import QGroundControl 1.0
import QGroundControl.FlightDisplay 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Controllers 1.0
Item { Item {
id: root id: root
property double _ar: QGroundControl.settingsManager.videoSettings.aspectRatio.rawValue property double _ar: QGroundControl.settingsManager.videoSettings.aspectRatio.rawValue
property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0 property bool _showGrid: QGroundControl.settingsManager.videoSettings.gridLines.rawValue > 0
property var _videoReceiver: QGroundControl.videoManager.videoReceiver property var _videoReceiver: QGroundControl.videoManager.videoReceiver
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property var _dynamicCameras: _activeVehicle ? _activeVehicle.dynamicCameras : null
property bool _connected: _activeVehicle ? !_activeVehicle.connectionLost : false
Rectangle { Rectangle {
id: noVideo id: noVideo
anchors.fill: parent anchors.fill: parent
...@@ -39,6 +40,12 @@ Item { ...@@ -39,6 +40,12 @@ Item {
font.pointSize: _mainIsMap ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize font.pointSize: _mainIsMap ? ScreenTools.smallFontPointSize : ScreenTools.largeFontPointSize
anchors.centerIn: parent anchors.centerIn: parent
} }
MouseArea {
anchors.fill: parent
onDoubleClicked: {
QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen
}
}
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
...@@ -67,29 +74,44 @@ Item { ...@@ -67,29 +74,44 @@ Item {
height: parent.height height: parent.height
width: 1 width: 1
x: parent.width * 0.33 x: parent.width * 0.33
visible: _showGrid visible: _showGrid && !QGroundControl.videoManager.fullScreen
} }
Rectangle { Rectangle {
color: Qt.rgba(1,1,1,0.5) color: Qt.rgba(1,1,1,0.5)
height: parent.height height: parent.height
width: 1 width: 1
x: parent.width * 0.66 x: parent.width * 0.66
visible: _showGrid visible: _showGrid && !QGroundControl.videoManager.fullScreen
} }
Rectangle { Rectangle {
color: Qt.rgba(1,1,1,0.5) color: Qt.rgba(1,1,1,0.5)
width: parent.width width: parent.width
height: 1 height: 1
y: parent.height * 0.33 y: parent.height * 0.33
visible: _showGrid visible: _showGrid && !QGroundControl.videoManager.fullScreen
} }
Rectangle { Rectangle {
color: Qt.rgba(1,1,1,0.5) color: Qt.rgba(1,1,1,0.5)
width: parent.width width: parent.width
height: 1 height: 1
y: parent.height * 0.66 y: parent.height * 0.66
visible: _showGrid visible: _showGrid && !QGroundControl.videoManager.fullScreen
} }
} }
MouseArea {
anchors.fill: parent
onDoubleClicked: {
QGroundControl.videoManager.fullScreen = !QGroundControl.videoManager.fullScreen
}
}
}
//-- Camera Controller
Loader {
source: QGroundControl.videoManager.fullScreen ? "" : (_dynamicCameras ? _dynamicCameras.controllerSource : "")
visible: !_mainIsMap && _dynamicCameras && _dynamicCameras.cameras.count && _connected && !QGroundControl.videoManager.fullScreen
anchors.right: parent.right
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.bottom: parent.bottom
anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2
} }
} }
...@@ -129,7 +129,7 @@ Item { ...@@ -129,7 +129,7 @@ Item {
property bool __flightMode: _flightMode property bool __flightMode: _flightMode
function _outputState() { function _outputState() {
console.log(qsTr("_activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleFlying(%4) _vehicleInRTLMode(%5) pauseVehicleSupported(%6) _vehiclePaused(%7) _flightMode(%8)").arg(_activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleFlying ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode)) //console.log(qsTr("_activeVehicle(%1) _vehicleArmed(%2) guidedModeSupported(%3) _vehicleFlying(%4) _vehicleInRTLMode(%5) pauseVehicleSupported(%6) _vehiclePaused(%7) _flightMode(%8)").arg(_activeVehicle ? 1 : 0).arg(_vehicleArmed ? 1 : 0).arg(__guidedModeSupported ? 1 : 0).arg(_vehicleFlying ? 1 : 0).arg(_vehicleInRTLMode ? 1 : 0).arg(__pauseVehicleSupported ? 1 : 0).arg(_vehiclePaused ? 1 : 0).arg(_flightMode))
} }
Component.onCompleted: _outputState() Component.onCompleted: _outputState()
...@@ -170,10 +170,10 @@ Item { ...@@ -170,10 +170,10 @@ Item {
property var _actionData property var _actionData
on_FlightModeChanged: { on_FlightModeChanged: {
_vehiclePaused = _flightMode === _activeVehicle.pauseFlightMode _vehiclePaused = _activeVehicle ? _flightMode === _activeVehicle.pauseFlightMode : false
_vehicleInRTLMode = _flightMode === _activeVehicle.rtlFlightMode _vehicleInRTLMode = _activeVehicle ? _flightMode === _activeVehicle.rtlFlightMode : false
_vehicleInLandMode = _flightMode === _activeVehicle.landFlightMode _vehicleInLandMode = _activeVehicle ? _flightMode === _activeVehicle.landFlightMode : false
_vehicleInMissionMode = _flightMode === _activeVehicle.missionFlightMode // Must be last to get correct signalling for showStartMission popups _vehicleInMissionMode = _activeVehicle ? _flightMode === _activeVehicle.missionFlightMode : false // Must be last to get correct signalling for showStartMission popups
} }
// Called when an action is about to be executed in order to confirm // Called when an action is about to be executed in order to confirm
......
...@@ -25,8 +25,8 @@ Rectangle { ...@@ -25,8 +25,8 @@ Rectangle {
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property real _vehicleAltitude: _activeVehicle ? _activeVehicle.altitudeRelative.rawValue : 0 property real _vehicleAltitude: _activeVehicle ? _activeVehicle.altitudeRelative.rawValue : 0
property bool _fixedWing: _activeVehicle ? _activeVehicle.fixedWing : false property bool _fixedWing: _activeVehicle ? _activeVehicle.fixedWing : false
property real _sliderMaxAlt: _fixedWing ? _guidedSettings.fixedWingMaximumAltitude.rawValue : _guidedSettings.vehicleMaximumAltitude.rawValue property real _sliderMaxAlt: _guidedSettings ? (_fixedWing ? _guidedSettings.fixedWingMaximumAltitude.rawValue : _guidedSettings.vehicleMaximumAltitude.rawValue) : 0
property real _sliderMinAlt: _fixedWing ? _guidedSettings.fixedWingMinimumAltitude.rawValue : _guidedSettings.vehicleMinimumAltitude.rawValue property real _sliderMinAlt: _guidedSettings ? (_fixedWing ? _guidedSettings.fixedWingMinimumAltitude.rawValue : _guidedSettings.vehicleMinimumAltitude.rawValue) : 0
function reset() { function reset() {
altSlider.value = 0 altSlider.value = 0
......
...@@ -34,6 +34,7 @@ VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox) ...@@ -34,6 +34,7 @@ VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox) : QGCTool(app, toolbox)
, _videoReceiver(NULL) , _videoReceiver(NULL)
, _videoSettings(NULL) , _videoSettings(NULL)
, _fullScreen(false)
{ {
} }
......
...@@ -35,10 +35,12 @@ public: ...@@ -35,10 +35,12 @@ public:
Q_PROPERTY(bool isGStreamer READ isGStreamer NOTIFY isGStreamerChanged) Q_PROPERTY(bool isGStreamer READ isGStreamer NOTIFY isGStreamerChanged)
Q_PROPERTY(QString videoSourceID READ videoSourceID NOTIFY videoSourceIDChanged) Q_PROPERTY(QString videoSourceID READ videoSourceID NOTIFY videoSourceIDChanged)
Q_PROPERTY(bool uvcEnabled READ uvcEnabled CONSTANT) Q_PROPERTY(bool uvcEnabled READ uvcEnabled CONSTANT)
Q_PROPERTY(bool fullScreen READ fullScreen WRITE setfullScreen NOTIFY fullScreenChanged)
Q_PROPERTY(VideoReceiver* videoReceiver READ videoReceiver CONSTANT) Q_PROPERTY(VideoReceiver* videoReceiver READ videoReceiver CONSTANT)
bool hasVideo (); bool hasVideo ();
bool isGStreamer (); bool isGStreamer ();
bool fullScreen () { return _fullScreen; }
QString videoSourceID () { return _videoSourceID; } QString videoSourceID () { return _videoSourceID; }
VideoReceiver* videoReceiver () { return _videoReceiver; } VideoReceiver* videoReceiver () { return _videoReceiver; }
...@@ -49,6 +51,8 @@ public: ...@@ -49,6 +51,8 @@ public:
bool uvcEnabled (); bool uvcEnabled ();
#endif #endif
void setfullScreen (bool f) { _fullScreen = f; emit fullScreenChanged(); }
// Override from QGCTool // Override from QGCTool
void setToolbox (QGCToolbox *toolbox); void setToolbox (QGCToolbox *toolbox);
...@@ -56,6 +60,7 @@ signals: ...@@ -56,6 +60,7 @@ signals:
void hasVideoChanged (); void hasVideoChanged ();
void isGStreamerChanged (); void isGStreamerChanged ();
void videoSourceIDChanged (); void videoSourceIDChanged ();
void fullScreenChanged ();
private slots: private slots:
void _videoSourceChanged (); void _videoSourceChanged ();
...@@ -70,6 +75,7 @@ private: ...@@ -70,6 +75,7 @@ private:
VideoReceiver* _videoReceiver; VideoReceiver* _videoReceiver;
VideoSettings* _videoSettings; VideoSettings* _videoSettings;
QString _videoSourceID; QString _videoSourceID;
bool _fullScreen;
}; };
#endif #endif
...@@ -7,73 +7,132 @@ ...@@ -7,73 +7,132 @@
* *
****************************************************************************/ ****************************************************************************/
/**
* @file
* @brief Implementation of audio output
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
* @author Thomas Gubler <thomasgubler@gmail.com>
*
*/
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QRegularExpression>
#include "GAudioOutput.h" #include "GAudioOutput.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "QGC.h" #include "QGC.h"
#include "SettingsManager.h" #include "SettingsManager.h"
#if defined __android__
#include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject>
#endif
GAudioOutput::GAudioOutput(QGCApplication* app, QGCToolbox* toolbox) GAudioOutput::GAudioOutput(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox) : QGCTool(app, toolbox)
#ifndef __android__
, thread(new QThread())
, worker(new QGCAudioWorker())
#endif
{ {
#ifndef __android__ _tts = new QTextToSpeech(this);
worker->moveToThread(thread); connect(_tts, &QTextToSpeech::stateChanged, this, &GAudioOutput::_stateChanged);
connect(this, &GAudioOutput::textToSpeak, worker, &QGCAudioWorker::say);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
connect(thread, &QThread::finished, worker, &QObject::deleteLater);
thread->start();
#endif
} }
GAudioOutput::~GAudioOutput()
{
#ifndef __android__
thread->quit();
#endif
}
bool GAudioOutput::say(const QString& inText) bool GAudioOutput::say(const QString& inText)
{ {
bool muted = qgcApp()->toolbox()->settingsManager()->appSettings()->audioMuted()->rawValue().toBool(); bool muted = qgcApp()->toolbox()->settingsManager()->appSettings()->audioMuted()->rawValue().toBool();
muted |= qgcApp()->runningUnitTests(); muted |= qgcApp()->runningUnitTests();
if (!muted && !qgcApp()->runningUnitTests()) { if (!muted && !qgcApp()->runningUnitTests()) {
#if defined __android__ QString text = fixTextMessageForAudio(inText);
#if defined QGC_SPEECH_ENABLED if(_tts->state() == QTextToSpeech::Speaking) {
static const char V_jniClassName[] {"org/mavlink/qgroundcontrol/QGCActivity"}; if(!_texts.contains(text)) {
QAndroidJniEnvironment env; //-- Some arbitrary limit
if (env->ExceptionCheck()) { if(_texts.size() > 20) {
env->ExceptionDescribe(); _texts.removeFirst();
env->ExceptionClear(); }
_texts.append(text);
}
} else {
_tts->say(text);
} }
QString text = QGCAudioWorker::fixTextMessageForAudio(inText);
QAndroidJniObject javaMessage = QAndroidJniObject::fromString(text);
QAndroidJniObject::callStaticMethod<void>(V_jniClassName, "say", "(Ljava/lang/String;)V", javaMessage.object<jstring>());
#endif
#else
emit textToSpeak(inText);
#endif
} }
return true; return true;
} }
void GAudioOutput::_stateChanged(QTextToSpeech::State state)
{
if(state == QTextToSpeech::Ready) {
if(_texts.size()) {
QString text = _texts.first();
_texts.removeFirst();
_tts->say(text);
}
}
}
bool GAudioOutput::getMillisecondString(const QString& string, QString& match, int& number) {
static QRegularExpression re("([0-9]+ms)");
QRegularExpressionMatchIterator i = re.globalMatch(string);
while (i.hasNext()) {
QRegularExpressionMatch qmatch = i.next();
if (qmatch.hasMatch()) {
match = qmatch.captured(0);
number = qmatch.captured(0).replace("ms", "").toInt();
return true;
}
}
return false;
}
QString GAudioOutput::fixTextMessageForAudio(const QString& string) {
QString match;
QString newNumber;
QString result = string;
//-- Look for codified terms
if(result.contains("ERR ", Qt::CaseInsensitive)) {
result.replace("ERR ", "error ", Qt::CaseInsensitive);
}
if(result.contains("ERR:", Qt::CaseInsensitive)) {
result.replace("ERR:", "error.", Qt::CaseInsensitive);
}
if(result.contains("POSCTL", Qt::CaseInsensitive)) {
result.replace("POSCTL", "Position Control", Qt::CaseInsensitive);
}
if(result.contains("ALTCTL", Qt::CaseInsensitive)) {
result.replace("ALTCTL", "Altitude Control", Qt::CaseInsensitive);
}
if(result.contains("AUTO_RTL", Qt::CaseInsensitive)) {
result.replace("AUTO_RTL", "auto Return To Launch", Qt::CaseInsensitive);
} else if(result.contains("RTL", Qt::CaseInsensitive)) {
result.replace("RTL", "Return To Launch", Qt::CaseInsensitive);
}
if(result.contains("ACCEL ", Qt::CaseInsensitive)) {
result.replace("ACCEL ", "accelerometer ", Qt::CaseInsensitive);
}
if(result.contains("RC_MAP_MODE_SW", Qt::CaseInsensitive)) {
result.replace("RC_MAP_MODE_SW", "RC mode switch", Qt::CaseInsensitive);
}
if(result.contains("REJ.", Qt::CaseInsensitive)) {
result.replace("REJ.", "Rejected", Qt::CaseInsensitive);
}
if(result.contains("WP", Qt::CaseInsensitive)) {
result.replace("WP", "way point", Qt::CaseInsensitive);
}
if(result.contains("CMD", Qt::CaseInsensitive)) {
result.replace("CMD", "command", Qt::CaseInsensitive);
}
if(result.contains("COMPID", Qt::CaseInsensitive)) {
result.replace("COMPID", "component eye dee", Qt::CaseInsensitive);
}
if(result.contains(" params ", Qt::CaseInsensitive)) {
result.replace(" params ", " parameters ", Qt::CaseInsensitive);
}
if(result.contains(" id ", Qt::CaseInsensitive)) {
result.replace(" id ", " eye dee ", Qt::CaseInsensitive);
}
if(result.contains(" ADSB ", Qt::CaseInsensitive)) {
result.replace(" ADSB ", " Hey Dee Ess Bee ", Qt::CaseInsensitive);
}
int number;
if(getMillisecondString(string, match, number) && number > 1000) {
if(number < 60000) {
int seconds = number / 1000;
newNumber = QString("%1 second%2").arg(seconds).arg(seconds > 1 ? "s" : "");
} else {
int minutes = number / 60000;
int seconds = (number - (minutes * 60000)) / 1000;
if (!seconds) {
newNumber = QString("%1 minute%2").arg(minutes).arg(minutes > 1 ? "s" : "");
} else {
newNumber = QString("%1 minute%2 and %3 second%4").arg(minutes).arg(minutes > 1 ? "s" : "").arg(seconds).arg(seconds > 1 ? "s" : "");
}
}
result.replace(match, newNumber);
}
return result;
}
...@@ -7,75 +7,35 @@ ...@@ -7,75 +7,35 @@
* *
****************************************************************************/ ****************************************************************************/
#pragma once
/**
* @file
* @brief Definition of audio output
*
* @author Lorenz Meier <mavteam@student.ethz.ch>
*
*/
#ifndef GAUDIOOUTPUT_H
#define GAUDIOOUTPUT_H
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QThread> #include <QThread>
#include <QStringList> #include <QStringList>
#include <QTextToSpeech>
#include "QGCAudioWorker.h"
#include "QGCToolbox.h" #include "QGCToolbox.h"
class QGCApplication; class QGCApplication;
/**
* @brief Audio Output (speech synthesizer and "beep" output)
* This class follows the singleton design pattern
* @see http://en.wikipedia.org/wiki/Singleton_pattern
*/
class GAudioOutput : public QGCTool class GAudioOutput : public QGCTool
{ {
Q_OBJECT Q_OBJECT
public: public:
GAudioOutput(QGCApplication* app, QGCToolbox* toolbox); GAudioOutput(QGCApplication* app, QGCToolbox* toolbox);
~GAudioOutput();
/** @brief List available voices */
QStringList listVoices(void);
enum
{
VOICE_MALE = 0,
VOICE_FEMALE
} QGVoice;
enum AUDIO_SEVERITY static bool getMillisecondString (const QString& string, QString& match, int& number);
{ static QString fixTextMessageForAudio (const QString& string);
AUDIO_SEVERITY_EMERGENCY = 0,
AUDIO_SEVERITY_ALERT = 1,
AUDIO_SEVERITY_CRITICAL = 2,
AUDIO_SEVERITY_ERROR = 3,
AUDIO_SEVERITY_WARNING = 4,
AUDIO_SEVERITY_NOTICE = 5,
AUDIO_SEVERITY_INFO = 6,
AUDIO_SEVERITY_DEBUG = 7
};
public slots: public slots:
/** @brief Say this text */ bool say (const QString& text);
bool say(const QString& text);
signals: private slots:
bool textToSpeak(QString text); void _stateChanged (QTextToSpeech::State state);
void beepOnce();
protected: protected:
#if !defined __android__ QTextToSpeech* _tts;
QThread* thread; QStringList _texts;
QGCAudioWorker* worker;
#endif
}; };
#endif // AUDIOOUTPUT_H
...@@ -111,13 +111,36 @@ bool JsonHelper::validateKeyTypes(const QJsonObject& jsonObject, const QStringLi ...@@ -111,13 +111,36 @@ bool JsonHelper::validateKeyTypes(const QJsonObject& jsonObject, const QStringLi
return true; return true;
} }
bool JsonHelper::parseEnum(const QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString) bool JsonHelper::parseEnum(const QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString, QString valueName)
{ {
enumStrings = jsonObject.value(_enumStringsJsonKey).toString().split(",", QString::SkipEmptyParts); if(jsonObject.value(_enumStringsJsonKey).isArray()) {
enumValues = jsonObject.value(_enumValuesJsonKey).toString().split(",", QString::SkipEmptyParts); // "enumStrings": ["Auto" , "Manual", "Shutter Priority", "Aperture Priority"],
QJsonArray jArray = jsonObject.value(_enumStringsJsonKey).toArray();
for(int i = 0; i < jArray.count(); ++i) {
enumStrings << jArray.at(i).toString();
}
} else {
// "enumStrings": "Auto,Manual,Shutter Priority,Aperture Priority",
enumStrings = jsonObject.value(_enumStringsJsonKey).toString().split(",", QString::SkipEmptyParts);
}
if(jsonObject.value(_enumValuesJsonKey).isArray()) {
// "enumValues": [0, 1, 2, 3, 4, 5],
QJsonArray jArray = jsonObject.value(_enumValuesJsonKey).toArray();
// This should probably be a variant list and not a string list.
for(int i = 0; i < jArray.count(); ++i) {
if(jArray.at(i).isString())
enumValues << jArray.at(i).toString();
else
enumValues << QString::number(jArray.at(i).toDouble());
}
} else {
// "enumValues": "0,1,2,3,4,5",
enumValues = jsonObject.value(_enumValuesJsonKey).toString().split(",", QString::SkipEmptyParts);
}
if (enumStrings.count() != enumValues.count()) { if (enumStrings.count() != enumValues.count()) {
errorString = QObject::tr("enum strings/values count mismatch strings:values %1:%2").arg(enumStrings.count()).arg(enumValues.count()); errorString = QObject::tr("enum strings/values count mismatch in %3 strings:values %1:%2").arg(enumStrings.count()).arg(enumValues.count()).arg(valueName);
return false; return false;
} }
......
...@@ -104,7 +104,7 @@ public: ...@@ -104,7 +104,7 @@ public:
static void savePolygon(QmlObjectListModel& list, ///< List which contains vertices static void savePolygon(QmlObjectListModel& list, ///< List which contains vertices
QJsonArray& polygonArray); ///< Array to save into QJsonArray& polygonArray); ///< Array to save into
static bool parseEnum(const QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString); static bool parseEnum(const QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString, QString valueName = QString());
/// Returns NaN if the value is null, or it not the double value /// Returns NaN if the value is null, or it not the double value
static double possibleNaNJsonValue(const QJsonValue& value); static double possibleNaNJsonValue(const QJsonValue& value);
......
...@@ -47,10 +47,10 @@ ...@@ -47,10 +47,10 @@
}, },
{ {
"name": "CameraMode", "name": "CameraMode",
"shortDescription": "Specify whether the camera should switch to photo or video mode", "shortDescription": "Specify whether the camera should switch to Photo, Video or Survey mode",
"type": "uint32", "type": "uint32",
"enumStrings": "Photo,Video", "enumStrings": "Photo,Video,Survey",
"enumValues": "0,1", "enumValues": "0,1,2",
"defaultValue": 0 "defaultValue": 0
} }
] ]
...@@ -120,10 +120,9 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -120,10 +120,9 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
MissionItem* item = new MissionItem(nextSequenceNumber++, MissionItem* item = new MissionItem(nextSequenceNumber++,
MAV_CMD_SET_CAMERA_MODE, MAV_CMD_SET_CAMERA_MODE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // camera id, all cameras 0, // Reserved (Set to 0)
_cameraModeFact.rawValue().toDouble(), _cameraModeFact.rawValue().toDouble(),
NAN, // Audio off/on NAN, NAN, NAN, NAN, NAN, // param 3-7 reserved
NAN, NAN, NAN, NAN, // param 4-7 reserved
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
missionItemParent); missionItemParent);
...@@ -153,7 +152,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -153,7 +152,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
item = new MissionItem(nextSequenceNumber++, item = new MissionItem(nextSequenceNumber++,
MAV_CMD_IMAGE_START_CAPTURE, MAV_CMD_IMAGE_START_CAPTURE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // Camera ID, all cameras 0, // Reserved (Set to 0)
_cameraPhotoIntervalTimeFact.rawValue().toInt(), // Interval _cameraPhotoIntervalTimeFact.rawValue().toInt(), // Interval
0, // Unlimited photo count 0, // Unlimited photo count
NAN, NAN, NAN, NAN, // param 4-7 reserved NAN, NAN, NAN, NAN, // param 4-7 reserved
...@@ -179,7 +178,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -179,7 +178,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
item = new MissionItem(nextSequenceNumber++, item = new MissionItem(nextSequenceNumber++,
MAV_CMD_VIDEO_START_CAPTURE, MAV_CMD_VIDEO_START_CAPTURE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // camera id = 0, all cameras 0, // Reserved (Set to 0)
0, // No CAMERA_CAPTURE_STATUS streaming 0, // No CAMERA_CAPTURE_STATUS streaming
NAN, NAN, NAN, NAN, NAN, // param 3-7 reserved NAN, NAN, NAN, NAN, NAN, // param 3-7 reserved
true, // autoContinue true, // autoContinue
...@@ -191,7 +190,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -191,7 +190,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
item = new MissionItem(nextSequenceNumber++, item = new MissionItem(nextSequenceNumber++,
MAV_CMD_VIDEO_STOP_CAPTURE, MAV_CMD_VIDEO_STOP_CAPTURE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // Camera ID, all cameras 0, // Reserved (Set to 0)
NAN, NAN, NAN, NAN, NAN, NAN, // param 2-7 reserved NAN, NAN, NAN, NAN, NAN, NAN, // param 2-7 reserved
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
...@@ -211,7 +210,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -211,7 +210,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
item = new MissionItem(nextSequenceNumber++, item = new MissionItem(nextSequenceNumber++,
MAV_CMD_IMAGE_STOP_CAPTURE, MAV_CMD_IMAGE_STOP_CAPTURE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // camera id, all cameras 0, // Reserved (Set to 0)
NAN, NAN, NAN, NAN, NAN, NAN, // param 2-7 reserved NAN, NAN, NAN, NAN, NAN, NAN, // param 2-7 reserved
true, // autoContinue true, // autoContinue
false, // isCurrentItem false, // isCurrentItem
...@@ -222,7 +221,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss ...@@ -222,7 +221,7 @@ void CameraSection::appendSectionItems(QList<MissionItem*>& items, QObject* miss
item = new MissionItem(nextSequenceNumber++, item = new MissionItem(nextSequenceNumber++,
MAV_CMD_IMAGE_START_CAPTURE, MAV_CMD_IMAGE_START_CAPTURE,
MAV_FRAME_MISSION, MAV_FRAME_MISSION,
0, // camera id = 0, all cameras 0, // Reserved (Set to 0)
0, // Interval (none) 0, // Interval (none)
1, // Take 1 photo 1, // Take 1 photo
NAN, NAN, NAN, NAN, // param 4-7 reserved NAN, NAN, NAN, NAN, // param 4-7 reserved
...@@ -394,7 +393,7 @@ bool CameraSection::_scanSetCameraMode(QmlObjectListModel* visualItems, int scan ...@@ -394,7 +393,7 @@ bool CameraSection::_scanSetCameraMode(QmlObjectListModel* visualItems, int scan
MissionItem& missionItem = item->missionItem(); MissionItem& missionItem = item->missionItem();
if ((MAV_CMD)item->command() == MAV_CMD_SET_CAMERA_MODE) { if ((MAV_CMD)item->command() == MAV_CMD_SET_CAMERA_MODE) {
// We specifically don't test param 5/6/7 since we don't have NaN persistence for those fields // We specifically don't test param 5/6/7 since we don't have NaN persistence for those fields
if (missionItem.param1() == 0 && (missionItem.param2() == 0 || missionItem.param2() == 1) && qIsNaN(missionItem.param3())) { if (missionItem.param1() == 0 && (missionItem.param2() == CAMERA_MODE_IMAGE || missionItem.param2() == CAMERA_MODE_VIDEO || missionItem.param2() == CAMERA_MODE_IMAGE_SURVEY) && qIsNaN(missionItem.param3())) {
setSpecifyCameraMode(true); setSpecifyCameraMode(true);
cameraMode()->setRawValue(missionItem.param2()); cameraMode()->setRawValue(missionItem.param2());
visualItems->removeAt(scanIndex)->deleteLater(); visualItems->removeAt(scanIndex)->deleteLater();
......
...@@ -34,12 +34,6 @@ public: ...@@ -34,12 +34,6 @@ public:
}; };
Q_ENUMS(CameraAction) Q_ENUMS(CameraAction)
enum CameraMode {
CameraModePhoto,
CameraModeVideo
};
Q_ENUMS(CameraMode)
Q_PROPERTY(bool specifyGimbal READ specifyGimbal WRITE setSpecifyGimbal NOTIFY specifyGimbalChanged) Q_PROPERTY(bool specifyGimbal READ specifyGimbal WRITE setSpecifyGimbal NOTIFY specifyGimbalChanged)
Q_PROPERTY(Fact* gimbalPitch READ gimbalPitch CONSTANT) Q_PROPERTY(Fact* gimbalPitch READ gimbalPitch CONSTANT)
Q_PROPERTY(Fact* gimbalYaw READ gimbalYaw CONSTANT) Q_PROPERTY(Fact* gimbalYaw READ gimbalYaw CONSTANT)
......
This diff is collapsed.
...@@ -72,5 +72,6 @@ private: ...@@ -72,5 +72,6 @@ private:
SimpleMissionItem* _validStopTimeItem; SimpleMissionItem* _validStopTimeItem;
SimpleMissionItem* _validCameraPhotoModeItem; SimpleMissionItem* _validCameraPhotoModeItem;
SimpleMissionItem* _validCameraVideoModeItem; SimpleMissionItem* _validCameraVideoModeItem;
SimpleMissionItem* _validCameraSurveyPhotoModeItem;
SimpleMissionItem* _validTakePhotoItem; SimpleMissionItem* _validTakePhotoItem;
}; };
...@@ -971,23 +971,12 @@ ...@@ -971,23 +971,12 @@
"id": 530, "id": 530,
"rawName": "MAV_CMD_SET_CAMERA_MODE", "rawName": "MAV_CMD_SET_CAMERA_MODE",
"friendlyName": "Set camera modes" , "friendlyName": "Set camera modes" ,
"description": "Set camera photo, video, audio modes.", "description": "Set camera photo, video modes.",
"category": "Camera", "category": "Camera",
"param1": {
"label": "Camera id",
"default": 0,
"decimalPlaces": 0
},
"param2": { "param2": {
"label": "Mode", "label": "Mode",
"enumStrings": "Take photos,Record video", "enumStrings": "Take photos,Record video,Survey photo mode",
"enumValues": "0,1", "enumValues": "0,1,2",
"default": 0
},
"param3": {
"label": "Audio",
"enumStrings": "Recording disabled,Recording enabled",
"enumValues": "0,1",
"default": 0 "default": 0
} }
}, },
...@@ -998,7 +987,7 @@ ...@@ -998,7 +987,7 @@
"description": "Start taking one or more photos.", "description": "Start taking one or more photos.",
"category": "Camera", "category": "Camera",
"param1": { "param1": {
"label": "Camera id", "label": "Reserved",
"default": 0, "default": 0,
"decimalPlaces": 0 "decimalPlaces": 0
}, },
...@@ -1021,7 +1010,7 @@ ...@@ -1021,7 +1010,7 @@
"description": "Stop taking photos.", "description": "Stop taking photos.",
"category": "Camera", "category": "Camera",
"param1": { "param1": {
"label": "Camera id", "label": "Reserved",
"default": 0, "default": 0,
"decimalPlaces": 0 "decimalPlaces": 0
} }
...@@ -1034,7 +1023,7 @@ ...@@ -1034,7 +1023,7 @@
"description": "Start video capture.", "description": "Start video capture.",
"category": "Camera", "category": "Camera",
"param1": { "param1": {
"label": "Camera id", "label": "Reserved",
"default": 0, "default": 0,
"decimalPlaces": 0 "decimalPlaces": 0
} }
...@@ -1046,7 +1035,7 @@ ...@@ -1046,7 +1035,7 @@
"description": "Stop video capture.", "description": "Stop video capture.",
"category": "Camera", "category": "Camera",
"param1": { "param1": {
"label": "Camera id", "label": "Reserved",
"default": 0, "default": 0,
"decimalPlaces": 0 "decimalPlaces": 0
} }
......
...@@ -367,7 +367,7 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate ...@@ -367,7 +367,7 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate
// Set camera to photo mode (leave alone if user already specified) // Set camera to photo mode (leave alone if user already specified)
if (cameraSection->cameraModeSupported() && !cameraSection->specifyCameraMode()) { if (cameraSection->cameraModeSupported() && !cameraSection->specifyCameraMode()) {
cameraSection->setSpecifyCameraMode(true); cameraSection->setSpecifyCameraMode(true);
cameraSection->cameraMode()->setRawValue(0); cameraSection->cameraMode()->setRawValue(CAMERA_MODE_IMAGE_SURVEY);
} }
// Point gimbal straight down // Point gimbal straight down
if (_controllerVehicle->firmwarePlugin()->hasGimbal(_controllerVehicle, rollSupported, pitchSupported, yawSupported) && pitchSupported) { if (_controllerVehicle->firmwarePlugin()->hasGimbal(_controllerVehicle, rollSupported, pitchSupported, yawSupported) && pitchSupported) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -107,6 +107,7 @@ private slots: ...@@ -107,6 +107,7 @@ private slots:
signals: signals:
void updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); void updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize);
void internetUpdated ();
private: private:
void _wipeOldCaches (); void _wipeOldCaches ();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment