sgslib 1.5.1 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
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,96 @@ require 'msgpack'
40
47
  #
41
48
  module SGS
42
49
  class Otto < RedisBase
43
- attr_accessor :raw_rudder, :raw_sail, :raw_compass, :raw_awa, :raw_tc, :raw_ta
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
- attr_accessor :serial_port
47
- attr_reader :alarm_status, :wind, :compass, :actual_rudder, :actual_sail
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
+ RUDDER_PID_P = 14
73
+ RUDDER_PID_I = 15
74
+ RUDDER_PID_D = 16
75
+ RUDDER_PID_E_NUM = 17
76
+ RUDDER_PID_E_DEN = 18
77
+ RUDDER_PID_U_DIV = 19
78
+ SAIL_MXC_M_VALUE = 20
79
+ SAIL_MXC_C_VALUE = 21
80
+ SAIL_MXC_U_DIV = 22
81
+ MAX_REGISTER = 23
82
+
83
+ #
84
+ # This is different from mission mode. This mode defines how Otto should
85
+ # operate. Inert means "do nothing". Diagnostic mode is for the low-level
86
+ # code to run self-checks and calibrations. Manual means that the upper
87
+ # level system controls the rudder and sail angle without any higher-level
88
+ # PID controller. Track compass means that the boat will try to keep the
89
+ # actual compass reading within certain parameters, and track AWA will
90
+ # try to maintain a specific "apparent wind angle".
50
91
  MODE_INERT = 0
51
- MODE_DIAGNOSTICS = 1
92
+ MODE_DIAG = 1
52
93
  MODE_MANUAL = 2
53
- MODE_TRACK_COMPASS = 3
54
- MODE_TRACK_AWA = 4
94
+ MODE_REMOTE = 3
95
+ MODE_TRACK_COMPASS = 4
96
+ MODE_TRACK_AWA = 5
55
97
 
56
- MODE_NAMES = [
57
- "Inert Mode", "Diagnostics Mode", "Manual Control Mode",
58
- "Compass-Tracking Mode", "AWA-Tracking Mode"
59
- ].freeze
98
+ #
99
+ # Define some tweaks for rudder and sail setting. Rudder goes from
100
+ # +/-40 degrees, with zero indicating a straight rudder. On Otto, this
101
+ # translates to 0 (for -40.0), 128 (for the zero position) and 255 (for
102
+ # +40 degrees of rudder). A fully trimmed-in sail is zero and a fully
103
+ # extended sail is 255 (0->100 from a function perspective).
104
+ RUDDER_MAX = 40.0
105
+ RUDDER_MIN = -40.0
106
+ RUDDER_M = 3.175
107
+ RUDDER_C = 128.0
108
+ SAIL_MAX = 100.0
109
+ SAIL_MIN = 0.0
110
+ SAIL_M = 2.55
111
+ SAIL_C = 0.0
60
112
 
61
113
  #
62
- # Set up some useful defaults. We assume rudder goes from 0 to 200 as does
63
- # the sail angle.
114
+ # Set up some useful defaults. We assume rudder goes from 0 to 255 as does
115
+ # the sail angle.
64
116
  def initialize
65
117
  serial_port = nil
66
118
  #
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
119
  # Set some defaults for the read-back parameters
78
- @alarm_status = @wind = @compass = @actual_rudder = @actual_sail = 0
79
- @otto_mode = 0
80
- @otto_timestamp = 1000
120
+ # The following five parameters are reported back by Otto with a status
121
+ # message, and are read-only. @alarm_status is 16 bits while the other
122
+ # four are 8-bit values. The helper methods convert these 8-bit values
123
+ # into radians, etc. The telemetry parameters are used to capture
124
+ # telemetry data from Otto.
125
+ @alarm_status = 0
126
+ @actual_rudder = @actual_sail = @actual_awa = @actual_compass = 0
81
127
  @telemetry = Array.new(16)
82
128
  #
129
+ # Mode is used by Otto to decide how to steer the boat and trim the
130
+ # sails.
131
+ @otto_mode = MODE_INERT
132
+ @otto_timestamp = 1000
133
+ #
83
134
  # Set up some basic parameters for battery/solar readings
84
135
  @bv_m = @bi_m = @bt_m = @sv_m = 1.0
85
136
  @bv_c = @bi_c = @bt_c = @sv_c = 0.0
137
+ #
138
+ # RPC client / server
139
+ @rpc_client = @rpc_server = nil
86
140
  super
87
141
  end
88
142
 
@@ -96,7 +150,7 @@ module SGS
96
150
  def self.daemon
