nmea_plus 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14b78eb70f5197e702eda48e3b297cfa9e6aed78
4
- data.tar.gz: cc2f08b71f5841d8436f2e53baca38745aa67169
3
+ metadata.gz: a207c93360fededdabcaff54e1728e9ab275b344
4
+ data.tar.gz: 1085b632c37d05ef034c64804283d376417f55d5
5
5
  SHA512:
6
- metadata.gz: f2db86ca89249ba01692b2cd4251eede675e1550defbb0bb80b486fad391e6ed2b1dbcfe9ef08c20b9854d8454510ba429cdb1f56c318d99f62d6e19a41ca2e8
7
- data.tar.gz: 33a427ee981915f75cfdbf3f4143ddc2d6349db562f03fb59884f5f7562660c3f59d5f2e781b03addd7f33c1768750aa42fcf6430b39543a8594f02d4e1f2cfe
6
+ metadata.gz: b8a9716472c3c20a86cf6daaadecc78aa06301d8b3f37b1e9141ec2d05c5135f2dd5f5bc70e5e2f09339e59a0e2fe30c8773805ea18e3aa59887dd5b54f109cf
7
+ data.tar.gz: 005a20dcb935adb5fd9d0762ed40b94a9c6950ea7dc2b1c8b914fe7631bbb005cc305a825f74b931c25bcb2d97908d87e657393f38c585e0e0973549ad6c1c7c
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/nmea_plus.svg)](https://rubygems.org/gems/nmea_plus)
4
4
  [![Build Status](https://travis-ci.org/ifreecarve/nmea_plus.svg)](https://travis-ci.org/ifreecarve/nmea_plus)
5
+ [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.org/gems/nmea_plus/frames)
5
6
 
6
7
  [NMEA Plus](https://github.com/ifreecarve/nmea_plus) is a Ruby gem for parsing and decoding "GPS" messages: NMEA, AIS, and any other similar formats of short messaging typically used by marine equipment. It provides convenient access (by name) to the fields of each message type, and a stream reader designed for use with Ruby Blocks.
7
8
 
data/lib/nmea_plus.rb CHANGED
@@ -4,6 +4,8 @@ require 'nmea_plus/generated_parser/parser'
4
4
  require 'nmea_plus/generated_parser/tokenizer'
5
5
 
6
6
  # NMEAPlus contains classes for parsing and decoding NMEA and AIS messages.
7
+ # You probably want to check out {NMEAPlus::Message::NMEA::NMEAMessage}
8
+ # and {NMEAPlus::Message::AIS::AISMessage}.
7
9
  # @author Ian Katz
8
10
  module NMEAPlus
9
11
 
@@ -3,13 +3,20 @@ require_relative "../base"
3
3
 
4
4
  module NMEAPlus
5
5
  module Message
6
+ # A container for all {AISMessage} types.
6
7
  module AIS
7
8
 
8
9
  class AISMessage < NMEAPlus::Message::Base
10
+ # NMEA (AIS) message types are 5 characters, the first 2 of which are the talker ID
11
+ # @!parse attr_accessor :talker
12
+ # @return [String] The two-character "talker ID" of the message
9
13
  def talker
10
14
  data_type[0..1]
11
15
  end
12
16
 
17
+ # NMEA (AIS) message types are 5 characters (or so), the last of which are the message type
18
+ # @!parse attr_accessor :message_type
19
+ # @return [String] The two-character "talker ID" of the message
13
20
  def message_type
14
21
  data_type[2..-1]
15
22
  end
@@ -21,7 +21,6 @@ require_relative "vdm_payload/vdm_msg1"
21
21
  require_relative "vdm_payload/vdm_msg5"
22
22
  require_relative "vdm_payload/vdm_msg8"
23
23
 
24
-
25
24
  module NMEAPlus
26
25
  module Message
27
26
  module AIS
@@ -33,8 +32,10 @@ module NMEAPlus
33
32
  field_reader :raw_ais_payload, 5, :_string
34
33
  field_reader :ais_payload_fill_bits, 6, :_integer
35
34
 
35
+ # factory method: find the appropriate message type class and instantiate it
36
+ # @!parse attr_reader :ais
37
+ # @return [VDMPayload::VDMMsg]
36
38
  def ais
37
- # factory method: find the appropriate message type class and instantiate it
38
39
  p = full_dearmored_ais_payload
39
40
  ret = _payload_container(p[0, 6].to_i(2))
40
41
  ret.payload_bitstring = p
@@ -42,7 +43,9 @@ module NMEAPlus
42
43
  ret
43
44
  end
44
45
 
45
- # the full encoded payload as it was received
46
+ # the full encoded payload as it was received -- spanning multiple messages
47
+ # @!parse attr_reader :full_armored_ais_payload
48
+ # @return [String]
46
49
  def full_armored_ais_payload
47
50
  # get the full message and fill bits for the last one
48
51
  ptr = self
@@ -56,6 +59,8 @@ module NMEAPlus
56
59
  end
57
60
 
58
61
  # a binary string ("0010101110110") representing the dearmored payload
62
+ # @!parse attr_reader :full_dearmored_ais_payload
63
+ # @return [String]
59
64
  def full_dearmored_ais_payload
60
65
  data = full_armored_ais_payload
61
66
  out = ""
@@ -65,8 +70,10 @@ module NMEAPlus
65
70
  out
66
71
  end
67
72
 
73
+ # Get the fill bits for the last message in the sequence -- the only one that matters
74
+ # @!parse attr_reader :last_ais_fill_bits
75
+ # @return [Integer]
68
76
  def last_ais_fill_bits
69
- # get the fill bits for the last message in the sequence
70
77
  ptr = self
71
78
  fill_bits = nil
72
79
  loop do
@@ -78,6 +85,9 @@ module NMEAPlus
78
85
  end
79
86
 
80
87
  # perform the 6-bit to 8-bit conversion defined in the spec
88
+ # @param c [String] a character
89
+ # @param len [Integer] The number of bits to consider
90
+ # @return [String] a binary encoded string
81
91
  def _dearmor6b(c, len = 6)
82
92
  val = c.ord
83
93
  if val >= 96
@@ -88,6 +98,9 @@ module NMEAPlus
88
98
  ret.to_s(2).rjust(6, "0")[0..(len - 1)]
89
99
  end
90
100
 
101
+ # Find an appropriate payload container for the payload type, based on its stated message ID
102
+ # @param message_type_id [String]
103
+ # @return [NMEAPlus::Message::AIS::VDMPayload::VDMMsg] The parsed payload
91
104
  def _payload_container(message_type_id)
92
105
  class_identifier = "NMEAPlus::Message::AIS::VDMPayload::VDMMsg#{message_type_id}"
93
106
  Object::const_get(class_identifier).new
@@ -1,69 +1,111 @@
1
1
  class Class
2
- # make our own shortcut syntax for payload attributes
3
- def payload_reader(name, start_bit, length, formatter, formatter_arg = nil)
4
- if formatter_arg.nil?
5
- self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length});end")
6
- else
7
- self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length}, #{formatter_arg});end")
8
- end
9
- end
10
2
  end
11
3
 
12
4
  module NMEAPlus
13
5
  module Message
14
6
  module AIS
7
+ # There are many VDM payload types, and this is their container. See {VDMMsg}.
15
8
  module VDMPayload
9
+ # The base class for the AIS payload (of {NMEAPlus::Message::AIS::VDM}) which can be of many types.
16
10
  class VDMMsg
11
+ # @return [String] The raw "armored payload" in the original message
17
12
  attr_accessor :payload_bitstring
13
+
14
+ # @return [Integer] The number of padding characters required to bring the payload to a 6 bit boundary
18
15
  attr_accessor :fill_bits
19
16
 
17
+ # make our own shortcut syntax for payload attributes
18
+ # @param name [String] What the accessor will be called
19
+ # @param start_bit [Integer] The index of first bit of this field in the payload
20
+ # @param length [Integer] The number of bits in this field
21
+ # @param formatter [Symbol] The symbol for the formatting function to apply to the field (optional)
22
+ # @param formatter_arg Any argument necessary for the formatting function
23
+ # @macro [attach] payload_reader
24
+ # @!attribute [r] $1
25
+ # @return The field defined by $3 bits starting at bit $2 of the payload, formatted with the function {#$4}($5)
26
+ def self.payload_reader(name, start_bit, length, formatter, formatter_arg = nil)
27
+ if formatter_arg.nil?
28
+ self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length});end")
29
+ else
30
+ self.class_eval("def #{name};#{formatter}(#{start_bit}, #{length}, #{formatter_arg});end")
31
+ end
32
+ end
33
+
20
34
  payload_reader :message_type, 0, 6, :_u
