Class: SGS::Course

Inherits:
Object
  • Object
show all
Defined in:
lib/sgs/course.rb

Overview

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.

Constant Summary collapse

TACK_NAME =
["Starboard", "Port"].freeze
STARBOARD =
0
PORT =
1
STANDARD =

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

[
   -3.15994,
   23.8741,
  -27.4595,
   16.4868,
   -5.15663,
    0.743936,
   -0.0344716
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wind = nil) ⇒ Course

Set up the default values



66
67
68
69
70
71
72
73
# 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

Instance Attribute Details

#awaObject

Returns the value of attribute awa.



44
45
46
# File 'lib/sgs/course.rb', line 44

def awa
  @awa
end

#polar_curve=(value) ⇒ Object (writeonly)

Sets the attribute polar_curve

Parameters:

  • value

    the value to set the attribute polar_curve to.



45
46
47
# File 'lib/sgs/course.rb', line 45

def polar_curve=(value)
  @polar_curve = value
end

#speedObject (readonly)

Returns the value of attribute speed.



44
45
46
# File 'lib/sgs/course.rb', line 44

def speed
  @speed
end

Instance Method Details

#awa_dObject

Return the Apparent Wind Angle (AWA) in degrees



95
96
97
# File 'lib/sgs/course.rb', line 95

def awa_d
  Bearing.rtod @awa
end

#compute_speedObject

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.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# 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

#headingObject

Return the current heading



77
78
79
# File 'lib/sgs/course.rb', line 77

def heading
  @heading
end

#heading=(new_heading) ⇒ Object

Set the heading



113
114
115
116
117
118
119
120
121
122
# 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_dObject

Return the heading in degrees



83
84
85
# File 'lib/sgs/course.rb', line 83

def heading_d
  Bearing.rtod @heading
end

#relative_vmg(waypt) ⇒ Object

Compute a relative VMG based on the waypoint



148
149
150
151
152
# 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

#tackObject

Return the current tack



101
102
103
# File 'lib/sgs/course.rb', line 101

def tack
  (@awa and @awa < 0.0) ? PORT : STARBOARD
end

#tack_nameObject

Return the tack name



107
108
109
# File 'lib/sgs/course.rb', line 107

def tack_name
  TACK_NAME[tack]
end

#to_sObject

Convert to a string



174
175
176
# 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

#windObject

Return the wind direction/speed



89
90
91
# File 'lib/sgs/course.rb', line 89

def wind
  @wind
end

#wind=(new_wind) ⇒ Object

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



127
128
129
130
131
# 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