97
151
  puts "Low-level (Otto) communication subsystem starting up..."
98
152
  otto = new
99
- config = SGS::Config.load
153
+ config = Config.load
100
154
  otto.serial_port = SerialPort.new config.otto_device, config.otto_speed
101
155
  otto.serial_port.read_timeout = 10000
102
156
  #
@@ -111,9 +165,31 @@ module SGS
111
165
  t2.join
112
166
  end
113
167
 
168
+ #
169
+ # Build a C include file based on the current register definitions
170
+ def self.build_include(fname)
171
+ otto = new
172
+ File.open(fname, "w") do |f|
173
+ f.puts "/*\n * Autogenerated by #{__FILE__}.\n * DO NOT HAND-EDIT!\n */"
174
+ constants.sort.each do |c|
175
+ if c.to_s =~ /REGISTER$/
176
+ cval = Otto.const_get(c)
177
+ str = "#define SGS_#{c.to_s}"
178
+ str += "\t" if str.length < 32
179
+ str += "\t#{cval}"
180
+ f.puts str
181
+ end
182
+ end
183
+ end
184
+ end
185
+
114
186
  #
115
187
  # Synchronize with the low-level board by sending CQ messages until
116
- # they respond.
188
+ # they respond. When Mother boots up, the serial console is shared with
189
+ # Otto so a lot of rubbish is sent to the low-level board. To notify
190
+ # Otto that we are now talking sense, we send @@CQ! and Otto responds
191
+ # with +CQOK. Note that this function, which is always called before any
192
+ # of the threads, is bidirectional in terms of serial I/O.
117
193
  def synchronize
118
194
  index = 0
119
195
  backoffs = [1, 1, 1, 1, 2, 2, 3, 5, 10, 10, 20, 30, 60]
@@ -154,6 +230,10 @@ module SGS
154
230
  #
155
231
  # Telemetry data (every two seconds)
156
232
  parse_telemetry(data[1..])
233
+ when '*'
234
+ #
235
+ # Message for the debug log
236
+ parse_debug(data[1..])
157
237
  end
158
238
  end
159
239
  end
@@ -164,31 +244,19 @@ module SGS
164
244
  puts "Starting OTTO writer thread..."
165
245
  #
166
246
  # Now listen for Redis PUB/SUB requests and act on each one.
247
+ myredis = Redis.new
167
248
  while true
168
- channel, request = SGS::RedisBase.redis.brpop("otto")
249
+ channel, request = myredis.brpop("otto")
169
250
  request = MessagePack.unpack(request)
170
251
  puts "Req:[#{request.inspect}]"
171
- cmd = {
172
- id: request['id'],
173
- args: request['params'].unshift(request['method'])
174
- }
175
- puts "CMD:#{cmd.inspect}"
176
- #
177
- # Don't let the command stack get too big.
178
- while @command_stack.length > 5
179
- sleep 5
180
- end
181
-
252
+ params = request['params']
253
+ next if request['method'] != "set_local_register"
254
+ puts "PARAMS: #{params}"
255
+ cmd = "R%d=%X\r\n" % params
256
+ puts "Command: #{cmd}"
257
+ @serial_port.write cmd
182
258
  puts "> Sending command: #{str}"
183
259
  @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
260
  end
193
261
  end
194
262
 
@@ -208,13 +276,13 @@ module SGS
208
276
  # Parse a status message from Otto. In the form:
209
277
  # 0001:C000:0000
210
278
  def parse_status(status)
211
- puts "Parse status: #{status}"
279
+ puts "OTTO PARSE: #{status}"
212
280
  args = status.split /:/
213
281
  @alarm_status = args[0].to_i(16)
214
282
  wc = args[1].to_i(16)
215
283
  rs = args[2].to_i(16)
216
- @wind = (wc >> 8) & 0xff
217
- @compass = (wc & 0xff)
284
+ @actual_awa = (wc >> 8) & 0xff
285
+ @actual_compass = (wc & 0xff)
218
286
  @actual_rudder = (rs >> 8) & 0xff
219
287
  @actual_sail = (rs & 0xff)
220
288
  p self
@@ -225,7 +293,6 @@ module SGS
225
293
  # Parse a timestamp message from Otto. In the form: "000FE2" 24 bits
226
294
  # representing the elapsed seconds since Otto restarted.
227
295
  def parse_tstamp(tstamp)
228
- puts "Parse timestamp: #{tstamp}"
229
296
  newval = tstamp.to_i(16)
230
297
  if newval < @otto_timestamp
