schwehr / libais

C++ decoder for Automatic Identification System for tracking ships and decoding maritime information
Other
215 stars 94 forks source link

Question, what is the SECOND argument in ais.decode() #208

Open bbookman opened 3 years ago

bbookman commented 3 years ago

Sorry if this is obvious for those well versed in ais . . . What do the 0 and 2 represent below?

ais.decode('402u=TiuaA000r5UJH4?7000S:', 0) ais.decode('55NBjP01mtGIL@CW;SM<D60P5Ld000000000000P0<3557l0<50@kk@K5h@00000000000', 2)`

LordKobra commented 3 years ago

IIRC it does represent the padding of the message. Type 1,2,3 Messages are 168 bit long. Because of the encoding, 6 bit are encoded into one char. You will get exactly 28 characters and have 0 bit padding.

The description says: You have to handle multi-line messages and padding yourself.

brucebookman commented 3 years ago

"The description says: You have to handle multi-line messages and padding yourself."

Do you happen to have code that does this? I'm not super familiar with the concept of padding.

I am currently working on code that can put together the encoded strings of a multiline message. Knowing NOTHING, I guessed the second argument there would be a 0 for single line messages and a 2 or 3 for multi line - depending on the number of lines.

However, reading your response, I'm wrong.

I have invested a ton of time in leveraging this library even though it isn't getting active work. I'm hoping not to have to rip and replace.

Any ideas or suggestions on handing multi-line. Answer like I was 5 years old :p

LordKobra commented 3 years ago

First of all, if you read from a NMEA-stream, you can try out the high-level iterator interface shown in the description.

Normally, the first parts of the multiline-messages have 0 bit padding (to use all the available space) and the padding of the last part can be extracted from the NMEA message. "!AIVDM,1,1,,B,181:Kjh01ewHFRPDK1s3IRcn06sd,0*08" it's the number between ',' and '*', in this case a '0'

Sorry, i have no working code right now, but here are some resources on the message structure: https://en.wikipedia.org/wiki/Automatic_identification_system#Messages_sent_to_other_equipment_in_the_ship https://gpsd.gitlab.io/gpsd/AIVDM.html gpsd does have it's own decoder for linux, called gpsdecode. If you can't get this library to work, you might take a look at it.

bjornasm commented 3 years ago

Thank you for answering, hoping that this can be mentioned explicitly as it is pretty vague that AIS messages contain information regarding the padding and that it is this padding the second argument in the function represents. Documenting all the input variables in function should be pretty standard.

Shal-Ziar commented 2 years ago

This ais library requires you to first check if the message is part of a two-part message, I've listed part of my implementation below:

 s = msg.split(",")
  # Check if it has the correct length
  if not len(s) == 7:
      return False

  # variables to keep track of the type of AIS message
  msg_size = int(s[1])
  msg_part = int(s[2])

  # Check if it is a multiline message
  try:
      # One line AIS messages
      if msg_size == 1:
          # clear old message since it is a new call
          self.ais_decode = ais.decode(s[5], 0)
          return True

      # Two line AIS messages
      elif msg_size == 2:
          if msg_part == 1:
              self.buffer = ""
              self.ais_decode = {}
              self.buffer = s[5]
              return False
          else:
              self.buffer += s[5]
              self.ais_decode = ais.decode(self.buffer, 2)
              return True
brucebookman commented 2 years ago

I was able to use code that does concatenate the group tags. Further, I replaced this library with another as there were other issues with this specific library. I'm now able to decode the group messages