Class: DrivingPhysics::Tire::Condition

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

Overview

treat attributes of this class as mutable

Defined Under Namespace

Classes: Destroyed, Error

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(temp_c: AIR_TEMP, tread_mm:, cords_mm:) ⇒ Condition

Returns a new instance of Condition.



143
144
145
146
147
148
149
150
151
# File 'lib/driving_physics/tire.rb', line 143

def initialize(temp_c: AIR_TEMP, tread_mm:, cords_mm:)
  @tread_mm = tread_mm.to_f
  @cords_mm = cords_mm.to_f
  @temp_c = temp_c.to_f
  @heat_cycles = 0
  @hottest_temp = @temp_c
  @debug_temp = false
  @debug_wear = false
end

Instance Attribute Details

#cords_mmObject

Returns the value of attribute cords_mm.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def cords_mm
  @cords_mm
end

#debug_tempObject

Returns the value of attribute debug_temp.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def debug_temp
  @debug_temp
end

#debug_wearObject

Returns the value of attribute debug_wear.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def debug_wear
  @debug_wear
end

#heat_cyclesObject

Returns the value of attribute heat_cycles.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def heat_cycles
  @heat_cycles
end

#temp_cObject

Returns the value of attribute temp_c.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def temp_c
  @temp_c
end

#tread_mmObject

Returns the value of attribute tread_mm.



136
137
138
# File 'lib/driving_physics/tire.rb', line 136

def tread_mm
  @tread_mm
end

Instance Method Details

#temp_tick(ambient_temp:, g:, slide_speed:, mass:, tire_mass:, critical_temp:) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/driving_physics/tire.rb', line 160

def temp_tick(ambient_temp:, g:, slide_speed:,
              mass:, tire_mass:, critical_temp:)
  # env:
  # * mass (kg) (e.g. 1000 kg)
  # * tire_mass (kg) (e.g. 10 kg)
  # * critical temp (c) (e.g. 100c)
  # * g (e.g. 1.0 g)
  # * slide_speed (m/s) (typically 0.1, up to 1 or 10 or 50)
  # * ambient_temp (c) (e.g. 30c)

  # g gives a target temp between 25 and 100
  # at 0g, tire tends to ambient temp
  # at 1g, tire tends to 100 c
  # that 100c upper target also gets adjusted due to ambient temps

  target_hot = critical_temp + 5
  ambient_diff = AIR_TEMP - ambient_temp
  target_hot -= (ambient_diff / 2)
  puts "target_hot=#{target_hot}" if @debug_temp

  if slide_speed <= 0.1
    target_g_temp = ambient_temp + (target_hot - ambient_temp) * g
  else
    target_g_temp = target_hot
  end
  puts "target_g_temp=#{target_g_temp}" if @debug_temp

  slide_factor = slide_speed * 5
  target_slide_temp = target_g_temp + slide_factor

  puts "target_slide_temp=#{target_slide_temp}" if @debug_temp

  # temp_tick is presumed to be +1.0 or -1.0 (100th of a degree)
  # more mass biases towards heat
  # more tire mass biases for smaller tick

  tick = @temp_c < target_slide_temp ? 1.0 : -1.0
  tick += slide_speed / 10
  puts "base tick: #{tick}" if @debug_temp

  mass_factor = (mass - 1000).to_f / 1000
  if mass_factor < 0
    # lighter car cools quicker; heats slower
    tick += mass_factor
  else
    # heavier car cools slower, heats quicker
    tick += mass_factor / 10
  end
  puts "mass tick: #{tick}" if @debug_temp

  tire_mass_factor = (tire_mass - 10).to_f / 10
  if tire_mass_factor < 0
    # lighter tire has bigger tick
    tick -= tire_mass_factor
  else
    # heavier tire has smaller tick
    tire_mass_factor = (tire_mass - 10).to_f / 100
    tick -= tire_mass_factor
  end
  puts "tire mass tick: #{tick}" if @debug_temp
  puts if @debug_temp

  tick
end

#tick!(ambient_temp:, g:, slide_speed:, mass:, tire_mass:, critical_temp:) ⇒ Object



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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/driving_physics/tire.rb', line 242

def tick!(ambient_temp:, g:, slide_speed:,
          mass:, tire_mass:, critical_temp:)

  # heat cycle:
  # when the tire goes above the critical temp and then
  # cools significantly below the critical temp
  # track @hottest_temp

  @temp_c += temp_tick(ambient_temp: ambient_temp,
                       g: g,
                       slide_speed: slide_speed,
                       mass: mass,
                       tire_mass: tire_mass,
                       critical_temp: critical_temp) / 100
  @hottest_temp = @temp_c if @temp_c > @hottest_temp
  if @hottest_temp > critical_temp and @temp_c < critical_temp * 0.8
    @heat_cycles += 1
    @hottest_temp = @temp_c
  end

  # a tire should last for 30 minutes at 1g sustained
  # with minimal sliding
  # 100 ticks / sec
  # 6000 ticks / min
  # 180_000 ticks / 30 min
  # 10mm = 180_000 ticks
  # wear_tick is nominally 1 / 18_000 mm

  wt = wear_tick(g: g,
                 slide_speed: slide_speed,
                 mass: mass,
                 critical_temp: critical_temp)

  if @tread_mm > 0
    @tread_mm -= wt / 18000
    @tread_mm = 0 if @tread_mm < 0
  else
    # cords wear 2x faster
    @cords_mm -= wt * 2 / 18000
    if @cords_mm <= 0
      raise(Destroyed, "no more cords")
    end
  end
end

#to_sObject



153
154
155
156
157
158
# File 'lib/driving_physics/tire.rb', line 153

def to_s
  [format("Temp: %.1f C", @temp_c),
   format("Tread: %.2f (%.1f) mm", @tread_mm, @cords_mm),
   format("Cycles: %d", @heat_cycles),
  ].join(' | ')
end

#wear_tick(g:, slide_speed:, mass:, critical_temp:) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/driving_physics/tire.rb', line 225

def wear_tick(g:, slide_speed:, mass:, critical_temp:)
  # cold tires wear less
  tick = [0, @temp_c.to_f / critical_temp].max
  puts "wear tick: #{tick}" if @debug_wear

  # lower gs reduce wear in the absence of sliding
  tick *= g if slide_speed <= 0.1
  puts "g wear tick: #{tick}" if @debug_wear

  # slide wear
  tick += slide_speed
  puts "slide wear tick: #{tick}" if @debug_wear
  puts if @debug_wear
  tick
end