3#include <QtCore/QDateTime>
7#ifndef QGC_NO_SERIAL_LINK
23bool isSaneCoord(
double lat,
double lon)
25 return qIsFinite(lat) && qIsFinite(lon) && !(lat == 0.0 && lon == 0.0) && qAbs(lat) <= 90.0 && qAbs(lon) <= 180.0;
46 const double lat = latF->
rawValue().toDouble();
47 const double lon = lonF->
rawValue().toDouble();
49 if (isSaneCoord(lat, lon)) {
50 return {QGeoCoordinate(lat, lon, veh->
coordinate().altitude()), QStringLiteral(
"Vehicle GPS")};
64 const QGeoCoordinate coord = veh->
coordinate();
65 if (coord.isValid() && isSaneCoord(coord.latitude(), coord.longitude())) {
66 return {coord, QStringLiteral(
"Vehicle EKF")};
71#ifndef QGC_NO_SERIAL_LINK
85 Fact* validF = rtkGroup->
getFact(QStringLiteral(
"valid"));
86 if (!validF || !validF->
rawValue().toBool())
89 Fact* latF = rtkGroup->
getFact(QStringLiteral(
"currentLatitude"));
90 Fact* lonF = rtkGroup->
getFact(QStringLiteral(
"currentLongitude"));
94 Fact* altF = rtkGroup->
getFact(QStringLiteral(
"currentAltitude"));
95 const double lat = latF->
rawValue().toDouble();
96 const double lon = lonF->
rawValue().toDouble();
97 const double alt = altF ? altF->
rawValue().toDouble() : 0.0;
99 if (isSaneCoord(lat, lon)) {
100 return {QGeoCoordinate(lat, lon, alt), QStringLiteral(
"RTK Base")};
112 const QGeoCoordinate coord = posMgr->
gcsPosition();
113 if (coord.isValid() && isSaneCoord(coord.latitude(), coord.longitude())) {
114 return {coord, QStringLiteral(
"GCS Position")};
123 _timer.setInterval(_normalInterval);
124 connect(&_timer, &QChronoTimer::timeout,
this, &NTRIPGgaProvider::_sendGGA);
136 auto* sourceFact = settings->ntripGgaPositionSource();
137 auto refreshSource = [
this, sourceFact]() {
138 _cachedSource =
static_cast<PositionSource>(sourceFact->rawValue().toUInt());
143 auto* intervalFact = settings->ntripGgaIntervalSec();
144 auto refreshInterval = [
this, intervalFact]() {
145 const uint seconds = intervalFact->rawValue().toUInt();
148 (seconds > 0) ? std::chrono::milliseconds{
static_cast<qint64
>(seconds) * 1000} :
kDefaultInterval;
149 if (_retryPhase == RetryPhase::Normal) {
150 _timer.setInterval(_normalInterval);
159 _providers[source] = std::move(provider);
164 _transport = transport;
167 _setRetryPhase(RetryPhase::Fast);
175 _transport =
nullptr;
179void NTRIPGgaProvider::_setRetryPhase(RetryPhase phase)
185void NTRIPGgaProvider::_clearSource()
187 if (_source.isEmpty()) {
194void NTRIPGgaProvider::_sendGGA()
200 _ensureDefaultProviders();
202 const auto position = _getBestPosition();
204 if (!position.isValid()) {
205 if (++_fastRetryCount >= 5 && _retryPhase == RetryPhase::Fast) {
206 _setRetryPhase(RetryPhase::Normal);
212 if (_retryPhase != RetryPhase::Normal) {
213 _setRetryPhase(RetryPhase::Normal);
216 double alt_msl = position.coordinate.altitude();
217 if (!qIsFinite(alt_msl)) {
222 _transport->sendNMEA(gga);
224 if (!position.source.isEmpty() && position.source != _source) {
225 _source = position.source;
230void NTRIPGgaProvider::_ensureDefaultProviders()
236 static const std::pair<PositionSource, PositionProvider> kDefaults[] = {
239#ifndef QGC_NO_SERIAL_LINK
244 for (
const auto& [source, provider] : kDefaults) {
245 if (!_providers.contains(source)) {
246 _providers.insert(source, provider);
257 auto it = _providers.find(source);
258 if (it != _providers.end()) {
273 auto it = _providers.find(s);
274 if (it != _providers.end()) {
275 auto result = it.value()();
276 if (result.isValid()) {
Used to group Facts together into an object hierarachy.
Q_INVOKABLE Fact * getFact(const QString &name) const
A Fact is used to hold a single value within the system.
void rawValueChanged(const QVariant &value)
QVariant rawValue() const
Value after translation.
static GPSManager * instance()
FactGroup * gpsRtkFactGroup()
static MultiVehicleManager * instance()
Vehicle * activeVehicle() const
static constexpr std::chrono::milliseconds kDefaultInterval
Fallback when no NTRIPSettings are available (unit tests, early init).
void sourceChanged(const QString &source)
NTRIPGgaProvider(QObject *parent=nullptr)
std::function< PositionResult()> PositionProvider
static constexpr std::chrono::milliseconds kFastRetryInterval
void init(NTRIPSettings *settings)
void start(NTRIPTransport *transport)
void setPositionProvider(PositionSource source, PositionProvider provider)
static QGCPositionManager * instance()
QGeoCoordinate gcsPosition() const
QGeoCoordinate coordinate()
FactGroup * gpsFactGroup()
QByteArray makeGGA(const QGeoCoordinate &coord, double altitudeMsl, int fixQuality, int numSatellites)
Build a GGA sentence from a coordinate and altitude.