Skip to content

Commit 51202eb

Browse files
Louis-max-HTory9
authored andcommitted
Septentrio GNSS resilience reporting (PX4#25012)
Co-authored-by: Tory9 <vvpost05@gmail.com>
1 parent 2c970e6 commit 51202eb

15 files changed

Lines changed: 361 additions & 30 deletions

File tree

msg/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ set(msg_files
195195
SensorCombined.msg
196196
SensorCorrection.msg
197197
SensorGnssRelative.msg
198+
SensorGnssStatus.msg
198199
SensorGps.msg
199200
SensorGyro.msg
200201
SensorGyroFft.msg

msg/SensorGnssStatus.msg

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Gnss quality indicators
2+
3+
uint64 timestamp # time since system start (microseconds)
4+
uint32 device_id # unique device ID for the sensor that does not change between power cycles
5+
6+
bool quality_available # Set to true if quality indicators are available
7+
uint8 quality_corrections # Corrections quality from 0 to 10, or 255 if not available
8+
uint8 quality_receiver # Overall receiver operating status from 0 to 10, or 255 if not available
9+
uint8 quality_gnss_signals # Quality of GNSS signals from 0 to 10, or 255 if not available
10+
uint8 quality_post_processing # Expected post processing quality from 0 to 10, or 255 if not available

msg/SensorGps.msg

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,26 @@ float32 vdop # Vertical dilution of precision
3030
int32 noise_per_ms # GPS noise per millisecond
3131
uint16 automatic_gain_control # Automatic gain control monitor
3232

33-
uint8 JAMMING_STATE_UNKNOWN = 0
34-
uint8 JAMMING_STATE_OK = 1
35-
uint8 JAMMING_STATE_WARNING = 2
36-
uint8 JAMMING_STATE_CRITICAL = 3
37-
uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical
38-
int32 jamming_indicator # indicates jamming is occurring
39-
40-
uint8 SPOOFING_STATE_UNKNOWN = 0
41-
uint8 SPOOFING_STATE_NONE = 1
42-
uint8 SPOOFING_STATE_INDICATED = 2
43-
uint8 SPOOFING_STATE_MULTIPLE = 3
44-
uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Warning, 3: Critical
33+
uint8 JAMMING_STATE_UNKNOWN = 0 #default
34+
uint8 JAMMING_STATE_OK = 1
35+
uint8 JAMMING_STATE_MITIGATED = 2
36+
uint8 JAMMING_STATE_DETECTED = 3
37+
uint8 jamming_state # indicates whether jamming has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected
38+
int32 jamming_indicator # indicates jamming is occurring
39+
40+
uint8 SPOOFING_STATE_UNKNOWN = 0 #default
41+
uint8 SPOOFING_STATE_OK = 1
42+
uint8 SPOOFING_STATE_MITIGATED = 2
43+
uint8 SPOOFING_STATE_DETECTED = 3
44+
uint8 spoofing_state # indicates whether spoofing has been detected or suspected by the receivers. O: Unknown, 1: OK, 2: Mitigated, 3: Detected
45+
46+
# Combined authentication state (e.g. Galileo OSNMA)
47+
uint8 AUTHENTICATION_STATE_UNKNOWN = 0 #default
48+
uint8 AUTHENTICATION_STATE_INITIALIZING = 1
49+
uint8 AUTHENTICATION_STATE_ERROR = 2
50+
uint8 AUTHENTICATION_STATE_OK = 3
51+
uint8 AUTHENTICATION_STATE_DISABLED = 4
52+
uint8 authentication_state # GPS signal authentication state
4553

4654
float32 vel_m_s # GPS ground speed, (metres/sec)
4755
float32 vel_n_m_s # GPS North velocity, (metres/sec)
@@ -55,6 +63,16 @@ uint64 time_utc_usec # Timestamp (microseconds, UTC), this is the timestamp whi
5563

5664
uint8 satellites_used # Number of satellites used
5765

66+
uint32 SYSTEM_ERROR_OK = 0 #default
67+
uint32 SYSTEM_ERROR_INCOMING_CORRECTIONS = 1
68+
uint32 SYSTEM_ERROR_CONFIGURATION = 2
69+
uint32 SYSTEM_ERROR_SOFTWARE = 4
70+
uint32 SYSTEM_ERROR_ANTENNA = 8
71+
uint32 SYSTEM_ERROR_EVENT_CONGESTION = 16
72+
uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32
73+
uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64
74+
uint32 system_error # General errors with the connected GPS receiver
75+
5876
float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI])
5977
float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI])
6078
float32 heading_accuracy # heading accuracy (rad, [0, 2PI])

