Module: DrivingPhysics
- Defined in:
- lib/driving_physics.rb,
lib/driving_physics/wheel.rb,
lib/driving_physics/imperial.rb,
lib/driving_physics/environment.rb,
lib/driving_physics/scalar_force.rb,
lib/driving_physics/vector_force.rb
Defined Under Namespace
Modules: Imperial, ScalarForce, VectorForce, VectorZeroBackport Classes: Environment, Wheel
Constant Summary collapse
- HZ =
environmental defaults
1000- TICK =
Rational(1) / HZ
- G =
m/s^2
9.8- AIR_TEMP =
deg c
25- AIR_DENSITY =
kg / m^3
1.29- PETROL_DENSITY =
kg / L TODO: move to car.rb
0.71
- FRONTAL_AREA =
defaults for resistance forces
2.2- DRAG_COF =
m^2, based roughly on 2000s-era Chevrolet Corvette
0.3
- DRAG =
based roughly on 2000s-era Chevrolet Corvette
0.4257
- ROT_COF =
air_resistance at 1 m/s given above numbers
12.771- ROLL_COF =
if rotating resistance matches air resistance at 30 m/s
0.01
- SECS_PER_MIN =
constants
60- MINS_PER_HOUR =
60- SECS_PER_HOUR =
SECS_PER_MIN * MINS_PER_HOUR
Class Method Summary collapse
-
.acc(force, mass) ⇒ Object
acceleration; F=ma force can be a scalar or a Vector.
-
.accum(init, rate, dt: TICK) ⇒ Object
(also: vel, pos, omega, theta)
init and rate can be scalar or Vector but must match this provides the general form for determining velocity and position.
-
.compass_dir(unit_vector) ⇒ Object
,0 E 0, N .9,.1 ENE .1,.9 NNE.
- .elapsed_display(elapsed_ms) ⇒ Object
- .kph(meters_per_sec) ⇒ Object
-
.random_centered_zero(magnitude) ⇒ Object
e.g.
- .random_unit_vector(dimensions = 2, resolution: 9) ⇒ Object
- .rot_90(vec, clockwise: true) ⇒ Object
Class Method Details
.acc(force, mass) ⇒ Object
acceleration; F=ma force can be a scalar or a Vector
55 56 57 |
# File 'lib/driving_physics.rb', line 55 def self.acc(force, mass) force / mass.to_f end |
.accum(init, rate, dt: TICK) ⇒ Object Also known as: vel, pos, omega, theta
init and rate can be scalar or Vector but must match this provides the general form for determining velocity and position
61 62 63 |
# File 'lib/driving_physics.rb', line 61 def self.accum(init, rate, dt: TICK) init + rate * dt end |
.compass_dir(unit_vector) ⇒ Object
,0 E 0, N .9,.1 ENE .1,.9 NNE
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/driving_physics/vector_force.rb', line 43 def self.compass_dir(unit_vector) horz = case when unit_vector[0] < -0.001 then 'W' when unit_vector[0] > 0.001 then 'E' else '' end vert = case when unit_vector[1] < -0.001 then 'S' when unit_vector[1] > 0.001 then 'N' else '' end dir = [vert, horz].join if dir.length == 2 # detect and include bias if (unit_vector[0].abs - unit_vector[1].abs).abs > 0.2 bias = unit_vector[0].abs > unit_vector[1].abs ? horz : vert dir = [bias, dir].join end end dir end |
.elapsed_display(elapsed_ms) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/driving_physics.rb', line 38 def self.elapsed_display(elapsed_ms) elapsed_s, ms = elapsed_ms.divmod 1000 h = elapsed_s / SECS_PER_HOUR elapsed_s -= h * SECS_PER_HOUR m, s = elapsed_s.divmod SECS_PER_MIN [[h, m, s].map { |i| i.to_s.rjust(2, '0') }.join(':'), ms.to_s.rjust(3, '0')].join('.') end |
.kph(meters_per_sec) ⇒ Object
49 50 51 |
# File 'lib/driving_physics.rb', line 49 def self.kph(meters_per_sec) meters_per_sec.to_f * SECS_PER_HOUR / 1000 end |
.random_centered_zero(magnitude) ⇒ Object
e.g. given 5, yields a uniformly random number from -5 to +5
18 19 20 21 |
# File 'lib/driving_physics/vector_force.rb', line 18 def self.random_centered_zero(magnitude) m = [magnitude.abs, 1].max Random.rand(m * 2 + 1) - m end |
.random_unit_vector(dimensions = 2, resolution: 9) ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/driving_physics/vector_force.rb', line 23 def self.random_unit_vector(dimensions = 2, resolution: 9) begin v = Vector.elements(Array.new(dimensions) { random_centered_zero(resolution) }) end while v.zero? v.normalize end |
.rot_90(vec, clockwise: true) ⇒ Object
32 33 34 35 36 |
# File 'lib/driving_physics/vector_force.rb', line 32 def self.rot_90(vec, clockwise: true) raise(Vector::ZeroVectorError) if vec.zero? raise(ArgumentError, "vec should be size 2") unless vec.size == 2 clockwise ? Vector[vec[1], -1 * vec[0]] : Vector[-1 * vec[1], vec[0]] end |