@ -21,13 +21,15 @@
@@ -21,13 +21,15 @@
//
# include "AP_GPS.h"
# include "AP_GPS_UBLOX.h"
# include <AP_HAL/Util.h>
# include <DataFlash/DataFlash.h>
# include <GCS_MAVLink/GCS.h>
# if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
CONFIG_HAL_BOARD_SUBTYPE = = HAL_BOARD_SUBTYPE_LINUX_BH
# define UBLOX_VERSION_AUTODETECTION 1
# define UBLOX_SPEED_CHANGE 1
# else
# define UBLOX_VERSION_AUTODETECTION 0
# define UBLOX_SPEED_CHANGE 0
# endif
@ -48,100 +50,258 @@ AP_GPS_UBLOX::AP_GPS_UBLOX(AP_GPS &_gps, AP_GPS::GPS_State &_state, AP_HAL::UART
@@ -48,100 +50,258 @@ AP_GPS_UBLOX::AP_GPS_UBLOX(AP_GPS &_gps, AP_GPS::GPS_State &_state, AP_HAL::UART
_msg_id ( 0 ) ,
_payload_length ( 0 ) ,
_payload_counter ( 0 ) ,
_fix_count ( 0 ) ,
_class ( 0 ) ,
_cfg_saved ( false ) ,
_last_cfg_sent_time ( 0 ) ,
_num_cfg_save_tries ( 0 ) ,
_last_config_time ( 0 ) ,
_delay_time ( 0 ) ,
_next_message ( STEP_RATE_NAV ) ,
_ublox_port ( 255 ) ,
_have_version ( false ) ,
_unconfigured_messages ( CONFIG_ALL ) ,
_hardware_generation ( 0 ) ,
_new_position ( 0 ) ,
_new_speed ( 0 ) ,
need_rate_update ( false ) ,
_disable_counter ( 0 ) ,
next_fix ( AP_GPS : : NO_FIX ) ,
rate_update_step ( 0 ) ,
_last_5hz_time ( 0 ) ,
noReceivedHdop ( true )
{
// stop any config strings that are pending
gps . send_blob_start ( state . instance , NULL , 0 ) ;
// configure the GPS for the messages we want
_configure_gps ( ) ;
_last_5hz_time = AP_HAL : : millis ( ) ;
// start the process of updating the GPS rates
_request_next_config ( ) ;
}
/*
send the next step of rate updates to the GPS . This reconfigures the
GPS on the fly to have the right message rates . It needs to be
careful to only send a message if there is sufficient buffer space
available on the serial port to avoid it blocking the CPU
*/
void
AP_GPS_UBLOX : : send_next_rate_update ( void )
AP_GPS_UBLOX : : _request_next_config ( void )
{
// don't request config if we shouldn't configure the GPS
if ( gps . _auto_config = = 0 ) {
return ;
}
// Ensure there is enough space for the largest possible outgoing message
if ( port - > txspace ( ) < ( int16_t ) ( sizeof ( struct ubx_header ) + sizeof ( struct ubx_cfg_nav_rate ) + 2 ) ) {
// not enough space - do it next time
return ;
}
//hal.console->printf("next_rate: %u\n", (unsigned)rate_update_step);
Debug ( " Unconfigured messages: %d Current message: %d \n " , _unconfigured_messages , _next_message ) ;
switch ( rate_update_step + + ) {
case 0 :
_configure_navigation_ rate ( 200 ) ;
switch ( _next_message + + ) {
case STEP_RATE_NAV :
_configure_rate ( ) ;
break ;
case 1 :
_configure_message_rate ( CLASS_NAV , MSG_POSLLH , 1 ) ; // 28+8 bytes
case STEP_RATE_POSLLH :
if ( ! _configure_message_rate ( CLASS_NAV , MSG_POSLLH , RATE_POSLLH ) ) {
_next_message - - ;
}
break ;
case 2 :
_configure_message_rate ( CLASS_NAV , MSG_STATUS , 1 ) ; // 16+8 bytes
case STEP_RATE_VELNED :
if ( ! _configure_message_rate ( CLASS_NAV , MSG_VELNED , RATE_VELNED ) ) {
_next_message - - ;
}
break ;
case 3 :
_configure_message_rate ( CLASS_NAV , MSG_SOL , 1 ) ; // 52+8 bytes
case STEP_PORT :
_request_port ( ) ;
break ;
case 4 :
_configure_message_rate ( CLASS_NAV , MSG_VELNED , 1 ) ; // 36+8 bytes
case STEP_POLL_SVINFO :
// not required once we know what generation we are on
if ( _hardware_generation = = 0 ) {
_send_message ( CLASS_NAV , MSG_NAV_SVINFO , 0 , 0 ) ;
}
break ;
case 5 :
_configure_message_rate ( CLASS_NAV , MSG_DOP , 1 ) ; // 18+8 bytes
case STEP_POLL_SBAS :
_send_message ( CLASS_CFG , MSG_CFG_SBAS , NULL , 0 ) ;
break ;
case STEP_POLL_NAV :
_send_message ( CLASS_CFG , MSG_CFG_NAV_SETTINGS , NULL , 0 ) ;
break ;
case 6 :
# if UBLOX_HW_LOGGING
// gather MON_HW at 0.5Hz
_configure_message_rate ( CLASS_MON , MSG_MON_HW , 2 ) ; // 64+8 bytes
# endif
case STEP_POLL_GNSS :
_send_message ( CLASS_CFG , MSG_CFG_GNSS , NULL , 0 ) ;
break ;
case 7 :
# if UBLOX_HW_LOGGING
// gather MON_HW2 at 0.5Hz
_configure_message_rate ( CLASS_MON , MSG_MON_HW2 , 2 ) ; // 24+8 bytes
# endif
case STEP_NAV_RATE :
_request_navigation_rate ( ) ;
break ;
case 8 :
case STEP_POSLLH :
if ( ! _request_message_rate ( CLASS_NAV , MSG_POSLLH ) ) {
_next_message - - ;
}
break ;
case STEP_STATUS :
if ( ! _request_message_rate ( CLASS_NAV , MSG_STATUS ) ) {
_next_message - - ;
}
break ;
case STEP_SOL :
if ( ! _request_message_rate ( CLASS_NAV , MSG_SOL ) ) {
_next_message - - ;
}
break ;
case STEP_VELNED :
if ( ! _request_message_rate ( CLASS_NAV , MSG_VELNED ) ) {
_next_message - - ;
}
break ;
case STEP_DOP :
if ( ! _request_message_rate ( CLASS_NAV , MSG_DOP ) ) {
_next_message - - ;
}
break ;
case STEP_MON_HW :
if ( ! _request_message_rate ( CLASS_MON , MSG_MON_HW ) ) {
_next_message - - ;
}
break ;
case STEP_MON_HW2 :
if ( ! _request_message_rate ( CLASS_MON , MSG_MON_HW2 ) ) {
_next_message - - ;
}
break ;
case STEP_RAW :
# if UBLOX_RXM_RAW_LOGGING
_configure_message_rate ( CLASS_RXM , MSG_RXM_RAW , gps . _raw_data ) ;
if ( gps . _raw_data = = 0 ) {
_unconfigured_messages & = ~ CONFIG_RATE_RAW ;
} else if ( ! _request_message_rate ( CLASS_RXM , MSG_RXM_RAW ) ) {
_next_message - - ;
}
# else
_unconfigured_messages & = ~ COONFIG_RATE_RAW ;
# endif
break ;
case 9 :
case STEP_RAWX :
# if UBLOX_RXM_RAW_LOGGING
_configure_message_rate ( CLASS_RXM , MSG_RXM_RAWX , gps . _raw_data ) ;
if ( gps . _raw_data = = 0 ) {
_unconfigured_messages & = ~ CONFIG_RATE_RAW ;
} else if ( ! _request_message_rate ( CLASS_RXM , MSG_RXM_RAWX ) ) {
_next_message - - ;
}
# else
_unconfigured_messages & = ~ COONFIG_RATE_RAW ;
# endif
break ;
case 10 :
# if UBLOX_VERSION_AUTODETECTION
_request_version ( ) ;
# endif
case STEP_VERSION :
if ( ! _have_version & & ! hal . util - > get_soft_armed ( ) ) {
_request_version ( ) ;
}
// no need to send the initial rates, move to checking only
_next_message = STEP_PORT ;
break ;
default :
need_rate_update = false ;
rate_update_step = 0 ;
// this case should never be reached, do a full reset if it is hit
_next_message = STEP_RATE_NAV ;
break ;
}
}
void
AP_GPS_UBLOX : : _verify_rate ( uint8_t msg_class , uint8_t msg_id , uint8_t rate ) {
switch ( msg_class ) {
case CLASS_NAV :
switch ( msg_id ) {
case MSG_POSLLH :
if ( rate = = RATE_POSLLH ) {
_unconfigured_messages & = ~ CONFIG_RATE_POSLLH ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_POSLLH ) ;
_unconfigured_messages | = CONFIG_RATE_POSLLH ;
}
break ;
case MSG_STATUS :
if ( rate = = RATE_STATUS ) {
_unconfigured_messages & = ~ CONFIG_RATE_STATUS ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_STATUS ) ;
_unconfigured_messages | = CONFIG_RATE_STATUS ;
}
break ;
case MSG_SOL :
if ( rate = = RATE_SOL ) {
_unconfigured_messages & = ~ CONFIG_RATE_SOL ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_SOL ) ;
_unconfigured_messages | = CONFIG_RATE_SOL ;
}
break ;
case MSG_VELNED :
if ( rate = = RATE_VELNED ) {
_unconfigured_messages & = ~ CONFIG_RATE_VELNED ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_VELNED ) ;
_unconfigured_messages | = CONFIG_RATE_VELNED ;
}
break ;
case MSG_DOP :
if ( rate = = RATE_DOP ) {
_unconfigured_messages & = ~ CONFIG_RATE_DOP ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_DOP ) ;
_unconfigured_messages | = CONFIG_RATE_DOP ;
}
break ;
}
break ;
case CLASS_MON :
switch ( msg_id ) {
case MSG_MON_HW :
if ( rate = = RATE_HW ) {
_unconfigured_messages & = ~ CONFIG_RATE_MON_HW ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_HW ) ;
_unconfigured_messages | = CONFIG_RATE_MON_HW ;
}
break ;
case MSG_MON_HW2 :
if ( rate = = RATE_HW2 ) {
_unconfigured_messages & = ~ CONFIG_RATE_MON_HW2 ;
} else {
_configure_message_rate ( msg_class , msg_id , RATE_HW2 ) ;
_unconfigured_messages | = CONFIG_RATE_MON_HW2 ;
}
break ;
}
break ;
# if UBLOX_RXM_RAW_LOGGING
case CLASS_RXM :
switch ( msg_id ) {
case MSG_RXM_RAW :
if ( rate = = gps . _raw_data ) {
_unconfigured_messages & = ~ CONFIG_RATE_RAW ;
} else {
_configure_message_rate ( msg_class , msg_id , gps . _raw_data ) ;
_unconfigured_messages | = CONFIG_RATE_RAW ;
}
break ;
case MSG_RXM_RAWX :
if ( rate = = gps . _raw_data ) {
_unconfigured_messages & = ~ CONFIG_RATE_RAW ;
} else {
_configure_message_rate ( msg_class , msg_id , gps . _raw_data ) ;
_unconfigured_messages | = CONFIG_RATE_RAW ;
}
break ;
}
break ;
# endif // UBLOX_RXM_RAW_LOGGING
}
}
// Requests the ublox driver to identify what port we are using to communicate
void
AP_GPS_UBLOX : : _request_port ( void )
{
if ( port - > txspace ( ) < ( int16_t ) ( sizeof ( struct ubx_header ) + 2 ) ) {
// not enough space - do it next time
return ;
}
_send_message ( CLASS_CFG , MSG_CFG_PRT , NULL , 0 ) ;
}
// Ensure there is enough space for the largest possible outgoing message
// Process bytes available from the stream
//
// The stream is assumed to contain only messages we recognise. If it
@ -159,12 +319,26 @@ AP_GPS_UBLOX::read(void)
@@ -159,12 +319,26 @@ AP_GPS_UBLOX::read(void)
bool parsed = false ;
uint32_t millis_now = AP_HAL : : millis ( ) ;
if ( need_rate_update ) {
send_next_rate_update ( ) ;
} else if ( ! _cfg_saved & & gps . _save_config & & _num_cfg_save_tries < 5 & & ( millis_now - _last_cfg_sent_time ) > 5000 ) { //save the configuration sent until now
_last_cfg_sent_time = millis_now ;
// walk through the gps configuration at 1 message per second
if ( millis_now - _last_config_time > = _delay_time ) {
_request_next_config ( ) ;
_last_config_time = millis_now ;
if ( _unconfigured_messages ) { // send the updates faster until fully configured
if ( _next_message < STEP_PORT ) { // blast the initial settings out
_delay_time = 0 ;
} else {
_delay_time = 750 ;
}
} else {
_delay_time = 2000 ;
}
}
if ( ! _unconfigured_messages & & gps . _save_config & &
_num_cfg_save_tries < 5 & & ( millis_now - _last_cfg_sent_time ) > 5000 & &
! hal . util - > get_soft_armed ( ) ) {
//save the configuration sent until now
_save_cfg ( ) ;
_num_cfg_save_tries + + ;
}
numc = port - > available ( ) ;
@ -275,8 +449,6 @@ AP_GPS_UBLOX::read(void)
@@ -275,8 +449,6 @@ AP_GPS_UBLOX::read(void)
}
// Private Methods /////////////////////////////////////////////////////////////
# if UBLOX_HW_LOGGING
void AP_GPS_UBLOX : : log_mon_hw ( void )
{
if ( gps . _DataFlash = = NULL | | ! gps . _DataFlash - > logging_started ( ) ) {
@ -318,8 +490,6 @@ void AP_GPS_UBLOX::log_mon_hw2(void)
@@ -318,8 +490,6 @@ void AP_GPS_UBLOX::log_mon_hw2(void)
gps . _DataFlash - > WriteBlock ( & pkt , sizeof ( pkt ) ) ;
}
# endif // UBLOX_HW_LOGGING
# if UBLOX_RXM_RAW_LOGGING
void AP_GPS_UBLOX : : log_rxm_raw ( const struct ubx_rxm_raw & raw )
{
@ -405,120 +575,218 @@ AP_GPS_UBLOX::_parse_gps(void)
@@ -405,120 +575,218 @@ AP_GPS_UBLOX::_parse_gps(void)
if ( _class = = CLASS_ACK ) {
Debug ( " ACK %u " , ( unsigned ) _msg_id ) ;
if ( _msg_id = = MSG_ACK_ACK & & _buffer . ack . clsID = = CLASS_CFG & & _buffer . ack . msgID = = MSG_CFG_CFG ) {
_cfg_saved = true ;
if ( _msg_id = = MSG_ACK_ACK ) {
switch ( _buffer . ack . clsID ) {
case CLASS_CFG :
switch ( _buffer . ack . msgID ) {
case MSG_CFG_CFG :
_cfg_saved = true ;
break ;
case MSG_CFG_GNSS :
_unconfigured_messages & = ~ CONFIG_GNSS ;
break ;
case MSG_CFG_MSG :
// There is no way to know what MSG config was ack'ed, assume it was the last
// one requested. To verify it rerequest the last config we sent. If we miss
// the actual ack we will catch it next time through the poll loop, but that
// will be a good chunk of time later.
break ;
case MSG_CFG_NAV_SETTINGS :
_unconfigured_messages & = ~ CONFIG_NAV_SETTINGS ;
break ;
case MSG_CFG_RATE :
_unconfigured_messages & = ~ CONFIG_RATE_NAV ;
break ;
case MSG_CFG_SBAS :
_unconfigured_messages & = ~ CONFIG_SBAS ;
break ;
}
break ;
case CLASS_MON :
switch ( _buffer . ack . msgID ) {
case MSG_MON_HW :
_unconfigured_messages & = ~ CONFIG_RATE_MON_HW ;
break ;
case MSG_MON_HW2 :
_unconfigured_messages & = ~ CONFIG_RATE_MON_HW2 ;
break ;
}
}
}
return false ;
}
if ( _class = = CLASS_CFG & & _msg_id = = MSG_CFG_NAV_SETTINGS ) {
Debug ( " Got settings %u min_elev %d drLimit %u \n " ,
( unsigned ) _buffer . nav_settings . dynModel ,
( int ) _buffer . nav_settings . minElev ,
( unsigned ) _buffer . nav_settings . drLimit ) ;
_buffer . nav_settings . mask = 0 ;
if ( gps . _navfilter ! = AP_GPS : : GPS_ENGINE_NONE & &
_buffer . nav_settings . dynModel ! = gps . _navfilter ) {
// we've received the current nav settings, change the engine
// settings and send them back
Debug ( " Changing engine setting from %u to %u \n " ,
( unsigned ) _buffer . nav_settings . dynModel , ( unsigned ) gps . _navfilter ) ;
_buffer . nav_settings . dynModel = gps . _navfilter ;
_buffer . nav_settings . mask | = 1 ;
}
if ( gps . _min_elevation ! = - 100 & &
_buffer . nav_settings . minElev ! = gps . _min_elevation ) {
Debug ( " Changing min elevation to %d \n " , ( int ) gps . _min_elevation ) ;
_buffer . nav_settings . minElev = gps . _min_elevation ;
_buffer . nav_settings . mask | = 2 ;
}
if ( _buffer . nav_settings . mask ! = 0 ) {
_send_message ( CLASS_CFG , MSG_CFG_NAV_SETTINGS ,
& _buffer . nav_settings ,
sizeof ( _buffer . nav_settings ) ) ;
_cfg_saved = false ; //save configuration
}
return false ;
}
if ( _class = = CLASS_CFG ) {
switch ( _msg_id ) {
case MSG_CFG_NAV_SETTINGS :
Debug ( " Got settings %u min_elev %d drLimit %u \n " ,
( unsigned ) _buffer . nav_settings . dynModel ,
( int ) _buffer . nav_settings . minElev ,
( unsigned ) _buffer . nav_settings . drLimit ) ;
_buffer . nav_settings . mask = 0 ;
if ( gps . _navfilter ! = AP_GPS : : GPS_ENGINE_NONE & &
_buffer . nav_settings . dynModel ! = gps . _navfilter ) {
// we've received the current nav settings, change the engine
// settings and send them back
Debug ( " Changing engine setting from %u to %u \n " ,
( unsigned ) _buffer . nav_settings . dynModel , ( unsigned ) gps . _navfilter ) ;
_buffer . nav_settings . dynModel = gps . _navfilter ;
_buffer . nav_settings . mask | = 1 ;
}
if ( gps . _min_elevation ! = - 100 & &
_buffer . nav_settings . minElev ! = gps . _min_elevation ) {
Debug ( " Changing min elevation to %d \n " , ( int ) gps . _min_elevation ) ;
_buffer . nav_settings . minElev = gps . _min_elevation ;
_buffer . nav_settings . mask | = 2 ;
}
if ( _buffer . nav_settings . mask ! = 0 ) {
_send_message ( CLASS_CFG , MSG_CFG_NAV_SETTINGS ,
& _buffer . nav_settings ,
sizeof ( _buffer . nav_settings ) ) ;
_unconfigured_messages | = CONFIG_NAV_SETTINGS ;
} else {
_unconfigured_messages & = ~ CONFIG_NAV_SETTINGS ;
}
return false ;
# if UBLOX_GNSS_SETTINGS
if ( _class = = CLASS_CFG & & _msg_id = = MSG_CFG_GNSS & & gps . _gnss_mode ! = 0 ) {
uint8_t gnssCount = 0 ;
Debug ( " Got GNSS Settings %u %u %u %u: \n " ,
( unsigned ) _buffer . gnss . msgVer ,
( unsigned ) _buffer . gnss . numTrkChHw ,
( unsigned ) _buffer . gnss . numTrkChUse ,
( unsigned ) _buffer . gnss . numConfigBlocks ) ;
case MSG_CFG_GNSS :
if ( gps . _gnss_mode [ state . instance ] ! = 0 ) {
struct ubx_cfg_gnss start_gnss = _buffer . gnss ;
uint8_t gnssCount = 0 ;
Debug ( " Got GNSS Settings %u %u %u %u: \n " ,
( unsigned ) _buffer . gnss . msgVer ,
( unsigned ) _buffer . gnss . numTrkChHw ,
( unsigned ) _buffer . gnss . numTrkChUse ,
( unsigned ) _buffer . gnss . numConfigBlocks ) ;
# if UBLOX_DEBUGGING
for ( int i = 0 ; i < _buffer . gnss . numConfigBlocks ; i + + ) {
Debug ( " %u %u %u 0x%08x \n " ,
( unsigned ) _buffer . gnss . configBlock [ i ] . gnssId ,
( unsigned ) _buffer . gnss . configBlock [ i ] . resTrkCh ,
( unsigned ) _buffer . gnss . configBlock [ i ] . maxTrkCh ,
( unsigned ) _buffer . gnss . configBlock [ i ] . flags ) ;
}
for ( int i = 0 ; i < _buffer . gnss . numConfigBlocks ; i + + ) {
Debug ( " %u %u %u 0x%08x \n " ,
( unsigned ) _buffer . gnss . configBlock [ i ] . gnssId ,
( unsigned ) _buffer . gnss . configBlock [ i ] . resTrkCh ,
( unsigned ) _buffer . gnss . configBlock [ i ] . maxTrkCh ,
( unsigned ) _buffer . gnss . configBlock [ i ] . flags ) ;
}
# endif
for ( int i = 0 ; i < UBLOX_MAX_GNSS_CONFIG_BLOCKS ; i + + ) {
if ( ( gps . _gnss_mode & ( 1 < < i ) ) & & i ! = GNSS_SBAS ) {
gnssCount + + ;
}
}
for ( int i = 0 ; i < UBLOX_MAX_GNSS_CONFIG_BLOCKS ; i + + ) {
if ( ( gps . _gnss_mode [ state . instance ] & ( 1 < < i ) ) & & i ! = GNSS_SBAS ) {
gnssCount + + ;
}
}
for ( int i = 0 ; i < _buffer . gnss . numConfigBlocks ; i + + ) {
// Reserve an equal portion of channels for all enabled systems
if ( gps . _gnss_mode & ( 1 < < _buffer . gnss . configBlock [ i ] . gnssId ) ) {
if ( GNSS_SBAS ! = _buffer . gnss . configBlock [ i ] . gnssId ) {
_buffer . gnss . configBlock [ i ] . resTrkCh = ( _buffer . gnss . numTrkChHw - 3 ) / ( gnssCount * 2 ) ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = _buffer . gnss . numTrkChHw ;
for ( int i = 0 ; i < _buffer . gnss . numConfigBlocks ; i + + ) {
// Reserve an equal portion of channels for all enabled systems
if ( gps . _gnss_mode [ state . instance ] & ( 1 < < _buffer . gnss . configBlock [ i ] . gnssId ) ) {
if ( GNSS_SBAS ! = _buffer . gnss . configBlock [ i ] . gnssId ) {
_buffer . gnss . configBlock [ i ] . resTrkCh = ( _buffer . gnss . numTrkChHw - 3 ) / ( gnssCount * 2 ) ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = _buffer . gnss . numTrkChHw ;
} else {
_buffer . gnss . configBlock [ i ] . resTrkCh = 1 ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = 3 ;
}
_buffer . gnss . configBlock [ i ] . flags = _buffer . gnss . configBlock [ i ] . flags | 0x00000001 ;
} else {
_buffer . gnss . configBlock [ i ] . resTrkCh = 0 ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = 0 ;
_buffer . gnss . configBlock [ i ] . flags = _buffer . gnss . configBlock [ i ] . flags & 0xFFFFFFFE ;
}
}
if ( ! memcmp ( & start_gnss , & _buffer . gnss , sizeof ( start_gnss ) ) ) {
_send_message ( CLASS_CFG , MSG_CFG_GNSS , & _buffer . gnss , 4 + ( 8 * _buffer . gnss . numConfigBlocks ) ) ;
_unconfigured_messages | = CONFIG_GNSS ;
} else {
_buffer . gnss . configBlock [ i ] . resTrkCh = 1 ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = 3 ;
_unconfigured_messages & = ~ CONFIG_GNSS ;
}
_buffer . gnss . configBlock [ i ] . flags = _buffer . gnss . configBlock [ i ] . flags | 0x00000001 ;
} else {
_buffer . gnss . configBlock [ i ] . resTrkCh = 0 ;
_buffer . gnss . configBlock [ i ] . maxTrkCh = 0 ;
_buffer . gnss . configBlock [ i ] . flags = _buffer . gnss . configBlock [ i ] . flags & 0xFFFFFFFE ;
_unconfigured_messages & = ~ CONFIG_GNSS ;
}
}
_send_message ( CLASS_CFG , MSG_CFG_GNSS , & _buffer . gnss , 4 + ( 8 * _buffer . gnss . numConfigBlocks ) ) ;
return false ;
}
return false ;
# endif
if ( _class = = CLASS_CFG & & _msg_id = = MSG_CFG_SBAS & & gps . _sbas_mode ! = 2 ) {
Debug ( " Got SBAS settings %u %u %u 0x%x 0x%x \n " ,
( unsigned ) _buffer . sbas . mode ,
( unsigned ) _buffer . sbas . usage ,
( unsigned ) _buffer . sbas . maxSBAS ,
( unsigned ) _buffer . sbas . scanmode2 ,
( unsigned ) _buffer . sbas . scanmode1 ) ;
if ( _buffer . sbas . mode ! = gps . _sbas_mode ) {
_buffer . sbas . mode = gps . _sbas_mode ;
_send_message ( CLASS_CFG , MSG_CFG_SBAS ,
& _buffer . sbas ,
sizeof ( _buffer . sbas ) ) ;
_cfg_saved = false ;
case MSG_CFG_SBAS :
if ( gps . _sbas_mode ! = 2 ) {
Debug ( " Got SBAS settings %u %u %u 0x%x 0x%x \n " ,
( unsigned ) _buffer . sbas . mode ,
( unsigned ) _buffer . sbas . usage ,
( unsigned ) _buffer . sbas . maxSBAS ,
( unsigned ) _buffer . sbas . scanmode2 ,
( unsigned ) _buffer . sbas . scanmode1 ) ;
if ( _buffer . sbas . mode ! = gps . _sbas_mode ) {
_buffer . sbas . mode = gps . _sbas_mode ;
_send_message ( CLASS_CFG , MSG_CFG_SBAS ,
& _buffer . sbas ,
sizeof ( _buffer . sbas ) ) ;
_unconfigured_messages | = CONFIG_SBAS ;
} else {
_unconfigured_messages & = ~ CONFIG_SBAS ;
}
} else {
_unconfigured_messages & = ~ CONFIG_SBAS ;
}
return false ;
case MSG_CFG_MSG :
if ( _payload_length = = sizeof ( ubx_cfg_msg_rate_6 ) ) {
// can't verify the setting without knowing the port
// request the port again
if ( _ublox_port > = UBLOX_MAX_PORTS ) {
_request_port ( ) ;
return false ;
}
_verify_rate ( _buffer . msg_rate_6 . msg_class , _buffer . msg_rate_6 . msg_id ,
_buffer . msg_rate_6 . rates [ _ublox_port ] ) ;
} else {
_verify_rate ( _buffer . msg_rate . msg_class , _buffer . msg_rate . msg_id ,
_buffer . msg_rate . rate ) ;
}
return false ;
case MSG_CFG_PRT :
_ublox_port = _buffer . prt . portID ;
return false ;
case MSG_CFG_RATE :
if ( _buffer . nav_rate . measure_rate_ms ! = MEASURE_RATE | |
_buffer . nav_rate . nav_rate ! = 1 | |
_buffer . nav_rate . timeref ! = 0 ) {
_configure_rate ( ) ;
_unconfigured_messages | = CONFIG_RATE_NAV ;
} else {
_unconfigured_messages & = ~ CONFIG_RATE_NAV ;
}
return false ;
}
}
# if UBLOX_HW_LOGGING
if ( _class = = CLASS_MON ) {
if ( _msg_id = = MSG_MON_HW ) {
switch ( _msg_id ) {
case MSG_MON_HW :
if ( _payload_length = = 60 | | _payload_length = = 68 ) {
log_mon_hw ( ) ;
}
} else if ( _msg_id = = MSG_MON_HW2 ) {
break ;
case MSG_MON_HW2 :
if ( _payload_length = = 28 ) {
log_mon_hw2 ( ) ;
}
} else {
break ;
case MSG_MON_VER :
char version_buffer [ 46 ] ; //17 string swVersion 30 hwVersion 10
_have_version = true ;
hal . util - > snprintf ( version_buffer , sizeof ( version_buffer ) ,
" u-blox %d HW: %s SW: %s " ,
state . instance ,
_buffer . mon_ver . hwVersion ,
_buffer . mon_ver . swVersion ) ;
GCS_MAVLINK : : send_statustext_all ( MAV_SEVERITY_INFO , version_buffer ) ;
if ( gps . _DataFlash ! = NULL & & gps . _DataFlash - > logging_started ( ) ) {
gps . _DataFlash - > Log_Write_Message ( version_buffer ) ;
}
break ;
default :
unexpected_message ( ) ;
}
return false ;
}
# endif // UBLOX_HW_LOGGING
# if UBLOX_RXM_RAW_LOGGING
if ( _class = = CLASS_RXM & & _msg_id = = MSG_RXM_RAW & & gps . _raw_data ! = 0 ) {
@ -652,31 +920,33 @@ AP_GPS_UBLOX::_parse_gps(void)
@@ -652,31 +920,33 @@ AP_GPS_UBLOX::_parse_gps(void)
# endif
_new_speed = true ;
break ;
# if UBLOX_VERSION_AUTODETECTION
case MSG_NAV_SVINFO :
{
Debug ( " MSG_NAV_SVINFO \n " ) ;
static const uint8_t HardwareGenerationMask = 0x07 ;
uint8_t hardware_generation = _buffer . svinfo_header . globalFlags & HardwareGenerationMask ;
switch ( hardware_generation ) {
_ hardware_generation = _buffer . svinfo_header . globalFlags & HardwareGenerationMask ;
switch ( _ hardware_generation) {
case UBLOX_5 :
case UBLOX_6 :
/*speed already configured */ ;
// only 7 and newer support CONFIG_GNSS
_unconfigured_messages & = ~ CONFIG_GNSS ;
break ;
case UBLOX_7 :
case UBLOX_M8 :
# if UBLOX_SPEED_CHANGE
port - > begin ( 4000000U ) ;
Debug ( " Changed speed to 5Mhzfor SPI-driven UBlox \n " ) ;
Debug ( " Changed speed to 4Mhz for SPI-driven UBlox \n " ) ;
# endif
break ;
default :
hal . console - > printf ( " Wrong Ublox' Hardware Version%u \n " , hardware_generation ) ;
hal . console - > printf ( " Wrong Ublox Hardware Version%u \n " , _ hardware_generation) ;
break ;
} ;
_unconfigured_messages & = ~ CONFIG_VERSION ;
/* We don't need that anymore */
_configure_message_rate ( CLASS_NAV , MSG_NAV_SVINFO , 0 ) ;
break ;
}
# endif
default :
Debug ( " Unexpected NAV message 0x%02x " , ( unsigned ) _msg_id ) ;
if ( + + _disable_counter = = 0 ) {
@ -690,27 +960,16 @@ AP_GPS_UBLOX::_parse_gps(void)
@@ -690,27 +960,16 @@ AP_GPS_UBLOX::_parse_gps(void)
// this ensures we don't use stale data
if ( _new_position & & _new_speed & & _last_vel_time = = _last_pos_time ) {
_new_speed = _new_position = false ;
_fix_count + + ;
if ( ( AP_HAL : : millis ( ) - _last_5hz_time ) > 15000U & & ! need_rate_update ) {
// the GPS is running slow. It possibly browned out and
// restarted with incorrect parameters. We will slowly
// send out new parameters to fix it
need_rate_update = true ;
rate_update_step = 0 ;
if ( AP_HAL : : millis ( ) - _last_5hz_time > 10000U ) {
// the gps seems to be slow, possibly due to a brown out
// invalidate the config so it can be reset
_last_5hz_time = AP_HAL : : millis ( ) ;
_unconfigured_messages = CONFIG_ALL ;
_request_next_config ( ) ;
GCS_MAVLINK : : send_statustext_all ( MAV_SEVERITY_CRITICAL ,
" GPS: u-blox %d is not maintaining a 5Hz update " ,
state . instance ) ;
}
if ( _fix_count = = 50 & & gps . _sbas_mode ! = 2 ) {
// ask for SBAS settings every 20 seconds
Debug ( " Asking for SBAS setting \n " ) ;
_send_message ( CLASS_CFG , MSG_CFG_SBAS , NULL , 0 ) ;
}
if ( _fix_count = = 100 ) {
// ask for nav settings every 20 seconds
Debug ( " Asking for engine setting \n " ) ;
_send_message ( CLASS_CFG , MSG_CFG_NAV_SETTINGS , NULL , 0 ) ;
_fix_count = 0 ;
}
return true ;
}
return false ;
@ -756,49 +1015,54 @@ AP_GPS_UBLOX::_send_message(uint8_t msg_class, uint8_t msg_id, void *msg, uint16
@@ -756,49 +1015,54 @@ AP_GPS_UBLOX::_send_message(uint8_t msg_class, uint8_t msg_id, void *msg, uint16
port - > write ( ( const uint8_t * ) & ck_b , 1 ) ;
}
/*
* requests the given message rate for a specific message class
* and msg_id
* returns true if it sent the request , false if waiting on knowing the port
*/
bool
AP_GPS_UBLOX : : _request_message_rate ( uint8_t msg_class , uint8_t msg_id )
{
// Without knowing what communication port is being used it isn't possible to verify
// always ensure we have a port before sending the request
if ( _ublox_port > = UBLOX_MAX_PORTS ) {
_request_port ( ) ;
return false ;
} else {
struct ubx_cfg_msg msg ;
msg . msg_class = msg_class ;
msg . msg_id = msg_id ;
_send_message ( CLASS_CFG , MSG_CFG_MSG , & msg , sizeof ( msg ) ) ;
return true ;
}
}
/*
* configure a UBlox GPS for the given message rate for a specific
* message class and msg_id
*/
void
bool
AP_GPS_UBLOX : : _configure_message_rate ( uint8_t msg_class , uint8_t msg_id , uint8_t rate )
{
if ( port - > txspace ( ) < ( int16_t ) ( sizeof ( struct ubx_header ) + sizeof ( struct ubx_cfg_msg_rate ) + 2 ) ) {
return false ;
}
struct ubx_cfg_msg_rate msg ;
msg . msg_class = msg_class ;
msg . msg_id = msg_id ;
msg . rate = rate ;
_send_message ( CLASS_CFG , MSG_CFG_SET_RATE , & msg , sizeof ( msg ) ) ;
}
/*
* configure a UBlox GPS navigation solution rate of 200 ms
*/
void
AP_GPS_UBLOX : : _configure_navigation_rate ( uint16_t rate_ms )
{
struct ubx_cfg_nav_rate msg ;
msg . measure_rate_ms = rate_ms ;
msg . nav_rate = 1 ;
msg . timeref = 0 ; // UTC time
_send_message ( CLASS_CFG , MSG_CFG_RATE , & msg , sizeof ( msg ) ) ;
_send_message ( CLASS_CFG , MSG_CFG_MSG , & msg , sizeof ( msg ) ) ;
return true ;
}
/*
* configure a UBlox GPS for the given message rate
* request the current naviation solution rate
*/
void
AP_GPS_UBLOX : : _configure_gps ( void )
AP_GPS_UBLOX : : _request_navigation_rate ( void )
{
// start the process of updating the GPS rates
need_rate_update = true ;
_last_5hz_time = AP_HAL : : millis ( ) ;
rate_update_step = 0 ;
// ask for the current navigation settings
Debug ( " Asking for engine setting \n " ) ;
_send_message ( CLASS_CFG , MSG_CFG_NAV_SETTINGS , NULL , 0 ) ;
_send_message ( CLASS_CFG , MSG_CFG_GNSS , NULL , 0 ) ;
_send_message ( CLASS_CFG , MSG_CFG_RATE , 0 , 0 ) ;
}
/*
@ -813,6 +1077,8 @@ AP_GPS_UBLOX::_save_cfg()
@@ -813,6 +1077,8 @@ AP_GPS_UBLOX::_save_cfg()
save_cfg . saveMask = SAVE_CFG_ALL ;
save_cfg . loadMask = 0 ;
_send_message ( CLASS_CFG , MSG_CFG_CFG , & save_cfg , sizeof ( save_cfg ) ) ;
_last_cfg_sent_time = AP_HAL : : millis ( ) ;
_num_cfg_save_tries + + ;
}
/*
@ -880,5 +1146,15 @@ reset:
@@ -880,5 +1146,15 @@ reset:
void
AP_GPS_UBLOX : : _request_version ( void )
{
_configure_message_rate ( CLASS_NAV , MSG_NAV_SVINFO , 2 ) ;
_send_message ( CLASS_MON , MSG_MON_VER , NULL , 0 ) ;
}
void
AP_GPS_UBLOX : : _configure_rate ( void )
{
struct ubx_cfg_nav_rate msg ;
msg . measure_rate_ms = MEASURE_RATE ;
msg . nav_rate = 1 ;
msg . timeref = 0 ; // UTC time
_send_message ( CLASS_CFG , MSG_CFG_RATE , & msg , sizeof ( msg ) ) ;
}