⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gps.c

📁 Open DMT Client C Source code
💻 C
📖 第 1 页 / 共 4 页
字号:
            //      6    A=valid, V=invalid            // $GPGSA - GPS DOP and Active Satellites            //   $GPGSA|A|1|||||||||||||50.0|50.0|50.0*05|            //   $GPGSA|A|3|16|20|13|23|||||||||4.3|2.3|3.7*36|            //   $GPGSA,1,2, 3, 4, 5, 6,  ...    15, 16, 17            //      1    A =Auto2D/3D, M=Forced2D/3D            //      2    1=NoFix, 2=2D, 3=3D            //      3    Satellites used #1            //    ...            //     14    Satellites used #12            //     15    PDOP            //     16    HDOP            //     17    VDOP            // $GPGSV - GPS Satellites in View            //   $GPGSV|3|1|9|16|35|51|32|4|9|269|0|20|32|177|33|13|62|329|37*4E|            //   $GPGSV|3|2|9|3|14|113|0|24|5|230|0|8|12|251|0|23|71|71|39*70|            //   $GPGSV|3|3|9|131|0|0|0*43|            // $GPRMC - Recommended Minimum Specific GPS/TRANSIT Data            //   $GPRMC|015402.240|V|36000.0000|N|72000.0000|E|0.000000||200505||*3C|            //   $GPRMC,025423.494,A,3709.0642,N,11907.8315,W,0.094824,108.52,200505,,*12            //   $GPRMC,      1   ,2,    3    ,4,     5    ,6, 7      ,   8  ,  9   ,A,B*M            //      1   UTC time of position HHMMSS            //      2   validity of the fix ("A" = valid, "V" = invalid)            //      3   current latitude in ddmm.mm format            //      4   latitude hemisphere ("N" = northern, "S" = southern)            //      5   current longitude in dddmm.mm format            //      6   longitude hemisphere ("E" = eastern, "W" = western)            //      7   speed in knots            //      8   true course in degrees            //      9   date in DDMMYY format            //      A   magnetic variation in degrees            //      B   direction of magnetic variation ("E" = east, "W" = west)            //      M   checksum            // $GPVTG - Track Made Good and Ground Speed            //   $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*41            //             1  2    3  4    5  6    7  8            //      1   True course made good over ground, degrees            //      2   Magnetic course made good over ground, degrees            //      3   Ground speed, N=Knots            //      4   Ground speed, K=Kilometers per hour            utBool validFix_GPRMC = utFalse;            utBool validFix_GPGGA = utFalse;            char fldData[256], *fld[22];            memset(fld, 0, sizeof(fld));            strncpy(fldData, data, sizeof(fldData) - 1); // local copy            fldData[sizeof(fldData) - 1] = 0; // safety net terminator            strParseArray(fldData, fld, 20);            /* checksum (XOR sum of all characters between '$' and '*', exclusive) */            if (!cksumIsValidCharXOR(&data[1],(int*)0)) {                logWARNING(LOGSRC,"GPS record failed checksum: %s", fld[0]);                continue; // skip this record            }            /* handle record type */            // We cannot assume that the GPRMC will arrive before GPGGA, or visa-versa.            // so we must handle either case.            if (strEqualsIgnoreCase(fld[0],"$GPRMC")) {#if defined(SUPPORT_TYPE_GPRMC)                if (*fld[2] == 'A') {                    // "A" - valid gps fix                                        /* parse */                    UInt32 hms       = strParseUInt32(fld[1], 0L);                    UInt32 dmy       = strParseUInt32(fld[9], 0L);                    UInt32 fixtime   = _gpsGetUTCSeconds(dmy, hms);                    double latitude  = getLatitude (fld[3], fld[4]);                    double longitude = getLongitude(fld[5], fld[6]);                    double knots     = strParseDouble(fld[7], -1.0);                    double heading   = strParseDouble(fld[8], -1.0);                    double speedKPH  = (knots >= 0.0)? (knots * KILOMETERS_PER_KNOT) : -1.0;                                        /* HDOP expired? */                    if (utcIsTimerExpired(gpsLastHDOPTimer,60L)) {                        gpsLastPDOP = GPS_UNDEFINED_DOP;                        gpsLastHDOP = GPS_UNDEFINED_DOP;                        gpsLastVDOP = GPS_UNDEFINED_DOP;                        // do not reset timer                    }                                        /* save */                    if (fixtime < MIN_CLOCK_TIME) {                                                // The fixtime is invalid                        char dt[32];                        utcFormatDateTime(dt, fixtime);                        logERROR(LOGSRC,"$GPRMC invalid fixtime: [%lu] %s UTC", fixtime, dt);                        logERROR(LOGSRC,"GPS: %s", data);                                            } else                    if ((latitude  >=  90.0) || (latitude  <=  -90.0) ||                        (longitude >= 180.0) || (longitude <= -180.0)   ) {                                                    // We have an valid record, but the lat/lon appears to be invalid!                        logWARNING(LOGSRC,"$GPRMC invalid lat/lon: %.5lf/%.5lf", latitude, longitude);                                            } else {                                                GPS_LOCK {                            // If the $GPGGA came first, we don't want to indiscriminately clear                            // out the GPS structure before adding the $GPRMC data.                            if ((gpsFixUnsafe.fixtype == 0)                  ||     // no GPS fix                                (gpsFixUnsafe.fixtime < MIN_CLOCK_TIME)      ||     // uninitialized fixtime                                (gpsFixUnsafe.fixtime > fixtime)             ||     // fixtime in the future                                ((fixtime - gpsFixUnsafe.fixtime) > GP_EXPIRE) ) {  // expired fixtime                                gpsClear(&gpsFixUnsafe);                                gpsFixUnsafe.fixtype = 1; // GPS                            } else                            if ((gpsFixUnsafe.point.latitude  != latitude ) ||      // latitude  changed (no GGA?)                                (gpsFixUnsafe.point.longitude != longitude)   ) {   // longitude changed (no GGA?)                                gpsClear(&gpsFixUnsafe);                                gpsFixUnsafe.fixtype = 1; // GPS                            } else {                                // I will be adding to the existing data                            }                            gpsFixUnsafe.ageTimer        = utcGetTimer();                            gpsFixUnsafe.fixtime         = fixtime;                            gpsFixUnsafe.speedKPH        = speedKPH;                            gpsFixUnsafe.heading         = heading;                            gpsFixUnsafe.point.latitude  = latitude;                            gpsFixUnsafe.point.longitude = longitude;                            gpsFixUnsafe.pdop            = gpsLastPDOP;                            gpsFixUnsafe.hdop            = gpsLastHDOP;                            gpsFixUnsafe.vdop            = gpsLastVDOP;                            gpsFixUnsafe.nmea           |= NMEA0183_GPRMC;                            if (gpsFixUnsafe.nmea & NMEA0183_GPGGA) {                                gpsCopy(&gpsFixLast, &gpsFixUnsafe);                            }                        } GPS_UNLOCK                        validFix_GPRMC = utTrue;                        /* update system clock ($GPRMC records only!) */                        gpsUpdateSystemClock(fixtime + 2L);                    }                                                /* count valid record type */                    SAMPLE_LOCK { // locked to prevent external access                        gpsSampleCount_A++;                        if (gpsLastSampleTimer == 0L) {                            logINFO(LOGSRC,"First $GPRMC record (A) @%lu", fixtime);                        }                         gpsLastSampleTimer = utcGetTimer();                        if (validFix_GPRMC) { gpsLastValidTimer = utcGetTimer(); }                    } SAMPLE_UNLOCK                } else {                    // "V" - invalid gps fix                                            /* count invalid record type */                    SAMPLE_LOCK { // locked to prevent external access                        gpsSampleCount_V++;                        if (gpsLastSampleTimer == 0L) {                            logINFO(LOGSRC,"First $GPRMC record (V) @%lu", utcGetTimeSec());                        }                         gpsLastSampleTimer = utcGetTimer();                    } SAMPLE_UNLOCK                    // No valid fix aquired                }#endif            } else            if (strEqualsIgnoreCase(fld[0],"$GPGGA")) {#if defined(SUPPORT_TYPE_GPGGA)                if (*fld[6] != '0') {                    // "1" = GPS                    // "2" = DGPS                    /* parse */                    UInt32 hms       = strParseUInt32(fld[1], 0L);                    UInt32 dmy       = 0L; // we don't know the day                    UInt32 fixtime   = _gpsGetUTCSeconds(dmy, hms);                    double latitude  = getLatitude (fld[2], fld[3]);                    double longitude = getLongitude(fld[4], fld[5]);                    gpsLastHDOP      = strParseDouble(fld[8], GPS_UNDEFINED_DOP);                    int    fixtype   = (int)strParseUInt32(fld[6], 1L); // 1=GPS, 2=DGPS, 3=PPS?, ...                    double altitude  = strParseDouble(fld[9], 0.0);                    /* PDOP/VDOP expired? */                    if (utcIsTimerExpired(gpsLastHDOPTimer,60L)) {                        gpsLastPDOP = GPS_UNDEFINED_DOP;                        gpsLastVDOP = GPS_UNDEFINED_DOP;                    }                    gpsLastHDOPTimer = utcGetTimer(); // reset timer                    /* save */                    if (fixtime < MIN_CLOCK_TIME) {                        // The fixtime is invalid                        // (this can occur if the system clock time hasn't yet been updated)                        char dt[32];                        utcFormatDateTime(dt, fixtime);                        logINFO(LOGSRC,"$GPGGA invalid fixtime: [%lu] %s UTC", fixtime, dt);                        logINFO(LOGSRC,"GPS: %s", data);                    } else                    if ((latitude  >=  90.0) || (latitude  <=  -90.0) ||                        (longitude >= 180.0) || (longitude <= -180.0)   ) {                        // We have an valid record, but the lat/lon appears to be invalid!                        logWARNING(LOGSRC,"$GPGGA invalid lat/lon: %.5lf/%.5lf", latitude, longitude);                    } else {                        GPS_LOCK {                            // If the $GPRMC came first, we don't want to indiscriminately clear                            // out the GPS structure before adding the $GPGGA data.                            if ((gpsFixUnsafe.fixtype == 0)                  ||      // no GPS fix                                (gpsFixUnsafe.fixtime < MIN_CLOCK_TIME)      ||      // uninitialized fixtime                                (gpsFixUnsafe.fixtime > fixtime)             ||      // fixtime in the future                                ((fixtime - gpsFixUnsafe.fixtime) > GP_EXPIRE) ) {   // expired fixtime                                gpsClear(&gpsFixUnsafe);                            } else                            if ((gpsFixUnsafe.point.latitude  != latitude ) ||      // latitude  changed (no GGA?)                                (gpsFixUnsafe.point.longitude != longitude)   ) {   // longitude changed (no GGA?)                                //gpsClear(&gpsFixUnsafe);                            } else {                                // I will be adding to the existing data                            }                            gpsFixUnsafe.ageTimer        = utcGetTimer();                            gpsFixUnsafe.fixtime         = fixtime;                            gpsFixUnsafe.altitude        = altitude;                            gpsFixUnsafe.point.latitude  = latitude;                            gpsFixUnsafe.point.longitude = longitude;                            gpsFixUnsafe.fixtype         = fixtype;                            gpsFixUnsafe.pdop            = gpsLastPDOP;                            gpsFixUnsafe.hdop            = gpsLastHDOP;                            gpsFixUnsafe.vdop            = gpsLastVDOP;                            gpsFixUnsafe.nmea           |= NMEA0183_GPGGA;                            if (gpsFixUnsafe.nmea & NMEA0183_GPRMC) {                                gpsCopy(&gpsFixLast, &gpsFixUnsafe);                            }                        } GPS_UNLOCK                        validFix_GPGGA = utTrue;                    }                                                /* count valid record type */                    SAMPLE_LOCK { // locked to prevent external access to 'gpsLastValidTimer'                        if (validFix_GPGGA) { gpsLastValidTimer = utcGetTimer(); }                    } SAMPLE_UNLOCK                }#endif            } else            if (strEqualsIgnoreCase(fld[0],"$GPGSA")) {#if defined(SUPPORT_TYPE_GPGSA)                if ((*fld[2] != '2') || (*fld[2] != '3')) {                    // "2" = 2D                    // "3" = 3D                    /* parse */                    gpsLastPDOP = strParseDouble(fld[15], GPS_UNDEFINED_DOP);                    gpsLastHDOP = strParseDouble(fld[16], GPS_UNDEFINED_DOP);                    gpsLastVDOP = strParseDouble(fld[17], GPS_UNDEFINED_DOP);                    gpsLastHDOPTimer = utcGetTimer();                                        /* save */                    GPS_LOCK {                        gpsFixUnsafe.pdop  = gpsLastPDOP;                        gpsFixUnsafe.hdop  = gpsLastHDOP;                        gpsFixUnsafe.vdop  = gpsLastVDOP;                        gpsFixUnsafe.nmea |= NMEA0183_GPGSA;                    } GPS_UNLOCK                                    }#endif            } else {                                // unsupported record type                            }            /* valid fix? */            // return now if we're concerned about timeouts and we have a valid fix            if ((timeoutSec > 0L) && validFix_GPRMC) {                return 1; // ok            }        } else {            // sentence does not start with "$GP..."        }                 } // while - read gps data        return 0; // timeout    }// ----------------------------------------------------------------------------#if defined(GPS_THREAD)/* where the thread spends its time */static void _gpsThreadRunnable(void *arg){    const char *gpsPortName = propGetString(PROP_CFG_GPS_PORT, DEFAULT_GPS_PORT);    /* simulator loop */#if defined(GPS_DEVICE_SIMULATOR)    gpsSimulator = strEqualsIgnoreCase(gpsPortName, GPS_SIMULATOR_PORT);    if (gpsSimulator) {        logWARNING(LOGSRC,"Starting GPS simulator thread");        while (gpsRunThread) {            _gpsReadGPSFix(0L); // no timeouts        }        logERROR(LOGSRC,"Stopping GPS simulator thread");        threadExit();        return;    }#endif    /* non-simulator loop */    TimerSec_t gpsLastOpenErrorTimer = 0L;    while (gpsRunThread) {                /* power-conservation */        // The HP hw6945 turns off the GPS receiver when the comport is closed.  To conserve        // power, we may want to wait here until the next 'gpsAquire(...)' is called.  This is        // only checked if the GPS sample interval is fairly long (ie. greater than 2 minutes).        // The trade-off is that with infrequent GPS sampling, arrivals/departures, etc, may        // be delayed, or may even be missed entirely.        UInt32 intervalSec        = propGetUInt32(PROP_GPS_SAMPLE_RATE, 15L);        utBool powerSaveMode      = (intervalSec >= POWER_SAVE_THRESHOLD)? utTrue : utFalse;        UInt32 powerSaveTimeoutMS = 0L;        AQUIRE_LOCK {            if (powerSaveMode) {                // We're only sampling the GPS every POWER_SAVE_THRESHOLD seconds, or more.                // Wait here unit 'gpsAquire(...)' tells us to continue                logDEBUG(LOGSRC,"PowerSave - waiting for 'gpsAquire(...)' ...");                while (!gpsAquireRequest && gpsRunThread) {                    // wait for condition (ie. another thread requesting a GPS fix)                    AQUIRE_WAIT                }                powerSaveTimeoutMS = gpsAquireTimeoutMS;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -