Nissan: drive the LKAS HUD from lateral engagement - #318
Open
downquark7 wants to merge 1 commit into
Open
Conversation
|
Thanks for contributing! A maintainer will review your pull request soon. |
The PROPILOT HUD was gated on CC.enabled, which on Nissan is only true when the stock ACC is engaged. Under Always On Lateral openpilot commands the EPS with CC.enabled false, so the cluster showed no steering wheel icon and no green lane lines while the car was actively being steered. CC.latActive on its own is too narrow: the EPS won't hold an angle at a standstill, so controlsd forces it false below 0.3 m/s and the icon would blink off at every light. Hold the last engaged state across that same gate, guarded by cruiseState.available so it clears when ProPILOT is switched off, and keep CC.enabled as a fallback. The HUD can only light up in cases where it is currently dark and never goes dark where it currently lights. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
downquark7
force-pushed
the
feature/update-carcontroller
branch
from
August 20, 2026 17:32
6ec597a to
21a7c28
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On Nissan the ProPILOT HUD is driven by
CC.enabled:nissan/interface.pynever setsopenpilotLongitudinalControl, so Nissan inherits the defaults (pcmCruise = True,openpilotLongitudinalControl = False) andCC.enabledonly goes true when the stock ACC is engaged.With Always On Lateral that's the wrong condition. AOL steers with cruise off, and
controlsd.pyalready folds it into the lateral flag:So the LKAS frame goes out with
LKA_ACTIVEset and real torque behind it, while the HUD frame in the very same tick reports nothing. The cluster shows no steering wheel icon and no green lane lines while the car is actively being steered.Why the steering wheel icon matters
It's the driver's only in-cluster confirmation that the car is steering itself. The openpilot UI lives on a separate screen that's usually outside the primary sightline, so when AOL is holding the lane and the dash shows nothing, the driver gets a direct contradiction: the wheel is moving on its own but every instrument says the system is off. That's the exact ambiguity a HUD exists to remove — is that resistance in the wheel openpilot steering, or is it a fault? Am I responsible for this lane or is the car?
An honest icon resolves it in both directions. Lit means keep supervising the lateral task. Dark means you own the wheel. Right now it's dark in a state where the driver very much should be supervising. The green lane lines carry the same meaning and are wrong for the same reason, so they follow the same signal here.
Why not just
CC.latActiveThat was my first instinct and it's too narrow.
NissanCarSpecsdoesn't overrideminSteerSpeed(defaults0.0) andsteerAtStandstillis never set, so the gate incontrolsd.pyreduces to:with no escape hatch.
latActivetherefore drops at every stop, and the icon would blink off at each red light — a visible regression against today's behavior, whereCC.enabledholds through the stop.frogpilotPlan.lateralCheckandsteerFaultTemporaryadd more flicker on top of that.The EPS declining to hold an angle at 0 mph is an actuation limit, not a change in engagement, so the HUD shouldn't track it.
The fix
Latch the last engaged state across the standstill gate, and keep
CC.enabledas a fallback for anyone not running AOL:The refresh condition is the exact inverse of controlsd's standstill predicate, so the hold covers precisely the window the gate blanks — including creeping between 0 and 0.3 m/s, which
CS.out.standstillalone would miss (it's wheel-speed-zero on Nissan,carstate.py:60).The held state is guarded by
cruiseState.availablebecause that is literally what arms AOL on a non-Hyundai platform:so switching ProPILOT off while stopped clears the icon on the next frame instead of leaving it lit until the car moves.
Because
CC.enabledis still in the disjunction, this is a strict superset of the current condition — it can only ever light the icon where it is currently dark, and can never darken it where it currently lights. No existing behavior changes for anyone not using Always On Lateral.Scope
Nissan only —
nissan/carcontroller.pyandnissan/nissancan.py, +14/−5. No shared files, nocerealchanges, no new toggle, no safety or DBC changes (every signal already exists with the right value table).create_lkas_hud_msghas exactly one caller, and itsenabledparameter is renamed tolat_engagedto match what it now means.NISSAN_ALTIMA is unaffected — it gets no HUD message at all because of its ADAS bus topology.
Verification
create_lkas_hud_msghas a single call site, so the signature change is contained.LARGE_STEERING_WHEEL_ICONis a lateral indicator:VAL_ 689 LARGE_STEERING_WHEEL_ICON 0 "NO_STEERINGWHEEL" 1 "GRAY_STEERINGWHEEL" 2 "GREEN_STEERINGWHEEL" 3 "GREEN_STEERINGWHEEL_FLASHING".On not plumbing
alwaysOnLateralEnabledThe alternative would be exposing
frogpilotCarState.alwaysOnLateralEnabledto the car layer, which reads cleaner but touchescerealand the shared car-port API for a single-brand HUD fix.interfaces.pyforwards only(c, self.CS, now_nanos, frogpilot_toggles)to the controller, so there's no way to reach it without widening that signature for every brand. GivencruiseState.availableis the same condition AOL arms on, the local version gets the same behavior with no blast radius. Happy to switch if you'd rather have it plumbed properly.Prior art
Same fix, same reasoning, merged upstream in sunnypilot: sunnypilot/opendbc#371. There it reads
CC_SP.mads.enabled, which is their MADS state-machine flag including thepausedstate — engagement rather than actuation. FrogPilot has noCC_SPequivalent exposed to car ports, hence the latch. Ford, Honda, VW and Chrysler already drive their LKAS indicators from lateral state upstream in opendbc; Nissan and Rivian are the remaining ports still onCC.enabled.