Skip to content

mazda: add alpha longitudinal support#3355

Open
yummydirtx wants to merge 3 commits intocommaai:masterfrom
yummydirtx:mazda-longitudinal-upstream
Open

mazda: add alpha longitudinal support#3355
yummydirtx wants to merge 3 commits intocommaai:masterfrom
yummydirtx:mazda-longitudinal-upstream

Conversation

@yummydirtx
Copy link
Copy Markdown

Mazda Longitudinal (MRCC) Port Writeup

This PR adds alpha longitudinal control for the Mazda CX-5 by taking over the stock MRCC longitudinal path and publishing synthetic ACC control messages that preserve Mazda's expected state transitions, including stop-and-go hold and resume behavior.

The implementation is intentionally conservative: it keeps the stock lateral path structure, reuses OEM-like signal patterns where possible, and aligns software behavior with Panda safety constraints so invalid longitudinal packets are rejected early.

Scope

  • Adds Mazda longitudinal control plumbing in:
    • opendbc/car/mazda/interface.py
    • opendbc/car/mazda/carstate.py
    • opendbc/car/mazda/carcontroller.py
    • opendbc/car/mazda/longitudinal.py
  • Extends Mazda safety mode for long control:
    • opendbc/safety/modes/mazda.h
  • Extends safety tests:
    • opendbc/safety/tests/test_mazda.py
    • opendbc/safety/tests/common.py
  • Refines Mazda DBC signal coverage for ACC control messages:
    • opendbc/dbc/mazda_2017.dbc

Current Availability

Longitudinal is enabled as alpha-long for:

  • MAZDA_CX5_2022

In CarInterface, this is gated with:

  • ret.alphaLongitudinalAvailable = candidate == CAR.MAZDA_CX5_2022
  • ret.openpilotLongitudinalControl = alpha_long and ret.alphaLongitudinalAvailable

It's entirely possible that this alpha longitudinal method works on CX-9 too, but that needs to be verified with further on-car testing.

Architecture Overview

Mazda stock ACC behavior is radar-owned for longitudinal. The approach in this port is:

  1. Enter radar diagnostic programming session at init.
  2. Keep that session alive with periodic tester-present.
  3. Publish synthetic ACC control messages (CRZ_INFO and CRZ_CTRL) at stock-like timing and state transitions.
  4. Preserve expected cruise/HOLD/resume semantics by emulating Mazda's stop-go substate progression.

Radar Session Management

  • Radar UDS address: 0x764 on bus 0
  • Init path sends diagnostic session control to programming session (0x10 0x02), with retries.
  • Runtime sends tester-present (0x3E 0x80) periodically to keep suppression active.
  • Deinit intentionally does not force default session because explicit teardown requests were observed to fault radar, no working method exists to teardown without triggering said fault, which disables MRCC activation until the next vehicle power cycle.

Key implementation points:

  • enter_radar_programming_session(...) in longitudinal.py
  • create_radar_tester_present(...) sent every TESTER_PRESENT_STEP = 50 control frames

Assuming DT_CTRL = 0.01s, tester-present is sent at ~2 Hz.

Command Path

Messages and Timing

Longitudinal control publishes:

  • CRZ_INFO (0x21B) on bus 0
  • CRZ_CTRL (0x21C) on bus 0

at LONG_COMMAND_STEP = 2 control frames.

Assuming DT_CTRL = 0.01s, this is ~50 Hz.

CRZ_INFO (0x21B)

CRZ_INFO carries the synthetic acceleration request and stop/resume state bits.

Fields explicitly controlled:

  • ACCEL_CMD
  • ACC_ACTIVE
  • ACC_SET_ALLOWED
  • CRZ_ENDED (forced 0)
  • STOPPING_MAYBE
  • STOPPING_MAYBE2
  • RESUME_UNLATCHING_MAYBE
  • CTR1 (mod 16)
  • checksum

Accel Command Mapping

ACCEL_CMD is generated as a raw integer command with speed-dependent scaling:

  • Positive accel scale breakpoints (m/s): (0.0, 4.2, 11.1, 22.2)
  • Positive scale values: (1000, 1000, 950, 800)
  • Negative accel scale breakpoints (m/s): (0.0, 1.4, 5.6, 22.2)
  • Negative scale values: (1200, 1000, 925, 950)
  • Clipped raw output range: [-2000, 2000]

