Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit dca757f

Browse files
authored
Merge pull request #141 from dotMorten/dotMorten/AutoDOP
Adds support for auto-reporting DOP values
2 parents 5edcbf6 + fc33d0b commit dca757f

File tree

2 files changed

+277
-12
lines changed

2 files changed

+277
-12
lines changed

src/SparkFun_Ublox_Arduino_Library.cpp

+236-7
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,9 @@ void SFE_UBLOX_GPS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t re
553553
//This is not an ACK and we do not have a complete class and ID match
554554
//So let's check for an HPPOSLLH message arriving when we were expecting PVT and vice versa
555555
else if ((packetBuf.cls == requestedClass) &&
556-
(((packetBuf.id == UBX_NAV_PVT) && (requestedID == UBX_NAV_HPPOSLLH)) ||
557-
((packetBuf.id == UBX_NAV_HPPOSLLH) && (requestedID == UBX_NAV_PVT))))
556+
(((packetBuf.id == UBX_NAV_PVT) && (requestedID == UBX_NAV_HPPOSLLH || requestedID == UBX_NAV_DOP)) ||
557+
((packetBuf.id == UBX_NAV_HPPOSLLH) && (requestedID == UBX_NAV_PVT || requestedID == UBX_NAV_DOP)) ||
558+
((packetBuf.id == UBX_NAV_DOP) && (requestedID == UBX_NAV_PVT || requestedID == UBX_NAV_HPPOSLLH))))
558559
{
559560
//This is not the message we were expecting but we start diverting data into incomingUBX (usually packetCfg) and process it anyway
560561
activePacketBuffer = SFE_UBLOX_PACKET_PACKETCFG;
@@ -563,7 +564,7 @@ void SFE_UBLOX_GPS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t re
563564
incomingUBX->counter = packetBuf.counter; //Copy over the .counter too
564565
if (_printDebug == true)
565566
{
566-
_debugSerial->print(F("process: auto PVT/HPPOSLLH collision: Requested ID: 0x"));
567+
_debugSerial->print(F("process: auto PVT/HPPOSLLH/DOP collision: Requested ID: 0x"));
567568
_debugSerial->print(requestedID, HEX);
568569
_debugSerial->print(F(" Message ID: 0x"));
569570
_debugSerial->println(packetBuf.id, HEX);
@@ -825,14 +826,15 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t
825826
//This is not an ACK and we do not have a complete class and ID match
826827
//So let's check for an HPPOSLLH message arriving when we were expecting PVT and vice versa
827828
else if ((incomingUBX->cls == requestedClass) &&
828-
(((incomingUBX->id == UBX_NAV_PVT) && (requestedID == UBX_NAV_HPPOSLLH)) ||
829-
((incomingUBX->id == UBX_NAV_HPPOSLLH) && (requestedID == UBX_NAV_PVT))))
829+
(((incomingUBX->id == UBX_NAV_PVT) && (requestedID == UBX_NAV_HPPOSLLH || requestedID == UBX_NAV_DOP)) ||
830+
((incomingUBX->id == UBX_NAV_HPPOSLLH) && (requestedID == UBX_NAV_PVT || requestedID == UBX_NAV_DOP)) ||
831+
((incomingUBX->id == UBX_NAV_DOP) && (requestedID == UBX_NAV_PVT || requestedID == UBX_NAV_HPPOSLLH))))
830832
{
831833
// This isn't the message we are looking for...
832834
// Let's say so and leave incomingUBX->classAndIDmatch _unchanged_
833835
if (_printDebug == true)
834836
{
835-
_debugSerial->print(F("processUBX: auto PVT/HPPOSLLH collision: Requested ID: 0x"));
837+
_debugSerial->print(F("processUBX: auto PVT/HPPOSLLH/DOP collision: Requested ID: 0x"));
836838
_debugSerial->print(requestedID, HEX);
837839
_debugSerial->print(F(" Message ID: 0x"));
838840
_debugSerial->println(incomingUBX->id, HEX);
@@ -1080,6 +1082,24 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
10801082
}
10811083
*/
10821084
}
1085+
else if (msg->id == UBX_NAV_DOP && msg->len == 18)
1086+
{
1087+
geometricDOP = extractInt(4);
1088+
positionDOP = extractInt(6);
1089+
timeDOP = extractInt(8);
1090+
verticalDOP = extractInt(10);
1091+
horizontalDOP = extractInt(12);
1092+
northingDOP = extractInt(14);
1093+
eastingDOP = extractInt(16);
1094+
dopModuleQueried.all = true;
1095+
dopModuleQueried.geometricDOP = true;
1096+
dopModuleQueried.positionDOP = true;
1097+
dopModuleQueried.timeDOP = true;
1098+
dopModuleQueried.verticalDOP = true;
1099+
dopModuleQueried.horizontalDOP = true;
1100+
dopModuleQueried.northingDOP = true;
1101+
dopModuleQueried.eastingDOP = true;
1102+
}
10831103
break;
10841104
}
10851105
}
@@ -2403,6 +2423,49 @@ boolean SFE_UBLOX_GPS::setAutoHPPOSLLH(boolean enable, boolean implicitUpdate, u
24032423
return ok;
24042424
}
24052425

