sgslib 0.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +24 -17
- data/README.md +43 -7
- data/Rakefile +2 -2
- data/bin/console +34 -1
- data/exe/sgs_alarm +41 -0
- data/exe/sgs_diag +41 -0
- data/exe/sgs_gpsread +42 -0
- data/exe/sgs_logger +45 -0
- data/exe/sgs_mission +45 -0
- data/exe/sgs_nav +43 -0
- data/exe/sgs_otto +46 -0
- data/exe/sgs_report +44 -0
- data/lib/sgs/alarm.rb +55 -23
- data/lib/sgs/bearing.rb +150 -0
- data/lib/sgs/config.rb +35 -24
- data/lib/sgs/course.rb +29 -24
- data/lib/sgs/diagnostics.rb +49 -0
- data/lib/sgs/gps.rb +37 -21
- data/lib/sgs/location.rb +58 -159
- data/lib/sgs/logger.rb +35 -82
- data/lib/sgs/mission.rb +96 -173
- data/lib/sgs/mission_status.rb +128 -0
- data/lib/sgs/navigate.rb +37 -21
- data/lib/sgs/nmea.rb +32 -22
- data/lib/sgs/otto.rb +37 -21
- data/lib/sgs/redis_base.rb +32 -24
- data/lib/sgs/report.rb +49 -0
- data/lib/sgs/rpc.rb +29 -21
- data/lib/sgs/timing.rb +32 -24
- data/lib/sgs/version.rb +35 -1
- data/lib/sgs/waypoint.rb +69 -33
- data/lib/sgslib.rb +40 -24
- data/sgslib.gemspec +13 -5
- metadata +47 -19
- data/.gitignore +0 -9
- data/.rspec +0 -2
- data/.travis.yml +0 -4
- data/CODE_OF_CONDUCT.md +0 -49
- data/bin/setup +0 -8
data/lib/sgs/mission.rb
CHANGED
@@ -1,53 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
#
|
2
|
-
# Copyright (c) 2013, Kalopa
|
3
|
-
#
|
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
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
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
|
-
#
|
13
|
-
#
|
14
|
-
#
|
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
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
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 '
|
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
|
-
|
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
|
-
#
|
269
|
-
def
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
@
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
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
|
-
#
|
293
|
-
def
|
294
|
-
|
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
|
-
#
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
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
|
3
|
-
#
|
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
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
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
|
-
#
|
13
|
-
#
|
14
|
-
#
|
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
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
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
|
3
|
-
#
|
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
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
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
|
-
#
|
13
|
-
#
|
14
|
-
#
|
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
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
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
|
-
|
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
|