读书人

【转】android hal 层GPS 研究小结

发布时间: 2012-08-14 10:39:57 作者: rapoo

【转】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 !"); */        }    }
?

?

读书人网 >Android

热点推荐