2010年12月29日 星期三

Android GPS porting HAL code - Fix GPSStatus and GPSSvStatus issue. 可以看到衛星訊號強度與收訊狀況

AP透過GpsStatus.Listener()監聽底層的資訊
接到GpsStatus.GPS_EVENT_FIRST_FIX後
透過getTimeToFirstFix function抓取資訊
這個資訊會透過LocationManager.getGpsStauts

GPS_EVENT_FIRST_FIX是LocationManager.java會送出,  在OnFirstFix實做

GpsLocationProvider.java告知reportLocation會負責更新getTimeToFirstFix的參數內容
reportLocation: called from native code to update our position.

在jni/android_location_GpsLocationProvider.cpp找到會將init_native 對應到reportLocation

這邊說
上層AP呼叫addGpsStatusListener就會call onSvStatusChanged (會更新mGpsStatus)

看到jni/android_location_GpsLocationProvider.cpp
GpsCallbacks sGpsCallbacks = {
    location_callback,
    status_callback,
    sv_status_callback,
    nmea_callback
};
實際上glgps.cpp只有implement location_callback
其他都沒有implment.
需要自行implement 這兩個function



status_callback,
sv_status_callback

--


在GPS中定義

/** Represents SV information. */
typedef struct {
    /** Pseudo-random number for the SV. */
    int     prn;
    /** Signal to noise ratio. */
    float   snr;
    /** Elevation of SV in degrees. */
    float   elevation;
    /** Azimuth of SV in degrees. */
    float   azimuth;
} GpsSvInfo;


/** Represents SV status. */
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;

需要填寫GpsSvStatus

最後透過sv_status_callback回傳資料給android gps interface


接下來要解釋一下上述結構的定義
以及跟GPGSA and GPGSV的關係


在GpsSvStatus中
num_svs:實收的衛星數目. 這個會影響android gps interface要收集多少資料
used_in_fix_mask:填寫目前fix的衛星id. 此部份可以經由GPGSA的第3到14個位置中取得.
ephemeris_mask and almanac_mask: 沒有特別設定
據Tommy and Richard的說法, 這個是衛星所發出的訊號, 會經由gps firmware解析之後output出nmea data.
會定義這兩個, 我猜測android給予一般系統廠或是gps module廠有不同的實做內容而做的開關.


sv_list是一個GpsSvInfo的structure.
有下列四個資訊
prn:衛星id編號
snr:衛星訊號
elevation:仰角
azimuth:方位角
以上資訊可以透過GPGSV取得




參考文章有說明 nmea format - GPGSA and GPGSV

GPS nmea - GPGSA and GPGSV


填完GpsSvStatus之後

你需要根據目前GPS的狀態設定GpsStatus

gps.h內定義
/** GPS status event values. */
typedef uint16_t GpsStatusValue;
// IMPORTANT: Note that the following values must match
// constants in GpsLocationProvider.java.
/** GPS status unknown. */
#define GPS_STATUS_NONE             0
/** GPS has begun navigating. */
#define     1
/** GPS has stopped navigating. */
#define GPS_STATUS_SESSION_END      2
/** GPS has powered on but is not navigating. */
#define GPS_STATUS_ENGINE_ON        3
/** GPS is powered off. */
#define GPS_STATUS_ENGINE_OFF       4

所以我在成功開com port後 將status設成GPS_STATUS_ENGINE_ON, 透過callback回傳
讀取到gps nmea後送出GPS_STATUS_SESSION_BEGIN. 

最後感謝Zerget分享的資訊


透過Facebook分享

沒有留言: