Home |
Search |
Today's Posts |
#1
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
Hi all, I am a navigation software developer from Italy.
I need to understand how to read AIS data inside the "blob" contained in VDO NMEA sentece. I have the ITU-R M.1371-1 document that should let me understand such format. Unfortunately I really cannot understand how to read the bits. Someone, some times ago, posted such message: The AIS sentences are in a strange format, encapsulated 6 bits. One example he '!AIVDO,1,1,,,13:r`R5P1orpG60JeHgRSj4l0000,0*56 ' 0 1 2 34 5 6 '1 Total number of sentences needed to transfer the message, 1 to 9 '2 Message sentence number, 1 to 9 '3 Sequential message identifier, 0 to 9 '4 AIS channel number '5 Encapsulateled 6-bit radio message '6 Number of fill-bits, 0 to 5 '14eG=ch021rp4FTJdTGRRR0605q4 'VDO.Identifier : 1 000001 'Repeat indicator : 0 00 'MMSI : 316001711 010010110101011100110110101111 'VDO1.NavStatus : 0 0000 'VDO1.ROT : 0 00000000 'VDO1.SOG : 12.9 kns 0010000001 'VDO1.PosAcc : 1 1 'VDO1.Latitude : 46º 39.3182'N 1101011100000010001011010010 'VDO1.Longitude : 71º 38.2703'W 0011010101100100100010111100010100010100 'VDO1.COG : 065º 010000000000 'VDO1.Heading : 064º 110000000 'VDO1.TimeStamp : 3 sec. 000101 'VDO1.NavStatus : 0 1 'VDO1.CommStatus : 15:17 h 11001000100 I really cannot understand how he found such information inside 14eG=ch021rp4FTJdTGRRR0605q4. Please Help Ciao Cristiano |
#2
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
|
#4
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
Pascal wrote:
See this site: http://www.navicon.dk/web/normal.php?pageid=95 escreveu: Hi all, I am a navigation software developer from Italy. I need to understand how to read AIS data inside the "blob" contained in VDO NMEA sentece. I have the ITU-R M.1371-1 document that should let me understand such format. Unfortunately I really cannot understand how to read the bits. Someone, some times ago, posted such message: The AIS sentences are in a strange format, encapsulated 6 bits. One example he '!AIVDO,1,1,,,13:r`R5P1orpG60JeHgRSj4l0000,0* 56 ' 0 1 2 34 5 6 '1 Total number of sentences needed to transfer the message, 1 to 9 '2 Message sentence number, 1 to 9 '3 Sequential message identifier, 0 to 9 '4 AIS channel number '5 Encapsulateled 6-bit radio message '6 Number of fill-bits, 0 to 5 '14eG=ch021rp4FTJdTGRRR0605q4 'VDO.Identifier : 1 000001 'Repeat indicator : 0 00 'MMSI : 316001711 010010110101011100110110101111 'VDO1.NavStatus : 0 0000 'VDO1.ROT : 0 00000000 'VDO1.SOG : 12.9 kns 0010000001 'VDO1.PosAcc : 1 1 'VDO1.Latitude : 46º 39.3182'N 1101011100000010001011010010 'VDO1.Longitude : 71º 38.2703'W 0011010101100100100010111100010100010100 'VDO1.COG : 065º 010000000000 'VDO1.Heading : 064º 110000000 'VDO1.TimeStamp : 3 sec. 000101 'VDO1.NavStatus : 0 1 'VDO1.CommStatus : 15:17 h 11001000100 I really cannot understand how he found such information inside 14eG=ch021rp4FTJdTGRRR0605q4. Please Help Ciao Cristiano Disassembling message protocols is tedious by hand. Automated equipment does it with logic circuitry, which accomplishes tedious tasks easily and knows the secret code. We humans must parse manually. The data is actually send as a bitstream and the protocol for every device is proprietary. The data presented above is actually encoded as hexadecimal or ascii encode binary characters, so it actually looks more like 11110110010110101010101010101101100110011010101010 1010111010101..., etc. These bits are sent as analogue levels, data encoded in one long serial string. 100 character might be 800 bits, or 1600 bits, in number base 10 notation. It might use another numerical base, likely octal or hexadecimal. The ports have their own protocols, and take each byte of 7 or 8 bits (as one example, I am not certain what this one actually uses, perhaps 16 bit bytes) as a character. Each group of bits represents one character in the string given above. The alphabet used by the system may have many more than the 26 in our human alphabet, and some of those characters are specific to the device in use. The spacing and syntax is combined with error correcting parity (even - odd) codes and checksum numbers which must also be decoded in logic if you are writing an interface. Each receiving device must be up to date with whatever protocol is used by all of the transmitters if it is not to become discombobulated and confused, losing track of character boundaries, etc, and those protocols seem to change with each new generation of devices. Different portions of the data string may use different schemes, ie, the first 6 bits might be all ones, as a preamble and sync. The next 4 bits might be a code to identify the remainder as a specific type of statement, ie, sender I.D. Sometimes the info is bitsliced, so that each bit represents a switch setting in the receiving parser to cause it to understand that it is radar, weather, whatever. I once independantly decoded the data sent by telco in it's caller id string, sent between the ring tones to your phone. There are padding bits, a preamble, and then each character is sent twice. It was painful for a while, as I had to scope out the data without benefit of knowing the protocol, even as simple as it was, using a capture buffer to read each character out in ascii values, a sofware protocol analyzer I wrote myself, which spit out gibberish ascii codes until I learned to read it. If it had not been straight ascii, normal in telephone modems, I would still be propping up my eyelids with toothpicks. You seem to have a protocol guide or data map, which you must now come to know imtimately. Reverse engineering software data is fun for some masochists, for a while. 400 page logic diagrams is where I cut my teeth, back in the 60's. It's one way to burn out your brain so far as computers is concerned. I got fed up with them, and retired years ago. Wouldn't touch it, now, without cash up front and a clearly defined mission statement engraved in titanium. Good luck. Terry K -SofDevCo- |
#5
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
Terry, you're making this sound alot more complicated than it really
is. The 6-bit encoded part of a VDM sentence is simply a bitstream, packed using a special code. Each character represents 6 bits of data from 0x00 ot 0x3F. It starts with the message ID (6 bits), repeat (2 bits), MMSI (30 bits), etc. This is all defined in m.1371 and 61993-2, even if it is a bit confusing at first. The first 6 bits being a character and the message ID make it easy to tell that the example string above is a message 1. |
#6
|
|||
|
|||
Quote:
Hi guys, I'm actually working on a similar project right now except I have to do the ENCODE part of the VDM message. At first I thought every character represents 6-bit but that is not true. As you can see in the message there are lowered case alphabet characters (i.e. 'e') and the ascii value for 'e' is more than 6-bits. I'm a little stuck on my project right now too, can someone give me more info. Perhaps an example in C or C++. Thanks. |
#7
posted to rec.boats.electronics
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
"tcdang714" wrote in message ... Wrote: Terry, you're making this sound alot more complicated than it really is. The 6-bit encoded part of a VDM sentence is simply a bitstream, packed using a special code. Each character represents 6 bits of data from 0x00 ot 0x3F. It starts with the message ID (6 bits), repeat (2 bits), MMSI (30 bits), etc. This is all defined in m.1371 and 61993-2, even if it is a bit confusing at first. The first 6 bits being a character and the message ID make it easy to tell that the example string above is a message 1. Hi guys, I'm actually working on a similar project right now except I have to do the ENCODE part of the VDM message. At first I thought every character represents 6-bit but that is not true. As you can see in the message there are lowered case alphabet characters (i.e. 'e') and the ascii value for 'e' is more than 6-bits. I'm a little stuck on my project right now too, can someone give me more info. Perhaps an example in C or C++. Thanks. -- tcdang714 I realize that you've asked about *encoding*, but here's an example of a decoder written in visual basic, from a program I wrote for my pocket PC. Perhaps you will be able to reverse-engineer something from this. ------------------ Function AsciiToHex6(AsciiIn) AsciiToHex6 = A2H6(Asc(AsciiIn)) End Function Dim A2H6(128) Sub InitA2H6 Dim i, h For i = 0 To 127 h = i If i 48 Then h = -1 ElseIf i 88 Then h = h - 48 ElseIf i 119 Then h = -1 ElseIf i 96 Then h = -1 Else h = h - 56 End If A2H6(i) = h Next End Sub InitA2H6 ------------------ The array A2H6() contains the hex6 value of the ascii input character, using the character as an index. I put "-1" in the illegal positions, and ought to do a little more defensive error-checking (but I probably won't ever get around to it). The function AsciiToHex6(AsciiIn) just looks up the code and returns it. The IEC documents that describe the messages and coding aren't free, but while I was googling around I did find this one: http://www.gicoms.go.kr/knowledge/download.asp?filename=IEC%20standard%2061993(class %20A%20AIS).pdf&filepath=D:%5CGICOMS_FILE%5Cupdown %5CIEC%20standard%2061993(class%20A%20AIS).pdf This contains a decent description of the 6-bit ascii encoding, as well as the message structure. Note that the AIS data elements are not necessarily six-bits long, so there will be an arbitrary alignment of the various parameters across the 6-bit-ascii character stream. Also, some of the AIS messages are longer than allowed in the NMEA sentence, so the messages have to be split into multiple NMEA sentence. I can post my code for decoding the arbitrary data if you think it would be instructive. Be aware that some of the earlier discussions of 6-bit ascii encoding for AIS show a different encoding (don't ask me how long I struggled with that issue!). The one in my code sample, and the document above seem to be the encoding actually used. Good Luck, Paul |
#8
posted to rec.boats.electronics
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
I too have been struggling with this.
I convert every 6 bits to a byte and convert to the approriate 8 bit ascii character. It all works for message type 1. So, I thought I'd look at message type 5, which is id 6 bits repeat 2 user id 30 version 2 imo 30 call sign 42 name 120 It works up until imo, then for the call sign I get gibberish. It seems characters don't like my approach ... Does anyone have any code or suggestions? Thanks |
#9
posted to rec.boats.electronics
|
|||
|
|||
how to read AIS data from encapsulated NMEA VDO sentence
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) |
#10
posted to rec.boats.electronics
|
|||
|
|||
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 |