sgslib 0.4.0 → 1.5.0

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.
data/lib/sgs/mission.rb CHANGED
@@ -1,53 +1,89 @@
1
+ #!/usr/bin/env ruby
1
2
  #
2
- # Copyright (c) 2013, Kalopa Research. All rights reserved. This is free
3
- # software; you can redistribute it and/or modify it under the terms of the
4
- # GNU General Public License as published by the Free Software Foundation;
5
- # either version 2, or (at your option) any later version.
3
+ # Copyright (c) 2013-2023, Kalopa Robotics Limited. All rights
4
+ # reserved.
6
5
  #
7
- # It is distributed in the hope that it will be useful, but WITHOUT
8
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10
- # for more details.
6
+ # This program is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU General Public License as
8
+ # published by the Free Software Foundation; either version 2 of
9
+ # the License, or (at your option) any later version.
11
10
  #
12
- # You should have received a copy of the GNU General Public License along
13
- # with this product; see the file COPYING. If not, write to the Free
14
- # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
15
  #
16
- # THIS SOFTWARE IS PROVIDED BY KALOPA RESEARCH "AS IS" AND ANY EXPRESS OR
17
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
- # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
- # IN NO EVENT SHALL KALOPA RESEARCH BE LIABLE FOR ANY DIRECT, INDIRECT,
20
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22
- # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
+ # 02110-1301, USA.
20
+ #
21
+ # THIS SOFTWARE IS PROVIDED BY KALOPA ROBOTICS LIMITED "AS IS" AND
22
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24
+ # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALOPA
25
+ # ROBOTICS LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28
+ # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ #
34
+ # ABSTRACT
26
35
  #
27
36
 
28
37
  ##
29
38
  # Routines for handling sailboat navigation and route planning.
30
39
  #
31
- require 'date'
32
- require 'nokogiri'
40
+ require 'yaml'
33
41
 
34
42
  module SGS
35
43
  #
36
44
  # Handle a specific mission.
37
45
  class Mission
46
+ attr_accessor :title, :url, :description
47
+ attr_accessor :launch_site, :launch_location
38
48
  attr_accessor :attractors, :repellors, :track
39
49
  attr_accessor :where, :time, :course, :distance
40
50
 
51
+ #
52
+ # Main daemon function (called from executable)
53
+ def self.daemon
54
+ loop do
55
+ sleep 300
56
+ end
57
+ end
58
+
59
+ #
60
+ # Load a new mission from the missions directory.
61
+ def self.file_load(filename)
62
+ parse YAML.load(File.open(filename))
63
+ end
64
+
65
+ #
66
+ # Load a new mission from the missions directory.
67
+ def self.parse(data)
68
+ mission = new
69
+ mission.parse(data)
70
+ mission
71
+ end
72
+
41
73
  #
42
74
  # Create the attractors and repellors as well as the track array
43
75
  # and other items. @where is our current TrackPoint, @current_wpt is
44
76
  # the waypoint we're working (-1 if none), @course is the heading/speed
45
77
  # the boat is on.
46
78
  def initialize
79
+ @title = nil
80
+ @url = nil
81
+ @description = nil
82
+ @launch_site = nil
83
+ @launch_location = nil
47
84
  @attractors = []
48
85
  @repellors = []
49
86
  @track = nil
50
- @current_wpt = -1
51
87
  @start_time = @time = nil
52
88
  @where = nil
53
89
  @course = Course.new
@@ -55,29 +91,6 @@ module SGS
55
91
  @swing = 60
56
92
  end
57
93
 
58
- #
59
- # Load a new mission from the missions directory.
60
- def self.load(filename)
61
- mission = new
62
- mission.read(File.open(filename))
63
- mission
64
- end
65
-
66
- #
67
- # Commence a mission...
68
- def commence(time = nil)
69
- @start_time = @time = time || Time.now
70
- @track = [TrackPoint.new(time, @where)]
71
- @current_wpt = 0
72
- end
73
-
74
- #
75
- # Terminate a mission.
76
- def terminate
77
- puts "***** Mission terminated! *****"
78
- @current_wpt = -1
79
- end
80
-
81
94
  #
82
95
  # Compute the best heading based on our current position and the position
83
96
  # of the current attractor. This is where the heavy-lifting happens
@@ -158,13 +171,6 @@ module SGS
158
171
  set_position(@time + how_long, @where + Bearing.new(@course.heading, distance))
159
172
  end
160
173
 
161
- #
162
- # On-mission means we have something to do. In other words, we have a
163
- # waypoint to get to.
164
- def active?
165
- @current_wpt >= 0 and @current_wpt < @attractors.count
166
- end
167
-
168
174
  #
169
175
  # How long has the mission been active?
170
176
  def elapsed
@@ -174,7 +180,7 @@ module SGS
174
180
  #
