Skip to content

zoompilotjetlinkwiki

How steering works

zoompilot sends Mazda steering commands 100 times a second, learns the response at each speed, and checks how much torque the motor applies.

  1. Command. The torque controller turns the driving model's path into a torque in counts for the EPS (the power steering motor).
  2. Check. The panda checks every command against the same limits.
  3. Report. The EPS reports the torque it applied, and the panda reports any command it refused.
comma device torque command panda same limits Mazda EPS applies torque wheels every 10 ms refused commands torque applied

torque limits

  • Maximum. 1200 counts at every speed.
  • Rate. 12 counts per 10 ms up or down, the EPS's own rate: full torque takes 1 s.
  • EPS ceiling. The EPS applies at most about 1148 counts below 18 mph (29 km/h) and 620 from 32 mph (52 km/h). zoompilot caps its command there and warns "Turn Exceeds Steering Limit" when the motor is maxed out.
  • Your hands win. Steer against zoompilot and its allowed torque drops fast.

steering down to a stop

A compatible Mazda EPS (2022+) steers down to a stop in any gen1 Mazda. An older EPS has the same limits and tune, plus two firmware lockouts:

  • Minimum speed. No steering below 28 mph (45 km/h) until you pass 32 mph (52 km/h) again. With cruise on you see "Steer Assist Unavailable Below 28 mph".
  • Hands off. If the EPS decides your hands are off, it blocks steering and steering turns off: "Steering Assist Temporarily Unavailable".

the steering tune

Speed ranges. With Self-Tune on, zoompilot learns the LAF and friction for each speed range and blends them by speed. Most cars have 7 ranges, from 11 to 89 mph (18 to 144 km/h); the CX-5 2022–25 has 9, from 4 mph (7 km/h). Learned values stay within ±30% (LAF) and ±50% (friction) of the starting values, survive a reboot if the car and software match, and restart when an update brings new starting values.

Starting values. The CX-5 2022–25 starts from a test car's learned values; older Mazdas with a compatible EPS borrow them. The CX-9 2021–23 and CX-8 2023 share their own; other cars start from one stock value. The first time it identifies a Mazda, zoompilot turns on Enforce Torque Lateral Control and Self-Tune and picks tune v2.0.

Tune per model size. Small and big driving models each keep a tune (v0.0, v1.0 or v2.0); on a Mazda, v2.0 for small and v1.0 for big by default. v2.0 is steadier on straights, hands back more smoothly when you let go, and damps swing-back after sharp turns below 32 mph.

when the car blocks steering

The EPS blocks (LKAS_BLOCK). On a compatible EPS a block often still lets some torque through, so zoompilot keeps steering. If the EPS applies nothing for 0.2 s against a real request, zoompilot stops asking, then ramps up from zero when the block lifts.

  • Usually silent. Short blocks, blocks below 12 mph (19 km/h) and the standby after a stop show nothing.
  • Real dropout. A block that began while moving and lasts 1 s at 12 mph or more shows a small "Steering Assist Temporarily Unavailable" with one chime. Steering stays engaged; steer yourself until it clears. On an older EPS, a block above its minimum speed turns steering off with the same message.

The car's lane keep is off. The EPS applies no torque while the car's own LKAS is off.

  • MADS on. Steering pauses; cruise is unaffected. A comma 4 shows "Lateral Disabled: LKAS is off"; a comma 3X shows it in the screen border. Switch lane keep back on and steering resumes after the EPS re-arms (about 3 s).
  • MADS off. You see "Invalid LKAS setting", and zoompilot will not engage.

keeping the steering signal flowing

The EPS expects a steering message every 10 ms. If the stream breaks for about 0.6 s, the EPS faults, and about 5 s later the camera shows "LKAS Fault: Restart the Car". The usual cause is the panda refusing commands: after one refusal it accepts only a command near zero. zoompilot prevents this:

  • Matching limits. Device and panda use identical limits, and zoompilot judges your steering effort cautiously.
  • Refusal report. After a refusal, zoompilot restarts from zero, which the panda accepts.
  • Camera passthrough. When zoompilot is not steering, the panda passes the camera's own messages through.

MADS on Mazda