231
298
  puts "ALARM! Otto rebooted (or something)..."
@@ -237,7 +304,6 @@ module SGS
237
304
  # Parse a mode state message from Otto. In the form: "00". An eight bit
238
305
  # quantity.
239
306
  def parse_mode(mode)
240
- puts "Parse Otto Mode State: #{mode}"
241
307
  @otto_mode = mode.to_i(16)
242
308
  end
243
309
 
@@ -245,80 +311,126 @@ module SGS
245
311
  # Parse a telemetry message from Otto. In the form: "7327" where the first
246
312
  # character is the channel (0->9) and the remaining 12 bits are the value.
247
313
  def parse_telemetry(telemetry)
248
- puts "Parse Otto Telemetry Data: #{telemetry}"
249
314
  data = telemetry.to_i(16)
250
315
  chan = (data >> 12) & 0xf
251
- @telemetry[chan] = data & 0xff
316
+ @telemetry[chan] = data & 0xfff
317
+ end
318
+
319
+ #
320
+ # Parse a debug message from the low-level code. Basically just append it
321
+ # to a log file.
322
+ def parse_debug(debug_data)
323
+ puts "DEBUG: [#{debug_data}].\n"
324
+ end
325
+
326
+ #
327
+ # Clear an alarm setting
328
+ def alarm_clear(alarm)
329
+ set_register(ALARM_CLEAR_REGISTER, alarm)
330
+ end
331
+
332
+ #
333
+ # Set the Otto mode
334
+ def mode=(val)
335
+ set_register(MODE_REGISTER, val) if @otto_mode != val
252
336
  end
253
337
 
254
338
  #
255
339
  # Set the required rudder angle. Input values range from +/- 40.0 degrees
256
340
  def rudder=(val)
257
- val = -40.0 if val < -40.0
258
- val = 40.0 if val > 40.0
259
- @raw_rudder = (@rudder_m * val.to_f + @rudder_c).to_i
341
+ val = RUDDER_MIN if val < RUDDER_MIN
342
+ val = RUDDER_MAX if val > RUDDER_MAX
343
+ val = (RUDDER_M * val.to_f + RUDDER_C).to_i
344
+ if val != @actual_rudder
345
+ @actual_rudder = val
346
+ set_register(RUDDER_ANGLE_REGISTER, val)
347
+ end
348
+ mode = MODE_MANUAL
260
349
  end
261
350
 
262
351
  #
263
352
  # Return the rudder angle in degrees
264
353
  def rudder
265
- (@raw_rudder.to_f - @rudder_c) / @rudder_m
354
+ (@actual_rudder.to_f - RUDDER_C) / RUDDER_M
266
355
  end
267
356
 
268
357
  #
269
- # Set the required sail angle. Input values range from 0 -> 90 degrees.
358
+ # Set the required sail angle. Input values range from 0 -> 100.
270
359
  def sail=(val)
271
- val = 0.0 if val < 0.0
272
- val = 100.0 if val > 100.0
273
- @raw_sail = (@sail_m * val.to_f + @sail_c).to_i
360
+ val = SAIL_MIN if val < SAIL_MIN
361
+ val = SAIL_MAX if val > SAIL_MAX
362
+ val = (SAIL_M * val.to_f + SAIL_C).to_i
363
+ if val != @actual_sail
364
+ @actual_sail = val
365
+ set_register(SAIL_ANGLE_REGISTER, val)
366
+ end
367
+ mode = MODE_MANUAL
274
368
  end
275
369
 
276
370
  #
277
371
  # Return the sail setting (0.0 -> 100.0)
278
372
  def sail
279
- (@raw_sail.to_f - @sail_c) / @sail_m
373
+ (@actual_sail.to_f - SAIL_C) / SAIL_M
280
374
  end
281
375
 
282
376
  #
283
377
  # Return the compass angle (in radians)
284
378
  def compass
285
- @raw_compass.to_f * Math::PI / 128.0
379
+ Bearing.xtor(@actual_compass)
286
380
  end
287
381
 
288
382
  #
289
383
  # Return the apparent wind angle (in radians)
290
384
  def awa
291
- @raw_awa.to_f * Math::PI / 128.0
385
+ @actual_awa -= 256 if @actual_awa > 128
386
+ Bearing.xtor(@actual_awa)
387
+ end
388
+
389
+ #
390
+ # Return the actual wind direction (in radians)
391
+ def wind
392
+ Bearing.xtor(@actual_compass + @actual_awa)
292
393
  end
293
394
 
294
395
  #
