Skip to content

Commit cfa8369

Browse files
committed
feat(gps): Comprehensive GPS subsystem improvements
1 parent 6515cd3 commit cfa8369

File tree

226 files changed

+13683
-2649
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

226 files changed

+13683
-2649
lines changed

qgcimages.qrc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@
100100
<file alias="GeoFence.svg">src/AutoPilotPlugins/PX4/Images/GeoFence.svg</file>
101101
<file alias="GeoFenceLight.svg">src/AutoPilotPlugins/PX4/Images/GeoFenceLight.svg</file>
102102
<file alias="GeoTagIcon.svg">src/AnalyzeView/GeoTag/GeoTagIcon.svg</file>
103-
<file alias="Gps.svg">src/UI/toolbar/Images/Gps.svg</file>
104-
<file alias="GpsAuthentication.svg">src/UI/toolbar/Images/GpsAuthentication.svg</file>
105-
<file alias="GpsInterference.svg">src/UI/toolbar/Images/GpsInterference.svg</file>
106103
<file alias="Hamburger.svg">src/UI/toolbar/Images/Hamburger.svg</file>
107104
<file alias="HamburgerThin.svg">src/UI/toolbar/Images/HamburgerThin.svg</file>
108105
<file alias="Help.svg">src/FlightMap/Images/Help.svg</file>
@@ -172,7 +169,6 @@
172169
<file alias="roi.svg">src/UI/toolbar/Images/roi.svg</file>
173170
<file alias="rollDialWhite.svg">src/FlightMap/Images/rollDialWhite.svg</file>
174171
<file alias="rollPointerWhite.svg">src/FlightMap/Images/rollPointerWhite.svg</file>
175-
<file alias="RTK.svg">src/UI/toolbar/Images/RTK.svg</file>
176172
<file alias="SafetyComponentIcon.png">src/AutoPilotPlugins/Common/Images/SafetyComponentIcon.png</file>
177173
<file alias="scale.png">src/FlightMap/Images/scale.png</file>
178174
<file alias="scale_end.png">src/FlightMap/Images/scale_end.png</file>

