Prawdopodobnie znakomita większość z nas słyszała o systemie lokalizacji GPS. Biorąc pod uwagę jego rosnącą popularność bardzo możliwe, że już korzystaliśmy z jego usług w praktyce - dziś nawigacja samochodowa nie stanowi luksusu, a wiele popularnych modeli palmtopów / telefonów komórkowych posiada wbudowane odbiorniki gps. Jeśli nawet nasze urządzenie nie posiada takowego, to zawsze można podłączyć je poprzez interfejs bluetooth lub usb (odbiorniki takie można kupić już za kilkadziesiąt złotych).
W tym krótkim atykule chciałbym pokazać, jak, z punktu widzenia programisty, możemy odczytać informacje zawarte w sygnale gps.
Co jemy...
Wystarczy zapytać google'a o gps, żeby przekonać się o olbrzymiej ilości informacji na ten temat. W największym możliwym skrócie: jest to system pozwalający ustalić, z dokładnością rzędu metrów, pozycję odbiornika na Ziemi. Zainteresowanym polecam na początek lekturę Wikipedii oraz tego tekstu przystępnie wyjaśniającego działanie systemu. Szukających bardziej technicznych informacji powinien zadowolić ten artykuł.
Czym...
Na początek musimy dysponować odbiornikiem sygnału gps. W moim przypadku użyłem modelu gm720 firmy Navibe podłączanego do komputera przez port usb.

Niezależnie od sposobu podłączenia (wewnętrzny, bluetooth czy usb) odbiornik komunikuje się z komputerem przez wirtualny port szeregowy (COM). W C# obsługa portów szeregowych zawarta jest w System.IO.Ports.
Zgromadzimy teraz kilka informacji o parametrach połączenia. W przypadku komputera sprawdzamy to uruchamiając Menadżera Urządzeń i wyszukując na liście porty COM.

Dzięki temu znamy już nazwę portu. W jego właściwościach znajdziemy kolejne potrzebne parametry.

Informacje te są potrzebne do utworzenia obiektu klasy SerialPort, którego jeden z konstruktorów jest następujący:
public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
SerialPort port = new SerialPort("COM13", 9600, Parity.None, 8, StopBits.One);
port.Open();
string dane = port.ReadExisting();
Jeśli poprawnie skonfigurowaliśmy port, to powinniśmy otrzymać dane w rodzaju tych przedstawionych na obrazku niżej:

Wiemy już, czym ugryźć nadawany sygnał, a teraz pora dowiedzieć się...
Jak...
Mimo, że symbole powyżej wyglądają dość enigmatycznie, to tak naprawdę są nadawane wg ustalonego standardu, który nazywa sie NMEA i jego opisy można znaleźć np. tu lub szczegółowiej tu.
Nam wystarczą informacje, że
Opis wszystkich nagłówków i znaczenie danych po nich występujących są podane w linkach powyżej. Nas interesować będą dwa: GPGGA oraz GPRMC.
Najlepiej opisać je będzie na przykładach (wypisując tylko dane użyte w przykładowej aplikacji):
GPGGA:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
GPRMC:
$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
Przykład wykorzystania
Na potrzeby artykułu napisałem prostą aplikację, która pobiera dane z odbiornika, odczytuje interesujące nas informacje, formatuje i wyświetla na ekranie, dodatkowo umożliwiając pokazanie odczytanej pozycji na Google Maps. Źródła projektu można pobrać stąd. Starałem się dobrze okomentować kod, więc jego działanie powinno być dość jasne. Wspomnę tylko, że sercem aplikacji przetwarzającym dane jest funkcja:
void parseNMEA(string data)
private void timer1_Tick(object sender, EventArgs e) { //odczyt danych z portu szeregowego string dane = port.ReadExisting(); parseNMEA(dane); }
Okno przykładowej aplikacji:

oraz lokalizacja zobrazowana dzięki Google Maps:

Pod tym linkiem dostępna jest wersja demonstrująca możliwość wyznaczania tras w Google Maps.
|
|