上方這是一款常見的USB介面的GPS衛星接收器,透過USB模擬TTY介面,我們可以使用程式讀取serial port獲得GPS的資訊。以Linux環境(包含Raspberry OS)為例,OS透過所謂的UDEV daemon來進行設備的管理,對應並維護/dev目錄底下的裝置節點。因此,當我們插入了此USB GPS,會在/dev目錄下產生一個ttyUSB0的序列埠裝置,此時我們便可依tty的讀取方式,取得即時的GPS資訊。
如果您購買的GPS裝置不是USB介面而是UART介面,那麼就要接到Raspberry GPIO的序列埠,Raspberry Pi比較特殊的是,在/dev下它本機的UART介面不叫ttyS0或ttyS1,而是ttyAMA0或ttyAMA1,這是在使用TTY時需要注意的。
GPS的格式
目前GPS標準的規格稱為NMEA 0183,由美國國家海洋電子協會(National Marine Electronics Association,NMEA)所制定,其傳輸規範如下:(來源:WIKI)
- Baud rate:4,800
- Data bits:8
- Parity:None
- Stop bits:1
- Handshake:None
保留字元:(已使用於GPS訊息中)
ASCII | Hex | Dec | Use |
<CR> | 0x0d | 13 | Carriage return |
<LF> | 0x0a | 10 | Line feed, end delimiter |
! | 0x21 | 33 | Start of encapsulation sentence delimiter |
$ | 0x24 | 36 | Start delimiter |
* | 0x2a | 42 | Checksum delimiter |
, | 0x2c | 44 | Field delimiter |
\ | 0x5c | 92 | TAG block delimiter |
^ | 0x5e | 94 | Code delimiter for HEX representation of ISO/IEC 8859-1 (ASCII) characters |
~ | 0x7e | 126 | Reserved |
讀取GPS
- 將GPS插上USB port後,在/dev目錄下會多出一個ttyUSB0的檔案。
- 安裝pySerial,透過Python讀取serial的模組:
pip install pyserial
- 執行下方的程式:
# -*- coding: UTF-8 -*- import serial COM_PORT = '/dev/ttyUSB0' BAUD_RATES = 4800 ser = serial.Serial(COM_PORT, BAUD_RATES) try: while True: while ser.in_waiting: data_raw = ser.readline() data = data_raw.decode() # 預設的UTF-8解碼 print('Raw data:', data_raw) print('Decoded :', data) except KeyboardInterrupt: ser.close() print('by...')
第一行的「# -*- coding: UTF-8 -*-」一定要加上,否則decode()編碼為UTF-8時會出現如下的error message。
UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xc6 in position 2: invalid continuation byte
解碼GPS
執行後會持續收取到如下的message,這些資訊很明顯為CSV格式,每一行稱為一個sentence,一個sentence最長不會超過82個字元:
Raw data: b’,11,32,32,149,,29,18,043,,18,02,102,*48\r\n’
Decoded : ,11,32,32,149,,29,18,043,,18,02,102,*48
Raw data: b’$GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65\r\n’
Decoded : $GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65
Raw data: b’$GPGGA,095913.000,2446.4094,N,12101.0267,E,1,06,1.8,125.8,M,15.0,M,,0000*53\r\n’
Decoded : $GPGGA,095913.000,2446.4094,N,12101.0267,E,1,06,1.8,125.8,M,15.0,M,,0000*53
Raw data: b’$GPGSA,A,3,26,16,27,04,03,22,,,,,,,2.9,1.8,2.2*31\r\n’
Decoded : $GPGSA,A,3,26,16,27,04,03,22,,,,,,,2.9,1.8,2.2*31
Raw data: b’$GPRMC,095913.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*64\r\n’
Decoded : $GPRMC,095913.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*64
每行sentence具有以下的結構:
start character
每行的啟始字元只有兩種:$以及!,「$」符號表示該行為正確的GPS資訊,「!」符號表示該行有特殊的異常資訊。
Ex: $GPRMC,095912.000,A,2446.4094,N,12101.0267,E,0.00,121.28,281120,,,A*65
identify characters
啟始字元後方的五個字元稱為identifier,表示該sentence的種類,目前已知超過五十多種。(下方資料來源:http://aprs.gids.nl/nmea/#allgp)
- $GPAAM – Waypoint Arrival Alarm
- $GPALM – GPS Almanac Data
- $GPAPA – Autopilot Sentence “A"
- $GPAPB – Autopilot Sentence “B"
- $GPASD – Autopilot System Data
- $GPBEC – Bearing & Distance to Waypoint, Dead Reckoning
- $GPBOD – Bearing, Origin to Destination
- $GPBWC – Bearing & Distance to Waypoint, Great Circle
- $GPBWR – Bearing & Distance to Waypoint, Rhumb Line
- $GPBWW – Bearing, Waypoint to Waypoint
- $GPDBT – Depth Below Transducer
- $GPDCN – Decca Position
- $GPDPT – Depth
- $GPFSI – Frequency Set Information
- $GPGGA – Global Positioning System Fix Data
- $GPGLC – Geographic Position, Loran-C
- $GPGLL – Geographic Position, Latitude/Longitude
- $GPGSA – GPS DOP and Active Satellites
- $GPGSV – GPS Satellites in View
- $GPGXA – TRANSIT Position
- $GPHDG – Heading, Deviation & Variation
- $GPHDT – Heading, True
- $GPHSC – Heading Steering Command
- $GPLCD – Loran-C Signal Data
- $GPMTA – Air Temperature (to be phased out)
- $GPMTW – Water Temperature
- $GPMWD – Wind Direction
- $GPMWV – Wind Speed and Angle
- $GPOLN – Omega Lane Numbers
- $GPOSD – Own Ship Data
- $GPR00 – Waypoint active route (not standard)
- $GPRMA – Recommended Minimum Specific Loran-C Data
- $GPRMB – Recommended Minimum Navigation Information
- $GPRMC – Recommended Minimum Specific GPS/TRANSIT Data
- $GPROT – Rate of Turn
- $GPRPM – Revolutions
- $GPRSA – Rudder Sensor Angle
- $GPRSD – RADAR System Data
- $GPRTE – Routes
- $GPSFI – Scanning Frequency Information
- $GPSTN – Multiple Data ID
- $GPTRF – Transit Fix Data
- $GPTTM – Tracked Target Message
- $GPVBW – Dual Ground/Water Speed
- $GPVDR – Set and Drift
- $GPVHW – Water Speed and Heading
- $GPVLW – Distance Traveled through the Water
- $GPVPW – Speed, Measured Parallel to Wind
- $GPVTG – Track Made Good and Ground Speed
- $GPWCV – Waypoint Closure Velocity
- $GPWNC – Distance, Waypoint to Waypoint
- $GPWPL – Waypoint Location
- $GPXDR – Transducer Measurements
- $GPXTE – Cross-Track Error, Measured
- $GPXTR – Cross-Track Error, Dead Reckoning
- $GPZDA – Time & Date
- $GPZFO – UTC & Time from Origin Waypoint
- $GPZTG – UTC & Time to Destination Waypoint
但不是每種GPS裝置都支援(可輸出)這麼多種,以我手上的這支環天出品的GPS為例,僅支援GPRMC、GPGGA與GPGSA這三種identifier。
GPGGA格式
- 為identify characters
- 為UTC 時間,格式:hhmmss(時分秒)。
- 緯度ddmm.mmmm(度分)格式
- 緯度半球N(北半球)或S(南半球)
- 經度dddmm.mmmm(度分)格式
- 經度半球E(東經)或W(西經)
- Fix Quality:0=未定位,1=非差分定位,2=差分定位,6=正在估算
- 已抓取定位的衛星數目:如本例為7個
- Horizontal Dilution of Precision (HDOP) 海拔高度
- 海拔高度(-9999.9~99999.9),指高於海平面的高度。
- 衛星高度單位:M為公尺
- 地球橢球面相對大地水準面的高度
- 水平面高度單位:M為公尺
- 差分時間(從最近一次接收到差分信號開始的秒數,如果不是差分定位將為空)
- 差分站ID號0000~1023(前面的0也將被傳輸,如果不是差分定位將為空)
GPGSA格式
- 為identify characters
- 定位方式:M = 手動, A = 自動。
- 定位型式 1 = 未定位, 2 = 二維定位, 3 = 三維定位。
- 第一組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第二組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第三組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第四組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第五組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第六組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第七組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第八組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第九組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第十組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第十一組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
- 第十二組PRN 數字(IDs of SVs used in position):01 至 32 表天空使用中的衛星編號
(最多可接收12顆衛星資訊) - PDOP位置精度因數(0.5~99.9)
- HDOP水準精度因數(0.5~99.9)
- VDOP垂直精度因數(0.5~99.9)
- Checksum.(檢查位).
GPRMC格式
- 為identify characters
- UTC時間,hhmmss(時分秒)格式
- 定位狀態,A=有效定位,V=無效定位
- 緯度ddmm.mmmm(度分)格式
- 緯度半球N(北半球)或S(南半球)
- 經度dddmm.mmmm(度分)格式
- 經度半球E(東經)或W(西經)
- 地面速率(000.0~999.9節)
- 地面航向(000.0~359.9度,以真北為參考基準)
- UTC日期,ddmmyy(日月年)格式
- 磁偏角(000.0~180.0度)
- 磁偏角方向,E(東)或W(西)
- 模式指示(A=自主定位,D=差分,E=估算,N=資料無效)
使用GPS
以這支Globalsat 環天衛星接收器(BU-353S4 GPS)為例,它可輸出三種格式的資訊:GPRMC、GPGGA與GPGSA,從上方表格的identify資訊我們可以知道,如果要取得目前GPS所在位置,使用GPRMS是最適合的,如果要取得目前海拔高度,就要使用GPGGA,而如果要知道各衛星的詳細定位資訊,那麼就要用GPGSA。
透過TTY來使用GPS模組相當的容易且方便,因此,我們可以利用Arduino或樹莓派等開發板,快速的開發出各式功能以滿足與「位置」情境相關的應用需求。