src/API/QGCCorePlugin.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ const QVariantList &QGCCorePlugin::analyzePages()
8282
tr("Vibration"),
8383
QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Vibration/VibrationPage.qml")),
8484
QUrl::fromUserInput(QStringLiteral("qrc:/qmlimages/VibrationPageIcon")))),
85+
QVariant::fromValue(new QmlComponentInfo(
86+
tr("Satellites"),
87+
QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Satellite/SatellitePage.qml")),
88+
QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/AnalyzeView/Satellite/SatelliteIcon.svg")))),
8589
};
8690

8791
return analyzeList;
@@ -302,7 +306,7 @@ const QVariantList &QGCCorePlugin::toolBarIndicators()
302306
{
303307
static const QVariantList toolBarIndicatorList = QVariantList(
304308
{
305-
QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/Toolbar/RTKGPSIndicator.qml"))),
309+
QVariant::fromValue(QUrl::fromUserInput(QStringLiteral("qrc:/qml/QGroundControl/GPS/RTK/RTKGPSIndicator.qml"))),
306310
}
307311
);
308312

src/AnalyzeView/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ qt_add_qml_module(AnalyzeViewModule
3131
MAVLinkInspector/MAVLinkMessageButton.qml
3232
MAVLinkInspector/MAVLinkInspectorPage.qml
3333
OnboardLogs/OnboardLogPage.qml
34+
Satellite/SatellitePage.qml
3435
Vibration/VibrationPage.qml
36+
RESOURCES
37+
Satellite/SatelliteIcon.svg
3538
NO_PLUGIN
3639
)

src/AnalyzeView/GeoTag/GeoTagPage.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import QtQuick.Layouts
55
import QGroundControl
66
import QGroundControl.AnalyzeView
77
import QGroundControl.Controls
8+
import "qrc:/qml/QGroundControl/GPS/GPSFormatHelpers.js" as GPSHelpers
89

910
AnalyzePage {
1011
id: geoTagPage
@@ -530,7 +531,7 @@ AnalyzePage {
530531
Layout.preferredWidth: ScreenTools.defaultFontPixelWidth * 20
531532
text: {
532533
if (model.coordinate && model.coordinate.isValid) {
533-
return model.coordinate.latitude.toFixed(6) + ", " + model.coordinate.longitude.toFixed(6)
534+
return GPSHelpers.formatCoordinate(model.coordinate.latitude, model.coordinate.longitude, 6)
534535
}
535536
return ""
536537
}
Lines changed: 11 additions & 0 deletions
Loading
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import QtQuick
2+
import QtQuick.Controls
3+
import QtQuick.Layouts
4+
5+
import QGroundControl
6+
import QGroundControl.Controls
7+
import QGroundControl.FactControls
8+
import QGroundControl.GPS.RTK
9+
10+
AnalyzePage {
11+
id: satellitePage
12+
pageComponent: pageComponent
13+
pageDescription: qsTr("Real-time satellite sky plot and signal strength from connected GPS receivers.")
14+
allowPopout: true
15+
16+
property var _posMgr: QGroundControl.qgcPositionManger
17+
property var _gpsMgr: QGroundControl.gpsManager
18+
property var _gcsModel: _posMgr ? _posMgr.gcsSatelliteModel : null
19+
property var _rtkModel: _gpsMgr ? _gpsMgr.rtkSatelliteModel : null
20+
property bool _hasGcs: !!_gcsModel && _gcsModel.satellitesInView > 0
21+
property bool _hasRtk: !!_rtkModel && _rtkModel.count > 0
22+
23+
QGCPalette { id: qgcPal }
24+
25+
Component {
26+
id: pageComponent
27+
28+
Item {
29+
width: childrenRect.width
30+
height: childrenRect.height
31+
32+
ColumnLayout {
33+
spacing: ScreenTools.defaultFontPixelHeight
34+
35+
QGCLabel {
36+
visible: !_hasGcs && !_hasRtk
37+
text: qsTr("No satellite data available. Connect an RTK base station or NMEA GPS source.")
38+
color: qgcPal.colorGrey
39+
}
40+
41+
RowLayout {
42+
spacing: ScreenTools.defaultFontPixelHeight * 2
43+
visible: _hasGcs || _hasRtk
44+
45+
ColumnLayout {
46+
spacing: ScreenTools.defaultFontPixelHeight * 0.5
47+
visible: _hasGcs
48+
49+
QGCLabel {
50+
text: qsTr("GCS Position Source")
51+
font.bold: true
52+
}
53+
54+
QGCLabel {
55+
text: _gcsModel ? qsTr("%1 in view, %2 in use").arg(_gcsModel.satellitesInView).arg(_gcsModel.satellitesInUse) : ""
56+
font.pointSize: ScreenTools.smallFontPointSize
57+
color: qgcPal.colorGrey
58+
}
59+
60+
QGCLabel {
61+
text: _gcsModel ? _gcsModel.constellationSummary : ""
62+
font.pointSize: ScreenTools.smallFontPointSize
63+
color: qgcPal.colorGrey
64+
visible: text !== ""
65+
}
66+
67+
SatelliteSkyPlot {
68+
satelliteModel: _gcsModel
69+
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 16
70+
Layout.preferredHeight: Layout.preferredWidth
71+
}
72+
73+
Row {
74+
id: gcsSignalRow
75+
spacing: 1
76+
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 16
77+
78+
Repeater {
79+
model: _gcsModel
80+
81+
SignalStrengthBar {
82+
width: Math.max(3, (gcsSignalRow.Layout.preferredWidth - (_gcsModel.satellitesInView - 1)) / Math.max(1, _gcsModel.satellitesInView))
83+
barHeight: ScreenTools.defaultFontPixelHeight * 3
84+
snr: model.signalStrength
85+
used: model.inUse
86+
}
87+
}
88+
}
89+
}
90+
91+
ColumnLayout {
92+
spacing: ScreenTools.defaultFontPixelHeight * 0.5
93+
visible: _hasRtk
94+
95+
QGCLabel {
96+
text: qsTr("RTK Base Station")
97+
font.bold: true
98+
}
99+
100+
QGCLabel {
101+
text: _rtkModel ? qsTr("%1 in view, %2 in use").arg(_rtkModel.count).arg(_rtkModel.usedCount) : ""
102+
font.pointSize: ScreenTools.smallFontPointSize
103+
color: qgcPal.colorGrey
104+
}
105+
106+
QGCLabel {
107+
text: _rtkModel ? _rtkModel.constellationSummary : ""
108+
font.pointSize: ScreenTools.smallFontPointSize
109+
color: qgcPal.colorGrey
110+
visible: text !== ""
111+
}
112+
113+
Row {
114+
id: rtkSignalRow
115+
spacing: 1
116+
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 16
117+
118+
Repeater {
119+
model: _rtkModel
120+
121+
SignalStrengthBar {
122+
width: Math.max(3, (rtkSignalRow.Layout.preferredWidth - (_rtkModel.count - 1)) / Math.max(1, _rtkModel.count))
123+
barHeight: ScreenTools.defaultFontPixelHeight * 3
124+
snr: model.snr
125+
used: model.used
126+
}
127+
}
128+
}
129+
}
130+
}
131+
132+
RowLayout {
133+
spacing: ScreenTools.defaultFontPixelHeight
134+
visible: _hasGcs || _hasRtk
135+
136+
Rectangle {
137+
width: ScreenTools.defaultFontPixelHeight * 0.75
138+
height: width; radius: width / 2
139+
color: qgcPal.colorGreen
140+
}
141+
QGCLabel { text: qsTr("Strong (SNR ≥ 35)"); font.pointSize: ScreenTools.smallFontPointSize }
142+
143+
Rectangle {
144+
width: ScreenTools.defaultFontPixelHeight * 0.75
145+
height: width; radius: width / 2
146+
color: qgcPal.colorOrange
147+
}
148+
QGCLabel { text: qsTr("Medium (SNR 20–34)"); font.pointSize: ScreenTools.smallFontPointSize }
149+
150+
Rectangle {
151+
width: ScreenTools.defaultFontPixelHeight * 0.75
152+
height: width; radius: width / 2
153+
color: qgcPal.colorRed
154+
}
155+
QGCLabel { text: qsTr("Weak (SNR < 20)"); font.pointSize: ScreenTools.smallFontPointSize }
156+
157+
Rectangle {
158+
width: ScreenTools.defaultFontPixelHeight * 0.75
159+
height: width; radius: width / 2
160+
color: qgcPal.colorGrey
161+
}
162+
QGCLabel { text: qsTr("Not in use"); font.pointSize: ScreenTools.smallFontPointSize }
163+
}
164+
}
165+
}
166+
}
167+
}

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_subdirectory(FirmwarePlugin)
3939
add_subdirectory(FlyView)
4040
add_subdirectory(FlightMap)
4141
add_subdirectory(FollowMe)
42+
add_subdirectory(GCSGeofence)
4243
add_subdirectory(Gimbal)
4344
add_subdirectory(GPS)
4445
add_subdirectory(Utilities)
@@ -131,6 +132,10 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
131132
FirstRunPromptDialogsModule
132133
FlyViewModule
133134
FlightMapModule
135+
GCSGeofenceModule
136+
GPSModule
137+
GPSNTRIPModule
138+
GPSRTKModule
134139
PlanViewModule
135140
QGroundControlControlsModule
136141
QGroundControlModule

src/Comms/LinkManager.cc

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717
#ifndef QGC_NO_SERIAL_LINK
1818
#include "SerialLink.h"
1919
#include "GPSManager.h"
20-
#include "PositionManager.h"
21-
#include "UdpIODevice.h"
22-
#include "GPSRtk.h"
2320
#endif
2421

2522
#ifdef QT_DEBUG
@@ -38,9 +35,6 @@ LinkManager::LinkManager(QObject *parent)
3835
: QObject(parent)
3936
, _portListTimer(new QTimer(this))
4037
, _qmlConfigurations(new QmlObjectListModel(this))
41-
#ifndef QGC_NO_SERIAL_LINK
42-
, _nmeaSocket(new UdpIODevice(this))
43-
#endif
4438
{
4539
qCDebug(LinkManagerLog) << this;
4640

@@ -432,26 +426,6 @@ void LinkManager::_updateAutoConnectLinks()
432426
_addUDPAutoConnectLink();
433427
_addMAVLinkForwardingLink();
434428

435-
// check to see if nmea gps is configured for UDP input, if so, set it up to connect
436-
if (_autoConnectSettings->autoConnectNmeaPort()->cookedValueString() == "UDP Port") {
437-
if ((_nmeaSocket->localPort() != _autoConnectSettings->nmeaUdpPort()->rawValue().toUInt()) || (_nmeaSocket->state() != UdpIODevice::BoundState)) {
438-
qCDebug(LinkManagerLog) << "Changing port for UDP NMEA stream";
439-
_nmeaSocket->close();
440-
_nmeaSocket->bind(QHostAddress::AnyIPv4, _autoConnectSettings->nmeaUdpPort()->rawValue().toUInt());
441-
QGCPositionManager::instance()->setNmeaSourceDevice(_nmeaSocket);
442-
}
443-
#ifndef QGC_NO_SERIAL_LINK
444-
if (_nmeaPort) {
445-
_nmeaPort->close();
446-
delete _nmeaPort;
447-
_nmeaPort = nullptr;
448-
_nmeaDeviceName = "";
449-
}
450-
#endif
451-
} else {
452-
_nmeaSocket->close();
453-
}
454-
455429
#ifndef QGC_NO_SERIAL_LINK
456430
_addSerialAutoConnectLink();
457431
#endif
@@ -758,27 +732,7 @@ void LinkManager::_addSerialAutoConnectLink()
758732
QGCSerialPortInfo::BoardType_t boardType;
759733
QString boardName;
760734

761-
// check to see if nmea gps is configured for current Serial port, if so, set it up to connect
762-
if (portInfo.systemLocation().trimmed() == _autoConnectSettings->autoConnectNmeaPort()->cookedValueString()) {
763-
if (portInfo.systemLocation().trimmed() != _nmeaDeviceName) {
764-
_nmeaDeviceName = portInfo.systemLocation().trimmed();
765-
qCDebug(LinkManagerLog) << "Configuring nmea port" << _nmeaDeviceName;
766-
QSerialPort* newPort = new QSerialPort(portInfo, this);
767-
_nmeaBaud = _autoConnectSettings->autoConnectNmeaBaud()->cookedValue().toUInt();
768-
newPort->setBaudRate(static_cast<qint32>(_nmeaBaud));
769-
qCDebug(LinkManagerLog) << "Configuring nmea baudrate" << _nmeaBaud;
770-
// This will stop polling old device if previously set
771-
QGCPositionManager::instance()->setNmeaSourceDevice(newPort);
772-
if (_nmeaPort) {
773-
delete _nmeaPort;
774-
}
775-
_nmeaPort = newPort;
776-
} else if (_autoConnectSettings->autoConnectNmeaBaud()->cookedValue().toUInt() != _nmeaBaud) {
777-
_nmeaBaud = _autoConnectSettings->autoConnectNmeaBaud()->cookedValue().toUInt();
778-
_nmeaPort->setBaudRate(static_cast<qint32>(_nmeaBaud));
779-
qCDebug(LinkManagerLog) << "Configuring nmea baudrate" << _nmeaBaud;
780-
}
781-
} else if (portInfo.getBoardInfo(boardType, boardName)) {
735+
if (portInfo.getBoardInfo(boardType, boardName)) {
782736
// Should we be auto-connecting to this board type?
783737
if (!_allowAutoConnectToBoard(boardType)) {
784738
continue;
@@ -789,7 +743,7 @@ void LinkManager::_addSerialAutoConnectLink()
789743
qCDebug(LinkManagerLog) << "Waiting for bootloader to finish" << portInfo.systemLocation();
790744
continue;
791745
}
792-
if (_portAlreadyConnected(portInfo.systemLocation()) || (_autoConnectRTKPort == portInfo.systemLocation())) {
746+
if (_portAlreadyConnected(portInfo.systemLocation()) || _autoConnectRTKPorts.contains(portInfo.systemLocation())) {
793747
qCDebug(LinkManagerVerboseLog) << "Skipping existing autoconnect" << portInfo.systemLocation();
794748
} else if (!_autoconnectPortWaitList.contains(portInfo.systemLocation())) {
795749
// We don't connect to the port the first time we see it. The ability to correctly detect whether we
@@ -812,9 +766,9 @@ void LinkManager::_addSerialAutoConnectLink()
812766
pSerialConfig = new SerialConfiguration(tr("%1 on %2 (AutoConnect)").arg(boardName, portInfo.portName().trimmed()));
813767
break;
814768
case QGCSerialPortInfo::BoardTypeRTKGPS:
815-
qCDebug(LinkManagerLog) << "RTK GPS auto-connected" << portInfo.portName().trimmed();
816-
_autoConnectRTKPort = portInfo.systemLocation();
817-
GPSManager::instance()->gpsRtk()->connectGPS(portInfo.systemLocation(), boardName);
769+
qCDebug(LinkManagerLog) << "RTK GPS auto-connected" << portInfo.portName().trimmed() << boardName;
770+
_autoConnectRTKPorts.append(portInfo.systemLocation());
771+
GPSManager::instance()->connectGPS(portInfo.systemLocation(), boardName);
818772
break;
819773
default:
820774
qCWarning(LinkManagerLog) << "Internal error: Unknown board type" << boardType;
@@ -835,11 +789,14 @@ void LinkManager::_addSerialAutoConnectLink()
835789
}
836790
}
837791

838-
// Check for RTK GPS connection gone
839-
if (!_autoConnectRTKPort.isEmpty() && !currentPorts.contains(_autoConnectRTKPort)) {
840-
qCDebug(LinkManagerLog) << "RTK GPS disconnected" << _autoConnectRTKPort;
841-
GPSManager::instance()->gpsRtk()->disconnectGPS();
842-
_autoConnectRTKPort.clear();
792+
// Check for RTK GPS connections gone
793+
for (int i = _autoConnectRTKPorts.size() - 1; i >= 0; --i) {
794+
const QString &port = _autoConnectRTKPorts.at(i);
795+
if (!currentPorts.contains(port)) {
796+
qCDebug(LinkManagerLog) << "RTK GPS disconnected" << port;
797+
GPSManager::instance()->disconnectGPS(port);
798+
_autoConnectRTKPorts.removeAt(i);
799+
}
843800
}
844801
}
845802

@@ -862,7 +819,7 @@ bool LinkManager::_allowAutoConnectToBoard(QGCSerialPortInfo::BoardType_t boardT
862819
}
863820
break;
864821
case QGCSerialPortInfo::BoardTypeRTKGPS:
865-
if (_autoConnectSettings->autoConnectRTKGPS()->rawValue().toBool() && !GPSManager::instance()->gpsRtk()->connected()) {
822+
if (_autoConnectSettings->autoConnectRTKGPS()->rawValue().toBool() && !GPSManager::instance()->connected()) {
866823
return true;
867824
}
868825
break;

0 commit comments

Comments
 (0)