21
35
  payload_reader :repeat_indicator, 6, 2, :_u
22
36
  payload_reader :source_mmsi, 8, 30, :_u
23
37
 
24
- # lookup table for 6-bit ascii
38
+ # Convert 6-bit ascii to a character, according to http://catb.org/gpsd/AIVDM.html#_ais_payload_data_types
39
+ # @param ord [Integer] The 6-bit ascii code
40
+ # @return [String] the character for that code
25
41
  def _6b_ascii(ord)
26
42
  '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !"#$%&\'()*+,-./0123456789:;<=>?'[ord]
27
43
  end
28
44
 
29
- # access part of the payload. if there aren't bytes, there, return nil
45
+ # Access part of the payload. If there aren't bytes, there, return nil
30
46
  # else execute a block
47
+ # @param start [Integer] The index of the first bit in the payload field
48
+ # @param length [Integer] The number of bits in the payload field
49
+ # @return Nil or whatever is yielded by the block
50
+ # @yield [String] A binary coded string ("010010101" etc)
31
51
  def _access(start, length)
32
52
  part = @payload_bitstring[start, length]
33
53
  return nil if part.nil? || part.empty?
34
54
  yield part
35
55
  end
36
56
 
37
- # convert an entire string from the payload
57
+ # pull out 6b chunks from the payload, then convert those to their more familar characters
58
+ # @param start [Integer] The index of the first bit in the payload field
59
+ # @param length [Integer] The number of bits in the payload field
60
+ # @return [String]
38
61
  def _6b_string(start, length)
