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
欢迎交流。
Java代码
<pre name="code" class="cpp">static void
nmea_reader_parse( NmeaReader* r )
{D("%s,%d,%s\n",__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\n",__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(t
补充:移动开发 , Android ,