lib/sgs/navigate.rb in sgslib-1.8.1 vs lib/sgs/navigate.rb in sgslib-1.8.5
- old
+ new
@@ -47,57 +47,55 @@
##
#
module SGS
class Navigate
+ attr_reader :course, :gps, :otto, :waypoint
+
#
# Initialize the navigational parameters
def initialize(mission)
@mission = mission
+ @course = nil
@swing = 45
end
#
# Compute the best heading based on our current position and the position
- # of the current attractor. This is where the heavy-lifting happens
+ # of the current attractor. This is where the heavy-lifting happens.
+ # Returns TRUE if we're done.
def navigate
if @mission.status.current_waypoint == -1
@mission.status.current_waypoint = 0
@mission.status.distance = 0
end
set_waypoint
puts "Attempting to navigate to #{@waypoint}..."
- #
- # Pull the latest GPS data...
- @gps = GPS.load
- puts "GPS: #{@gps}"
- return unless @gps.valid?
- #
- # Pull the latest Otto data...
- @otto = Otto.load
- puts "OTTO:"
- p @otto
- puts "Compass: #{@otto.compass}"
- puts "AWA: #{@otto.awa}"
- puts "Wind: #{@otto.wind}"
- #
- # Update our local copy of the course based on what Otto says.
- puts "Course:"
- @course = Course.new
- @course.heading = @otto.compass
- @course.awa = @otto.awa
- @course.compute_wind
- #
- # Compute a new course from the parameter set
- compute_new_course
+ pull_gps_data
+ pull_otto_data
+ return compute_new_course
end
#
# Compute a new course based on our position and other information.
def compute_new_course
+ #
+ # Update our local copy of the course based on what Otto says.
puts "Compute new course..."
+ unless @course
+ #
+ # First time through, the current course is whichever way the boat
+ # is pointing.
+ @course = Course.new
+ @course.heading = @otto.compass
+ end
#
+ # Really it's the AWA we're interested in, not the boat heading.
+ @course.awa = @otto.awa
+ @course.compute_wind
+ p @course
+ #
# First off, compute distance and bearing from our current location
# to every attractor and repellor. We only look at forward attractors,
# not ones behind us.
compute_bearings(@mission.attractors[@mission.status.current_waypoint..-1])
compute_bearings(@mission.repellors)
@@ -105,11 +103,11 @@
# Right. Now look to see if we've achieved the current waypoint and
# adjust, accordingly
while active? and reached?
next_waypoint!
end
- return nil unless active?
+ return true unless active?
puts "Angle to next waypoint: #{@waypoint.bearing.angle_d}d"
puts "Adjusted distance to waypoint is #{@waypoint.distance}"
#
# Now, start the vector field analysis by examining headings either side
# of the bearing to the waypoint.
@@ -140,16 +138,17 @@
if relvmg > best_relvmg
best_relvmg = relvmg
best_course = new_course
end
end
- puts "Best course:"
+ puts "Best course: AWA: #{best_course.awa_d} degrees, Course: #{best_course.heading_d} degrees, Speed: #{best_course.speed} knots"
p best_course
if best_course.tack != @course.tack
puts "TACKING!!!!"
end
- best_course
+ @course = best_course
+ return false
end
#
# Compute the bearing for every attractor or repellor
def compute_bearings(waypoints)
@@ -251,9 +250,34 @@
wpt.compute_bearing(loc)
dist += wpt.bearing.distance
loc = wpt.location
end
dist
+ end
+
+ #
+ # Pull the latest GPS data. Failure is not an option.
+ def pull_gps_data
+ loop do
+ @gps = GPS.load
+ puts "GPS: #{@gps}"
+ break if @gps.valid?
+ puts "Retrying GPS..."
+ sleep 1
+ end
+ end
+
+ #
+ # Pull the latest Otto data.
+ def pull_otto_data
+ #
+ # Pull the latest Otto data...
+ @otto = Otto.load
+ puts "OTTO:"
+ p @otto
+ puts "Compass: #{@otto.compass}"
+ puts "AWA: #{@otto.awa}"
+ puts "Wind: #{@otto.wind}"
end
#
# Navigate a course up to a windward mark which is one nautical mile
# upwind of the start position. From there, navigate downwind to the