MADS keeps steering separate from cruise. Cancel and the brake stop cruise but leave steering on, unless Steering Mode on Brake Pedal says pause or disengage. The cruise main button turns both off.

TJA button. With Mazda TJA Button on, the TJA button switches steering and the main button controls only cruise. If a TJA press arms cruise that was off, zoompilot disarms it. While zoompilot steers with cruise off, the dash shows a white steering wheel.

Two checks in step. The device and the panda each decide from the same signals whether steering is allowed. If they disagree, you see "Steering Blocked by Panda Safety", then "Controls Mismatch: Lateral" turns steering off.

settings

Under Settings → Steering (comma 4: torque control and mads submenus), keep Enforce Torque Lateral Control on. Customize Torque Params holds Self-Tune, Less Restrict Settings for Self-Tune (Beta) (widens the bands to ±100%) and Torque Control Tune Version. Enable Custom Tuning and Manual Real-Time Tuning use your own values instead of learned ones. Customize MADS holds the two MADS settings above.

For developers

Code at develop.

  • Car: opendbc_repo/opendbc/car/mazda/{values,interface,carcontroller,carstate}.py.
  • Panda: opendbc_repo/opendbc/safety/modes/mazda.h (MAZDA_EPS_HW_STEERING_LIMITS, selected by MazdaSafetyFlags.EPS_HW, set on every gen1 Mazda).
  • Tune: openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v2.py, latcontrol_torque_ext_zp.py (EPS rail as steer_max, per-speed interpolation), steer_limit.py, torque_tune.py, controls_lateral_zp.py (per-size tune swap).
  • Learner: openpilot/sunnypilot/selfdrive/locationd/speed_bin_learner.py; seeds in opendbc_repo/opendbc/car/torque_data/speed_dependent.toml; config in opendbc_repo/opendbc/sunnypilot/car/lateral_tune.py.
  • Seed: openpilot/sunnypilot/selfdrive/car/mazda_torque_seed.py.
  • MADS: openpilot/sunnypilot/mads/mads.py, opendbc_repo/opendbc/sunnypilot/car/mazda/mads.py; events in openpilot/sunnypilot/selfdrive/car/car_specific.py.

Constants.

EPS_STEER_MAX = STEER_MAX = 1200; STEER_DELTA_UP = STEER_DELTA_DOWN = 12; STEER_STEP = 1; STEER_DRIVER_ALLOWANCE = 15; STEER_DRIVER_MULTIPLIER = 15; STEER_DRIVER_SAMPLES = 10; STEER_DRIVER_MARGIN = 2; panda max_rt_delta = 384; TUNE_STEER_MAX = 800 (TUNE_SCALE = 1.5 for params.toml, NNLC and typed values); EPS_CEILING_LOOKUP = 1148 at 8.0 m/s to 620 at 14.5 m/s; STEER_UNDELIVERED_MIN = 200; STEER_UNDELIVERED_FRAMES = 20; STEER_UNDELIVERED_ALERT_FRAMES = 80; STEER_UNDELIVERED_ALERT_MIN_SPEED = 12 mph; STEER_UNDELIVERED_ALERT_ORIGIN_SPEED = 1.0 m/s; LKAS_LIMITS.DISABLE_SPEED / ENABLE_SPEED = 45 / 52 km/h; LKAS_REARM_T = 3.0 s; LKAS_REARM_FAULT_T = 4.0 s; steerActuatorDelay = 0.14 s; MAZDA_STEER_TO_ZERO_TORQUE_TUNE = 2.0; TUNE_SWAP_INACTIVE_FRAMES = 0.5 s; LATERAL_MISMATCH_WARN_FRAMES = 20; LATERAL_MISMATCH_DISABLE_FRAMES = 200. CX-5 2022 speed bins: 3.5, 6.5, 9.5, 12.0, 16.4, 21.0, 28.0, 34.5, 37.0 m/s, min_speed = 2.0, seed_version = 3. Default bins: 5 to 40 m/s in 7 ranges.

Engineering record.

mazda-lateral.md · lateral-tune.md · lateral-tune-roadmap.md · mads.md. The measurements and route data live in the private zoompilot-research repository.

This is experimental software. You drive the car, follow the law, and carry all the risk. Read the safety page first.

zoom-zoom-zoom · by Zeph Leggett