Skip to content

mazda: lateral toggle, independent TJA/MRCC, wheel HUD for lateral-engage - #17

Closed
mzdnick wants to merge 4 commits into
zoompilot:developfrom
mzdnick:mazda-lateral-line
Closed

mzdnick wants to merge 4 commits into
zoompilot:developfrom
mzdnick:mazda-lateral-line

Conversation

@mzdnick

@mzdnick mzdnick commented Sep 20, 2026 •

Copy link
Copy Markdown

Problem

  • invalidLkasSetting read the wrong bits and never triggered when Lane-keep Assist System was disabled in vehicle settings.
  • The dash LKA button disengaged openpilot, canceling longitudinal if active.
  • A physical TJA press arms MRCC on bus 0 as a side effect.
  • TJA cars have no visual indication when they're in lateral-only mode.

Fix

  • invalidLkasSetting keys on the intervention bits: either bit is a live setting, only both clear reads as off.
  • On a TJA-enabled car the TJA button is the switch, otherwise the dash LKA button serves the same function; toggle MADS lateral.
  • When MRCC was off before the TJA button is pressed, the controller cancels the MRCC state. MRCC remains active if it was already active.
  • The HUD draws the steering wheel glyph while MADS lateral is ours, dimmed while arming and full once the EPS delivers.

Validation

  • 620 mazda car tests + 296 safety tests host-side, ruff clean; car-wide interface, docs, platform-config and fw-fingerprint suites pass.
  • Device validation pending

Note for future syncs

Event ordinals reserve @32/@33 for future jetlink sync.

Credit

Credit to @chinna244 for the TJA work, majority of the TJA button handling comes from their research and code.

AI Usage

Disclaimer: GLM-5.3 by Z.ai was used to help develop, debug, and document this submission. All changes were reviewed and validated by me.

Issue: a settings-menu or camera state can leave the EPS taking our
steer request and applying none of it, with no block or fault.
Fix: the lane-assist-off state clears both CAM_SETTINGS intervention
bits, LKAS_INERVENTION_ON1 and ILKAS_NTERVENTION_ON2, together; either
bit alone is a live setting, and cameras assert them unevenly, so
CarState raises invalidLkasSetting only when both are clear, replacing
the LANE_LINES term. Latch that the camera sent CAM_SETTINGS once, so
a car that never sends it cannot read as off, and the state holds
through the message's silent cycles.

Validation: mazda car suite 546 passed; corpus replay: a single-bit
camera no longer reads as off, the lane-assist-off drive stays blocked.
@mzdnick
mzdnick force-pushed the mazda-lateral-line branch 2 times, most recently from 3b42f16 to e58419c Compare September 24, 2026 01:42
@mzdnick
mzdnick marked this pull request as ready for review September 24, 2026 02:30
Issue: non-TJA trims expose no wheel button for lateral; the dash LKAS
button is the only switch, and with MADS on its press read as a steering
fault - the delivery watchdog sees the EPS stop applying torque the
instant the button goes off - instead of the driver choice it is.

Fix: read the button's edge from LANE_LINES, the state the dash button
drives (0 lane keep off, 1-4 lane state): two agreeing frames make a
0 <-> nonzero edge one ButtonType.lkas press, the debounced off state
publishes as lkaButtonOff for a lateral-only refusal, and the panda arms
lateral on the on-press from the same frame, its HUD-frame liveness
check riding the declaration. One lateral switch per car: a declared TJA
button owns the press, the state still publishes. The delivery watchdog
holds through a button-off window and alerts only while a request
stands: the latch can outlive the request that earned it. Stock-long
only: a SET press with LKA off is a stock ACC run openpilot never
joined, so cancel no longer kills it.

The TJA press hands a joined cruise back to the driver: on a
TJA-declared car under stock longitudinal, the press that turns MADS
lateral off leaves the driver's stock MRCC engaged underneath, and
controlsd raises cruiseControl.cancel for exactly that state; the
cancel spam disengaged an MRCC the press never asked about. Clear
cruise_joined every cycle CRZ_BTNS carries the TJA bit, on the press
cycle itself and before the MADS disable lands, so the standing
engagement falls into the never-joined protection; joining the cruise
again re-arms the sync cancel. Alpha-long still cancels, the engagement
there being openpilot's own. Without the declaration carstate publishes
tja_button as zero, so the clause is unreachable on other cars.

The re-enabled button stops overselling control too: the EPS holds
LKAS_BLOCK through standstill, a dash LKA-off, and a fixed ~3 s re-arm
after a re-enable (3.03 to 3.06 s, nine of nine measured dash cycles)
before it takes lateral. carstate publishes the bit debounced (0.2 s) as
latBlocked on carState, so the UI can hold lateral as arming until the
EPS actually grants it.

The declaration rides every platform now: sp_flags=LKA_BUTTON on all
eight, not the one body the feature was written on. The 2022-generation
cameras (CX-5 2022, CX-9 2021-23, CX-8 2023) share the family the
feature was tuned on. The 2016.5-era camera bodies (CX-5 KE and
2017-21, CX-9 2016-20, Mazda 3, Mazda 6) are declared on the shared
decode alone: a 121 s KE firmware capture shows that camera streaming
the HUD frame continuously at 1 Hz with LANE_LINES in one steady state,
but no capture holds a button edge on the older family, so a drive log
per body closes the press semantics. Declaring also carries the
HUD-frame disappearance check to those bodies' drivers, MADS on or off.
Suites on the rebuilt line: 620 car + 296 safety passed, 44 skipped,
220 subtests; ruff clean.

