Add support for AssistNow Offline. Add Example. Add findMGAANOForDate.
This commit is contained in:
@@ -3987,23 +3987,56 @@ bool SFE_UBLOX_GNSS::pushRawData(uint8_t *dataBytes, size_t numDataBytes, bool s
|
||||
// allowing the user to override with their own time data with setUTCTimeAssistance.
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(false, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
return (pushAssistNowDataInternal(0, false, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(false, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
return (pushAssistNowDataInternal(0, false, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(skipTime, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
return (pushAssistNowDataInternal(0, skipTime, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(skipTime, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
return (pushAssistNowDataInternal(0, skipTime, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowDataInternal(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(size_t offset, bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
size_t dataPtr = 0; // Pointer into dataBytes
|
||||
return (pushAssistNowDataInternal(offset, skipTime, (const uint8_t *)dataBytes.c_str(), numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowData(size_t offset, bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
return (pushAssistNowDataInternal(offset, skipTime, dataBytes, numDataBytes, mgaAck, maxWait));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::pushAssistNowDataInternal(size_t offset, bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck, uint16_t maxWait)
|
||||
{
|
||||
size_t dataPtr = offset; // Pointer into dataBytes
|
||||
|
||||
if ((offset >= numDataBytes) || (offset < 0)) // Sanity check. Return now if offset is invalid.
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("pushAssistNowData: offset ("));
|
||||
_debugSerial->print(offset);
|
||||
_debugSerial->println(F(") is invalid! Aborting..."));
|
||||
}
|
||||
#endif
|
||||
return ((size_t)0);
|
||||
}
|
||||
|
||||
if (numDataBytes < 0) // Sanity check. Return now if numDataBytes is negative.
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->println(F("pushAssistNowData: numDataBytes is negative! Aborting..."));
|
||||
}
|
||||
#endif
|
||||
return ((size_t)0);
|
||||
}
|
||||
|
||||
size_t packetsProcessed = 0; // Keep count of how many packets have been processed
|
||||
|
||||
bool checkForAcks = (mgaAck == SFE_UBLOX_MGA_ASSIST_ACK_YES); // If mgaAck is YES, always check for Acks
|
||||
@@ -4245,7 +4278,152 @@ bool SFE_UBLOX_GNSS::setUTCTimeAssistance(uint16_t year, uint8_t month, uint8_t
|
||||
}
|
||||
|
||||
// Return true if the one packet was pushed successfully
|
||||
return (pushAssistNowDataInternal(false, iniTimeUTC, 32, mgaAck, maxWait) == 1);
|
||||
return (pushAssistNowDataInternal(0, false, iniTimeUTC, 32, mgaAck, maxWait) == 1);
|
||||
}
|
||||
|
||||
// Find the start of the AssistNow Offline (UBX_MGA_ANO) data for the chosen day
|
||||
// The daysIntoFture parameter makes it easy to get the data for (e.g.) tomorrow based on today's date
|
||||
// Returns numDataBytes if unsuccessful
|
||||
// TO DO: enhance this so it will find the nearest data for the chosen day - instead of an exact match
|
||||
size_t SFE_UBLOX_GNSS::findMGAANOForDate(const String &dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture)
|
||||
{
|
||||
return (findMGAANOForDateInternal((const uint8_t *)dataBytes.c_str(), numDataBytes, year, month, day, daysIntoFuture));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::findMGAANOForDate(const uint8_t *dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture)
|
||||
{
|
||||
return (findMGAANOForDateInternal(dataBytes, numDataBytes, year, month, day, daysIntoFuture));
|
||||
}
|
||||
size_t SFE_UBLOX_GNSS::findMGAANOForDateInternal(const uint8_t *dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture)
|
||||
{
|
||||
size_t dataPtr = 0; // Pointer into dataBytes
|
||||
bool dateFound = false; // Flag to indicate when the date has been found
|
||||
|
||||
// Calculate matchDay, matchMonth and matchYear
|
||||
uint8_t matchDay = day;
|
||||
uint8_t matchMonth = month;
|
||||
uint8_t matchYear = (uint8_t)(year - 2000);
|
||||
|
||||
// Add on daysIntoFuture
|
||||
uint8_t daysIntoFutureCopy = daysIntoFuture;
|
||||
while (daysIntoFutureCopy > 0)
|
||||
{
|
||||
matchDay++;
|
||||
daysIntoFutureCopy--;
|
||||
switch (matchMonth)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 12:
|
||||
if (matchDay == 32)
|
||||
{
|
||||
matchDay = 1;
|
||||
matchMonth++;
|
||||
if (matchMonth == 13)
|
||||
{
|
||||
matchMonth = 1;
|
||||
matchYear++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
case 9:
|
||||
case 11:
|
||||
if (matchDay == 31)
|
||||
{
|
||||
matchDay = 1;
|
||||
matchMonth++;
|
||||
}
|
||||
break;
|
||||
default: // February
|
||||
if (((matchYear % 4) == 0) && (matchDay == 30))
|
||||
{
|
||||
matchDay = 1;
|
||||
matchMonth++;
|
||||
}
|
||||
else if (((matchYear % 4) > 0) && (matchDay == 29))
|
||||
{
|
||||
matchDay = 1;
|
||||
matchMonth++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while ((!dateFound) && (dataPtr < numDataBytes)) // Keep going until we have found the date or processed all the bytes
|
||||
{
|
||||
// Start by checking the validity of the packet being pointed to
|
||||
bool dataIsOK = true;
|
||||
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 0) == UBX_SYNCH_1); // Check for 0xB5
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 1) == UBX_SYNCH_2); // Check for 0x62
|
||||
dataIsOK &= (*(dataBytes + dataPtr + 2) == UBX_CLASS_MGA); // Check for class UBX-MGA
|
||||
|
||||
size_t packetLength = ((size_t)*(dataBytes + dataPtr + 4)) | (((size_t)*(dataBytes + dataPtr + 5)) << 8); // Extract the length
|
||||
|
||||
uint8_t checksumA = 0;
|
||||
uint8_t checksumB = 0;
|
||||
// Calculate the checksum bytes
|
||||
// Keep going until the end of the packet is reached (payloadPtr == (dataPtr + packetLength))
|
||||
// or we reach the end of the AssistNow data (payloadPtr == numDataBytes)
|
||||
for (size_t payloadPtr = dataPtr + ((size_t)2); (payloadPtr < (dataPtr + packetLength + ((size_t)6))) && (payloadPtr < numDataBytes); payloadPtr++)
|
||||
{
|
||||
checksumA += *(dataBytes + payloadPtr);
|
||||
checksumB += checksumA;
|
||||
}
|
||||
// Check the checksum bytes
|
||||
dataIsOK &= (checksumA == *(dataBytes + dataPtr + packetLength + ((size_t)6)));
|
||||
dataIsOK &= (checksumB == *(dataBytes + dataPtr + packetLength + ((size_t)7)));
|
||||
|
||||
dataIsOK &= ((dataPtr + packetLength + ((size_t)8)) <= numDataBytes); // Check we haven't overrun
|
||||
|
||||
// If the data is valid, check for a date match
|
||||
if (dataIsOK)
|
||||
{
|
||||
if ((*(dataBytes + dataPtr + 3) == UBX_MGA_ANO)
|
||||
&& (*(dataBytes + dataPtr + 10) == matchYear)
|
||||
&& (*(dataBytes + dataPtr + 11) == matchMonth)
|
||||
&& (*(dataBytes + dataPtr + 12) == matchDay))
|
||||
{
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("findMGAANOForDate: found date match at location "));
|
||||
_debugSerial->println(dataPtr);
|
||||
}
|
||||
#endif
|
||||
dateFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The data is valid, but these are not the droids we are looking for...
|
||||
dataPtr += packetLength + ((size_t)8); // Point to the next message
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
|
||||
// The data was invalid. Send a debug message and then try to find the next 0xB5
|
||||
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||
{
|
||||
_debugSerial->print(F("findMGAANOForDate: bad data - ignored! dataPtr is "));
|
||||
_debugSerial->println(dataPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((dataPtr < numDataBytes) && (*(dataBytes + ++dataPtr) != UBX_SYNCH_1))
|
||||
{
|
||||
; // Increment dataPtr until we are pointing at the next 0xB5 - or we reach the end of the data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (dataPtr);
|
||||
}
|
||||
|
||||
// Support for data logging
|
||||
|
||||
@@ -295,6 +295,7 @@ const uint8_t UBX_LOG_STRING = 0x04; //Store arbitrary string on on-board fl
|
||||
//Class: MGA
|
||||
//The following are used to configure MGA UBX messages (Multiple GNSS Assistance Messages). Descriptions from UBX messages overview (ZED_F9P Interface Description Document page 34)
|
||||
const uint8_t UBX_MGA_ACK_DATA0 = 0x60; //Multiple GNSS Acknowledge message
|
||||
const uint8_t UBX_MGA_ANO = 0x20; //Multiple GNSS AssistNow Offline assistance - NOT SUPPORTED BY THE ZED-F9P! "The ZED-F9P supports AssistNow Online only."
|
||||
const uint8_t UBX_MGA_BDS_EPH = 0x03; //BDS Ephemeris Assistance
|
||||
const uint8_t UBX_MGA_BDS_ALM = 0x03; //BDS Almanac Assistance
|
||||
const uint8_t UBX_MGA_BDS_HEALTH = 0x03; //BDS Health Assistance
|
||||
@@ -710,11 +711,14 @@ public:
|
||||
// Return how many MGA packets were pushed successfully.
|
||||
// If skipTime is true, any UBX-MGA-INI-TIME_UTC or UBX-MGA-INI-TIME_GNSS packets found in the data will be skipped,
|
||||
// allowing the user to override with their own time data with setUTCTimeAssistance.
|
||||
// offset allows a sub-set of the data to be sent - starting from offset.
|
||||
#define defaultMGAdelay 7 // Default to waiting for 7ms between each MGA message
|
||||
size_t pushAssistNowData(const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(size_t offset, bool skipTime, const String &dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t pushAssistNowData(size_t offset, bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
|
||||
// Provide initial time assistance
|
||||
#define defaultMGAINITIMEtAccS 2 // Default to setting the seconds time accuracy to 2 seconds
|
||||
@@ -722,6 +726,13 @@ public:
|
||||
#define defaultMGAINITIMEsource 0 // Set default source to none, i.e. on receipt of message (will be inaccurate!)
|
||||
bool setUTCTimeAssistance(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, uint32_t nanos = 0, uint16_t tAccS = defaultMGAINITIMEtAccS, uint32_t tAccNs = defaultMGAINITIMEtAccNs, uint8_t source = defaultMGAINITIMEsource, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
|
||||
// Find the start of the AssistNow Offline (UBX_MGA_ANO) data for the chosen day
|
||||
// The daysIntoFture parameter makes it easy to get the data for (e.g.) tomorrow based on today's date
|
||||
// Returns numDataBytes if unsuccessful
|
||||
// TO DO: enhance this so it will find the nearest data for the chosen day - instead of an exact match
|
||||
size_t findMGAANOForDate(const String &dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture = 0);
|
||||
size_t findMGAANOForDate(const uint8_t *dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture = 0);
|
||||
|
||||
// Support for data logging
|
||||
void setFileBufferSize(uint16_t bufferSize); // Set the size of the file buffer. This must be called _before_ .begin.
|
||||
uint16_t getFileBufferSize(void); // Return the size of the file buffer
|
||||
@@ -1316,8 +1327,9 @@ private:
|
||||
|
||||
//Functions
|
||||
bool checkUbloxInternal(ubxPacket *incomingUBX, uint8_t requestedClass = 255, uint8_t requestedID = 255); //Checks module with user selected commType
|
||||
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
|
||||
size_t pushAssistNowDataInternal(bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
|
||||
size_t pushAssistNowDataInternal(size_t offset, bool skipTime, const uint8_t *dataBytes, size_t numDataBytes, sfe_ublox_mga_assist_ack_e mgaAck = SFE_UBLOX_MGA_ASSIST_ACK_NO, uint16_t maxWait = defaultMGAdelay);
|
||||
size_t findMGAANOForDateInternal(const uint8_t *dataBytes, size_t numDataBytes, uint16_t year, uint8_t month, uint8_t day, uint8_t daysIntoFuture = 0);
|
||||
|
||||
//Return true if this "automatic" message has storage allocated for it
|
||||
bool checkAutomatic(uint8_t Class, uint8_t ID);
|
||||
|
||||
Reference in New Issue
Block a user