android hal 层GPS 研究总结——关于GPS GGA/GSV/RMC 数据的解析

快跑的未必能赢,力战的未必获胜,聪明的未必得粮食,明哲的未必得资财,灵活的未必得喜悦。所临到世人的,是在乎当时的机会。

人生一世间,忽若暮春草。/Eclair/hardware/libhardware_legacy/include/hardware_legacy/gps.h

typedef struct {
? ? /** Contains GpsLocationFlags bits. */
? ? uint16_t ? ? ? ?flags;
? ? /** Represents latitude in degrees. */
? ? double ? ? ? ? ?latitude;
? ? /** Represents longitude in degrees. */
? ? double ? ? ? ? ?longitude;
? ? /** 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是标识

#define GPS_LOCATION_HAS_LAT_LONG ? 0 x0001,?flags 的bit0为1时,标识地位信息有经纬度的信息
/** GpsLocation has valid altitude. */
#define GPS_LOCATION_HAS_ALTITUDE ? 0 x0002,flags 的bit1为1时,标识地位信息有高度的信息,以下标识位类似。
/** GpsLocation has valid speed. */
#define GPS_LOCATION_HAS_SPEED ? ? ?0 x0004
/** GpsLocation has valid bearing. */
#define GPS_LOCATION_HAS_BEARING ? ?0 x0008
/** GpsLocation has valid accuracy. */
#define GPS_LOCATION_HAS_ACCURACY ? 0 x0010

typedef void (* gps_status_callback)(GpsStatus* status);

可以应用这个函数提交标识信息。

timestamp时候戳

是一个64位的无符号的整数。它底本的定义是,UTC时候从1970年01月01日00:00:00至如今的秒数。然则在android的Java说话中Date的机关函数必须输入毫秒值,但获得的十进制是秒,所以要乘以1000。

bearing

对应着RMC的第8(从0起)个数据断。对地航向(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

若是收到如下数据报¥GPGSA,A,3,07,19,08,03,16,11,06,,,,,,2.8,1.5,2.3*38

? ? ?07 , 19 , ?08 ?,03 ?, ?16 , 11 , ?06 是有效的卫星编号(prn)used_in_fix_mask的

bit ?6 ?, 18 , ? 7 ? , 2 ?, ? 15 ?, 10 , ? 5 ?为1,其它位为0.(bit0也是0)


ephemeris_mask,almanac_mask

这两个掩码,与GSV信息亲近相干。

比如收到如下的信息。(为了便于数据解析我多加了转行)

¥GPGSV,3,1,11,

19,79,359,30, ?

13,47,260,22,

03,46,029,31,

23,40,217,24*7B

卫星编号(prn)19,13,03,23

¥GPGSV,3,2,11,

11,37,180,,

06,33,036,29,

16,30,050,35,

07,27,324,25*7A

卫星编号(prn)11,6,16,07

¥GPGSV,3,3,11,

24,17,178,,

08,03,319,

28,31,02,133,*4C

卫星编号(prn)24,08,28

ephemeris_mask和almanac_mask的bit(18,12,02,22,10,5,15,06,?23,07,27)为1,其它位为0(bit从第0位开端),

掩码的值与卫星编号是慎密相干的。

总之,要对NEMA数据格局有深切的懂得。

贴出首要代码:Eclair/hardware/libhardware_legacy/gps/gps_qemu.c

迎接交换。

[java]  view plain copy
  1. <pre name="code" class="cpp">static void  
  2. nmea_reader_parse( NmeaReader* r )  
  3. {D("%s,%d,%s  
  4. ",__FILE__,__LINE__,__FUNCTION__);  
  5.    /* we received a complete sentence, now parse it to generate 
  6.     * a new GPS fix... 
  7.     */  
  8.     NmeaTokenizer tzer[1];  
  9.     Token tok;  
  10.   
  11.    D("Received: ""%.*s""", r->pos, r->in);  
  12.     if (r->pos < 9) {  
  13.         D("Too short. discarded.");  
  14.         return;  
  15.     }  
  16.   
  17.     nmea_tokenizer_init(tzer, r->in, r->in + r->pos);  
  18. if GPS_DEBUG  
  19.     {  
  20.         int n;  
  21.         for (n = 0; n < tzer->count; n++) {  
  22.             Token tok = nmea_tokenizer_get(tzer,n);  
  23.         }  
  24.     }  
  25. #endif  
  26.   
  27.     tok = nmea_tokenizer_get(tzer, 0);  
  28.     if (tok.p + 5 > tok.end) {  
  29.         return;  
  30.     }  
  31.   
  32.     /* ignore first two characters.*/  
  33.     tok.p += 2;  
  34.     if ( !memcmp(tok.p, "GGA", 3) ) {  
  35.         /* GPS fix */D("may%s,%d,%s,gGA  
  36. ",__FILE__,__LINE__,__FUNCTION__);  
  37.       
  38.         Token tok_time = nmea_tokenizer_get(tzer,1);  
  39.         Token tok_latitude = nmea_tokenizer_get(tzer,2);  
  40.         Token tok_latitudeHemi = nmea_tokenizer_get(tzer,3);  
  41.         Token tok_longitude = nmea_tokenizer_get(tzer,4);  
  42.         Token tok_longitudeHemi = nmea_tokenizer_get(tzer,5);  
  43.         Token tok_altitude = nmea_tokenizer_get(tzer,9);  
  44.         Token tok_altitudeUnits = nmea_tokenizer_get(tzer,10);  
  45.   
  46.         nmea_reader__time(r, tok_time);  
  47.         nmea_reader__latlong(r, tok_latitude,  
  48.                                       tok_latitudeHemi.p[0],  
  49.                                       tok_longitude,  
  50.                                       tok_longitudeHemi.p[0]);  
  51.         nmea_reader__altitude(r, tok_altitude, tok_altitudeUnits);  
  52.     }else if ( !memcmp(tok.p, "GLL", 3) ) {  
  53.     Token tok_fixstaus = nmea_tokenizer_get(tzer,6);  
  54.     if (tok_fixstaus.p[0] == ""A"") {  
  55.      Token tok_latitude = nmea_tokenizer_get(tzer,1);  
  56.      Token tok_latitudeHemi = nmea_tokenizer_get(tzer,2);  
  57.      Token tok_longitude = nmea_tokenizer_get(tzer,3);  
  58.      Token tok_longitudeHemi = nmea_tokenizer_get(tzer,4);  
  59.      Token tok_time = nmea_tokenizer_get(tzer,5);  
  60.      nmea_reader__time(r, tok_time);  
  61.      nmea_reader__latlong(r, tok_latitude, tok_latitudeHemi.p[0], tok_longitude, tok_longitudeHemi.p[0]);  
  62.     }  
  63.     }  
  64.     #ifdef Svpnd_Version  
  65.     else if ( !memcmp(tok.p, "GSV", 3) ) {  
  66. D("may%s,%d,%s,gsV  
  67. ",__FILE__,__LINE__,__FUNCTION__);  
  68.     Token tok_noSatellites = nmea_tokenizer_get(tzer, 3);  
  69.     int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);  
  70.        D("%d,inview=%d,  
  71. ",__LINE__,noSatellites);    
  72.     if (noSatellites > 0) {  
  73.      Token tok_noSentences = nmea_tokenizer_get(tzer, 1);  
  74.      Token tok_sentence     = nmea_tokenizer_get(tzer, 2);  
  75.       
  76.      int sentence = str2int(tok_sentence.p, tok_sentence.end);  
  77.      int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end);  
  78.    D("%d,gsv_index=%d,gsv_total=%d  
  79. ",__LINE__,sentence,totalSentences);    
  80.      int curr;  
  81.      int i;  
  82.                
  83.      if (sentence == 1) {  
  84. D("msg_index=%d  
  85. ",sentence);  
  86.    //  r->sv_status_changed = 0;  
  87.      r->sv_status.num_svs = 0;  
  88.     r->sv_status.ephemeris_mask=0ul;  
  89.     r->sv_status.almanac_mask=0ul;  
  90.      }  
  91.       
  92.         curr = r->sv_status.num_svs;  
  93.      
  94.         i = 0;  
  95.       
  96.         while (i < 4 && r->sv_status.num_svs < noSatellites){  
  97.          Token    tok_prn = nmea_tokenizer_get(tzer, i * 4 + 4);  
  98.          Token    tok_elevation = nmea_tokenizer_get(tzer, i * 4 + 5);  
  99.          Token    tok_azimuth = nmea_tokenizer_get(tzer, i * 4 + 6);  
  100.          Token    tok_snr = nmea_tokenizer_get(tzer, i * 4 + 7);  
  101.       
  102.          r->sv_status.sv_list[curr].prn = str2int(tok_prn.p, tok_prn.end);  
  103.          r->sv_status.sv_list[curr].elevation = str2float(tok_elevation.p, tok_elevation.end);  
  104.          r->sv_status.sv_list[curr].azimuth = str2float(tok_azimuth.p, tok_azimuth.end);  
  105.          r->sv_status.sv_list[curr].snr = str2float(tok_snr.p, tok_snr.end);  
  106.          r->sv_status.ephemeris_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));  
  107.     r->sv_status.almanac_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));           
  108.     r->sv_status.num_svs += 1;  
  109.  D("**********curr=%d  
  110. ",curr);  
  111.    
  112.    D("%d,prn=%d:snr=%f  
  113. ",__LINE__,r->sv_status.sv_list[curr].prn,r->sv_status.sv_list[curr].snr);  
  114.          curr += 1;  
  115.       
  116.          i += 1;  
  117.      }  
  118.       
  119.      if (sentence == totalSentences) {  
  120. D("msg=%d,msgindex=%d",totalSentences,sentence);  
  121.         #ifdef Svpnd_Version  
  122. r->callback.sv_status_cb=_gps_state->callbacks.sv_status_cb;  
  123.   
  124.      if (r->sv_status_changed !=0) {  
  125.            if (r->callback.sv_status_cb) {  
  126.           
  127.         #if GPS_DEBUG  
  128.         D("%d,SV_STATSU,change=%d  
  129. ",__LINE__,r->sv_status_changed);  
  130.         int nums=r->sv_status.num_svs;  
  131.         D("num_svs=%d,emask=%x,amask=%x,inusemask=%x  
  132. ",r->sv_status.num_svs,r->sv_status.ephemeris_mask,r->sv_status.almanac_mask,r->sv_status.used_in_fix_mask);  
  133.         D("************88  
  134. ");       
  135.         while(nums)  
  136.         {  
  137.         nums--;  
  138.         D("prn=%d:snr=%f  
  139. ",r->sv_status.sv_list[nums].prn,r->sv_status.sv_list[nums].snr);  
  140.           
  141.         }D("************88  
  142. ");  
  143.         #endif  
  144.                  r->callback.sv_status_cb( &(r->sv_status) );  
  145.                r->sv_status_changed = 0;  
  146.              }else {  
  147.                 D("no callback, keeping status data until needed !");  
  148.            }  
  149.   
  150.         }  
  151.      #endif  
  152.      }  
  153.       
  154.      D("%s: GSV message with total satellites %d", __FUNCTION__, noSatellites);   
  155.       
  156.     }           
  157.       
  158.     }  
  159.     #endif  
  160.       
  161.     else if ( !memcmp(tok.p, "GSA", 3) ) {  
  162.     #ifdef Svpnd_Version  
  163.         /* do something ? */  
  164.         {  
  165. D("may%s,%d,%s,gsa  
  166. ",__FILE__,__LINE__,__FUNCTION__);  
  167.         Token tok_fixStatus = nmea_tokenizer_get(tzer, 2);  
  168.         int i;  
  169.   
  170.         if (tok_fixStatus.p[0] != """" && tok_fixStatus.p[0] != ""1"") {  
  171.   
  172.             Token tok_accuracy = nmea_tokenizer_get(tzer, 15);//position dilution of precision dop  
  173.   
  174.             nmea_reader__accuracy(r, tok_accuracy);  
  175.   
  176.             r->sv_status.used_in_fix_mask = 0ul;  
  177.     D("  
  178. ");  
  179.             for (i = 3; i <= 14; ++i){  
  180.   
  181.                 Token tok_prn = nmea_tokenizer_get(tzer, i);  
  182.                 int prn = str2int(tok_prn.p, tok_prn.end);  
  183.         D("gsa,prn=%d,",prn);  
  184.                 if (prn > 0){  
  185.                     r->sv_status.used_in_fix_mask |= (1ul << ( prn-1));  
  186.                     r->sv_status_changed = 1;  
  187.                      
  188.                }  
  189.   
  190.            }D("  
  191. ");  
  192.      D("%s: fix mask is %x", __FUNCTION__, r->sv_status.used_in_fix_mask);  
  193.       //   D(" [log hit][%s:%d] fix.flags=0 x%x ", __FUNCTION__, __LINE__, r->fix.flags);   
  194.        }  
  195.   
  196.        D(" [log hit][%s:%d] fix.flags=0 x%x ", __FUNCTION__, __LINE__, r->fix.flags);  
  197.   
  198.     }  
  199.     #endif  
  200.         /* do something ? */  
  201.     } else if ( !memcmp(tok.p, "RMC", 3) ) {  
  202.       
  203.         Token tok_time = nmea_tokenizer_get(tzer,1);  
  204.         Token tok_fixStatus = nmea_tokenizer_get(tzer,2);  
  205.         Token tok_latitude = nmea_tokenizer_get(tzer,3);  
  206.         Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4);  
  207.         Token tok_longitude = nmea_tokenizer_get(tzer,5);  
  208.         Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6);  
  209.         Token tok_speed = nmea_tokenizer_get(tzer,7);  
  210.         Token tok_bearing = nmea_tokenizer_get(tzer,8);  
  211.         Token tok_date = nmea_tokenizer_get(tzer,9);  
  212.   
  213.         D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);  
  214.        if (tok_fixStatus.p[0] == ""A"")  
  215.         {  
  216.             nmea_reader__date( r, tok_date, tok_time );  
  217.   
  218.             nmea_reader__latlong( r, tok_latitude,  
  219.                                            tok_latitudeHemi.p[0],  
  220.                                            tok_longitude,  
  221.                                            tok_longitudeHemi.p[0] );  
  222.   
  223.             nmea_reader__bearing( r, tok_bearing );  
  224.             nmea_reader__speed ( r, tok_speed );  
  225.          #ifdef Svpnd_Version  
  226. r->callback.location_cb=_gps_state->callbacks.location_cb;  
  227. r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;  
  228. r->callback.status_cb=_gps_state->callbacks.status_cb;  
  229. if (r->callback.status_cb) {  
  230. D("report,status,flags=%d  
  231. ",r->fix.flags);  
  232.             r->callback.status_cb( (struct GpsStatus *)&(r->fix.flags) );  
  233.         }  
  234.      if (r->callback.location_cb) {  
  235. 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  
  236. ",r->fix.flags,r->fix.latitude,r->fix.longitude,r->fix.altitude,r->fix.speed,r->fix.bearing,r->fix.accuracy);  
  237.             r->callback.location_cb( &r->fix );  
  238. D("%d,cc=%d",__LINE__,cc);  
  239.         r->fix.flags = 0;  
  240.           
  241.         }  
  242. if (r->callback.nmea_cb) {  
  243. D("report,timestamp=%llx,%llu  
  244. ",r->fix.timestamp,r->fix.timestamp);  
  245.             r->callback.nmea_cb( r->fix.timestamp,r->in,r->pos );  
  246.           
  247.              
  248.         }  
  249.   
  250.     #else  
  251. r->callback=_gps_state.callbacks->location_cb;  
  252. //r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;  
  253.         if (r->callback) {D("if2 (r->callback.location_cb)  
  254. ");  
  255.              r->callback( &r->fix );  
  256.              r->fix.flags = 0;  
  257.          }  
  258.         #endif  
  259.         }  
  260.     }  
  261.     else if ( !memcmp(tok.p, "VTG", 3) ) {  
  262.      Token tok_fixStatus = nmea_tokenizer_get(tzer,9);  
  263.      if (tok_fixStatus.p[0] != """" && tok_fixStatus.p[0] != ""N"") {  
  264.      Token tok_bearing = nmea_tokenizer_get(tzer,1);  
  265.      Token tok_speed = nmea_tokenizer_get(tzer,5);  
  266.      nmea_reader__bearing( r, tok_bearing );  
  267.      nmea_reader__speed ( r, tok_speed );  
  268.      }  
  269.     }  
  270.     else if ( !memcmp(tok.p, "ZDA", 3) ) {  
  271.      Token tok_time;  
  272.      Token tok_year = nmea_tokenizer_get(tzer,4);  
  273.      if (tok_year.p[0] != """") {  
  274.      Token tok_day = nmea_tokenizer_get(tzer,2);  
  275.      Token tok_mon = nmea_tokenizer_get(tzer,3);  
  276.      nmea_reader__cdate( r, tok_day, tok_mon, tok_year );  
  277.      }  
  278.      tok_time = nmea_tokenizer_get(tzer,1);  
  279.      if (tok_time.p[0] != """")  
  280.      nmea_reader__time(r, tok_time);  
  281.     }  
  282.     else {  
  283.      tok.p -= 2;  
  284.      D("unknown sentence ""%.*s", tok.end-tok.p, tok.p);  
  285.     }D("%s,%d,  
  286. ",__FILE__,__LINE__);  
  287.     if (r->fix.flags!=0) {  
  288. if GPS_DEBUG  
  289.     D("%d,flags=%d  
  290. ",__LINE__,r->fix.flags);  
  291.         char temp[256];  
  292.         char* p = temp;  
  293.         char* end = p + sizeof(temp);  
  294.         struct tm utc;  
  295.   
  296.         p += snprintf( p, end-p, "sending fix" );  
  297.         if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {  
  298.             p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);  
  299.         }  
  300.         if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {  
  301.             p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);  
  302.         }  
  303.         if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {  
  304.             p += snprintf(p, end-p, " speed=%g", r->fix.speed);  
  305.         }  
  306.         if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {  
  307.             p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);  
  308.         }  
  309.         if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {  
  310.             p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);  
  311.         }  
  312.         gmtime_r( (time_t*) &r->fix.timestamp, &utc );  
  313.         p += snprintf(p, end-p, " time=%s", asctime( &utc ) );  
  314.         D(temp);  
  315. //added by mayzhang for debug  
  316.   
  317. D("******************************1  
  318. %s,%d:%s,may callback  
  319. ***************************  
  320. ",__FILE__,__LINE__,__FUNCTION__);  
  321. #endif  
  322.   
  323. D("******************************2  
  324. %s,%d:%s,may callback  
  325. ***************************  
  326. ",__FILE__,__LINE__,__FUNCTION__);  
  327.    }  
  328.           
  329.         else {  
  330.              /* D("no callback, keeping data until needed !"); */  
  331.         }  
  332.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值