|
|
|
@ -16,25 +16,37 @@
@@ -16,25 +16,37 @@
|
|
|
|
|
#include "FollowMe.h" |
|
|
|
|
#include "Vehicle.h" |
|
|
|
|
#include "PositionManager.h" |
|
|
|
|
#include "SettingsManager.h" |
|
|
|
|
#include "AppSettings.h" |
|
|
|
|
|
|
|
|
|
FollowMe::FollowMe(QGCApplication* app, QGCToolbox* toolbox) |
|
|
|
|
: QGCTool(app, toolbox), estimatation_capabilities(0) |
|
|
|
|
, _manualControl(false) |
|
|
|
|
{ |
|
|
|
|
memset(&_motionReport, 0, sizeof(motionReport_s)); |
|
|
|
|
runTime.start(); |
|
|
|
|
_gcsMotionReportTimer.setSingleShot(false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FollowMe::setToolbox(QGCToolbox* toolbox) |
|
|
|
|
{ |
|
|
|
|
QGCTool::setToolbox(toolbox); |
|
|
|
|
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&) |
|
|
|
|
{ |
|
|
|
|
if(!_manualControl) { |
|
|
|
|
//-- If we are to change based on current flight mode
|
|
|
|
|
if(_currentMode == MODE_FOLLOWME) { |
|
|
|
|
QmlObjectListModel & vehicles = *_toolbox->multiVehicleManager()->vehicles(); |
|
|
|
|
for (int i=0; i< vehicles.count(); i++) { |
|
|
|
|
Vehicle* vehicle = qobject_cast<Vehicle*>(vehicles[i]); |
|
|
|
|
if (vehicle->px4Firmware() && vehicle->flightMode().compare(FirmwarePlugin::px4FollowMeFlightMode, Qt::CaseInsensitive) == 0) { |
|
|
|
|
_enable(_toolbox->qgcPositionManager()->updateInterval()); |
|
|
|
|
_enable(); |
|
|
|
|
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; |
|
|
|
|
_enable(interval); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void FollowMe::manualDisable() |
|
|
|
|
{ |
|
|
|
|
_manualControl = false; |
|
|
|
|
_disable(); |
|
|
|
|
uint32_t mode = _toolbox->settingsManager()->appSettings()->followTarget()->rawValue().toUInt(); |
|
|
|
|
if(_currentMode != mode) { |
|
|
|
|
_currentMode = mode; |
|
|
|
|
switch (mode) { |
|
|
|
|
case MODE_NEVER: |
|
|
|
|
if(_gcsMotionReportTimer.isActive()) { |
|
|
|
|
_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(), |
|
|
|
|
SIGNAL(positionInfoUpdated(QGeoPositionInfo)), |
|
|
|
|
this, |
|
|
|
|
SLOT(_setGPSLocation(QGeoPositionInfo))); |
|
|
|
|
_gcsMotionReportTimer.setInterval(interval); |
|
|
|
|
_gcsMotionReportTimer.setInterval(_toolbox->qgcPositionManager()->updateInterval()); |
|
|
|
|
_gcsMotionReportTimer.start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -75,15 +102,17 @@ void FollowMe::_disable()
@@ -75,15 +102,17 @@ void FollowMe::_disable()
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate(); |
|
|
|
|
|
|
|
|
|
_motionReport.lat_int = geoCoordinate.latitude()*1e7; |
|
|
|
|
_motionReport.lon_int = geoCoordinate.longitude()*1e7; |
|
|
|
|
_motionReport.alt = geoCoordinate.altitude(); |
|
|
|
|
_motionReport.lat_int = geoCoordinate.latitude() * 1e7; |
|
|
|
|
_motionReport.lon_int = geoCoordinate.longitude() * 1e7; |
|
|
|
|
_motionReport.alt = geoCoordinate.altitude(); |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
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.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(); |
|
|
|
|
mavlink_follow_target_t 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.position_cov[0] = _motionReport.pos_std_dev[0]; |
|
|
|
|
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++) { |
|
|
|
|
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_msg_follow_target_encode_chan(mavlinkProtocol->getSystemId(), |
|
|
|
|
mavlinkProtocol->getComponentId(), |
|
|
|
|