nmea_plus 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -9
  3. data/lib/nmea_plus/ais_message_factory.rb +3 -1
  4. data/lib/nmea_plus/generated_parser/tokenizer.rb +1 -1
  5. data/lib/nmea_plus/message/ais/base_ais.rb +9 -2
  6. data/lib/nmea_plus/message/ais/vdm.rb +8 -2
  7. data/lib/nmea_plus/message/ais/vdm_payload/payload.rb +59 -23
  8. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb +444 -76
  9. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg1.rb +6 -5
  10. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg12.rb +5 -2
  11. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg14.rb +1 -1
  12. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg18.rb +5 -3
  13. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg20.rb +2 -1
  14. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg21.rb +2 -1
  15. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg24.rb +2 -1
  16. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg27.rb +2 -1
  17. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg4.rb +15 -2
  18. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg5.rb +3 -2
  19. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6.rb +55 -0
  20. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1022f61.rb +122 -0
  21. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d235f10.rb +54 -0
  22. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg7.rb +36 -0
  23. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg8.rb +2 -9
  24. data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg9.rb +5 -5
  25. data/lib/nmea_plus/message/base.rb +27 -14
  26. data/lib/nmea_plus/message/nmea/base_nmea.rb +13 -7
  27. data/lib/nmea_plus/message/nmea/bwr.rb +2 -2
  28. data/lib/nmea_plus/message/nmea/dtm.rb +2 -2
  29. data/lib/nmea_plus/message/nmea/gga.rb +2 -2
  30. data/lib/nmea_plus/message/nmea/gll.rb +2 -2
  31. data/lib/nmea_plus/message/nmea/gns.rb +2 -2
  32. data/lib/nmea_plus/message/nmea/gxa.rb +2 -2
  33. data/lib/nmea_plus/message/nmea/hdg.rb +2 -2
  34. data/lib/nmea_plus/message/nmea/rma.rb +3 -3
  35. data/lib/nmea_plus/message/nmea/rmb.rb +2 -2
  36. data/lib/nmea_plus/message/nmea/rmc.rb +3 -3
  37. data/lib/nmea_plus/message/nmea/trf.rb +2 -2
  38. data/lib/nmea_plus/message/nmea/wpl.rb +2 -2
  39. data/lib/nmea_plus/nmea_message_factory.rb +3 -1
  40. data/lib/nmea_plus/version.rb +1 -1
  41. metadata +9 -5
@@ -7,7 +7,7 @@ module NMEAPlus
7
7
  module AIS
8
8
  module VDMPayload
9
9
 
10
- # Type 8: Binary Broadcast Message
10
+ # AIS Type 8: Binary Broadcast Message
11
11
  class VDMMsg8 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg
12
12
 
13
13
  payload_reader :designated_area_code, 40, 10, :_u
@@ -41,16 +41,9 @@ module NMEAPlus
41
41
  _object_by_name("NMEAPlus::Message::AIS::VDMPayload::VDMMsg8Undefined") # generic
42
42
  end
43
43
 
44
- # Return an object by its class name, or nil if it isn't defined
45
- def _object_by_name(class_identifier)
46
- Object::const_get(class_identifier).new
47
- rescue ::NameError
48
- nil
49
- end
50
-
51
44
  end
52
45
 
53
- # Base class for dynamic payloads (subtypes) of AIS VDM message 8
46
+ # Base class for {VDMMsg8#dp dynamic payload}s (subtypes) of {VDMMsg8 AIS VDM message 8}
54
47
  class VDMMsg8DynamicPayload < NMEAPlus::Message::AIS::VDMPayload::Payload; end
55
48
 
56
49
  # Placeholder for undefined message 8 payload subtypes
@@ -4,18 +4,18 @@ module NMEAPlus
4
4
  module Message
5
5
  module AIS
6
6
  module VDMPayload
7
- # Type 9: Standard SAR Aircraft Position Report
7
+ # AIS Type 9: Standard SAR Aircraft Position Report
8
8
  class VDMMsg9 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg
9
9
 
