sgslib 1.8.1 → 1.8.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bdbf4fe47373b9771e9727d8a259d5ddfb545ee64ef51a3fb4b569d4d4e3e1f
4
- data.tar.gz: 5664da38c87316350e921af2432f81079732f1942b8fd9896bb59107ea1e49f2
3
+ metadata.gz: 5b772fccd0d24dd037a52734c72ef29a5203f5e32bbad85a47b4d8b16985c507
4
+ data.tar.gz: f717f8defef045a95408bbe34217bb8bf60f6ae802e5ddf95d4ff08dc223b8ff
5
5
  SHA512:
6
- metadata.gz: 10336b0228e40cd9b86e51206d4c0f33bdbe0a456ae6ab99de6e0cc57b2cff569f459f0fb94d0658bea9e248da8cd2eec874fafa8fa0bc14e6b25f1cb45818e2
7
- data.tar.gz: a358fd0c6a7eb67c091d857428a70c2ad738c2f98658cc1d7daf60b0dc83e8623e37c5bb2df4ed7c27de65928c20809d943a2f2263b5e5a8cd2db78e835c0e2c
6
+ metadata.gz: 739c91c93129d8da5e9271d10d9debe893746c10601fa206efa734498d6cc991ebcf0da3b9462d0f1a0a99eaf054e2ffa5e1b984832445b161b39026fcab8396
7
+ data.tar.gz: f546060ce3000f7d1c65ca079095863431bcd7b9ed2b2f997a30ac238cdfb8acfb28e1ca2822d586b9eab5058e711528619ab7f171daa60e4f304d1ed4d8197d
data/lib/sgs/alarm.rb CHANGED
@@ -46,25 +46,25 @@ module SGS
46
46
 
47
47
  #
48
48
  # Alarms generated by Otto.
49
- MISSION_SWITCH = 0
50
- RUDDSRV_FAULT = 1
51
- SAILSRV_FAULT = 2
52
- VBATT_CRITICAL = 3
53
- VBATT_UNDERVOLTAGE = 4
54
- VBATT_OVERVOLTAGE = 5
55
- IBATT_INRUSH = 6
56
- IBATT_DRAIN = 7
57
- VSOLAR_OVERVOLTAGE = 8
58
- COMPASS_ERROR = 9
59
- COMPASS_NOREAD = 10
60
- WDI_STUCK = 11
61
- WDI_NOREAD = 12
62
- RUDDER_NOZERO = 13
63
- SAIL_NOZERO = 14
64
- MOTHER_UNRESP = 15
49
+ OTTO_RESTART = 0
50
+ MISSION_SWITCH = 1
51
+ RUDDER_FAULT = 2
52
+ SAIL_FAULT = 3
53
+ BATTERY_FAULT = 4
54
+ SOLAR_FAULT = 5
55
+ COMPASS_FAULT = 6
56
+ ACCEL_FAULT = 7
57
+ WDI_FAULT = 8
58
+ MOTHER_UNRESP = 9
59
+ RESERVED1 = 10
60
+ RESERVED2 = 11
61
+ RESERVED3 = 12
62
+ RESERVED4 = 13
63
+ RESERVED5 = 14
64
+ RESERVED6 = 15
65
65
  #
66
66
  # Alarms generated by Mother.
67
- OTTO_RESTART = 16
67
+ OTTO_FAULT = 16
68
68
  MISSION_COMMENCE = 17
69
69
  MISSION_COMPLETE = 18
70
70
  MISSION_ABORT = 19
@@ -73,23 +73,23 @@ module SGS
73
73
  INSIDE_FENCE = 22
74
74
 