Rationale: one global scale worked but felt too aggressive at higher speed; split maps keep stronger low/mid-speed authority and soften high-speed behavior.

Checksum

CRZ_INFO checksum is computed as inverted byte-sum (excluding checksum byte), with an additional +0x04 bias when active stop bits are asserted (ACTIVE_STOP_CHECKSUM_BIAS).

That bias was required to match Mazda's expected stop-phase encoding.

CRZ_CTRL (0x21C)

CRZ_CTRL is built from profile templates and then patched with state bits/signals.

Profiles:

  • STANDBY: 02010b0000000000
  • ENGAGED_CRUISE: 0a018b2000001000
  • ENGAGED_FOLLOW: 0a018b4000001000
  • STOP_GO_HOLD: 0a018b6000001000
  • STOP_GO_HOLD_LATCHED: 0a018b8000001000

Patched fields include:

  • CRZ_ACTIVE
  • ACC_ACTIVE_2
  • DISABLE_TIMER_1 and DISABLE_TIMER_2 (forced 0)
  • RADAR_HAS_LEAD
  • RADAR_LEAD_RELATIVE_DISTANCE
  • ACC_GAS_MAYBE2

The logic explicitly sets lead-distance/gas semantics for OEM-like transitions:

  • Passive/latched hold: distance = 4, ACC_GAS_MAYBE2 = 0
  • Active stop-go or resume phase: distance = 3, ACC_GAS_MAYBE2 = 1
  • Follow/cruise: uses template defaults

Stop-and-Go Strategy

The core goal is to reproduce Mazda's hold/release behavior without abrupt unlatches.

State Latching

Controller-level latches track stop intent and resume phases:

  • stop_intent_latched
  • standstill_hold_frames
  • resume_release_frames
  • resume_crz_latched_frames
  • resume_phase_frames

Important timing thresholds:

  • CRZ_CTRL_LATCH_FRAMES: ~2.0s
  • CRZ_CTRL_PASSIVE_FRAMES: ~9.6s
  • HOLD_REQUEST_FRAMES: ~6.0s
  • RESUME_RELEASE_FRAMES: ~0.5s
  • CRZ_INFO_RESUME_PHASE_FRAMES: ~0.2s

Hold Brake Commands

When stop intent is active:

  • Near stop: command ramps toward hold target before standstill
  • Standstill (pre-latched): strong hold command
  • Latched hold: command relaxes near zero as chassis hold latch takes over

Raw targets used:

  • Hold brake target: -1024
  • Near-stop target: -750 (ramped into hold)
  • Hold-latched target: -1

This mirrors observed OEM behavior: braking force is carried through active stop, then relaxed once hold latch is established.

Resume Handling

Resume can be requested physically (wheel RES) or virtually (planner resume), but virtual resume is intentionally delayed until a RES frame is actually transmitted and hold latch is ready.

This avoids releasing synthetic hold from transient planner noise.

Additional safeguards:

  • During brake-release window, accel is clamped non-negative.
  • CRZ_INFO stop bits are cleared during release to avoid "positive accel + active stop" mismatch.

CarState and Engagement Semantics

In alpha-long mode, radar-owned CRZ_CTRL is suppressed. Because of that:

  • CarState does not rely on CRZ_CTRL for cruise availability.
  • Cruise available/enabled is derived from PEDALS bits:
    • ACC_OFF = armed
    • ACC_ACTIVE = engaged
  • CRZ_BTNS parsing includes CANCEL and synthetic MAIN decoding (MODE_X && MODE_Y) so button events remain reliable under radar suppression.

This keeps higher-level engagement logic stable while stock radar control messages are intentionally absent.

Safety Model

Mazda safety mode now supports a longitudinal parameter:

  • MAZDA_PARAM_LONGITUDINAL = 1

When enabled, TX allowlist extends to:

  • 0x21B (CRZ_INFO)
  • 0x21C (CRZ_CTRL)
  • 0x764 (radar UDS)

Longitudinal Safety Checks

  • CRZ_INFO.ACCEL_CMD is decoded from packed bits and validated with longitudinal limits:
    • max_accel = 2000
    • min_accel = -2000
    • inactive_accel = 0
  • CRZ_CTRL with active cruise is blocked when controls are not allowed.
  • UDS at 0x764 is strictly whitelisted to:
    • tester-present (0x3E 0x80)
    • session control (0x10 0x01 or 0x10 0x02)
  • In long mode, ACC state tracking shifts from CRZ_CTRL to PEDALS bits to avoid false disengage edges during suppression.

