sgslib 0.4.0 → 1.5.1
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 +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 +74 -32
- data/lib/sgs/bearing.rb +151 -0
- data/lib/sgs/config.rb +35 -24
- data/lib/sgs/course.rb +29 -24
- data/lib/sgs/diagnostics.rb +50 -0
- data/lib/sgs/gps.rb +50 -21
- data/lib/sgs/location.rb +58 -159
- data/lib/sgs/logger.rb +30 -84
- data/lib/sgs/mission.rb +97 -173
- data/lib/sgs/mission_status.rb +127 -0
- data/lib/sgs/navigate.rb +56 -21
- data/lib/sgs/nmea.rb +32 -22
- data/lib/sgs/otto.rb +207 -22
- data/lib/sgs/redis_base.rb +32 -24
- data/lib/sgs/report.rb +54 -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 +34 -21
- data/sgslib.gemspec +16 -6
- metadata +91 -21
- 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,90 @@
|
|
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
|
+
puts "Mission management system starting up..."
|
55
|
+
loop do
|
56
|
+
sleep 300
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Load a new mission from the missions directory.
|
62
|
+
def self.file_load(filename)
|
63
|
+
parse YAML.load(File.open(filename))
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Load a new mission from the missions directory.
|
68
|
+
def self.parse(data)
|
69
|
+
mission = new
|
70
|
+
mission.parse(data)
|
71
|
+
mission
|
72
|
+
end
|
73
|
+
|
41
74
|
#
|
42
75
|
# Create the attractors and repellors as well as the track array
|
43
76
|
# and other items. @where is our current TrackPoint, @current_wpt is
|
44
77
|
# the waypoint we're working (-1 if none), @course is the heading/speed
|
45
78
|
# the boat is on.
|
46
79
|
def initialize
|
80
|
+
@title = nil
|
81
|
+
@url = nil
|
82
|
+
@description = nil
|
83
|
+
@launch_site = nil
|
84
|
+
@launch_location = nil
|
47
85
|
@attractors = []
|
48
86
|
@repellors = []
|
49
87
|
@track = nil
|
50
|
-
@current_wpt = -1
|
51
88
|
@start_time = @time = nil
|
52
89
|
@where = nil
|
53
90
|
@course = Course.new
|
@@ -55,29 +92,6 @@ module SGS
|
|
55
92
|
@swing = 60
|
56
93
|
end
|
57
94
|
|
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
95
|
#
|
82
96
|
# Compute the best heading based on our current position and the position
|
83
97
|
# of the current attractor. This is where the heavy-lifting happens
|
@@ -158,13 +172,6 @@ module SGS
|
|
158
172
|
set_position(@time + how_long, @where + Bearing.new(@course.heading, distance))
|
159
173
|
end
|
160
174
|
|
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
175
|
#
|
169
176
|
# How long has the mission been active?
|
170
177
|
def elapsed
|
@@ -174,7 +181,7 @@ module SGS
|
|
174
181
|
#
|
175
182
|
# Return the current waypoint.
|
176
183
|
def waypoint
|
177
|
-
|
184
|
+
#@attractors[@current_wpt] : nil
|
178
185
|
end
|
179
186
|
|
180
187
|
#
|
@@ -237,135 +244,52 @@ module SGS
|
|
237
244
|
loc = wpt.location
|
238
245
|
end
|
239
246
|
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
247
|
end
|
266
248
|
|
267
249
|
#
|
268
|
-
#
|
269
|
-
def
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
@
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
wpt.name]
|
287
|
-
end
|
250
|
+
# Parse mission data from a hash.
|
251
|
+
def parse(data)
|
252
|
+
@title = data["title"] || "Untitled Mission"
|
253
|
+
@url = data["url"]
|
254
|
+
@description = data["description"]
|
255
|
+
if data["launch"]
|
256
|
+
@launch_site = data["launch"]["name"] || "Launch Site"
|
257
|
+
@launch_location = SGS::Location.parse data["launch"]
|
258
|
+
end
|
259
|
+
data["attractors"].each do |waypt_data|
|
260
|
+
waypt = Waypoint.parse(waypt_data)
|
261
|
+
waypt.attractor = true
|
262
|
+
@attractors << waypt
|
263
|
+
end
|
264
|
+
data["repellors"].each do |waypt_data|
|
265
|
+
waypt = Waypoint.parse(waypt_data)
|
266
|
+
waypt.attractor = false
|
267
|
+
@repellors << waypt
|
288
268
|
end
|
289
269
|
end
|
290
270
|
|
291
271
|
#
|
292
|
-
#
|
293
|
-
def
|
294
|
-
|
272
|
+
# Return a YAML string from the mission data
|
273
|
+
def to_yaml
|
274
|
+
to_hash.to_yaml
|
295
275
|
end
|
296
276
|
|
297
277
|
#
|
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
|
-
}
|
278
|
+
# Convert the mission into a hash
|
279
|
+
def to_hash
|
280
|
+
hash = {"title" => @title}
|
281
|
+
hash["url"] = @url if @url
|
282
|
+
hash["description"] = @description if @description
|
283
|
+
if @launch_location
|
284
|
+
hash["launch"] = @launch_location.to_hash
|
285
|
+
hash["launch"]["site"] = @launch_site
|
353
286
|
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
|
-
}
|
287
|
+
hash["attractors"] = []
|
288
|
+
@attractors.each do |waypt|
|
289
|
+
hash["attractors"] << waypt.to_hash
|
290
|
+
end
|
291
|
+
hash["repellors"] = []
|
292
|
+
hash
|
369
293
|
end
|
370
294
|
end
|
371
295
|
end
|
@@ -0,0 +1,127 @@
|
|
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
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Print a user-friendly label for the state
|
80
|
+
def state_name
|
81
|
+
STATE_NAMES[@state][0]
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Are we actively on-mission?
|
86
|
+
def active?
|
87
|
+
@state >= STATE_START_TEST && @state < STATE_COMPLETE
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Commence a mission...
|
92
|
+
def start_test!(time = nil)
|
93
|
+
puts "***** Starting test phase *****"
|
94
|
+
@start_time = time || Time.now
|
95
|
+
@state = STATE_START_TEST
|
96
|
+
@current_waypoint = 0
|
97
|
+
save_and_publish
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Terminate a mission.
|
102
|
+
def completed!(time = nil)
|
103
|
+
@end_time = time || Time.now
|
104
|
+
@state = STATE_COMPLETE
|
105
|
+
save_and_publish
|
106
|
+
puts "***** Mission completed! *****"
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Terminate a mission.
|
111
|
+
def terminate!(time = nil)
|
112
|
+
@end_time = time || Time.now
|
113
|
+
@state = STATE_TERMINATED
|
114
|
+
save_and_publish
|
115
|
+
puts "***** Mission terminated! *****"
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Terminate a mission.
|
120
|
+
def failure!(time = nil)
|
121
|
+
@end_time = time || Time.now
|
122
|
+
@state = STATE_FAILURE
|
123
|
+
save_and_publish
|
124
|
+
puts "***** Mission failure! *****"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
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,33 @@ module SGS
|
|
60
68
|
super
|
61
69
|
end
|
62
70
|
|
71
|
+
#
|
72
|
+
# Main daemon function (called from executable)
|
73
|
+
def self.daemon
|
74
|
+
puts "Navigation system starting up..."
|
75
|
+
#
|
76
|
+
# Load the mission data from Redis and augment it with the
|
77
|
+
# contents of the mission file.
|
78
|
+
config = SGS::Config.load
|
79
|
+
mission = SGS::Mission.file_load config.mission_file
|
80
|
+
#
|
81
|
+
# Now listen for GPS data...
|
82
|
+
SGS::GPS.subscribe do |count|
|
83
|
+
puts "Received new GPS count: #{count}"
|
84
|
+
case SGS::MissionStatus.state
|
85
|
+
when STATE_COMPASS_FOLLOW
|
86
|
+
when STATE_WIND_FOLLOW
|
87
|
+
mission.navigate
|
88
|
+
when STATE_COMPLETE
|
89
|
+
when STATE_TERMINATED
|
90
|
+
when STATE_FAILURE
|
91
|
+
mission.hold_station
|
92
|
+
end
|
93
|
+
gps = SGS::GPS.load
|
94
|
+
p gps
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
63
98
|
#
|
64
99
|
# What is the mode name?
|
65
100
|
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
|