10#include <QtPositioning/QGeoPositionInfo>
18 , _gcsMotionReportTimer(new QTimer(this))
22 _gcsMotionReportTimer->setSingleShot(
false);
26 _gcsMotionReportTimer->setInterval(kMotionUpdateInterval);
36 return _followMeInstance();
41 static bool once =
false;
43 (void) connect(_gcsMotionReportTimer, &QTimer::timeout,
this, &FollowMe::_sendGCSMotionReport);
46 _settingsChanged(SettingsManager::instance()->appSettings()->followTarget()->rawValue());
51void FollowMe::_settingsChanged(QVariant value)
53 _currentMode =
static_cast<FollowMode
>(value.toUInt());
55 switch (_currentMode) {
69 _enableIfVehicleInFollow();
74void FollowMe::_enableFollowSend()
76 if (!_gcsMotionReportTimer->isActive()) {
77 _gcsMotionReportTimer->start();
81void FollowMe::_disableFollowSend()
83 if (_gcsMotionReportTimer->isActive()) {
84 _gcsMotionReportTimer->stop();
88void FollowMe::_sendGCSMotionReport()
90 const QGeoPositionInfo geoPositionInfo = QGCPositionManager::instance()->geoPositionInfo();
91 const QGeoCoordinate gcsCoordinate = geoPositionInfo.coordinate();
93 if (!geoPositionInfo.isValid()) {
98 bool needFollowMe =
false;
99 if (_currentMode == MODE_ALWAYS) {
101 }
else if (_currentMode == MODE_FOLLOWME) {
103 for (
int i = 0; i < vehicles->
count(); i++) {
105 if (_isFollowFlightMode(vehicle, vehicle->
flightMode())) {
114 GCSMotionReport motionReport{};
115 uint8_t estimationCapabilities = 0;
119 motionReport.lat_int =
static_cast<int>(gcsCoordinate.latitude() * 1e7);
120 motionReport.lon_int =
static_cast<int>(gcsCoordinate.longitude() * 1e7);
121 motionReport.altMetersAMSL = gcsCoordinate.altitude();
122 estimationCapabilities |= (1 <<
POS);
124 if (geoPositionInfo.hasAttribute(QGeoPositionInfo::Direction)) {
125 estimationCapabilities |= (1 <<
HEADING);
126 motionReport.headingDegrees = geoPositionInfo.attribute(QGeoPositionInfo::Direction);
130 if (geoPositionInfo.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
131 motionReport.pos_std_dev[0] = motionReport.pos_std_dev[1] = geoPositionInfo.attribute(QGeoPositionInfo::HorizontalAccuracy);
135 if (geoPositionInfo.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
136 motionReport.pos_std_dev[2] = geoPositionInfo.attribute(QGeoPositionInfo::VerticalAccuracy);
140 if (geoPositionInfo.hasAttribute(QGeoPositionInfo::VerticalSpeed)) {
141 motionReport.vzMetersPerSec = geoPositionInfo.attribute(QGeoPositionInfo::VerticalSpeed);
145 if (geoPositionInfo.hasAttribute(QGeoPositionInfo::Direction) && geoPositionInfo.hasAttribute(QGeoPositionInfo::GroundSpeed)) {
146 estimationCapabilities |= (1 <<
VEL);
148 const qreal direction = qDegreesToRadians(geoPositionInfo.attribute(QGeoPositionInfo::Direction));
149 const qreal velocity = geoPositionInfo.attribute(QGeoPositionInfo::GroundSpeed);
151 motionReport.vxMetersPerSec = cos(direction) * velocity;
152 motionReport.vyMetersPerSec = sin(direction) * velocity;
154 motionReport.vxMetersPerSec = 0;
155 motionReport.vyMetersPerSec = 0;
160 for (
int i = 0; i < vehicles->
count(); i++) {
162 if ((_currentMode == MODE_ALWAYS) || (_isFollowFlightMode(vehicle, vehicle->
flightMode()))) {
163 qCDebug(FollowMeLog) <<
"sendGCSMotionReport latInt:lonInt:altMetersAMSL" << motionReport.lat_int << motionReport.lon_int << motionReport.altMetersAMSL;
169void FollowMe::_vehicleAdded(
Vehicle *vehicle)
172 _enableIfVehicleInFollow();
175void FollowMe::_vehicleRemoved(
Vehicle *vehicle)
178 _enableIfVehicleInFollow();
181void FollowMe::_enableIfVehicleInFollow()
183 if (_currentMode == MODE_ALWAYS) {
190 for (
int i = 0; i < vehicles->
count(); i++) {
192 if (_isFollowFlightMode(vehicle, vehicle->
flightMode())) {
198 _disableFollowSend();
201bool FollowMe::_isFollowFlightMode(
const Vehicle *vehicle,
const QString &flightMode)
Q_APPLICATION_STATIC(FollowMe, _followMeInstance)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Fact *followTarget READ followTarget CONSTANT Fact * followTarget()
void rawValueChanged(const QVariant &value)
virtual void sendGCSMotionReport(Vehicle *vehicle, const FollowMe::GCSMotionReport &motionReport, uint8_t estimationCapabilities) const
Sends the appropriate mavlink message for follow me support.
static FollowMe * instance()
void vehicleAdded(Vehicle *vehicle)
void vehicleRemoved(Vehicle *vehicle)
int count() const override final
QString flightMode() const
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
QString followFlightMode() const
void flightModeChanged(const QString &flightMode)