20 std::isfinite(report.position.latitudeDegrees) && std::isfinite(report.position.longitudeDegrees);
21 const double accuracy = report.meanAccuracyMeters.value_or(
22 surveyAccuracyLimitMeters.value_or(std::numeric_limits<double>::quiet_NaN()));
23 if (report.valid && located && std::isfinite(accuracy)) {
24 position = std::pair(report.position, accuracy);
31 bool allowPersistentChanges, QString*
error)
34 if (type != GPSType::passive) {
41 *
error = std::move(diagnostic);
49 if (type == GPSType::passive) {
52 if (
const auto* fixed = std::get_if<GPSBaseStationConfig::Fixed>(&
config.base.mode)) {
54 state.
position = std::pair(fixed->position,
static_cast<double>(fixed->accuracyMeters));
55 }
else if (
const auto* survey = std::get_if<GPSBaseStationConfig::SurveyIn>(&
config.base.mode)) {
67 , _connection(std::move(connection))
70 qCDebug(GPSReceiverSessionLog) <<
this;
76 qCDebug(GPSReceiverSessionLog) <<
this;
90 if (_retired || _worker) {
94 _worker = factory ? factory(std::move(transportFactory), type, _connection.
config,
this)
105 emit
ended(GPSConnectionError::DeviceError, {});
108 Qt::QueuedConnection);
114 [
this, handler](Args... args) {
116 (this->*handler)(args...);
119 Qt::QueuedConnection);
135 if (_retired || !positionManager || _position) {
138 auto registration = positionManager->
registerReceiver(producer, _sessionId);
141 _position = std::move(registration);
147 if (std::exchange(_retired,
true)) {
150 const QPointer<GPSReceiverWorker>
worker = _worker;
152 (void) disconnect(
worker,
nullptr,
this,
nullptr);
154 worker->setParent(
nullptr);
164 _base.
position->second, receivedAtUs)
179void GPSReceiverSession::_onReady(
const QString& identity)
182 qCDebug(GPSReceiverSessionLog) <<
"Receiver identity:" <<
identity;
187void GPSReceiverSession::_onDetected(
GPSType type)
189 if (_connection.
type != GPSType::automatic && _connection.
type != GPSType::passive) {
192 _detectedType = type;
193 qCDebug(GPSReceiverSessionLog) <<
"Detected receiver family:" << type;
197void GPSReceiverSession::_forwardCorrection(
const QByteArray& data, qint64 receivedAtMs)
200 _correction->submit(data, receivedAtMs);
QString gpsReceiverConfigError(GPSType type, const GPSReceiverConfig &config)
An empty diagnostic means the receiver supports the role and all supplied settings.
std::function< GPSReceiverWorker *(GPSReceiverWorker::TransportFactory, GPSType, const GPSReceiverConfig &, QObject *)> GPSReceiverWorkerFactory
Creates a receiver session's worker; tests inject scripted workers.
GPSReceiverCapabilities gpsReceiverCapabilities(GPSType type)
What type supports, for either role; unknown receiver families support nothing.
GPSBaseStationState gpsBaseStationStateFor(GPSType type, const GPSReceiverConfig &config)
The state a session starts from; a fixed base knows its position before the receiver reports.
GPSReceiverConfig gpsReceiverConfigFor(const GPSBaseStationConfig &base, GPSType type, uint32_t baudRate, bool allowPersistentChanges, QString *error)
#define QGC_LOGGING_CATEGORY(name, categoryStr)
std::unique_ptr< GPSCorrectionSourceHandle > openSource(GPSCorrectionSettings::CorrectionSource source, const QString &instance)
void registerPosition(PositionManager *positionManager, GPSSourceHealth *producer)
Publishes producer as the receiver position source. Registration observers may retire this session.
GPSReceiverSession(quint64 id, Connection connection, QObject *parent)
~GPSReceiverSession() override
void registerCorrections(GPSCorrectionManager *manager, const QString &sourceInstance)
Forwards the receiver's RTCM as the local correction source when the connection asks for it.
void receiverReady(const QString &identity)
GPSObservation observation(const GPSPositionReport &report, quint64 receivedAtUs) const
A base with a known antenna position reports that position instead of its navigation solution.
void ended(GPSConnectionError error, const QString &detail)
The worker failed or exited; the owner ends the session.
void surveyInStatusUpdated(const GPSSurveyReport &report)
Survey progress of a configured base.
QPointer< GPSReceiverWorker > worker() const
The worker, which outlives the session once retired until its thread exits.
bool start(const GPSReceiverWorkerFactory &factory, GPSReceiverWorker::TransportFactory transportFactory)
Creates the worker, with a real worker for an empty factory, and starts it. False when none is create...
void positionUpdated(const GPSPositionReport &report)
const QString & identity() const
void receiverDetected(GPSType type)
The family an Automatic session detected, or the protocol a passive receiver's output carries.
void inputProblem(GPSInputProblem problem)
Why a passive receiver delivers no position; None once positions arrive.
void satelliteInfoUpdated(const GPSSatelliteReport &report)
void inputProblem(GPSInputProblem problem)
void connectionError(GPSConnectionError error, const QString &detail={})
detail is the transport's or the protocol's diagnostic, or empty when it gave none.
void finished()
Delivered on this object's thread once the session thread has finished.
void receiverReady(const QString &identity={})
identity is the receiver model and firmware, or empty when the family does not report them.
void satelliteInfoUpdated(const GPSSatelliteReport &message)
void surveyInStatusUpdated(const GPSSurveyReport &report)
void receiverDetected(GPSType type)
std::function< std::unique_ptr< GPSTransport >(GPSCancelToken)> TransportFactory
Consumed on the worker thread, so transport construction, I/O and destruction share that thread.
void rtcmDataReceived(const QByteArray &message, qint64 receivedAtMs)
RTCM output the receiver sent, stamped with the steady clock when it was read.
void positionUpdated(const GPSPositionReport &report)
Session health is independent of transport readiness and RTK survey-in validity.
GPSPositionSourceRegistration registerReceiver(GPSSourceHealth *producer, quint64 sessionId=0)
Configuration used only by the RTK base-station role.
A receiver session's base-station mode and the antenna position it reports.
void applySurvey(const GPSSurveyReport &report)
A surveying base adopts a valid, located result and otherwise has no position.
std::optional< std::pair< GPSEllipsoidPosition, double > > position
Antenna position and its accuracy in meters once known; the receiver then reports only a time fix.
std::optional< double > surveyAccuracyLimitMeters
Assumed accuracy of a survey-in result that reports none.
std::optional< BaseModeDefinition::Mode > mode
Base mode of a configured base; empty for a passive receiver.
Receiver-independent data. Unknown metadata remains absent, never a manufactured zero.
static GPSObservation fromSurveyedPosition(const GPSEllipsoidPosition &position, double accuracyMeters, quint64 receivedAtUs)
A known antenna position, such as a fixed or surveyed RTK base, which receivers report as a time-only...
static GPSObservation fromNavigation(const GPSNavigationValues &navigation, quint64 receivedAtUs)
Converts a native receiver solution that arrived at receivedAtUs on the monotonic clock.
GPSNavigationValues navigation
uint32_t baudRate
Zero lets a configurable receiver detect the rate; passive serial input requires an explicit rate.
RTKSettings::ReceiverRole role
bool forwardsCorrections
The receiver's RTCM output is a correction source.