@@ -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)
24072470boolean 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
32443459uint32_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
35013730boolean SFE_UBLOX_GPS::getRELPOSNED (uint16_t maxWait)
@@ -3800,4 +4029,4 @@ bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefXOrLat, int8_t ecefXOrLatHP, i
38004029bool 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