【转】android hal 层GPS 研究总结
/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 ? 0x0001,?flags 的bit0为1时,标识位置信息有经纬度的信息
/** GpsLocation has valid altitude. */
#define GPS_LOCATION_HAS_ALTITUDE ? 0x0002,flags 的bit1为1时,标识位置信息有高度的信息,以下标识位类似。
/** GpsLocation has valid speed. */
#define GPS_LOCATION_HAS_SPEED ? ? ?0x0004
/** GpsLocation has valid bearing. */
#define GPS_LOCATION_HAS_BEARING ? ?0x0008
/** GpsLocation has valid accuracy. */
#define GPS_LOCATION_HAS_ACCURACY ? 0x0010
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
欢迎交流。
<pre name="code" [log hit][%s:%d] fix.flags=0x%x ", __FUNCTION__, __LINE__, r->fix.flags); } D(" [log hit][%s:%d] fix.flags=0x%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_update_date( r, tok_date, tok_time ); nmea_reader_update_latlong( r, tok_latitude, tok_latitudeHemi.p[0], tok_longitude, tok_longitudeHemi.p[0] ); nmea_reader_update_bearing( r, tok_bearing ); nmea_reader_update_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\n",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\n",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\n",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)\n"); 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] != '\0' && tok_fixStatus.p[0] != 'N') { Token tok_bearing = nmea_tokenizer_get(tzer,1); Token tok_speed = nmea_tokenizer_get(tzer,5); nmea_reader_update_bearing( r, tok_bearing ); nmea_reader_update_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] != '\0') { Token tok_day = nmea_tokenizer_get(tzer,2); Token tok_mon = nmea_tokenizer_get(tzer,3); nmea_reader_update_cdate( r, tok_day, tok_mon, tok_year ); } tok_time = nmea_tokenizer_get(tzer,1); if (tok_time.p[0] != '\0') nmea_reader_update_time(r, tok_time); } else { tok.p -= 2; D("unknown sentence '%.*s", tok.end-tok.p, tok.p); }D("%s,%d,\n",__FILE__,__LINE__); if (r->fix.flags!=0) {#if GPS_DEBUGD("%d,flags=%d\n",__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\n%s,%d:%s,may callback\n***************************\n",__FILE__,__LINE__,__FUNCTION__);#endifD("******************************2\n%s,%d:%s,may callback\n***************************\n",__FILE__,__LINE__,__FUNCTION__); } else { /* D("no callback, keeping data until needed !"); */ } }??