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



71
72
73
74
75
76
77
78
# File 'lib/sgs/course.rb', line 71

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.



49
50
51
# File 'lib/sgs/course.rb', line 49

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.



50
51
52
# File 'lib/sgs/course.rb', line 50

def polar_curve=(value)
  @polar_curve = value
end

#speedObject (readonly)

Returns the value of attribute speed.



49
50
51
# File 'lib/sgs/course.rb', line 49

def speed
  @speed
end

Instance Method Details

#awa_dObject

Return the Apparent Wind Angle (AWA) in degrees



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

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.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/sgs/course.rb', line 172

def compute_speed
  awa = @awa.abs
  if awa < 0.75
    @speed = 0.0
    return
  end
  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

#compute_windObject

Compute the wind (as a Bearing) based on the compass heading and the apparent wind as reported.



165
166
167
# File 'lib/sgs/course.rb', line 165

def compute_wind
  @wind.angle = @heading + @awa
end

#headingObject

Return the current heading



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

def heading
  @heading
end

#heading=(new_heading) ⇒ Object

Set the heading



118
119
120
121
122
123
124
125
126
127
# File 'lib/sgs/course.rb', line 118

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



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

def heading_d
  Bearing.rtod @heading
end

#relative_vmg(waypt) ⇒ Object

Compute a relative VMG based on the waypoint. If you’re computing angles to one waypoint, the relative VMG will allow you to compare against each possible angle. If you’re computing to different waypoints, then the distance from your position to that waypoint is taken into consideration so that waypoints further away have less impact on your VMG choice.



158
159
160
# File 'lib/sgs/course.rb', line 158

def relative_vmg(waypt)
  @speed * Math::cos(waypt.bearing.angle - @heading) / waypt.distance
end

#tackObject

Return the current tack



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

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

#tack_nameObject

Return the tack name



112
113
114
# File 'lib/sgs/course.rb', line 112

def tack_name
  TACK_NAME[tack]
end

#to_sObject

Convert to a string



192
193
194
# File 'lib/sgs/course.rb', line 192

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



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

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)



132
133
134
135
136
# File 'lib/sgs/course.rb', line 132

def wind=(new_wind)
  return if @wind and @wind.angle == new_wind.angle
  @wind = new_wind
  self.awa = @wind.angle - @heading
end