10
- payload_reader :altitude_meters, 38, 12, :_u
10
+ payload_reader :altitude_meters, 38, 12, :_u, 4095
11
11
 
12
- payload_reader :speed_over_ground, 50, 10, :_U, 1
12
+ payload_reader :speed_over_ground, 50, 10, :_U, 1, 1023
13
13
  payload_reader :position_10m_accuracy?, 60, 1, :_b
14
14
  payload_reader :longitude, 61, 28, :_I, 60 * 10**4, 181
15
15
  payload_reader :latitude, 89, 27, :_I, 60 * 10**4, 91
16
- payload_reader :course_over_ground, 116, 12, :_U, 1
16
+ payload_reader :course_over_ground, 116, 12, :_U, 10
17
17
  payload_reader :time_stamp, 128, 6, :_u
18
- payload_reader :dte?, 142, 1, :_b
18
+ payload_reader :dte_ready?, 142, 1, :_nb
19
19
 
20
20
  payload_reader :assigned?, 146, 1, :_b
21
21
  payload_reader :raim?, 147, 1, :_b
@@ -1,17 +1,22 @@
1
1
 
2
2
  module NMEAPlus
3
3
 
4
- # The module containing all parsed message types.
5
- # @see NMEAPlus::Message::Base
4
+ # This module contains all parsed NMEA message types, and their subtypes.
5
+ # @see NMEAPlus::Message::Base Base class for all NMEA-style messages
6
6
  module Message
7
7
 
8
- # The base message type, from which all others inherit
8
+ # The base NMEA message type, from which all others inherit. Messages have a prefix character,
9
+ # fields, and checksum. This class provides convenience functions for accessing the fields as
10
+ # the appropriate data type, and logic for constructing multipart messages.
9
11
  # @abstract
10
12
  class Base
11
- # make our own shortcut syntax for message attribute accessors
13
+ # Enable a shortcut syntax for message attribute accessors, in the style of `attr_accessor` metaprogramming.
14
+ # This is used to create a named field pointing to a specific indexed field in the payload, optionally applying
15
+ # a specific formatting function.
12
16
  # @param name [String] What the accessor will be called
13
17
  # @param field_num [Integer] The index of the field in the payload
14
18
  # @param formatter [Symbol] The symbol for the formatting function to apply to the field (optional)
19
+ # @return [void]
15
20
  # @macro [attach] field_reader
16
21
  # @!attribute [r] $1
17
22
  # @return field $2 of the payload, formatted with the function {#$3}
@@ -41,6 +46,7 @@ module NMEAPlus
41
46
  # @return [NMEAPlus::Message] The next part of a multipart message, if available
42
47
  attr_accessor :next_part
43
48
 
49
+ # @return [String] The NMEA data type of this message
44
50
  field_reader :data_type, 0, nil
45
51
 
46
52
  # @!parse attr_reader :original
@@ -129,26 +135,27 @@ module NMEAPlus
129
135
  # @param dm_string [String] An angular measurement in the form DDMM.MMM
130
136
  # @param sign_letter [String] can be N,S,E,W
131
137
  # @return [Float] A signed latitude or longitude
132
- def _degrees_minutes_to_decimal(dm_string, sign_letter = "")
138
+ def self.degrees_minutes_to_decimal(dm_string, sign_letter = "")
133
139
  return nil if dm_string.nil? || dm_string.empty?
134
140
  r = /(\d+)(\d{2}\.\d+)/ # (some number of digits) (2 digits for minutes).(decimal minutes)
135
141
  m = r.match(dm_string)
136
142
  raw = m.values_at(1)[0].to_f + (m.values_at(2)[0].to_f / 60)
137
- _nsew_signed_float(raw, sign_letter)
143
+ nsew_signed_float(raw, sign_letter)
138
144
  end
139
145
 
140
- # Use cardinal directions to assign positive or negative to mixed_val.
146
+ # Use cardinal directions to assign positive or negative to mixed_val
141
147
  # Of possible directions NSEW (sign_letter) treat N/E as + and S/W as -