39
- # pull out 6b chunks from the string, use their value as a lookup into the ascii array
40
62
  _bit_slices(start, length, 6).to_a.map(&:join).map { |x| _6b_ascii(x.to_i(2)) }.join
41
63
  end
42
64
 
65
+ # pull out 8b chunks from the payload, then convert those to their more familar characters
66
+ # @param start [Integer] The index of the first bit in the payload field
67
+ # @param length [Integer] The number of bits in the payload field
68
+ # @return [String]
43
69
  def _8b_data_string(start, length)
44
70
  _bit_slices(start, length, 8).to_a.map(&:join).map { |x| x.to_i(2).chr }.join
45
71
  end
46
72
 
73
+ # Slice a part of the payload into binary chunks of a given size
74
+ # @param start [Integer] The index of the first bit in the payload field
75
+ # @param length [Integer] The number of bits in the payload field
76
+ # @return [Array<String>] Strings representing binary ("01010101" etc) for each slice
47
77
  def _bit_slices(start, length, chunk_size)
48
78
  _access(start, length) { |bits| bits.chars.each_slice(chunk_size) }
49
79
  end
50
80
 
51
- # convert a string but trim off the 0s ('@')
81
+ # convert a 6b string but trim off the 0s ('@')
82
+ # @param start [Integer] The index of the first bit in the payload field
83
+ # @param length [Integer] The number of bits in the payload field
84
+ # @return [String]
52
85
  def _6b_string_nullterminated(start, length)
53
86
  _6b_string(start, length).split("@", 2)[0]
54
87
  end
55
88
 
56
89
  # directly convert a string to a binary number as you'd read it
90
+ # @param start [Integer] The index of the first bit in the payload field
91
+ # @param length [Integer] The number of bits in the payload field
92
+ # @return [Integer] an unsigned integer value
57
93
  def _6b_unsigned_integer(start, length)
58
94
  _access(start, length) { |bits| bits.to_i(2) }
59
95
  end
60
96
 
61
97
  # perform a twos complement operation on part of the payload
98
+ # @param start [Integer] The index of the first bit in the payload field
99
+ # @param length [Integer] The number of bits in the payload field
100
+ # @return [Integer] an integer value
62
101
  def _6b_twoscomplement(start, length)
63
102
  # two's complement: flip bits, then add 1
64
103
  _access(start, length) { |bits| bits.tr("01", "10").to_i(2) + 1 }
65
104
  end
66
105
 
106
+ # @param start [Integer] The index of the first bit in the payload field
107
+ # @param length [Integer] The number of bits in the payload field
108
+ # @return [Integer] an integer value
67
109
  def _6b_integer(start, length)
68
110
  # MSB is 1 for negative
69
111
  twoc = _6b_twoscomplement(start, length)
@@ -71,19 +113,35 @@ module NMEAPlus
71
113
  end
72
114
 
73
115
  # scale an integer by dividing it by 10^decimal_places
