Skip to content

Commit 3cee5ff

Browse files
committed
Merge branch 'release_candidate' into pcUpdates
2 parents 00da22c + 76a6d58 commit 3cee5ff

File tree

9 files changed

+1023
-770
lines changed

9 files changed

+1023
-770
lines changed

.github/workflows/compile-rtk-everywhere.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ jobs:
159159
mv RTK_Everywhere.ino.bin ${{ env.FILENAME_PREFIX }}${{ env.FILE_ENDING_UNDERSCORE }}.bin
160160
161161
- name: Upload binary to action
162-
uses: actions/upload-artifact@v3
162+
uses: actions/upload-artifact@v4
163163
with:
164164
name: ${{ env.FILENAME_PREFIX }}${{ env.FILE_ENDING_UNDERSCORE }}
165165
path: ./Firmware/RTK_Everywhere/build/esp32.esp32.esp32/${{ env.FILENAME_PREFIX }}${{ env.FILE_ENDING_UNDERSCORE }}.bin

Firmware/RTK_Everywhere/Developer.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ void pointperfectPrintKeyInformation(const char *requestedBy) {systemPrintln("**
277277
#ifndef COMPILE_LG290P
278278

279279
void lg290pHandler(uint8_t * buffer, int length) {}
280+
void lg290pModifyGst(char *nmeaSentence, uint16_t *sentenceLength) {}
280281

281282
#endif // COMPILE_LG290P
282283

Firmware/RTK_Everywhere/GNSS_LG290P.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,14 @@ const lg290pMsg lgMessagesRTCM[] = {
5151
{"RTCM3-107X", 1, 0}, {"RTCM3-108X", 1, 0}, {"RTCM3-109X", 1, 0}, {"RTCM3-111X", 1, 0}, {"RTCM3-112X", 1, 0}, {"RTCM3-113X", 1, 0},
5252
};
5353

54+
// Quectel Proprietary messages
55+
const lg290pMsg lgMessagesPQTM[] = {
56+
{"EPE", 0, 0}, {"PVT", 0, 0},
57+
};
58+
5459
#define MAX_LG290P_NMEA_MSG (sizeof(lgMessagesNMEA) / sizeof(lg290pMsg))
5560
#define MAX_LG290P_RTCM_MSG (sizeof(lgMessagesRTCM) / sizeof(lg290pMsg))
61+
#define MAX_LG290P_PQTM_MSG (sizeof(lgMessagesPQTM) / sizeof(lg290pMsg))
5662

5763
enum lg290p_Models
5864
{

Firmware/RTK_Everywhere/GNSS_LG290P.ino

Lines changed: 223 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,6 @@ uint8_t GNSS_LG290P::getFixType()
10801080
//----------------------------------------
10811081
float GNSS_LG290P::getHorizontalAccuracy()
10821082
{
1083-
// Coming soon from EPE
10841083
if (online.gnss)
10851084
return (_lg290p->get2DError());
10861085
return 0;
@@ -1574,6 +1573,7 @@ void GNSS_LG290P::menuMessages()
15741573
systemPrintln("1) Set NMEA Messages");
15751574
systemPrintln("2) Set Rover RTCM Messages");
15761575
systemPrintln("3) Set Base RTCM Messages");
1576+
systemPrintln("4) Set PQTM Messages");
15771577

15781578
systemPrintln("10) Reset to Defaults");
15791579

@@ -1587,6 +1587,8 @@ void GNSS_LG290P::menuMessages()
15871587
menuMessagesSubtype(settings.lg290pMessageRatesRTCMRover, "RTCMRover");
15881588
else if (incoming == 3)
15891589
menuMessagesSubtype(settings.lg290pMessageRatesRTCMBase, "RTCMBase");
1590+
else if (incoming == 4)
1591+
menuMessagesSubtype(settings.lg290pMessageRatesPQTM, "PQTM");
15901592
else if (incoming == 10)
15911593
{
15921594
// Reset rates to defaults
@@ -1601,6 +1603,10 @@ void GNSS_LG290P::menuMessages()
16011603
for (int x = 0; x < MAX_LG290P_RTCM_MSG; x++)
16021604
settings.lg290pMessageRatesRTCMBase[x] = lgMessagesRTCM[x].msgDefaultRate;
16031605

1606+
// Reset PQTM rates to defaults
1607+
for (int x = 0; x < MAX_LG290P_PQTM_MSG; x++)
1608+
settings.lg290pMessageRatesPQTM[x] = lgMessagesPQTM[x].msgDefaultRate;
1609+
16041610
systemPrintln("Reset to Defaults");
16051611
}
16061612

@@ -1638,7 +1644,7 @@ void GNSS_LG290P::menuMessagesSubtype(int *localMessageRate, const char *message
16381644
{
16391645
endOfBlock = MAX_LG290P_NMEA_MSG;
16401646

1641-
for (int x = 0; x < MAX_LG290P_NMEA_MSG; x++)
1647+
for (int x = 0; x < endOfBlock; x++)
16421648
{
16431649
if (lg290pFirmwareVersion <= lgMessagesNMEA[x].firmwareVersionSupported)
16441650
systemPrintf("%d) Message %s: %d - Requires firmware update\r\n", x + 1,
@@ -1652,7 +1658,7 @@ void GNSS_LG290P::menuMessagesSubtype(int *localMessageRate, const char *message
16521658
{
16531659
endOfBlock = MAX_LG290P_RTCM_MSG;
16541660

1655-
for (int x = 0; x < MAX_LG290P_RTCM_MSG; x++)
1661+
for (int x = 0; x < endOfBlock; x++)
16561662
{
16571663
if (lg290pFirmwareVersion <= lgMessagesRTCM[x].firmwareVersionSupported)
16581664
systemPrintf("%d) Message %s: %d - Requires firmware update\r\n", x + 1,
@@ -1666,16 +1672,30 @@ void GNSS_LG290P::menuMessagesSubtype(int *localMessageRate, const char *message
16661672
{
16671673
endOfBlock = MAX_LG290P_RTCM_MSG;
16681674

1669-
for (int x = 0; x < MAX_LG290P_RTCM_MSG; x++)
1675+
for (int x = 0; x < endOfBlock; x++)
16701676
{
16711677
if (lg290pFirmwareVersion <= lgMessagesRTCM[x].firmwareVersionSupported)
1672-
systemPrintf("%d) Message %s: %d - Requires firmware update\r\n", x + 1, lgMessagesRTCM[x].msgTextName,
1673-
settings.lg290pMessageRatesRTCMBase[x]);
1678+
systemPrintf("%d) Message %s: %d - Requires firmware update\r\n", x + 1,
1679+
lgMessagesRTCM[x].msgTextName, settings.lg290pMessageRatesRTCMBase[x]);
16741680
else
16751681
systemPrintf("%d) Message %s: %d\r\n", x + 1, lgMessagesRTCM[x].msgTextName,
16761682
settings.lg290pMessageRatesRTCMBase[x]);
16771683
}
16781684
}
1685+
else if (strcmp(messageType, "PQTM") == 0)
1686+
{
1687+
endOfBlock = MAX_LG290P_PQTM_MSG;
1688+
1689+
for (int x = 0; x < endOfBlock; x++)
1690+
{
1691+
if (lg290pFirmwareVersion <= lgMessagesPQTM[x].firmwareVersionSupported)
1692+
systemPrintf("%d) Message %s: %d - Requires firmware update\r\n", x + 1,
1693+
lgMessagesPQTM[x].msgTextName, settings.lg290pMessageRatesPQTM[x]);
1694+
else
1695+
systemPrintf("%d) Message %s: %d\r\n", x + 1, lgMessagesPQTM[x].msgTextName,
1696+
settings.lg290pMessageRatesPQTM[x]);
1697+
}
1698+
}
16791699

16801700
systemPrintln("x) Exit");
16811701

@@ -1698,6 +1718,11 @@ void GNSS_LG290P::menuMessagesSubtype(int *localMessageRate, const char *message
16981718
sprintf(messageString, "Enter number of fixes required before %s is reported (0 to disable)",
16991719
lgMessagesRTCM[incoming].msgTextName);
17001720
}
1721+
else if (strcmp(messageType, "PQTM") == 0)
1722+
{
1723+
sprintf(messageString, "Enter number of fixes required before %s is reported (0 to disable)",
1724+
lgMessagesPQTM[incoming].msgTextName);
1725+
}
17011726

17021727
int newSetting = 0;
17031728

@@ -1718,6 +1743,11 @@ void GNSS_LG290P::menuMessagesSubtype(int *localMessageRate, const char *message
17181743
if (getNewSetting(messageString, 0, 1200, &newSetting) == INPUT_RESPONSE_VALID)
17191744
settings.lg290pMessageRatesRTCMBase[incoming] = newSetting;
17201745
}
1746+
if (strcmp(messageType, "PQTM") == 0)
1747+
{
1748+
if (getNewSetting(messageString, 0, 1, &newSetting) == INPUT_RESPONSE_VALID)
1749+
settings.lg290pMessageRatesPQTM[incoming] = newSetting;
1750+
}
17211751
}
17221752
else if (incoming == INPUT_RESPONSE_GETNUMBER_EXIT)
17231753
break;
@@ -2134,3 +2164,190 @@ void lg290pReset()
21342164
{
21352165
digitalWrite(pin_GNSS_Reset, LOW);
21362166
}
2167+
2168+
// Given a NMEA or PQTM sentence, determine if it is enabled in settings
2169+
// This is used to signal to the processUart1Message() task to remove messages that are needed
2170+
// by the library to function (ie, PQTMEPE, PQTMPVT, GNGSV) but should not be logged or passed to other consumers
2171+
// If unknown, allow messages through. Filtering and suppression should be selectively added in.
2172+
bool lg290pMessageEnabled(char *nmeaSentence, int sentenceLength)
2173+
{
2174+
// Identify message type: PQTM or NMEA
2175+
char messageType[strlen("PQTM") + 1] = {0};
2176+
strncpy(messageType, &nmeaSentence[1],
2177+
4); // Copy four letters, starting in spot 1. Null terminated from array initializer.
2178+
2179+
if (strncmp(messageType, "PQTM", sizeof(messageType)) == 0)
2180+
{
2181+
// Identify sentence type
2182+
char sentenceType[strlen("EPE") + 1] = {0};
2183+
strncpy(sentenceType, &nmeaSentence[5],
2184+
3); // Copy three letters, starting in spot 5. Null terminated from array initializer.
2185+
2186+
// Find this sentence type in the settings array
2187+
for (int messageNumber = 0; messageNumber < MAX_LG290P_PQTM_MSG; messageNumber++)
2188+
{
2189+
if (strncmp(lgMessagesPQTM[messageNumber].msgTextName, sentenceType, sizeof(sentenceType)) == 0)
2190+
{
2191+
if (settings.lg290pMessageRatesPQTM[messageNumber] > 0)
2192+
return (true);
2193+
return (false);
2194+
}
2195+
}
2196+
}
2197+
2198+
else // We have to assume $G????
2199+
{
2200+
// Identify sentence type
2201+
char sentenceType[strlen("GSV") + 1] = {0};
2202+
strncpy(sentenceType, &nmeaSentence[3],
2203+
3); // Copy three letters, starting in spot 3. Null terminated from array initializer.
2204+
2205+
// Find this sentence type in the settings array
2206+
for (int messageNumber = 0; messageNumber < MAX_LG290P_NMEA_MSG; messageNumber++)
2207+
{
2208+
if (strncmp(lgMessagesNMEA[messageNumber].msgTextName, sentenceType, sizeof(sentenceType)) == 0)
2209+
{
2210+
if (settings.lg290pMessageRatesNMEA[messageNumber] > 0)
2211+
return (true);
2212+
return (false);
2213+
}
2214+
}
2215+
}
2216+
2217+
// If we can't ID this message, allow it by default. The device configuration should control most message flow.
2218+
return (true);
2219+
}
2220+
2221+
// Re-create the GST sentence to increase the horizontal and vertical precision number of decimals
2222+
// ie, 0.0 becomes 0.009
2223+
// See issue: https://github.com/sparkfun/SparkFun_RTK_Everywhere_Firmware/issues/513
2224+
// $GNGST,223954.500,1.7,1.5,1.0,109.3,1.412,1.055,2.4*7E
2225+
// Modifies the sentence length with new length
2226+
void lg290pModifyGst(char *nmeaSentence, uint16_t *sentenceLength)
2227+
{
2228+
// This issue currently only applies to LG290P firmware version 4
2229+
// Version 3 does not support GST messages. Version 5 should fix the issue.
2230+
if (lg290pFirmwareVersion != 4)
2231+
return;
2232+
2233+
if (online.gnss == false)
2234+
return;
2235+
2236+
// Only apply the GST patch if our HPA is very small (<0.1m), ie RTK Float or Fix.
2237+
if (gnss->isRTKFix() == false && gnss->isRTKFloat() == false)
2238+
return;
2239+
2240+
GNSS_LG290P *lg290p = (GNSS_LG290P *)gnss;
2241+
2242+
// Identify sentence type
2243+
char sentenceType[strlen("GST") + 1] = {0};
2244+
strncpy(sentenceType, &nmeaSentence[3],
2245+
3); // Copy three letters, starting in spot 3. Null terminated from array initializer.
2246+
2247+
// We only care about GST sentences
2248+
if (strncmp(sentenceType, "GST", sizeof(sentenceType)) != 0)
2249+
return;
2250+
2251+
const int latitudeErrorComma = 6;
2252+
const int longitudeErrorComma = 7;
2253+
const int altitudeErrorComma = 8;
2254+
2255+
uint8_t latitudeStart = 0;
2256+
uint8_t latitudeStop = 0;
2257+
uint8_t longitudeStart = 0;
2258+
uint8_t longitudeStop = 0;
2259+
uint8_t altitudeStart = 0;
2260+
uint8_t checksumStart = 0;
2261+
2262+
if (settings.enableImuCompensationDebug == true && !inMainMenu)
2263+
systemPrintf("Original GNGST:\r\n%s\r\n", nmeaSentence);
2264+
2265+
int commaCount = 0;
2266+
for (int x = 0; x < strnlen(nmeaSentence, *sentenceLength); x++) // Assumes sentence is null terminated
2267+
{
2268+
if (nmeaSentence[x] == ',')
2269+
{
2270+
commaCount++;
2271+
if (commaCount == latitudeErrorComma)
2272+
latitudeStart = x + 1;
2273+
if (commaCount == latitudeErrorComma + 1)
2274+
latitudeStop = x;
2275+
if (commaCount == longitudeErrorComma)
2276+
longitudeStart = x + 1;
2277+
if (commaCount == longitudeErrorComma + 1)
2278+
longitudeStop = x;
2279+
if (commaCount == altitudeErrorComma)
2280+
altitudeStart = x + 1;
2281+
}
2282+
if (nmeaSentence[x] == '*')
2283+
{
2284+
checksumStart = x;
2285+
break;
2286+
}
2287+
}
2288+
2289+
if (latitudeStart == 0 || latitudeStop == 0 || longitudeStart == 0 || longitudeStop == 0 || altitudeStart == 0 ||
2290+
checksumStart == 0)
2291+
{
2292+
systemPrintln("Delineator not found");
2293+
return;
2294+
}
2295+
2296+
char newSentence[150] = {0};
2297+
2298+
if (sizeof(newSentence) < *sentenceLength)
2299+
{
2300+
systemPrintln("newSentence not big enough!");
2301+
return;
2302+
}
2303+
2304+
char errorString[strlen("0.000") + 1] = {0};
2305+
2306+
// strncat terminates
2307+
2308+
// Add start of message up to latitude
2309+
strncat(newSentence, nmeaSentence, latitudeStart);
2310+
2311+
// Convert error from EPE message to string. We don't have pure lat error, only 2D and 3D.
2312+
snprintf(errorString, sizeof(errorString), "%0.3f", lg290p->getHorizontalAccuracy());
2313+
2314+
// Add latitude error
2315+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2316+
2317+
// Add interstitial between end of lat and beginning of lon
2318+
strncat(newSentence, nmeaSentence + latitudeStop, longitudeStart - latitudeStop);
2319+
2320+
// Add same error for longitude error
2321+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2322+
2323+
// Add interstitial between end of lon and beginning of alt
2324+
strncat(newSentence, nmeaSentence + longitudeStop, altitudeStart - longitudeStop);
2325+
2326+
// Convert error from EPE message to string. We don't have pure altitude error, use double 2D error as stand-in.
2327+
snprintf(errorString, sizeof(errorString), "%0.3f", lg290p->getHorizontalAccuracy() * 2);
2328+
2329+
// Add altitude error. We don't really have altitude so use 3D error in its place.
2330+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2331+
2332+
// From: http://engineeringnotes.blogspot.com/2015/02/generate-crc-for-nmea-strings-arduino.html
2333+
byte CRC = 0; // XOR chars between '$' and '*'
2334+
for (byte x = 1; x < strlen(newSentence); x++)
2335+
CRC = CRC ^ newSentence[x];
2336+
2337+
// Convert CRC to string, add * and CR LF
2338+
snprintf(errorString, sizeof(errorString), "*%02X\r\n", CRC);
2339+
2340+
// Add CRC
2341+
strncat(newSentence, errorString, sizeof(newSentence) - 1);
2342+
2343+
// Increase length of sentence
2344+
*sentenceLength = strlen(newSentence);
2345+
2346+
// Overwrite the original NMEA
2347+
strncpy(nmeaSentence, newSentence, *sentenceLength);
2348+
2349+
nmeaSentence[*sentenceLength] = '\0'; // Terminate string
2350+
2351+
if (settings.enableImuCompensationDebug == true && !inMainMenu)
2352+
systemPrintf("Corrected GNGST:\r\n%s\r\n", nmeaSentence);
2353+
}

Firmware/RTK_Everywhere/GNSS_None.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ class GNSS_None : public GNSS
429429
{
430430
}
431431

432+
void modifyGst(char *nmeaSentence, uint16_t *sentenceLength)
433+
{
434+
}
435+
432436
// Print the module type and firmware version
433437
void printModuleInfo()
434438
{

Firmware/RTK_Everywhere/Tasks.ino

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,19 @@ void processUart1Message(SEMP_PARSE_STATE *parse, uint16_t type)
641641
{
642642
// Give this data to the library to update its internal variables
643643
lg290pHandler(parse->buffer, parse->length);
644+
645+
if (type == RTK_NMEA_PARSER_INDEX)
646+
{
647+
// Suppress PQTM/NMEA messages as needed
648+
if (lg290pMessageEnabled((char *)parse->buffer, parse->length) == false)
649+
{
650+
parse->buffer[0] = 0;
651+
parse->length = 0;
652+
}
653+
654+
// Gimme three decimals!
655+
lg290pModifyGst((char *)parse->buffer, &parse->length);
656+
}
644657
}
645658

646659
// Handle LLA compensation due to tilt or outputTipAltitude setting

0 commit comments

Comments
 (0)