2426+
2427+
//In case no config access to the GPS is possible and DOP is send cyclically already
2428+
//set config to suitable parameters
2429+
boolean SFE_UBLOX_GPS::assumeAutoDOP(boolean enabled, boolean implicitUpdate)
2430+
{
2431+
boolean changes = autoDOP != enabled || autoDOPImplicitUpdate != implicitUpdate;
2432+
if (changes)
2433+
{
2434+
autoDOP = enabled;
2435+
autoDOPImplicitUpdate = implicitUpdate;
2436+
}
2437+
return changes;
2438+
}
2439+
2440+
//Enable or disable automatic navigation message generation by the GPS. This changes the way getDOP
2441+
//works.
2442+
boolean SFE_UBLOX_GPS::setAutoDOP(boolean enable, uint16_t maxWait)
2443+
{
2444+
return setAutoDOP(enable, true, maxWait);
2445+
}
2446+
2447+
//Enable or disable automatic navigation message generation by the GPS. This changes the way getDOP
2448+
//works.
2449+
boolean SFE_UBLOX_GPS::setAutoDOP(boolean enable, boolean implicitUpdate, uint16_t maxWait)
2450+
{
2451+
packetCfg.cls = UBX_CLASS_CFG;
2452+
packetCfg.id = UBX_CFG_MSG;
2453+
packetCfg.len = 3;
2454+
packetCfg.startingSpot = 0;
2455+
payloadCfg[0] = UBX_CLASS_NAV;
2456+
payloadCfg[1] = UBX_NAV_DOP;
2457+
payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq.
2458+
2459+
boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
2460+
if (ok)
2461+
{
2462+
autoDOP = enable;
2463+
autoDOPImplicitUpdate = implicitUpdate;
2464+
}
2465+
dopModuleQueried.all = false;
2466+
return ok;
2467+
}
2468+
24062469
//Configure a given message type for a given port (UART1, I2C, SPI, etc)
24072470
boolean SFE_UBLOX_GPS::configureMessage(uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate, uint16_t maxWait)
24082471
{
@@ -3054,6 +3117,15 @@ boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
30543117
return (true);
30553118
}
30563119

3120+
if ((retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) && (packetCfg.id == UBX_NAV_DOP))
3121+
{
3122+
if (_printDebug == true)
3123+
{
3124+
_debugSerial->println(F("getPVT: data was OVERWRITTEN by DOP (but that's OK)"));
3125+
}
3126+
return (true);
3127+
}
3128+
30573129
if (_printDebug == true)
30583130
{
30593131
_debugSerial->print(F("getPVT retVal: "));
@@ -3229,6 +3301,14 @@ boolean SFE_UBLOX_GPS::getHPPOSLLH(uint16_t maxWait)
32293301
}
32303302
return (true);
32313303
}
3304+
if ((retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) && (packetCfg.id == UBX_NAV_DOP))
3305+
{
3306+
if (_printDebug == true)
3307+
{
3308+
_debugSerial->println(F("getHPPOSLLH: data was OVERWRITTEN by DOP (but that's OK)"));
3309+
}
3310+
return (true);
3311+
}
32323312