116
+ # @param start [Integer] The index of the first bit in the payload field
117
+ # @param length [Integer] The number of bits in the payload field
118
+ # @param decimal_places [Integer] The power of ten to use in scaling the result
119
+ # @return [Integer] an integer value
74
120
  def _6b_integer_scaled(start, length, decimal_places)
75
121
  _6b_integer(start, length).to_f / (10 ** decimal_places)
76
122
  end
77
123
 
78
124
  # scale an unsigned integer by dividing it by 10^decimal_places
125
+ # @param start [Integer] The index of the first bit in the payload field
126
+ # @param length [Integer] The number of bits in the payload field
127
+ # @param decimal_places [Integer] The power of ten to use in scaling the result
128
+ # @return [Integer] an integer value
79
129
  def _6b_unsigned_integer_scaled(start, length, decimal_places)
80
130
  _6b_unsigned_integer(start, length).to_f / (10.0 ** decimal_places)
81
131
  end
82
132
 
133
+ # Get the value of a bit in the payload
134
+ # @param start [Integer] The index of the first bit in the payload field
135
+ # @param _ [Integer] Doesn't matter. Here so signatures match; we hard-code 1 because it's 1 bit.
136
+ # @return [bool]
83
137
  def _6b_boolean(start, _)
84
138
  _access(start, 1) { |bits| bits.to_i == 1 }
85
139
  end
86
140
 
141
+ # Return a string representing binary
142
+ # @param start [Integer] The index of the first bit in the payload field
143
+ # @param length [Integer] The number of bits in the payload field
144
+ # @return [String] e.g. "0101010101011000"
87
145
  def _2b_data_string(start, length)
88
146
  _access(start, length)
89
147
  end
@@ -100,6 +158,7 @@ module NMEAPlus
100
158
 
101
159
  end
102
160
 
161
+ # We haven't defined all the AIS payload types, so this is a catch-all
103
162
  class VDMMsgUndefined < VDMMsg; end
104
163
 
105
164
  end
@@ -4,10 +4,13 @@ module NMEAPlus
4
4
  module Message
5
5
  module AIS
6
6
  module VDMPayload
7
+ # CNB - The Common Navigation Block, transmitted by AIS messages 1, 2, and 3.
7
8
  class VDMMsgCNB < NMEAPlus::Message::AIS::VDMPayload::VDMMsg
8
9
 
9
10
  payload_reader :navigational_status, 38, 4, :_u
10
11
 
12
+ # @!parse attr_reader :navigational_status_description
13
+ # @return [String] the human-readable description of navigational status
11
14
  def navigational_status_description
12
15
  case navigational_status
13
16
  when 0 then return "Under way using engine"
@@ -25,6 +28,9 @@ module NMEAPlus
25
28
  end
26
29
  end
27
30
 
31
+ # The rate of turn in degrees per minute
32
+ # @!parse attr_reader :rate_of_turn
33
+ # @return [Float]
28
34
  def rate_of_turn
29
35
  ret = _i(42, 8)
30
36
  return nil if ret == -128
@@ -34,16 +40,22 @@ module NMEAPlus
34
40
  payload_reader :speed_over_ground, 50, 10, :_U, 1
35
41
  payload_reader :position_10m_accuracy?, 60, 1, :_b
36
42
 
43
+ # @!parse attr_reader :longitude
44
+ # @return [Float]
37
45
  def longitude
38
46
  _I(61, 28, 4) / 60
39
47
  end
40
48
 
49
+ # @!parse attr_reader :latitude
50
+ # @return [Float]
41
51
  def latitude
42
52
  _U(89, 27, 4) / 60
43
53
  end
44
54
 
45
55
  payload_reader :course_over_ground, 116, 12, :_U, 1
46
56
 
57
+ # @!parse attr_reader :true_heading
58
+ # @return [Float]
47
59
  def true_heading
48
60
  ret = _u(128, 9)
49
61
  return nil if ret == 511 # means "not available"
@@ -22,6 +22,8 @@ module NMEAPlus
22
22
  payload_reader :ship_dimension_to_starboard, 264, 6, :_u
23
23
  payload_reader :epfd_type, 270, 4, :_e
24
24
 
25
+ # @!parse attr_reader :eta
26
+ # @return [Time]
25
27
  def eta
26
28
  now = Time.now