src/drivers/gnss/septentrio/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ px4_add_module(
3737
COMPILE_FLAGS
3838
# -DDEBUG_BUILD # Enable during development of the module
3939
-DSEP_LOG_ERROR # Enable module-level error logs
40-
# -DSEP_LOG_WARN # Enable module-level warning logs
40+
-DSEP_LOG_WARN # Enable module-level warning logs
4141
# -DSEP_LOG_INFO # Enable module-level info logs
4242
# -DSEP_LOG_TRACE_PARSING # Tracing of parsing steps
4343
SRCS

src/drivers/gnss/septentrio/sbf/decoder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ int Decoder::parse(QualityInd *message) const
163163

164164
int Decoder::parse(RFStatus *message) const
165165
{
166-
if (can_parse() && id() == BlockID::PVTGeodetic) {
166+
if (can_parse() && id() == BlockID::RFStatus) {
167167
static_assert(sizeof(*message) <= sizeof(_message.payload), "Buffer too small");
168168
memcpy(message, _message.payload, sizeof(RFStatus) - sizeof(RFStatus::rf_band));
169169

src/drivers/gnss/septentrio/sbf/messages.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,14 @@ struct QualityInd {
243243
};
244244

245245
struct RFBand {
246+
enum class InfoMode : uint8_t {
247+
Suppressed = 1,
248+
Mitigated = 2,
249+
Interference = 8
250+
};
246251
uint32_t frequency;
247252
uint16_t bandwidth;
248-
uint8_t info_mode: 4;
253+
uint8_t info_mode: 4;
249254
uint8_t info_reserved: 2;
250255
uint8_t info_antenna_id: 2;
251256
};
@@ -261,6 +266,15 @@ struct RFStatus {
261266
};
262267

263268
struct GALAuthStatus {
269+
enum class OSNMAStatus : uint16_t {
270+
Disabled = 0,
271+
Initializing = 1,
272+
AwaitingTrustedTimeInfo = 2,
273+
InitFailedInconsistentTime = 3,
274+
InitFailedKROOTInvalid = 4,
275+
InitFailedInvalidParam = 5,
276+
Authenticating = 6,
277+
};
264278
uint16_t osnma_status_status: 3;
265279
uint16_t osnma_status_initialization_progress: 8;
266280
uint16_t osnma_status_trusted_time_source: 3;
@@ -271,6 +285,8 @@ struct GALAuthStatus {
271285
uint64_t gal_authentic_mask;
272286
uint64_t gps_active_mask;
273287
uint64_t gps_authentic_mask;
288+
289+
OSNMAStatus osnmaStatus() const { return static_cast<OSNMAStatus>(osnma_status_status); }
274290
};
275291

276292
struct VelCovGeodetic {

src/drivers/gnss/septentrio/septentrio.cpp

Lines changed: 147 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ constexpr size_t k_min_receiver_read_bytes = 32;
9292
*/
9393
constexpr uint32_t k_septentrio_receiver_default_baud_rate = 115200;
9494

95-
constexpr uint8_t k_max_command_size = 120;
95+
constexpr uint8_t k_max_command_size = 140;
9696
constexpr uint16_t k_timeout_5hz = 500;
9797
constexpr uint32_t k_read_buffer_size = 150;
9898
constexpr time_t k_gps_epoch_secs = 1234567890ULL; // TODO: This seems wrong
@@ -112,7 +112,7 @@ constexpr const char *k_command_reset_hot = "erst,soft,none\n";
112112
constexpr const char *k_command_reset_warm = "erst,soft,PVTData\n";
113113
constexpr const char *k_command_reset_cold = "erst,hard,SatData\n";
114114
constexpr const char *k_command_sbf_output_pvt =
115-
"sso,Stream%" PRIu32 ",%s,PVTGeodetic+VelCovGeodetic+DOP+AttEuler+AttCovEuler+EndOfPVT+ReceiverStatus,%s\n";
115+
"sso,Stream%lu,%s,PVTGeodetic+VelCovGeodetic+DOP+AttEuler+AttCovEuler+EndOfPVT+ReceiverStatus+GALAuthStatus+RFStatus+QualityInd,%s\n";
116116
constexpr const char *k_command_set_sbf_output =
117117
"sso,Stream%" PRIu32 ",%s,%s%s,%s\n";
118118
constexpr const char *k_command_clear_sbf = "sso,Stream%" PRIu32 ",%s,none,off\n";
@@ -967,7 +967,7 @@ SeptentrioDriver::ConfigureResult SeptentrioDriver::configure()
967967
}
968968

969969
// Output a set of SBF blocks on a given connection at a regular interval.
970-
snprintf(msg, sizeof(msg), k_command_sbf_output_pvt, _receiver_stream_main, com_port, sbf_frequency);
970+
snprintf(msg, sizeof(msg), k_command_sbf_output_pvt, (long unsigned int) _receiver_stream_main, com_port, sbf_frequency);
971971
if (!send_message_and_wait_for_ack(msg, k_receiver_ack_timeout_fast)) {
972972
SEP_WARN("CONFIG: Failed to configure SBF");
973973
return ConfigureResult::FailedCompletely;
@@ -1191,20 +1191,138 @@ int SeptentrioDriver::process_message()
11911191
if (_sbf_decoder.parse(&receiver_status) == PX4_OK) {
11921192
_sensor_gps.rtcm_msg_used = receiver_status.rx_state_diff_corr_in ? sensor_gps_s::RTCM_MSG_USED_USED : sensor_gps_s::RTCM_MSG_USED_NOT_USED;
11931193
_time_synced = receiver_status.rx_state_wn_set && receiver_status.rx_state_tow_set;
1194+
1195+
_sensor_gps.system_error = sensor_gps_s::SYSTEM_ERROR_OK;
1196+
1197+
if (receiver_status.rx_error_cpu_overload) {
1198+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_CPU_OVERLOAD;
1199+
}
1200+
if (receiver_status.rx_error_antenna) {
1201+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_ANTENNA;
1202+
}
1203+
if (receiver_status.ext_error_diff_corr_error) {
1204+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_INCOMING_CORRECTIONS;
1205+
}
1206+
if (receiver_status.ext_error_setup_error) {
1207+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_CONFIGURATION;
1208+
}
1209+
if (receiver_status.rx_error_software) {
1210+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_SOFTWARE;
1211+
}
1212+
if (receiver_status.rx_error_congestion) {
1213+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_OUTPUT_CONGESTION;
1214+
}
1215+
if (receiver_status.rx_error_missed_event) {
1216+
_sensor_gps.system_error |= sensor_gps_s::SYSTEM_ERROR_EVENT_CONGESTION;
1217+
}
11941218
}
11951219

11961220
break;
11971221
}
11981222
case BlockID::QualityInd: {
1223+
using Type = QualityIndicator::Type;
1224+
11991225
SEP_TRACE_PARSING("Processing QualityInd SBF message");
1226+
1227+
QualityInd quality_ind;
1228+
1229+
if (_sbf_decoder.parse(&quality_ind) == PX4_OK) {
1230+
_message_sensor_gnss_status.quality_available = true;
1231+
_message_sensor_gnss_status.device_id = get_device_id();
1232+
1233+
_message_sensor_gnss_status.quality_corrections = 255;
1234+
_message_sensor_gnss_status.quality_receiver = 255;
1235+
_message_sensor_gnss_status.quality_post_processing = 255;
1236+
_message_sensor_gnss_status.quality_gnss_signals = 255;
1237+
1238+
for (int i = 0; i < math::min(quality_ind.n, static_cast<uint8_t>(sizeof(quality_ind.indicators) / sizeof(quality_ind.indicators[0]))); i++) {
1239+
int quality = quality_ind.indicators[i].value;
1240+
1241+
switch (quality_ind.indicators[i].type) {
1242+
case Type::BaseStationMeasurements:
1243+
_message_sensor_gnss_status.quality_corrections = quality;
1244+
break;
1245+
case Type::Overall:
1246+
_message_sensor_gnss_status.quality_receiver = quality;
1247+
break;
1248+
case Type::RTKPostProcessing:
1249+
_message_sensor_gnss_status.quality_post_processing = quality;
1250+
break;
1251+
case Type::GNSSSignalsMainAntenna:
1252+
_message_sensor_gnss_status.quality_gnss_signals = quality;
1253+
break;
1254+
default:
1255+
break;
1256+
}
1257+
}
1258+
1259+
1260+
_message_sensor_gnss_status.timestamp = hrt_absolute_time();
1261+
_time_last_qualityind_received = hrt_absolute_time();
1262+
_sensor_gnss_status_pub.publish(_message_sensor_gnss_status);
1263+
}
1264+
12001265
break;
12011266
}
12021267
case BlockID::RFStatus: {
1268+
using InfoMode = RFBand::InfoMode;
1269+
12031270
SEP_TRACE_PARSING("Processing RFStatus SBF message");
1271+
1272+
RFStatus rf_status;
1273+
1274+
if (_sbf_decoder.parse(&rf_status) == PX4_OK) {
1275+
_sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_OK;
1276+
_sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_OK;
1277+
1278+
for (int i = 0; i < math::min(rf_status.n, static_cast<uint8_t>(sizeof(rf_status.rf_band) / sizeof(rf_status.rf_band[0]))); i++) {
1279+
InfoMode status = static_cast<InfoMode>(rf_status.rf_band[i].info_mode);
1280+
1281+
if(status == InfoMode::Interference){
1282+
_sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_DETECTED;
1283+
break; // Worst case, we don't need to check the other bands
1284+
}
1285+
1286+
if(status == InfoMode::Suppressed || status == InfoMode::Mitigated){
1287+
_sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_MITIGATED;
1288+
}
1289+
}
1290+
1291+
if (rf_status.flags_inauthentic_gnss_signals || rf_status.flags_inauthentic_navigation_message) {
1292+
_sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_DETECTED;
1293+
}
1294+
_time_last_resilience_received = hrt_absolute_time();
1295+
}
1296+
12041297
break;
12051298
}
12061299
case BlockID::GALAuthStatus: {
1300+
using OSNMAStatus = GALAuthStatus::OSNMAStatus;
1301+
12071302
SEP_TRACE_PARSING("Processing GALAuthStatus SBF message");
1303+
1304+
GALAuthStatus gal_auth_status;
1305+
1306+
if (_sbf_decoder.parse(&gal_auth_status) == PX4_OK) {
1307+
switch (gal_auth_status.osnmaStatus()) {
1308+
case OSNMAStatus::Disabled:
1309+
_sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_DISABLED;
1310+
break;
1311+
case OSNMAStatus::AwaitingTrustedTimeInfo:
1312+
case OSNMAStatus::Initializing:
1313+
_sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_INITIALIZING;
1314+
break;
1315+
case OSNMAStatus::InitFailedInconsistentTime:
1316+
case OSNMAStatus::InitFailedKROOTInvalid:
1317+
case OSNMAStatus::InitFailedInvalidParam:
1318+
_sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_ERROR;
1319+
break;
1320+
case OSNMAStatus::Authenticating:
1321+
_sensor_gps.authentication_state = sensor_gps_s::AUTHENTICATION_STATE_OK;
1322+
break;
1323+
}
1324+
}
1325+
12081326
break;
12091327
}
12101328
case BlockID::EndOfPVT: {
@@ -1277,6 +1395,31 @@ int SeptentrioDriver::process_message()
12771395
}
12781396
}
12791397

1398+
//Check for how recent the resilience data for reciever is, if outdated set to unknown
1399+
if ((_time_last_resilience_received != 0) && (hrt_elapsed_time(&_time_last_resilience_received) > 5_s)) {
1400+
_sensor_gps.jamming_state = sensor_gps_s::JAMMING_STATE_UNKNOWN;
1401+
_sensor_gps.spoofing_state = sensor_gps_s::SPOOFING_STATE_UNKNOWN;
1402+
1403+
_time_last_resilience_received = 0; // Reset
1404+
}
1405+
1406+
// Check for how recent the status data for receiver is, if outdated set to unknown
1407+
if ((_time_last_qualityind_received != 0) && (hrt_elapsed_time(&_time_last_qualityind_received) > 5_s)) {
1408+
_message_sensor_gnss_status.quality_available = false;
1409+
_message_sensor_gnss_status.device_id = get_device_id();
1410+
_message_sensor_gnss_status.timestamp = hrt_absolute_time();
1411+
1412+
_message_sensor_gnss_status.quality_corrections = 255;
1413+
_message_sensor_gnss_status.quality_receiver = 255;
1414+
_message_sensor_gnss_status.quality_post_processing = 255;
1415+
_message_sensor_gnss_status.quality_gnss_signals = 255;
1416+
1417+
1418+
_sensor_gnss_status_pub.publish(_message_sensor_gnss_status);
1419+
1420+
_time_last_qualityind_received = 0; // Reset
1421+
}
1422+
12801423
break;
12811424
}
12821425
case DecodingStatus::RTCMv3: {
@@ -1532,6 +1675,7 @@ void SeptentrioDriver::publish()
15321675
_sensor_gps.device_id = get_device_id();
15331676
_sensor_gps.selected_rtcm_instance = _selected_rtcm_instance;
15341677
_sensor_gps.rtcm_injection_rate = rtcm_injection_frequency();
1678+
_sensor_gps.timestamp = hrt_absolute_time();
15351679
_sensor_gps_pub.publish(_sensor_gps);
15361680
}
15371681

src/drivers/gnss/septentrio/septentrio.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <uORB/SubscriptionMultiArray.hpp>
5454
#include <uORB/topics/satellite_info.h>
5555
#include <uORB/topics/sensor_gps.h>
56+
#include <uORB/topics/sensor_gnss_status.h>
5657
#include <uORB/topics/gps_dump.h>
5758
#include <uORB/topics/gps_inject_data.h>
5859
#include <drivers/drv_hrt.h>
@@ -710,12 +711,16 @@ class SeptentrioDriver : public ModuleBase<SeptentrioDriver>, public device::Dev
710711
char _port[20] {}; ///< The path of the used serial device
711712
hrt_abstime _last_rtcm_injection_time {0}; ///< Time of last RTCM injection
712713
uint8_t _selected_rtcm_instance {0}; ///< uORB instance that is being used for RTCM corrections
714+
uint8_t _spoofing_state {0}; ///< Receiver spoofing state
715+
uint8_t _jamming_state {0}; ///< Receiver jamming state
713716
bool _time_synced {false}; ///< Receiver time in sync with GPS time
714717
const Instance _instance {Instance::Main}; ///< The receiver that this instance of the driver controls
715718
uint32_t _chosen_baud_rate {0}; ///< The baud rate requested by the user
716719
static px4::atomic<SeptentrioDriver *> _secondary_instance;
717720
hrt_abstime _sleep_end {0}; ///< End time for sleeping
718721
State _resume_state {State::OpeningSerialPort}; ///< Resume state after sleep
722+
hrt_abstime _time_last_qualityind_received{0}; ///< Time of last quality message reception
723+
hrt_abstime _time_last_resilience_received{0}; ///< Time of last resilience message reception
719724

720725
// Module configuration
721726
float _heading_offset {0.0f}; ///< The heading offset given by the `SEP_YAW_OFFS` parameter
@@ -737,14 +742,16 @@ class SeptentrioDriver : public ModuleBase<SeptentrioDriver>, public device::Dev
737742
rtcm::Decoder *_rtcm_decoder {nullptr}; ///< RTCM message decoder
738743

739744
// uORB topics and subscriptions
740-
sensor_gps_s _sensor_gps{}; ///< uORB topic for position
741-
gps_dump_s *_message_data_to_receiver {nullptr}; ///< uORB topic for dumping data to the receiver
742-
gps_dump_s *_message_data_from_receiver {nullptr}; ///< uORB topic for dumping data from the receiver
743-
satellite_info_s *_message_satellite_info {nullptr}; ///< uORB topic for satellite info
744-
uORB::PublicationMulti<sensor_gps_s> _sensor_gps_pub {ORB_ID(sensor_gps)}; ///< uORB publication for gps position
745-
uORB::Publication<gps_dump_s> _gps_dump_pub {ORB_ID(gps_dump)}; ///< uORB publication for dump GPS data
746-
uORB::Publication<gps_inject_data_s> _gps_inject_data_pub {ORB_ID(gps_inject_data)}; ///< uORB publication for injected data to the receiver
747-
uORB::PublicationMulti<satellite_info_s> _satellite_info_pub {ORB_ID(satellite_info)}; ///< uORB publication for satellite info
745+
sensor_gps_s _sensor_gps {}; ///< uORB topic for position
746+
sensor_gnss_status_s _message_sensor_gnss_status {}; ///< uORB topic for gps status
747+
gps_dump_s *_message_data_to_receiver {nullptr}; ///< uORB topic for dumping data to the receiver
748+
gps_dump_s *_message_data_from_receiver {nullptr}; ///< uORB topic for dumping data from the receiver
749+
satellite_info_s *_message_satellite_info {nullptr}; ///< uORB topic for satellite info
750+
uORB::PublicationMulti<sensor_gps_s> _sensor_gps_pub {ORB_ID(sensor_gps)}; ///< uORB publication for gps position
751+
uORB::PublicationMulti<sensor_gnss_status_s> _sensor_gnss_status_pub {ORB_ID(sensor_gnss_status)}; ///< uORB publication for gnss status
752+
uORB::Publication<gps_dump_s> _gps_dump_pub {ORB_ID(gps_dump)}; ///< uORB publication for dump GPS data
753+
uORB::Publication<gps_inject_data_s> _gps_inject_data_pub {ORB_ID(gps_inject_data)}; ///< uORB publication for injected data to the receiver
754+
uORB::PublicationMulti<satellite_info_s> _satellite_info_pub {ORB_ID(satellite_info)}; ///< uORB publication for satellite info
748755
uORB::SubscriptionMultiArray<gps_inject_data_s, gps_inject_data_s::MAX_INSTANCES> _gps_inject_data_sub {ORB_ID::gps_inject_data}; ///< uORB subscription about data to inject to the receiver
749756

750757
// Data about update frequencies of various bits of information like RTCM message injection frequency, received data rate...

0 commit comments

Comments
 (0)