Android Hal layer GPS research summary-Analysis of gps gga/GSV/RMC data

Source: Internet
Author: User
Tags in degrees
[Turn] Android Hal layer GPS research summary
2011-09-22

A fast run may not win, a competitive battle may not win, a smart one may not win food, or a wise one may not win money, or a flexible one may not be excited. What came to the world was the opportunity.

In my life, if the twilight grass. /Eclair/hardware/libhardware_legacy/include/hardware_legacy/GPS. h

Typedef struct {
? ? /** Contains gpslocationflags bits .*/
? ? Uint16_t? ? ? ? Flags;
? ? /** Represents latitude in degrees .*/
? ? Double? ? ? ? ? Latitude;
? ? /** Represents longpolling in degrees .*/
? ? Double? ? ? ? ? Longpolling;
? ? /** Represents altitude in meters above the WGS 84 reference
? ? ? * Ellipsoid .*/
? ? Double? ? ? ? ? Altitude;
? ? /** Represents speed in meters per second .*/
? ? Float? ? ? ? ? Speed;
? ? /** Represents heading in degrees .*/
? ? Float? ? ? ? ? Bearing;
? ? /** Represents expected accuracy in meters .*/
? ? Float? ? ? ? ? Accuracy;
? ? /** Timestamp for the location fix .*/
? ? Gpsutctime? ? ? Timestamp;
} Gpslocation;

?

Flags is the identifier

# Define gps_location_has_lat_long? 0x0001 ,? When the bit0 value of flags is 1, the ID position information includes the longitude and latitude information.
/** Gpslocation has valid altitude .*/
# Define gps_location_has_altitude? 0x0002. When the bit1 value of flags is 1, the status information of the flag has a height. The following identifiers are similar.
/** Gpslocation has valid speed .*/
# Define gps_location_has_speed? ? ? Zero X 0004
/** Gpslocation has valid bearing .*/
# Define gps_location_has_bearing? ? Zero X 0008
/** Gpslocation has valid accuracy .*/
# Define gps_location_has_accuracy? Zero X 0010

Typedef void (* gps_status_callback) (gpsstatus * status );

You can use this function to submit the identification information.

Timestamp

Is a 64-bit unsigned integer. It defines the number of seconds from 00:00:00 on January 1, January 01, 1970 to the present in UTC. However, in Android Java, the date function must input a millisecond value, but the decimal value is second, so it must be multiplied by 1000.

Bearing

Corresponding to 8th data disconnections (from 0) of RMC. Course over ground)

Typedef struct {
? ? ? ? /** Number of SVS currently visible .*/
? ? ? ? Int? ? ? ? Num_svs;
? ? ? ? /** Contains an array of SV information .*/
? ? ? ? Gpssvinfo? Sv_list [gps_max_svs];
? ? ? ? /** Represents a bit mask indicating which SVS
? ? ? ? ? * Have ephemeris data.
? ? ? ? ? */
? ? ? ? Uint32_t? ? Ephemeris_mask;
? ? ? ? /** Represents a bit mask indicating which SVS
? ? ? ? ? * Have almanac data.
? ? ? ? ? */
? ? ? ? Uint32_t? ? Almanac_mask;
? ? ? ? /**
? ? ? ? ? * Represents a bit mask indicating which SVS
? ? ? ? ? * Were used for computing the most recent position fix.
? ? ? ? ? */
? ? ? ? Uint32_t? ? Used_in_fix_mask;
} Gpssvstatus;

?

Used_in_fix_mask

If you receive the following datagram ¥ gpgsa, A, 2.8, 1.5, 2.3, * 38

? ? ? 07, 19 ,? 08 ?, 03 ?, ? 16, 11 ,? 06 is a valid Satellite Number (PRN)Used_in_fix_mask

Bit? 6 ?, 18 ,? 7? , 2 ?, ? 15 ?, 10 ,? 5? It is 1, and the other bits are 0. (bit0 is also 0)


Ephemeris_mask, almanac_mask

These two masks are closely related to GSV information.

For example, the following information is received. (In order to facilitate data parsing, I have added a new line)

¥ Gpgsv, 3,1, 11,

19,79, 359,30 ,?

, 22,

, 46,