32333313
if (_printDebug == true)
32343314
{
@@ -3239,6 +3319,141 @@ boolean SFE_UBLOX_GPS::getHPPOSLLH(uint16_t maxWait)
32393319
}
32403320
}
32413321

3322+
uint16_t SFE_UBLOX_GPS::getGeometricDOP(uint16_t maxWait /* = 250*/)
3323+
{
3324+
if (dopModuleQueried.geometricDOP == false)
3325+
getDOP(maxWait);
3326+
dopModuleQueried.geometricDOP = false; //Since we are about to give this to user, mark this data as stale
3327+
dopModuleQueried.all = false;
3328+
3329+
return (geometricDOP);
3330+
}
3331+
3332+
uint16_t SFE_UBLOX_GPS::getPositionDOP(uint16_t maxWait /* = 250*/)
3333+
{
3334+
if (dopModuleQueried.positionDOP == false)
3335+
getDOP(maxWait);
3336+
dopModuleQueried.positionDOP = false; //Since we are about to give this to user, mark this data as stale
3337+
dopModuleQueried.all = false;
3338+
3339+
return (positionDOP);
3340+
}
3341+
3342+
uint16_t SFE_UBLOX_GPS::getTimeDOP(uint16_t maxWait /* = 250*/)
3343+
{
3344+
if (dopModuleQueried.timeDOP == false)
3345+
getDOP(maxWait);
3346+
dopModuleQueried.timeDOP = false; //Since we are about to give this to user, mark this data as stale
3347+
dopModuleQueried.all = false;
3348+
3349+
return (timeDOP);
3350+
}
3351+
3352+
uint16_t SFE_UBLOX_GPS::getVerticalDOP(uint16_t maxWait /* = 250*/)
3353+
{
3354+
if (dopModuleQueried.verticalDOP == false)
3355+
getDOP(maxWait);
3356+
dopModuleQueried.verticalDOP = false; //Since we are about to give this to user, mark this data as stale
3357+
dopModuleQueried.all = false;
3358+
3359+
return (verticalDOP);
3360+
}
3361+
3362+
uint16_t SFE_UBLOX_GPS::getHorizontalDOP(uint16_t maxWait /* = 250*/)
3363+
{
3364+
if (dopModuleQueried.horizontalDOP == false)
3365+
getDOP(maxWait);
3366+
dopModuleQueried.horizontalDOP = false; //Since we are about to give this to user, mark this data as stale
3367+
dopModuleQueried.all = false;
3368+
3369+
return (horizontalDOP);
3370+
}
3371+
3372+
uint16_t SFE_UBLOX_GPS::getNorthingDOP(uint16_t maxWait /* = 250*/)
3373+
{
3374+
if (dopModuleQueried.northingDOP == false)
3375+
getDOP(maxWait);
3376+
dopModuleQueried.northingDOP = false; //Since we are about to give this to user, mark this data as stale
3377+
dopModuleQueried.all = false;
3378+
3379+
return (northingDOP);
3380+
}
3381+
3382+
uint16_t SFE_UBLOX_GPS::getEastingDOP(uint16_t maxWait /* = 250*/)
3383+
{
3384+
if (dopModuleQueried.eastingDOP == false)
3385+
getDOP(maxWait);
3386+
dopModuleQueried.eastingDOP = false; //Since we are about to give this to user, mark this data as stale
3387+
dopModuleQueried.all = false;
3388+
3389+
return (eastingDOP);
3390+
}
3391+
3392+
boolean SFE_UBLOX_GPS::getDOP(uint16_t maxWait)
3393+
{
3394+
if (autoDOP && autoDOPImplicitUpdate)
3395+
{
3396+
//The GPS is automatically reporting, we just check whether we got unread data
3397+
if (_printDebug == true)
3398+
{
3399+
_debugSerial->println(F("getDOP: Autoreporting"));
3400+
}
3401+
checkUbloxInternal(&packetCfg, UBX_CLASS_NAV, UBX_NAV_DOP);
3402+
return dopModuleQueried.all;
3403+
}
3404+
else if (autoDOP && !autoDOPImplicitUpdate)
3405+
{
3406+
//Someone else has to call checkUblox for us...
3407+
if (_printDebug == true)
3408+
{
3409+
_debugSerial->println(F("getDOP: Exit immediately"));
3410+
}
3411+
return (false);
3412+
}
3413+
else
3414+
{
3415+
if (_printDebug == true)
3416+
{
3417+
_debugSerial->println(F("getDOP: Polling"));
3418+
}
3419+
3420+
//The GPS is not automatically reporting navigation position so we have to poll explicitly
3421+
packetCfg.cls = UBX_CLASS_NAV;
3422+
packetCfg.id = UBX_NAV_DOP;
3423+
packetCfg.len = 0;
3424+
3425+
//The data is parsed as part of processing the response
3426+
sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
3427+
3428+
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
3429+
return (true);
3430+
3431+
if ((retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) && (packetCfg.id == UBX_NAV_PVT))
3432+
{
3433+
if (_printDebug == true)
3434+
{
3435+
_debugSerial->println(F("getHPPOSLLH: data was OVERWRITTEN by PVT (but that's OK)"));
3436+
}
3437+
return (true);
3438+
}
3439+
3440+
if ((retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN) && (packetCfg.id == UBX_NAV_HPPOSLLH))
3441+
{
3442+
if (_printDebug == true)
3443+
{
3444+
_debugSerial->println(F("getPVT: data was OVERWRITTEN by HPPOSLLH (but that's OK)"));
3445+
}
3446+
return (true);
3447+
}
3448+
3449+
if (_printDebug == true)
3450+
{
3451+
_debugSerial->print(F("getDOP retVal: "));
3452+
_debugSerial->println(statusString(retVal));
3453+
}
3454+
return (false);
3455+
}
3456+
}
32423457
//Get the current 3D high precision positional accuracy - a fun thing to watch
32433458
//Returns a long representing the 3D accuracy in millimeters
32443459
uint32_t SFE_UBLOX_GPS::getPositionAccuracy(uint16_t maxWait)
@@ -3496,6 +3711,20 @@ void SFE_UBLOX_GPS::flushHPPOSLLH()
34963711
//moduleQueried.gpsiTOW = false; // this can arrive via HPPOS too.
34973712
}
34983713