175
181
  # Return the current waypoint.
176
182
  def waypoint
177
- active? ? @attractors[@current_wpt] : nil
183
+ #@attractors[@current_wpt] : nil
178
184
  end
179
185
 
180
186
  #
@@ -237,135 +243,52 @@ module SGS
237
243
  loc = wpt.location
238
244
  end
239
245
  dist
240
- end
241
-
242
- #
243
- # Parse a mission file.
244
- def read(file)
245
- file.each do |line|
246
- unless line =~ /^#/
247
- args = line.split(':')
248
- code = args[0]
249
- loc = Location.parse_str(args[1])
250
- nrml = Bearing.dtor args[2].to_i
251
- dist = args[3].to_f
252
- name = args[4].chomp
253
- case code
254
- when /[Xx]/
255
- @where = loc
256
- @course.wind = Bearing.new(nrml, dist)
257
- when /\d/
258
- @attractors[code.to_i] = Waypoint.new(loc, nrml, dist, name)
259
- when /[Rr]/
260
- @repellors << Waypoint.new(loc, nrml, dist, name, true)
261
- end
262
- end
263
- end
264
- @current_wpt = -1
265
246
  end
266
247
 
267
248
  #
268
- # Write a mission to a file.
269
- def write(filename)
270
- File.open(filename, 'w') do |file|
271
- file.puts "#\n# My starting position."
272
- file.puts ["X", @where.to_s, @course.wind.angle_d.to_i, @course.wind.distance.to_i, "Starting position"].join(':')
273
- file.puts "#\n# Attractors."
274
- @attractors.each_with_index do |wpt, i|
275
- file.puts "%d:%s:%d:%f:%s" % [i,
276
- wpt.location,
277
- wpt.normal_d,
278
- wpt.radius,
279
- wpt.name]
280
- end
281
- file.puts "#\n# Repellors."
282
- @repellors.each do |wpt|
283
- file.puts "r:%s:%d:%f:%s" % [wpt.location,
284
- wpt.normal_d,
285
- wpt.radius,
286
- wpt.name]
287
- end
249
+ # Parse mission data from a hash.
250
+ def parse(data)
251
+ @title = data["title"] || "Untitled Mission"
252
+ @url = data["url"]
253
+ @description = data["description"]
254
+ if data["launch"]
255
+ @launch_site = data["launch"]["name"] || "Launch Site"
256
+ @launch_location = SGS::Location.parse data["launch"]
257
+ end
258
+ data["attractors"].each do |waypt_data|
259
+ waypt = Waypoint.parse(waypt_data)
260
+ waypt.attractor = true
261
+ @attractors << waypt
262
+ end
263
+ data["repellors"].each do |waypt_data|
264
+ waypt = Waypoint.parse(waypt_data)
265
+ waypt.attractor = false
266
+ @repellors << waypt
288
267
  end
289
268
  end
290
269
 
291
270
  #
292
- # Save the track.
293
- def track_save(filename)
294
- kml_write(File.open(filename, 'w'))
271
+ # Return a YAML string from the mission data
272
+ def to_yaml
273
+ to_hash.to_yaml
295
274
  end
296
275
 
297
276
  #
298
- # Write the track data as a KML file.
299
- # xml.LineString {
300
- # xml.extrude 1
301
- # xml.tessellate 1
302
- # xml.coordinates wpt.to_kml
303
- # }
304
- # }
305
- # xml.Placemark {
306
- # xml.styleUrl "#attractorLine"
307
- # xml.LineString {
308
- # xml.extrude 1
309
- # xml.tessellate 1
310
- # xml.coordinates wpt.to_axis_kml
311
- # }
312
- # }
313
- def kml_write(file)
314
- builder = Nokogiri::XML::Builder.new do |xml|
315
- xml.kml('xmlns' => 'http://www.opengis.net/kml/2.2',
316
- 'xmlns:gx' => 'http://www.google.com/kml/ext/2.2') {
317
- xml.Folder {
318
- xml_line_style(xml, "attractorLine", "0xffcf0000", 4)
319
- xml_line_style(xml, "repellorLine", "0xff00007f", 4)
320
- xml_line_style(xml, "trackLine")
321
- @attractors.each do |wpt|
322
- xml.Placemark {
323
- xml.name wpt.name
324
- xml.styleUrl "#attractorLine"
325
- xml.Point {
326
- xml.coordinates wpt.location.to_kml
327
- }
328
- }
329
- end
330
- @repellors.each do |wpt|
331
- xml.Placemark {
332
- xml.name wpt.name
333
- xml.styleUrl "#repellorLine"
334
- xml.Point {
335
- xml.coordinates wpt.location.to_kml
336
- }
337
- }
338
- end
339
- xml.Placemark {
340
- xml.name "Track"
341
- xml.styleUrl "#trackLine"
342
- xml.GX_Track {
343
- @track.each do |pt|
344
- xml.when pt.time.strftime('%Y-%m-%dT%H:%M:%S+00:00')
345
- end
346
- @track.each do |pt|
347
- xml.GX_coord pt.location.to_kml(' ')
348
- end
349
- }
350
- }
351
- }
352
- }
277
+ # Convert the mission into a hash
278
+ def to_hash
279
+ hash = {"title" => @title}
280
+ hash["url"] = @url if @url
281
+ hash["description"] = @description if @description
282
+ if @launch_location
283
+ hash["launch"] = @launch_location.to_hash
284
+ hash["launch"]["site"] = @launch_site
353
285
  end
