Class: DrivingPhysics::Car::Condition

Inherits:
Object
  • Object
show all
Defined in:
lib/driving_physics/car.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir: DrivingPhysics.random_unit_vector, brake_temp: AIR_TEMP, brake_pad_depth:) ⇒ Condition



175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/driving_physics/car.rb', line 175

def initialize(dir: DrivingPhysics.random_unit_vector,
               brake_temp: AIR_TEMP,
               brake_pad_depth: )
  @dir = dir  # maybe rename to @heading ?
  @pos = Vector[0, 0]
  @vel = Vector[0, 0]
  @acc = Vector[0, 0]
  @fuel = 0.0   # L
  @lat_g = 0.0  # g
  @lon_g = 0.0  # g
  @wheelspeed = 0.0 # m/s (sliding when it differs from @speed)
  @brake_temp = brake_temp
  @brake_pad_depth = brake_pad_depth   # mm
end

Instance Attribute Details

#accObject (readonly)

Returns the value of attribute acc.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def acc
  @acc
end

#brake_pad_depthObject (readonly)

Returns the value of attribute brake_pad_depth.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def brake_pad_depth
  @brake_pad_depth
end

#brake_tempObject (readonly)

Returns the value of attribute brake_temp.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def brake_temp
  @brake_temp
end

#dirObject (readonly)

Returns the value of attribute dir.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def dir
  @dir
end

#fuelObject (readonly)

Returns the value of attribute fuel.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def fuel
  @fuel
end

#lat_gObject (readonly)

Returns the value of attribute lat_g.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def lat_g
  @lat_g
end

#lon_gObject (readonly)

Returns the value of attribute lon_g.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def lon_g
  @lon_g
end

#posObject (readonly)

Returns the value of attribute pos.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def pos
  @pos
end

#velObject (readonly)

Returns the value of attribute vel.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def vel
  @vel
end

#wheelspeedObject (readonly)

Returns the value of attribute wheelspeed.



172
173
174
# File 'lib/driving_physics/car.rb', line 172

def wheelspeed
  @wheelspeed
end

Instance Method Details

#add_fuel(liters) ⇒ Object



273
274
275
# File 'lib/driving_physics/car.rb', line 273

def add_fuel(liters)
  @fuel += liters
end

#compassObject



289
290
291
# File 'lib/driving_physics/car.rb', line 289

def compass
  DrivingPhysics.compass_dir(@dir)
end

#consume_fuel(liters) ⇒ Object



277
278
279
# File 'lib/driving_physics/car.rb', line 277

def consume_fuel(liters)
  @fuel -= liters
end

#lat_dirObject

left is negative, right is positive



209
210
211
# File 'lib/driving_physics/car.rb', line 209

def lat_dir
  DrivingPhysics.rot_90(@dir, clockwise: true)
end

#movement_dirObject

note, we might be moving backwards, so not always @dir and we can’t normalize a zero vector if we’re not moving



215
216
217
# File 'lib/driving_physics/car.rb', line 215

def movement_dir
  (speed == 0.0) ? @dir : @vel.normalize
end

#slide_speedObject



285
286
287
# File 'lib/driving_physics/car.rb', line 285

def slide_speed
  (speed - @wheelspeed).abs
end

#speedObject



281
282
283
# File 'lib/driving_physics/car.rb', line 281

def speed
  @vel.magnitude
end

#tick!(force:, mass:, tire:, env:) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/driving_physics/car.rb', line 219

def tick!(force:, mass:, tire:, env:)
  # take the longitudinal component of the force, relative to vel dir
  vel_dir = @vel.zero? ? @dir : @vel.normalize
  lon_force = force.dot(vel_dir)
  @wheelspeed = nil

  if lon_force < 0.0
    is_stopping = true
    if @vel.zero?
      @acc = Vector[0,0]
      @wheelspeed = 0.0
      @lon_g = 0.0

      # TODO: update any other physical vars
      return
    end
  else
    is_stopping = false
  end

  # now detect sliding
  nominal_acc = DrivingPhysics.acc(force, mass)
  init_v = @vel

  if nominal_acc.magnitude > tire.max_g * env.g
    nominal_v = DrivingPhysics.vel(@vel, nominal_acc, dt: env.tick)

    # check for reversal of velocity; could be wheelspin while
    # moving backwards, so can't just look at is_stopping
    if nominal_v.dot(@vel) < 0 and is_stopping
      @wheelspeed = 0.0
    else
      @wheelspeed = nominal_v.magnitude
    end
    @acc = nominal_acc.normalize * tire.max_g * env.g
  else
    @acc = nominal_acc
  end

  @vel = DrivingPhysics.vel(@vel, @acc, dt: env.tick)
  @wheelspeed ||= @vel.magnitude

  # finally, detect velocity reversal when stopping
  if is_stopping and @vel.dot(init_v) < 0
    puts "crossed zero; stopping!"
    @vel = Vector[0, 0]
    @wheelspeed = 0.0
    @lon_g = 0.0
  end

  @lon_g = @acc.dot(@dir) / env.g
  @pos = DrivingPhysics.pos(@pos, @vel, dt: env.tick)
end

#to_sObject



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/driving_physics/car.rb', line 190

def to_s
  [[compass,
    format('P(%d, %d)', @pos[0], @pos[1]),
    format('V(%.1f, %.1f)', @vel[0], @vel[1]),
    format('A(%.2f, %.2f)', @acc[0], @acc[1]),
   ].join(' | '),
   [format('%.1f m/s', speed),
    format('LatG: %.2f', lat_g),
    format('LonG: %.2f', lon_g),
    format('Whl: %.1f m/s', @wheelspeed),
    format('Slide: %.1f m/s', slide_speed),
   ].join(' | '),
   [format('Brakes: %.1f C %.1f mm', @brake_temp, @brake_pad_depth),
    format('Fuel: %.2f L', @fuel),
   ].join(' | ')
  ].join("\n")
end