Forum: WHALER
  ContinuousWave
  Whaler
  Moderated Discussion Areas
  ContinuousWave: Small Boat Electrical
  Decoding AIS Messages

Post New Topic  Post Reply
search | FAQ | profile | register | author help

Author Topic:   Decoding AIS Messages
jimh posted 12-29-2011 10:35 AM ET (US)   Profile for jimh   Send Email to jimh  
Being technically curious, I have been looking into the method used to encode and decode data sent in AIS messages. There is a wonderful resource that explains the method that is available from:

http://gpsd.berlios.de/AIVDM.html

Using that information as a guide, I set about to decode a random AIS message I had received. Here is the raw AIS message:

!AIVDM,1,1,,A,15O86n001TJ3KutH8ar@<h;l06Hh,0*5D

The message is not particularly human-readable, and it must be carefully decoded to extract the data. Here is my attempt to decode, which will by example demonstrate the method.

The message has seven fields. The first five fields are easily decoded by simple inspection. The sixth field is the data payload and requires rather complicated decoding: Using my sample message as an example, we find:

FIELD     DATA      INTERPRETATION
1 !AIVDM Identifier for AIVDM packet
2 1 Count of fragments in current message; One fragment, i.e., the message is complete in this fragment.
3 1 The fragment number of this fragment; this is the first fragment of the message.
4 (empty) Sequential message ID for multi-sentence messages.
5 A The radio channel; A means 161.975-MHz; B means 162.025-MHz
6 15O86n001TJ3KutH8ar@<h;l06Hh The data payload; see below.
7 0*5D The number of fill bits needed to pad the data payload; see below

With fairly simple inspection we know this is an AIS message, it is in one fragment, this is the first fragment, it is not part of a longer message sequence, and it was sent on radio channel 161.975-MHz. Now for the hard part: decoding the data paylod.

Decoding the data payload

The data payload is a complicated encoding of information into ASCII strings. Each ASCII character represents six bits of data. We explain by example. Consider the first ASCII character in the payload, "1":

ASCII character "1" is ASCII value 49. To recover the data payload we subtract 48 from this value. If the result is greater than 40, subtract 8.

49 - 48 = 1

Our data payload is decimal 1. Decimal 1 is a six-bit binary number 000001.

The first six bits of our data payload are 000001. They are the message type. A message type of "000001" decodes to "Position Report Class A."

The next ASCII character is "5". This decodes to "110101"
Continuing this process we have a payload table as follows
(See Table 1 in reference linked above)

ASCII   BINARY PAYLOAD
1 000001
5 000101
O 011111
8 001000
6 000110
n 110110
0 000000
0 000000
1 000001
T 100100
J 011010
3 000011
K 011011
u 111101
t 111100
8 001000
a 101001
r 111010
@ 010000
< 001100
h 110000
; 001011
l 110100
0 000000
6 000110
H 011000
h 110000

Now we concatenate all the decoded payloads into one long message string. This string is then decoded as follows

BIT POSITION  DATA             OUR DATA     MEANING
0-5 Message Type 000001 Position Report Class A

Now we can decode the data that follows according to the format for Position Report Class A, which is:

6-7          Repeat Indicator 00    

8-37 MMSI 010101111100100000011011011000

The data in position 8 through 37 represents the unsigned binary number which is the binary equivalent of a 9-digit decimal number--the vessel MMSI:

1     5     O     8     6     n     0     0     1         RAW DATA
00000100010101111100010000001101101100000000000000 EXTRACT 6-BIT CODING
010101111100100000011011011000 EXTRACT 8 to 37
01234567890123456789012345678901234567890123456789
1 2 3 4

--------010101111100100000011011011000---> 368183000 CONVERT TO DECIMAL

The MMSI of the vessel sending this packet is 368183000.

Field 38 through 41 (four bits) encodes the Navigation status as an enumerated type. With four bits there are 16 enumerated types. Our message payload is

1     5     O     8     6     n     0     0     1         RAW DATA
00000100010101111100010000001101101100000000000000 EXTRACT 6-BIT CODING
0000 EXTRACT 38 to 41
01234567890123456789012345678901234567890123456789
1 2 3 4

which interprets to "Underway using engine."

Field 42 through 49 are eight bits which encode the Rate of Turn.

1     5     O     8     6     n     0     0     1         RAW DATA
00000100010101111100010000001101101100000000000000 EXTRACT 6-BIT CODING
00000000 EXTRACT 42 to 49
01234567890123456789012345678901234567890123456789
1 2 3 4

The data payload for Rate of Turn in this case is 00000000 or "not turning."

Now we get more of the data payload for the next encoded data.

1     T     J     3     K     u     t     8     a     r          RAW DATA                   
000001100100011010000011011011111101111100001000101001111101 6-BIT CODING
890123456789012345678901234567890123456789012345678901234567890
5 6 7 8 9 0 1
1 1

Field 50 to 59 encode the Speed Over Ground. Our data payload is

0001100100

which is a binary number that converts to decimal 100. Speed is given to the tenth of a knot, so the vessel speed is 10.0-knots.

jimh posted 12-29-2011 11:01 AM ET (US)     Profile for jimh  Send Email to jimh     
So far I have been able to successfully decode the data from the message, but on the longitude field, I have been stumped. I need some help.


Field 60 encodes the position accuracy with a single bit. Our value is 0, which means an un-augmented GNSS fix. A value of 1 is used for DGPS quality fix, better than 10-meter accuracy.

