sgslib 1.5.1 → 1.6.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.
- checksums.yaml +4 -4
- data/lib/sgs/alarm.rb +2 -2
- data/lib/sgs/bearing.rb +31 -3
- data/lib/sgs/config.rb +0 -1
- data/lib/sgs/course.rb +18 -5
- data/lib/sgs/diagnostics.rb +1 -1
- data/lib/sgs/gps.rb +23 -3
- data/lib/sgs/location.rb +115 -59
- data/lib/sgs/logger.rb +1 -1
- data/lib/sgs/mission.rb +61 -185
- data/lib/sgs/mission_status.rb +16 -4
- data/lib/sgs/navigate.rb +203 -79
- data/lib/sgs/nmea.rb +3 -2
- data/lib/sgs/otto.rb +181 -78
- data/lib/sgs/redis_base.rb +9 -9
- data/lib/sgs/report.rb +2 -2
- data/lib/sgs/rpc.rb +5 -6
- data/lib/sgs/version.rb +1 -1
- data/lib/sgs/waypoint.rb +2 -2
- data/sgslib.gemspec +3 -3
- metadata +8 -10
- data/exe/sgs_nav +0 -43
data/lib/sgs/otto.rb
CHANGED
@@ -31,6 +31,13 @@
|
|
31
31
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
32
32
|
#
|
33
33
|
# ABSTRACT
|
34
|
+
# This daemon handles all serial I/O with the low-level board (Otto). Otto
|
35
|
+
# publishes various status messages at regular intervals, and has a series
|
36
|
+
# of registers which can be used to alter the low-level operational state.
|
37
|
+
# This daemon code has two threads. One thread listens for RPCs to update
|
38
|
+
# Otto register state, and the other listens for status messages from Otto.
|
39
|
+
# The class also has helper functions for converting between Otto data
|
40
|
+
# formats (usually 8bit) and internal formats (usually floating point).
|
34
41
|
#
|
35
42
|
require 'serialport'
|
36
43
|
require 'msgpack'
|
@@ -40,49 +47,87 @@ require 'msgpack'
|
|
40
47
|
#
|
41
48
|
module SGS
|
42
49
|
class Otto < RedisBase
|
43
|
-
attr_accessor :
|
44
|
-
attr_accessor :mode, :rudder_m, :rudder_c, :sail_m, :sail_c
|
50
|
+
attr_accessor :mode, :serial_port
|
45
51
|
attr_accessor :bv_m, :bv_c, :bi_m, :bi_c, :bt_m, :bt_c, :sv_m, :sv_c
|
46
|
-
|
47
|
-
attr_reader :
|
52
|
+
attr_reader :alarm_status
|
53
|
+
attr_reader :actual_rudder, :actual_sail
|
48
54
|
attr_reader :otto_mode, :otto_timestamp, :telemetry
|
49
55
|
|
56
|
+
#
|
57
|
+
# Updates to Otto are done by setting an 8bit register value, as below.
|
58
|
+
ALARM_CLEAR_REGISTER = 0
|
59
|
+
MISSION_CONTROL_REGISTER = 1
|
60
|
+
MODE_REGISTER = 2
|
61
|
+
BUZZER_REGISTER = 3
|
62
|
+
RUDDER_ANGLE_REGISTER = 4
|
63
|
+
SAIL_ANGLE_REGISTER = 5
|
64
|
+
COMPASS_HEADING_REGISTER = 6
|
65
|
+
MIN_COMPASS_REGISTER = 7
|
66
|
+
MAX_COMPASS_REGISTER =8
|
67
|
+
AWA_HEADING_REGISTER = 9
|
68
|
+
MIN_AWA_REGISTER = 10
|
69
|
+
MAX_AWA_REGISTER = 11
|
70
|
+
WAKE_DURATION_REGISTER = 12
|
71
|
+
NEXT_WAKEUP_REGISTER = 13
|
72
|
+
MAX_REGISTER = 14
|
73
|
+
|
74
|
+
#
|
75
|
+
# This is different from mission mode. This mode defines how Otto should
|
76
|
+
# operate. Inert means "do nothing". Diagnostic mode is for the low-level
|
77
|
+
# code to run self-checks and calibrations. Manual means that the upper
|
78
|
+
# level system controls the rudder and sail angle without any higher-level
|
79
|
+
# PID controller. Track compass means that the boat will try to keep the
|
80
|
+
# actual compass reading within certain parameters, and track AWA will
|
81
|
+
# try to maintain a specific "apparent wind angle".
|
50
82
|
MODE_INERT = 0
|
51
|
-
|
83
|
+
MODE_DIAG = 1
|
52
84
|
MODE_MANUAL = 2
|
53
|
-
|
54
|
-
|
85
|
+
MODE_REMOTE = 3
|
86
|
+
MODE_TRACK_COMPASS = 4
|
87
|
+
MODE_TRACK_AWA = 5
|
55
88
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
89
|
+
#
|
90
|
+
# Define some tweaks for rudder and sail setting. Rudder goes from
|
91
|
+
# +/-40 degrees, with zero indicating a straight rudder. On Otto, this
|
92
|
+
# translates to 0 (for -40.0), 128 (for the zero position) and 255 (for
|
93
|
+
# +40 degrees of rudder). A fully trimmed-in sail is zero and a fully
|
94
|
+
# extended sail is 255 (0->100 from a function perspective).
|
95
|
+
RUDDER_MAX = 40.0
|
96
|
+
RUDDER_MIN = -40.0
|
97
|
+
RUDDER_M = 3.175
|
98
|
+
RUDDER_C = 128.0
|
99
|
+
SAIL_MAX = 100.0
|
100
|
+
SAIL_MIN = 0.0
|
101
|
+
SAIL_M = 2.55
|
102
|
+
SAIL_C = 0.0
|
60
103
|
|
61
104
|
#
|
62
|
-
# Set up some useful defaults. We assume rudder goes from 0 to
|
63
|
-
# the sail angle.
|
105
|
+
# Set up some useful defaults. We assume rudder goes from 0 to 255 as does
|
106
|
+
# the sail angle.
|
64
107
|
def initialize
|
65
108
|
serial_port = nil
|
66
109
|
#
|
67
|
-
# Configure the Mx + C values for sail and rudder
|
68
|
-
@rudder_m = 2.5
|
69
|
-
@rudder_c = 100.0
|
70
|
-
@sail_m = 2.0
|
71
|
-
@sail_c = 0.0
|
72
|
-
#
|
73
|
-
# Now set the rudder and sail to default positions (rudder is centered)
|
74
|
-
rudder = 0.0
|
75
|
-
sail = 0.0
|
76
|
-
#
|
77
110
|
# Set some defaults for the read-back parameters
|
78
|
-
|
79
|
-
@
|
80
|
-
|
111
|
+
# The following five parameters are reported back by Otto with a status
|
112
|
+
# message, and are read-only. @alarm_status is 16 bits while the other
|
113
|
+
# four are 8-bit values. The helper methods convert these 8-bit values
|
114
|
+
# into radians, etc. The telemetry parameters are used to capture
|
115
|
+
# telemetry data from Otto.
|
116
|
+
@alarm_status = 0
|
117
|
+
@actual_rudder = @actual_sail = @actual_awa = @actual_compass = 0
|
81
118
|
@telemetry = Array.new(16)
|
82
119
|
#
|
120
|
+
# Mode is used by Otto to decide how to steer the boat and trim the
|
121
|
+
# sails.
|
122
|
+
@otto_mode = MODE_INERT
|
123
|
+
@otto_timestamp = 1000
|
124
|
+
#
|
83
125
|
# Set up some basic parameters for battery/solar readings
|
84
126
|
@bv_m = @bi_m = @bt_m = @sv_m = 1.0
|
85
127
|
@bv_c = @bi_c = @bt_c = @sv_c = 0.0
|
128
|
+
#
|
129
|
+
# RPC client / server
|
130
|
+
@rpc_client = @rpc_server = nil
|
86
131
|
super
|
87
132
|
end
|
88
133
|
|
@@ -96,7 +141,7 @@ module SGS
|
|
96
141
|
def self.daemon
|
97
142
|
puts "Low-level (Otto) communication subsystem starting up..."
|
98
143
|
otto = new
|
99
|
-
config =
|
144
|
+
config = Config.load
|
100
145
|
otto.serial_port = SerialPort.new config.otto_device, config.otto_speed
|
101
146
|
otto.serial_port.read_timeout = 10000
|
102
147
|
#
|
@@ -111,9 +156,31 @@ module SGS
|
|
111
156
|
t2.join
|
112
157
|
end
|
113
158
|
|
159
|
+
#
|
160
|
+
# Build a C include file based on the current register definitions
|
161
|
+
def self.build_include(fname)
|
162
|
+
otto = new
|
163
|
+
File.open(fname, "w") do |f|
|
164
|
+
f.puts "/*\n * Autogenerated by #{__FILE__}.\n * DO NOT HAND-EDIT!\n */"
|
165
|
+
constants.sort.each do |c|
|
166
|
+
if c.to_s =~ /REGISTER$/
|
167
|
+
cval = Otto.const_get(c)
|
168
|
+
str = "#define SGS_#{c.to_s}"
|
169
|
+
str += "\t" if str.length < 32
|
170
|
+
str += "\t#{cval}"
|
171
|
+
f.puts str
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
114
177
|
#
|
115
178
|
# Synchronize with the low-level board by sending CQ messages until
|
116
|
-
# they respond.
|
179
|
+
# they respond. When Mother boots up, the serial console is shared with
|
180
|
+
# Otto so a lot of rubbish is sent to the low-level board. To notify
|
181
|
+
# Otto that we are now talking sense, we send @@CQ! and Otto responds
|
182
|
+
# with +CQOK. Note that this function, which is always called before any
|
183
|
+
# of the threads, is bidirectional in terms of serial I/O.
|
117
184
|
def synchronize
|
118
185
|
index = 0
|
119
186
|
backoffs = [1, 1, 1, 1, 2, 2, 3, 5, 10, 10, 20, 30, 60]
|
@@ -154,6 +221,10 @@ module SGS
|
|
154
221
|
#
|
155
222
|
# Telemetry data (every two seconds)
|
156
223
|
parse_telemetry(data[1..])
|
224
|
+
when '*'
|
225
|
+
#
|
226
|
+
# Message for the debug log
|
227
|
+
parse_debug(data[1..])
|
157
228
|
end
|
158
229
|
end
|
159
230
|
end
|
@@ -164,31 +235,19 @@ module SGS
|
|
164
235
|
puts "Starting OTTO writer thread..."
|
165
236
|
#
|
166
237
|
# Now listen for Redis PUB/SUB requests and act on each one.
|
238
|
+
myredis = Redis.new
|
167
239
|
while true
|
168
|
-
channel, request =
|
240
|
+
channel, request = myredis.brpop("otto")
|
169
241
|
request = MessagePack.unpack(request)
|
170
242
|
puts "Req:[#{request.inspect}]"
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
puts "
|
176
|
-
|
177
|
-
# Don't let the command stack get too big.
|
178
|
-
while @command_stack.length > 5
|
179
|
-
sleep 5
|
180
|
-
end
|
181
|
-
|
243
|
+
params = request['params']
|
244
|
+
next if request['method'] != "set_local_register"
|
245
|
+
puts "PARAMS: #{params}"
|
246
|
+
cmd = "R%d=%X\r\n" % params
|
247
|
+
puts "Command: #{cmd}"
|
248
|
+
@serial_port.write cmd
|
182
249
|
puts "> Sending command: #{str}"
|
183
250
|
@serial_port.puts "#{str}"
|
184
|
-
|
185
|
-
reply = {
|
186
|
-
'id' => id,
|
187
|
-
'jsonrpc' => '2.0',
|
188
|
-
'result' => result
|
189
|
-
}
|
190
|
-
SGS::RedisBase.redis.rpush(id, MessagePack.pack(reply))
|
191
|
-
SGS::RedisBase.redis.expire(id, 30)
|
192
251
|
end
|
193
252
|
end
|
194
253
|
|
@@ -208,13 +267,13 @@ module SGS
|
|
208
267
|
# Parse a status message from Otto. In the form:
|
209
268
|
# 0001:C000:0000
|
210
269
|
def parse_status(status)
|
211
|
-
puts "
|
270
|
+
puts "OTTO PARSE: #{status}"
|
212
271
|
args = status.split /:/
|
213
272
|
@alarm_status = args[0].to_i(16)
|
214
273
|
wc = args[1].to_i(16)
|
215
274
|
rs = args[2].to_i(16)
|
216
|
-
@
|
217
|
-
@
|
275
|
+
@actual_awa = (wc >> 8) & 0xff
|
276
|
+
@actual_compass = (wc & 0xff)
|
218
277
|
@actual_rudder = (rs >> 8) & 0xff
|
219
278
|
@actual_sail = (rs & 0xff)
|
220
279
|
p self
|
@@ -225,7 +284,6 @@ module SGS
|
|
225
284
|
# Parse a timestamp message from Otto. In the form: "000FE2" 24 bits
|
226
285
|
# representing the elapsed seconds since Otto restarted.
|
227
286
|
def parse_tstamp(tstamp)
|
228
|
-
puts "Parse timestamp: #{tstamp}"
|
229
287
|
newval = tstamp.to_i(16)
|
230
288
|
if newval < @otto_timestamp
|
231
289
|
puts "ALARM! Otto rebooted (or something)..."
|
@@ -237,7 +295,6 @@ module SGS
|
|
237
295
|
# Parse a mode state message from Otto. In the form: "00". An eight bit
|
238
296
|
# quantity.
|
239
297
|
def parse_mode(mode)
|
240
|
-
puts "Parse Otto Mode State: #{mode}"
|
241
298
|
@otto_mode = mode.to_i(16)
|
242
299
|
end
|
243
300
|
|
@@ -245,80 +302,126 @@ module SGS
|
|
245
302
|
# Parse a telemetry message from Otto. In the form: "7327" where the first
|
246
303
|
# character is the channel (0->9) and the remaining 12 bits are the value.
|
247
304
|
def parse_telemetry(telemetry)
|
248
|
-
puts "Parse Otto Telemetry Data: #{telemetry}"
|
249
305
|
data = telemetry.to_i(16)
|
250
306
|
chan = (data >> 12) & 0xf
|
251
|
-
@telemetry[chan] = data &
|
307
|
+
@telemetry[chan] = data & 0xfff
|
308
|
+
end
|
309
|
+
|
310
|
+
#
|
311
|
+
# Parse a debug message from the low-level code. Basically just append it
|
312
|
+
# to a log file.
|
313
|
+
def parse_debug(debug_data)
|
314
|
+
puts "DEBUG: [#{debug_data}].\n"
|
315
|
+
end
|
316
|
+
|
317
|
+
#
|
318
|
+
# Clear an alarm setting
|
319
|
+
def alarm_clear(alarm)
|
320
|
+
set_register(ALARM_CLEAR_REGISTER, alarm)
|
321
|
+
end
|
322
|
+
|
323
|
+
#
|
324
|
+
# Set the Otto mode
|
325
|
+
def mode=(val)
|
326
|
+
set_register(MODE_REGISTER, val) if @otto_mode != val
|
252
327
|
end
|
253
328
|
|
254
329
|
#
|
255
330
|
# Set the required rudder angle. Input values range from +/- 40.0 degrees
|
256
331
|
def rudder=(val)
|
257
|
-
val =
|
258
|
-
val =
|
259
|
-
|
332
|
+
val = RUDDER_MIN if val < RUDDER_MIN
|
333
|
+
val = RUDDER_MAX if val > RUDDER_MAX
|
334
|
+
val = (RUDDER_M * val.to_f + RUDDER_C).to_i
|
335
|
+
if val != @actual_rudder
|
336
|
+
@actual_rudder = val
|
337
|
+
set_register(RUDDER_ANGLE_REGISTER, val)
|
338
|
+
end
|
339
|
+
mode = MODE_MANUAL
|
260
340
|
end
|
261
341
|
|
262
342
|
#
|
263
343
|
# Return the rudder angle in degrees
|
264
344
|
def rudder
|
265
|
-
(@
|
345
|
+
(@actual_rudder.to_f - RUDDER_C) / RUDDER_M
|
266
346
|
end
|
267
347
|
|
268
348
|
#
|
269
|
-
# Set the required sail angle. Input values range from 0 ->
|
349
|
+
# Set the required sail angle. Input values range from 0 -> 100.
|
270
350
|
def sail=(val)
|
271
|
-
val =
|
272
|
-
val =
|
273
|
-
|
351
|
+
val = SAIL_MIN if val < SAIL_MIN
|
352
|
+
val = SAIL_MAX if val > SAIL_MAX
|
353
|
+
val = (SAIL_M * val.to_f + SAIL_C).to_i
|
354
|
+
if val != @actual_sail
|
355
|
+
@actual_sail = val
|
356
|
+
set_register(SAIL_ANGLE_REGISTER, val)
|
357
|
+
end
|
358
|
+
mode = MODE_MANUAL
|
274
359
|
end
|
275
360
|
|
276
361
|
#
|
277
362
|
# Return the sail setting (0.0 -> 100.0)
|
278
363
|
def sail
|
279
|
-
(@
|
364
|
+
(@actual_sail.to_f - SAIL_C) / SAIL_M
|
280
365
|
end
|
281
366
|
|
282
367
|
#
|
283
368
|
# Return the compass angle (in radians)
|
284
369
|
def compass
|
285
|
-
@
|
370
|
+
Bearing.xtor(@actual_compass)
|
286
371
|
end
|
287
372
|
|
288
373
|
#
|
289
374
|
# Return the apparent wind angle (in radians)
|
290
375
|
def awa
|
291
|
-
@
|
376
|
+
@actual_awa -= 256 if @actual_awa > 128
|
377
|
+
Bearing.xtor(@actual_awa)
|
378
|
+
end
|
379
|
+
|
380
|
+
#
|
381
|
+
# Return the actual wind direction (in radians)
|
382
|
+
def wind
|
383
|
+
Bearing.xtor(@actual_compass + @actual_awa)
|
292
384
|
end
|
293
385
|
|
294
386
|
#
|
295
|
-
# Set the required compass reading
|
387
|
+
# Set the required compass reading (in radians)
|
296
388
|
def track_compass=(val)
|
297
|
-
|
298
|
-
|
389
|
+
val = Bearing.rtox(val)
|
390
|
+
if @track_compass.nil? or @track_compass != val
|
391
|
+
@track_compass = val
|
392
|
+
set_register(COMPASS_HEADING_REGISTER, val)
|
299
393
|
end
|
300
|
-
|
301
|
-
@raw_tc = (val.to_f * 128.0 / Math::PI).to_i
|
394
|
+
mode = MODE_TRACK_COMPASS
|
302
395
|
end
|
303
396
|
|
304
397
|
#
|
305
398
|
# Return the compass value for tracking.
|
306
399
|
def track_compass
|
307
|
-
@
|
400
|
+
Bearing.xtor(@track_compass)
|
308
401
|
end
|
309
402
|
|
310
403
|
#
|
311
|
-
# Set the required AWA for tracking.
|
404
|
+
# Set the required AWA for tracking (in radians).
|
312
405
|
def track_awa=(val)
|
313
|
-
val =
|
314
|
-
|
315
|
-
|
406
|
+
val = Bearing.rtox(val)
|
407
|
+
if @track_awa.nil? or @track_awa != val
|
408
|
+
@track_awa = val
|
409
|
+
set_register(AWA_HEADING_REGISTER, val)
|
410
|
+
end
|
411
|
+
mode = MODE_TRACK_AWA
|
316
412
|
end
|
317
413
|
|
318
414
|
#
|
319
|
-
# Return the current tracking AWA.
|
415
|
+
# Return the current tracking AWA (in radians).
|
320
416
|
def track_awa
|
321
|
-
@
|
417
|
+
Bearing.xtor(@track_awa)
|
418
|
+
end
|
419
|
+
|
420
|
+
#
|
421
|
+
# RPC client call to set register - sent to writer function above
|
422
|
+
def set_register(regno, value)
|
423
|
+
@rpc_client = RPCClient.new("otto") unless @rpc_client
|
424
|
+
@rpc_client.set_local_register(regno, value)
|
322
425
|
end
|
323
426
|
end
|
324
427
|
end
|
data/lib/sgs/redis_base.rb
CHANGED
@@ -75,7 +75,7 @@ module SGS
|
|
75
75
|
# Initialize a Redis variable.
|
76
76
|
def self.var_init(var, val, idx = nil)
|
77
77
|
cls = new
|
78
|
-
|
78
|
+
RedisBase.redis.setnx cls.make_redis_name(var, :idx => idx), self.to_redis(var, val, idx)
|
79
79
|
end
|
80
80
|
|
81
81
|
#
|
@@ -96,8 +96,8 @@ module SGS
|
|
96
96
|
# It's an array - iterate and read the values.
|
97
97
|
lval.size.times do |idx|
|
98
98
|
idx_val = lval[idx]
|
99
|
-
lval[idx] = redis_read_var var, idx_val.class, :idx => idx
|
100
|
-
|
99
|
+
lval[idx] = redis_read_var var, idx_val.class, :idx => idx
|
100
|
+
end
|
101
101
|
elsif lval.kind_of? Location
|
102
102
|
#
|
103
103
|
# ::FIXME:: Yes. this is a hack.
|
@@ -141,7 +141,7 @@ module SGS
|
|
141
141
|
#
|
142
142
|
# Inside a multi-block, set all the variables and increment
|
143
143
|
# the count.
|
144
|
-
|
144
|
+
RedisBase.redis.multi do |pipeline|
|
145
145
|
var_list.each do |key, value|
|
146
146
|
pipeline.set key, value
|
147
147
|
end
|
@@ -157,7 +157,7 @@ module SGS
|
|
157
157
|
# class name), you can remember the last received count and decide if
|
158
158
|
# there is fresh data. Or, you can just act anyway.
|
159
159
|
def publish
|
160
|
-
|
160
|
+
RedisBase.redis.publish self.class.redis_handle, count.to_s
|
161
161
|
end
|
162
162
|
|
163
163
|
#
|
@@ -182,7 +182,7 @@ module SGS
|
|
182
182
|
#
|
183
183
|
# Retrieve the count
|
184
184
|
def count
|
185
|
-
|
185
|
+
RedisBase.redis.get count_name
|
186
186
|
end
|
187
187
|
|
188
188
|
#
|
@@ -195,7 +195,7 @@ module SGS
|
|
195
195
|
# Get an instance variable value from a Redis value.
|
196
196
|
def redis_read_var(var, klass, opts = {})
|
197
197
|
redis_name = make_redis_name var, opts
|
198
|
-
redis_val =
|
198
|
+
redis_val = RedisBase.redis.get redis_name
|
199
199
|
redis_val = nil if redis_val == ""
|
200
200
|
if redis_val
|
201
201
|
if not klass or klass == NilClass
|
@@ -211,9 +211,9 @@ module SGS
|
|
211
211
|
when klass == Float
|
212
212
|
redis_val = redis_val.to_f
|
213
213
|
when klass == FalseClass
|
214
|
-
redis_val =
|
214
|
+
redis_val = (redis_val == "true" or redis_val == "TRUE")
|
215
215
|
when klass == TrueClass
|
216
|
-
redis_val = true
|
216
|
+
redis_val = (redis_val == "true" or redis_val == "TRUE")
|
217
217
|
end
|
218
218
|
end
|
219
219
|
redis_val
|
data/lib/sgs/report.rb
CHANGED
@@ -38,12 +38,12 @@ require 'serialport'
|
|
38
38
|
# Routines for handling sailboat navigation and route planning.
|
39
39
|
#
|
40
40
|
module SGS
|
41
|
-
class Report
|
41
|
+
class Report
|
42
42
|
#
|
43
43
|
# Main daemon function (called from executable)
|
44
44
|
def self.daemon
|
45
45
|
puts "Reporting subsystem starting up..."
|
46
|
-
config =
|
46
|
+
config = Config.load
|
47
47
|
sp = SerialPort.new config.comm_device, config.comm_speed
|
48
48
|
sp.read_timeout = 10000
|
49
49
|
loop do
|
data/lib/sgs/rpc.rb
CHANGED
@@ -55,9 +55,8 @@ module SGS
|
|
55
55
|
'method' => name,
|
56
56
|
'params' => args
|
57
57
|
}
|
58
|
-
|
59
|
-
|
60
|
-
MessagePack.unpack(response)['result']
|
58
|
+
puts "RPC CLIENT SENDING MESSAGE! request: #{request.inspect}, channel: #{@channel}"
|
59
|
+
RedisBase.redis.lpush(@channel, request.to_msgpack)
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
@@ -70,7 +69,7 @@ module SGS
|
|
70
69
|
def start
|
71
70
|
puts "Starting RPC server for #{@channel}"
|
72
71
|
loop do
|
73
|
-
channel, request =
|
72
|
+
channel, request = RedisBase.redis.brpop(@channel)
|
74
73
|
request = MessagePack.unpack(request)
|
75
74
|
|
76
75
|
puts "Working on request: #{request['id']}"
|
@@ -84,8 +83,8 @@ module SGS
|
|
84
83
|
'id' => request['id']
|
85
84
|
}
|
86
85
|
|
87
|
-
|
88
|
-
|
86
|
+
RedisBase.redis.rpush(request['id'], MessagePack.pack(reply))
|
87
|
+
RedisBase.redis.expire(request['id'], 30)
|
89
88
|
end
|
90
89
|
end
|
91
90
|
end
|
data/lib/sgs/version.rb
CHANGED
data/lib/sgs/waypoint.rb
CHANGED
@@ -39,7 +39,7 @@
|
|
39
39
|
module SGS
|
40
40
|
#
|
41
41
|
# Waypoint, Attractor, and Repellor definitions
|
42
|
-
class Waypoint
|
42
|
+
class Waypoint
|
43
43
|
attr_accessor :location, :normal, :range, :name, :attractor
|
44
44
|
attr_reader :bearing, :distance
|
45
45
|
|
@@ -58,7 +58,7 @@ module SGS
|
|
58
58
|
def parse(data)
|
59
59
|
@@count += 1
|
60
60
|
@name = data["name"] || "Waypoint ##{@@count}"
|
61
|
-
@location =
|
61
|
+
@location = Location.parse(data)
|
62
62
|
@normal = data["normal"] || 0.0
|
63
63
|
@range = data["range"] || 0.1
|
64
64
|
end
|
data/sgslib.gemspec
CHANGED
@@ -34,15 +34,15 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
35
|
spec.require_paths = ["lib"]
|
36
36
|
|
37
|
-
spec.required_ruby_version = '>=
|
37
|
+
spec.required_ruby_version = '>= 2.7.6'
|
38
38
|
|
39
39
|
spec.add_development_dependency "bundler", "~> 2.2"
|
40
40
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
41
41
|
spec.add_development_dependency "rspec", "~> 3.0"
|
42
42
|
|
43
|
-
spec.add_runtime_dependency "redis", "~>
|
43
|
+
spec.add_runtime_dependency "redis", "~> 5.0"
|
44
44
|
spec.add_runtime_dependency "serialport", "~> 1.3"
|
45
|
-
spec.add_runtime_dependency "msgpack", "~> 1.
|
45
|
+
spec.add_runtime_dependency "msgpack", "~> 1.6"
|
46
46
|
spec.add_runtime_dependency "json"
|
47
47
|
spec.add_runtime_dependency "securerandom"
|
48
48
|
spec.add_runtime_dependency "yaml"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sgslib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dermot Tynan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '5.0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '5.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: serialport
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '1.
|
89
|
+
version: '1.6'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '1.
|
96
|
+
version: '1.6'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: json
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,7 +146,6 @@ executables:
|
|
146
146
|
- sgs_gpsread
|
147
147
|
- sgs_logger
|
148
148
|
- sgs_mission
|
149
|
-
- sgs_nav
|
150
149
|
- sgs_otto
|
151
150
|
- sgs_report
|
152
151
|
extensions: []
|
@@ -162,7 +161,6 @@ files:
|
|
162
161
|
- exe/sgs_gpsread
|
163
162
|
- exe/sgs_logger
|
164
163
|
- exe/sgs_mission
|
165
|
-
- exe/sgs_nav
|
166
164
|
- exe/sgs_otto
|
167
165
|
- exe/sgs_report
|
168
166
|
- lib/sgs/alarm.rb
|
@@ -199,14 +197,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
199
197
|
requirements:
|
200
198
|
- - ">="
|
201
199
|
- !ruby/object:Gem::Version
|
202
|
-
version:
|
200
|
+
version: 2.7.6
|
203
201
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
202
|
requirements:
|
205
203
|
- - ">="
|
206
204
|
- !ruby/object:Gem::Version
|
207
205
|
version: '0'
|
208
206
|
requirements: []
|
209
|
-
rubygems_version: 3.1
|
207
|
+
rubygems_version: 3.0.3.1
|
210
208
|
signing_key:
|
211
209
|
specification_version: 4
|
212
210
|
summary: Sailboat Guidance System
|