sgslib 1.8.1 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
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