Module: EngineTune::Calculator
- Defined in:
- lib/engine-tune/calculator.rb
Overview
A collection of formulas and calculations used to determine, among other things, the relative horsepower of an engine given different environmental conditions.
These calculations are modeled after Richard Shelquist’s Engine Tuner’s Calculator, but have been re-factored to be more ruby-like. I urge you to read his technical articles on Density Altitude and Corrected Horsepower for detailed explanations of these concepts.
In some cases I took a guess at what a method should be named based on the calculation it is returning, so any better suggestions are welcomed.
Class Method Summary collapse
- .absolute_pressure(altimeter, altitude) ⇒ Object
- .altitude(altimeter, elevation, dew_point, temperature) ⇒ Object
- .altitude_z(altimeter, elevation, dew_point, temperature) ⇒ Object
- .celsius_to_fahrenheit(temp) ⇒ Object
- .density(altimeter, altitude, dew_point, temperature) ⇒ Object
- .density_altitude(altimeter, altitude, dew_point, temperature) ⇒ Object
- .dyno_correction_factor(altimeter, altitude, dew_point, temperature) ⇒ Object
- .geopotential_altitude(elevation_in_meters) ⇒ Object
- .inches_to_millibars(inches) ⇒ Object
- .meters_to_feet(meters) ⇒ Object
-
.millibars_to_inches(mb) ⇒ Object
Systems of measurement conversion methods.
- .relative_density(altimeter, altitude, dew_point, temperature) ⇒ Object
- .relative_horsepower(altimeter, altitude, dew_point, temperature) ⇒ Object
- .relative_humidity(temperature, dew_point) ⇒ Object
- .round(f, d) ⇒ Object
-
.vapor_pressure(temperature_c) ⇒ Object
Polynomial from Herman Wobus.
- .virtual_temperature(altimeter, altitude, dew_point, temperature) ⇒ Object
Class Method Details
.absolute_pressure(altimeter, altitude) ⇒ Object
85 86 87 88 |
# File 'lib/engine-tune/calculator.rb', line 85 def absolute_pressure(altimeter, altitude) k1, k2 = 0.190263, 8.417286E-5 ((altimeter**k1)-(k2 * self.geopotential_altitude(altitude)))**(1/k1) end |
.altitude(altimeter, elevation, dew_point, temperature) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'lib/engine-tune/calculator.rb', line 69 def altitude(altimeter, elevation, dew_point, temperature) density = self.density(altimeter, elevation, dew_point, temperature) g, po, to, l, r, m = 9.80665, 101325, 288.15, 6.5, 8.314320, 28.9644 density = density * 1000 p2 = ( (l * r)/(g* m - l * r) ) * Math.log( (r * to * density) / (m * po) ) h = -(to / l)*( Math.exp(p2) -1 ) h * 1000 end |
.altitude_z(altimeter, elevation, dew_point, temperature) ⇒ Object
78 79 80 81 82 |
# File 'lib/engine-tune/calculator.rb', line 78 def altitude_z(altimeter, elevation, dew_point, temperature) altitude = self.altitude(altimeter, elevation, dew_point, temperature) r = 6369E3 ((r * altitude) / (r - altitude)) end |
.celsius_to_fahrenheit(temp) ⇒ Object
124 125 126 |
# File 'lib/engine-tune/calculator.rb', line 124 def celsius_to_fahrenheit(temp) ((temp * 9.0) / 5.0) + 32.0 end |
.density(altimeter, altitude, dew_point, temperature) ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/engine-tune/calculator.rb', line 58 def density(altimeter, altitude, dew_point, temperature) vapor_pressure = self.vapor_pressure(dew_point) absolute_pressure = self.absolute_pressure(altimeter, altitude) rv, rd = 461.4964, 287.0531 temperature_k = temperature + 273.15 pv = vapor_pressure * 100 pd = (absolute_pressure - vapor_pressure) * 100 (pv / (rv * temperature_k)) + (pd / (rd * temperature_k)) end |
.density_altitude(altimeter, altitude, dew_point, temperature) ⇒ Object
18 19 20 21 22 23 24 25 |
# File 'lib/engine-tune/calculator.rb', line 18 def density_altitude(altimeter, altitude, dew_point, temperature) # Calculate geometric altitude Z (m) from geopotential altitude (m) H densaltzm = self.altitude_z(altimeter, altitude, dew_point, temperature) unless (-5000..11000).include?(densaltzm) raise "Out of range for Troposhere Algorithm: Altitude =" + densaltzm.round + " meters" end densaltzm.round end |
.dyno_correction_factor(altimeter, altitude, dew_point, temperature) ⇒ Object
27 28 29 30 31 32 33 34 35 |
# File 'lib/engine-tune/calculator.rb', line 27 def dyno_correction_factor(altimeter, altitude, dew_point, temperature) vapor_pressure_mb = self.vapor_pressure(dew_point) absolute_pressure_mb = self.absolute_pressure(altimeter, altitude) absolute_pressure_in = (absolute_pressure_mb) vapor_pressure_in = (vapor_pressure_mb) p1 = 29.235 / (absolute_pressure_in - vapor_pressure_in) p2 = ((temperature + 273) / 298)**0.5 (1.18 * (p1 * p2) - 0.18) end |
.geopotential_altitude(elevation_in_meters) ⇒ Object
53 54 55 56 |
# File 'lib/engine-tune/calculator.rb', line 53 def geopotential_altitude(elevation_in_meters) r = 6369E3; ((r * elevation_in_meters) / (r + elevation_in_meters)) end |
.inches_to_millibars(inches) ⇒ Object
112 113 114 |
# File 'lib/engine-tune/calculator.rb', line 112 def (inches) inches * 33.8637526 end |
.meters_to_feet(meters) ⇒ Object
116 117 118 |
# File 'lib/engine-tune/calculator.rb', line 116 def meters_to_feet(meters) meters * 3.2808399 end |
.millibars_to_inches(mb) ⇒ Object
Systems of measurement conversion methods
108 109 110 |
# File 'lib/engine-tune/calculator.rb', line 108 def (mb) mb * (1/33.86389) end |
.relative_density(altimeter, altitude, dew_point, temperature) ⇒ Object
90 91 92 93 |
# File 'lib/engine-tune/calculator.rb', line 90 def relative_density(altimeter, altitude, dew_point, temperature) density = self.density(altimeter, altitude, dew_point, temperature) 100 * (density / 1.225) end |
.relative_horsepower(altimeter, altitude, dew_point, temperature) ⇒ Object
99 100 101 102 |
# File 'lib/engine-tune/calculator.rb', line 99 def relative_horsepower(altimeter, altitude, dew_point, temperature) dyno_correction_factor = self.dyno_correction_factor(altimeter, altitude, dew_point, temperature) round((100 / dyno_correction_factor), 1) end |
.relative_humidity(temperature, dew_point) ⇒ Object
95 96 97 |
# File 'lib/engine-tune/calculator.rb', line 95 def relative_humidity(temperature, dew_point) (vapor_pressure(dew_point) / vapor_pressure(temperature)) * 100 end |
.round(f, d) ⇒ Object
120 121 122 |
# File 'lib/engine-tune/calculator.rb', line 120 def round(f, d) (f * 10**d).round.to_f / 10**d end |
.vapor_pressure(temperature_c) ⇒ Object
Polynomial from Herman Wobus
47 48 49 50 51 |
# File 'lib/engine-tune/calculator.rb', line 47 def vapor_pressure(temperature_c) values = [ 1.1112018e-17, -1.7892321e-15, 2.1874425e-13, -2.9883885e-11, 4.3884187e-09, -6.1117958e-07, 7.8736169e-05, -0.0090826951, 0.99999683 ] pol = values.inject(-0.30994571E-19) { |result, v| result = v + temperature_c * result } 6.1078 / (pol**8) end |
.virtual_temperature(altimeter, altitude, dew_point, temperature) ⇒ Object
38 39 40 41 42 |
# File 'lib/engine-tune/calculator.rb', line 38 def virtual_temperature(altimeter, altitude, dew_point, temperature) absolute_pressure = self.absolute_pressure(altimeter, altitude) vapor_pressure = self.vapor_pressure(dew_point) ((temperature + 273.15) / (1- (0.377995 * vapor_pressure / absolute_pressure)))-273.15 end |