295
- # Set the required compass reading. Input values range from 0 -> 359 degrees
396
+ # Set the required compass reading (in radians)
296
397
  def track_compass=(val)
297
- while val < 0.0
298
- val += 360.0
398
+ val = Bearing.rtox(val)
399
+ if @track_compass.nil? or @track_compass != val
400
+ @track_compass = val
401
+ set_register(COMPASS_HEADING_REGISTER, val)
299
402
  end
300
- val %= 360.0
301
- @raw_tc = (val.to_f * 128.0 / Math::PI).to_i
403
+ mode = MODE_TRACK_COMPASS
302
404
  end
303
405
 
304
406
  #
305
407
  # Return the compass value for tracking.
306
408
  def track_compass
307
- @raw_tc.to_f * Math::PI / 128.0
409
+ Bearing.xtor(@track_compass)
308
410
  end
309
411
 
310
412
  #
311
- # Set the required AWA for tracking.
413
+ # Set the required AWA for tracking (in radians).
312
414
  def track_awa=(val)
313
- val = -180.0 if val < -180.0
314
- val = 180.0 if val > 180.0
315
- @raw_ta = (val.to_f * 128.0 / Math::PI).to_i
415
+ val = Bearing.rtox(val)
416
+ if @track_awa.nil? or @track_awa != val
417
+ @track_awa = val
418
+ set_register(AWA_HEADING_REGISTER, val)
419
+ end
420
+ mode = MODE_TRACK_AWA
316
421
  end
317
422
 
318
423
  #
319
- # Return the current tracking AWA.
424
+ # Return the current tracking AWA (in radians).
320
425
  def track_awa
321
- @raw_ta.to_f * Math::PI / 128.0
426
+ Bearing.xtor(@track_awa)
427
+ end
428
+
429
+ #
430
+ # RPC client call to set register - sent to writer function above
431
+ def set_register(regno, value)
432
+ @rpc_client = RPCClient.new("otto") unless @rpc_client
433
+ @rpc_client.set_local_register(regno, value)
322
434
  end
323
435
  end
324
436
  end
@@ -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
- SGS::RedisBase.redis.setnx cls.make_redis_name(var, :idx => idx), self.to_redis(var, val, idx)
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
- end
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
- SGS::RedisBase.redis.multi do |pipeline|
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
- SGS::RedisBase.redis.publish self.class.redis_handle, count.to_s
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
- SGS::RedisBase.redis.get count_name
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 = SGS::RedisBase.redis.get redis_name
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 = false
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 < RedisBase
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 = SGS::Config.load
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
- SGS::RedisBase.redis.lpush(@channel, request.to_msgpack)
59
- channel, response = SGS::RedisBase.redis.brpop(uuid, timeout=60)
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 = SGS::RedisBase.redis.brpop(@channel)
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
- SGS::RedisBase.redis.rpush(request['id'], MessagePack.pack(reply))
88
- SGS::RedisBase.redis.expire(request['id'], 30)
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
@@ -33,5 +33,5 @@
33
33
  # ABSTRACT
34
34
  #
35
35
  module SGS
36
- VERSION = "1.5.1"
36
+ VERSION = "1.7.1"
37
37
  end
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 < RedisBase
42
+ class Waypoint
43
43
  attr_accessor :location, :normal, :range, :name, :attractor
44
44
  attr_reader :bearing, :distance
45
45
 
@@ -58,7 +58,8 @@ module SGS
58
58
  def parse(data)
59
59
  @@count += 1
60
60
  @name = data["name"] || "Waypoint ##{@@count}"
61
- @location = SGS::Location.parse(data)
61
+ @location = Location.new
62
+ @location.parse_hash(data)
62
63
  @normal = data["normal"] || 0.0
63
64
  @range = data["range"] || 0.1
64
65
  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 = '>= 1.9.2'
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", "~> 4.7"
43
+ spec.add_runtime_dependency "redis", "~> 5.0"
44
44
  spec.add_runtime_dependency "serialport", "~> 1.3"
45
- spec.add_runtime_dependency "msgpack", "~> 1.3"
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.5.1
4
+ version: 1.7.1
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-01-16 00:00:00.000000000 Z
11
+ date: 2023-05-31 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: '4.7'
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: '4.7'
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.3'
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.3'
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,7 +197,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
199
197
  requirements:
200
198
  - - ">="
201
199
  - !ruby/object:Gem::Version
202
- version: 1.9.2
200
+ version: 2.7.6
203
201
  required_rubygems_version: !ruby/object:Gem::Requirement
204
202
  requirements:
205
203
  - - ">="