27
29
  Time.new(now.year,
@@ -12,8 +12,8 @@ module NMEAPlus
12
12
  # @param name [String] What the accessor will be called
13
13
  # @param field_num [Integer] The index of the field in the payload
14
14
  # @param formatter [Symbol] The symbol for the formatting function to apply to the field (optional)
15
- # @!macro [attach] field_reader
16
- # @method $1
15
+ # @macro [attach] field_reader
16
+ # @!attribute [r] $1
17
17
  # @return field $2 of the payload, formatted with the function {#$3}
18
18
  def self.field_reader(name, field_num, formatter = nil)
19
19
  if formatter.nil?
@@ -149,7 +149,7 @@ module NMEAPlus
149
149
  end
150
150
 
151
151
  # integer or nil
152
- # @param field [String] the field index to check
152
+ # @param field [String] the value in the field to be checked
153
153
  # @return [Integer] The value in the field or nil
154
154
  def _integer(field)
155
155
  return nil if field.nil? || field.empty?
@@ -157,7 +157,7 @@ module NMEAPlus
157
157
  end
158
158
 
159
159
  # float or nil
160
- # @param field [String] the field index to check
160
+ # @param field [String] the value in the field to be checked
161
161
  # @return [Float] The value in the field or nil
162
162
  def _float(field)
163
163
  return nil if field.nil? || field.empty?
@@ -165,7 +165,7 @@ module NMEAPlus
165
165
  end
166
166
 
167
167
  # string or nil
168
- # @param field [String] the field index to check
168
+ # @param field [String] the value in the field to be checked
169
169
  # @return [String] The value in the field or nil
170
170
  def _string(field)
171
171
  return nil if field.nil? || field.empty?
@@ -173,7 +173,7 @@ module NMEAPlus
173
173
  end
174
174
 
175
175
  # hex to int or nil
176
- # @param field [String] the field index to check
176
+ # @param field [String] the value in the field to be checked
177
177
  # @return [Integer] The value in the field or nil
178
178
  def _hex_to_integer(field)
179
179
  return nil if field.nil? || field.empty?
@@ -181,7 +181,7 @@ module NMEAPlus
181
181
  end
182
182
 
183
183
  # utc time or nil (HHMMSS or HHMMSS.SS)
184
- # @param field [String] the field index to check
184
+ # @param field [String] the value in the field to be checked
185
185
  # @return [Time] The value in the field or nil
186
186
  def _utctime_hms(field)
187
187
  return nil if field.nil? || field.empty?
@@ -196,7 +196,7 @@ module NMEAPlus
196
196
  end
197
197
 
198
198
  # time interval or nil (HHMMSS or HHMMSS.SS)
199
- # @param field [String] the field index to check
199
+ # @param field [String] the value in the field to be checked
200
200
  # @return [Time] The value in the field or nil
201
201
  def _interval_hms(field)
202
202
  return nil if field.nil? || field.empty?
@@ -209,8 +209,8 @@ module NMEAPlus
209
209
  end
210
210
  end
211
211
 
212
- # @param d_field [String] the date field index to check
213
- # @param t_field [String] the time field index to check
212
+ # @param d_field [String] the date value in the field to be checked
213
+ # @param t_field [String] the time value in the field to be checked
214
214
  # @return [Time] The value in the fields, or nil if either is not provided
215
215
  def _utc_date_time(d_field, t_field)
216
216
  return nil if t_field.nil? || t_field.empty?
@@ -3,27 +3,42 @@ require_relative "../base"
3
3
 
4
4
  module NMEAPlus
5
5
  module Message
6
+ # A container for all {NMEAMessage} typs.
6
7
  module NMEA
7
8
 
9
+ # The base class for NMEA messages includes a few more NMEA-specific parsing functions
8
10
  class NMEAMessage < NMEAPlus::Message::Base
11
+
12
+ # NMEA message types are 5 characters, the first 2 of which are the talker ID
13
+ # @!parse attr_accessor :talker
14
+ # @return [String] The two-character "talker ID" of the message
9
15
  def talker
10
16
  data_type[0..1]
11
17
  end
12
18
 
19
+ # NMEA message types are 5 characters (or so), the last of which are the message type
20
+ # @!parse attr_accessor :message_type
21
+ # @return [String] The two-character "talker ID" of the message
13
22
  def message_type
14
23
  data_type[2..-1]
15
24
  end
16
25
 
17
- def _av_boolean(data)
18
- case data
26
+ # Convert a string true/false (encoded as A=true, V=false) to boolean
27
+ # @param field [String] the value in the field to be checked
28
+ # @return [bool] The value in the field or nil
29
+ def _av_boolean(field)
30
+ case field
19
31
  when 'A' then return true
20
32
  when 'V' then return false
21
33
  end
22
34
  nil
23
35
  end
24
36
 
25
- def _10_boolean(data)
26
- case data
37
+ # Convert a string true/false (encoded as 1=true, 0=false) to boolean
38
+ # @param field [String] the value in the field to be checked
39
+ # @return [bool] The value in the field or nil
40
+ def _10_boolean(field)
41
+ case field
27
42
  when '1' then return true
28
43
  when '0' then return false
29
44
  end
@@ -6,10 +6,14 @@ module NMEAPlus
6
6
  class BWR < NMEAPlus::Message::NMEA::NMEAMessage
7
7
  field_reader :utc_time, 1, :_utctime_hms
8
8
 
9
+ # @!parse attr_reader :waypoint_latitude
10
+ # @return [Float]
9
11
  def waypoint_latitude
10
12
  _degrees_minutes_to_decimal(@fields[2], @fields[3])
11
13
  end
12
14
 
15
+ # @!parse attr_reader :waypoint_longitude
16
+ # @return [Float]
13
17
  def waypoint_longitude
14
18
  _degrees_minutes_to_decimal(@fields[4], @fields[5])
15
19
  end
@@ -7,10 +7,14 @@ module NMEAPlus
7
7
  field_reader :code, 1, :_string
8
8
  field_reader :subcode, 2, :_string
9
9
 
10
+ # @!parse attr_reader :latitude_offset
11
+ # @return [Float]
10
12
  def latitude_offset
11
13
  _nsew_signed_float(@fields[3], @fields[4])
12
14
  end
13
15
 
16
+ # @!parse attr_reader :longitude_offset
17
+ # @return [Float]
14
18
  def longitude_offset
15
19
  _nsew_signed_float(@fields[5], @fields[6])
16
20
  end
@@ -8,10 +8,14 @@ module NMEAPlus
8
8
  class GGA < NMEAPlus::Message::NMEA::NMEAMessage
9
9
  field_reader :fix_time, 1, :_utctime_hms
10
10
 
11
+ # @!parse attr_reader :latitude
12
+ # @return [Float]
11
13
  def latitude
12
14
  _degrees_minutes_to_decimal(@fields[2], @fields[3])
13
15
  end
14
16
 
17
+ # @!parse attr_reader :longitude
18
+ # @return [Float]
15
19
  def longitude
16
20
  _degrees_minutes_to_decimal(@fields[4], @fields[5])
17
21
  end
@@ -4,10 +4,15 @@ module NMEAPlus
4
4
  module Message
5
5
  module NMEA
6
6
  class GLL < NMEAPlus::Message::NMEA::NMEAMessage
7
+
8
+ # @!parse attr_reader :latitude
9
+ # @return [Float]
7
10
  def latitude
8
11
  _degrees_minutes_to_decimal(@fields[1], @fields[2])
9
12
  end
10
13
 
14
+ # @!parse attr_reader :longitude
15
+ # @return [Float]
11
16
  def longitude
12
17
  _degrees_minutes_to_decimal(@fields[3], @fields[4])
13
18
  end
@@ -7,10 +7,14 @@ module NMEAPlus
7
7
  class GNS < NMEAPlus::Message::NMEA::NMEAMessage
8
8
  field_reader :fix_time, 1, :_utctime_hms
9
9
 
10
+ # @!parse attr_reader :latitude
11
+ # @return [Float]
10
12
  def latitude
11
13
  _degrees_minutes_to_decimal(@fields[2], @fields[3])
12
14
  end
13
15
 
16
+ # @!parse attr_reader :longitude
17
+ # @return [Float]
14
18
  def longitude
15
19
  _degrees_minutes_to_decimal(@fields[4], @fields[5])
16
20
  end
@@ -6,10 +6,15 @@ module NMEAPlus
6
6
  class GXA < NMEAPlus::Message::NMEA::NMEAMessage
7
7
 
8
8
  field_reader :fix_time, 1, :_utctime_hms
9
+
10
+ # @!parse attr_reader :latitude
11
+ # @return [Float]
9
12
  def latitude
10
13
  _degrees_minutes_to_decimal(@fields[2], @fields[3])
11
14
  end
12
15
 
16
+ # @!parse attr_reader :longitude
17
+ # @return [Float]
13
18
  def longitude
14
19
  _degrees_minutes_to_decimal(@fields[4], @fields[5])
15
20
  end
@@ -6,10 +6,14 @@ module NMEAPlus
6
6
  module NMEA
7
7
  class HDG < NMEAPlus::Message::NMEA::HDM
8
8
 
9
+ # @!parse attr_reader :magnetic_deviation_degrees
10
+ # @return [Float]
9
11
  def magnetic_deviation_degrees
10
12
  _nsew_signed_float(@fields[2], @fields[3])
11
13
  end
12
14
 
15
+ # @!parse attr_reader :magnetic_variation_degrees
16
+ # @return [Float]
13
17
  def magnetic_variation_degrees
14
18
  _nsew_signed_float(@fields[4], @fields[5])
15
19
  end
@@ -7,10 +7,14 @@ module NMEAPlus
7
7
 
8
8
  field_reader :blink_warning, 1, :_av_boolean
9
9
 
10
+ # @!parse attr_reader :latitude
11
+ # @return [Float]
10
12
  def latitude
11
13
  _degrees_minutes_to_decimal(@fields[2], @fields[3])
12
14
  end
13
15
 
16
+ # @!parse attr_reader :longitude
17
+ # @return [Float]
14
18
  def longitude
15
19
  _degrees_minutes_to_decimal(@fields[4], @fields[5])
16
20
  end
@@ -20,6 +24,8 @@ module NMEAPlus
20
24
  field_reader :speed_over_ground_knots, 8, :_float
21
25
  field_reader :track_made_good_degrees_true, 9, :_float
22
26
 
27
+ # @!parse attr_reader :magnetic_variation_degrees
28
+ # @return [Float]
23
29
  def magnetic_variation_degrees
24
30
  _nsew_signed_float(@fields[10], @fields[11])
25
31
  end
@@ -11,10 +11,14 @@ module NMEAPlus
11
11
  field_reader :waypoint_to, 4, :_integer
12
12
  field_reader :waypoint_from, 5, :_integer
13
13
 
14
+ # @!parse attr_reader :waypoint_latitude
15
+ # @return [Float]
14
16
  def waypoint_latitude
15
17
  _degrees_minutes_to_decimal(@fields[6], @fields[7])
16
18
  end
17
19
 
20
+ # @!parse attr_reader :waypoint_longitude
21
+ # @return [Float]
18
22
  def waypoint_longitude
19
23
  _degrees_minutes_to_decimal(@fields[8], @fields[9])
20
24
  end
@@ -5,16 +5,22 @@ module NMEAPlus
5
5
  module NMEA
6
6
  class RMC < NMEAPlus::Message::NMEA::NMEAMessage
7
7
 
8
+ # @!parse attr_reader :utc_time
9
+ # @return [Time]
8
10
  def utc_time
9
11
  _utc_date_time(@fields[9], @fields[1])
10
12
  end
11
13
 
12
14
  field_reader :active?, 2, :_av_boolean
13
15
 
16
+ # @!parse attr_reader :latitude
17
+ # @return [Float]
14
18
  def latitude
15
19
  _degrees_minutes_to_decimal(@fields[3], @fields[4])
16
20
  end
17
21
 
22
+ # @!parse attr_reader :longitude
23
+ # @return [Float]
18
24
  def longitude
19
25
  _degrees_minutes_to_decimal(@fields[5], @fields[6])
20
26
  end
@@ -22,6 +28,8 @@ module NMEAPlus
22
28
  field_reader :speed_over_ground_knots, 7, :_float
23
29
  field_reader :track_made_good_degrees_true, 8, :_float
24
30
 
31
+ # @!parse attr_reader :magnetic_variation_degrees
32
+ # @return [Float]
25
33
  def magnetic_variation_degrees
26
34
  _nsew_signed_float(@fields[10], @fields[11])
27
35
  end
@@ -7,6 +7,9 @@ module NMEAPlus
7
7
  field_reader :total_messages, 1, :_integer
8
8
  field_reader :message_number, 2, :_integer
9
9
  field_reader :mode, 3, :_string
10
+
11
+ # @!parse attr_reader :waypoints
12
+ # @return [Array<Integer>]
10
13
  def waypoints
11
14
  @fields[4..-1].map(&:to_i)
12
15
  end
@@ -8,6 +8,8 @@ module NMEAPlus
8
8
  field_reader :message_number, 2, :_integer
9
9
 
10
10
  # returns pairs of frequency, mode
11
+ # @!parse attr_reader :frequencies
12
+ # @return [Array<Float>]
11
13
  def frequencies
12
14
  @fields[3..-1].each_slice(2).to_a.map { |x| [x[0].to_f, x[1]] }
13
15
  end
@@ -4,14 +4,20 @@ module NMEAPlus
4
4
  module Message
5
5
  module NMEA
6
6
  class TRF < NMEAPlus::Message::NMEA::NMEAMessage
7
+ # @!parse attr_reader :utc_time
8
+ # @return [Time]
7
9
  def utc_time
8
10
  _utc_date_time(@fields[2], @fields[1])
9
11
  end
10
12
 
13
+ # @!parse attr_reader :latitude
14
+ # @return [Float]
11
15
  def latitude
12
16
  _degrees_minutes_to_decimal(@fields[3], @fields[4])
13
17
  end
14
18
 
19
+ # @!parse attr_reader :longitude
20
+ # @return [Float]
15
21
  def longitude
16
22
  _degrees_minutes_to_decimal(@fields[5], @fields[6])
17
23
  end
@@ -5,30 +5,39 @@ module NMEAPlus
5
5
  module NMEA
6
6
  class VTG < NMEAPlus::Message::NMEA::NMEAMessage
7
7
  # whether this is the new format. docs say check field #2 for value "2"
8
+ # @return [bool]
8
9
  def new_format?
9
10
  'T' == @fields[2]
10
11
  end
11
12
 
12
13
  field_reader :track_degrees_true, 1, :_float
13
14
 
15
+ # @!parse attr_reader :track_degrees_magnetic
16
+ # @return [Float]
14
17
  def track_degrees_magnetic
15
18
  f = new_format? ? 3 : 2
16
19
  return nil if @fields[f].nil? || @fields[f].empty?
17
20
  @fields[f].to_f
18
21
  end
19
22
 
23
+ # @!parse attr_reader :speed_knots
24
+ # @return [Float]
20
25
  def speed_knots
21
26
  f = new_format? ? 5 : 3
22
27
  return nil if @fields[f].nil? || @fields[f].empty?
23
28
  @fields[f].to_f
24
29
  end
25
30
 
31
+ # @!parse attr_reader :speed_kmh
32
+ # @return [Float]
26
33
  def speed_kmh
27
34
  f = new_format? ? 7 : 4
28
35
  return nil if @fields[f].nil? || @fields[f].empty?
29
36
  @fields[f].to_f
30
37
  end
31
38
 
39
+ # @!parse attr_reader :faa_mode
40
+ # @return [String]
32
41
  def faa_mode
33
42
  f = new_format? ? 9 : 100
34
43
  return nil if @fields[f].nil? || @fields[f].empty?
@@ -4,10 +4,14 @@ module NMEAPlus
4
4
  module Message
5
5
  module NMEA
6
6
  class WPL < NMEAPlus::Message::NMEA::NMEAMessage
7
+ # @!parse attr_reader :latitude
8
+ # @return [Float]
7
9
  def latitude
8
10
  _degrees_minutes_to_decimal(@fields[1], @fields[2])
9
11
  end
10
12
 
13
+ # @!parse attr_reader :longitude
14
+ # @return [Float]
11
15
  def longitude
12
16
  _degrees_minutes_to_decimal(@fields[3], @fields[4])
13
17
  end
@@ -4,8 +4,10 @@ module NMEAPlus
4
4
  module Message
5
5
  module NMEA
6
6
  class ZDA < NMEAPlus::Message::NMEA::NMEAMessage
7
- def utc_time
8
7
 
8
+ # @!parse attr_reader :utc_time
9
+ # @return [Time]
10
+ def utc_time
9
11
  re_format = /(\d{2})(\d{2})(\d{2}(\.\d+)?)/
10
12
  hms = re_format.match(@fields[1])
11
13
  begin
@@ -79,6 +79,8 @@ require_relative 'message/nmea/ztg'
79
79
  # proprietary
80
80
  require_relative 'message/nmea/pashr'
81
81
 
82
+ module NMEAPlus
83
+
82
84
  =begin boilerplate for message definitions
83
85
  require_relative 'base_nmea'
84
86
 
@@ -93,8 +95,6 @@ module NMEAPlus
93
95
  end
94
96
  =end
95
97
 
96
- module NMEAPlus
97
-
98
98
  # Defines a factory for NMEA messages, which will all use {NMEAPlus::Message::NMEA::NMEAMessage} as their base
99
99
  class NMEAMessageFactory < MessageFactory
100
100
 
@@ -1,3 +1,3 @@
1
1
  module NMEAPlus
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nmea_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Katz