Commit 9b97ac30 authored by Gus Grubba's avatar Gus Grubba

Make Follow Target stream a setting.

parent 1501aca1
...@@ -16,25 +16,37 @@ ...@@ -16,25 +16,37 @@
#include "FollowMe.h" #include "FollowMe.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "PositionManager.h" #include "PositionManager.h"
#include "SettingsManager.h"
#include "AppSettings.h"
FollowMe::FollowMe(QGCApplication* app, QGCToolbox* toolbox) FollowMe::FollowMe(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox), estimatation_capabilities(0) : QGCTool(app, toolbox), estimatation_capabilities(0)
, _manualControl(false)
{ {
memset(&_motionReport, 0, sizeof(motionReport_s)); memset(&_motionReport, 0, sizeof(motionReport_s));
runTime.start(); runTime.start();
_gcsMotionReportTimer.setSingleShot(false); _gcsMotionReportTimer.setSingleShot(false);
}
void FollowMe::setToolbox(QGCToolbox* toolbox)
{
QGCTool::setToolbox(toolbox);
connect(&_gcsMotionReportTimer, &QTimer::timeout, this, &FollowMe::_sendGCSMotionReport); connect(&_gcsMotionReportTimer, &QTimer::timeout, this, &FollowMe::_sendGCSMotionReport);
connect(toolbox->settingsManager()->appSettings()->followTarget(), &Fact::rawValueChanged, this, &FollowMe::_settingsChanged);
_currentMode = _toolbox->settingsManager()->appSettings()->followTarget()->rawValue().toUInt();
if(_currentMode == MODE_ALWAYS) {
_enable();
}
} }
void FollowMe::followMeHandleManager(const QString&) void FollowMe::followMeHandleManager(const QString&)
{ {
if(!_manualControl) { //-- If we are to change based on current flight mode
if(_currentMode == MODE_FOLLOWME) {
QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles(); QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles();
for (int i=0; i< vehicles.count(); i++) { for (int i=0; i< vehicles.count(); i++) {
Vehicle* vehicle = qobject_cast<Vehicle*>(vehicles[i]); Vehicle* vehicle = qobject_cast<Vehicle*>(vehicles[i]);
if (vehicle->px4Firmware() && vehicle->flightMode().compare(FirmwarePlugin::px4FollowMeFlightMode, Qt::CaseInsensitive) == 0) { if (vehicle->px4Firmware() && vehicle->flightMode().compare(FirmwarePlugin::px4FollowMeFlightMode, Qt::CaseInsensitive) == 0) {
_enable(_toolbox->qgcPositionManager()->updateInterval()); _enable();
return; return;
} }
} }
...@@ -42,25 +54,40 @@ void FollowMe::followMeHandleManager(const QString&) ...@@ -42,25 +54,40 @@ void FollowMe::followMeHandleManager(const QString&)
} }
} }
void FollowMe::manualEnable(int interval) void FollowMe::_settingsChanged()
{ {
_manualControl = true; uint32_t mode = _toolbox->settingsManager()->appSettings()->followTarget()->rawValue().toUInt();
_enable(interval); if(_currentMode != mode) {
} _currentMode = mode;
switch (mode) {
void FollowMe::manualDisable() case MODE_NEVER:
{ if(_gcsMotionReportTimer.isActive()) {
_manualControl = false; _disable();
_disable(); }
break;
case MODE_ALWAYS:
if(!_gcsMotionReportTimer.isActive()) {
_enable();
}
break;
case MODE_FOLLOWME:
if(!_gcsMotionReportTimer.isActive()) {
followMeHandleManager(QString());
}
break;
default:
break;
}
}
} }
void FollowMe::_enable(int interval) void FollowMe::_enable()
{ {
connect(_toolbox->qgcPositionManager(), connect(_toolbox->qgcPositionManager(),
SIGNAL(positionInfoUpdated(QGeoPositionInfo)), SIGNAL(positionInfoUpdated(QGeoPositionInfo)),
this, this,
SLOT(_setGPSLocation(QGeoPositionInfo))); SLOT(_setGPSLocation(QGeoPositionInfo)));
_gcsMotionReportTimer.setInterval(interval); _gcsMotionReportTimer.setInterval(_toolbox->qgcPositionManager()->updateInterval());
_gcsMotionReportTimer.start(); _gcsMotionReportTimer.start();
} }
...@@ -75,15 +102,17 @@ void FollowMe::_disable() ...@@ -75,15 +102,17 @@ void FollowMe::_disable()
void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo) void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo)
{ {
if (geoPositionInfo.isValid()) if (!geoPositionInfo.isValid()) {
{ //-- Invalidate cached coordinates
memset(&_motionReport, 0, sizeof(motionReport_s));
} else {
// get the current location coordinates // get the current location coordinates
QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate(); QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
_motionReport.lat_int = geoCoordinate.latitude()*1e7; _motionReport.lat_int = geoCoordinate.latitude() * 1e7;
_motionReport.lon_int = geoCoordinate.longitude()*1e7; _motionReport.lon_int = geoCoordinate.longitude() * 1e7;
_motionReport.alt = geoCoordinate.altitude(); _motionReport.alt = geoCoordinate.altitude();
estimatation_capabilities |= (1 << POS); estimatation_capabilities |= (1 << POS);
...@@ -111,7 +140,7 @@ void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo) ...@@ -111,7 +140,7 @@ void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo)
estimatation_capabilities |= (1 << VEL); estimatation_capabilities |= (1 << VEL);
qreal direction = _degreesToRadian(geoPositionInfo.attribute(QGeoPositionInfo::Direction)); qreal direction = _degreesToRadian(geoPositionInfo.attribute(QGeoPositionInfo::Direction));
qreal velocity = geoPositionInfo.attribute(QGeoPositionInfo::GroundSpeed); qreal velocity = geoPositionInfo.attribute(QGeoPositionInfo::GroundSpeed);
_motionReport.vx = cos(direction)*velocity; _motionReport.vx = cos(direction)*velocity;
_motionReport.vy = sin(direction)*velocity; _motionReport.vy = sin(direction)*velocity;
...@@ -123,15 +152,20 @@ void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo) ...@@ -123,15 +152,20 @@ void FollowMe::_setGPSLocation(QGeoPositionInfo geoPositionInfo)
} }
} }
void FollowMe::_sendGCSMotionReport(void) void FollowMe::_sendGCSMotionReport()
{ {
QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles();
//-- Do we have any real data?
if(_motionReport.lat_int == 0 && _motionReport.lon_int == 0 && _motionReport.alt == 0) {
return;
}
QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles();
MAVLinkProtocol* mavlinkProtocol = _toolbox->mavlinkProtocol(); MAVLinkProtocol* mavlinkProtocol = _toolbox->mavlinkProtocol();
mavlink_follow_target_t follow_target; mavlink_follow_target_t follow_target;
memset(&follow_target, 0, sizeof(follow_target)); memset(&follow_target, 0, sizeof(follow_target));
follow_target.timestamp = runTime.nsecsElapsed()*1e-6; follow_target.timestamp = runTime.nsecsElapsed() * 1e-6;
follow_target.est_capabilities = estimatation_capabilities; follow_target.est_capabilities = estimatation_capabilities;
follow_target.position_cov[0] = _motionReport.pos_std_dev[0]; follow_target.position_cov[0] = _motionReport.pos_std_dev[0];
follow_target.position_cov[2] = _motionReport.pos_std_dev[2]; follow_target.position_cov[2] = _motionReport.pos_std_dev[2];
...@@ -143,7 +177,7 @@ void FollowMe::_sendGCSMotionReport(void) ...@@ -143,7 +177,7 @@ void FollowMe::_sendGCSMotionReport(void)
for (int i=0; i< vehicles.count(); i++) { for (int i=0; i< vehicles.count(); i++) {
Vehicle* vehicle = qobject_cast<Vehicle*>(vehicles[i]); Vehicle* vehicle = qobject_cast<Vehicle*>(vehicles[i]);
if(_manualControl || vehicle->flightMode().compare(FirmwarePlugin::px4FollowMeFlightMode, Qt::CaseInsensitive) == 0) { if(_currentMode || vehicle->flightMode().compare(FirmwarePlugin::px4FollowMeFlightMode, Qt::CaseInsensitive) == 0) {
mavlink_message_t message; mavlink_message_t message;
mavlink_msg_follow_target_encode_chan(mavlinkProtocol->getSystemId(), mavlink_msg_follow_target_encode_chan(mavlinkProtocol->getSystemId(),
mavlinkProtocol->getComponentId(), mavlinkProtocol->getComponentId(),
......
...@@ -29,15 +29,15 @@ class FollowMe : public QGCTool ...@@ -29,15 +29,15 @@ class FollowMe : public QGCTool
public: public:
FollowMe(QGCApplication* app, QGCToolbox* toolbox); FollowMe(QGCApplication* app, QGCToolbox* toolbox);
void manualEnable (int interval); void setToolbox(QGCToolbox* toolbox) override;
void manualDisable ();
public slots: public slots:
void followMeHandleManager(const QString&); void followMeHandleManager (const QString&);
private slots: private slots:
void _setGPSLocation(QGeoPositionInfo geoPositionInfo); void _setGPSLocation (QGeoPositionInfo geoPositionInfo);
void _sendGCSMotionReport(void); void _sendGCSMotionReport ();
void _settingsChanged ();
private: private:
QElapsedTimer runTime; QElapsedTimer runTime;
...@@ -69,9 +69,15 @@ private: ...@@ -69,9 +69,15 @@ private:
uint8_t estimatation_capabilities; uint8_t estimatation_capabilities;
void _disable (); void _disable ();
void _enable (int interval); void _enable ();
double _degreesToRadian(double deg); double _degreesToRadian(double deg);
bool _manualControl; enum {
MODE_NEVER,
MODE_ALWAYS,
MODE_FOLLOWME
};
uint32_t _currentMode;
}; };
...@@ -183,5 +183,13 @@ ...@@ -183,5 +183,13 @@
"shortDescription": "Default firmware type for flashing", "shortDescription": "Default firmware type for flashing",
"type": "uint32", "type": "uint32",
"defaultValue": 12 "defaultValue": 12
},
{
"name": "FollowTarget",
"shortDescription": "Stream GCS' coordinates to Autopilot",
"type": "uint32",
"enumStrings": "Never,Always,When in Follow Me Flight Mode",
"enumValues": "0,1,2",
"defaultValue": 0
} }
] ]
...@@ -37,6 +37,7 @@ const char* AppSettings::mapboxTokenName = "MapboxT ...@@ -37,6 +37,7 @@ const char* AppSettings::mapboxTokenName = "MapboxT
const char* AppSettings::esriTokenName = "EsriToken"; const char* AppSettings::esriTokenName = "EsriToken";
const char* AppSettings::defaultFirmwareTypeName = "DefaultFirmwareType"; const char* AppSettings::defaultFirmwareTypeName = "DefaultFirmwareType";
const char* AppSettings::gstDebugName = "GstreamerDebugLevel"; const char* AppSettings::gstDebugName = "GstreamerDebugLevel";
const char* AppSettings::followTargetName = "FollowTarget";
const char* AppSettings::parameterFileExtension = "params"; const char* AppSettings::parameterFileExtension = "params";
const char* AppSettings::planFileExtension = "plan"; const char* AppSettings::planFileExtension = "plan";
...@@ -78,6 +79,7 @@ AppSettings::AppSettings(QObject* parent) ...@@ -78,6 +79,7 @@ AppSettings::AppSettings(QObject* parent)
, _esriTokenFact (NULL) , _esriTokenFact (NULL)
, _defaultFirmwareTypeFact (NULL) , _defaultFirmwareTypeFact (NULL)
, _gstDebugFact (NULL) , _gstDebugFact (NULL)
, _followTargetFact (NULL)
{ {
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
qmlRegisterUncreatableType<AppSettings>("QGroundControl.SettingsManager", 1, 0, "AppSettings", "Reference only"); qmlRegisterUncreatableType<AppSettings>("QGroundControl.SettingsManager", 1, 0, "AppSettings", "Reference only");
...@@ -403,3 +405,13 @@ Fact* AppSettings::defaultFirmwareType(void) ...@@ -403,3 +405,13 @@ Fact* AppSettings::defaultFirmwareType(void)
return _defaultFirmwareTypeFact; return _defaultFirmwareTypeFact;
} }
Fact* AppSettings::followTarget(void)
{
if (!_followTargetFact) {
_followTargetFact = _createSettingsFact(followTargetName);
}
return _followTargetFact;
}
...@@ -41,6 +41,7 @@ public: ...@@ -41,6 +41,7 @@ public:
Q_PROPERTY(Fact* esriToken READ esriToken CONSTANT) Q_PROPERTY(Fact* esriToken READ esriToken CONSTANT)
Q_PROPERTY(Fact* defaultFirmwareType READ defaultFirmwareType CONSTANT) Q_PROPERTY(Fact* defaultFirmwareType READ defaultFirmwareType CONSTANT)
Q_PROPERTY(Fact* gstDebug READ gstDebug CONSTANT) Q_PROPERTY(Fact* gstDebug READ gstDebug CONSTANT)
Q_PROPERTY(Fact* followTarget READ followTarget CONSTANT)
Q_PROPERTY(QString missionSavePath READ missionSavePath NOTIFY savePathsChanged) Q_PROPERTY(QString missionSavePath READ missionSavePath NOTIFY savePathsChanged)
Q_PROPERTY(QString parameterSavePath READ parameterSavePath NOTIFY savePathsChanged) Q_PROPERTY(QString parameterSavePath READ parameterSavePath NOTIFY savePathsChanged)
...@@ -78,6 +79,7 @@ public: ...@@ -78,6 +79,7 @@ public:
Fact* esriToken (void); Fact* esriToken (void);
Fact* defaultFirmwareType (void); Fact* defaultFirmwareType (void);
Fact* gstDebug (void); Fact* gstDebug (void);
Fact* followTarget (void);
QString missionSavePath (void); QString missionSavePath (void);
QString parameterSavePath (void); QString parameterSavePath (void);
...@@ -112,6 +114,7 @@ public: ...@@ -112,6 +114,7 @@ public:
static const char* esriTokenName; static const char* esriTokenName;
static const char* defaultFirmwareTypeName; static const char* defaultFirmwareTypeName;
static const char* gstDebugName; static const char* gstDebugName;
static const char* followTargetName;
// Application wide file extensions // Application wide file extensions
static const char* parameterFileExtension; static const char* parameterFileExtension;
...@@ -161,6 +164,7 @@ private: ...@@ -161,6 +164,7 @@ private:
SettingsFact* _esriTokenFact; SettingsFact* _esriTokenFact;
SettingsFact* _defaultFirmwareTypeFact; SettingsFact* _defaultFirmwareTypeFact;
SettingsFact* _gstDebugFact; SettingsFact* _gstDebugFact;
SettingsFact* _followTargetFact;
}; };
#endif #endif
...@@ -41,6 +41,7 @@ QGCView { ...@@ -41,6 +41,7 @@ QGCView {
property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30
property Fact _mapProvider: QGroundControl.settingsManager.flightMapSettings.mapProvider property Fact _mapProvider: QGroundControl.settingsManager.flightMapSettings.mapProvider
property Fact _mapType: QGroundControl.settingsManager.flightMapSettings.mapType property Fact _mapType: QGroundControl.settingsManager.flightMapSettings.mapType
property Fact _followTarget: QGroundControl.settingsManager.appSettings.followTarget
property real _panelWidth: _qgcView.width * _internalWidthRatio property real _panelWidth: _qgcView.width * _internalWidthRatio
readonly property real _internalWidthRatio: 0.8 readonly property real _internalWidthRatio: 0.8
...@@ -245,6 +246,23 @@ QGCView { ...@@ -245,6 +246,23 @@ QGCView {
} }
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
//-- Follow Target
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _followTarget.visible
QGCLabel {
text: qsTr("Stream GCS Position:")
width: _labelWidth
anchors.verticalCenter: parent.verticalCenter
}
FactComboBox {
width: _editFieldWidth
fact: _followTarget
indexModel: false
anchors.verticalCenter: parent.verticalCenter
}
}
//-----------------------------------------------------------------
//-- Audio preferences //-- Audio preferences
FactCheckBox { FactCheckBox {
text: qsTr("Mute all audio output") text: qsTr("Mute all audio output")
......
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