Validation: mazda suites 562 car + 289 safety passed, 44 skipped, 215
subtests; ruff clean. Route 9ff65375 (2026-09-16): every toggle drove
LANE_LINES to zero and back on marked road, unmarked streets held the
count at one. Stage drive the same evening: boot-off silent arm,
no-entry while off, ON edges engage lateral, and the standing-request
gate silenced the four false warnings seen before it. The re-arm window
was measured on the stage drive's dedicated capture, ten dash cycles.
Issue: the physical TJA button arms MRCC on bus 0 as a side effect of
the press the driver declared as the lateral switch; the frame reaches
bus-0 ECUs directly, so the arm cannot be prevented.
Fix: when MRCC was off before the press, the controller answers the arm
with the same MRCC master press the driver would use: one exact
active-low CRZ_BTNS shape, one frame per body-paced 200 ms slot, at
most three frames per unreconciled arm, never sent while PEDALS reads
disarmed, stopped by raw PEDALS confirming the arm is gone. A second
press before the first arm reconciled read that arm as the driver's
baseline and cancelled the undo; a press edge inside a live episode
now keeps the episode with its frame budget back, since the visible
arm is the first press's artifact, and only a press with no live
episode samples the armed state. The driver's own cruise presses, a
held TJA press, and radar or stock-ECU transitions all stand down, and
ICBM stands down through the whole TJA hold. A car that never arms
through the press stands down after 1 s of brake-free time, since
PEDALS cannot witness an arm under braking.

Validation: 620 mazda car tests + 296 safety tests host-side; the
double-press regression tests fail without the episode rule.
While the EPS takes our request and holds no lateral (the arming window
after engagement, the re-arm hold after a dash LKA re-enable), the stock
HUD shows nothing to explain the missing assistance. Draw the steering
wheel glyph on the HUD while MADS lateral is ours, dimmed while arming
and full once the EPS delivers, on declared cars only.

Validation: 620 mazda car tests + 296 safety tests host-side, ruff clean.
@zephleggett

Copy link
Copy Markdown

Taken into danger-unstable for on-car testing: commit 1 (invalidLkasSetting from the CAM_SETTINGS intervention bits) as 854bb8b, merged as a union with a local fix so the upstream LANE_LINES term still counts and the setting reads off only when both bits are clear. The same branch removes the bus-2 camera TJA press (a02b4a5): route 00000105 showed it switching the car's own lane-keep setting off, so the press this PR keeps is the cause of the state commit 1 detects.

Not taken, for now:

  • Commit 2: LKA_BUTTON defaults on for every platform, LANE_LINES 0 also happens on a camera fault (two of our segments) so it would emit a false LKAS press there, the new 0x440 rx check adds a disengage path for every Mazda, and the stock-long cancel change lands on every user. If resubmitted, one mechanism per PR, opt-in per platform, and the STEER_UNDELIVERED_MIN alert gate on its own since that one is a clear fix.
  • Commits 3 and 4 reverse the 09-09 decision to leave the MRCC arm and the white wheel alone. Separate discussion.

zephleggett added a commit that referenced this pull request Sep 25, 2026
With the car's own lane-keep setting off the EPS applies nothing by
design, so a blocked request is not a delivery failure: clear the latch
and do not re-arm or alert while invalidLkasSetting holds. From
#17 (6fff61a), reworked onto the setting read. Its
other change, gating the alert on a nonzero request, is not taken: the
latch zeroes the command, so that gate would never let the alert fire.
@zephleggett

Copy link
Copy Markdown

Update: commits 3 and 4 are now on danger-unstable as well (74fdc86 MRCC undo, dbd88fa white wheel), cherry-picked on top of the camera-press removal; the TestCameraPress suite went with the press, the rest of the tests are intact (866 car + safety pass). Also taken from commit 2 as d088e1a: the non-delivery latch clears and stays off while the lane-keep setting is off, keyed on invalidLkasSetting. Not taken from commit 2: the nonzero-request gate on the alert (the latch zeroes the command, so the alert could never fire with it), the dash LKA toggle, the platform-wide LKA_BUTTON flag, the 0x440 rx check and the stock-long cancel change. HBC on #15 is now relay-only (60300cf): 1164 night segments show stock raising the beams with all six radar slots empty, so the far object was not what the lamps needed.

zephleggett added a commit to zoompilot/zoompilot that referenced this pull request Sep 25, 2026
opendbc dbd88fa682: the TJA-press MRCC undo and the dash white wheel
(zoompilot/opendbc#17), the non-delivery latch inhibited while the car's
lane-keep setting is off, HBC relay only.
@zephleggett

Copy link
Copy Markdown

Closing: everything taken from this PR is on danger-unstable (see the comments above for what changed and what was left out). We will test on the car from a personal branch before it reaches develop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants