@@ -553,8 +553,9 @@ void SFE_UBLOX_GPS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t re
553
553
// This is not an ACK and we do not have a complete class and ID match
554
554
// So let's check for an HPPOSLLH message arriving when we were expecting PVT and vice versa
555
555
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))))
558
559
{
559
560
// This is not the message we were expecting but we start diverting data into incomingUBX (usually packetCfg) and process it anyway
560
561
activePacketBuffer = SFE_UBLOX_PACKET_PACKETCFG;
@@ -563,7 +564,7 @@ void SFE_UBLOX_GPS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t re
563
564
incomingUBX->counter = packetBuf.counter ; // Copy over the .counter too
564
565
if (_printDebug == true )
565
566
{
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" ));
567
568
_debugSerial->print (requestedID, HEX);
568
569
_debugSerial->print (F (" Message ID: 0x" ));
569
570
_debugSerial->println (packetBuf.id , HEX);
@@ -825,14 +826,15 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX, uint8_t
825
826
// This is not an ACK and we do not have a complete class and ID match
826
827
// So let's check for an HPPOSLLH message arriving when we were expecting PVT and vice versa
827
828
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))))
830
832
{
831
833
// This isn't the message we are looking for...
832
834
// Let's say so and leave incomingUBX->classAndIDmatch _unchanged_
833
835
if (_printDebug == true )
834
836
{
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" ));
836
838
_debugSerial->print (requestedID, HEX);
837
839
_debugSerial->print (F (" Message ID: 0x" ));
838
840
_debugSerial->println (incomingUBX->id , HEX);
@@ -1080,6 +1082,24 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
1080
1082
}
1081
1083
*/
1082
1084
}
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
+ }
1083
1103
break ;
1084
1104
}
1085
1105
}
@@ -2403,6 +2423,49 @@ boolean SFE_UBLOX_GPS::setAutoHPPOSLLH(boolean enable, boolean implicitUpdate, u
2403
2423
return ok;
2404
2424
}
2405
2425
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
+
2406
2469
// Configure a given message type for a given port (UART1, I2C, SPI, etc)
2407
2470
boolean SFE_UBLOX_GPS::configureMessage (uint8_t msgClass, uint8_t msgID, uint8_t portID, uint8_t sendRate, uint16_t maxWait)
2408
2471
{
@@ -3054,6 +3117,15 @@ boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
3054
3117
return (true );
3055
3118
}
3056
3119
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
+
3057
3129
if (_printDebug == true )
3058
3130
{
3059
3131
_debugSerial->print (F (" getPVT retVal: " ));
@@ -3229,6 +3301,14 @@ boolean SFE_UBLOX_GPS::getHPPOSLLH(uint16_t maxWait)
3229
3301
}
3230
3302
return (true );
3231
3303
}
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
+ }
3232
3312
3233
3313
if (_printDebug == true )
3234
3314
{
@@ -3239,6 +3319,141 @@ boolean SFE_UBLOX_GPS::getHPPOSLLH(uint16_t maxWait)
3239
3319
}
3240
3320
}
3241
3321
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
+ }
3242
3457
// Get the current 3D high precision positional accuracy - a fun thing to watch
3243
3458
// Returns a long representing the 3D accuracy in millimeters
3244
3459
uint32_t SFE_UBLOX_GPS::getPositionAccuracy (uint16_t maxWait)
@@ -3496,6 +3711,20 @@ void SFE_UBLOX_GPS::flushHPPOSLLH()
3496
3711
// moduleQueried.gpsiTOW = false; // this can arrive via HPPOS too.
3497
3712
}
3498
3713
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
+
3499
3728
// Relative Positioning Information in NED frame
3500
3729
// Returns true if commands was successful
3501
3730
boolean SFE_UBLOX_GPS::getRELPOSNED (uint16_t maxWait)
@@ -3800,4 +4029,4 @@ bool SFE_UBLOX_GPS::setStaticPosition(int32_t ecefXOrLat, int8_t ecefXOrLatHP, i
3800
4029
bool SFE_UBLOX_GPS::setStaticPosition (int32_t ecefXOrLat, int32_t ecefYOrLon, int32_t ecefZOrAlt, bool latlong, uint16_t maxWait)
3801
4030
{
3802
4031
return (setStaticPosition (ecefXOrLat, 0 , ecefYOrLon, 0 , ecefZOrAlt, 0 , latlong, maxWait));
3803
- }
4032
+ }
0 commit comments