3714+
//Mark all the DOP data as read/stale. This is handy to get data alignment after CRC failure
3715+
void SFE_UBLOX_GPS::flushDOP()
3716+
{
3717+
//Mark all DOPs as stale (read before)
3718+
dopModuleQueried.all = false;
3719+
dopModuleQueried.geometricDOP = false;
3720+
dopModuleQueried.positionDOP = false;
3721+
dopModuleQueried.timeDOP = false;
3722+
dopModuleQueried.verticalDOP = false;
3723+
dopModuleQueried.horizontalDOP = false;
3724+
dopModuleQueried.northingDOP = false;
3725+
dopModuleQueried.eastingDOP = false;
3726+
}
3727+
34993728
//Relative Positioning Information in NED frame
35003729
//Returns true if commands was successful
35013730
boolean SFE_UBLOX_GPS::getRELPOSNED(uint16_t maxWait)
@@ -3800,4 +4029,4 @@ bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefXOrLat, int8_t ecefXOrLatHP, i
38004029
bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefXOrLat, int32_t ecefYOrLon, int32_t ecefZOrAlt, bool latlong, uint16_t maxWait)
38014030
{
38024031
return (setStaticPosition(ecefXOrLat, 0, ecefYOrLon, 0, ecefZOrAlt, 0, latlong, maxWait));
3803-
}
4032+
}

0 commit comments

Comments
 (0)