Test Coverage

Added/extended tests include:

  • TestMazdaLongitudinalSafety with Mazda long safety param (1)
  • Longitudinal accel boundary checks over full integer-domain range around [-2000, 2000]
  • Validation in both default and raised-longitudinal-limit alternative experience modes
  • Common safety test adjustment so shared Mazda TX message expectations are compared correctly across base and long variants

This ensures Panda safety behavior is aligned with sender-side clipping and signal packing.

My Approach (Design Notes)

The guiding principles for this implementation were:

  • OEM-state emulation over minimal actuation: reproducing hold/resume substate transitions reduced unlatch artifacts and improved stop-go reliability.
  • Bit-level DBC correctness first: many early issues were not control law issues but state-bit/checksum mismatches; correctness at message level was prioritized.
  • Safety symmetry: software command limits and Panda limits were kept intentionally identical to avoid silent safety drops at runtime.
  • Conservative rollout: feature-gated to a narrow Mazda variant (CX-5 2022) while behavior and logs mature.

Known Limitations

  • Alpha-long is currently scoped to MAZDA_CX5_2022 only.
  • Radar remains unavailable while longitudinal is synthesized.
  • AEB braking is disabled on-car.
  • A number of malfunctions relating to the Radar being unavailable appear on the dash. In my testing, they have never interfered with vehicle operation.

Future Work

  • Expand alpha-long eligibility to additional Mazda fingerprints after route validation.
  • Improve per-speed command shaping and near-stop tuning with more maneuvers.
  • Investigate broader use of radar/object data paths once takeover behavior is stable.
  • Find a way to suppress superfluous dash malfunctions while alpha longitudinal is enabled.
  • Add more route-backed regression tests for stop-go resume edge cases.

Validation

@github-actions github-actions Bot added DBC signals car related to opendbc/car/ mazda car safety vehicle-specific safety code labels Apr 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

Car behavior report

Replays driving segments through this PR and compares the behavior to master.
Please review any changes carefully to ensure they are expected.

Testing 17 segments for: MAZDA_CX5, MAZDA_CX9_2021, MAZDA_CX5_2022

⚠️ 3 changed, 14 passed, 0 errors

Show changes

MAZDA_CX5_2022 - 8a9dac95d24c4e8d/2025-04-15--07-27-00/2

  carParams.alphaLongitudinalAvailable (1 diffs)

<!-- thollander/actions-comment-pull-request "car_diff" -->

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing to opendbc! In order for us to review your PR as quickly as possible, check the following:

  • Convert your PR to a draft unless it's ready to review
  • Read the contributing docs
  • Before marking as "ready for review", ensure:
    • the goal is clearly stated in the description
    • all the tests are passing
    • include a route or your device' dongle ID if relevant

@yummydirtx yummydirtx marked this pull request as draft April 24, 2026 03:29
@yummydirtx yummydirtx marked this pull request as ready for review April 24, 2026 04:10
yozorakumo added a commit to yozorakumo/FrogPilot that referenced this pull request May 8, 2026
… for Mazda 2 DJ MT

- Fix hazard recognition: use BLINK_INFO LEFT_BLINK+RIGHT_BLINK instead of TURN_SWITCH HAZARD (momentary signal)
- Add longitudinal control support based on PR commaai/opendbc#3355
- New file: selfdrive/car/mazda/longitudinal.py (CRZ_INFO/CRZ_CTRL message builder, radar session management)
- Update DBC: add CRZ_INFO, STEER_RELATED, STEER2 messages to mazda_2_dj_mt.dbc
- Update interface.py: enable alphaLongitudinalAvailable for MAZDA_2_DJ_MT
- Update carstate.py: PEDALS-based cruise state for longitudinal mode
- Update carcontroller.py: Stop-and-Go state machine, accel calculation, longitudinal message sending
- Update safety_mazda.h: longitudinal safety checks (ACCEL_CMD, CRZ_CTRL, RADAR UDS whitelist)
- Add implementation plan document
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

car safety vehicle-specific safety code car related to opendbc/car/ DBC signals mazda

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant