TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
Optional: Gears, Grip and Wheel Slip

This reading explains the gearbox and the simple ABS and traction-control filters already supplied with Tutorial 3. You can leave them enabled and keep working on the main speed-planning exercises.

1. Speed, wheel rotation and engine rotation

For a rolling wheel without slip, one revolution advances the car by one circumference. In angular-speed notation:

Rolling-wheel relation

\[ v=\omega_w r_w,\qquad \omega_e\approx G_k\omega_w=G_k\frac{v}{r_w}. \]

Symbol Meaning Unit
\(r_w\) Wheel radius m
\(\omega_w\) Wheel angular speed rad/s
\(\omega_e\) Engine angular speed rad/s
\(G_k\) Overall gear ratio, including the final drive Dimensionless

The engine relation assumes the clutch is engaged and the drivetrain is not slipping significantly. To convert angular speed to the RPM shown on a gauge:

\[ \mathrm{RPM}=\omega\frac{60}{2\pi}. \]

Despite their names, car->_enginerpm and car->_enginerpmRedLine use internal angular-speed units, radians per second. Ratios such as current speed divided by red-line speed are unaffected by the conversion, provided both use the same units.

2. Derive the shift thresholds

With upshift fraction \(q_{\mathrm{up}}\), the nominal road speed at the upshift threshold in gear \(k\) is:

\[ v_{\mathrm{up},k}=q_{\mathrm{up}} \frac{\omega_{\mathrm{red}}r_w}{G_k}. \]

For a downshift, predict the engine speed in the lower gear first:

\[ \omega_{\mathrm{lower}}\approx G_{k-1}\frac{v}{r_w}. \]

The example requires this prediction to be below SHIFT_DOWN times the red line and the current engine speed to be relatively low. The up/down thresholds leave an overlap in which we keep the current gear. SHIFT_DELAY adds a minimum time between requests. These prevent hunting for different reasons: the overlap handles small speed fluctuations, while the time delay gives a shift time to finish.

gearRatio validates the gear and array index before reading a ratio. TORCS stores the ratio for gear k at car->_gearRatio[k + car->_gearOffset]; the array includes non-forward entries. The current implementation reports its highest forward gear as car->_gearNb - 1. We also require a positive ratio before requesting the next gear, rather than blindly adding one at the top.

Wheel spin can make engine speed high while road speed is still low. The upshift rule checks both engine speed and the road-speed estimate to avoid mistaking that for a useful upshift opportunity. Recovery controls reverse separately.

Why not use this as a throttle formula?

The relation between road speed and engine speed is useful for gearing, but \(\omega_{\mathrm{target}}/\omega_{\mathrm{red}}\) is not a general throttle command. In the current engine model, throttle affects torque; it does not ask the engine to hold a specified RPM. Load, drag, gear, and acceleration all matter. The driver therefore uses speed feedback for the pedals. The relation between road speed and engine speed helps it choose gears.

3. The tyres share a grip budget

A tyre has to transmit both longitudinal force (accelerating or braking) and lateral force (turning). A simple illustration is the friction-circle model:

\[ F_x^2+F_y^2\leq(\mu N)^2. \]

Here \(N\) is the normal force, in newtons. Using the full cornering limit and the full straight-line braking limit simultaneously would exceed this budget. This is why we plan most of the slowdown before the bend and retain conservative cornering and braking factors.

Actual tyre forces are nonlinear functions of slip, load, temperature, and other conditions. Some slip is needed to generate longitudinal force; excessive slip can reduce useful grip. Treat the circle as an explanatory approximation, not the complete TORCS tyre model.

4. Read wheel slip

Compare forward car speed with the wheel's circumferential speed:

\[ u_i=\omega_i r_i. \]

This is rotation relative to the wheel centre. In pure rolling, its velocity at the contact point cancels the car's translation, so that point is momentarily at rest relative to the road.

Rolling, locked and spinning wheel-speed examples, all compared with the same forward car speed

The picture uses \(u/v\). The traction-control filter below uses the inverse, \(v/\overline u\): in the spinning example that is \(20/30\approx0.67\).

  • During near-pure rolling, \(u_i\approx v\).
  • During braking, a wheel rotating too slowly has \(u_i<v\); a locked wheel has \(u_i\approx0\) even while the car moves.
  • Under power, a driven wheel can spin too fast, giving \(u_i>v\).

These ratios are practical indicators. They are not the full slip-vector calculation used by the tyre model, particularly while cornering.

5. A simple anti-lock braking filter

The supplied ABS helper takes the mean rolling ratio over all four wheels:

\[ r_{\mathrm{roll}}=\frac14\sum_{i=1}^4\frac{\omega_i r_i}{v}. \]

For forward speeds of at least 3 m/s, if this ratio is below 0.9 it reduces the requested brake command:

\[ B_{\mathrm{out}}=B_{\mathrm{in}}\, \operatorname{clamp}(r_{\mathrm{roll}},0,1). \]

Otherwise it leaves the request alone. The minimum-speed check avoids division by a tiny speed and leaves low-speed stopping straightforward.

This deliberately small filter uses an average over all four wheels. Averaging can hide one wheel's problem when other wheel speeds differ. Possible extensions include examining individual wheels or weighting them by load. TORCS's available control interface and brake distribution also constrain what a more advanced controller can request.

A brake command is a normalized request, not a specified deceleration. The car's brake pressure and front/rear balance determine the available brake torque. Too little torque can invalidate a braking-distance estimate; too much can lock wheels without suitable control. Estimating a useful brake-pressure setup automatically is developed as an optional experiment in the Car Setup Workshop.

Try ENABLE_ABS = false in speed.cpp for a comparison, then restore it. Whether you visibly lock wheels depends on how strongly the controller asks for braking; a gentle run may show little difference.

6. A simple traction-control filter

For traction control, only the driven wheels belong in the average:

\[ \overline u_{\mathrm{driven}}= \frac{1}{n}\sum_{i\in\mathrm{driven}}\omega_i r_i, \qquad r_{\mathrm{traction}}=\frac{v}{\overline u_{\mathrm{driven}}}. \]

The ratio is useful for interpreting slip, but division by road speed is awkward at launch. The supplied filter instead uses excess wheel speed \(\Delta u=\overline u_{\mathrm{driven}}-v\) and subtracts \(\max(0,\Delta u-2\,\mathrm{m/s})/(10\,\mathrm{m/s})\) from the requested throttle, clamping the result at zero. Below 2 m/s of excess speed it passes the request unchanged, including full throttle. Above that threshold it reduces power progressively rather than switching it fully off. This also works at standstill without a separate reduced-throttle launch cap.

Drivetrain Wheels included
Front-wheel drive Front pair
Rear-wheel drive Rear pair
All-wheel drive All four

configure reads the drivetrain once. A small enum and loop select the wheels; no member-function-pointer machinery or class hierarchy is needed here. Each wheel uses its own radius before averaging, so unequal wheel sizes are not silently treated as equal.

The mean is still a simplification. A spinning wheel and a slow wheel can partly cancel in the average. The thresholds are controller tuning values, not a full tyre model; wheel-specific control is an experiment for later.

Try ENABLE_TRACTION_CONTROL = false, observe the launch, then restore it. The helpers reduce normal-driving commands; they do not override the recovery controller's manoeuvres.

7. Keep the control order clear

Each normal update chooses a speed target, computes throttle or brake, chooses a gear, and applies the appropriate slip filter. Steering still uses the earlier centerline rule.

Recovery is checked first. When it supplies the controls, normal driving is skipped completely. That prevents the gear selector or speed controller from replacing a deliberate reverse manoeuvre.

if (recovery.driveIfNeeded(car, situation)) {
driver.resumeAfterRecovery(situation->currentTime);
return;
}
driver.drive(car, situation);

8. What is worth precomputing?

Get the behaviour right first, then optimize measured costs. The example caches configured tyre coefficients, drivetrain selection, aerodynamic coefficients, and the lowest main-track surface coefficient at session start. Fuel changes, current position, speed, and the upcoming road are evaluated while driving.

The numerical braking model performs more work than the closed-form expression; that is another reason the analytical solution is useful. More elaborate precomputed speed profiles are possible, but must be updated when assumptions such as grip or setup change. The simple implementation keeps those assumptions visible while you learn.

Return to Chapter 3, or visit Questions and feedback.