nmea_plus 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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