142
148
  # @param mixed_val [String] input value, can be string or float
143
149
  # @param sign_letter [String] can be N,S,E,W, or empty
144
150
  # @return [Float] The input value signed as per the sign letter.
145
- def _nsew_signed_float(mixed_val, sign_letter = "")
151
+ def self.nsew_signed_float(mixed_val, sign_letter = "")
146
152
  value = mixed_val.to_f
147
153
  value *= -1 if !sign_letter.empty? && "SW".include?(sign_letter.upcase)
148
154
  value
149
155
  end
150
156
 
151
- # integer or nil
157
+ # integer or nil.
158
+ # This function is meant to be passed as a formatter to {field_reader}.
152
159
  # @param field [String] the value in the field to be checked
153
160
  # @return [Integer] The value in the field or nil
154
161
  def _integer(field)
@@ -156,7 +163,8 @@ module NMEAPlus
156
163
  field.to_i
157
164
  end
158
165
 
159
- # float or nil
166
+ # float or nil.
167
+ # This function is meant to be passed as a formatter to {field_reader}.
160
168
  # @param field [String] the value in the field to be checked
161
169
  # @return [Float] The value in the field or nil
162
170
  def _float(field)
@@ -164,7 +172,8 @@ module NMEAPlus
164
172
  field.to_f
165
173
  end
166
174
 
167
- # string or nil
175
+ # string or nil.
176
+ # This function is meant to be passed as a formatter to {field_reader}.
168
177
  # @param field [String] the value in the field to be checked
169
178
  # @return [String] The value in the field or nil
170
179
  def _string(field)
@@ -172,7 +181,8 @@ module NMEAPlus
172
181
  field
173
182
  end
174
183
 
175
- # hex to int or nil
184
+ # hex to int or nil.
185
+ # This function is meant to be passed as a formatter to {field_reader}.
176
186
  # @param field [String] the value in the field to be checked
177
187
  # @return [Integer] The value in the field or nil
178
188
  def _hex_to_integer(field)
@@ -180,7 +190,8 @@ module NMEAPlus
180
190
  field.hex
181
191
  end
182
192
 
183
- # utc time or nil (HHMMSS or HHMMSS.SS)
193
+ # utc time or nil (HHMMSS or HHMMSS.SS).
194
+ # This function is meant to be passed as a formatter to {field_reader}.
184
195
  # @param field [String] the value in the field to be checked
185
196
  # @return [Time] The value in the field or nil
186
197
  def _utctime_hms(field)
@@ -195,7 +206,8 @@ module NMEAPlus
195
206
  end
196
207
  end
197
208
 
198
- # time interval or nil (HHMMSS or HHMMSS.SS)
209
+ # time interval or nil (HHMMSS or HHMMSS.SS).
210
+ # This function is meant to be passed as a formatter to {field_reader}.
199
211
  # @param field [String] the value in the field to be checked
200
212
  # @return [Time] The value in the field or nil
201
213
  def _interval_hms(field)
@@ -209,6 +221,7 @@ module NMEAPlus
209
221
  end
210
222
  end
211
223
 
224
+ # Create a Time object from a date and time field
212
225
  # @param d_field [String] the date value in the field to be checked
213
226
  # @param t_field [String] the time value in the field to be checked
214
227
  # @return [Time] The value in the fields, or nil if either is not provided
@@ -3,27 +3,32 @@ require_relative "../base"
3
3
 
4
4
  module NMEAPlus
5
5
  module Message
6
- # A container for all {NMEAMessage} typs.
6
+ # A container for all {NMEAMessage} types.
7
+ # Most definitions were sourced from http://www.catb.org/gpsd/NMEA.txt
7
8
  module NMEA
8
9
 
9
- # The base class for NMEA messages includes a few more NMEA-specific parsing functions
10
+ # The base class for NMEA messages includes a few NMEA-specific parsing functions
11
+ # beyond the base NMEA class.
10
12
  class NMEAMessage < NMEAPlus::Message::Base
11
13
 
