Skip to content

Commit 6cf494d

Browse files
MaEtUgRdakejahl
andauthored
Publish RTCM stream telemetry also for UAVCAN GNSS receivers (#25315)
* uavcan gnss: publish rtcm instance and injection rate * GPS drivers minor refactor (#25316) * GPS drivers: adhere to message name based variable naming convention * uavcan gnss: use matrix norm calculation * GPS drivers: rate naming refactor and robust timeout checks --------- Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
1 parent b5bf28c commit 6cf494d

File tree

5 files changed

+149
-129
lines changed

5 files changed

+149
-129
lines changed

src/drivers/gnss/septentrio/septentrio.cpp

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ int SeptentrioDriver::print_status()
249249

250250
if (first_gps_uorb_message_created() && _state == State::ReceivingData) {
251251
PX4_INFO("rate RTCM injection: %6.2f Hz", static_cast<double>(rtcm_injection_frequency()));
252-
print_message(ORB_ID(sensor_gps), _message_gps_state);
252+
print_message(ORB_ID(sensor_gps), _sensor_gps);
253253
}
254254

255255
if (_instance == Instance::Main && secondary_instance) {
@@ -1057,8 +1057,8 @@ int SeptentrioDriver::process_message()
10571057
DOP dop;
10581058

10591059
if (_sbf_decoder.parse(&dop) == PX4_OK) {
1060-
_message_gps_state.hdop = dop.h_dop * 0.01f;
1061-
_message_gps_state.vdop = dop.v_dop * 0.01f;
1060+
_sensor_gps.hdop = dop.h_dop * 0.01f;
1061+
_sensor_gps.vdop = dop.v_dop * 0.01f;
10621062
result = PX4_OK;
10631063
}
10641064

@@ -1077,71 +1077,71 @@ int SeptentrioDriver::process_message()
10771077
if (_sbf_decoder.parse(&header) == PX4_OK && _sbf_decoder.parse(&pvt_geodetic) == PX4_OK) {
10781078
switch (static_cast<sbf::PVTGeodetic::ModeType>(pvt_geodetic.mode_type)) {
10791079
case ModeType::NoPVT:
1080-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_NONE;
1080+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_NONE;
10811081
break;
10821082
case ModeType::PVTWithSBAS:
1083-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_RTCM_CODE_DIFFERENTIAL;
1083+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_RTCM_CODE_DIFFERENTIAL;
10841084
break;
10851085
case ModeType::RTKFloat:
10861086
case ModeType::MovingBaseRTKFloat:
1087-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_RTK_FLOAT;
1087+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_RTK_FLOAT;
10881088
break;
10891089
case ModeType::RTKFixed:
10901090
case ModeType::MovingBaseRTKFixed:
1091-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_RTK_FIXED;
1091+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_RTK_FIXED;
10921092
break;
10931093
default:
1094-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_3D;
1094+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_3D;
10951095
break;
10961096
}
10971097

10981098
// Check boundaries and invalidate GPS velocities
10991099
if (pvt_geodetic.vn <= k_dnu_f4_value || pvt_geodetic.ve <= k_dnu_f4_value || pvt_geodetic.vu <= k_dnu_f4_value) {
1100-
_message_gps_state.vel_ned_valid = false;
1100+
_sensor_gps.vel_ned_valid = false;
11011101
}
11021102

11031103
if (pvt_geodetic.latitude > k_dnu_f8_value && pvt_geodetic.longitude > k_dnu_f8_value && pvt_geodetic.height > k_dnu_f8_value && pvt_geodetic.undulation > k_dnu_f4_value) {
1104-
_message_gps_state.latitude_deg = pvt_geodetic.latitude * M_RAD_TO_DEG;
1105-
_message_gps_state.longitude_deg = pvt_geodetic.longitude * M_RAD_TO_DEG;
1106-
_message_gps_state.altitude_msl_m = pvt_geodetic.height - static_cast<double>(pvt_geodetic.undulation);
1107-
_message_gps_state.altitude_ellipsoid_m = pvt_geodetic.height;
1104+
_sensor_gps.latitude_deg = pvt_geodetic.latitude * M_RAD_TO_DEG;
1105+
_sensor_gps.longitude_deg = pvt_geodetic.longitude * M_RAD_TO_DEG;
1106+
_sensor_gps.altitude_msl_m = pvt_geodetic.height - static_cast<double>(pvt_geodetic.undulation);
1107+
_sensor_gps.altitude_ellipsoid_m = pvt_geodetic.height;
11081108
} else {
1109-
_message_gps_state.fix_type = sensor_gps_s::FIX_TYPE_NONE;
1109+
_sensor_gps.fix_type = sensor_gps_s::FIX_TYPE_NONE;
11101110
}
11111111

11121112
if (pvt_geodetic.nr_sv != PVTGeodetic::k_dnu_nr_sv) {
1113-
_message_gps_state.satellites_used = pvt_geodetic.nr_sv;
1113+
_sensor_gps.satellites_used = pvt_geodetic.nr_sv;
11141114

11151115
if (_message_satellite_info) {
11161116
// Only fill in the satellite count for now (we could use the ChannelStatus message for the
11171117
// other data, but it's really large: >800B)
11181118
_message_satellite_info->timestamp = hrt_absolute_time();
1119-
_message_satellite_info->count = _message_gps_state.satellites_used;
1119+
_message_satellite_info->count = _sensor_gps.satellites_used;
11201120
}
11211121

11221122
} else {
1123-
_message_gps_state.satellites_used = 0;
1123+
_sensor_gps.satellites_used = 0;
11241124
}
11251125

11261126
/* H and V accuracy are reported in 2DRMS, but based off the u-blox reporting we expect RMS.
11271127
* Divide by 100 from cm to m and in addition divide by 2 to get RMS. */
1128-
_message_gps_state.eph = static_cast<float>(pvt_geodetic.h_accuracy) / 200.0f;
1129-
_message_gps_state.epv = static_cast<float>(pvt_geodetic.v_accuracy) / 200.0f;
1128+
_sensor_gps.eph = static_cast<float>(pvt_geodetic.h_accuracy) / 200.0f;
1129+
_sensor_gps.epv = static_cast<float>(pvt_geodetic.v_accuracy) / 200.0f;
11301130

11311131
// Check fix and error code
1132-
_message_gps_state.vel_ned_valid = _message_gps_state.fix_type > sensor_gps_s::FIX_TYPE_NONE && pvt_geodetic.error == Error::None;
1133-
_message_gps_state.vel_n_m_s = pvt_geodetic.vn;
1134-
_message_gps_state.vel_e_m_s = pvt_geodetic.ve;
1135-
_message_gps_state.vel_d_m_s = -1.0f * pvt_geodetic.vu;
1136-
_message_gps_state.vel_m_s = sqrtf(_message_gps_state.vel_n_m_s * _message_gps_state.vel_n_m_s +
1137-
_message_gps_state.vel_e_m_s * _message_gps_state.vel_e_m_s);
1132+
_sensor_gps.vel_ned_valid = _sensor_gps.fix_type > sensor_gps_s::FIX_TYPE_NONE && pvt_geodetic.error == Error::None;
1133+
_sensor_gps.vel_n_m_s = pvt_geodetic.vn;
1134+
_sensor_gps.vel_e_m_s = pvt_geodetic.ve;
1135+
_sensor_gps.vel_d_m_s = -1.0f * pvt_geodetic.vu;
1136+
_sensor_gps.vel_m_s = sqrtf(_sensor_gps.vel_n_m_s * _sensor_gps.vel_n_m_s +
1137+
_sensor_gps.vel_e_m_s * _sensor_gps.vel_e_m_s);
11381138

11391139
if (pvt_geodetic.cog > k_dnu_f4_value) {
1140-
_message_gps_state.cog_rad = pvt_geodetic.cog * M_DEG_TO_RAD_F;
1140+
_sensor_gps.cog_rad = pvt_geodetic.cog * M_DEG_TO_RAD_F;
11411141
}
1142-
_message_gps_state.c_variance_rad = M_DEG_TO_RAD_F;
1142+
_sensor_gps.c_variance_rad = M_DEG_TO_RAD_F;
11431143

1144-
_message_gps_state.time_utc_usec = 0;
1144+
_sensor_gps.time_utc_usec = 0;
11451145
#ifndef __PX4_QURT // NOTE: Functionality isn't available on Snapdragon yet.
11461146
if (_time_synced) {
11471147
struct tm timeinfo;
@@ -1170,13 +1170,13 @@ int SeptentrioDriver::process_message()
11701170
ts.tv_nsec = (header.tow % 1000) * 1000 * 1000;
11711171
set_clock(ts);
11721172

1173-
_message_gps_state.time_utc_usec = static_cast<uint64_t>(epoch) * 1000000ULL;
1174-
_message_gps_state.time_utc_usec += (header.tow % 1000) * 1000;
1173+
_sensor_gps.time_utc_usec = static_cast<uint64_t>(epoch) * 1000000ULL;
1174+
_sensor_gps.time_utc_usec += (header.tow % 1000) * 1000;
11751175
}
11761176
}
11771177

11781178
#endif
1179-
_message_gps_state.timestamp = hrt_absolute_time();
1179+
_sensor_gps.timestamp = hrt_absolute_time();
11801180
result = PX4_OK;
11811181
}
11821182

@@ -1189,7 +1189,7 @@ int SeptentrioDriver::process_message()
11891189
ReceiverStatus receiver_status;
11901190

11911191
if (_sbf_decoder.parse(&receiver_status) == PX4_OK) {
1192-
_message_gps_state.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;
1192+
_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;
11941194
}
11951195

@@ -1222,7 +1222,7 @@ int SeptentrioDriver::process_message()
12221222

12231223
if (_sbf_decoder.parse(&vel_cov_geodetic) == PX4_OK) {
12241224
if (vel_cov_geodetic.cov_ve_ve > k_dnu_f4_value && vel_cov_geodetic.cov_vn_vn > k_dnu_f4_value && vel_cov_geodetic.cov_vu_vu > k_dnu_f4_value) {
1225-
_message_gps_state.s_variance_m_s = math::max(math::max(vel_cov_geodetic.cov_ve_ve, vel_cov_geodetic.cov_vn_vn), vel_cov_geodetic.cov_vu_vu);
1225+
_sensor_gps.s_variance_m_s = math::max(math::max(vel_cov_geodetic.cov_ve_ve, vel_cov_geodetic.cov_vn_vn), vel_cov_geodetic.cov_vu_vu);
12261226
}
12271227
}
12281228

@@ -1252,7 +1252,7 @@ int SeptentrioDriver::process_message()
12521252
heading -= 2.f * M_PI_F;
12531253
}
12541254

1255-
_message_gps_state.heading = heading;
1255+
_sensor_gps.heading = heading;
12561256
}
12571257