354
- # Requires a hack to get rid of the 'gx:' for the when tag.
355
- file.puts builder.to_xml.gsub(/GX_/, 'gx:')
356
- end
357
-
358
- #
359
- # Do a line style. The colour is of the form aabbggrr for some unknown
360
- # reason...
361
- def xml_line_style(xml, label, color = "0xffffffff", width = 1)
362
- xml.Style(:id => label) {
363
- xml.LineStyle {
364
- xml.color color
365
- xml.width width
366
- xml.GX_labelVisibility 1
367
- }
368
- }
286
+ hash["attractors"] = []
287
+ @attractors.each do |waypt|
288
+ hash["attractors"] << waypt.to_hash
289
+ end
290
+ hash["repellors"] = []
291
+ hash
369
292
  end
370
293
  end
371
294
  end
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (c) 2023, Kalopa Robotics Limited. All rights reserved.
4
+ #
5
+ # This program is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as
7
+ # published by the Free Software Foundation; either version 2 of
8
+ # the License, or (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
+ # 02110-1301, USA.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY KALOPA ROBOTICS LIMITED "AS IS" AND
21
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
+ # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALOPA
24
+ # ROBOTICS LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
+ # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ #
33
+ # ABSTRACT
34
+ #
35
+
36
+ ##
37
+ # Mission state
38
+ #
39
+ module SGS
40
+ #
41
+ # Handle a specific mission.
42
+ class MissionStatus < RedisBase
43
+ attr_accessor :state, :current_waypoint, :start_time, :end_time
44
+
45
+ STATE_AWAITING = 0
46
+ STATE_READY_TO_START = 1
47
+ STATE_START_TEST = 2
48
+ STATE_RADIO_CONTROL = 3
49
+ STATE_COMPASS_FOLLOW = 4
50
+ STATE_WIND_FOLLOW = 5
51
+ STATE_COMPLETE = 6
52
+ STATE_TERMINATED = 7
53
+ STATE_FAILURE = 8
54
+
55
+ STATE_NAMES = [
56
+ ["Awaiting Instructions", STATE_AWAITING],
57
+ ["Ready to Start", STATE_READY_TO_START],
58
+ ["Initial Testing", STATE_START_TEST],
59
+ ["On-Mission - Radio Control", STATE_RADIO_CONTROL],
60
+ ["On-Mission - Track Compass Heading", STATE_COMPASS_FOLLOW],
61
+ ["On-Mission - Track Wind Direction", STATE_WIND_FOLLOW],
62
+ ["Mission Completed!", STATE_COMPLETE],
63
+ ["Mission Terminated", STATE_TERMINATED],
64
+ ["Mission Failure", STATE_FAILURE]
65
+ ].freeze
66
+
67
+ #
68
+ # Create the attractors and repellors as well as the track array
69
+ # and other items. @where is our current TrackPoint, @current_wpt is
70
+ # the waypoint we're working (-1 if none), @course is the heading/speed
71
+ # the boat is on.
72
+ def initialize
73
+ @state = STATE_AWAITING
74
+ @current_waypoint = 0
75
+ @start_time = @end_time = nil
76
+ @logger = Logger.new(STDOUT)
77
+ end
78
+
79
+ #
80
+ # Print a user-friendly label for the state
81
+ def state_name
82
+ STATE_NAMES[@state][0]
83
+ end
84
+
85
+ #
86
+ # Are we actively on-mission?
87
+ def active?
88
+ @state >= STATE_START_TEST && @state < STATE_COMPLETE
89
+ end
90
+
91
+ #
92
+ # Commence a mission...
93
+ def start_test!(time = nil)
94
+ @logger.warn "***** Starting test phase *****"
95
+ @start_time = time || Time.now
96
+ @state = STATE_START_TEST
97
+ @current_waypoint = 0
98
+ save_and_publish
99
+ end
100
+
101
+ #
102
+ # Terminate a mission.
103
+ def completed!(time = nil)
104
+ @end_time = time || Time.now
105
+ @state = STATE_COMPLETE
106
+ save_and_publish
107
+ @logger.warn "***** Mission completed! *****"
108
+ end
109
+
110
+ #
111
+ # Terminate a mission.
112
+ def terminate!(time = nil)
113
+ @end_time = time || Time.now
114
+ @state = STATE_TERMINATED
115
+ save_and_publish
116
+ @logger.warn "***** Mission terminated! *****"
117
+ end
118
+
119
+ #
120
+ # Terminate a mission.
121
+ def failure!(time = nil)
122
+ @end_time = time || Time.now
123
+ @state = STATE_FAILURE
124
+ save_and_publish
125
+ @logger.warn "***** Mission failure! *****"
126
+ end
127
+ end
128
+ end
data/lib/sgs/navigate.rb CHANGED
@@ -1,28 +1,36 @@
1
1
  #