12
- # NMEA message types are 5 characters, the first 2 of which are the talker ID
14
+ # The first two characters of the NMEA message type
13
15
  # @!parse attr_accessor :talker
14
16
  # @return [String] The two-character "talker ID" of the message
15
17
  def talker
16
18
  data_type[0..1]
17
19
  end
18
20
 
19
- # NMEA message types are 5 characters (or so), the last of which are the message type
21
+ # The generic type of the NMEA message.
22
+ # NMEA message types are 5 characters (or so): the first 2 are the talker ID, and the
23
+ # remaining characters are the generic message type.
20
24
  # @!parse attr_accessor :message_type
21
- # @return [String] The two-character "talker ID" of the message
25
+ # @return [String] The generic part of the NMEA "data type" of the message
22
26
  def message_type
23
27
  data_type[2..-1]
24
28
  end
25
29
 
26
- # Convert a string true/false (encoded as A=true, V=false) to boolean
30
+ # Convert a string true/false (encoded as A=true, V=false) to boolean.
31
+ # This function is meant to be passed as a formatter to {field_reader}.
27
32
  # @param field [String] the value in the field to be checked
28
33
  # @return [bool] The value in the field or nil
29
34
  def _av_boolean(field)
@@ -34,7 +39,8 @@ module NMEAPlus
34
39
  nil
35
40
  end
36
41
 
37
- # Convert a string true/false (encoded as 1=true, 0=false) to boolean
42
+ # Convert a string true/false (encoded as 1=true, 0=false) to boolean.
43
+ # This function is meant to be passed as a formatter to {field_reader}.
38
44
  # @param field [String] the value in the field to be checked
39
45
  # @return [bool] The value in the field or nil
40
46
  def _10_boolean(field)
@@ -10,13 +10,13 @@ module NMEAPlus
10
10
  # @!parse attr_reader :waypoint_latitude
11
11
  # @return [Float]
12
12
  def waypoint_latitude
13
- _degrees_minutes_to_decimal(@fields[2], @fields[3])
13
+ self.class.degrees_minutes_to_decimal(@fields[2], @fields[3])
14
14
  end
15
15
 
16
16
  # @!parse attr_reader :waypoint_longitude
17
17
  # @return [Float]
18
18
  def waypoint_longitude
19
- _degrees_minutes_to_decimal(@fields[4], @fields[5])
19
+ self.class.degrees_minutes_to_decimal(@fields[4], @fields[5])
20
20
  end
21
21
 
22
22
  field_reader :bearing_true, 6, :_float
@@ -11,13 +11,13 @@ module NMEAPlus
11
11
  # @!parse attr_reader :latitude_offset
12
12
  # @return [Float]
13
13
  def latitude_offset
14
- _nsew_signed_float(@fields[3], @fields[4])
14
+ self.class.nsew_signed_float(@fields[3], @fields[4])
15
15
  end
16
16
 
17
17
  # @!parse attr_reader :longitude_offset
18
18
  # @return [Float]
19
19
  def longitude_offset
20
- _nsew_signed_float(@fields[5], @fields[6])
20
+ self.class.nsew_signed_float(@fields[5], @fields[6])
21
21
  end
22
22
 
23
23
  field_reader :altitude_meters, 7, :_float
@@ -11,13 +11,13 @@ module NMEAPlus
11
11
  # @!parse attr_reader :latitude
12
12
  # @return [Float]
13
13
  def latitude
14
- _degrees_minutes_to_decimal(@fields[2], @fields[3])
14
+ self.class.degrees_minutes_to_decimal(@fields[2], @fields[3])
15
15
  end
16
16
 
17
17
  # @!parse attr_reader :longitude
18
18
  # @return [Float]
19
19
  def longitude
20
- _degrees_minutes_to_decimal(@fields[4], @fields[5])
20
+ self.class.degrees_minutes_to_decimal(@fields[4], @fields[5])
21
21
  end
22
22
 
23
23
  field_reader :fix_quality, 6, :_integer
@@ -9,13 +9,13 @@ module NMEAPlus
9
9
  # @!parse attr_reader :latitude
10
10
  # @return [Float]
