2010年5月25日 星期二

[轉]如何以 Java 取得衛星定位資訊 ?


http://ccckmit.wikidot.com/gps

許多程式設計人員一聽到要寫衛星定位程式,就覺得那一定很難,如果又要以 Java 寫成,那可能就會打退堂鼓了,本文即是要對此問題,提出一個極簡單的做法,只要利用 javax.comm 這個函式庫,可以在 20 行之內就寫完衛星的位的接收器,這個程式就是Gps.java

簡介

衛星定位系統的運作原理,雖然極為複雜,然而要寫一個衛星定位接收程式,卻是極為簡單的,其原因是市面上所販售的衛星定位接收器,有一套固定的規格,早已把複雜的部分處理好了,我們只要利用 MS Windows 中的 COM port,就可以接收到衛星定位資訊了,而在 Java 語言中接收與寫入 COM port 的方法,就是利用 SUN 所提出來的 communication API (javax.comm),在本文中、我們將說明 javax.comm 函式庫的用法,並實做一個不到 20 行的衛星定位程式。

==衛星定位的資訊格式
市面上所販售的衛星定位器,會將衛星定位資訊,編碼成一種稱為 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 

其中,一般的程式通常只需要 "經度座標,北或南,緯度座標,東或西,品質,衛星數量" 等資訊就夠了,以下我們將說明一個衛星定位接收的 Java 程式寫法。

用Java收衛星資訊

由於程式實在太簡單,因此、我們將直接用程式的註解來說明即可。

import java.io.*; import javax.comm.*;  public class Gps {   public static void main( String[] args) throws Exception {      receive(args[0]);    // 接收來自指定的 COM port 的衛星訊號。   }    // 以下是衛星接收的主要程式。   public static void receive(String port) throws Exception {     // 開啟 COM port (在 Java 中稱為 Serial Port)。     SerialPort serialPort = ( SerialPort ) CommPortIdentifier.getPortIdentifier( port ).open( "GPS", 60 );     // 設定接收參數,包含頻率為 4800bps, 8個資料位元後接著一個停止位元,沒有同位位元(parity bit)等。     serialPort.setSerialPortParams( 4800, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );     // 將該 Serial Port 當成檔案一樣開啟,然後不斷讀取即可。     BufferedReader in = new BufferedReader( new InputStreamReader(serialPort.getInputStream()) );     while (true ) {       String msg = in.readLine();       System.out.println(msg);     }   } } 

Gps.java 程式的安裝與執行方法

欲執行 Gps.java,請將 Gps.zip 下載後解壓縮,其中有兩個特殊的檔案,必須先複製到指定位置中才能順利執行本程式,這是由於我們在程式中使用到了 javax.comm 這個不在標準 JDK 中的函式庫,因此、必須加裝這個函式庫所使用到的資源於系統中,其安裝方法稍嫌複雜,在 MS Windows 系統中的安裝步驟如下:

* 將 win32com.dll 檔案複製到 {JDK}\bin 的目錄下。  * 將 javax.comm.properties 檔案複製到 {JDK}\lib 的目錄下。 

接著,請切換到解壓縮後的目錄 {…}\Gps 中,打上下列指令以編譯該程式,並接著執行之。

javac -classpath comm.jar;. Gps.java java -classpath comm.jar;. Gps COM4 

只要你的衛星定位接收器在 COM4 的位置,就可以看到類似下列的資訊:

$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 

當然、若 COM port 不是 COM4,則程式會收不到任何訊息,此時、請確定你的 GPS 所在的 COM port,假如是 COM2 則請重新執行下列命令即可。

java -classpath comm.jar;. Gps COM2 

然而,要如何得知衛星定位接收器被安裝於哪一個 COM port 呢 ? 你只要選取 MS windows 中的裝置管理員,看一下 連接埠(COM 和 LPT) 的項目中,GPS 在哪一個 port 上即可曉得,以下作者的電腦接上 GPS 於 COM4 後的裝置管理員畫面。

ComPort.jpg

(註:裝置管理員的位置位於: 開始/控制台/系統/硬體/裝置管理員 中)

結語

以 Java 撰寫衛星定位程式,其實相當簡單,然而用途卻非常大,在行動裝置普及率愈來愈高的狀況下,衛星定位的相關應用可望蓬勃發展,本文期望藉由簡單而清楚的說明,讓大家能很容易的開發出相關的應用程式,並了解衛星定位的程式設計方式。

參考文獻

  1. Java(tm) Communications API Win32 Installation Instructions
  2. NMEA format.
  3. GPS tutorial

沒有留言: