Commit 4112826b authored by dogmaphobic's avatar dogmaphobic

Merge remote-tracking branch 'MavLink/master' into mapCache

* MavLink/master: (59 commits)
  Fix incorrect method name
  Add vehicles to Plan view
  Flight lines different color than waypoint lines
  In progress indicator for vehicle sync
  Land items default to 0 altitude
  Keep ParameterLoader on first seen dedicated link
  Keep ParameterLoader on first seen dedicated link
  Only save to eeprom when value changes
  Remove 3D Mouse Support
  Don't auto-select on mobile
  Fix ArduPlane FLTMODE_CH usage
  Don't try to use QCoreApplication::arguments before an app is created
  Move the buglist override to as early as possible, include switches for specific rendering backends on windows
  Add Intel PowerVR based GPUs to the naughty list
  Remove unused code
  PX4: Rename auto loiter to auto pause
  Update param meta data for PX4
  Don't check driver version on Intel GMA graphics adapters
  Thumbtack alternate instrument panel
  Vehicle.battery FactGroup
  ...
parents 8624fb71 1f63fcfb
Thank you for considering to contribute to QGroundControl.
Contributions must be made under QGroundControl's dual-license system, under GPLv3 and Apache 2.0. This by definition rules out the re-use of any copyleft (e.g. GPL) licensed code. All contributions must be original or from a compatible license (BSD 2/3 clause, MIT, Apache 2.0).
* https://opensource.org/licenses/gpl-3.0.html
* https://opensource.org/licenses/Apache-2.0
Users of the codebase are free to use it under either license. The dual approach is necessary to be able to offer QGroundControl through the iOS and Android app stores and offers the open source community choice.
...@@ -115,51 +115,6 @@ contains(DEFINES, DISABLE_XBEE) { ...@@ -115,51 +115,6 @@ contains(DEFINES, DISABLE_XBEE) {
message("Skipping support for XBee API (unsupported platform)") message("Skipping support for XBee API (unsupported platform)")
} }
#
# [OPTIONAL] Magellan 3DxWare library. Provides support for 3DConnexion's 3D mice.
#
contains(DEFINES, DISABLE_3DMOUSE) {
message("Skipping support for 3DConnexion mice (manual override from command line)")
DEFINES -= DISABLE_3DMOUSE
# 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_3DMOUSE) {
message("Skipping support for 3DConnexion mice (manual override from user_config.pri)")
} else:LinuxBuild {
exists(/usr/local/lib/libxdrvlib.so) {
message("Including support for 3DConnexion mice")
DEFINES += \
QGC_MOUSE_ENABLED_LINUX \
ParameterCheck
# Hack: Has to be defined for magellan usage
HEADERS += src/input/Mouse6dofInput.h
SOURCES += src/input/Mouse6dofInput.cpp
LIBS += -L/usr/local/lib/ -lxdrvlib
} else {
warning("Skipping support for 3DConnexion mice (missing libraries, see README)")
}
} else:WindowsBuild {
message("Including support for 3DConnexion mice")
DEFINES += QGC_MOUSE_ENABLED_WIN
INCLUDEPATH += libs/thirdParty/3DMouse/win
HEADERS += \
libs/thirdParty/3DMouse/win/I3dMouseParams.h \
libs/thirdParty/3DMouse/win/MouseParameters.h \
libs/thirdParty/3DMouse/win/Mouse3DInput.h \
src/input/Mouse6dofInput.h
SOURCES += \
libs/thirdParty/3DMouse/win/MouseParameters.cpp \
libs/thirdParty/3DMouse/win/Mouse3DInput.cpp \
src/input/Mouse6dofInput.cpp
} else {
message("Skipping support for 3DConnexion mice (unsupported platform)")
}
# #
# [OPTIONAL] Opal RT-LAB Library. Provides integration with Opal-RT's RT-LAB simulator. # [OPTIONAL] Opal RT-LAB Library. Provides integration with Opal-RT's RT-LAB simulator.
# #
......
...@@ -70,6 +70,8 @@ Section "create Start Menu Shortcuts" ...@@ -70,6 +70,8 @@ Section "create Start Menu Shortcuts"
SetShellVarContext all SetShellVarContext all
CreateDirectory "$SMPROGRAMS\$StartMenuFolder" CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\QGroundControl.lnk" "$INSTDIR\qgroundcontrol.exe" "" "$INSTDIR\qgroundcontrol.exe" 0 CreateShortCut "$SMPROGRAMS\$StartMenuFolder\QGroundControl.lnk" "$INSTDIR\qgroundcontrol.exe" "" "$INSTDIR\qgroundcontrol.exe" 0
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\QGroundControl (GPU Compatibility Mode).lnk" "$INSTDIR\qgroundcontrol.exe" "-angle" "$INSTDIR\qgroundcontrol.exe" 0
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\QGroundControl (GPU Safe Mode).lnk" "$INSTDIR\qgroundcontrol.exe" "-swrast" "$INSTDIR\qgroundcontrol.exe" 0
SectionEnd SectionEnd
Function .onInit Function .onInit
......
Subproject commit eca21980688a7f0abe15993227bb07bb92f22c63 Subproject commit a2f37a142c14acbc56390f7a8c6946730f4ae25e
#ifndef I3D_MOUSE_PARAMS_H
#define I3D_MOUSE_PARAMS_H
/*
Parameters for the 3D mouse based on the SDK from 3Dconnexion
*/
class I3dMouseSensor
{
public:
enum ESpeed {
kLowSpeed = 0,
kMidSpeed,
kHighSpeed
};
virtual bool IsPanZoom() const = 0;
virtual bool IsRotate() const = 0;
virtual ESpeed GetSpeed() const = 0;
virtual void SetPanZoom(bool isPanZoom) = 0;
virtual void SetRotate(bool isRotate) = 0;
virtual void SetSpeed(ESpeed speed) = 0;
protected:
virtual ~I3dMouseSensor() {}
};
class I3dMouseNavigation
{
public:
enum EPivot {
kManualPivot = 0,
kAutoPivot,
kAutoPivotOverride
};
enum ENavigation {
kObjectMode = 0,
kCameraMode,
kFlyMode,
kWalkMode,
kHelicopterMode
};
enum EPivotVisibility {
kHidePivot = 0,
kShowPivot,
kShowMovingPivot
};
virtual ENavigation GetNavigationMode() const = 0;
virtual EPivot GetPivotMode() const = 0;
virtual EPivotVisibility GetPivotVisibility() const = 0;
virtual bool IsLockHorizon() const = 0;
virtual void SetLockHorizon(bool bOn) = 0;
virtual void SetNavigationMode(ENavigation navigation) = 0;
virtual void SetPivotMode(EPivot pivot) = 0;
virtual void SetPivotVisibility(EPivotVisibility visibility) = 0;
protected:
virtual ~I3dMouseNavigation(){}
};
class I3dMouseParam : public I3dMouseSensor, public I3dMouseNavigation
{
public:
virtual ~I3dMouseParam() {}
};
#endif
This diff is collapsed.
#ifndef T3DMOUSE_INPUT_H
#define T3DMOUSE_INPUT_H
#include "MouseParameters.h"
#include <QWidget>
#include <QByteArray>
#include <QAbstractNativeEventFilter>
#include <vector>
#include <map>
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 //target at least windows XP
#endif
#include <windows.h>
/*
A class for connecting to and receiving data from a 3D Connexion 3D mouse
This helper class manages the connection to a 3D mouse, collecting WM_INPUT
messages from Windows and converting the data into 3D motion data.
This class is based on the SDK from 3D Connexion but is modified to work with Qt.
It is Windows only since it uses the WM_INPUT messages from windows directly
rather than Qt events.
Note that it needs to be compiled with _WIN32_WINNT defined as 0x0501 (windows XP)
or later because the raw input API was added in Windows XP. This also means that
Qt needs to be compiled with this enabled otherwise the QEventDispatcherWin32 blocks
in processEvents because the raw input messages do not cause the thread to be woken if
Qt is compiled for Win 2000 targets.
*/
class Mouse3DInput : public QObject, public QAbstractNativeEventFilter
{
Q_OBJECT
public:
Mouse3DInput(QWidget* widget);
~Mouse3DInput();
virtual bool nativeEventFilter(const QByteArray& eventType, void* msg, long* result);
static bool Is3dmouseAttached();
I3dMouseParam& MouseParams();
const I3dMouseParam& MouseParams() const;
virtual void Move3d(HANDLE device, std::vector<float>& motionData);
virtual void On3dmouseKeyDown(HANDLE device, int virtualKeyCode);
virtual void On3dmouseKeyUp(HANDLE device, int virtualKeyCode);
signals:
void Move3d(std::vector<float>& motionData);
void On3dmouseKeyDown(int virtualKeyCode);
void On3dmouseKeyUp(int virtualKeyCode);
private:
bool InitializeRawInput(HWND hwndTarget);
void OnRawInput(UINT nInputCode, HRAWINPUT hRawInput);
UINT GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader);
bool TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput);
void On3dmouseInput();
class TInputData
{
public:
TInputData() : fAxes(6) {}
bool IsZero() {
return (0.==fAxes[0] && 0.==fAxes[1] && 0.==fAxes[2] &&
0.==fAxes[3] && 0.==fAxes[4] && 0.==fAxes[5]);
}
int fTimeToLive; // For telling if the device was unplugged while sending data
bool fIsDirty;
std::vector<float> fAxes;
};
HWND fWindow;
// Data cache to handle multiple rawinput devices
std::map< HANDLE, TInputData> fDevice2Data;
std::map< HANDLE, unsigned long> fDevice2Keystate;
// 3dmouse parameters
MouseParameters f3dMouseParams; // Rotate, Pan Zoom etc.
// use to calculate distance traveled since last event
DWORD fLast3dmouseInputTime;
};
#endif
#include "MouseParameters.h"
MouseParameters::MouseParameters(): fNavigation(kObjectMode)
, fPivot(kAutoPivot)
, fPivotVisibility(kShowPivot)
, fIsLockHorizon(true)
, fIsPanZoom(true)
, fIsRotate(true)
, fSpeed(kLowSpeed)
{
}
MouseParameters::~MouseParameters()
{
}
bool MouseParameters::IsPanZoom() const
{
return fIsPanZoom;
}
bool MouseParameters::IsRotate() const
{
return fIsRotate;
}
MouseParameters::ESpeed MouseParameters::GetSpeed() const
{
return fSpeed;
}
void MouseParameters::SetPanZoom(bool isPanZoom)
{
fIsPanZoom=isPanZoom;
}
void MouseParameters::SetRotate(bool isRotate)
{
fIsRotate=isRotate;
}
void MouseParameters::SetSpeed(ESpeed speed)
{
fSpeed=speed;
}
MouseParameters::ENavigation MouseParameters::GetNavigationMode() const
{
return fNavigation;
}
MouseParameters::EPivot MouseParameters::GetPivotMode() const
{
return fPivot;
}
MouseParameters::EPivotVisibility MouseParameters::GetPivotVisibility() const
{
return fPivotVisibility;
}
bool MouseParameters::IsLockHorizon() const
{
return fIsLockHorizon;
}
void MouseParameters::SetLockHorizon(bool bOn)
{
fIsLockHorizon=bOn;
}
void MouseParameters::SetNavigationMode(ENavigation navigation)
{
fNavigation=navigation;
}
void MouseParameters::SetPivotMode(EPivot pivot)
{
if (fPivot!=kManualPivot || pivot!=kAutoPivotOverride)
fPivot = pivot;
}
void MouseParameters::SetPivotVisibility(EPivotVisibility visibility)
{
fPivotVisibility = visibility;
}
#ifndef T3D_MOUSE_PARAMS_H
#define T3D_MOUSE_PARAMS_H
#include "I3dMouseParams.h"
class MouseParameters : public I3dMouseParam
{
public:
MouseParameters();
~MouseParameters();
// I3dmouseSensor interface
bool IsPanZoom() const;
bool IsRotate() const;
ESpeed GetSpeed() const;
void SetPanZoom(bool isPanZoom);
void SetRotate(bool isRotate);
void SetSpeed(ESpeed speed);
// I3dmouseNavigation interface
ENavigation GetNavigationMode() const;
EPivot GetPivotMode() const;
EPivotVisibility GetPivotVisibility() const;
bool IsLockHorizon() const;
void SetLockHorizon(bool bOn);
void SetNavigationMode(ENavigation navigation);
void SetPivotMode(EPivot pivot);
void SetPivotVisibility(EPivotVisibility visibility);
private:
MouseParameters (const MouseParameters&);
const MouseParameters& operator =(const MouseParameters&);
ENavigation fNavigation;
EPivot fPivot;
EPivotVisibility fPivotVisibility;
bool fIsLockHorizon;
bool fIsPanZoom;
bool fIsRotate;
ESpeed fSpeed;
};
#endif
...@@ -237,4 +237,7 @@ ...@@ -237,4 +237,7 @@
<qresource prefix="/FirmwarePlugin/APM"> <qresource prefix="/FirmwarePlugin/APM">
<file alias="apm.pdef.xml">src/FirmwarePlugin/APM/apm.pdef.xml</file> <file alias="apm.pdef.xml">src/FirmwarePlugin/APM/apm.pdef.xml</file>
</qresource> </qresource>
<qresource prefix="/opengl">
<file>resources/opengl/buglist.json</file>
</qresource>
</RCC> </RCC>
...@@ -186,6 +186,7 @@ INCLUDEPATH += \ ...@@ -186,6 +186,7 @@ INCLUDEPATH += \
src/comm \ src/comm \
src/FlightDisplay \ src/FlightDisplay \
src/FlightMap \ src/FlightMap \
src/FlightMap/Widgets \
src/input \ src/input \
src/Joystick \ src/Joystick \
src/lib/qmapcontrol \ src/lib/qmapcontrol \
...@@ -247,10 +248,12 @@ HEADERS += \ ...@@ -247,10 +248,12 @@ HEADERS += \
src/comm/UDPLink.h \ src/comm/UDPLink.h \
src/FlightDisplay/FlightDisplayViewController.h \ src/FlightDisplay/FlightDisplayViewController.h \
src/FlightMap/FlightMapSettings.h \ src/FlightMap/FlightMapSettings.h \
src/FlightMap/Widgets/ValuesWidgetController.h \
src/GAudioOutput.h \ src/GAudioOutput.h \
src/HomePositionManager.h \ src/HomePositionManager.h \
src/Joystick/Joystick.h \ src/Joystick/Joystick.h \
src/Joystick/JoystickManager.h \ src/Joystick/JoystickManager.h \
src/JsonHelper.h \
src/LogCompressor.h \ src/LogCompressor.h \
src/MG.h \ src/MG.h \
src/MissionManager/MissionCommandList.h \ src/MissionManager/MissionCommandList.h \
...@@ -372,10 +375,12 @@ SOURCES += \ ...@@ -372,10 +375,12 @@ SOURCES += \
src/comm/UDPLink.cc \ src/comm/UDPLink.cc \
src/FlightDisplay/FlightDisplayViewController.cc \ src/FlightDisplay/FlightDisplayViewController.cc \
src/FlightMap/FlightMapSettings.cc \ src/FlightMap/FlightMapSettings.cc \
src/FlightMap/Widgets/ValuesWidgetController.cc \
src/GAudioOutput.cc \ src/GAudioOutput.cc \
src/HomePositionManager.cc \ src/HomePositionManager.cc \
src/Joystick/Joystick.cc \ src/Joystick/Joystick.cc \
src/Joystick/JoystickManager.cc \ src/Joystick/JoystickManager.cc \
src/JsonHelper.cc \
src/LogCompressor.cc \ src/LogCompressor.cc \
src/main.cc \ src/main.cc \
src/MissionManager/MissionCommandList.cc \ src/MissionManager/MissionCommandList.cc \
...@@ -675,6 +680,7 @@ INCLUDEPATH += \ ...@@ -675,6 +680,7 @@ INCLUDEPATH += \
HEADERS += \ HEADERS += \
src/FactSystem/Fact.h \ src/FactSystem/Fact.h \
src/FactSystem/FactGroup.h \
src/FactSystem/FactControls/FactPanelController.h \ src/FactSystem/FactControls/FactPanelController.h \
src/FactSystem/FactMetaData.h \ src/FactSystem/FactMetaData.h \
src/FactSystem/FactSystem.h \ src/FactSystem/FactSystem.h \
...@@ -684,6 +690,7 @@ HEADERS += \ ...@@ -684,6 +690,7 @@ HEADERS += \
SOURCES += \ SOURCES += \
src/FactSystem/Fact.cc \ src/FactSystem/Fact.cc \
src/FactSystem/FactGroup.cc \
src/FactSystem/FactControls/FactPanelController.cc \ src/FactSystem/FactControls/FactPanelController.cc \
src/FactSystem/FactMetaData.cc \ src/FactSystem/FactMetaData.cc \
src/FactSystem/FactSystem.cc \ src/FactSystem/FactSystem.cc \
......
...@@ -93,6 +93,8 @@ ...@@ -93,6 +93,8 @@
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewVideo.qml">src/FlightDisplay/FlightDisplayViewVideo.qml</file> <file alias="QGroundControl/FlightDisplay/FlightDisplayViewVideo.qml">src/FlightDisplay/FlightDisplayViewVideo.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewWidgets.qml">src/FlightDisplay/FlightDisplayViewWidgets.qml</file> <file alias="QGroundControl/FlightDisplay/FlightDisplayViewWidgets.qml">src/FlightDisplay/FlightDisplayViewWidgets.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</file> <file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</file>
<file alias="QGroundControl/FlightMap/qmldir">src/FlightMap/qmldir</file>
<file alias="QGroundControl/FlightMap/FlightMap.qml">src/FlightMap/FlightMap.qml</file> <file alias="QGroundControl/FlightMap/FlightMap.qml">src/FlightMap/FlightMap.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemIndicator.qml">src/FlightMap/MapItems/MissionItemIndicator.qml</file> <file alias="QGroundControl/FlightMap/MissionItemIndicator.qml">src/FlightMap/MapItems/MissionItemIndicator.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemView.qml">src/FlightMap/MapItems/MissionItemView.qml</file> <file alias="QGroundControl/FlightMap/MissionItemView.qml">src/FlightMap/MapItems/MissionItemView.qml</file>
...@@ -102,11 +104,13 @@ ...@@ -102,11 +104,13 @@
<file alias="QGroundControl/FlightMap/QGCAttitudeWidget.qml">src/FlightMap/Widgets/QGCAttitudeWidget.qml</file> <file alias="QGroundControl/FlightMap/QGCAttitudeWidget.qml">src/FlightMap/Widgets/QGCAttitudeWidget.qml</file>
<file alias="QGroundControl/FlightMap/QGCCompassWidget.qml">src/FlightMap/Widgets/QGCCompassWidget.qml</file> <file alias="QGroundControl/FlightMap/QGCCompassWidget.qml">src/FlightMap/Widgets/QGCCompassWidget.qml</file>
<file alias="QGroundControl/FlightMap/QGCInstrumentWidget.qml">src/FlightMap/Widgets/QGCInstrumentWidget.qml</file> <file alias="QGroundControl/FlightMap/QGCInstrumentWidget.qml">src/FlightMap/Widgets/QGCInstrumentWidget.qml</file>
<file alias="QGroundControl/FlightMap/QGCInstrumentWidgetAlternate.qml">src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml</file>
<file alias="QGroundControl/FlightMap/QGCPitchIndicator.qml">src/FlightMap/Widgets/QGCPitchIndicator.qml</file> <file alias="QGroundControl/FlightMap/QGCPitchIndicator.qml">src/FlightMap/Widgets/QGCPitchIndicator.qml</file>
<file alias="QGroundControl/FlightMap/QGCSlider.qml">src/FlightMap/Widgets/QGCSlider.qml</file> <file alias="QGroundControl/FlightMap/QGCSlider.qml">src/FlightMap/Widgets/QGCSlider.qml</file>
<file alias="QGroundControl/FlightMap/QGCVideoBackground.qml">src/FlightMap/QGCVideoBackground.qml</file> <file alias="QGroundControl/FlightMap/QGCVideoBackground.qml">src/FlightMap/QGCVideoBackground.qml</file>
<file alias="QGroundControl/FlightMap/qmldir">src/FlightMap/qmldir</file> <file alias="QGroundControl/FlightMap/ValuesWidget.qml">src/FlightMap/Widgets/ValuesWidget.qml</file>
<file alias="QGroundControl/FlightMap/VehicleMapItem.qml">src/FlightMap/MapItems/VehicleMapItem.qml</file> <file alias="QGroundControl/FlightMap/VehicleMapItem.qml">src/FlightMap/MapItems/VehicleMapItem.qml</file>
<file alias="QGroundControl/ScreenTools/qmldir">src/QmlControls/QGroundControl.ScreenTools.qmldir</file> <file alias="QGroundControl/ScreenTools/qmldir">src/QmlControls/QGroundControl.ScreenTools.qmldir</file>
<file alias="QGroundControl/ScreenTools/ScreenTools.qml">src/QmlControls/ScreenTools.qml</file> <file alias="QGroundControl/ScreenTools/ScreenTools.qml">src/QmlControls/ScreenTools.qml</file>
<file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file> <file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
...@@ -150,5 +154,8 @@ ...@@ -150,5 +154,8 @@
<file alias="PX4/MavCmdInfoCommon.json">src/FirmwarePlugin/PX4/MavCmdInfoCommon.json</file> <file alias="PX4/MavCmdInfoCommon.json">src/FirmwarePlugin/PX4/MavCmdInfoCommon.json</file>
<file alias="PX4/MavCmdInfoFixedWing.json">src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json</file> <file alias="PX4/MavCmdInfoFixedWing.json">src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json</file>
<file alias="PX4/MavCmdInfoMultiRotor.json">src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json</file> <file alias="PX4/MavCmdInfoMultiRotor.json">src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json</file>
<file alias="Vehicle/VehicleFact.json">src/Vehicle/VehicleFact.json</file>
<file alias="Vehicle/BatteryFact.json">src/Vehicle/BatteryFact.json</file>
<file alias="Vehicle/GPSFact.json">src/Vehicle/GPSFact.json</file>
</qresource> </qresource>
</RCC> </RCC>
{
"name": "QGroundControl OpenGL Driver Blacklist",
"version": "5.5",
"entries": [
{
"id": 1,
"description": "Desktop OpenGL is unreliable on some Intel HD laptops (QTBUG-43263, QTBUG-42240)",
"vendor_id": "0x8086",
"device_id": [ "0x0A16" ],
"os": {
"type": "win"
},
"driver_version": {
"op": "<=",
"value": "10.18.10.3277"
},
"features": [
"disable_desktopgl"
]
},
{
"id": 2,
"description": "Desktop OpenGL is unreliable on some Intel Mobile GMA Devices",
"vendor_id": "0x8086",
"device_id": [ "0x2972", "0x2973",
"0x2992", "0x2993",
"0x29A2", "0x29A3",
"0x2982", "0x2983",
"0x2A02", "0x2A03", "0x2A12", "0x2A13",
"0x2E42", "0x2E43", "0x2E92", "0x2E93",
"0x2E12", "0x2E13",
"0x2E32", "0x2E33",
"0x2E22", "0x2E23",
"0x2A42", "0x2A43",
"0x2E5B",
"0x8108", "0x8109",
"0x4102",
"0x0BE0", "0x0BE1", "0x0BE2", "0x0BE0",
"0x08C7", "0x08C8", "0x08C9", "0x08CA", "0x08CB", "0x08CC", "0x08CD", "0x08CE", "0x08CF"
],
"os": {
"type": "win"
},
"features": [
"disable_desktopgl"
]
}
]
}
...@@ -32,6 +32,8 @@ APMFlightModesComponentController::APMFlightModesComponentController(void) ...@@ -32,6 +32,8 @@ APMFlightModesComponentController::APMFlightModesComponentController(void)
: _activeFlightMode(0) : _activeFlightMode(0)
, _channelCount(Vehicle::cMaxRcChannels) , _channelCount(Vehicle::cMaxRcChannels)
, _fixedWing(_vehicle->vehicleType() == MAV_TYPE_FIXED_WING) , _fixedWing(_vehicle->vehicleType() == MAV_TYPE_FIXED_WING)
, _flightModeChannel(4)
{ {
QStringList usedParams; QStringList usedParams;
usedParams << QStringLiteral("FLTMODE1") << QStringLiteral("FLTMODE2") << QStringLiteral("FLTMODE3") usedParams << QStringLiteral("FLTMODE1") << QStringLiteral("FLTMODE2") << QStringLiteral("FLTMODE3")
...@@ -40,6 +42,10 @@ APMFlightModesComponentController::APMFlightModesComponentController(void) ...@@ -40,6 +42,10 @@ APMFlightModesComponentController::APMFlightModesComponentController(void)
return; return;
} }
if (parameterExists(FactSystem::defaultComponentId, QStringLiteral("FLTMODE_CH"))) {
_flightModeChannel = getParameterFact(FactSystem::defaultComponentId, QStringLiteral("FLTMODE_CH"))->rawValue().toInt();
}
_rgChannelOptionEnabled << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false); _rgChannelOptionEnabled << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false) << QVariant(false);
connect(_vehicle, &Vehicle::rcChannelsChanged, this, &APMFlightModesComponentController::_rcChannelsChanged); connect(_vehicle, &Vehicle::rcChannelsChanged, this, &APMFlightModesComponentController::_rcChannelsChanged);
...@@ -48,10 +54,12 @@ APMFlightModesComponentController::APMFlightModesComponentController(void) ...@@ -48,10 +54,12 @@ APMFlightModesComponentController::APMFlightModesComponentController(void)
/// Connected to Vehicle::rcChannelsChanged signal /// Connected to Vehicle::rcChannelsChanged signal
void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels]) void APMFlightModesComponentController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels])
{ {
Q_UNUSED(channelCount); if (_flightModeChannel > channelCount) {
return;
}
_activeFlightMode = 0; _activeFlightMode = 0;
int channelValue = pwmValues[4]; int channelValue = pwmValues[_flightModeChannel - 1];
if (channelValue != -1) { if (channelValue != -1) {
bool found = false; bool found = false;
int rgThreshold[] = { 1230, 1360, 1490, 1620, 1749 }; int rgThreshold[] = { 1230, 1360, 1490, 1620, 1749 };
......
...@@ -62,6 +62,7 @@ private: ...@@ -62,6 +62,7 @@ private:
int _channelCount; int _channelCount;
QVariantList _rgChannelOptionEnabled; QVariantList _rgChannelOptionEnabled;
bool _fixedWing; bool _fixedWing;
int _flightModeChannel;
}; };
#endif #endif
...@@ -102,6 +102,12 @@ ...@@ -102,6 +102,12 @@
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="OctoRotorXCoaxial" name="Octo Coax Wide">
<airframe id="12002" maintainer="Simon Wilks &lt;simon@uaventure.com&gt;" name="Steadidrone MAVRIK">
<maintainer>Simon Wilks &lt;simon@uaventure.com&gt;</maintainer>
<type>Octo Coax Wide</type>
</airframe>
</airframe_group>
<airframe_group image="OctoRotorPlus" name="Octorotor +"> <airframe_group image="OctoRotorPlus" name="Octorotor +">
<airframe id="9001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="Generic Octocopter + geometry"> <airframe id="9001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="Generic Octocopter + geometry">
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer> <maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
...@@ -349,9 +355,13 @@ ...@@ -349,9 +355,13 @@
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="VTOLDuoRotorTailSitter" name="VTOL Duo Tailsitter"> <airframe_group image="VTOLDuoRotorTailSitter" name="VTOL Duo Tailsitter">
<airframe id="13001" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Duorotor Tailsitter"> <airframe id="13001" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Caipiroshka Duo Tailsitter">
<maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer> <maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer>
<type>VTOL Duo Tailsitter</type> <type>VTOL Duo Tailsitter</type>
<output name="MAIN1">motor left</output>
<output name="MAIN2">motor right</output>
<output name="MAIN5">elevon left</output>
<output name="MAIN6">elevon right</output>
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="VTOLQuadRotorTailSitter" name="VTOL Quad Tailsitter"> <airframe_group image="VTOLQuadRotorTailSitter" name="VTOL Quad Tailsitter">
......
...@@ -35,6 +35,8 @@ Fact::Fact(QObject* parent) ...@@ -35,6 +35,8 @@ Fact::Fact(QObject* parent)
, _rawValue(0) , _rawValue(0)
, _type(FactMetaData::valueTypeInt32) , _type(FactMetaData::valueTypeInt32)
, _metaData(NULL) , _metaData(NULL)
, _sendValueChangedSignals(true)
, _deferredValueChangeSignal(false)
{ {
FactMetaData* metaData = new FactMetaData(_type, this); FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData); setMetaData(metaData);
...@@ -47,6 +49,8 @@ Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObjec ...@@ -47,6 +49,8 @@ Fact::Fact(int componentId, QString name, FactMetaData::ValueType_t type, QObjec
, _rawValue(0) , _rawValue(0)
, _type(type) , _type(type)
, _metaData(NULL) , _metaData(NULL)
, _sendValueChangedSignals(true)
, _deferredValueChangeSignal(false)
{ {
FactMetaData* metaData = new FactMetaData(_type, this); FactMetaData* metaData = new FactMetaData(_type, this);
setMetaData(metaData); setMetaData(metaData);
...@@ -60,11 +64,13 @@ Fact::Fact(const Fact& other, QObject* parent) ...@@ -60,11 +64,13 @@ Fact::Fact(const Fact& other, QObject* parent)
const Fact& Fact::operator=(const Fact& other) const Fact& Fact::operator=(const Fact& other)
{ {
_name = other._name; _name = other._name;
_componentId = other._componentId; _componentId = other._componentId;
_rawValue = other._rawValue; _rawValue = other._rawValue;
_type = other._type; _type = other._type;
_sendValueChangedSignals = other._sendValueChangedSignals;
_deferredValueChangeSignal = other._deferredValueChangeSignal;
if (_metaData && other._metaData) { if (_metaData && other._metaData) {
*_metaData = *other._metaData; *_metaData = *other._metaData;
} else { } else {
...@@ -82,7 +88,7 @@ void Fact::forceSetRawValue(const QVariant& value) ...@@ -82,7 +88,7 @@ void Fact::forceSetRawValue(const QVariant& value)
if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) { if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
_rawValue.setValue(typedValue); _rawValue.setValue(typedValue);
emit valueChanged(cookedValue()); _sendValueChangedSignal(cookedValue());
emit _containerRawValueChanged(rawValue()); emit _containerRawValueChanged(rawValue());
} }
} else { } else {
...@@ -99,7 +105,7 @@ void Fact::setRawValue(const QVariant& value) ...@@ -99,7 +105,7 @@ void Fact::setRawValue(const QVariant& value)
if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) { if (_metaData->convertAndValidateRaw(value, true /* convertOnly */, typedValue, errorString)) {
if (typedValue != _rawValue) { if (typedValue != _rawValue) {
_rawValue.setValue(typedValue); _rawValue.setValue(typedValue);
emit valueChanged(cookedValue()); _sendValueChangedSignal(cookedValue());
emit _containerRawValueChanged(rawValue()); emit _containerRawValueChanged(rawValue());
} }
} }
...@@ -141,7 +147,7 @@ void Fact::setEnumIndex(int index) ...@@ -141,7 +147,7 @@ void Fact::setEnumIndex(int index)
void Fact::_containerSetRawValue(const QVariant& value) void Fact::_containerSetRawValue(const QVariant& value)
{ {
_rawValue = value; _rawValue = value;
emit valueChanged(cookedValue()); _sendValueChangedSignal(cookedValue());
emit vehicleUpdated(_rawValue); emit vehicleUpdated(_rawValue);
} }
...@@ -492,3 +498,43 @@ bool Fact::rebootRequired(void) const ...@@ -492,3 +498,43 @@ bool Fact::rebootRequired(void) const
return false; return false;
} }
} }
void Fact::setSendValueChangedSignals (bool sendValueChangedSignals)
{
if (sendValueChangedSignals != _sendValueChangedSignals) {
_sendValueChangedSignals = sendValueChangedSignals;
emit sendValueChangedSignalsChanged(_sendValueChangedSignals);
}
}
void Fact::_sendValueChangedSignal(QVariant value)
{
if (_sendValueChangedSignals) {
emit valueChanged(value);
_deferredValueChangeSignal = false;
} else {
_deferredValueChangeSignal = true;
}
}
void Fact::sendDeferredValueChangedSignal(void)
{
if (_deferredValueChangeSignal) {
_deferredValueChangeSignal = false;
emit valueChanged(cookedValue());
}
}
QString Fact::enumOrValueString(void)
{
if (_metaData) {
if (_metaData->enumStrings().count()) {
return enumStringValue();
} else {
return cookedValueString();
}
} else {
qWarning() << "Meta data pointer missing";
}
return QString();
}
...@@ -72,7 +72,8 @@ public: ...@@ -72,7 +72,8 @@ public:
Q_PROPERTY(QString units READ cookedUnits CONSTANT) Q_PROPERTY(QString units READ cookedUnits CONSTANT)
Q_PROPERTY(QVariant value READ cookedValue WRITE setCookedValue NOTIFY valueChanged) Q_PROPERTY(QVariant value READ cookedValue WRITE setCookedValue NOTIFY valueChanged)
Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged)
Q_PROPERTY(QVariant valueString READ cookedValueString NOTIFY valueChanged) Q_PROPERTY(QString valueString READ cookedValueString NOTIFY valueChanged)
Q_PROPERTY(QString enumOrValueString READ enumOrValueString NOTIFY valueChanged)
/// 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
...@@ -111,12 +112,22 @@ public: ...@@ -111,12 +112,22 @@ public:
QString cookedValueString (void) const; QString cookedValueString (void) const;
bool valueEqualsDefault (void) const; bool valueEqualsDefault (void) const;
bool rebootRequired (void) const; bool rebootRequired (void) const;
QString enumOrValueString (void); // This is not const, since an unknown value can modify the enum lists
void setRawValue (const QVariant& value); void setRawValue (const QVariant& value);
void setCookedValue (const QVariant& value); void setCookedValue (const QVariant& value);
void setEnumIndex (int index); void setEnumIndex (int index);
void setEnumStringValue (const QString& value); void setEnumStringValue (const QString& value);
// The following methods allow you to defer sending of the valueChanged signals in order to implement
// rate limited signalling for ui performance. Used by FactGroup for example.
void setSendValueChangedSignals (bool sendValueChangedSignals);
bool sendValueChangedSignals (void) const { return _sendValueChangedSignals; }
bool deferredValueChangeSignal(void) const { return _deferredValueChangeSignal; }
void clearDeferredValueChangeSignal(void) { _deferredValueChangeSignal = false; }
void sendDeferredValueChangedSignal(void);
// C++ methods // C++ methods
/// Sets and sends new value to vehicle even if value is the same /// Sets and sends new value to vehicle even if value is the same
...@@ -129,12 +140,14 @@ public: ...@@ -129,12 +140,14 @@ public:
/// 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; }
signals: signals:
void bitmaskStringsChanged(void); void bitmaskStringsChanged(void);
void bitmaskValuesChanged(void); void bitmaskValuesChanged(void);
void enumStringsChanged(void); void enumStringsChanged(void);
void enumValuesChanged(void); void enumValuesChanged(void);
void sendValueChangedSignalsChanged(bool sendValueChangedSignals);
/// QObject Property System signal for value property changes /// QObject Property System signal for value property changes
/// ///
...@@ -151,12 +164,15 @@ signals: ...@@ -151,12 +164,15 @@ signals:
protected: protected:
QString _variantToString(const QVariant& variant) const; QString _variantToString(const QVariant& variant) const;
void _sendValueChangedSignal(QVariant value);
QString _name; QString _name;
int _componentId; int _componentId;
QVariant _rawValue; QVariant _rawValue;
FactMetaData::ValueType_t _type; FactMetaData::ValueType_t _type;
FactMetaData* _metaData; FactMetaData* _metaData;
bool _sendValueChangedSignals;
bool _deferredValueChangeSignal;
}; };
#endif #endif
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "FactGroup.h"
#include "JsonHelper.h"
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QDebug>
#include <QFile>
#include <QQmlEngine>
QGC_LOGGING_CATEGORY(FactGroupLog, "FactGroupLog")
const char* FactGroup::_decimalPlacesJsonKey = "decimalPlaces";
const char* FactGroup::_nameJsonKey = "name";
const char* FactGroup::_propertiesJsonKey = "properties";
const char* FactGroup::_versionJsonKey = "version";
const char* FactGroup::_typeJsonKey = "type";
const char* FactGroup::_shortDescriptionJsonKey = "shortDescription";
const char* FactGroup::_unitsJsonKey = "units";
FactGroup::FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent)
: QObject(parent)
, _updateRateMSecs(updateRateMsecs)
{
if (_updateRateMSecs > 0) {
connect(&_updateTimer, &QTimer::timeout, this, &FactGroup::_updateAllValues);
_updateTimer.setSingleShot(false);
_updateTimer.start(_updateRateMSecs);
}
_loadMetaData(metaDataFile);
}
Fact* FactGroup::getFact(const QString& name)
{
Fact* fact = NULL;
if (name.contains(".")) {
QStringList parts = name.split(".");
if (parts.count() != 2) {
qWarning() << "Only single level of hierarchy supported";
return NULL;
}
FactGroup * factGroup = getFactGroup(parts[0]);
if (!factGroup) {
qWarning() << "Unknown FactGroup" << parts[0];
return NULL;
}
return factGroup->getFact(parts[1]);
}
if (_nameToFactMap.contains(name)) {
fact = _nameToFactMap[name];
QQmlEngine::setObjectOwnership(fact, QQmlEngine::CppOwnership);
} else {
qWarning() << "Unknown Fact" << name;
}
return fact;
}
FactGroup* FactGroup::getFactGroup(const QString& name)
{
FactGroup* factGroup = NULL;
if (_nameToFactGroupMap.contains(name)) {
factGroup = _nameToFactGroupMap[name];
QQmlEngine::setObjectOwnership(factGroup, QQmlEngine::CppOwnership);
} else {
qWarning() << "Unknown FactGroup" << name;
}
return factGroup;
}
void FactGroup::_addFact(Fact* fact, const QString& name)
{
if (_nameToFactMap.contains(name)) {
qWarning() << "Duplicate Fact" << name;
return;
}
fact->setSendValueChangedSignals(_updateRateMSecs == 0);
if (_nameToFactMetaDataMap.contains(name)) {
fact->setMetaData(_nameToFactMetaDataMap[name]);
}
_nameToFactMap[name] = fact;
}
void FactGroup::_addFactGroup(FactGroup* factGroup, const QString& name)
{
if (_nameToFactGroupMap.contains(name)) {
qWarning() << "Duplicate FactGroup" << name;
return;
}
_nameToFactGroupMap[name] = factGroup;
}
void FactGroup::_updateAllValues(void)
{
foreach(Fact* fact, _nameToFactMap) {
fact->sendDeferredValueChangedSignal();
}
}
void FactGroup::_loadMetaData(const QString& jsonFilename)
{
if (jsonFilename.isEmpty()) {
return;
}
qCDebug(FactGroupLog) << "Loading" << jsonFilename;
QFile jsonFile(jsonFilename);
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Unable to open file" << jsonFilename << jsonFile.errorString();
return;
}
QByteArray bytes = jsonFile.readAll();
jsonFile.close();
QJsonParseError jsonParseError;
QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError);
if (jsonParseError.error != QJsonParseError::NoError) {
qWarning() << "Unable to open json document" << jsonFilename << jsonParseError.errorString();
return;
}
QJsonObject json = doc.object();
int version = json.value(_versionJsonKey).toInt();
if (version != 1) {
qWarning() << "Invalid version" << version;
return;
}
QJsonValue jsonValue = json.value(_propertiesJsonKey);
if (!jsonValue.isArray()) {
qWarning() << "properties object not array";
return;
}
QJsonArray jsonArray = jsonValue.toArray();
foreach(QJsonValue property, jsonArray) {
if (!property.isObject()) {
qWarning() << "properties object should contain only objects";
return;
}
QJsonObject jsonObject = property.toObject();
// Make sure we have the required keys
QString errorString;
QStringList requiredKeys;
requiredKeys << _nameJsonKey << _decimalPlacesJsonKey << _typeJsonKey << _shortDescriptionJsonKey;
if (!JsonHelper::validateRequiredKeys(jsonObject, requiredKeys, errorString)) {
qWarning() << errorString;
return;
}
// Validate key types
QStringList keys;
QList<QJsonValue::Type> types;
keys << _nameJsonKey << _decimalPlacesJsonKey;
types << QJsonValue::String << QJsonValue::Double;
if (!JsonHelper::validateKeyTypes(jsonObject, keys, types, errorString)) {
qWarning() << errorString;
return;
}
QString name = jsonObject.value(_nameJsonKey).toString();
if (_nameToFactMetaDataMap.contains(name)) {
qWarning() << "Duplicate property name" << name;
continue;
}
bool unknownType;
FactMetaData::ValueType_t type = FactMetaData::stringToType(jsonObject.value(_typeJsonKey).toString(), unknownType);
if (unknownType) {
qWarning() << "Unknown type" << jsonObject.value(_typeJsonKey).toString();
return;
}
QStringList enumValues, enumStrings;
if (!JsonHelper::parseEnum(jsonObject, enumStrings, enumValues, errorString)) {
qWarning() << errorString;
return;
}
FactMetaData* metaData = new FactMetaData(type, this);
metaData->setDecimalPlaces(jsonObject.value(_decimalPlacesJsonKey).toInt());
metaData->setShortDescription(jsonObject.value(_shortDescriptionJsonKey).toString());
metaData->setRawUnits(jsonObject.value(_unitsJsonKey).toString());
for (int i=0; i<enumValues.count(); i++) {
QVariant enumVariant;
QString errorString;
if (metaData->convertAndValidateRaw(enumValues[i], false /* validate */, enumVariant, errorString)) {
metaData->addEnumInfo(enumStrings[i], enumVariant);
} else {
qWarning() << "Invalid enum value, name:" << metaData->name()
<< " type:" << metaData->type() << " value:" << enumValues[i]
<< " error:" << errorString;
delete metaData;
return;
}
}
_nameToFactMetaDataMap[name] = metaData;
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef FactGroup_H
#define FactGroup_H
#include "Fact.h"
#include "QGCLoggingCategory.h"
#include <QStringList>
#include <QMap>
#include <QTimer>
Q_DECLARE_LOGGING_CATEGORY(VehicleLog)
/// Used to group Facts together into an object hierarachy.
class FactGroup : public QObject
{
Q_OBJECT
public:
FactGroup(int updateRateMsecs, const QString& metaDataFile, QObject* parent = NULL);
Q_PROPERTY(QStringList factNames READ factNames CONSTANT)
Q_PROPERTY(QStringList factGroupNames READ factGroupNames CONSTANT)
/// @return Fact for specified name, NULL if not found
Q_INVOKABLE Fact* getFact(const QString& name);
/// @return FactGroup for specified name, NULL if not found
Q_INVOKABLE FactGroup* getFactGroup(const QString& name);
QStringList factNames(void) const { return _nameToFactMap.keys(); }
QStringList factGroupNames(void) const { return _nameToFactGroupMap.keys(); }
protected:
void _addFact(Fact* fact, const QString& name);
void _addFactGroup(FactGroup* factGroup, const QString& name);
int _updateRateMSecs; ///< Update rate for Fact::valueChanged signals, 0: immediate update
private slots:
void _updateAllValues(void);
private:
void _loadMetaData(const QString& filename);
QMap<QString, Fact*> _nameToFactMap;
QMap<QString, FactGroup*> _nameToFactGroupMap;
QMap<QString, FactMetaData*> _nameToFactMetaDataMap;
QTimer _updateTimer;
static const char* _propertiesJsonKey;
static const char* _nameJsonKey;
static const char* _decimalPlacesJsonKey;
static const char* _typeJsonKey;
static const char* _versionJsonKey;
static const char* _shortDescriptionJsonKey;
static const char* _unitsJsonKey;
};
#endif
...@@ -398,3 +398,39 @@ void FactMetaData::setRawUnits(const QString& rawUnits) ...@@ -398,3 +398,39 @@ void FactMetaData::setRawUnits(const QString& rawUnits)
_setBuiltInTranslator(); _setBuiltInTranslator();
} }
FactMetaData::ValueType_t FactMetaData::stringToType(const QString& typeString, bool& unknownType)
{
QStringList knownTypeStrings;
QList<ValueType_t> knownTypes;
unknownType = false;
knownTypeStrings << QStringLiteral("Uint8")
<< QStringLiteral("Int8")
<< QStringLiteral("Uint16")
<< QStringLiteral("Int16")
<< QStringLiteral("Uint32")
<< QStringLiteral("Int32")
<< QStringLiteral("Float")
<< QStringLiteral("Double");
knownTypes << valueTypeUint8
<< valueTypeInt8
<< valueTypeUint16
<< valueTypeInt16
<< valueTypeUint32
<< valueTypeInt32
<< valueTypeFloat
<< valueTypeDouble;
for (int i=0; i<knownTypeStrings.count(); i++) {
if (knownTypeStrings[i].compare(typeString, Qt::CaseInsensitive) == 0) {
return knownTypes[i];
}
}
unknownType = true;
return valueTypeDouble;
}
...@@ -120,6 +120,8 @@ public: ...@@ -120,6 +120,8 @@ public:
static const int defaultDecimalPlaces = 3; static const int defaultDecimalPlaces = 3;
static ValueType_t stringToType(const QString& typeString, bool& unknownType);
private: private:
QVariant _minForType(void) const; QVariant _minForType(void) const;
QVariant _maxForType(void) const; QVariant _maxForType(void) const;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
/// @author Don Gagne <don@thegagnes.com> /// @author Don Gagne <don@thegagnes.com>
#include "FactSystem.h" #include "FactSystem.h"
#include "FactGroup.h"
#include "FactPanelController.h" #include "FactPanelController.h"
#include <QtQml> #include <QtQml>
...@@ -41,6 +42,8 @@ void FactSystem::setToolbox(QGCToolbox *toolbox) ...@@ -41,6 +42,8 @@ void FactSystem::setToolbox(QGCToolbox *toolbox)
{ {
QGCTool::setToolbox(toolbox); QGCTool::setToolbox(toolbox);
qmlRegisterType<Fact>(_factSystemQmlUri, 1, 0, "Fact"); qmlRegisterType<Fact> (_factSystemQmlUri, 1, 0, "Fact");
qmlRegisterType<FactPanelController>(_factSystemQmlUri, 1, 0, "FactPanelController"); qmlRegisterType<FactPanelController>(_factSystemQmlUri, 1, 0, "FactPanelController");
qmlRegisterUncreatableType<FactGroup>(_factSystemQmlUri, 1, 0, "FactGroup", "ReferenceOnly");
} }
...@@ -50,8 +50,10 @@ ParameterLoader::ParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, Q ...@@ -50,8 +50,10 @@ ParameterLoader::ParameterLoader(AutoPilotPlugin* autopilot, Vehicle* vehicle, Q
, _autopilot(autopilot) , _autopilot(autopilot)
, _vehicle(vehicle) , _vehicle(vehicle)
, _mavlink(qgcApp()->toolbox()->mavlinkProtocol()) , _mavlink(qgcApp()->toolbox()->mavlinkProtocol())
, _dedicatedLink(_vehicle->priorityLink())
, _parametersReady(false) , _parametersReady(false)
, _initialLoadComplete(false) , _initialLoadComplete(false)
, _saveRequired(false)
, _defaultComponentId(FactSystem::defaultComponentId) , _defaultComponentId(FactSystem::defaultComponentId)
, _totalParamCount(0) , _totalParamCount(0)
{ {
...@@ -290,6 +292,7 @@ void ParameterLoader::_valueUpdated(const QVariant& value) ...@@ -290,6 +292,7 @@ void ParameterLoader::_valueUpdated(const QVariant& value)
_waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry _waitingWriteParamNameMap[componentId].remove(name); // Remove any old entry
_waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count _waitingWriteParamNameMap[componentId][name] = 0; // Add new entry and set retry count
_waitingParamTimeoutTimer.start(); _waitingParamTimeoutTimer.start();
_saveRequired = true;
_dataMutex.unlock(); _dataMutex.unlock();
...@@ -327,7 +330,7 @@ void ParameterLoader::refreshAllParameters(uint8_t componentID) ...@@ -327,7 +330,7 @@ void ParameterLoader::refreshAllParameters(uint8_t componentID)
mavlink_message_t msg; mavlink_message_t msg;
mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, _vehicle->id(), componentID); mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, _vehicle->id(), componentID);
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), msg); _vehicle->sendMessageOnLink(_dedicatedLink, msg);
QString what = (componentID == MAV_COMP_ID_ALL) ? "MAV_COMP_ID_ALL" : QString::number(componentID); QString what = (componentID == MAV_COMP_ID_ALL) ? "MAV_COMP_ID_ALL" : QString::number(componentID);
qCDebug(ParameterLoaderLog) << "Request to refresh all parameters for component ID:" << what; qCDebug(ParameterLoaderLog) << "Request to refresh all parameters for component ID:" << what;
...@@ -529,7 +532,7 @@ void ParameterLoader::_tryCacheLookup() ...@@ -529,7 +532,7 @@ void ParameterLoader::_tryCacheLookup()
mavlink_message_t msg; mavlink_message_t msg;
mavlink_msg_param_request_read_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, _vehicle->id(), MAV_COMP_ID_ALL, "_HASH_CHECK", -1); mavlink_msg_param_request_read_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, _vehicle->id(), MAV_COMP_ID_ALL, "_HASH_CHECK", -1);
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), msg); _vehicle->sendMessageOnLink(_dedicatedLink, msg);
} }
void ParameterLoader::_readParameterRaw(int componentId, const QString& paramName, int paramIndex) void ParameterLoader::_readParameterRaw(int componentId, const QString& paramName, int paramIndex)
...@@ -545,7 +548,7 @@ void ParameterLoader::_readParameterRaw(int componentId, const QString& paramNam ...@@ -545,7 +548,7 @@ void ParameterLoader::_readParameterRaw(int componentId, const QString& paramNam
componentId, // Target component id componentId, // Target component id
fixedParamName, // Named parameter being requested fixedParamName, // Named parameter being requested
paramIndex); // Parameter index being requested, -1 for named paramIndex); // Parameter index being requested, -1 for named
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), msg); _vehicle->sendMessageOnLink(_dedicatedLink, msg);
} }
void ParameterLoader::_writeParameterRaw(int componentId, const QString& paramName, const QVariant& value) void ParameterLoader::_writeParameterRaw(int componentId, const QString& paramName, const QVariant& value)
...@@ -598,7 +601,7 @@ void ParameterLoader::_writeParameterRaw(int componentId, const QString& paramNa ...@@ -598,7 +601,7 @@ void ParameterLoader::_writeParameterRaw(int componentId, const QString& paramNa
mavlink_message_t msg; mavlink_message_t msg;
mavlink_msg_param_set_encode(_mavlink->getSystemId(), _mavlink->getComponentId(), &msg, &p); mavlink_msg_param_set_encode(_mavlink->getSystemId(), _mavlink->getComponentId(), &msg, &p);
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), msg); _vehicle->sendMessageOnLink(_dedicatedLink, msg);
} }
void ParameterLoader::_writeLocalParamCache() void ParameterLoader::_writeLocalParamCache()
...@@ -672,13 +675,16 @@ void ParameterLoader::_tryCacheHashLoad(int uasId, QVariant hash_value) ...@@ -672,13 +675,16 @@ void ParameterLoader::_tryCacheHashLoad(int uasId, QVariant hash_value)
void ParameterLoader::_saveToEEPROM(void) void ParameterLoader::_saveToEEPROM(void)
{ {
if (_vehicle->firmwarePlugin()->isCapable(FirmwarePlugin::MavCmdPreflightStorageCapability)) { if (_saveRequired) {
mavlink_message_t msg; _saveRequired = false;
mavlink_msg_command_long_pack(_mavlink->getSystemId(), _mavlink->getComponentId(), &msg, _vehicle->id(), 0, MAV_CMD_PREFLIGHT_STORAGE, 1, 1, -1, -1, -1, 0, 0, 0); if (_vehicle->firmwarePlugin()->isCapable(FirmwarePlugin::MavCmdPreflightStorageCapability)) {
_vehicle->sendMessageOnLink(_vehicle->priorityLink(), msg); mavlink_message_t msg;
qCDebug(ParameterLoaderLog) << "_saveToEEPROM"; mavlink_msg_command_long_pack(_mavlink->getSystemId(), _mavlink->getComponentId(), &msg, _vehicle->id(), 0, MAV_CMD_PREFLIGHT_STORAGE, 1, 1, -1, -1, -1, 0, 0, 0);
} else { _vehicle->sendMessageOnLink(_dedicatedLink, msg);
qCDebug(ParameterLoaderLog) << "_saveToEEPROM skipped due to FirmwarePlugin::isCapable"; qCDebug(ParameterLoaderLog) << "_saveToEEPROM";
} else {
qCDebug(ParameterLoaderLog) << "_saveToEEPROM skipped due to FirmwarePlugin::isCapable";
}
} }
} }
......
...@@ -127,6 +127,8 @@ private: ...@@ -127,6 +127,8 @@ private:
FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType); FactMetaData::ValueType_t _mavTypeToFactType(MAV_PARAM_TYPE mavType);
void _saveToEEPROM(void); void _saveToEEPROM(void);
void _checkInitialLoadComplete(void); void _checkInitialLoadComplete(void);
LinkInterface* _dedicatedLink; ///< Parameter protocol stays on this link
/// First mapping is by component id /// First mapping is by component id
/// Second mapping is parameter name, to Fact* in QVariant /// Second mapping is parameter name, to Fact* in QVariant
...@@ -139,6 +141,7 @@ private: ...@@ -139,6 +141,7 @@ private:
bool _parametersReady; ///< true: full set of parameters correctly loaded bool _parametersReady; ///< true: full set of parameters correctly loaded
bool _initialLoadComplete; ///< true: Initial load of all parameters complete, whether succesful or not bool _initialLoadComplete; ///< true: Initial load of all parameters complete, whether succesful or not
bool _saveRequired; ///< true: _saveToEEPROM should be called
int _defaultComponentId; int _defaultComponentId;
QString _defaultComponentIdParam; QString _defaultComponentIdParam;
......
...@@ -483,8 +483,8 @@ QList<MAV_CMD> APMFirmwarePlugin::supportedMissionCommands(void) ...@@ -483,8 +483,8 @@ QList<MAV_CMD> APMFirmwarePlugin::supportedMissionCommands(void)
{ {
QList<MAV_CMD> list; QList<MAV_CMD> list;
list << MAV_CMD_NAV_WAYPOINT list << MAV_CMD_NAV_WAYPOINT << MAV_CMD_NAV_SPLINE_WAYPOINT
<< MAV_CMD_NAV_LOITER_UNLIM << MAV_CMD_NAV_LOITER_TURNS << MAV_CMD_NAV_LOITER_TIME << MAV_CMD_NAV_LOITER_UNLIM << MAV_CMD_NAV_LOITER_TURNS << MAV_CMD_NAV_LOITER_TIME << MAV_CMD_NAV_LOITER_TO_ALT
<< MAV_CMD_NAV_RETURN_TO_LAUNCH << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF << MAV_CMD_NAV_RETURN_TO_LAUNCH << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF
<< MAV_CMD_NAV_GUIDED_ENABLE << MAV_CMD_NAV_GUIDED_ENABLE
<< MAV_CMD_DO_SET_ROI << MAV_CMD_DO_GUIDED_LIMITS << MAV_CMD_DO_JUMP << MAV_CMD_DO_CHANGE_SPEED << MAV_CMD_DO_SET_CAM_TRIGG_DIST << MAV_CMD_DO_SET_ROI << MAV_CMD_DO_GUIDED_LIMITS << MAV_CMD_DO_JUMP << MAV_CMD_DO_CHANGE_SPEED << MAV_CMD_DO_SET_CAM_TRIGG_DIST
...@@ -492,7 +492,13 @@ QList<MAV_CMD> APMFirmwarePlugin::supportedMissionCommands(void) ...@@ -492,7 +492,13 @@ QList<MAV_CMD> APMFirmwarePlugin::supportedMissionCommands(void)
<< MAV_CMD_DO_SET_SERVO << MAV_CMD_DO_REPEAT_SERVO << MAV_CMD_DO_SET_SERVO << MAV_CMD_DO_REPEAT_SERVO
<< MAV_CMD_DO_DIGICAM_CONFIGURE << MAV_CMD_DO_DIGICAM_CONTROL << MAV_CMD_DO_DIGICAM_CONFIGURE << MAV_CMD_DO_DIGICAM_CONTROL
<< MAV_CMD_DO_MOUNT_CONTROL << MAV_CMD_DO_MOUNT_CONTROL
<< MAV_CMD_CONDITION_DELAY << MAV_CMD_CONDITION_CHANGE_ALT << MAV_CMD_CONDITION_DISTANCE << MAV_CMD_CONDITION_YAW; << MAV_CMD_DO_SET_HOME
<< MAV_CMD_DO_LAND_START
<< MAV_CMD_DO_FENCE_ENABLE << MAV_CMD_DO_PARACHUTE << MAV_CMD_DO_INVERTED_FLIGHT << MAV_CMD_DO_GRIPPER
<< MAV_CMD_CONDITION_DELAY << MAV_CMD_CONDITION_CHANGE_ALT << MAV_CMD_CONDITION_DISTANCE << MAV_CMD_CONDITION_YAW
<< MAV_CMD_NAV_VTOL_TAKEOFF << MAV_CMD_NAV_VTOL_LAND
<< MAV_CMD_NAV_CONTINUE_AND_CHANGE_ALT;
return list; return list;
} }
......
...@@ -2,5 +2,44 @@ ...@@ -2,5 +2,44 @@
"version": 1, "version": 1,
"mavCmdInfo": [ "mavCmdInfo": [
{
"id": 22,
"rawName": "MAV_CMD_NAV_TAKEOFF",
"friendlyName": "Takeoff",
"description": "Take off from the ground.",
"specifiesCoordinate": false,
"friendlyEdit": true,
"category": "Basic",
"param1": {
"label": "Pitch:",
"units": "radians",
"default": 0.26179939,
"decimalPlaces": 2
}
},
{
"id": 84,
"rawName": "MAV_CMD_NAV_VTOL_TAKEOFF",
"friendlyName": "VTOL takeoff",
"description": "Takeoff from ground using VTOL mode.",
"specifiesCoordinate": true,
"friendlyEdit": true,
"category": "VTOL"
},
{
"id": 85,
"rawName": "MAV_CMD_NAV_VTOL_LAND",
"friendlyName": "VTOL land",
"description": "Land using VTOL mode.",
"specifiesCoordinate": true,
"friendlyEdit": true,
"category": "VTOL",
"param7": {
"label": "Altitude:",
"units": "meters",
"default": 0.0,
"decimalPlaces": 2
}
}
] ]
} }
...@@ -2,20 +2,5 @@ ...@@ -2,20 +2,5 @@
"version": 1, "version": 1,
"mavCmdInfo": [ "mavCmdInfo": [
{
"id": 22,
"rawName": "MAV_CMD_NAV_TAKEOFF",
"friendlyName": "Takeoff",
"description": "Take off from the ground.",
"specifiesCoordinate": true,
"friendlyEdit": true,
"category": "Basic",
"param1": {
"label": "Pitch:",
"units": "radians",
"default": 0.26179939,
"decimalPlaces": 2
}
}
] ]
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"rawName": "MAV_CMD_NAV_TAKEOFF", "rawName": "MAV_CMD_NAV_TAKEOFF",
"friendlyName": "Takeoff", "friendlyName": "Takeoff",
"description": "Take off from the ground.", "description": "Take off from the ground.",
"specifiesCoordinate": true, "specifiesCoordinate": false,
"friendlyEdit": true, "friendlyEdit": true,
"category": "Basic" "category": "Basic"
}, },
......
...@@ -68,7 +68,7 @@ struct Modes2Name { ...@@ -68,7 +68,7 @@ struct Modes2Name {
}; };
/// Tranlates from PX4 custom modes to flight mode names /// Tranlates from PX4 custom modes to flight mode names
// FIXME: Doens't handle fixed-wing/multi-rotor name differences
static const struct Modes2Name rgModes2Name[] = { static const struct Modes2Name rgModes2Name[] = {
{ PX4_CUSTOM_MAIN_MODE_MANUAL, 0, "Manual", true }, { PX4_CUSTOM_MAIN_MODE_MANUAL, 0, "Manual", true },
{ PX4_CUSTOM_MAIN_MODE_ACRO, 0, "Acro", true }, { PX4_CUSTOM_MAIN_MODE_ACRO, 0, "Acro", true },
...@@ -77,12 +77,12 @@ static const struct Modes2Name rgModes2Name[] = { ...@@ -77,12 +77,12 @@ static const struct Modes2Name rgModes2Name[] = {
{ PX4_CUSTOM_MAIN_MODE_ALTCTL, 0, "Altitude Control", true }, { PX4_CUSTOM_MAIN_MODE_ALTCTL, 0, "Altitude Control", true },
{ PX4_CUSTOM_MAIN_MODE_POSCTL, 0, "Position Control", true }, { PX4_CUSTOM_MAIN_MODE_POSCTL, 0, "Position Control", true },
{ PX4_CUSTOM_MAIN_MODE_OFFBOARD, 0, "Offboard Control", true }, { PX4_CUSTOM_MAIN_MODE_OFFBOARD, 0, "Offboard Control", true },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_READY, "Auto Ready", false }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_READY, "Auto: Ready", false },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF, "Taking Off", false }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_TAKEOFF, "Auto: Takeoff", false },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_LOITER, "Loiter", true }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_LOITER, "Auto: Pause", true },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_MISSION, "Mission", true }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_MISSION, "Auto: Mission", true },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_RTL, "Return To Land", true }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_RTL, "Auto: Return To Land", true },
{ PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_LAND, "Landing", false }, { PX4_CUSTOM_MAIN_MODE_AUTO, PX4_CUSTOM_SUB_MODE_AUTO_LAND, "Auto: Landing", false },
}; };
...@@ -215,14 +215,15 @@ QList<MAV_CMD> PX4FirmwarePlugin::supportedMissionCommands(void) ...@@ -215,14 +215,15 @@ QList<MAV_CMD> PX4FirmwarePlugin::supportedMissionCommands(void)
list << MAV_CMD_NAV_WAYPOINT list << MAV_CMD_NAV_WAYPOINT
<< MAV_CMD_NAV_LOITER_UNLIM << MAV_CMD_NAV_LOITER_TIME << MAV_CMD_NAV_LOITER_UNLIM << MAV_CMD_NAV_LOITER_TIME
<< MAV_CMD_NAV_RETURN_TO_LAUNCH << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF << MAV_CMD_NAV_LAND << MAV_CMD_NAV_TAKEOFF
<< MAV_CMD_NAV_ROI << MAV_CMD_NAV_ROI
<< MAV_CMD_DO_JUMP << MAV_CMD_DO_JUMP
<< MAV_CMD_CONDITION_DELAY << MAV_CMD_CONDITION_DELAY
<< MAV_CMD_DO_VTOL_TRANSITION << MAV_CMD_DO_VTOL_TRANSITION << MAV_CMD_NAV_VTOL_TAKEOFF << MAV_CMD_NAV_VTOL_LAND
<< MAV_CMD_DO_DIGICAM_CONTROL << MAV_CMD_DO_DIGICAM_CONTROL
<< MAV_CMD_DO_SET_SERVO << MAV_CMD_DO_SET_SERVO
<< MAV_CMD_DO_CHANGE_SPEED; << MAV_CMD_DO_CHANGE_SPEED
<< MAV_CMD_NAV_PATHPLANNING;
return list; return list;
} }
......
...@@ -198,30 +198,9 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void) ...@@ -198,30 +198,9 @@ void PX4ParameterMetaData::_loadParameterFactMetaData(void)
qCDebug(PX4ParameterMetaDataLog) << "Found parameter name:" << name << " type:" << type << " default:" << strDefault; qCDebug(PX4ParameterMetaDataLog) << "Found parameter name:" << name << " type:" << type << " default:" << strDefault;
// Convert type from string to FactMetaData::ValueType_t // Convert type from string to FactMetaData::ValueType_t
bool unknownType;
struct String2Type { FactMetaData::ValueType_t foundType = FactMetaData::stringToType(type, unknownType);
const char* strType; if (unknownType) {
FactMetaData::ValueType_t type;
};
static const struct String2Type rgString2Type[] = {
{ "FLOAT", FactMetaData::valueTypeFloat },
{ "INT32", FactMetaData::valueTypeInt32 },
};
static const size_t crgString2Type = sizeof(rgString2Type) / sizeof(rgString2Type[0]);
bool found = false;
FactMetaData::ValueType_t foundType;
for (size_t i=0; i<crgString2Type; i++) {
const struct String2Type* info = &rgString2Type[i];
if (type == info->strType) {
found = true;
foundType = info->type;
break;
}
}
if (!found) {
qWarning() << "Parameter meta data with bad type:" << type << " name:" << name; qWarning() << "Parameter meta data with bad type:" << type << " name:" << name;
return; return;
} }
......
This diff is collapsed.
...@@ -44,6 +44,9 @@ FlightMap { ...@@ -44,6 +44,9 @@ FlightMap {
property bool _activeVehicleCoordinateValid: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.coordinateValid : false property bool _activeVehicleCoordinateValid: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.coordinateValid : false
property var activeVehicleCoordinate: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.coordinate : QtPositioning.coordinate() property var activeVehicleCoordinate: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.coordinate : QtPositioning.coordinate()
Component.onCompleted: QGroundControl.flightMapPosition = center
onCenterChanged: QGroundControl.flightMapPosition = center
onActiveVehicleCoordinateChanged: { onActiveVehicleCoordinateChanged: {
if (_followVehicle && _activeVehicleCoordinateValid && activeVehicleCoordinate.isValid) { if (_followVehicle && _activeVehicleCoordinateValid && activeVehicleCoordinate.isValid) {
_initialMapPositionSet = true _initialMapPositionSet = true
...@@ -62,7 +65,7 @@ FlightMap { ...@@ -62,7 +65,7 @@ FlightMap {
delegate: delegate:
MapPolyline { MapPolyline {
line.width: 3 line.width: 3
line.color: "orange" line.color: "red"
z: QGroundControl.zOrderMapItems - 1 z: QGroundControl.zOrderMapItems - 1
path: [ path: [
{ latitude: object.coordinate1.latitude, longitude: object.coordinate1.longitude }, { latitude: object.coordinate1.latitude, longitude: object.coordinate1.longitude },
......
...@@ -36,10 +36,10 @@ import QGroundControl.Vehicle 1.0 ...@@ -36,10 +36,10 @@ import QGroundControl.Vehicle 1.0
import QGroundControl.FlightMap 1.0 import QGroundControl.FlightMap 1.0
Item { Item {
id: _root
readonly property string _InstrumentVisibleKey: "IsInstrumentPanelVisible" property var _activeVehicle: multiVehicleManager.activeVehicle
property bool _isSatellite: _mainIsMap ? _flightMap ? _flightMap.isSatelliteMap : true : true
property bool _isInstrumentVisible: QGroundControl.loadBoolGlobalSetting(_InstrumentVisibleKey, true)
QGCMapPalette { id: mapPal; lightColors: !isBackgroundDark } QGCMapPalette { id: mapPal; lightColors: !isBackgroundDark }
...@@ -95,99 +95,46 @@ Item { ...@@ -95,99 +95,46 @@ Item {
anchors.margins: ScreenTools.defaultFontPixelHeight anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: _isInstrumentVisible && !QGroundControl.virtualTabletJoystick visible: !QGroundControl.virtualTabletJoystick
size: getGadgetWidth() size: getGadgetWidth()
active: _activeVehicle != null active: _activeVehicle != null
heading: _heading heading: _heading
rollAngle: _roll rollAngle: _roll
pitchAngle: _pitch pitchAngle: _pitch
altitude: _altitudeWGS84 groundSpeedFact: _groundSpeedFact
groundSpeed: _groundSpeed airSpeedFact: _airSpeedFact
airSpeed: _airSpeed isSatellite: _isSatellite
isSatellite: _mainIsMap ? _flightMap ? _flightMap.isSatelliteMap : true : true
z: QGroundControl.zOrderWidgets z: QGroundControl.zOrderWidgets
onClicked: { qgcView: parent.parent.qgcView
_isInstrumentVisible = false maxHeight: parent.height - (ScreenTools.defaultFontPixelHeight * 2)
QGroundControl.saveBoolGlobalSetting(_InstrumentVisibleKey, false)
}
} }
//-- Alternate Instrument Panel QGCInstrumentWidgetAlternate {
Rectangle { id: instrumentGadgetAlternate
visible: QGroundControl.virtualTabletJoystick anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.margins: ScreenTools.defaultFontPixelHeight anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom visible: QGroundControl.virtualTabletJoystick
width: pipSize width: getGadgetWidth()
height: pipSize * (9/16) active: _activeVehicle != null
color: Qt.rgba(0,0,0,0.75) heading: _heading
Column { rollAngle: _roll
id: instruments pitchAngle: _pitch
width: parent.width groundSpeedFact: _groundSpeedFact
spacing: ScreenTools.defaultFontPixelSize * 0.33 airSpeedFact: _airSpeedFact
anchors.verticalCenter: parent.verticalCenter isSatellite: _isSatellite
QGCLabel { z: QGroundControl.zOrderWidgets
text: "Altitude (m)"
font.pixelSize: ScreenTools.defaultFontPixelSize * 0.75
width: parent.width
height: ScreenTools.defaultFontPixelSize * 0.75
color: "white"
horizontalAlignment: TextEdit.AlignHCenter
}
QGCLabel {
text: _altitudeWGS84 < 10000 ? _altitudeWGS84.toFixed(1) : _altitudeWGS84.toFixed(0)
font.pixelSize: ScreenTools.defaultFontPixelSize * 1.5
font.weight: Font.DemiBold
width: parent.width
color: "white"
horizontalAlignment: TextEdit.AlignHCenter
}
QGCLabel {
text: "Ground Speed (km/h)"
font.pixelSize: ScreenTools.defaultFontPixelSize * 0.75
width: parent.width
height: ScreenTools.defaultFontPixelSize * 0.75
color: "white"
horizontalAlignment: TextEdit.AlignHCenter
}
QGCLabel {
text: (_groundSpeed * 3.6).toFixed(1)
font.pixelSize: ScreenTools.defaultFontPixelSize
font.weight: Font.DemiBold
width: parent.width
color: "white"
horizontalAlignment: TextEdit.AlignHCenter
}
}
} }
//-- Show (Hidden) Instrument Panel ValuesWidget {
Rectangle { anchors.topMargin: ScreenTools.defaultFontPixelHeight
id: openButton anchors.top: instrumentGadgetAlternate.bottom
anchors.right: parent.right anchors.left: instrumentGadgetAlternate.left
anchors.bottom: parent.bottom width: getGadgetWidth()
anchors.margins: ScreenTools.defaultFontPixelHeight qgcView: parent.parent.qgcView
height: ScreenTools.defaultFontPixelSize * 2 textColor: _isSatellite ? "white" : "black"
width: ScreenTools.defaultFontPixelSize * 2 visible: QGroundControl.virtualTabletJoystick
radius: ScreenTools.defaultFontPixelSize / 3 maxHeight: multiTouchItem.y - y
visible: !_isInstrumentVisible && !QGroundControl.virtualTabletJoystick
color: isBackgroundDark ? Qt.rgba(0,0,0,0.75) : Qt.rgba(0,0,0,0.5)
Image {
width: parent.width * 0.75
height: parent.height * 0.75
source: "/res/buttonLeft.svg"
mipmap: true
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
_isInstrumentVisible = true
QGroundControl.saveBoolGlobalSetting(_InstrumentVisibleKey, true)
}
}
} }
//-- Vertical Tool Buttons //-- Vertical Tool Buttons
......
...@@ -51,7 +51,7 @@ Map { ...@@ -51,7 +51,7 @@ Map {
readonly property real maxZoomLevel: 20 readonly property real maxZoomLevel: 20
zoomLevel: 18 zoomLevel: 18
center: QGroundControl.defaultMapPosition center: QGroundControl.lastKnownHomePosition
gesture.flickDeceleration: 3000 gesture.flickDeceleration: 3000
gesture.activeGestures: MapGestureArea.ZoomGesture | MapGestureArea.PanGesture | MapGestureArea.FlickGesture gesture.activeGestures: MapGestureArea.ZoomGesture | MapGestureArea.PanGesture | MapGestureArea.FlickGesture
......
...@@ -35,41 +35,13 @@ import QGroundControl.Controls 1.0 ...@@ -35,41 +35,13 @@ import QGroundControl.Controls 1.0
MapItemView { MapItemView {
id: _root id: _root
property var itemDragger ///< Set to item drag control if you want to support drag
delegate: MissionItemIndicator { delegate: MissionItemIndicator {
id: itemIndicator id: itemIndicator
coordinate: object.coordinate coordinate: object.coordinate
visible: object.specifiesCoordinate && (!object.homePosition || object.homePositionValid) visible: object.specifiesCoordinate && (index != 0 || object.showHomePosition)
z: QGroundControl.zOrderMapItems z: QGroundControl.zOrderMapItems
missionItem: object missionItem: object
onClicked: setCurrentItem(object.sequenceNumber)
Connections {
target: object
onIsCurrentItemChanged: {
if (isCurrentItem) {
if (_root.itemDragger) {
// Setup our drag item
if (object.sequenceNumber != 0) {
_root.itemDragger.visible = true
_root.itemDragger.missionItem = Qt.binding(function() { return object })
_root.itemDragger.missionItemIndicator = Qt.binding(function() { return itemIndicator })
} else {
_root.itemDragger.clearItem()
}
}
// Zoom the map and move to the new position
_root.parent.zoomLevel = _root.parent.maxZoomLevel
_root.parent.latitude = object.coordinate.latitude
_root.parent.longitude = object.coordinate.longitude
}
}
}
// These are the non-coordinate child mission items attached to this item // These are the non-coordinate child mission items attached to this item
Row { Row {
anchors.top: parent.top anchors.top: parent.top
......
...@@ -30,6 +30,10 @@ import QGroundControl.Palette 1.0 ...@@ -30,6 +30,10 @@ import QGroundControl.Palette 1.0
/// The MissionLineView control is used to add lines between mission items /// The MissionLineView control is used to add lines between mission items
MapItemView { MapItemView {
id: _root
property bool homePositionValid: true ///< true: show home position, false: don't show home position
delegate: MapPolyline { delegate: MapPolyline {
line.width: 3 line.width: 3
line.color: "#be781c" // Hack, can't get palette to work in here line.color: "#be781c" // Hack, can't get palette to work in here
......
...@@ -51,7 +51,7 @@ MapQuickItem { ...@@ -51,7 +51,7 @@ MapQuickItem {
transform: Rotation { transform: Rotation {
origin.x: vehicleIcon.width / 2 origin.x: vehicleIcon.width / 2
origin.y: vehicleIcon.height / 2 origin.y: vehicleIcon.height / 2
angle: vehicle ? vehicle.heading : 0 angle: vehicle ? vehicle.heading.value : 0
} }
} }
} }
...@@ -29,24 +29,30 @@ This file is part of the QGROUNDCONTROL project ...@@ -29,24 +29,30 @@ This file is part of the QGROUNDCONTROL project
import QtQuick 2.4 import QtQuick 2.4
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
import QGroundControl.FactSystem 1.0
Item { import QGroundControl.FlightMap 1.0
id: root
height: size Rectangle {
id: instrumentPanel
signal clicked height: compass.y + compass.height + _topBottomMargin
width: size
radius: size / 2
color: isSatellite ? Qt.rgba(1,1,1,0.75) : Qt.rgba(0,0,0,0.75)
property alias heading: compass.heading property alias heading: compass.heading
property alias rollAngle: attitude.rollAngle property alias rollAngle: attitude.rollAngle
property alias pitchAngle: attitude.pitchAngle property alias pitchAngle: attitude.pitchAngle
property real altitude: 0
property real groundSpeed: 0
property real airSpeed: 0
property real size: _defaultSize property real size: _defaultSize
property bool isSatellite: false property bool isSatellite: false
property bool active: false property bool active: false
property var qgcView
property real maxHeight
property Fact _emptyFact: Fact { }
property Fact groundSpeedFact: _emptyFact
property Fact airSpeedFact: _emptyFact
property real _defaultSize: ScreenTools.defaultFontPixelSize * (9) property real _defaultSize: ScreenTools.defaultFontPixelSize * (9)
...@@ -54,122 +60,59 @@ Item { ...@@ -54,122 +60,59 @@ Item {
property real _bigFontSize: ScreenTools.defaultFontPixelSize * 2.5 * _sizeRatio property real _bigFontSize: ScreenTools.defaultFontPixelSize * 2.5 * _sizeRatio
property real _normalFontSize:ScreenTools.defaultFontPixelSize * 1.5 * _sizeRatio property real _normalFontSize:ScreenTools.defaultFontPixelSize * 1.5 * _sizeRatio
property real _labelFontSize: ScreenTools.defaultFontPixelSize * 0.75 * _sizeRatio property real _labelFontSize: ScreenTools.defaultFontPixelSize * 0.75 * _sizeRatio
property real _spacing: ScreenTools.defaultFontPixelSize * 0.33
property real _topBottomMargin: (size * 0.05) / 2
property real _availableValueHeight: maxHeight - (attitude.height + _spacer1.height + _spacer2.height + compass.height + (_spacing * 4))
MouseArea {
anchors.fill: parent
onClicked: _valuesWidget.showPicker()
}
QGCAttitudeWidget {
id: attitude
y: _topBottomMargin
size: parent.width * 0.95
active: active
anchors.horizontalCenter: parent.horizontalCenter
}
//-- Instrument Panel
Rectangle { Rectangle {
id: instrumentPanel id: _spacer1
height: instruments.height + (size * 0.05) anchors.topMargin: _spacing
width: root.size anchors.top: attitude.bottom
radius: root.size / 2 height: 1
color: isSatellite ? Qt.rgba(1,1,1,0.75) : Qt.rgba(0,0,0,0.75) width: parent.width * 0.9
anchors.right: parent.right color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter
Column { }
id: instruments
width: parent.width ValuesWidget {
spacing: ScreenTools.defaultFontPixelSize * 0.33 id: _valuesWidget
anchors.verticalCenter: parent.verticalCenter anchors.topMargin: _spacing
//-- Attitude Indicator anchors.top: _spacer1.bottom
QGCAttitudeWidget { width: parent.width
id: attitude qgcView: instrumentPanel.qgcView
size: parent.width * 0.95 textColor: isSatellite ? "black" : "white"
active: root.active maxHeight: _availableValueHeight
anchors.horizontalCenter: parent.horizontalCenter }
}
//-- Altitude Rectangle {
Rectangle { id: _spacer2
height: 1 anchors.topMargin: _spacing
width: parent.width * 0.9 anchors.top: _valuesWidget.bottom
color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25) height: 1
anchors.horizontalCenter: parent.horizontalCenter width: parent.width * 0.9
} color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
QGCLabel { anchors.horizontalCenter: parent.horizontalCenter
text: "Altitude (m)" }
font.pixelSize: _labelFontSize
width: parent.width QGCCompassWidget {
height: _labelFontSize id: compass
color: isSatellite ? "black" : "white" anchors.topMargin: _spacing
horizontalAlignment: TextEdit.AlignHCenter anchors.top: _spacer2.bottom
} size: parent.width * 0.95
QGCLabel { active: active
text: altitude < 10000 ? altitude.toFixed(1) : altitude.toFixed(0) anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: _bigFontSize
font.weight: Font.DemiBold
width: parent.width
color: isSatellite ? "black" : "white"
horizontalAlignment: TextEdit.AlignHCenter
}
//-- Ground Speed
Rectangle {
height: 1
width: parent.width * 0.9
color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
anchors.horizontalCenter: parent.horizontalCenter
visible: airSpeed <= 0 && !ScreenTools.isTinyScreen
}
QGCLabel {
text: "Ground Speed (km/h)"
font.pixelSize: _labelFontSize
width: parent.width
height: _labelFontSize
color: isSatellite ? "black" : "white"
horizontalAlignment: TextEdit.AlignHCenter
visible: airSpeed <= 0 && !ScreenTools.isTinyScreen
}
QGCLabel {
text: (groundSpeed * 3.6).toFixed(1)
font.pixelSize: _normalFontSize
font.weight: Font.DemiBold
width: parent.width
color: isSatellite ? "black" : "white"
horizontalAlignment: TextEdit.AlignHCenter
visible: airSpeed <= 0 && !ScreenTools.isTinyScreen
}
//-- Air Speed
Rectangle {
height: 1
width: parent.width * 0.9
color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
anchors.horizontalCenter: parent.horizontalCenter
visible: airSpeed > 0 && !ScreenTools.isTinyScreen
}
QGCLabel {
text: "Air Speed (km/h)"
font.pixelSize: _labelFontSize
width: parent.width
height: _labelFontSize
color: isSatellite ? "black" : "white"
visible: airSpeed > 0 && !ScreenTools.isTinyScreen
horizontalAlignment: TextEdit.AlignHCenter
}
QGCLabel {
text: (airSpeed * 3.6).toFixed(1)
font.pixelSize: _normalFontSize
font.weight: Font.DemiBold
width: parent.width
color: isSatellite ? "black" : "white"
visible: airSpeed > 0 && !ScreenTools.isTinyScreen
horizontalAlignment: TextEdit.AlignHCenter
}
//-- Compass
Rectangle {
height: 1
width: parent.width * 0.9
color: isSatellite ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
anchors.horizontalCenter: parent.horizontalCenter
}
QGCCompassWidget {
id: compass
size: parent.width * 0.95
active: root.active
anchors.horizontalCenter: parent.horizontalCenter
}
}
MouseArea {
anchors.fill: parent
onClicked: {
onClicked: root.clicked()
}
}
} }
} }
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.4
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FlightMap 1.0
/// Instrument panel shown when virtual thumbsticks are visible
Rectangle {
id: root
height: _outerRadius * 2
radius: _outerRadius
color: isSatellite ? Qt.rgba(1,1,1,0.75) : Qt.rgba(0,0,0,0.75)
property alias heading: compass.heading
property alias rollAngle: attitude.rollAngle
property alias pitchAngle: attitude.pitchAngle
property real size: _defaultSize
property bool isSatellite: false
property bool active: false
property Fact _emptyFact: Fact { }
property Fact groundSpeedFact: _emptyFact
property Fact airSpeedFact: _emptyFact
property Fact altitudeFact: _emptyFact
property real _innerRadius: (width - (_topBottomMargin * 3)) / 4
property real _outerRadius: _innerRadius + _topBottomMargin
property real _defaultSize: ScreenTools.defaultFontPixelSize * (9)
property real _sizeRatio: ScreenTools.isTinyScreen ? (size / _defaultSize) * 0.5 : size / _defaultSize
property real _bigFontSize: ScreenTools.defaultFontPixelSize * 2.5 * _sizeRatio
property real _normalFontSize:ScreenTools.defaultFontPixelSize * 1.5 * _sizeRatio
property real _labelFontSize: ScreenTools.defaultFontPixelSize * 0.75 * _sizeRatio
property real _spacing: ScreenTools.defaultFontPixelSize * 0.33
property real _topBottomMargin: (size * 0.05) / 2
QGCAttitudeWidget {
id: attitude
anchors.leftMargin: _topBottomMargin
anchors.left: parent.left
size: _innerRadius * 2
active: active
anchors.verticalCenter: parent.verticalCenter
}
QGCCompassWidget {
id: compass
anchors.leftMargin: _spacing
anchors.left: attitude.right
size: _innerRadius * 2
active: active
anchors.verticalCenter: parent.verticalCenter
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.4
import QtQuick.Dialogs 1.2
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.Palette 1.0
import QGroundControl 1.0
QGCFlickable {
id: _root
visible: _activeVehicle
height: Math.min(maxHeight, _smallFlow.y + _smallFlow.height)
contentHeight: _smallFlow.y + _smallFlow.height
flickableDirection: Flickable.VerticalFlick
clip: true
property var qgcView
property color textColor
property var maxHeight
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
property real _margins: ScreenTools.defaultFontPixelWidth / 2
QGCPalette { id:qgcPal; colorGroupEnabled: true }
ValuesWidgetController {
id: controller
}
function showPicker() {
qgcView.showDialog(propertyPicker, "Value Widget Setup", qgcView.showDialogDefaultWidth, StandardButton.Ok)
}
MouseArea {
anchors.fill: parent
onClicked: showPicker()
}
Column {
id: _largeColumn
width: parent.width
spacing: _margins
Repeater {
model: _activeVehicle ? controller.largeValues : 0
Column {
id: valueColumn
width: _largeColumn.width
property Fact fact: _activeVehicle.getFact(modelData.replace("Vehicle.", ""))
QGCLabel {
width: parent.width
horizontalAlignment: Text.AlignHCenter
color: textColor
text: fact.shortDescription + (fact.units ? " (" + fact.units + ")" : "")
}
QGCLabel {
width: parent.width
horizontalAlignment: Text.AlignHCenter
font.pixelSize: ScreenTools.largeFontPixelSize
font.weight: Font.DemiBold
color: textColor
text: fact.valueString
}
}
} // Repeater - Large
} // Column - Large
Flow {
id: _smallFlow
width: parent.width
anchors.topMargin: _margins
anchors.top: _largeColumn.bottom
layoutDirection: Qt.LeftToRight
spacing: _margins
Repeater {
model: _activeVehicle ? controller.smallValues : 0
Column {
id: valueColumn
width: (_root.width / 2) - (_margins / 2) - 0.1
clip: true
property Fact fact: _activeVehicle.getFact(modelData.replace("Vehicle.", ""))
QGCLabel {
width: parent.width
horizontalAlignment: Text.AlignHCenter
font.pixelSize: ScreenTools.smallFontPixelSize
color: textColor
text: fact.shortDescription
}
QGCLabel {
width: parent.width
horizontalAlignment: Text.AlignHCenter
color: textColor
text: fact.enumOrValueString
}
QGCLabel {
width: parent.width
horizontalAlignment: Text.AlignHCenter
font.pixelSize: ScreenTools.smallFontPixelSize
color: textColor
text: fact.units
}
}
} // Repeater - Small
} // Flow
Component {
id: propertyPicker
QGCViewDialog {
id: _propertyPickerDialog
QGCLabel {
id: _label
text: "Select the values you want to display:"
}
Loader {
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: _margins
anchors.top: _label.bottom
anchors.bottom: parent.bottom
sourceComponent: factGroupList
property var factGroup: _activeVehicle
property var factGroupName: "Vehicle"
}
}
}
Component {
id: factGroupList
// You must push in the following properties from the Loader
// property var factGroup
// property string factGroupName
Column {
id: _root
spacing: _margins
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: factGroup ? factGroupName : "Vehicle must be connected to assign values."
}
Repeater {
model: factGroup ? factGroup.factNames : 0
Row {
spacing: _margins
property string propertyName: factGroupName + "." + modelData
function contains(list, value) {
for (var i=0; i<list.length; i++) {
if (list[i] === value) {
return true
}
}
return false
}
function removeFromList(list, value) {
var newList = []
for (var i=0; i<list.length; i++) {
if (list[i] !== value) {
newList.push(list[i])
}
}
return newList
}
function addToList(list, value) {
var found = false
for (var i=0; i<list.length; i++) {
if (list[i] === value) {
found = true
break
}
}
if (!found) {
list.push(value)
}
return list
}
function updateValues() {
if (_addCheckBox.checked) {
if (_largeCheckBox.checked) {
controller.largeValues = addToList(controller.largeValues, propertyName)
controller.smallValues = removeFromList(controller.smallValues, propertyName)
} else {
controller.smallValues = addToList(controller.smallValues, propertyName)
controller.largeValues = removeFromList(controller.largeValues, propertyName)
}
} else {
controller.largeValues = removeFromList(controller.largeValues, propertyName)
controller.smallValues = removeFromList(controller.smallValues, propertyName)
}
}
QGCCheckBox {
id: _addCheckBox
text: factGroup.getFact(modelData).shortDescription
checked: _largeCheckBox.checked || parent.contains(controller.smallValues, propertyName)
onClicked: updateValues()
}
QGCCheckBox {
id: _largeCheckBox
text: "large"
checked: parent.contains(controller.largeValues, propertyName)
enabled: _addCheckBox.checked
onClicked: updateValues()
}
}
}
Item { height: 1; width: 1 }
Repeater {
model: factGroup ? factGroup.factGroupNames : 0
Loader {
sourceComponent: factGroupList
property var factGroup: _root ? _root.parent.factGroup.getFactGroup(modelData) : undefined
property string factGroupName: _root ? _root.parent.factGroupName + "." + modelData : undefined
}
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "ValuesWidgetController.h"
#include <QSettings>
const char* ValuesWidgetController::_groupKey = "ValuesWidget";
const char* ValuesWidgetController::_largeValuesKey = "large";
const char* ValuesWidgetController::_smallValuesKey = "small";
ValuesWidgetController::ValuesWidgetController(void)
{
QSettings settings;
QStringList largeDefaults;
settings.beginGroup(_groupKey);
largeDefaults << "Vehicle.altitudeRelative" << "Vehicle.groundSpeed";
_largeValues = settings.value(_largeValuesKey, largeDefaults).toStringList();
_smallValues = settings.value(_smallValuesKey, QStringList()).toStringList();
// Keep back compat for removed WGS84 value
if (_largeValues.contains ("Vehicle.altitudeWGS84")) {
setLargeValues(_largeValues.replaceInStrings("Vehicle.altitudeWGS84", "Vehicle.altitudeRelative"));
}
if (_smallValues.contains ("Vehicle.altitudeWGS84")) {
setSmallValues(_largeValues.replaceInStrings("Vehicle.altitudeWGS84", "Vehicle.altitudeRelative"));
}
}
void ValuesWidgetController::setLargeValues(const QStringList& values)
{
QSettings settings;
settings.beginGroup(_groupKey);
settings.setValue(_largeValuesKey, values);
_largeValues = values;
emit largeValuesChanged(values);
}
void ValuesWidgetController::setSmallValues(const QStringList& values)
{
QSettings settings;
settings.beginGroup(_groupKey);
settings.setValue(_smallValuesKey, values);
_smallValues = values;
emit smallValuesChanged(values);
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef ValuesWidgetController_H
#define ValuesWidgetController_H
#include <QObject>
class ValuesWidgetController : public QObject
{
Q_OBJECT
public:
ValuesWidgetController(void);
Q_PROPERTY(QStringList largeValues READ largeValues WRITE setLargeValues NOTIFY largeValuesChanged)
Q_PROPERTY(QStringList smallValues READ smallValues WRITE setSmallValues NOTIFY smallValuesChanged)
QStringList largeValues(void) const { return _largeValues; }
QStringList smallValues(void) const { return _smallValues; }
void setLargeValues(const QStringList& values);
void setSmallValues(const QStringList& values);
signals:
void largeValuesChanged(QStringList values);
void smallValuesChanged(QStringList values);
private:
QStringList _largeValues;
QStringList _smallValues;
static const char* _groupKey;
static const char* _largeValuesKey;
static const char* _smallValuesKey;
};
#endif
...@@ -5,13 +5,15 @@ FlightMap 1.0 FlightMap.qml ...@@ -5,13 +5,15 @@ FlightMap 1.0 FlightMap.qml
QGCVideoBackground 1.0 QGCVideoBackground.qml QGCVideoBackground 1.0 QGCVideoBackground.qml
# Widgets # Widgets
QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml
QGCAttitudeHUD 1.0 QGCAttitudeHUD.qml QGCAttitudeHUD 1.0 QGCAttitudeHUD.qml
QGCAttitudeWidget 1.0 QGCAttitudeWidget.qml QGCAttitudeWidget 1.0 QGCAttitudeWidget.qml
QGCCompassWidget 1.0 QGCCompassWidget.qml QGCCompassWidget 1.0 QGCCompassWidget.qml
QGCInstrumentWidget 1.0 QGCInstrumentWidget.qml QGCInstrumentWidget 1.0 QGCInstrumentWidget.qml
QGCPitchIndicator 1.0 QGCPitchIndicator.qml QGCInstrumentWidgetAlternate 1.0 QGCInstrumentWidgetAlternate.qml
QGCSlider 1.0 QGCSlider.qml QGCPitchIndicator 1.0 QGCPitchIndicator.qml
QGCSlider 1.0 QGCSlider.qml
ValuesWidget 1.0 ValuesWidget.qml
# Map items # Map items
MissionItemIndicator 1.0 MissionItemIndicator.qml MissionItemIndicator 1.0 MissionItemIndicator.qml
......
/*===================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "JsonHelper.h"
#include <QJsonArray>
const char* JsonHelper::_enumStringsJsonKey = "enumStrings";
const char* JsonHelper::_enumValuesJsonKey = "enumValues";
bool JsonHelper::validateRequiredKeys(const QJsonObject& jsonObject, const QStringList& keys, QString& errorString)
{
QString missingKeys;
foreach(const QString& key, keys) {
if (!jsonObject.contains(key)) {
if (!missingKeys.isEmpty()) {
missingKeys += QStringLiteral(", ");
}
missingKeys += key;
}
}
if (missingKeys.count() != 0) {
errorString = QString("The following required keys are missing: %1").arg(missingKeys);
return false;
}
return true;
}
bool JsonHelper::toQGeoCoordinate(const QJsonValue& jsonValue, QGeoCoordinate& coordinate, bool altitudeRequired, QString& errorString)
{
if (!jsonValue.isArray()) {
errorString = QStringLiteral("JSon value for coordinate is not array");
return false;
}
QJsonArray coordinateArray = jsonValue.toArray();
int requiredCount = altitudeRequired ? 3 : 2;
if (coordinateArray.count() != requiredCount) {
errorString = QString("Json array must contains %1 values").arg(requiredCount);
return false;
}
coordinate = QGeoCoordinate(coordinateArray[0].toDouble(), coordinateArray[1].toDouble());
if (altitudeRequired) {
coordinate.setAltitude(coordinateArray[2].toDouble());
}
if (!coordinate.isValid()) {
errorString = QString("Coordinate is invalid: %1").arg(coordinate.toString());
return false;
}
return true;
}
bool JsonHelper::validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types, QString& errorString)
{
for (int i=0; i<keys.count(); i++) {
if (jsonObject.contains(keys[i])) {
if (jsonObject.value(keys[i]).type() != types[i]) {
errorString = QString("Incorrect type key:type:expected %1 %2 %3").arg(keys[i]).arg(jsonObject.value(keys[i]).type()).arg(types[i]);
return false;
}
}
}
return true;
}
bool JsonHelper::parseEnum(QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString)
{
enumStrings = jsonObject.value(_enumStringsJsonKey).toString().split(",", QString::SkipEmptyParts);
enumValues = jsonObject.value(_enumValuesJsonKey).toString().split(",", QString::SkipEmptyParts);
if (enumStrings.count() != enumValues.count()) {
errorString = QString("enum strings/values count mismatch: %1");
return false;
}
return true;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef JsonHelper_H
#define JsonHelper_H
#include <QJsonObject>
#include <QGeoCoordinate>
class JsonHelper
{
public:
static bool validateRequiredKeys(const QJsonObject& jsonObject, const QStringList& keys, QString& errorString);
static bool validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types, QString& errorString);
static bool toQGeoCoordinate(const QJsonValue& jsonValue, QGeoCoordinate& coordinate, bool altitudeRequired, QString& errorString);
static bool parseEnum(QJsonObject& jsonObject, QStringList& enumStrings, QStringList& enumValues, QString& errorString);
static const char* _enumStringsJsonKey;
static const char* _enumValuesJsonKey;
};
#endif
This diff is collapsed.
...@@ -32,7 +32,6 @@ Rectangle { ...@@ -32,7 +32,6 @@ Rectangle {
property var currentMissionItem ///< Mission item to display status for property var currentMissionItem ///< Mission item to display status for
property var missionItems ///< List of all available mission items property var missionItems ///< List of all available mission items
property real expandedWidth ///< Width of control when expanded property real expandedWidth ///< Width of control when expanded
property bool homePositionValid: false /// true: home position in missionItems[0] is valid
width: _expanded ? expandedWidth : _collapsedWidth width: _expanded ? expandedWidth : _collapsedWidth
height: expandLabel.y + expandLabel.height + _margins height: expandLabel.y + expandLabel.height + _margins
...@@ -49,7 +48,7 @@ Rectangle { ...@@ -49,7 +48,7 @@ Rectangle {
property real _altDifference: _currentMissionItem ? _currentMissionItem.altDifference : -1 property real _altDifference: _currentMissionItem ? _currentMissionItem.altDifference : -1
property real _azimuth: _currentMissionItem ? _currentMissionItem.azimuth : -1 property real _azimuth: _currentMissionItem ? _currentMissionItem.azimuth : -1
property real _isHomePosition: _currentMissionItem ? _currentMissionItem.homePosition : false property real _isHomePosition: _currentMissionItem ? _currentMissionItem.homePosition : false
property bool _statusValid: _distance != -1 && ((_isHomePosition && homePositionValid) || !_isHomePosition) property bool _statusValid: _distance != -1
property string _distanceText: _statusValid ? Math.round(_distance) + " meters" : "" property string _distanceText: _statusValid ? Math.round(_distance) + " meters" : ""
property string _altText: _statusValid ? Math.round(_altDifference) + " meters" : "" property string _altText: _statusValid ? Math.round(_altDifference) + " meters" : ""
property string _azimuthText: _statusValid ? Math.round(_azimuth) : "" property string _azimuthText: _statusValid ? Math.round(_azimuth) : ""
...@@ -97,6 +96,8 @@ Rectangle { ...@@ -97,6 +96,8 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
contentWidth: graphRow.width
clip: true
Row { Row {
id: graphRow id: graphRow
...@@ -108,14 +109,14 @@ Rectangle { ...@@ -108,14 +109,14 @@ Rectangle {
model: missionItems model: missionItems
Item { Item {
height: graphRow.height height: graphRow.height
width: ScreenTools.smallFontPixelWidth * 2 width: ScreenTools.smallFontPixelWidth * 2
visible: object.specifiesCoordinate && !object.standaloneCoordinate
property real availableHeight: height - ScreenTools.smallFontPixelHeight - indicator.height property real availableHeight: height - ScreenTools.smallFontPixelHeight - indicator.height
// If home position is not valid we are graphing relative based on a home alt of 0. Because of this property bool graphAbsolute: true
// we cannot graph absolute altitudes since we have no basis for comparison against the relative values.
property bool graphAbsolute: homePositionValid
MissionItemIndexLabel { MissionItemIndexLabel {
id: indicator id: indicator
......
This diff is collapsed.
...@@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project ...@@ -26,6 +26,7 @@ This file is part of the QGROUNDCONTROL project
#include "FirmwarePluginManager.h" #include "FirmwarePluginManager.h"
#include "QGCApplication.h" #include "QGCApplication.h"
#include "QGroundControlQmlGlobal.h" #include "QGroundControlQmlGlobal.h"
#include "JsonHelper.h"
#include <QStringList> #include <QStringList>
#include <QJsonDocument> #include <QJsonDocument>
...@@ -62,20 +63,6 @@ MissionCommandList::MissionCommandList(const QString& jsonFilename, QObject* par ...@@ -62,20 +63,6 @@ MissionCommandList::MissionCommandList(const QString& jsonFilename, QObject* par
_loadMavCmdInfoJson(jsonFilename); _loadMavCmdInfoJson(jsonFilename);
} }
bool MissionCommandList::_validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types)
{
for (int i=0; i<keys.count(); i++) {
if (jsonObject.contains(keys[i])) {
if (jsonObject.value(keys[i]).type() != types[i]) {
qWarning() << "Incorrect type key:type:expected" << keys[i] << jsonObject.value(keys[i]).type() << types[i];
return false;
}
}
}
return true;
}
void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename) void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename)
{ {
if (jsonFilename.isEmpty()) { if (jsonFilename.isEmpty()) {
...@@ -122,13 +109,12 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename) ...@@ -122,13 +109,12 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename)
QJsonObject jsonObject = info.toObject(); QJsonObject jsonObject = info.toObject();
// Make sure we have the required keys // Make sure we have the required keys
QString errorString;
QStringList requiredKeys; QStringList requiredKeys;
requiredKeys << _idJsonKey << _rawNameJsonKey; requiredKeys << _idJsonKey << _rawNameJsonKey;
foreach (const QString &key, requiredKeys) { if (!JsonHelper::validateRequiredKeys(jsonObject, requiredKeys, errorString)) {
if (!jsonObject.contains(key)) { qWarning() << errorString;
qWarning() << "Mission required key" << key; return;
return;
}
} }
// Validate key types // Validate key types
...@@ -139,7 +125,8 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename) ...@@ -139,7 +125,8 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename)
<< _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _categoryJsonKey; << _param1JsonKey << _param2JsonKey << _param3JsonKey << _param4JsonKey << _categoryJsonKey;
types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool types << QJsonValue::Double << QJsonValue::String << QJsonValue::String<< QJsonValue::String << QJsonValue::Bool << QJsonValue::Bool << QJsonValue::Bool
<< QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::String; << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::Object << QJsonValue::String;
if (!_validateKeyTypes(jsonObject, keys, types)) { if (!JsonHelper::validateKeyTypes(jsonObject, keys, types, errorString)) {
qWarning() << errorString;
return; return;
} }
...@@ -184,7 +171,8 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename) ...@@ -184,7 +171,8 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename)
QList<QJsonValue::Type> types; QList<QJsonValue::Type> types;
keys << _defaultJsonKey << _decimalPlacesJsonKey << _enumStringsJsonKey << _enumValuesJsonKey << _labelJsonKey << _unitsJsonKey; keys << _defaultJsonKey << _decimalPlacesJsonKey << _enumStringsJsonKey << _enumValuesJsonKey << _labelJsonKey << _unitsJsonKey;
types << QJsonValue::Double << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String; types << QJsonValue::Double << QJsonValue::Double << QJsonValue::String << QJsonValue::String << QJsonValue::String << QJsonValue::String;
if (!_validateKeyTypes(paramObject, keys, types)) { if (!JsonHelper::validateKeyTypes(jsonObject, keys, types, errorString)) {
qWarning() << errorString;
return; return;
} }
......
...@@ -143,7 +143,6 @@ public: ...@@ -143,7 +143,6 @@ public:
private: private:
void _loadMavCmdInfoJson(const QString& jsonFilename); void _loadMavCmdInfoJson(const QString& jsonFilename);
bool _validateKeyTypes(QJsonObject& jsonObject, const QStringList& keys, const QList<QJsonValue::Type>& types);
private: private:
QMap<MAV_CMD, MavCmdInfo*> _mavCmdInfoMap; QMap<MAV_CMD, MavCmdInfo*> _mavCmdInfoMap;
......
...@@ -77,10 +77,14 @@ void MissionCommands::_createCategories(void) ...@@ -77,10 +77,14 @@ void MissionCommands::_createCategories(void)
foreach (MAV_CMD command, cmdList) { foreach (MAV_CMD command, cmdList) {
MavCmdInfo* mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command); MavCmdInfo* mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command);
if (mavCmdInfo->friendlyEdit()) { if (mavCmdInfo) {
_categoryToMavCmdListMap[firmwareType][mavCmdInfo->category()].append(command); if (mavCmdInfo->friendlyEdit()) {
} else if (!allCommandsSupported) { _categoryToMavCmdListMap[firmwareType][mavCmdInfo->category()].append(command);
qWarning() << "Attempt to add non friendly edit supported command"; } else if (!allCommandsSupported) {
qWarning() << "Attempt to add non friendly edit supported command" << command;
}
} else {
qCDebug(MissionCommandsLog) << "Command missing from json" << command;
} }
} }
} }
...@@ -146,20 +150,20 @@ MavCmdInfo* MissionCommands::getMavCmdInfo(MAV_CMD command, Vehicle* vehicle) co ...@@ -146,20 +150,20 @@ MavCmdInfo* MissionCommands::getMavCmdInfo(MAV_CMD command, Vehicle* vehicle) co
if (vehicle) { if (vehicle) {
if (vehicle->fixedWing()) { if (vehicle->fixedWing()) {
if (_autopilotToFixedWingMissionCommands[firmwareType]->contains(command)) { if (_autopilotToFixedWingMissionCommands.contains(firmwareType) && _autopilotToFixedWingMissionCommands[firmwareType]->contains(command)) {
mavCmdInfo = _autopilotToFixedWingMissionCommands[firmwareType]->getMavCmdInfo(command); mavCmdInfo = _autopilotToFixedWingMissionCommands[firmwareType]->getMavCmdInfo(command);
} }
} else if (vehicle->multiRotor()) { } else if (vehicle->multiRotor()) {
if (_autopilotToMultiRotorMissionCommands[firmwareType]->contains(command)) { if (_autopilotToMultiRotorMissionCommands.contains(firmwareType) && _autopilotToMultiRotorMissionCommands[firmwareType]->contains(command)) {
mavCmdInfo = _autopilotToMultiRotorMissionCommands[firmwareType]->getMavCmdInfo(command); mavCmdInfo = _autopilotToMultiRotorMissionCommands[firmwareType]->getMavCmdInfo(command);
} }
} else {
if (_autopilotToCommonMissionCommands[firmwareType]->contains(command)) {
mavCmdInfo = _autopilotToCommonMissionCommands[firmwareType]->getMavCmdInfo(command);
}
} }
} }
if (!mavCmdInfo && _autopilotToCommonMissionCommands.contains(firmwareType) && _autopilotToCommonMissionCommands[firmwareType]->contains(command)) {
mavCmdInfo = _autopilotToCommonMissionCommands[firmwareType]->getMavCmdInfo(command);
}
if (!mavCmdInfo) { if (!mavCmdInfo) {
mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command); mavCmdInfo = _commonMissionCommands.getMavCmdInfo(command);
} }
......
This diff is collapsed.
...@@ -42,17 +42,19 @@ public: ...@@ -42,17 +42,19 @@ public:
Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged) Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged)
Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged) Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged)
Q_PROPERTY(bool liveHomePositionAvailable READ liveHomePositionAvailable NOTIFY liveHomePositionAvailableChanged)
Q_PROPERTY(QGeoCoordinate liveHomePosition READ liveHomePosition NOTIFY liveHomePositionChanged)
Q_PROPERTY(bool autoSync READ autoSync WRITE setAutoSync NOTIFY autoSyncChanged) Q_PROPERTY(bool autoSync READ autoSync WRITE setAutoSync NOTIFY autoSyncChanged)
Q_PROPERTY(bool syncInProgress READ syncInProgress NOTIFY syncInProgressChanged)
Q_INVOKABLE void start(bool editMode); Q_INVOKABLE void start(bool editMode);
Q_INVOKABLE void getMissionItems(void); Q_INVOKABLE void getMissionItems(void);
Q_INVOKABLE void sendMissionItems(void); Q_INVOKABLE void sendMissionItems(void);
Q_INVOKABLE void loadMissionFromFile(void); Q_INVOKABLE void loadMissionFromFile(void);
Q_INVOKABLE void saveMissionToFile(void); Q_INVOKABLE void saveMissionToFile(void);
Q_INVOKABLE void loadMobileMissionFromFile(const QString& file);
Q_INVOKABLE void saveMobileMissionToFile(const QString& file);
Q_INVOKABLE void removeMissionItem(int index); Q_INVOKABLE void removeMissionItem(int index);
Q_INVOKABLE void removeAllMissionItems(void); Q_INVOKABLE void removeAllMissionItems(void);
Q_INVOKABLE QStringList getMobileMissionFiles(void);
/// @param i: index to insert at /// @param i: index to insert at
Q_INVOKABLE int insertMissionItem(QGeoCoordinate coordinate, int i); Q_INVOKABLE int insertMissionItem(QGeoCoordinate coordinate, int i);
...@@ -61,18 +63,16 @@ public: ...@@ -61,18 +63,16 @@ public:
QmlObjectListModel* missionItems(void); QmlObjectListModel* missionItems(void);
QmlObjectListModel* waypointLines(void) { return &_waypointLines; } QmlObjectListModel* waypointLines(void) { return &_waypointLines; }
bool liveHomePositionAvailable(void) { return _liveHomePositionAvailable; }
QGeoCoordinate liveHomePosition(void) { return _liveHomePosition; }
bool autoSync(void) { return _autoSync; } bool autoSync(void) { return _autoSync; }
void setAutoSync(bool autoSync); void setAutoSync(bool autoSync);
bool syncInProgress(void);
signals: signals:
void missionItemsChanged(void); void missionItemsChanged(void);
void waypointLinesChanged(void); void waypointLinesChanged(void);
void liveHomePositionAvailableChanged(bool homePositionAvailable);
void liveHomePositionChanged(const QGeoCoordinate& homePosition);
void autoSyncChanged(bool autoSync); void autoSyncChanged(bool autoSync);
void newItemsFromVehicle(void); void newItemsFromVehicle(void);
void syncInProgressChanged(bool syncInProgress);
private slots: private slots:
void _newMissionItemsAvailableFromVehicle(); void _newMissionItemsAvailableFromVehicle();
...@@ -84,6 +84,7 @@ private slots: ...@@ -84,6 +84,7 @@ private slots:
void _activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition); void _activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition);
void _dirtyChanged(bool dirty); void _dirtyChanged(bool dirty);
void _inProgressChanged(bool inProgress); void _inProgressChanged(bool inProgress);
void _currentMissionItemChanged(int sequenceNumber);
private: private:
void _recalcSequence(void); void _recalcSequence(void);
...@@ -95,25 +96,34 @@ private: ...@@ -95,25 +96,34 @@ private:
void _initMissionItem(MissionItem* item); void _initMissionItem(MissionItem* item);
void _deinitMissionItem(MissionItem* item); void _deinitMissionItem(MissionItem* item);
void _autoSyncSend(void); void _autoSyncSend(void);
void _setupMissionItems(bool loadFromVehicle, bool forceLoad);
void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle); void _setupActiveVehicle(Vehicle* activeVehicle, bool forceLoadFromVehicle);
void _calcPrevWaypointValues(bool homePositionValid, double homeAlt, MissionItem* currentItem, MissionItem* prevItem, double* azimuth, double* distance, double* altDifference); void _calcPrevWaypointValues(double homeAlt, MissionItem* currentItem, MissionItem* prevItem, double* azimuth, double* distance, double* altDifference);
bool _findLastAltitude(double* lastAltitude); bool _findLastAltitude(double* lastAltitude);
bool _findLastAcceptanceRadius(double* lastAcceptanceRadius); bool _findLastAcceptanceRadius(double* lastAcceptanceRadius);
void _addPlannedHomePosition(QmlObjectListModel* missionItems, bool addToCenter);
double _normalizeLat(double lat);
double _normalizeLon(double lon);
bool _loadJsonMissionFile(const QByteArray& bytes, QmlObjectListModel* missionItems, QString& errorString);
bool _loadTextMissionFile(QTextStream& stream, QmlObjectListModel* missionItems, QString& errorString);
void _loadMissionFromFile(const QString& file);
void _saveMissionToFile(const QString& file);
private: private:
bool _editMode; bool _editMode;
QmlObjectListModel* _missionItems; QmlObjectListModel* _missionItems;
QmlObjectListModel _waypointLines; QmlObjectListModel _waypointLines;
Vehicle* _activeVehicle; Vehicle* _activeVehicle;
bool _liveHomePositionAvailable;
QGeoCoordinate _liveHomePosition;
bool _autoSync; bool _autoSync;
bool _firstItemsFromVehicle; bool _firstItemsFromVehicle;
bool _missionItemsRequested; bool _missionItemsRequested;
bool _queuedSend; bool _queuedSend;
static const char* _settingsGroup; static const char* _settingsGroup;
static const char* _jsonVersionKey;
static const char* _jsonGroundStationKey;
static const char* _jsonMavAutopilotKey;
static const char* _jsonItemsKey;
static const char* _jsonPlannedHomePositionKey;
}; };
#endif #endif
This diff is collapsed.
...@@ -61,13 +61,11 @@ private: ...@@ -61,13 +61,11 @@ private:
enum { enum {
coordinateChangedSignalIndex = 0, coordinateChangedSignalIndex = 0,
homePositionValidChangedSignalIndex,
missionItemMaxSignalIndex missionItemMaxSignalIndex
}; };
enum { enum {
coordinateChangedSignalMask = 1 << coordinateChangedSignalIndex, coordinateChangedSignalMask = 1 << coordinateChangedSignalIndex,
homePositionValidChangedSignalMask = 1 << homePositionValidChangedSignalIndex,
missionItemMaxSignalMask = 1 << missionItemMaxSignalIndex, missionItemMaxSignalMask = 1 << missionItemMaxSignalIndex,
}; };
...@@ -76,16 +74,12 @@ private: ...@@ -76,16 +74,12 @@ private:
enum { enum {
missionItemsChangedSignalIndex = 0, missionItemsChangedSignalIndex = 0,
waypointLinesChangedSignalIndex, waypointLinesChangedSignalIndex,
liveHomePositionAvailableChangedSignalIndex,
liveHomePositionChangedSignalIndex,
missionControllerMaxSignalIndex missionControllerMaxSignalIndex
}; };
enum { enum {
missionItemsChangedSignalMask = 1 << missionItemsChangedSignalIndex, missionItemsChangedSignalMask = 1 << missionItemsChangedSignalIndex,
waypointLinesChangedSignalMask = 1 << waypointLinesChangedSignalIndex, waypointLinesChangedSignalMask = 1 << waypointLinesChangedSignalIndex,
liveHomePositionAvailableChangedSignalMask = 1 << liveHomePositionAvailableChangedSignalIndex,
liveHomePositionChangedSignalMask = 1 << liveHomePositionChangedSignalIndex,
}; };
MultiSignalSpy* _multiSpyMissionController; MultiSignalSpy* _multiSpyMissionController;
......
This diff is collapsed.
This diff is collapsed.
...@@ -38,7 +38,6 @@ const MissionItemTest::ItemInfo_t MissionItemTest::_rgItemInfo[] = { ...@@ -38,7 +38,6 @@ const MissionItemTest::ItemInfo_t MissionItemTest::_rgItemInfo[] = {
const MissionItemTest::FactValue_t MissionItemTest::_rgFactValuesWaypoint[] = { const MissionItemTest::FactValue_t MissionItemTest::_rgFactValuesWaypoint[] = {
{ "Altitude:", 70.1234567 }, { "Altitude:", 70.1234567 },
{ "Hold:", 10.1234567 }, { "Hold:", 10.1234567 },
{ "Accept radius:", 20.1234567 },
}; };
const MissionItemTest::FactValue_t MissionItemTest::_rgFactValuesLoiterUnlim[] = { const MissionItemTest::FactValue_t MissionItemTest::_rgFactValuesLoiterUnlim[] = {
...@@ -97,6 +96,9 @@ MissionItemTest::MissionItemTest(void) ...@@ -97,6 +96,9 @@ MissionItemTest::MissionItemTest(void)
void MissionItemTest::_test(void) void MissionItemTest::_test(void)
{ {
#if 0
// FIXME: Update to json
for (size_t i=0; i<sizeof(_rgItemInfo)/sizeof(_rgItemInfo[0]); i++) { for (size_t i=0; i<sizeof(_rgItemInfo)/sizeof(_rgItemInfo[0]); i++) {
const ItemInfo_t* info = &_rgItemInfo[i]; const ItemInfo_t* info = &_rgItemInfo[i];
const ItemExpected_t* expected = &_rgItemExpected[i]; const ItemExpected_t* expected = &_rgItemExpected[i];
...@@ -177,6 +179,7 @@ void MissionItemTest::_test(void) ...@@ -177,6 +179,7 @@ void MissionItemTest::_test(void)
delete item; delete item;
delete loadedItem; delete loadedItem;
} }
#endif
} }
void MissionItemTest::_testDefaultValues(void) void MissionItemTest::_testDefaultValues(void)
...@@ -185,6 +188,5 @@ void MissionItemTest::_testDefaultValues(void) ...@@ -185,6 +188,5 @@ void MissionItemTest::_testDefaultValues(void)
item.setCommand(MAV_CMD_NAV_WAYPOINT); item.setCommand(MAV_CMD_NAV_WAYPOINT);
item.setFrame(MAV_FRAME_GLOBAL_RELATIVE_ALT); item.setFrame(MAV_FRAME_GLOBAL_RELATIVE_ALT);
QCOMPARE(item.param2(), 3.0);
QCOMPARE(item.param7(), MissionItem::defaultAltitude); QCOMPARE(item.param7(), MissionItem::defaultAltitude);
} }
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.
...@@ -71,7 +71,7 @@ TextField { ...@@ -71,7 +71,7 @@ TextField {
} }
onActiveFocusChanged: { onActiveFocusChanged: {
if (activeFocus) { if (!ScreenTools.isMobile && activeFocus) {
selectAll() selectAll()
} }
} }
......
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.
...@@ -37,6 +37,7 @@ MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) : ...@@ -37,6 +37,7 @@ MAVLinkDecoder::MAVLinkDecoder(MAVLinkProtocol* protocol, QObject *parent) :
messageFilter.insert(MAVLINK_MSG_ID_DATA_STREAM, false); messageFilter.insert(MAVLINK_MSG_ID_DATA_STREAM, false);
messageFilter.insert(MAVLINK_MSG_ID_GPS_STATUS, false); messageFilter.insert(MAVLINK_MSG_ID_GPS_STATUS, false);
messageFilter.insert(MAVLINK_MSG_ID_RC_CHANNELS_RAW, false); messageFilter.insert(MAVLINK_MSG_ID_RC_CHANNELS_RAW, false);
messageFilter.insert(MAVLINK_MSG_ID_LOG_DATA, false);
#ifdef MAVLINK_MSG_ID_ENCAPSULATED_DATA #ifdef MAVLINK_MSG_ID_ENCAPSULATED_DATA
messageFilter.insert(MAVLINK_MSG_ID_ENCAPSULATED_DATA, false); messageFilter.insert(MAVLINK_MSG_ID_ENCAPSULATED_DATA, false);
#endif #endif
......
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