ESTIMATED MODEL. The coefficients in backend/app/models/parameters.py are
hand-chosen, not fitted to measured tyre data, and this is not a representation
of any tyre manufacturer's product.
What it is: an explainable, monotonic, parameterised degradation law whose output feeds the lap-time model through a derived sensitivity coefficient rather than a magic seconds-per-lap number.
Implementation: backend/app/models/tyre.py.
Grip is expressed as a fraction of the compound's peak. Four independent effects subtract from it:
grip_fraction(age) = 1 − warmup − linear − cliff − temperature
floored at minimum_grip_fraction (0.72), below which the model would be
extrapolating into nonsense.
warmup = warmup_deficit · exp(−age / warmup_laps)
A new tyre is off-peak for the first lap or two. This term is negative-going,
so a fresh tyre genuinely gets faster early in a stint before wear takes over.
That is a real effect the model reproduces rather than smooths away, and it is
easy to break by reordering terms — test_fresh_tyre_improves_through_warmup
guards it.
linear = effective_wear_rate · age
effective_wear_rate = (wear_rate_per_lap + fuel_coupling · fuel_kg)
· (severity / 0.5)^severity_exponent
Steady tread loss proportional to age. Two multipliers:
- Circuit severity — the tyre-energy index from the solved lap, raised to
severity_exponent = 1.35. Wear scales super-linearly with the energy put through the tyre. - Fuel load — a heavier car puts more energy through the tyre. Sized so a full tank raises the wear rate by roughly 60% over an empty one, keeping the term secondary to the compound's own rate.
cliff = cliff_rate · max(0, age − cliff_onset)²
A quadratic term that only switches on past a compound-specific age. This is the model's representation of the accelerating loss once the tread is worn through.
temperature = temp_sensitivity · Δ · (1 + Δ/45), Δ = |track_temp − optimal|
A quadratic penalty for operating away from the compound's optimal window. Symmetric — see Limitations.
| Soft | Medium | Hard | Inter | Wet | |
|---|---|---|---|---|---|
| Peak grip scale | 1.0000 | 0.9865 | 0.9720 | 0.8600 | 0.7800 |
| Linear wear /lap | 0.00190 | 0.00125 | 0.00085 | 0.00170 | 0.00135 |
| Cliff onset (laps) | 16 | 25 | 36 | 22 | 28 |
| Cliff rate /lap² | 0.00034 | 0.00024 | 0.00017 | 0.00028 | 0.00022 |
| Warm-up laps | 1.2 | 1.9 | 2.8 | 1.0 | 0.8 |
| Optimal track temp | 36 °C | 39 °C | 43 °C | 22 °C | 16 °C |
| Nominal life (laps) | 22 | 33 | 46 | 28 | 34 |
The ordering constraints — softer compounds have more peak grip, wear faster,
and last fewer laps — are asserted in
test_softer_compounds_have_more_peak_grip_and_wear_faster.
The wear rates above are half the values the model was first authored with. At the original values the model implied roughly 0.12 s per lap of tyre age at Silverstone, about double observed degradation rates, and the strategy optimiser consequently preferred three-stop plans everywhere. After halving:
| Circuit | Degradation at 15 laps | Usable life |
|---|---|---|
| Silverstone | 0.064 s/lap | 53 laps |
| Monaco | 0.047 s/lap | 56 laps |
| Monza | 0.055 s/lap | 54 laps |
| Spa | 0.062 s/lap | 54 laps |
These sit in the 0.04–0.08 s/lap range that matches published degradation figures, and one-stop strategies now win at Silverstone, Monza and Spa — which matches reality.
The fuel–wear coupling was also corrected during this pass: at the original
0.00016 per kg, a half tank contributed 0.0088/lap of wear, dwarfing the
compound's own 0.00125 rate. It is now 0.000008 per kg.
This is the part that makes the model auditable rather than arbitrary.
grip_sensitivity_s_per_grip in laptime.py answers: how many seconds per lap
does one unit of grip fraction cost on THIS circuit with THIS car? It is
computed by central difference on the quasi-steady-state lap-time model — solve
at grip ± δ, divide — not quoted as a constant.
The tyre model produces a grip fraction. Multiplying gives seconds:
0.031 grip lost × 33.8 s per unit grip at Silverstone = 1.05 s/lap
Every degradation figure in the UI is traceable through that product. It also means the same grip loss costs different amounts at different circuits, automatically — a corner-dominated circuit has a higher sensitivity than a power-dominated one.
delta(age) = [ (1 − peak_grip_scale) + (1 − grip_fraction(age)) ] · sensitivity
Two components: the compound's intrinsic peak-grip offset (a Hard is slower than a Soft even when both are new) and the accumulated degradation.
The analytic derivative:
d(loss)/d(age) = wear_rate
+ 2 · cliff_rate · max(0, age − onset)
− (warmup_deficit / warmup_laps) · exp(−age / warmup_laps)
The warm-up term is negative early in a stint. Because this is hand-
differentiated it can silently drift from grip_fraction, so
test_degradation_rate_matches_the_grip_curve pins it against a finite
difference of the curve to within 2%.
Age at which grip falls below the model's floor, solved by bisection on the grip curve rather than read from a table — so it responds to severity, temperature and fuel load rather than being a fixed number per compound.
ratio = age / nominal_life
ratio ≤ 0.75 → 0.92
0.75 < r ≤ 1.0 → 0.92 → 0.57 (linear)
ratio > 1.0 → 0.57 − 0.45(r − 1), floored at 0.28
Confidence is high while the tyre is inside the age range the model is parameterised for, and decays once the projection is extrapolating past the compound's nominal life — where the quadratic cliff term dominates and is least trustworthy.
Reported so the UI never presents an extrapolation with the same authority as an interpolation. The race view shows it beside every projection.
| Label | Grip fraction |
|---|---|
NEW |
≥ 99.5% |
OPTIMAL |
≥ 97.5% |
WORKING |
≥ 94.5%, before the cliff |
DEGRADED |
≥ 90.5% |
CRITICAL |
below that |
The coefficients are estimates. They are hand-authored to span a plausible range with correct relative ordering. They are not fitted to measured tyre data and do not represent any manufacturer's product.
The temperature penalty is symmetric. This is the model's weakest simplification. A real tyre that is overheating degrades far faster than one that is merely cold — it is not only gripping less, it is destroying itself. The model treats +20 °C and −20 °C from optimum identically.
No thermal state. Tyre temperature is not a state variable. There is no modelling of temperature building through a stint, of a driver cooling the tyres behind a safety car, or of graining and blistering as distinct mechanisms.
No pressure. Tyre pressure, and its interaction with temperature and ride height, is absent.
No per-corner wear. Wear is a function of circuit-average severity, not of which corners actually load which tyre. A circuit with one very heavy long right-hander wears the left-front disproportionately; this model cannot see that.
No compound crossover. The model does not represent the case where a harder compound is faster in the wrong temperature window, which does happen.
Wet compounds are present but under-exercised. Intermediate and Wet parameters exist and the compound set switches when conditions are wet, but there is no model of a drying line, of crossover laps, or of standing water.