View Single Post
  #10   Report Post  
posted to rec.boats.electronics
Paul
 
Posts: n/a
Default how to read AIS data from encapsulated NMEA VDO sentence


wrote in message
oups.com...
Actually, I re-read what I posted and it didn't really make sense.

1. Start with the array of ascii characters
2. Convert to the 6 bit binary value.
3. Convert this byte array to a 6 bit bitstream.
4. Then just pull out the bits yuo want using the various bit
operators. I tried to use a bit-field, but it didn't seem to work in
Windows.

As I said, it all works until I get to character arrays (call sign etc)


Here is a portion of the code i wrote to handle message type 5 (I'm only
handling the "Ship Static and Voyage Related Data
" variant for now). My comments follow the code. Pay attention to my
function H6StrToAsc, and how I manipulate the ascii.

-----------------
Case "5"
MMSI = H6StrToInt(AISString, 9, 38)
ndx = FindAISRecord(MMSI)
If ndx 0 Then Exit Sub 'not found and no room for new record --
discard report! (need to announce)

temp = H6StrToInt(AISString, 39, 40)
Select Case temp
Case 0 'Ship Static and Voyage Related Data
IMO = H6StrToInt(AISString, 41, 70)
ShipTypeStr = ShipType(H6StrToInt(AISString, 233, 240))
EtaMin = H6StrToInt(AISString, 289, 294)
EtaHour= H6StrToInt(AISString, 284, 288)
EtaDay = H6StrToInt(AISString, 279, 283)
EtaMonth= H6StrToInt(AISString, 275, 278)
Draft = H6StrToInt(AISString, 295, 302) / 10
Callsign = H6StrToAsc(AISString, 7, 71)
ShipName = H6StrToAsc(AISString, 20, 113)
Destination = H6StrToAsc(AISString, 20, 303)

Call CleanAt(Callsign) 'need to strip off any trailing '@'
characters some ships have
Call CleanAt(ShipName)
Call CleanAt(Destination)

AISArray(ndx, 0) = MMSI
AISArray(ndx, 15) = ShipName
AISArray(ndx, 16) = Callsign
AISArray(ndx, 17) = Destination
AISArray(ndx, 8) = CStr(EtaMonth) & ":" & CStr(EtaDay) & ":"
& CStr(EtaHour) & ":" & CStr(EtaMin)
AISArray(ndx, 11) = 0 '"Length val"
AISArray(ndx, 13) = Draft
AISArray(ndx, 14) = ShipTypeStr
AISArray(ndx, 18) = vbBLACK 'Plot Color

If AISArray(ndx, 29) = 1 Then Call DoAISLog(ndx) 'first time
a complete record
AISArray(ndx, 29) = AISArray(ndx, 29) Or 2
Call UpdateAISDisplayListElement(ndx)

Case 1 'Extended Ship Static and Voyage Related Data
ErrorReport("Extended Ship Static And Voyage Related Data: "
& AISString)

Case 2 'Aids to Navigation Data
ErrorReport("Aids to Navigation Data: " & AISString)

Case 3 'Regional Ship Static and Voyage Related Data
ErrorReport("Regional Ship Static and Voyage Related Data: "
& AISString)

End Select
-----------------
Sub CleanAt(str) 'used to strip off any trailing '@' characters some ships
leave in their strings
str = Left(str, InStr(str, "@")-1)
End Sub

-----------------
Function H6StrToAsc(str, characters, MSbit)
Dim tempstr, tempchar
Dim i
For i = 1 To characters
tempchar = H6StrToInt(str, MSbit, MSbit + 5)
If tempchar 32 Then tempchar = tempchar + 64
tempstr = tempstr & Chr(Tempchar)
MSbit = MSbit + 7
Next
H6StrToAsc = tempstr
End Function
-----------------

I decided to not convert the raw NMEA ascii string into an intermediate
form, but rather suck the bits out of the string as I need them. My
function H6StrToInt(AISString, starting_bit_position, ending_bit_position)
returns a the value of a particular bit-field.

The function H6StrToAsc(str, characters, MSbit) reads the encoded characters
from the NMEA ascii string, converting them from bits to numbers to
characters. I test the characters (char 32) and map those that are
between 0 and 31 (decimal) to the ascii characters between 64 and 95. I
don't remember exactly how I arrived at this manipulation, but I am pretty
sure I had to just look at the data and figure it out. There is a nice
application on the web that decodes some of the simple AIS strings, and I
probably used that to test my own decoding. Here is the URL:
http://rl.se/aivdm

Once you've got the decoder working, you can use the ITU "Search for Ship
Particulars" website to find out more about a specific ship, given it's
callsign or MMSI or name:
http://www.itu.int/cgi-bin/htsh/mars/ship_search.sh

Back to my code -- I just re-learned BASIC to do this application, after not
using it for over 30 years. I'm sure that my style is horrible, but I doubt
that I will attempt to improve it.

Oh yeah, in my code AISArray is where I keep the AIS records. I don't
remember why I used the intermediate variables instead of storing the data
directly in the array -- this is probably just how the code evolved and I
didn't want to go back and clean it up.

Good Luck!
-Paul