12581258
break;
@@ -1270,7 +1270,7 @@ int SeptentrioDriver::process_message()
12701270
static_cast<AttCovEuler::Error>(att_cov_euler.error_aux1) == Error::None &&
12711271
static_cast<AttCovEuler::Error>(att_cov_euler.error_aux2) == Error::None &&
12721272
att_cov_euler.cov_headhead > k_dnu_f4_value) {
1273-
_message_gps_state.heading_accuracy = att_cov_euler.cov_headhead * M_PI_F / 180.0f; // Convert range of degrees to range of radians in [0, 2PI]
1273+
_sensor_gps.heading_accuracy = att_cov_euler.cov_headhead * M_PI_F / 180.0f; // Convert range of degrees to range of radians in [0, 2PI]
12741274
}
12751275

12761276
break;
@@ -1475,15 +1475,16 @@ void SeptentrioDriver::handle_inject_data_topic()
14751475
bool already_copied = false;
14761476
gps_inject_data_s msg;
14771477

1478-
// If there has not been a valid RTCM message for a while, try to switch to a different RTCM link
1479-
if ((hrt_absolute_time() - _last_rtcm_injection_time) > 5_s) {
1478+
const hrt_abstime now = hrt_absolute_time();
14801479

1480+
// If there has not been a valid RTCM message for a while, try to switch to a different RTCM link
1481+
if (now > _last_rtcm_injection_time + 5_s) {
14811482
for (int instance = 0; instance < _gps_inject_data_sub.size(); instance++) {
14821483
const bool exists = _gps_inject_data_sub[instance].advertised();
14831484

14841485
if (exists) {
14851486
if (_gps_inject_data_sub[instance].copy(&msg)) {
1486-
if ((hrt_absolute_time() - msg.timestamp) < 5_s) {
1487+
if (now < msg.timestamp + 5_s) {
14871488
// Remember that we already did a copy on this instance.
14881489
already_copied = true;
14891490
_selected_rtcm_instance = instance;
@@ -1528,10 +1529,10 @@ void SeptentrioDriver::handle_inject_data_topic()
15281529

15291530
void SeptentrioDriver::publish()
15301531
{
1531-
_message_gps_state.device_id = get_device_id();
1532-
_message_gps_state.selected_rtcm_instance = _selected_rtcm_instance;
1533-
_message_gps_state.rtcm_injection_rate = rtcm_injection_frequency();
1534-
_sensor_gps_pub.publish(_message_gps_state);
1532+
_sensor_gps.device_id = get_device_id();
1533+
_sensor_gps.selected_rtcm_instance = _selected_rtcm_instance;
1534+
_sensor_gps.rtcm_injection_rate = rtcm_injection_frequency();
1535+
_sensor_gps_pub.publish(_sensor_gps);
15351536
}
15361537

15371538
void SeptentrioDriver::publish_satellite_info()
@@ -1543,7 +1544,7 @@ void SeptentrioDriver::publish_satellite_info()
15431544

15441545
bool SeptentrioDriver::first_gps_uorb_message_created() const
15451546
{
1546-
return _message_gps_state.timestamp != 0;
1547+
return _sensor_gps.timestamp != 0;
15471548
}
15481549

15491550
void SeptentrioDriver::publish_rtcm_corrections(uint8_t *data, size_t len)
@@ -1696,9 +1697,9 @@ bool SeptentrioDriver::is_healthy() const
16961697

16971698
void SeptentrioDriver::reset_gps_state_message()
16981699
{
1699-
memset(&_message_gps_state, 0, sizeof(_message_gps_state));
1700-
_message_gps_state.heading = NAN;
1701-
_message_gps_state.heading_offset = matrix::wrap_pi(math::radians(_heading_offset));
1700+
memset(&_sensor_gps, 0, sizeof(_sensor_gps));
1701+
_sensor_gps.heading = NAN;
1702+
_sensor_gps.heading_offset = matrix::wrap_pi(math::radians(_heading_offset));
17021703
}
17031704

17041705
uint32_t SeptentrioDriver::get_parameter(const char *name, int32_t *value)

src/drivers/gnss/septentrio/septentrio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ class SeptentrioDriver : public ModuleBase<SeptentrioDriver>, public device::Dev
737737
rtcm::Decoder *_rtcm_decoder {nullptr}; ///< RTCM message decoder
738738

739739
// uORB topics and subscriptions
740-
sensor_gps_s _message_gps_state {}; ///< uORB topic for position
740+
sensor_gps_s _sensor_gps{}; ///< uORB topic for position
741741
gps_dump_s *_message_data_to_receiver {nullptr}; ///< uORB topic for dumping data to the receiver
742742
gps_dump_s *_message_data_from_receiver {nullptr}; ///< uORB topic for dumping data from the receiver
743743
satellite_info_s *_message_satellite_info {nullptr}; ///< uORB topic for satellite info

0 commit comments

Comments
 (0)