AP_GPS: support UNIHEADINGA message for Unicore NMEA
this allows for good yaw even without a RTK fix, which makes yaw with dual-antenna Unicore GPS modules much more useful
This commit is contained in:
parent
cf2d1ec290
commit
17c25780c7
@ -470,26 +470,6 @@ bool AP_GPS_NMEA::_term_complete()
|
||||
state.have_horizontal_accuracy = true;
|
||||
state.have_vertical_accuracy = true;
|
||||
state.have_undulation = true;
|
||||
|
||||
if (ag.heading_status == 4) {
|
||||
#if GPS_MOVING_BASELINE
|
||||
Location slave( ag.slave_lat*1.0e7, ag.slave_lng*1.0e7, ag.slave_alt*1.0e2, Location::AltFrame::ABSOLUTE );
|
||||
const float dist = state.location.get_distance_NED(slave).length();
|
||||
const float bearing = degrees(state.location.get_bearing(slave));
|
||||
const float alt_diff = (state.location.alt - slave.alt)*0.01;
|
||||
state.relPosHeading = bearing;
|
||||
state.relPosLength = dist;
|
||||
state.relPosD = alt_diff;
|
||||
state.relposheading_ts = now;
|
||||
if (calculate_moving_base_yaw(bearing, dist, alt_diff)) {
|
||||
_last_yaw_ms = now;
|
||||
}
|
||||
state.gps_yaw_configured = true;
|
||||
#endif
|
||||
} else {
|
||||
state.have_gps_yaw = false;
|
||||
}
|
||||
|
||||
check_new_itow(ag.itow, _sentence_length);
|
||||
break;
|
||||
}
|
||||
@ -502,6 +482,31 @@ bool AP_GPS_NMEA::_term_complete()
|
||||
_versiona.build_date);
|
||||
break;
|
||||
}
|
||||
case _GPS_SENTENCE_UNIHEADINGA: {
|
||||
#if GPS_MOVING_BASELINE
|
||||
const auto &ag = _agrica;
|
||||
const auto &uh = _uniheadinga;
|
||||
if (now - _last_AGRICA_ms > 500 || ag.heading_status != 4) {
|
||||
// we need heading_status from AGRICA
|
||||
state.have_gps_yaw = false;
|
||||
break;
|
||||
}
|
||||
const float dist = uh.baseline_length;
|
||||
const float bearing = uh.heading;
|
||||
const float alt_diff = dist*tanf(radians(-uh.pitch));
|
||||
state.relPosHeading = bearing;
|
||||
state.relPosLength = dist;
|
||||
state.relPosD = alt_diff;
|
||||
state.relposheading_ts = now;
|
||||
if (calculate_moving_base_yaw(bearing, dist, alt_diff)) {
|
||||
state.have_gps_yaw_accuracy = true;
|
||||
state.gps_yaw_accuracy = uh.heading_sd;
|
||||
_last_yaw_ms = now;
|
||||
}
|
||||
state.gps_yaw_configured = true;
|
||||
#endif // GPS_MOVING_BASELINE
|
||||
break;
|
||||
}
|
||||
#endif // AP_GPS_NMEA_UNICORE_ENABLED
|
||||
}
|
||||
// see if we got a good message
|
||||
@ -533,6 +538,10 @@ bool AP_GPS_NMEA::_term_complete()
|
||||
_sentence_type = _GPS_SENTENCE_VERSIONA;
|
||||
return false;
|
||||
}
|
||||
if (strcmp(_term, "UNIHEADINGA") == 0 && _expect_agrica) {
|
||||
_sentence_type = _GPS_SENTENCE_UNIHEADINGA;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
The first two letters of the NMEA term are the talker
|
||||
@ -655,6 +664,11 @@ bool AP_GPS_NMEA::_term_complete()
|
||||
case _GPS_SENTENCE_VERSIONA + 1 ... _GPS_SENTENCE_VERSIONA + 20:
|
||||
parse_versiona_field(_term_number, _term);
|
||||
break;
|
||||
#if GPS_MOVING_BASELINE
|
||||
case _GPS_SENTENCE_UNIHEADINGA + 1 ... _GPS_SENTENCE_UNIHEADINGA + 28: // UNIHEADINGA message
|
||||
parse_uniheadinga_field(_term_number, _term);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -708,15 +722,6 @@ void AP_GPS_NMEA::parse_agrica_field(uint16_t term_number, const char *term)
|
||||
case 33:
|
||||
ag.alt = atof(term);
|
||||
break;
|
||||
case 46:
|
||||
ag.slave_lat = atof(term);
|
||||
break;
|
||||
case 47:
|
||||
ag.slave_lng = atof(term);
|
||||
break;
|
||||
case 48:
|
||||
ag.slave_alt = atof(term);
|
||||
break;
|
||||
case 49:
|
||||
ag.itow = atol(term);
|
||||
break;
|
||||
@ -729,6 +734,41 @@ void AP_GPS_NMEA::parse_agrica_field(uint16_t term_number, const char *term)
|
||||
}
|
||||
}
|
||||
|
||||
#if GPS_MOVING_BASELINE
|
||||
/*
|
||||
parse a UNIHEADINGA message term
|
||||
|
||||
Example:
|
||||
#UNIHEADINGA,79,GPS,FINE,2242,167498200,0,0,18,22;SOL_COMPUTED,L1_INT,2.7889,296.7233,-25.7710,0.0000,0.1127,0.1812,"999",49,37,37,0,3,00,1,51*d50af0ea
|
||||
*/
|
||||
void AP_GPS_NMEA::parse_uniheadinga_field(uint16_t term_number, const char *term)
|
||||
{
|
||||
const uint8_t hdr_align = 8;
|
||||
if (term_number < hdr_align) {
|
||||
// discard header;
|
||||
return;
|
||||
}
|
||||
term_number -= hdr_align;
|
||||
// useful for debugging
|
||||
// ::printf("UNIHEADINGA[%u]=%s\n", unsigned(term_number), term);
|
||||
auto &uh = _uniheadinga;
|
||||
switch (term_number) {
|
||||
case 4:
|
||||
uh.baseline_length = atof(term);
|
||||
break;
|
||||
case 5:
|
||||
uh.heading = atof(term);
|
||||
break;
|
||||
case 6:
|
||||
uh.pitch = atof(term);
|
||||
break;
|
||||
case 8:
|
||||
uh.heading_sd = atof(term);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // GPS_MOVING_BASELINE
|
||||
|
||||
// parse VERSIONA fields
|
||||
void AP_GPS_NMEA::parse_versiona_field(uint16_t term_number, const char *term)
|
||||
{
|
||||
@ -823,7 +863,7 @@ void AP_GPS_NMEA::send_config(void)
|
||||
"CONFIG HEADING FIXLENGTH\r\n" \
|
||||
"CONFIG UNDULATION AUTO\r\n" \
|
||||
"CONFIG\r\n" \
|
||||
"GPGGAH %.3f\r\n", // needed to get slave antenna position in AGRICA
|
||||
"UNIHEADINGA %.3f\r\n",
|
||||
rate_s);
|
||||
state.gps_yaw_configured = true;
|
||||
FALLTHROUGH;
|
||||
|
@ -85,7 +85,8 @@ private:
|
||||
_GPS_SENTENCE_THS = 160, // True heading with quality indicator, available on Trimble MB-Two
|
||||
_GPS_SENTENCE_KSXT = 170, // extension for Unicore, 21 fields
|
||||
_GPS_SENTENCE_AGRICA = 193, // extension for Unicore, 65 fields
|
||||
_GPS_SENTENCE_VERSIONA = 270, // extension for Unicore, version
|
||||
_GPS_SENTENCE_VERSIONA = 270, // extension for Unicore, version, 10 fields
|
||||
_GPS_SENTENCE_UNIHEADINGA = 290, // extension for Unicore, uniheadinga, 20 fields
|
||||
_GPS_SENTENCE_OTHER = 0
|
||||
};
|
||||
|
||||
@ -136,6 +137,11 @@ private:
|
||||
|
||||
// parse VERSIONA field
|
||||
void parse_versiona_field(uint16_t term_number, const char *term);
|
||||
|
||||
#if GPS_MOVING_BASELINE
|
||||
// parse UNIHEADINGA field
|
||||
void parse_uniheadinga_field(uint16_t term_number, const char *term);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -228,10 +234,10 @@ private:
|
||||
float alt;
|
||||
uint32_t itow;
|
||||
float undulation;
|
||||
double slave_lat, slave_lng;
|
||||
float slave_alt;
|
||||
Vector3f pos_stddev;
|
||||
} _agrica;
|
||||
|
||||
// unicore VERSIONA parsing
|
||||
struct {
|
||||
char type[10];
|
||||
char version[20];
|
||||
@ -239,6 +245,15 @@ private:
|
||||
} _versiona;
|
||||
bool _have_unicore_versiona;
|
||||
|
||||
#if GPS_MOVING_BASELINE
|
||||
// unicore UNIHEADINGA parsing
|
||||
struct {
|
||||
float baseline_length;
|
||||
float heading;
|
||||
float pitch;
|
||||
float heading_sd;
|
||||
} _uniheadinga;
|
||||
#endif
|
||||
#endif // AP_GPS_NMEA_UNICORE_ENABLED
|
||||
bool _expect_agrica;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user