Add full auto support for NAV SVIN

This commit is contained in:
PaulZC
2022-04-04 11:34:56 +01:00
parent 57f4189399
commit bedd4cc779
5 changed files with 176 additions and 20 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ v2.1 of the library adds support for u-blox AssistNow<sup>TM</sup> Assisted GNSS
This library is the new and improved version of the very popular SparkFun u-blox GNSS Arduino Library. v2.0 contains some big changes and improvements: This library is the new and improved version of the very popular SparkFun u-blox GNSS Arduino Library. v2.0 contains some big changes and improvements:
* Seamless support for "automatic" message delivery: * Seamless support for "automatic" message delivery:
* In v1.8, you could ask for the NAV PVT (Navigation Position Velocity Time) message to be delivered _automatically_, without polling. v2.0 adds automatic support for [**26 messages**](./Theory.md#auto-messages), covering the full range of: standard and High Precision position, velocity, attitude and time information; relative positioning; event capture with nanosecond time resolution; raw GNSS signal data including carrier phase; Sensor Fusion; and High Navigation Rate data. * In v1.8, you could ask for the NAV PVT (Navigation Position Velocity Time) message to be delivered _automatically_, without polling. v2.0 adds automatic support for [**27 messages**](./Theory.md#auto-messages), covering the full range of: standard and High Precision position, velocity, attitude and time information; relative positioning; event capture with nanosecond time resolution; raw GNSS signal data including carrier phase; Sensor Fusion; and High Navigation Rate data.
* Don't see the message you really need? [Adding_New_Messages](./Adding_New_Messages.md) provides details on how to add "auto" support for your favourite message. * Don't see the message you really need? [Adding_New_Messages](./Adding_New_Messages.md) provides details on how to add "auto" support for your favourite message.
* Dynamic memory allocation with clearly-defined data storage structs for each message: * Dynamic memory allocation with clearly-defined data storage structs for each message:
* There are no static 'global' variables to eat up your RAM. v2.0 automatically allocates memory for the automatic messages when they are enabled. You may find your total RAM use is lower with v2.0 than with v1.8. * There are no static 'global' variables to eat up your RAM. v2.0 automatically allocates memory for the automatic messages when they are enabled. You may find your total RAM use is lower with v2.0 than with v1.8.
+6
View File
@@ -359,6 +359,12 @@ getCurrentLeapSeconds KEYWORD2
initPacketUBXNAVTIMELS KEYWORD2 initPacketUBXNAVTIMELS KEYWORD2
getSurveyStatus KEYWORD2 getSurveyStatus KEYWORD2
setAutoNAVSVIN KEYWORD2
setAutoNAVSVINrate KEYWORD2
setAutoNAVSVINcallbackPtr KEYWORD2
assumeAutoNAVSVIN KEYWORD2
flushNAVSVIN KEYWORD2
logNAVSVIN KEYWORD2
initPacketUBXNAVSVIN KEYWORD2 initPacketUBXNAVSVIN KEYWORD2
getNAVSAT KEYWORD2 getNAVSAT KEYWORD2
+146 -1
View File
@@ -3588,6 +3588,20 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
// Mark all datums as fresh (not read before) // Mark all datums as fresh (not read before)
packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0xFFFFFFFF; packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0xFFFFFFFF;
// Check if we need to copy the data for the callback
if ((packetUBXNAVSVIN->callbackData != NULL) // If RAM has been allocated for the copy of the data
&& (packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid == false)) // AND the data is stale
{
memcpy(&packetUBXNAVSVIN->callbackData->version, &packetUBXNAVSVIN->data.version, sizeof(UBX_NAV_SVIN_data_t));
packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid = true;
}
// Check if we need to copy the data into the file buffer
if (packetUBXNAVSVIN->automaticFlags.flags.bits.addToFileBuffer)
{
storePacket(msg);
}
} }
} }
else if (msg->id == UBX_NAV_SAT) // Note: length is variable else if (msg->id == UBX_NAV_SAT) // Note: length is variable
@@ -5313,6 +5327,19 @@ void SFE_UBLOX_GNSS::checkCallbacks(void)
packetUBXNAVCLOCK->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale packetUBXNAVCLOCK->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
} }
if ((packetUBXNAVSVIN != NULL) // If RAM has been allocated for message storage
&& (packetUBXNAVSVIN->callbackData != NULL) // If RAM has been allocated for the copy of the data
&& (packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
{
if (packetUBXNAVSVIN->callbackPointerPtr != NULL) // If the pointer to the callback has been defined
{
// if (_printDebug == true)
// _debugSerial->println(F("checkCallbacks: calling callbackPtr for NAV SVIN"));
packetUBXNAVSVIN->callbackPointerPtr(packetUBXNAVSVIN->callbackData); // Call the callback
}
packetUBXNAVSVIN->automaticFlags.flags.bits.callbackCopyValid = false; // Mark the data as stale
}
if ((packetUBXNAVSAT != NULL) // If RAM has been allocated for message storage if ((packetUBXNAVSAT != NULL) // If RAM has been allocated for message storage
&& (packetUBXNAVSAT->callbackData != NULL) // If RAM has been allocated for the copy of the data && (packetUBXNAVSAT->callbackData != NULL) // If RAM has been allocated for the copy of the data
&& (packetUBXNAVSAT->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid && (packetUBXNAVSAT->automaticFlags.flags.bits.callbackCopyValid == true)) // If the copy of the data is valid
@@ -11629,6 +11656,20 @@ bool SFE_UBLOX_GNSS::getSurveyStatus(uint16_t maxWait)
if (packetUBXNAVSVIN == NULL) // Abort if the RAM allocation failed if (packetUBXNAVSVIN == NULL) // Abort if the RAM allocation failed
return (false); return (false);
if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate)
{
// The GPS is automatically reporting, we just check whether we got unread data
checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_SVIN);
return packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all;
}
else if (packetUBXNAVSVIN->automaticFlags.flags.bits.automatic && !packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate)
{
// Someone else has to call checkUblox for us...
return (false);
}
else
{
// The GPS is not automatically reporting SVIN so we have to poll explicitly
packetCfg.cls = UBX_CLASS_NAV; packetCfg.cls = UBX_CLASS_NAV;
packetCfg.id = UBX_NAV_SVIN; packetCfg.id = UBX_NAV_SVIN;
packetCfg.len = 0; packetCfg.len = 0;
@@ -11646,6 +11687,95 @@ bool SFE_UBLOX_GNSS::getSurveyStatus(uint16_t maxWait)
} }
return (false); return (false);
}
}
// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
// works.
bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, uint16_t maxWait)
{
return setAutoNAVSVINrate(enable ? 1 : 0, true, maxWait);
}
// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
// works.
bool SFE_UBLOX_GNSS::setAutoNAVSVIN(bool enable, bool implicitUpdate, uint16_t maxWait)
{
return setAutoNAVSVINrate(enable ? 1 : 0, implicitUpdate, maxWait);
}
// Enable or disable automatic SVIN message generation by the GNSS. This changes the way getSurveyStatus
// works.
bool SFE_UBLOX_GNSS::setAutoNAVSVINrate(uint8_t rate, bool implicitUpdate, uint16_t maxWait)
{
if (packetUBXNAVSVIN == NULL)
initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the data
if (packetUBXNAVSVIN == NULL) // Only attempt this if RAM allocation was successful
return false;
if (rate > 127)
rate = 127;
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_MSG;
packetCfg.len = 3;
packetCfg.startingSpot = 0;
payloadCfg[0] = UBX_CLASS_NAV;
payloadCfg[1] = UBX_NAV_SVIN;
payloadCfg[2] = rate; // rate relative to navigation freq.
bool ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
if (ok)
{
packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = (rate > 0);
packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = implicitUpdate;
}
packetUBXNAVSVIN->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale
return ok;
}
// Enable automatic navigation message generation by the GNSS.
bool SFE_UBLOX_GNSS::setAutoNAVSVINcallbackPtr(void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), uint16_t maxWait)
{
// Enable auto messages. Set implicitUpdate to false as we expect the user to call checkUblox manually.
bool result = setAutoNAVSVIN(true, false, maxWait);
if (!result)
return (result); // Bail if setAuto failed
if (packetUBXNAVSVIN->callbackData == NULL) // Check if RAM has been allocated for the callback copy
{
packetUBXNAVSVIN->callbackData = new UBX_NAV_SVIN_data_t; // Allocate RAM for the main struct
}
if (packetUBXNAVSVIN->callbackData == NULL)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("setAutoNAVSVINcallbackPtr: RAM alloc failed!"));
#endif
return (false);
}
packetUBXNAVSVIN->callbackPointerPtr = callbackPointerPtr;
return (true);
}
// In case no config access to the GNSS is possible and SVIN is send cyclically already
// set config to suitable parameters
bool SFE_UBLOX_GNSS::assumeAutoNAVSVIN(bool enabled, bool implicitUpdate)
{
if (packetUBXNAVSVIN == NULL)
initPacketUBXNAVSVIN(); // Check that RAM has been allocated for the SVIN data
if (packetUBXNAVSVIN == NULL) // Bail if the RAM allocation failed
return (false);
bool changes = packetUBXNAVSVIN->automaticFlags.flags.bits.automatic != enabled || packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate != implicitUpdate;
if (changes)
{
packetUBXNAVSVIN->automaticFlags.flags.bits.automatic = enabled;
packetUBXNAVSVIN->automaticFlags.flags.bits.implicitUpdate = implicitUpdate;
}
return changes;
} }
// PRIVATE: Allocate RAM for packetUBXNAVSVIN and initialize it // PRIVATE: Allocate RAM for packetUBXNAVSVIN and initialize it
@@ -11661,13 +11791,28 @@ bool SFE_UBLOX_GNSS::initPacketUBXNAVSVIN()
return (false); return (false);
} }
packetUBXNAVSVIN->automaticFlags.flags.all = 0; packetUBXNAVSVIN->automaticFlags.flags.all = 0;
packetUBXNAVSVIN->callbackPointer = NULL;
packetUBXNAVSVIN->callbackPointerPtr = NULL; packetUBXNAVSVIN->callbackPointerPtr = NULL;
packetUBXNAVSVIN->callbackData = NULL; packetUBXNAVSVIN->callbackData = NULL;
packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0; packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0;
return (true); return (true);
} }
// Mark all the data as read/stale
void SFE_UBLOX_GNSS::flushNAVSVIN()
{
if (packetUBXNAVSVIN == NULL)
return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!)
packetUBXNAVSVIN->moduleQueried.moduleQueried.all = 0; // Mark all datums as stale (read before)
}
// Log this data in file buffer
void SFE_UBLOX_GNSS::logNAVSVIN(bool enabled)
{
if (packetUBXNAVSVIN == NULL)
return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!)
packetUBXNAVSVIN->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
}
// ***** NAV SAT automatic support // ***** NAV SAT automatic support
// Signal information // Signal information
+9 -3
View File
@@ -1110,11 +1110,17 @@ public:
void flushNAVCLOCK(); // Mark all the data as read/stale void flushNAVCLOCK(); // Mark all the data as read/stale
void logNAVCLOCK(bool enabled = true); // Log data to file buffer void logNAVCLOCK(bool enabled = true); // Log data to file buffer
// Add "auto" support for NAV SVIN - to avoid needing 'global' storage bool getSurveyStatus(uint16_t maxWait = 2100); // NAV SVIN - Reads survey in status
bool getSurveyStatus(uint16_t maxWait); // Reads survey in status bool setAutoNAVSVIN(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic survey in reports at the navigation frequency
bool setAutoNAVSVIN(bool enabled, bool implicitUpdate, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic survey in reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
bool setAutoNAVSVINrate(uint8_t rate, bool implicitUpdate = true, uint16_t maxWait = defaultMaxWait); // Set the rate for automatic SVIN reports
bool setAutoNAVSVINcallbackPtr(void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *), uint16_t maxWait = defaultMaxWait); // Enable automatic SVIN reports at the navigation frequency. Data is accessed from the callback.
bool assumeAutoNAVSVIN(bool enabled, bool implicitUpdate = true); // In case no config access to the GPS is possible and survey in is send cyclically already
void flushNAVSVIN(); // Mark all the data as read/stale
void logNAVSVIN(bool enabled = true); // Log data to file buffer
// Add "auto" support for NAV TIMELS - to avoid needing 'global' storage // Add "auto" support for NAV TIMELS - to avoid needing 'global' storage
bool getLeapSecondEvent(uint16_t maxWait); // Reads leap second event info bool getLeapSecondEvent(uint16_t maxWait = defaultMaxWait); // Reads leap second event info
bool getNAVSAT(uint16_t maxWait = defaultMaxWait); // Query module for latest AssistNow Autonomous status and load global vars:. If autoNAVSAT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new NAVSAT is available. bool getNAVSAT(uint16_t maxWait = defaultMaxWait); // Query module for latest AssistNow Autonomous status and load global vars:. If autoNAVSAT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new NAVSAT is available.
bool setAutoNAVSAT(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic NAVSAT reports at the navigation frequency bool setAutoNAVSAT(bool enabled, uint16_t maxWait = defaultMaxWait); // Enable/disable automatic NAVSAT reports at the navigation frequency
-1
View File
@@ -1233,7 +1233,6 @@ typedef struct
ubxAutomaticFlags automaticFlags; ubxAutomaticFlags automaticFlags;
UBX_NAV_SVIN_data_t data; UBX_NAV_SVIN_data_t data;
UBX_NAV_SVIN_moduleQueried_t moduleQueried; UBX_NAV_SVIN_moduleQueried_t moduleQueried;
void (*callbackPointer)(UBX_NAV_SVIN_data_t);
void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *); void (*callbackPointerPtr)(UBX_NAV_SVIN_data_t *);
UBX_NAV_SVIN_data_t *callbackData; UBX_NAV_SVIN_data_t *callbackData;
} UBX_NAV_SVIN_t; } UBX_NAV_SVIN_t;