Class: NMEAPlus::Message::AIS::VDMPayload::VDMMsg

Inherits:
Object
  • Object
show all
Defined in:
lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb

Overview

The base class for the AIS payload (of NMEAPlus::Message::AIS::VDM) which can be of many types.

Direct Known Subclasses

VDMMsg5, VDMMsg8, VDMMsgCNB, VDMMsgUndefined

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fill_bitsInteger

Returns The number of padding characters required to bring the payload to a 6 bit boundary.

Returns:

  • (Integer)

    The number of padding characters required to bring the payload to a 6 bit boundary



15
16
17
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 15

def fill_bits
  @fill_bits
end

#message_typeObject (readonly)

Returns The field defined by 6 bits starting at bit 0 of the payload, formatted with the function #_u().

Returns:

  • The field defined by 6 bits starting at bit 0 of the payload, formatted with the function #_u()



34
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 34

payload_reader :message_type, 0, 6, :_u

#payload_bitstringString

Returns The raw “armored payload” in the original message.

Returns:

  • (String)

    The raw “armored payload” in the original message



12
13
14
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 12

def payload_bitstring
  @payload_bitstring
end

#repeat_indicatorObject (readonly)

Returns The field defined by 2 bits starting at bit 6 of the payload, formatted with the function #_u().

Returns:

  • The field defined by 2 bits starting at bit 6 of the payload, formatted with the function #_u()



35
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 35

payload_reader :repeat_indicator, 6, 2, :_u

#source_mmsiObject (readonly)

Returns The field defined by 30 bits starting at bit 8 of the payload, formatted with the function #_u().

Returns:

  • The field defined by 30 bits starting at bit 8 of the payload, formatted with the function #_u()



36
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 36

payload_reader :source_mmsi, 8, 30, :_u

Class Method Details

.payload_reader(name, start_bit, length, formatter, formatter_arg = nil) ⇒ Object

make our own shortcut syntax for payload attributes

Parameters:

  • name (String)

    What the accessor will be called

  • start_bit (Integer)

    The index of first bit of this field in the payload

  • length (Integer)

    The number of bits in this field

  • formatter (Symbol)

    The symbol for the formatting function to apply to the field (optional)

  • formatter_arg (defaults to: nil)

    Any argument necessary for the formatting function



26
27
28
29
30
31
32
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 26

def self.payload_reader(name, start_bit, length, formatter, formatter_arg = nil)
  if formatter_arg.nil?
    self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length});end")
  else
    self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length}, #{formatter_arg});end")
  end
end

Instance Method Details

#_2b_data_string(start, length) ⇒ String Also known as: _d

Return a string representing binary

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (String)

    e.g. “0101010101011000”



145
146
147
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 145

def _2b_data_string(start, length)
  _access(start, length)
end

#_6b_ascii(ord) ⇒ String

Convert 6-bit ascii to a character, according to catb.org/gpsd/AIVDM.html#_ais_payload_data_types

Parameters:

  • ord (Integer)

    The 6-bit ascii code

Returns:

  • (String)

    the character for that code



41
42
43
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 41

def _6b_ascii(ord)
  '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !"#$%&\'()*+,-./0123456789:;<=>?'[ord]
end

#_6b_boolean(start, _) ⇒ bool Also known as: _b

Get the value of a bit in the payload

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • _ (Integer)

    Doesn’t matter. Here so signatures match; we hard-code 1 because it’s 1 bit.

Returns:

  • (bool)


137
138
139
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 137

def _6b_boolean(start, _)
  _access(start, 1) { |bits| bits.to_i == 1 }
end

#_6b_integer(start, length) ⇒ Integer Also known as: _i

Returns an integer value.

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (Integer)

    an integer value



109
110
111
112
113
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 109

def _6b_integer(start, length)
  # MSB is 1 for negative
  twoc = _6b_twoscomplement(start, length)
  twoc && twoc * (@payload_bitstring[start] == 0 ? 1 : -1)
end

#_6b_integer_scaled(start, length, decimal_places) ⇒ Integer Also known as: _I

scale an integer by dividing it by 10^decimal_places

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

  • decimal_places (Integer)

    The power of ten to use in scaling the result

Returns:

  • (Integer)

    an integer value



120
121
122
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 120

def _6b_integer_scaled(start, length, decimal_places)
  _6b_integer(start, length).to_f / (10 ** decimal_places)
end

#_6b_string(start, length) ⇒ String

pull out 6b chunks from the payload, then convert those to their more familar characters

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (String)


61
62
63
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 61

def _6b_string(start, length)
  _bit_slices(start, length, 6).to_a.map(&:join).map { |x| _6b_ascii(x.to_i(2)) }.join
end

#_6b_string_nullterminated(start, length) ⇒ String Also known as: _t

convert a 6b string but trim off the 0s (‘@’)

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (String)


85
86
87
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 85

def _6b_string_nullterminated(start, length)
  _6b_string(start, length).split("@", 2)[0]
end

#_6b_twoscomplement(start, length) ⇒ Integer

perform a twos complement operation on part of the payload

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (Integer)

    an integer value



101
102
103
104
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 101

def _6b_twoscomplement(start, length)
  # two's complement: flip bits, then add 1
  _access(start, length) { |bits| bits.tr("01", "10").to_i(2) + 1 }
end

#_6b_unsigned_integer(start, length) ⇒ Integer Also known as: _u, _e

directly convert a string to a binary number as you’d read it

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (Integer)

    an unsigned integer value



93
94
95
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 93

def _6b_unsigned_integer(start, length)
  _access(start, length) { |bits| bits.to_i(2) }
end

#_6b_unsigned_integer_scaled(start, length, decimal_places) ⇒ Integer Also known as: _U

scale an unsigned integer by dividing it by 10^decimal_places

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

  • decimal_places (Integer)

    The power of ten to use in scaling the result

Returns:

  • (Integer)

    an integer value



129
130
131
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 129

def _6b_unsigned_integer_scaled(start, length, decimal_places)
  _6b_unsigned_integer(start, length).to_f / (10.0 ** decimal_places)
end

#_8b_data_string(start, length) ⇒ String

pull out 8b chunks from the payload, then convert those to their more familar characters

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (String)


69
70
71
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 69

def _8b_data_string(start, length)
  _bit_slices(start, length, 8).to_a.map(&:join).map { |x| x.to_i(2).chr }.join
end

#_access(start, length) {|String| ... } ⇒ Object

Access part of the payload. If there aren’t bytes, there, return nil else execute a block

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Yields:

  • (String)

    A binary coded string (“010010101” etc)

Returns:

  • Nil or whatever is yielded by the block



51
52
53
54
55
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 51

def _access(start, length)
  part = @payload_bitstring[start, length]
  return nil if part.nil? || part.empty?
  yield part
end

#_bit_slices(start, length, chunk_size) ⇒ Array<String>

Slice a part of the payload into binary chunks of a given size

Parameters:

  • start (Integer)

    The index of the first bit in the payload field

  • length (Integer)

    The number of bits in the payload field

Returns:

  • (Array<String>)

    Strings representing binary (“01010101” etc) for each slice



77
78
79
# File 'lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb', line 77

def _bit_slices(start, length, chunk_size)
  _access(start, length) { |bits| bits.chars.each_slice(chunk_size) }
end