Field 61 through 88 encodes the longitude.

1     T     J     3     K     u     t     8     a     r                          
1101000001101101111110111110
890123456789012345678901234567890123456789012345678901234567890
5 6 7 8 9 0 1
1 1

The data payload is 1101000001101101111110111110.

"Numeric bitfields are interpreted as big-endian two's-complement integers; when signed, the sign bit is the highest."

The first bit is the sign: 0 means positive and 1 means negative. This is a negative number, hence a longitude west of the prime meridian. The value of the negative number is

101000001101101111110111110

We decode this as 84336574. Is that correct?

The data "84336574" is supposed to represent the longitude in units of 0.0001-minutes. The actual longitude being transmitted is 083.135250-West. I know this because I used an automated decoder to process the message.

The longitude 083.135250 would be converted to the necessary units as follows:

083.135250-degrees x 60-minutes/1-degree = 4988.115-minutes

4988.115-minutes x (10,000) =49,881,150--10,000ths of a minute

and this implies the AIS ought to be transmitting a number "49881150"

I cannot figure out where I have gone off the tracks here. There are three possibilities:

--I extracted the wrong binary data from the payload;

--I converted the binary payload data to decimal incorrectly; or,

--I converted to the decimal data to longitude incorrectly.

I seek some assistance here. Perhaps someone can check my steps with the longitude data and discover the error. I suspect it is likely in the conversion of the binary data to decimal. See the linked reference for more details about the representation of signed numbers in binary. Thanks for any light you can shine on this for me.


jimh posted 12-29-2011 11:26 AM ET (US)     Profile for jimh  Send Email to jimh     
I found a very handy on-line binary<-->decimal converter at

http://www.binaryconvert.com/

Using this device, I convert my decoded payload binary to decimal as follows:

BINARY = 101000001101101111110111110

DECIMAL = 84336574

That is the same number I got, so my conversion must be correct. This means the error must be in:

--bad decoding of data payload to binary

--bad conversion of decimal to longitude

Again, I seek some assistance, as I have checked those steps myself already.

David Pendleton posted 12-29-2011 11:57 AM ET (US)     Profile for David Pendleton    
Using two's complement arithmetic, the number being represented is actually -49881154.


jimh posted 12-29-2011 12:10 PM ET (US)     Profile for jimh  Send Email to jimh     
Let's try Dave's number:

-49881154

As a negative, this means West longitude. The number represents the number of 10,000th-of-a-minute. It is also sent as an integer and needs to scaled to four decimal places, thus

4988.1154 minutes

Divide by 60 to get degrees:

4988.1154 / 60 =83.135256666666667-degrees

PERFECT!

The indicated position was supposed to be

083.135250-West

and this value (-49881154) decodes to

083.135256-West

The difference appears to be due to truncating instead of rounding. Perhaps that is an error in the other convertor.

Now, Dave, please explain to me the method you used to decode

101000001101101111110111110

into -49881154. I don't quite understand the two's-complement aspect you mention.

jimh posted 12-29-2011 12:23 PM ET (US)     Profile for jimh  Send Email to jimh     
Wait--I have it:

The method is as follows:

Take the decoded binary number from the AIS payload, strip off the first bit as a sign, then take the remaining bits as an unsigned integer that is the two's complement of the actual number. Convert the original data to its two's complement.

The first bit of the payload was a "1" hence a negative number. The remaining payload becomes:

101000001101101111110111110

We apply the method:

101000001101101111110111110------original data
010111110010010000001000001------one's complement
010111110010010000001000010------add one to get two's complement

Now we convert the new binary number to decimal as an unsigned integer:

010111110010010000001000010 --> 49881154

David Pendleton posted 12-29-2011 01:11 PM ET (US)     Profile for David Pendleton    
Yes, that's it.

There are 11 types of people that understand binary, those that do and those that do not. :)

David Pendleton posted 12-29-2011 01:13 PM ET (US)     Profile for David Pendleton    
And leave it to me to screw up a bad pun...
jimh posted 12-29-2011 01:56 PM ET (US)     Profile for jimh  Send Email to jimh     
There are two secrets to success: the first, don't share everything you know.
jimh posted 12-29-2011 02:55 PM ET (US)     Profile for jimh  Send Email to jimh     
ASIDE:

I tried entering the decoded binary in the convertor (linked above) but it never produced the right decimal. I think that was because the convertor need me to pad out the number to 32-bits. If I took my original data, padded the most-significant bits with "1" to fill out to 32-bits, the convertor worked correctly.

See

http://www.binaryconvert.com/result_signed_int.html?hexadecimal=FD06DFBE

I believe this is called "sign extension," as discussed at

http://en.wikipedia.org/wiki/Sign_extension

The original number was 28-bits. The convertor wanted a 32-bit number, so it needed to be padded with "1' on the MSB side to 32 bits. Confusing stuff, this binary arithmetic.

ASIDE: re Dave's joke, see

http://en.wikipedia.org/wiki/Mathematical_joke#Jokes_with_numeral_bases

jimh posted 12-29-2011 03:24 PM ET (US)     Profile for jimh  Send Email to jimh     
Well, now that I have demonstrated the method, we'll leave decoding of the latitude as an exercise for the reader. That's about all I remember from my last text in mathematics.

Post New Topic  Post Reply
Hop to:


Contact Us | RETURN to ContinuousWave Top Page

Powered by: Ultimate Bulletin Board, Freeware Version 2000
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.