衛星程式的運作原理

作品

書籍

課程

程式集

小說集

論文集

散文集

影片集

編輯雜誌

程式人

電子書

JavaScript

計算語言學

微積分

Blender 動畫

C# 語言

系統程式

高等 C 語言

Java

Android

Verilog

Wikidot

R 統計軟體

機率統計

計算機數學

組合語言

人工智慧

開放原始碼

網路資源運用

計算機結構

相關訊息

常用工具

友站連結

在家教育

RSS

最新修改

網頁列表

簡體版

English

簡介

如果您的電腦上有 GPS 衛星接收器,在該接收器接上後,衛星定位的訊息會從 ComPort 源源不斷的傳回來,這些訊息是以 NMEA 格式編碼的文字訊息,其格式如下所示。

$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPGSV,3,1,12,26,89,000,36,29,73,000,00,28,38,000,00,18,35,000,00*79
$GPGSV,3,2,12,09,27,000,00,21,27,000,41,15,23,000,00,10,18,000,00*79
$GPGSV,3,3,12,08,15,000,00,22,07,000,,19,07,000,,03,-01,000,*51
$GPRMC,113347.950,V,0000.0000,N,00000.0000,E,0.00,,120305,,*00
$GPGGA,113348.950,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*76
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPRMC,113348.950,V,0000.0000,N,00000.0000,E,0.00,,120305,,*0F
$GPGGA,113349.950,0000.0000,N,00000.0000,E,0,00,50.0,0.0,M,0.0,M,0.0,0000*77
$GPGSA,A,1,,,,,,,,,,,,,50.0,50.0,50.0*05
$GPRMC,113349.950,V,0000.0000,N,00000.0000,E,0.00,,120305,,*0E

其中,最重要的資訊是座標資訊,紀錄在以 GPSGGA 開頭的欄位中,以下是其欄位的說明:

標頭  ,收訊時間點,經度座標,北或南,緯度座標  ,東或西,品質,衛星數量,....
$GPGGA,113348.950,0000.0000,N    ,00000.0000,E     ,0   ,00      ,50.0,0.0,M,0.0,M,0.0,0000*76

從 ComPort 讀取衛星座標

在配備有 GPS 的電腦或手機當中,這個資訊會從某個 COM port (例如:COM1) 當中傳入,因此,只要一個從 ComPort 讀取資料的無窮迴圈,就能不斷顯示您現在的衛星座標。

但是如果每個程式都自行去開啟 ComPort,那麼,第一個開啟的人將會搶到該 ComPort,於是第二個開啟的程式將無法開啟 ComPort 而導致失敗。

// 請注意,這個成是沒有被測試過,請自行除錯。
class Gps
{
    static String gpsPort = "COM9";
    // 讀取 comPort 的方法
    static void Main(String[] args)
    {
        SerialPort port = new SerialPort(gpsPort, 4800);
        port.DataBits = 8;
        port.Parity = Parity.None;
        port.StopBits = StopBits.One;
        port.ReadTimeout = SerialPort.InfiniteTimeout;
        port.Open();
        try
        {
            while (true)
            {
                string line = gpsPort.ReadLine();
                Console.WriteLine(line);
            }
        }
        catch {}
        port.DiscardInBuffer();
        port.Dispose();
    }
}

使用系統 API 讀取衛星資訊

因此,許多支援 GPS 的程式開發環境,都會由系統提供衛星定位的 API,以方便應用程式取得衛星座標,像是 iPhone, Android, Windows Mobile 等手機系統,都提供了這樣的 GPS API,讓應用程式在讀取衛星資訊時不會導致鎖定 ComPort 的問題。所以程式設計師應該盡量使用這些 GPS API 以取的衛星資訊。

微軟的 Windows Mobile 6.0 中並沒有提供 .NET 版本的 GPS 元件給 C#, VB 等語言使用。於是使用者必須自行對 C++ 所寫的 *.dll 程式加以封裝,以便提供 C#, VB 等語言使用。

微軟的 Gps 系統函式主要包含 GPSOpenDevice(), GPSCloseDevice(), GPSGetPosition(), GPSGetDeviceState() 等函數,您必須搭配 CreateEvent(), CloseEvent(), WaitForMultipleObjects(), EventModify() 等系統函數,才能順利將其封裝為 C# 元件。以下是 C# 在封裝 GPS 系統函數時所需使用的函數宣告。

        #region PInvokes to gpsapi.dll
        [DllImport("gpsapi.dll")]
        static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);

        [DllImport("gpsapi.dll")]
        static extern int  GPSCloseDevice(IntPtr hGPSDevice);

        [DllImport("gpsapi.dll")]
        static extern int  GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);

        [DllImport("gpsapi.dll")]
        static extern int  GPSGetDeviceState(IntPtr pGPSDevice);
        #endregion

        #region PInvokes to coredll.dll
        [DllImport("coredll.dll")]
        static extern IntPtr CreateEvent(IntPtr lpEventAttributes, int bManualReset, int bInitialState, StringBuilder lpName);

        [DllImport("coredll.dll")]
        static extern int CloseHandle(IntPtr hObject);

        const int waitFailed = -1;
        [DllImport("coredll.dll")]
        static extern int WaitForMultipleObjects(int nCount, IntPtr lpHandles, int fWaitAll, int dwMilliseconds);

        const int eventSet = 3;
        [DllImport("coredll.dll")]
        static extern int EventModify(IntPtr hHandle, int dwFunc);

#endregion

    }

以上程式對於不熟悉微軟系統 C++ 程式的人而言,會形成一些障礙。還好,微軟在其 Code Samples for Windows Mobile 範例程式集中提供了一個 GPS 接收器範例 GPS Application ,並在該範例中將 GPS 封裝為 Microsoft.WindowsMobile.Samples.Location 專案,您只要將這個專案 (Microsoft.WindowsMobile.Samples.Location.csproj) 加入到您的方案總管中,就可以使用較簡單的方式取的衛星資訊,以下是該專案的檔案畫面,僅供參考。

GpsProjectFiles.jpg

微軟的 GPS 封裝專案

結語

雖然我們可以利用讀取 ComPort 的方式取得衛星座標訊息,但是應用程式的設計師最好不要這麼作,因為這會讓其他程式無法開啟該 ComPort 以讀取衛星資訊。正確的方法是利用系統所提供的 GPS 函數,利用回呼 (Callback) 的方式取得 GPS 座標,才不會霸佔 ComPort 而造成其他程式的問題。

Facebook

gps
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License