11
11
  def latitude
12
- _degrees_minutes_to_decimal(@fields[1], @fields[2])
12
+ self.class.degrees_minutes_to_decimal(@fields[1], @fields[2])
13
13
  end
14
14
 
15
15
  # @!parse attr_reader :longitude
16
16
  # @return [Float]
17
17
  def longitude
18
- _degrees_minutes_to_decimal(@fields[3], @fields[4])
18
+ self.class.degrees_minutes_to_decimal(@fields[3], @fields[4])
19
19
  end
20
20
 
21
21
  field_reader :fix_time, 5, :_utctime_hms
@@ -11,13 +11,13 @@ module NMEAPlus
11
11
  # @!parse attr_reader :latitude
12
12
  # @return [Float]
13
13
  def latitude
14
- _degrees_minutes_to_decimal(@fields[2], @fields[3])
14
+ self.class.degrees_minutes_to_decimal(@fields[2], @fields[3])
15
15
  end
16
16
 
17
17
  # @!parse attr_reader :longitude
18
18
  # @return [Float]
19
19
  def longitude
20
- _degrees_minutes_to_decimal(@fields[4], @fields[5])
20
+ self.class.degrees_minutes_to_decimal(@fields[4], @fields[5])
21
21
  end
22
22
 
23
23
  field_reader :mode, 6, :_string
@@ -11,13 +11,13 @@ module NMEAPlus
11
11
  # @!parse attr_reader :latitude
12
12
  # @return [Float]
13
13
  def latitude
14
- _degrees_minutes_to_decimal(@fields[2], @fields[3])
14
+ self.class.degrees_minutes_to_decimal(@fields[2], @fields[3])
15
15
  end
16
16
 
17
17
  # @!parse attr_reader :longitude
18
18
  # @return [Float]
19
19
  def longitude
20
- _degrees_minutes_to_decimal(@fields[4], @fields[5])
20
+ self.class.degrees_minutes_to_decimal(@fields[4], @fields[5])
21
21
  end
22
22
 
23
23
  field_reader :waypoint_id, 6, :_integer
@@ -10,13 +10,13 @@ module NMEAPlus
10
10
  # @!parse attr_reader :magnetic_deviation_degrees
11
11
  # @return [Float]
12
12
  def magnetic_deviation_degrees
13
- _nsew_signed_float(@fields[2], @fields[3])
13
+ self.class.nsew_signed_float(@fields[2], @fields[3])
14
14
  end
15
15
 
16
16
  # @!parse attr_reader :magnetic_variation_degrees
17
17
  # @return [Float]
18
18
  def magnetic_variation_degrees
19
- _nsew_signed_float(@fields[4], @fields[5])
19
+ self.class.nsew_signed_float(@fields[4], @fields[5])
20
20
  end
21
21
 
22
22
  end
@@ -11,13 +11,13 @@ module NMEAPlus
11
11
  # @!parse attr_reader :latitude
12
12
  # @return [Float]
13
13
  def latitude
14
- _degrees_minutes_to_decimal(@fields[2], @fields[3])
14
+ self.class.degrees_minutes_to_decimal(@fields[2], @fields[3])
15
15
  end
16
16
 
17
17
  # @!parse attr_reader :longitude
18
18
  # @return [Float]
19
19
  def longitude
20
- _degrees_minutes_to_decimal(@fields[4], @fields[5])
20
+ self.class.degrees_minutes_to_decimal(@fields[4], @fields[5])
21
21
  end
22
22
 
23
23
  field_reader :time_difference_a, 6, :_float
@@ -28,7 +28,7 @@ module NMEAPlus
28
28
  # @!parse attr_reader :magnetic_variation_degrees
29
29
  # @return [Float]
30
30
  def magnetic_variation_degrees
31
- _nsew_signed_float(@fields[10], @fields[11])
31
+ self.class.nsew_signed_float(@fields[10], @fields[11])
32
32
  end
33
33
 
34
34
  end
@@ -15,13 +15,13 @@ module NMEAPlus
15
15
  # @!parse attr_reader :waypoint_latitude