2
- # Copyright (c) 2013, Kalopa Research. All rights reserved. This is free
3
- # software; you can redistribute it and/or modify it under the terms of the
4
- # GNU General Public License as published by the Free Software Foundation;
5
- # either version 2, or (at your option) any later version.
2
+ # Copyright (c) 2013-2023, Kalopa Robotics Limited. All rights
3
+ # reserved.
6
4
  #
7
- # It is distributed in the hope that it will be useful, but WITHOUT
8
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10
- # for more details.
5
+ # This program is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as
7
+ # published by the Free Software Foundation; either version 2 of
8
+ # the License, or (at your option) any later version.
11
9
  #
12
- # You should have received a copy of the GNU General Public License along
13
- # with this product; see the file COPYING. If not, write to the Free
14
- # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
15
14
  #
16
- # THIS SOFTWARE IS PROVIDED BY KALOPA RESEARCH "AS IS" AND ANY EXPRESS OR
17
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
- # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
- # IN NO EVENT SHALL KALOPA RESEARCH BE LIABLE FOR ANY DIRECT, INDIRECT,
20
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22
- # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
+ # 02110-1301, USA.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY KALOPA ROBOTICS LIMITED "AS IS" AND
21
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
+ # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALOPA
24
+ # ROBOTICS LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
+ # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ #
33
+ # ABSTRACT
26
34
  #
27
35
 
28
36
  ##
@@ -60,6 +68,14 @@ module SGS
60
68
  super
61
69
  end
62
70
 
71
+ #
72
+ # Main daemon function (called from executable)
73
+ def self.daemon
74
+ loop do
75
+ sleep 300
76
+ end
77
+ end
78
+
63
79
  #
64
80
  # What is the mode name?
65
81
  def mode_name
data/lib/sgs/nmea.rb CHANGED
@@ -1,28 +1,36 @@
1
1
  #
2
- # Copyright (c) 2013, Kalopa Research. All rights reserved. This is free
3
- # software; you can redistribute it and/or modify it under the terms of the
4
- # GNU General Public License as published by the Free Software Foundation;
5
- # either version 2, or (at your option) any later version.
2
+ # Copyright (c) 2013-2023, Kalopa Robotics Limited. All rights
3
+ # reserved.
6
4
  #
7
- # It is distributed in the hope that it will be useful, but WITHOUT
8
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10
- # for more details.
5
+ # This program is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as
7
+ # published by the Free Software Foundation; either version 2 of
8
+ # the License, or (at your option) any later version.
11
9
  #
12
- # You should have received a copy of the GNU General Public License along
13
- # with this product; see the file COPYING. If not, write to the Free
14
- # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
15
14
  #
16
- # THIS SOFTWARE IS PROVIDED BY KALOPA RESEARCH "AS IS" AND ANY EXPRESS OR
17
- # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
- # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
- # IN NO EVENT SHALL KALOPA RESEARCH BE LIABLE FOR ANY DIRECT, INDIRECT,
20
- # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
- # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22
- # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
+ # 02110-1301, USA.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY KALOPA ROBOTICS LIMITED "AS IS" AND
21
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22
+ # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23
+ # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALOPA
24
+ # ROBOTICS LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
+ # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ #
33
+ # ABSTRACT
26
34
  #
27
35
 
28
36
  ##
@@ -90,7 +98,9 @@ module SGS
90
98
  mn = @args[9][2..3].to_i
91
99
  yy = @args[9][4..5].to_i + 2000
92
100
  gps.time = Time.gm(yy, mn, dd, hh, mm, ss, us)
93
- gps.location = Location.parse ll_nmea(@args[3,4]), ll_nmea(@args[5,6])
101
+ pos = {"latitude" => ll_nmea(@args[3,4]),
102
+ "longitude" => ll_nmea(@args[5,6])}
103
+ gps.location = Location.parse pos
94
104
  gps.sog = @args[7].to_f
95
105
  gps.cmg = Bearing.dtor @args[8].to_f
96
106
  gps