, 40, * 7b

Satellite No. (PRN ),

¥Gpgsv, 3,2, 11,

11,37, 180 ,,

, 29,

16,30, 050,35,

, 27, * 7A

Satellite Number (PRN ),

¥Gpgsv, 3,3, 11,

24, 17, 178 ,,

319,

28, 31, 02,133, * 4C

Satellite No. (PRN) 24, 08, 28

The BIT (, 22,10, 5, 15, 06,? , 07, 27) Is 1, and other bits are 0 (bit starts from 0th bits ),

The value of the mask is closely related to the Satellite Number.

In short, you must have a deep understanding of the data structure of the company.

Post the first code: eclair/hardware/libhardware_legacy/GPS/gps_qemu.c

Welcome to exchange.

<pre name="code" class="cpp">static voidnmea_reader_parse( NmeaReader* r ){D("%s,%d,%s",__FILE__,__LINE__,__FUNCTION__);   /* we received a complete sentence, now parse it to generate    * a new GPS fix...    */    NmeaTokenizer tzer[1];    Token tok;   D("Received: ""%.*s""", r->pos, r->in);    if (r->pos < 9) {        D("Too short. discarded.");        return;    }    nmea_tokenizer_init(tzer, r->in, r->in + r->pos);#if GPS_DEBUG    {        int n;        for (n = 0; n < tzer->count; n++) {            Token tok = nmea_tokenizer_get(tzer,n);        }    }#endif    tok = nmea_tokenizer_get(tzer, 0);    if (tok.p + 5 > tok.end) {        return;    }    /* ignore first two characters.*/    tok.p += 2;    if ( !memcmp(tok.p, "GGA", 3) ) {        /* GPS fix */D("may%s,%d,%s,gGA",__FILE__,__LINE__,__FUNCTION__);        Token tok_time = nmea_tokenizer_get(tzer,1);        Token tok_latitude = nmea_tokenizer_get(tzer,2);        Token tok_latitudeHemi = nmea_tokenizer_get(tzer,3);        Token tok_longitude = nmea_tokenizer_get(tzer,4);        Token tok_longitudeHemi = nmea_tokenizer_get(tzer,5);        Token tok_altitude = nmea_tokenizer_get(tzer,9);        Token tok_altitudeUnits = nmea_tokenizer_get(tzer,10);        nmea_reader__time(r, tok_time);        nmea_reader__latlong(r, tok_latitude,                                      tok_latitudeHemi.p[0],                                      tok_longitude,                                      tok_longitudeHemi.p[0]);        nmea_reader__altitude(r, tok_altitude, tok_altitudeUnits);    }else if ( !memcmp(tok.p, "GLL", 3) ) {    Token tok_fixstaus = nmea_tokenizer_get(tzer,6);    if (tok_fixstaus.p[0] == ""A"") {     Token tok_latitude = nmea_tokenizer_get(tzer,1);     Token tok_latitudeHemi = nmea_tokenizer_get(tzer,2);     Token tok_longitude = nmea_tokenizer_get(tzer,3);     Token tok_longitudeHemi = nmea_tokenizer_get(tzer,4);     Token tok_time = nmea_tokenizer_get(tzer,5);     nmea_reader__time(r, tok_time);     nmea_reader__latlong(r, tok_latitude, tok_latitudeHemi.p[0], tok_longitude, tok_longitudeHemi.p[0]);    }    }    #ifdef Svpnd_Version    else if ( !memcmp(tok.p, "GSV", 3) ) {D("may%s,%d,%s,gsV",__FILE__,__LINE__,__FUNCTION__);    Token tok_noSatellites = nmea_tokenizer_get(tzer, 3);    int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);       D("%d,inview=%d,",__LINE__,noSatellites);      if (noSatellites > 0) {     Token tok_noSentences = nmea_tokenizer_get(tzer, 1);     Token tok_sentence     = nmea_tokenizer_get(tzer, 2);         int sentence = str2int(tok_sentence.p, tok_sentence.end);     int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end);   D("%d,gsv_index=%d,gsv_total=%d",__LINE__,sentence,totalSentences);       int curr;     int i;                  if (sentence == 1) {D("msg_index=%d",sentence);   //  r->sv_status_changed = 0;     r->sv_status.num_svs = 0;r->sv_status.ephemeris_mask=0ul;r->sv_status.almanac_mask=0ul;     }            curr = r->sv_status.num_svs;           i = 0;            while (i < 4 && r->sv_status.num_svs < noSatellites){         Token    tok_prn = nmea_tokenizer_get(tzer, i * 4 + 4);         Token    tok_elevation = nmea_tokenizer_get(tzer, i * 4 + 5);         Token    tok_azimuth = nmea_tokenizer_get(tzer, i * 4 + 6);         Token    tok_snr = nmea_tokenizer_get(tzer, i * 4 + 7);             r->sv_status.sv_list[curr].prn = str2int(tok_prn.p, tok_prn.end);         r->sv_status.sv_list[curr].elevation = str2float(tok_elevation.p, tok_elevation.end);         r->sv_status.sv_list[curr].azimuth = str2float(tok_azimuth.p, tok_azimuth.end);         r->sv_status.sv_list[curr].snr = str2float(tok_snr.p, tok_snr.end);     r->sv_status.ephemeris_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));r->sv_status.almanac_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));         r->sv_status.num_svs += 1; D("**********curr=%d",curr);    D("%d,prn=%d:snr=%f",__LINE__,r->sv_status.sv_list[curr].prn,r->sv_status.sv_list[curr].snr);         curr += 1;             i += 1;     }         if (sentence == totalSentences) {D("msg=%d,msgindex=%d",totalSentences,sentence);        #ifdef Svpnd_Versionr->callback.sv_status_cb=_gps_state->callbacks.sv_status_cb;     if (r->sv_status_changed !=0) {           if (r->callback.sv_status_cb) {#if GPS_DEBUGD("%d,SV_STATSU,change=%d",__LINE__,r->sv_status_changed);int nums=r->sv_status.num_svs;D("num_svs=%d,emask=%x,amask=%x,inusemask=%x",r->sv_status.num_svs,r->sv_status.ephemeris_mask,r->sv_status.almanac_mask,r->sv_status.used_in_fix_mask);D("************88");while(nums){nums--;D("prn=%d:snr=%f",r->sv_status.sv_list[nums].prn,r->sv_status.sv_list[nums].snr);}D("************88");#endif                 r->callback.sv_status_cb( &(r->sv_status) );               r->sv_status_changed = 0;             }else {                D("no callback, keeping status data until needed !");           }        }     #endif     }         D("%s: GSV message with total satellites %d", __FUNCTION__, noSatellites);         }                 }    #endif        else if ( !memcmp(tok.p, "GSA", 3) ) {    #ifdef Svpnd_Version        /* do something ? */        {D("may%s,%d,%s,gsa",__FILE__,__LINE__,__FUNCTION__);        Token tok_fixStatus = nmea_tokenizer_get(tzer, 2);        int i;        if (tok_fixStatus.p[0] != """" && tok_fixStatus.p[0] != ""1"") {            Token tok_accuracy = nmea_tokenizer_get(tzer, 15);//position dilution of precision dop            nmea_reader__accuracy(r, tok_accuracy);            r->sv_status.used_in_fix_mask = 0ul;D("");            for (i = 3; i <= 14; ++i){                Token tok_prn = nmea_tokenizer_get(tzer, i);                int prn = str2int(tok_prn.p, tok_prn.end);D("gsa,prn=%d,",prn);                if (prn > 0){                    r->sv_status.used_in_fix_mask |= (1ul << ( prn-1));                    r->sv_status_changed = 1;                                  }           }D(""); D("%s: fix mask is %x", __FUNCTION__, r->sv_status.used_in_fix_mask);      //   D(" [log hit][%s:%d] fix.flags=0 x%x ", __FUNCTION__, __LINE__, r->fix.flags);        }       D(" [log hit][%s:%d] fix.flags=0 x%x ", __FUNCTION__, __LINE__, r->fix.flags);    }    #endif        /* do something ? */    } else if ( !memcmp(tok.p, "RMC", 3) ) {        Token tok_time = nmea_tokenizer_get(tzer,1);        Token tok_fixStatus = nmea_tokenizer_get(tzer,2);        Token tok_latitude = nmea_tokenizer_get(tzer,3);        Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4);        Token tok_longitude = nmea_tokenizer_get(tzer,5);        Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6);        Token tok_speed = nmea_tokenizer_get(tzer,7);        Token tok_bearing = nmea_tokenizer_get(tzer,8);        Token tok_date = nmea_tokenizer_get(tzer,9);        D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);       if (tok_fixStatus.p[0] == ""A"")        {            nmea_reader__date( r, tok_date, tok_time );            nmea_reader__latlong( r, tok_latitude,                                           tok_latitudeHemi.p[0],                                           tok_longitude,                                           tok_longitudeHemi.p[0] );            nmea_reader__bearing( r, tok_bearing );            nmea_reader__speed ( r, tok_speed ); #ifdef Svpnd_Versionr->callback.location_cb=_gps_state->callbacks.location_cb;r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;r->callback.status_cb=_gps_state->callbacks.status_cb;if (r->callback.status_cb) {D("report,status,flags=%d",r->fix.flags);            r->callback.status_cb( (struct GpsStatus *)&(r->fix.flags) );        }     if (r->callback.location_cb) {D("location_cb report:r->fix.flags=%d,r->latitude=%f,r->longitude=%f,r->altitude=%f,r->speed=%f,r->bearing=%f,r->accuracy=%f",r->fix.flags,r->fix.latitude,r->fix.longitude,r->fix.altitude,r->fix.speed,r->fix.bearing,r->fix.accuracy);            r->callback.location_cb( &r->fix );D("%d,cc=%d",__LINE__,cc);r->fix.flags = 0;        }if (r->callback.nmea_cb) {D("report,timestamp=%llx,%llu",r->fix.timestamp,r->fix.timestamp);            r->callback.nmea_cb( r->fix.timestamp,r->in,r->pos );                   }    #elser->callback=_gps_state.callbacks->location_cb;//r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;        if (r->callback) {D("if2 (r->callback.location_cb)");             r->callback( &r->fix );             r->fix.flags = 0;         }        #endif        }    }    else if ( !memcmp(tok.p, "VTG", 3) ) {     Token tok_fixStatus = nmea_tokenizer_get(tzer,9);     if (tok_fixStatus.p[0] != """" && tok_fixStatus.p[0] != ""N"") {     Token tok_bearing = nmea_tokenizer_get(tzer,1);     Token tok_speed = nmea_tokenizer_get(tzer,5);     nmea_reader__bearing( r, tok_bearing );     nmea_reader__speed ( r, tok_speed );     }    }    else if ( !memcmp(tok.p, "ZDA", 3) ) {     Token tok_time;     Token tok_year = nmea_tokenizer_get(tzer,4);     if (tok_year.p[0] != """") {     Token tok_day = nmea_tokenizer_get(tzer,2);     Token tok_mon = nmea_tokenizer_get(tzer,3);     nmea_reader__cdate( r, tok_day, tok_mon, tok_year );     }     tok_time = nmea_tokenizer_get(tzer,1);     if (tok_time.p[0] != """")     nmea_reader__time(r, tok_time);    }    else {     tok.p -= 2;     D("unknown sentence ""%.*s", tok.end-tok.p, tok.p);    }D("%s,%d,",__FILE__,__LINE__);    if (r->fix.flags!=0) {#if GPS_DEBUGD("%d,flags=%d",__LINE__,r->fix.flags);        char temp[256];        char* p = temp;        char* end = p + sizeof(temp);        struct tm utc;        p += snprintf( p, end-p, "sending fix" );        if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {            p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);        }        if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {            p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);        }        if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {            p += snprintf(p, end-p, " speed=%g", r->fix.speed);        }        if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {            p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);        }        if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {            p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);        }        gmtime_r( (time_t*) &r->fix.timestamp, &utc );        p += snprintf(p, end-p, " time=%s", asctime( &utc ) );        D(temp);//added by mayzhang for debugD("******************************1%s,%d:%s,may callback***************************",__FILE__,__LINE__,__FUNCTION__);#endifD("******************************2%s,%d:%s,may callback***************************",__FILE__,__LINE__,__FUNCTION__);   }                else {             /* D("no callback, keeping data until needed !"); */        }    }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.