class SGS::Course

A class to handle the course sailed, as well as polar speed calculations. For speed calculations, it takes a range of polars as polynomials and then applies them.

Constants

PORT
STANDARD

Right now, we have one polar - from a Catalina 22. Note that the speed is the same, regardless of the tack.

STARBOARD
TACK_NAME

Attributes

awa[R]
polar_curve[W]
speed[R]

Public Class Methods

new(wind = nil) click to toggle source

Set up the default values

# File lib/sgs/course.rb, line 66
def initialize(wind = nil)
  @polar_curve = STANDARD
  @awa = 0.0
  @speed = 0.0
  @wind = wind || Bearing.new(0.0, 10.0)
  @heading = nil
  self.heading = 0
end

Public Instance Methods

awa=(new_awa) click to toggle source

Calculate the AWA based on our heading and wind direction

# File lib/sgs/course.rb, line 135
def awa=(new_awa)
  if new_awa < -Math::PI
    new_awa += 2*Math::PI
  elsif new_awa > Math::PI
    new_awa -= 2*Math::PI
  end
  return if @awa == new_awa
  @awa = new_awa
  compute_speed
end
awa_d() click to toggle source

Return the Apparent Wind Angle (AWA) in degrees

# File lib/sgs/course.rb, line 95
def awa_d
  Bearing.rtod @awa
end
compute_speed() click to toggle source

Compute the hull speed from the polar. This is just a guestimate of how fast the boat will travel at the particular apparent wind angle.

# File lib/sgs/course.rb, line 157
def compute_speed
  awa = @awa.abs
  return 0.0 if awa < 0.75
  ap = 1.0
  @speed = 0.0
  @polar_curve.each do |poly_val|
    @speed += poly_val * ap
    ap *= awa
  end
  @speed /= 2.5           # Fudge for small boat
  if @speed < 0.0
    @speed = 0.0
  end
end
heading() click to toggle source

Return the current heading

# File lib/sgs/course.rb, line 77
def heading
  @heading
end
heading=(new_heading) click to toggle source

Set the heading

# File lib/sgs/course.rb, line 113
def heading=(new_heading)
  return if @heading and @heading == new_heading
  if new_heading > 2*Math::PI
    new_heading -= 2*Math::PI
  elsif new_heading < 0.0
    new_heading += 2*Math::PI
  end
  @heading = new_heading
  self.awa = @wind.angle - @heading
end
heading_d() click to toggle source

Return the heading in degrees

# File lib/sgs/course.rb, line 83
def heading_d
  Bearing.rtod @heading
end
relative_vmg(waypt) click to toggle source

Compute a relative VMG based on the waypoint

# File lib/sgs/course.rb, line 148
def relative_vmg(waypt)
  relvmg = @speed * Math::cos(waypt.bearing.angle - @heading) / waypt.distance
  puts "Relative VMG to WPT: #{waypt.name} is #{relvmg}"
  relvmg
end
tack() click to toggle source

Return the current tack

# File lib/sgs/course.rb, line 101
def tack
  (@awa and @awa < 0.0) ? PORT : STARBOARD
end
tack_name() click to toggle source

Return the tack name

# File lib/sgs/course.rb, line 107
def tack_name
  TACK_NAME[tack]
end
to_s() click to toggle source

Convert to a string

# File lib/sgs/course.rb, line 174
def to_s
  "Heading %dd (wind %.1f@%dd, AWA:%dd, speed=%.2fknots)" % [heading_d, wind.distance, wind.angle_d, awa_d, speed]
end
wind() click to toggle source

Return the wind direction/speed

# File lib/sgs/course.rb, line 89
def wind
  @wind
end
wind=(new_wind) click to toggle source

Set the wind direction and recompute the AWA if appropriate. Note that we don't care about wind speed (for now)

# File lib/sgs/course.rb, line 127
def wind=(new_wind)
  return if @wind and @wind.angle == new_wind.angle
  @wind = new_wind
  self.awa = @wind.angle - @heading
end