16
16
  # @return [Float]
17
17
  def waypoint_latitude
18
- _degrees_minutes_to_decimal(@fields[6], @fields[7])
18
+ self.class.degrees_minutes_to_decimal(@fields[6], @fields[7])
19
19
  end
20
20
 
21
21
  # @!parse attr_reader :waypoint_longitude
22
22
  # @return [Float]
23
23
  def waypoint_longitude
24
- _degrees_minutes_to_decimal(@fields[8], @fields[9])
24
+ self.class.degrees_minutes_to_decimal(@fields[8], @fields[9])
25
25
  end
26
26
 
27
27
  field_reader :range_to_destination_nautical_miles, 10, :_float
@@ -17,13 +17,13 @@ module NMEAPlus
17
17
  # @!parse attr_reader :latitude
18
18
  # @return [Float]
19
19
  def latitude
20
- _degrees_minutes_to_decimal(@fields[3], @fields[4])
20
+ self.class.degrees_minutes_to_decimal(@fields[3], @fields[4])
21
21
  end
22
22
 
23
23
  # @!parse attr_reader :longitude
24
24
  # @return [Float]
25
25
  def longitude
26
- _degrees_minutes_to_decimal(@fields[5], @fields[6])
26
+ self.class.degrees_minutes_to_decimal(@fields[5], @fields[6])
27
27
  end
28
28
 
29
29
  field_reader :speed_over_ground_knots, 7, :_float
@@ -32,7 +32,7 @@ module NMEAPlus
32
32
  # @!parse attr_reader :magnetic_variation_degrees
33
33
  # @return [Float]
34
34
  def magnetic_variation_degrees
35
- _nsew_signed_float(@fields[10], @fields[11])
35
+ self.class.nsew_signed_float(@fields[10], @fields[11])
36
36
  end
37
37
 
38
38
  field_reader :faa_mode, 12, :_string
@@ -14,13 +14,13 @@ module NMEAPlus
14
14
  # @!parse attr_reader :latitude
15
15
  # @return [Float]
16
16
  def latitude
17
- _degrees_minutes_to_decimal(@fields[3], @fields[4])
17
+ self.class.degrees_minutes_to_decimal(@fields[3], @fields[4])
18
18
  end
19
19
 
20
20
  # @!parse attr_reader :longitude
21
21
  # @return [Float]
22
22
  def longitude
23
- _degrees_minutes_to_decimal(@fields[5], @fields[6])
23
+ self.class.degrees_minutes_to_decimal(@fields[5], @fields[6])
24
24
  end
25
25
 
26
26
  field_reader :elevation_angle, 7, :_float
@@ -8,13 +8,13 @@ module NMEAPlus
8
8
  # @!parse attr_reader :latitude
9
9
  # @return [Float]
10
10
  def latitude
11
- _degrees_minutes_to_decimal(@fields[1], @fields[2])
11
+ self.class.degrees_minutes_to_decimal(@fields[1], @fields[2])
12
12
  end
13
13
 
14
14
  # @!parse attr_reader :longitude
15
15
  # @return [Float]
16
16
  def longitude
17
- _degrees_minutes_to_decimal(@fields[3], @fields[4])
17
+ self.class.degrees_minutes_to_decimal(@fields[3], @fields[4])
18
18
  end
19
19
 
20
20
  field_reader :name, 5, :_string
@@ -95,7 +95,9 @@ module NMEAPlus
95
95
  end
96
96
  =end
97
97
 
98
- # Defines a factory for NMEA messages, which will all use {NMEAPlus::Message::NMEA::NMEAMessage} as their base
98
+ # Defines a factory for NMEA messages, which will all use {NMEAPlus::Message::NMEA::NMEAMessage} as their base.
99
+ # The factory extracts the NMEA data type (prefixed by a 2-character "talker ID"), and looks for a class with
100
+ # that name within the NMEA message namespace.
99
101
  class NMEAMessageFactory < MessageFactory
100
102
 
101
103
  # @return [String] The name of the parent module: NMEA