75
75
  ALARM_NAMES = [
76
+ "OTTO Restarted Unexpectedly",
76
77
  "Mission Activation Switch",
77
- "Rudder Servo Fault",
78
- "Sail Servo Fault",
79
- "Battery voltage is critically low",
80
- "Battery voltage is low",
81
- "Battery voltage is too high",
82
- "Battery inrush current",
83
- "Battery drain current",
84
- "Solar voltage is too high",
85
- "Compass module error",
86
- "Compass not responding",
87
- "WDI reading is misaligned",
88
- "Cannot read from the WDI",
89
- "Cannot zero the rudder position",
90
- "Cannot zero the sail position",
91
- "Mother is unresponsive",
92
- "OTTO Restarted",
78
+ "Fault in Rudder Control System",
79
+ "Fault in Sail Control System",
80
+ "Battery Failure",
81
+ "Failure in Solar Array",
82
+ "Fault in Electronic Compass",
83
+ "Fault in Accelerometer",
84
+ "Fault in Wind Direction Indicator",
85
+ "Mother is Unresponsive",
86
+ "** Reserved 1 **",
87
+ "** Reserved 2 **",
88
+ "** Reserved 3 **",
89
+ "** Reserved 4 **",
90
+ "** Reserved 5 **",
91
+ "** Reserved 6 **",
92
+ "Fault with OTTO Communications",
93
93
  "Mission has commenced",
94
94
  "Mission is completed",
95
95
  "*** MISSION ABORT ***",
@@ -108,7 +108,7 @@ module SGS
108
108
  #
109
109
  # Main daemon function (called from executable)
110
110
  def self.daemon
111
- puts "Alarm daemon starting up..."
111
+ puts "Alarm daemon starting up. VERSION: #{SGS::VERSION}"
112
112
  otto = RPCClient.new(:otto)
113
113
  loop do
114
114
  #puts "Check for any alarms..."
@@ -41,7 +41,7 @@ module SGS
41
41
  #
42
42
  # Main daemon function (called from executable)
43
43
  def self.daemon
44
- puts "Diagnostics subsystem starting up..."
44
+ puts "Diagnostics subsystem starting up. Version #{SGS::VERSION}"
45
45
  loop do
46
46
  sleep 300
47
47
  end
data/lib/sgs/gps.rb CHANGED
@@ -53,17 +53,22 @@ module SGS
53
53
  #
54
54
  # Main daemon function (called from executable)
55
55
  def self.daemon
56
- puts "GPS reader starting up..."
56
+ puts "GPS reader starting up. Version #{SGS::VERSION}"
57
57
  config = Config.load
58
58
 
59
59
  sp = SerialPort.new config.gps_device, config.gps_speed
60
60
  sp.read_timeout = 10000
61
61
 
62
62
  loop do
63
- nmea = NMEA.parse sp.readline
63
+ line = sp.readline
64
+ nmea = NMEA.parse line
64
65
  if nmea.is_gprmc?
65
66
  gps = nmea.parse_gprmc
66
67
  p gps
68
+ if gps.cmg < 0.0
69
+ puts "CMG ERROR?!? #{gps.cmg}"
70
+ p line
71
+ end
67
72
  gps.save_and_publish if gps and gps.valid?
68
73
  end
69
74
  end
data/lib/sgs/mission.rb CHANGED
@@ -69,7 +69,7 @@ module SGS
69
69
  #
70
70
  # Main daemon function (called from executable)
71
71
  def self.daemon
72
- puts "Mission management system starting up..."
72
+ puts "Mission management system starting up. Version #{SGS::VERSION}"
73
73
  #
74
74
  # Load the mission data from Redis and augment it with the
75
75
  # contents of the mission file.
@@ -87,14 +87,14 @@ module SGS
87
87
  # a compass course), and set the Otto register accordingly.
88
88
  # Repeat until we run out of waypoints.
89
89
  GPS.subscribe do |count|
90
- puts "Mission received new GPS count: #{count}"
91
- new_course = nav.navigate
92
- if new_course.nil?
90
+ puts "\n***** Mission received new GPS count: #{count} *****"
91
+ if nav.navigate
93
92
  mission.status.completed!
94
93
  break
95
94
  end
96
95
  mission.status.save
97
- compass = Bearing.rtox(new_course.heading)
96
+ compass = Bearing.rtox(nav.course.heading)
97
+ puts "Proposed compass course: #{compass}xd"
98
98
  otto.set_register(Otto::COMPASS_HEADING_REGISTER, compass)
99
99
  end
100
100
  else
data/lib/sgs/navigate.rb CHANGED
@@ -49,16 +49,20 @@
49
49
  #
50
50
  module SGS
51
51
  class Navigate
52
+ attr_reader :course, :gps, :otto, :waypoint
53
+
52
54
  #
53
55
  # Initialize the navigational parameters
54
56
  def initialize(mission)
55
57
  @mission = mission
58
+ @course = nil
56
59
  @swing = 45
57
60
  end
58
61
 
59
62
  #
60
63
  # Compute the best heading based on our current position and the position
61
- # of the current attractor. This is where the heavy-lifting happens
64
+ # of the current attractor. This is where the heavy-lifting happens.
65
+ # Returns TRUE if we're done.
62
66
  def navigate
63
67
  if @mission.status.current_waypoint == -1
64
68
  @mission.status.current_waypoint = 0
@@ -66,35 +70,29 @@ module SGS
66
70
  end
67
71
  set_waypoint
68
72
  puts "Attempting to navigate to #{@waypoint}..."
69
- #
70
- # Pull the latest GPS data...
71
- @gps = GPS.load
72
- puts "GPS: #{@gps}"
73
- return unless @gps.valid?
74
- #
75
- # Pull the latest Otto data...
76
- @otto = Otto.load
77
- puts "OTTO:"
78
- p @otto
79
- puts "Compass: #{@otto.compass}"
80
- puts "AWA: #{@otto.awa}"
81
- puts "Wind: #{@otto.wind}"
82
- #
83
- # Update our local copy of the course based on what Otto says.
84
- puts "Course:"
85
- @course = Course.new
86
- @course.heading = @otto.compass
87
- @course.awa = @otto.awa
88
- @course.compute_wind
89
- #
90
- # Compute a new course from the parameter set
91
- compute_new_course
73
+ pull_gps_data
74
+ pull_otto_data
75
+ return compute_new_course
92
76
  end
93
77
 
94
78
  #
95
79
  # Compute a new course based on our position and other information.
96
80
  def compute_new_course
81
+ #
82
+ # Update our local copy of the course based on what Otto says.
97
83
  puts "Compute new course..."
84
+ unless @course
85
+ #
86
+ # First time through, the current course is whichever way the boat
87
+ # is pointing.
88
+ @course = Course.new
89
+ @course.heading = @otto.compass
90
+ end
91
+ #
92
+ # Really it's the AWA we're interested in, not the boat heading.
93
+ @course.awa = @otto.awa
94
+ @course.compute_wind
95
+ p @course
98
96
  #
99
97
  # First off, compute distance and bearing from our current location
100
98
  # to every attractor and repellor. We only look at forward attractors,
@@ -107,7 +105,7 @@ module SGS
107
105
  while active? and reached?
108
106
  next_waypoint!
109
107
  end
110
- return nil unless active?
108
+ return true unless active?
111
109
  puts "Angle to next waypoint: #{@waypoint.bearing.angle_d}d"
112
110
  puts "Adjusted distance to waypoint is #{@waypoint.distance}"
113
111
  #
@@ -142,12 +140,13 @@ module SGS
142
140
  best_course = new_course
143
141
  end
144
142
  end
145
- puts "Best course:"
143
+ puts "Best course: AWA: #{best_course.awa_d} degrees, Course: #{best_course.heading_d} degrees, Speed: #{best_course.speed} knots"
146
144
  p best_course
147
145
  if best_course.tack != @course.tack
148
146
  puts "TACKING!!!!"
149
147
  end
150
- best_course
148
+ @course = best_course
149
+ return false
151
150
  end
152
151
 
153
152
  #
@@ -255,6 +254,31 @@ module SGS
255
254
  dist
256
255
  end
257
256
 
257
+ #
258
+ # Pull the latest GPS data. Failure is not an option.
259
+ def pull_gps_data
260
+ loop do
261
+ @gps = GPS.load
262
+ puts "GPS: #{@gps}"
263
+ break if @gps.valid?
264
+ puts "Retrying GPS..."
265
+ sleep 1
266
+ end
267
+ end
268
+
269
+ #
270
+ # Pull the latest Otto data.
271
+ def pull_otto_data
272
+ #
273
+ # Pull the latest Otto data...
274
+ @otto = Otto.load
275
+ puts "OTTO:"
276
+ p @otto
277
+ puts "Compass: #{@otto.compass}"
278
+ puts "AWA: #{@otto.awa}"
279
+ puts "Wind: #{@otto.wind}"
280
+ end
281
+
258
282
  #
259
283
  # Navigate a course up to a windward mark which is one nautical mile
260
284
  # upwind of the start position. From there, navigate downwind to the
data/lib/sgs/otto.rb CHANGED
@@ -53,6 +53,14 @@ module SGS
53
53
  attr_reader :actual_rudder, :actual_sail
54
54
  attr_reader :otto_mode, :otto_timestamp, :telemetry
55
55
 
56
+ MISSION_SWITCH = 1
57
+ RUDDER_FAULT = 2
58
+ SAIL_FAULT = 3
59
+ BATTERY_FAULT = 4
60
+ SOLAR_FAULT = 5
61
+ COMPASS_FAULT = 6
62
+ ACCEL_FAULT = 7
63
+ WDI_FAULT = 8
56
64
  #
57
65
  # Updates to Otto are done by setting an 8bit register value, as below.
58
66
  ALARM_CLEAR_REGISTER = 0
@@ -116,6 +124,9 @@ module SGS
116
124
  def initialize
117
125
  serial_port = nil
118
126
  #
127
+ # Keep a local copy of the register set to avoid duplication.
128
+ @registers = Array.new(MAX_REGISTER)
129
+ #
119
130
  # Set some defaults for the read-back parameters
120
131
  # The following five parameters are reported back by Otto with a status
121
132
  # message, and are read-only. @alarm_status is 16 bits while the other
@@ -148,7 +159,7 @@ module SGS
148
159
  # to do an initial sync with the device as it will ignore the
149
160
  # usual serial console boot-up gumph awaiting our sync message.
150
161
  def self.daemon
151
- puts "Low-level (Otto) communication subsystem starting up..."
162
+ puts "Low-level (Otto) communication subsystem starting up. Version #{SGS::VERSION}"
152
163
  otto = new
153
164
  config = Config.load
154
165
  otto.serial_port = SerialPort.new config.otto_device, config.otto_speed
@@ -250,11 +261,17 @@ module SGS
250
261
  request = MessagePack.unpack(request)
251
262
  puts "Req:[#{request.inspect}]"
252
263
  params = request['params']
253
- next if request['method'] != "set_local_register"
254
264
  puts "PARAMS: #{params}"
255
- cmd = "R%d=%X\r\n" % params
256
- puts "Command: #{cmd}"
257
- @serial_port.write cmd
265
+ case request['method']
266
+ when "set_local_register"
267
+ reg, value = params
268
+ if @registers[reg] != value
269
+ cmd = "R%d=%X\r\n" % [reg, value]
270
+ puts "Command: #{cmd}"
271
+ @serial_port.write cmd
272
+ @registers[reg] = value
273
+ end
274
+ end
258
275
  end
259
276
  end
260
277
 
data/lib/sgs/report.rb CHANGED
@@ -42,7 +42,7 @@ module SGS
42
42
  #
43
43
  # Main daemon function (called from executable)
44
44
  def self.daemon
45
- puts "Reporting subsystem starting up..."
45
+ puts "Reporting subsystem starting up. Version #{SGS::VERSION}"
46
46
  config = Config.load
47
47
  sp = SerialPort.new config.comm_device, config.comm_speed
48
48
  sp.read_timeout = 10000
data/lib/sgs/version.rb CHANGED
@@ -33,5 +33,5 @@
33
33
  # ABSTRACT
34
34
  #
35
35
  module SGS
36
- VERSION = "1.8.1"
36
+ VERSION = "1.8.5"
37
37
  end
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.8.1
4
+ version: 1.8.5
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-10-13 00:00:00.000000000 Z
11
+ date: 2023-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -204,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
204
  - !ruby/object:Gem::Version
205
205
  version: '0'
206
206
  requirements: []
207
- rubygems_version: 3.0.3.1
207
+ rubygems_version: 3.3.5
208
208
  signing_key:
209
209
  specification_version: 4
210
210
  summary: Sailboat Guidance System