Jak interpretować próbkę surowych danych AIS

9

Znalazłem plik zawierający około 85 000 wiadomości (3-minutowy kanał AISHub na żywo), ale nie mogę tego zrobić.

http://www.aishub.net/nmea-sample.html

!AIVDM,1,1,,A,13aEOK?P00PD2wVMdLDRhgvL289?,0*26
!AIVDM,1,1,,B,16S`2cPP00a3UF6EKT@2:?vOr0S2,0*00
!AIVDM,2,1,9,B,53nFBv01SJ<thHp6220H4heHTf2222222222221?50:454o<`9QSlUDp,0*09
!AIVDM,2,2,9,B,888888888888880,2*2E

Czy jest gdzieś schemat?

Phillip Senn
źródło
Nie wiem, jakiego języka programowania używasz, ale polecam skorzystanie z biblioteki do jego odkodowania. To moja ulubiona: github.com/bcl/aisparser
bjornasm
1
Mogę polecić własną bibliotekę Ruby do dekodowania AIS , opartą na stronie catb.org, o której wspominali inni.
Ian

Odpowiedzi:

7

Istnieje dobre repozytorium github Kurta Schwehra, który pracuje w Centre for Coastal and Ocean Mapping ( na przykład w celu śledzenia działalności wielorybów ). Znajdziesz tam dekoder i dokumenty do zrozumienia wiadomości nmea (głównie linki wymienione w postach @ianmayo i @GID Dev). Oto małe howto biegnące pod LINUXi python 2.7.

Aby uzyskać pewne uruchomiony kod, musisz gitsię C++kompilatora, tym python setup environment, cmake. Pobierz dane z

$ cd YOUR_BUILD_PATH
$ git clone https://github.com/schwehr/libais.git

i postępuj zgodnie z instrukcjami instalacji na stronie github lub uruchom

$ cd YOUR_BUILD_PATH/libais
$ cmake .  # to bulid the Makefile 
$ make     # to build the libais C++
$ python setup.py build # to build the python stuff
$ sudo python setup.py install # to deploy it

W końcu powinieneś mieć biblioteki w swoim pythonśrodowisku.

 $ ls /usr/local/lib/python2.7/dist-packages/
 easy-install.pth  libais-0.16-py2.7-linux-x86_64.egg

 $ ls /usr/local/lib/python2.7/dist-packages/libais-0.16-py2.7-linux-x86_64.egg
 ais  _ais.py  _ais.pyc  _ais.so  EGG-INFO  test

Oto szybki i nieprzyzwoity kod w skrypcie wywoływanym w test-ais.pycelu uzyskania uniksowego polubienia headi zachowania tail. Używam jsonjako „ładnej drukarki z czystym tekstem”.

#!/usr/bin/python

# To supress the warning ...could be done better    
# FutureWarning: The stream module is deprecated and will be removed in 1.0
# https://github.com/schwehr/libais/blob/master/ais/stream/__init__.py
# coded in in __init__.py line 10-14
import warnings
warnings.filterwarnings("ignore")

# import json module for pretty print
import json

# import ais.stream module to decode
# a ais binary nmea message to json 
import ais.stream

# import sys module to read stuff from
# standard input STDIN
import sys

# decode a file or somthing form the STDIN
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin

# Iterate over the messages 
for msg in ais.stream.decode(f):
    # make a json pretty print for each message
    print json.dumps(msg, indent=4, sort_keys=True)

# EOF

Zakładając, że nmea-samplesplik znajduje się w datakatalogu, możesz odfiltrować wiersz, który chcesz wyświetlić cat, headi tail...

$ tail -1 data/nmea-sample | ./test-ais.py
 {
    "day": 14, 
    "fix_type": 1, 
    "hour": 11, 
    "id": 4, 
    "minute": 33, 
    "mmsi": 2320717, 
    "month": 3, 
    "position_accuracy": 0, 
    "raim": false, 
    "repeat_indicator": 3, 
    "second": 30, 
    "slot_offset": 2250, 
    "slot_timeout": 0, 
    "spare": 0, 
    "sync_state": 0, 
    "transmission_ctl": 0, 
    "x": -5.782454967498779, 
    "y": 57.842193603515625, 
    "year": 2012
 }

Począwszy od kodu json, powinno być łatwo kontynuować formatowanie i przechowywanie rzeczy.

huckfinn
źródło
5

AIVDM / protokół AIVDO dekodowania strona zawiera odpowiedź, ale nie ma wiele do przesiać przez nie. Aby odpowiedzieć na postawione pytanie, pochodzi ono ze wspomnianej strony w tym formacie:

Oto typowy pakiet danych AIVDM:

! AIVDM, 1,1,, B, 177KQJ5000G? TO`K> RA1wUbN0TKH, 0 * 5C

A oto, co oznaczają pola:

Pole 1! AIVDM identyfikuje to jako pakiet AIVDM.

Pole 2 (1 w tym przykładzie) to liczba fragmentów w aktualnie gromadzącej się wiadomości. Rozmiar ładunku każdego zdania jest ograniczony przez maksymalnie 82 znaki NMEA 0183, więc czasami wymagane jest podzielenie ładunku danych na kilka zdań fragmentarycznych.

Pole 3 (1 w tym przykładzie) to numer fragmentu tego zdania. Będzie to oparte na jednym. Zdanie o liczbie fragmentów 1 i liczbie fragmentów 1 jest kompletne samo w sobie.

Pole 4 (puste w tym przykładzie) to sekwencyjny identyfikator wiadomości dla wiadomości składających się z wielu zdań.

Pole 5 (B w tym przykładzie) to kod kanału radiowego. AIS wykorzystuje górną stronę dupleksu z dwóch kanałów radiowych VHF: Kanał AIS A wynosi 161,975 MHz (87B); Kanał B AIS to 162,025 MHz (88B). Na wolności można również spotkać kody kanałów 1 i 2; standardy nie określają ich interpretacji, ale jest to dość oczywiste ...

Pole 6 (177KQJ5000G? TO`K> RA1wUbN0TKH w tym przykładzie) to ładunek danych. W dalszej części opiszemy, jak to rozszyfrować.

Pole 7 (0) to liczba bitów wypełniania wymaganych do uzupełnienia ładunku danych do granicy 6 bitów, w zakresie od 0 do 5. Równolegle, odjęcie 5 od tego mówi, ile najmniej znaczących bitów ostatniego 6-bitowego skrawka w ładunek danych należy zignorować. Należy zauważyć, że ten bajt pada ma trudną interakcję z wymogiem <[ITU-1371]> dotyczącym wyrównania bajtów w komunikatach AIS bezprzewodowych; zobacz szczegółowe omówienie długości wiadomości i wyrównania w dalszej części.

* -Separowany przyrostek ( 5C) to suma kontrolna integralności danych NMEA 0183 dla zdania, poprzedzona znakiem „ ”. Jest on obliczany dla całego zdania, łącznie ze znacznikiem AIVDM, ale z wyłączeniem wiodącego „!”.

Co więcej, ważną częścią tutaj jest pole 6, więc jeśli przejrzysz trochę więcej strony, otrzymasz odpowiedź: ten ładunek danych pola 6 zawiera tonę (nie, naprawdę tonę!) Różnych pól w niej zawartych. Możesz więc napisać własny kod, aby go przeanalizować lub alternatywnie użyć repozytorium github zamieszczonego w innej odpowiedzi, która zawiera różne zestawy SDK / API, które prawdopodobnie powinny mieć to, czego potrzebujesz (w zależności od tego, skąd masz dane AIS): https: / /github.com/bcl/aisparser

GISD
źródło