Class: NMEAPlus::Message::AIS::VDM

Inherits:
AISMessage show all
Defined in:
lib/nmea_plus/message/ais/vdm.rb

Overview

VDM - Vessel Data Message This message type thinly wraps AIS payloads.

Direct Known Subclasses

VDO

Instance Attribute Summary collapse

Attributes inherited from AISMessage

#message_type, #talker

Attributes inherited from Base

#checksum, #data_type, #fields, #interpreted_data_type, #message_number, #next_part, #original, #payload, #prefix, #total_messages

Instance Method Summary collapse

Methods inherited from Base

_float, _hex_to_integer, #_highest_contiguous_index, _integer, _interval_hms, _string, _utc_date_time, _utctime_hms, #add_message_part, #all_checksums_ok?, #all_messages_received?, #calculated_checksum, #checksum_ok?, degrees_minutes_to_decimal, field_reader, #highest_contiguous_index, nsew_signed_float

Instance Attribute Details

#aisVDMPayload::VDMMsg (readonly)

factory method: find the appropriate class for this AIS message type and instantiate it

Returns:



62
63
64
65
66
67
68
# File 'lib/nmea_plus/message/ais/vdm.rb', line 62

def ais
  p = full_dearmored_ais_payload
  ret = _payload_container(p[0, 6].to_i(2))
  ret.payload_bitstring = p
  ret.fill_bits = last_ais_fill_bits
  ret
end

#full_armored_ais_payloadString (readonly)

the full encoded payload as it was received – spanning multiple messages

Returns:

  • (String)


73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/nmea_plus/message/ais/vdm.rb', line 73

def full_armored_ais_payload
  # get the full message and fill bits for the last one
  ptr = self
  ret = ""
  loop do
    break if ptr.raw_ais_payload.nil?  # guard against rare instances of message corruption
    ret << ptr.raw_ais_payload
    break if ptr.next_part.nil?        # stop when we run out of messages in the chain
    ptr = ptr.next_part
  end
  ret
end

#full_dearmored_ais_payloadString (readonly)

a binary string (“0010101110110”) representing the dearmored payload

Returns:

  • (String)


89
90
91
92
93
94
95
96
# File 'lib/nmea_plus/message/ais/vdm.rb', line 89

def full_dearmored_ais_payload
  data = full_armored_ais_payload
  out = ""
  # dearmor all but the last byte, then apply the fill bits to the last byte
  data[0..-2].each_char { |c| out << _dearmor6b(c) }
  out << _dearmor6b(data[-1], 6 - last_ais_fill_bits)
  out
end

#last_ais_fill_bitsInteger (readonly)

Get the fill bits for the last message in the sequence – the only one that matters

Returns:

  • (Integer)


101
102
103
104
105
106
107
108
109
110
# File 'lib/nmea_plus/message/ais/vdm.rb', line 101

def last_ais_fill_bits
  ptr = self
  fill_bits = nil
  loop do
    fill_bits = ptr.ais_payload_fill_bits
    break if ptr.next_part.nil?
    ptr = ptr.next_part
  end
  fill_bits.to_i
end

Instance Method Details

#_dearmor6b(c, len = 6) ⇒ String

perform the 6-bit to 8-bit conversion defined in the spec

Parameters:

  • c (String)

    a character

  • len (Integer) (defaults to: 6)

    The number of bits to consider

Returns:

  • (String)

    a binary encoded string



116
117
118
119
120
# File 'lib/nmea_plus/message/ais/vdm.rb', line 116

def _dearmor6b(c, len = 6)
  val = c.ord
  ret = val - (val >= 96 ? 56 : 48)  # Mapped to 2 separate contiguous blocks of ascii, so choose which
  ret.to_s(2).rjust(6, "0")[0..(len - 1)]
end

#_payload_container(message_type_id) ⇒ NMEAPlus::Message::AIS::VDMPayload::VDMMsg

Find an appropriate payload container for the payload type, based on its stated message ID

Parameters:

  • message_type_id (String)

Returns:



125
126
127
128
129
130
131
# File 'lib/nmea_plus/message/ais/vdm.rb', line 125

def _payload_container(message_type_id)
  class_identifier = "NMEAPlus::Message::AIS::VDMPayload::VDMMsg#{message_type_id}"
  Object::const_get(class_identifier).new
rescue ::NameError
  class_identifier = "NMEAPlus::Message::AIS::VDMPayload::VDMMsgUndefined" # generic
  Object::const_get(class_identifier).new
end