Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9269b9a
hyundai: stock-navigation camera kinds, + skip and section average
joongyu01 Sep 27, 2026
fe135cd
hyundai: fix button events zeroed by speedcam filter
joongyu01 Sep 27, 2026
4095894
hyundai: document rear flag as kind-independent (rear speed = kind 0)
joongyu01 Sep 27, 2026
d962410
hyundai: confirm stock-navigation kind 2 as mobile-camera box
joongyu01 Sep 27, 2026
4012b38
speedcam: gas-tap skip, manual section unlock, drop margin setting
joongyu01 Sep 27, 2026
81f428e
speedcam: long cruise - relocks a section without the -10 step
joongyu01 Sep 30, 2026
cacf6ff
speedcam: a mobile zone must sit one lead ahead of the warning start
joongyu01 Sep 30, 2026
eca3454
speedcam: merge repeated navigation previews
joongyu01 Sep 30, 2026
8e90e79
speedcam: drive the section allowance in true speed
joongyu01 Sep 30, 2026
f79974b
speedcam: one deceleration cancel request, now also for speed bumps
joongyu01 Oct 1, 2026
ff4da40
speedcam: optional deceleration cancel for fixed speed cameras
joongyu01 Oct 4, 2026
d04907d
Merge carrot-wip e169478d into joongyu01/carrot-wip-speedcam
joongyu01 Oct 4, 2026
ea8f739
Merge remote-tracking branch 'origin/carrot-wip' into joongyu01/carro…
joongyu01 Oct 4, 2026
6cfeeb9
hyundai: hold the turn signal for the whole lane change, release when…
joongyu01 Oct 3, 2026
d8ba6e7
hyundai: release the lane-change turn signal at 60 % across
joongyu01 Oct 4, 2026
90cee30
speedcam: experimental deceleration cancel for unknown warnings
joongyu01 Oct 4, 2026
084ee9a
speedcam: rename the experimental unknown-warning cancel in settings
joongyu01 Oct 4, 2026
09d170f
speedcam: match the undetected-kind cancel title to its siblings
joongyu01 Oct 4, 2026
7512215
hyundai: count turn-signal lever presses into carState
joongyu01 Oct 3, 2026
18dbb7e
desire: a turn-signal lever press asks for the next lane change
joongyu01 Oct 3, 2026
0b12f7a
desire: latched turn-signal lever means a turn below 50 km/h (Blinker…
joongyu01 Oct 4, 2026
963375f
desire: lever turn speed as a setting, one-touch request waits 5 flashes
joongyu01 Oct 4, 2026
05a2653
desire: a press after the model sees the line crossed asks for the ne…
joongyu01 Oct 4, 2026
b0ddfae
hyundai: cluster message while a latched lever turns the car
joongyu01 Oct 4, 2026
2fd6c15
hyundai: show the lever-turn notice as a 0x161 alert
joongyu01 Oct 4, 2026
b2406cf
speedcam: experimental early-warning correction for camera matching
joongyu01 Oct 5, 2026
2bdeebf
Merge carrot-wip 7135acf2 into joongyu01/carrot-wip-dev
joongyu01 Oct 5, 2026
984dbed
Merge carrot-wip b5c5f84e into joongyu01/carrot-wip-dev
joongyu01 Oct 8, 2026
be6134f
Merge carrot-wip c0c45b0f into joongyu01/carrot-wip-dev
joongyu01 Oct 9, 2026
67591b8
radar: mode 3 does not adopt an SCC body that radar places in another…
joongyu01 Oct 9, 2026
fdc11e2
speedcam: remove the fixed-camera deceleration cancel option
joongyu01 Oct 9, 2026
d792803
Merge carrot-wip 6eeb1999 into joongyu01/carrot-wip-dev
joongyu01 Oct 9, 2026
1db98b7
hyundai: flash the cluster red while the turn model drives
joongyu01 Oct 9, 2026
7639f82
Merge carrot-wip 6a3454e4 into joongyu01/carrot-wip-dev
joongyu01 Oct 11, 2026
71162d3
selfdrived: say "Turn" and "Straight" around the turn model
joongyu01 Oct 11, 2026
5bd2b0e
Merge carrot-wip 335c1c2f into joongyu01/carrot-wip-dev
joongyu01 Oct 11, 2026
42535a3
Merge carrot-wip 8183dfca into joongyu01/carrot-wip-dev
joongyu01 Oct 11, 2026
a0fecae
Merge carrot-wip c5f5a9a2 into joongyu01/carrot-wip-dev
joongyu01 Oct 11, 2026
64f4d27
speedcam: a horizon-bound fixed camera upgrades a running mobile-zone…
joongyu01 Oct 12, 2026
ba39915
Merge carrot-wip 0e4ee1bd into joongyu01/carrot-wip-dev
joongyu01 Oct 12, 2026
2bec4fd
sounds: neural "Turn" / "Straight" voice for the turn model
joongyu01 Oct 12, 2026
f0164e8
Merge carrot-wip 5e187ab9 into joongyu01/carrot-wip-dev
joongyu01 Oct 12, 2026
e64fd58
Merge carrot-wip ecae9957 into joongyu01/carrot-wip-dev
joongyu01 Oct 13, 2026
5ce6cbb
Merge carrot-wip 7dd3c11e into joongyu01/carrot-wip-dev
joongyu01 Oct 13, 2026
56ee63b
Merge carrot-wip 09df1475 into joongyu01/carrot-wip-dev
joongyu01 Oct 13, 2026
59897a3
selfdrived: remove the "Turn" / "Straight" voice prompts
joongyu01 Oct 13, 2026
67de82c
desire: a lever turn needs one-touch, two lamp lightings, then the latch
joongyu01 Oct 13, 2026
f4e6b3a
Merge carrot-wip 1cc404f37 into joongyu01/carrot-wip-dev
joongyu01 Oct 14, 2026
6491bee
Merge carrot-wip 2b8bbf6e8 into joongyu01/carrot-wip-dev
joongyu01 Oct 15, 2026
ea286a0
Merge carrot-wip 8e7eec049 into joongyu01/carrot-wip-dev
joongyu01 Oct 15, 2026
f6b8945
Revert "Merge carrot-wip 8e7eec049 into joongyu01/carrot-wip-dev"
joongyu01 Oct 15, 2026
69b9286
Reapply "Merge carrot-wip 8e7eec049 into joongyu01/carrot-wip-dev"
joongyu01 Oct 15, 2026
aa64dd2
ui(C4): always show the wide road camera
joongyu01 Oct 15, 2026
b8301a3
Reset to carrot-wip 98ded8c29; my changes archived on joongyu01/openp…
joongyu01 Oct 16, 2026
dd60046
ui(C4): ScreenOn setting (default on); turning it off cuts the screen…
joongyu01 Oct 16, 2026
824d88f
Merge carrot-wip c44d20f96 into joongyu01/carrot-wip-dev
joongyu01 Oct 17, 2026
00e3744
ui(C4): with ScreenOn off, a touch wakes the screen for 5 s and onroa…
joongyu01 Oct 17, 2026
52472cf
hyundai(CCNC): ClusterLaneTest sends a raw value to the 0x161 lane-li…
joongyu01 Oct 18, 2026
3edcdff
hyundai(CCNC): show the real gap bars and a gap-change popup while HD…
joongyu01 Oct 18, 2026
9dea619
hyundai(CCNC): keep steering and lane-change cluster icons at an enga…
joongyu01 Oct 18, 2026
5eb4e65
hyundai(CCNC): draw camera-dashed lane lines as dashed on the cluster
joongyu01 Oct 18, 2026
80b9f67
hyundai(CCNC): send 14 (draws nothing) for lane lines the model does …
joongyu01 Oct 18, 2026
1275945
hyundai(CCNC): remove the ClusterLaneTest setting
joongyu01 Oct 18, 2026
7b05287
hyundai(CCNC): keep orange lane lines visible when the model does not…
joongyu01 Oct 18, 2026
9979ad3
Merge carrot-wip 163c000e0 into joongyu01/carrot-wip-dev
joongyu01 Oct 18, 2026
559760d
hyundai(CCNC): keep stock SCC MAIN on for the cluster and add a sign …
joongyu01 Oct 18, 2026
0d5913d
hyundai(CCNC): turn stock SCC MAIN on from ignition, not only above 3…
joongyu01 Oct 18, 2026
539e149
hyundai(CCNC): ClusterLaneTest covers HDP and other 0x161 display fie…
joongyu01 Oct 18, 2026
62ac61e
hyundai(CCNC): ClusterLaneTest sweep mode (field x 10000 + 9999)
joongyu01 Oct 18, 2026
ee4572a
hyundai(CCNC): ClusterLaneTest sweep steps every 1 s
joongyu01 Oct 18, 2026
4085df5
hyundai(CCNC): split ClusterLaneTest into a field (0-26) and ClusterL…
joongyu01 Oct 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/user/en/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ These settings describe the car, harness, and device hardware configuration. Do
| Group | Parameters | Purpose |
|---|---|---|
| Hyundai/Kia | `HyundaiCameraSCC`, `IsLdwsCar`, `HapticFeedbackWhenSpeedCamera` | SCC connection, LDWS behavior, and speed-event haptics |
| CAN FD/HDA | `CanfdHDA2`, `HyundaiCanfdClusterDirectTx`, `CanfdDebug`, `HDPuse` | HDA2 selection, cluster direct send, CAN FD diagnostics, and HDP |
| CAN FD/HDA | `CanfdHDA2`, `HyundaiCanfdClusterDirectTx`, `CanfdDebug`, `HDPuse`, `ClusterLaneTest`, `ClusterLaneTestValue` | HDA2 selection, cluster direct send, CAN FD diagnostics, HDP, and a cluster display test |
| Radar | `EnableRadarTracks`, `RadarTrackFlip`, `EnableCornerRadar`, `CarrotRadarMode`, `CarrotRadarCutInSensitivity` | SCC radar, front-track orientation, corner radar, and Carrot Radar processing and cut-in sensitivity |
| Driver monitoring | `DriverMonitoringEnabled` (search only), `DriverMonitoringMode`, `CarrotVisionEnabled`, `MuteDoor`, `MuteSeatbelt` | Driver monitoring and selected vehicle alerts |
| Vehicle assistance | `MaxAngleFrames`, `SpeedFromPCM` | Steering-angle frames and stock-SCC speed control |
Expand Down Expand Up @@ -296,7 +296,7 @@ In modes `EnableRadarTracks=1`–`3`, a confirmed departing front lead can recei
<a id="display"></a>
## Display

Display contains 34 settings. External-HUD settings control the layout and output of separate display hardware.
Display contains 35 settings. External-HUD settings control the layout and output of separate display hardware.

`ClusterHud` (External HUD Display) switches a **direct USB HUD or a registered ESP32-S3 Wi-Fi HUD** on or off. A HUD connected to Jetson starts automatically even when this value is `0`, and normally turns its display off with ignition. Use the existing always-on `ClusterHudDebug` modes to keep it visible offroad. Brightness and layout settings also apply to the Jetson HUD.

Expand All @@ -313,7 +313,7 @@ With `CarrotVisionEnabled` on, the external HUD and web camera view can be used
|---|---|---|
| Information | `ShowDebugUI`, `ShowTpms`, `ShowDateTime`, `ShowPathEnd`, `ShowDeviceState`, `ShowLaneInfo`, `ShowRadarInfo`, `ShowRouteInfo`, `ShowPlotMode` | Debug, tire, time, lane, radar, and route information |
| Path | `ShowPathMode`, `ShowPathColor`, `ShowPathColorCruiseOff`, `ShowPathModeLane`, `ShowPathColorLane` | Path shape and color by driving state |
| Brightness/on-road view | `ShowCustomBrightness`, `ShowModelView`, `ShowCameraWithCluster` | Brightness, camera/model composition, and the on-device camera while the external HUD is connected |
| Brightness/on-road view | `ShowCustomBrightness`, `ScreenOn`, `ShowModelView`, `ShowCameraWithCluster` | Brightness, C4 screen on/off, camera/model composition, and the on-device camera while the external HUD is connected |
| External HUD | `ClusterHud`, `ClusterHudBrightness`, `ClusterHudOrientation`, and related `ClusterHud*` settings | Supported TURZX HUD layout, live brightness, screen rotation, camera, radar, and encoder options |

For RAV4 2022 with the ARS display stream, `ShowRadarInfo=3` on the standard device
Expand Down
6 changes: 3 additions & 3 deletions docs/user/ko/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ VW MEB(ID.4 포함)에도 수동 조향비와 학습 비율이 적용됩니다.
| 중분류 | 파라미터 | 용도 |
|---|---|---|
| 현대·기아 | `HyundaiCameraSCC`, `IsLdwsCar`, `HapticFeedbackWhenSpeedCamera` | SCC 연결 방식, LDWS 차량과 카메라 구간 햅틱 |
| CANFD·HDA | `CanfdHDA2`, `HyundaiCanfdClusterDirectTx`, `CanfdDebug`, `HDPuse` | HDA2 차량, 계기판 직접 송신과 CAN FD 디버그·HDP 기능 |
| CANFD·HDA | `CanfdHDA2`, `HyundaiCanfdClusterDirectTx`, `CanfdDebug`, `HDPuse`, `ClusterLaneTest`, `ClusterLaneTestValue` | HDA2 차량, 계기판 직접 송신과 CAN FD 디버그·HDP 기능, 계기판 표시 테스트 |
| 레이더 | `EnableRadarTracks`, `RadarTrackFlip`, `EnableCornerRadar`, `CarrotRadarMode`, `CarrotRadarCutInSensitivity` | SCC 레이더, 전방 트랙 좌우 보정, 코너 레이더와 당근레이더 처리·컷인 감도 |
| 운전자 모니터링 | `DriverMonitoringEnabled`(검색 전용), `DriverMonitoringMode`, `CarrotVisionEnabled`, `MuteDoor`, `MuteSeatbelt` | 운전자 모니터링과 일부 차량 경고음 처리 |
| 차량 보조 | `MaxAngleFrames`, `SpeedFromPCM` | 최대 조향각 관련 프레임과 순정 SCC 속도 제어 방식 |
Expand Down Expand Up @@ -295,7 +295,7 @@ Bosch MRRevo14F 수신을 지원하는 버전에서 Bosch MRRevo14F 후보 차
<a id="display"></a>
## 화면 표시

화면 표시에는 34개 항목이 있습니다. 외부 HUD 항목은 별도 하드웨어의 화면 구성과 출력 방식을 조정합니다.
화면 표시에는 35개 항목이 있습니다. 외부 HUD 항목은 별도 하드웨어의 화면 구성과 출력 방식을 조정합니다.

`ClusterHud`(외부 HUD 활성화)는 **본체 USB에 직접 연결한 HUD 또는 등록된 ESP32-S3 Wi-Fi HUD**를 켜고 끄는 설정입니다. Jetson에 연결한 HUD는 이 값이 `0`이어도 자동 실행되며, 기본적으로 시동 OFF 시 화면을 끕니다. 시동 OFF에도 표시하려면 기존 `ClusterHudDebug`의 항상 켜기를 사용합니다. 밝기·화면 구성 설정은 Jetson HUD에도 적용됩니다.

Expand All @@ -312,7 +312,7 @@ Jetson HUD에는 `jetSON` 아래에 Jetson 내부 센서의 최고 온도가 표
|---|---|---|
| 정보 표시 | `ShowDebugUI`, `ShowTpms`, `ShowDateTime`, `ShowPathEnd`, `ShowDeviceState`, `ShowLaneInfo`, `ShowRadarInfo`, `ShowRouteInfo`, `ShowPlotMode` | 주행 화면의 디버그, 타이어, 시간, 차선, 레이더와 경로 정보 |
| 경로 표시 | `ShowPathMode`, `ShowPathColor`, `ShowPathColorCruiseOff`, `ShowPathModeLane`, `ShowPathColorLane` | 레인리스·레인모드·크루즈 OFF 상태의 경로 모양과 색상 |
| 밝기·주행화면 | `ShowCustomBrightness`, `ShowModelView`, `ShowCameraWithCluster` | 주행 중 밝기, 카메라·모델 표시 조합과 외부 HUD 연결 중 본체 카메라 표시 |
| 밝기·주행화면 | `ShowCustomBrightness`, `ScreenOn`, `ShowModelView`, `ShowCameraWithCluster` | 주행 중 밝기, C4 화면 켜기·끄기, 카메라·모델 표시 조합과 외부 HUD 연결 중 본체 카메라 표시 |
| 외부 HUD·기본 | `ClusterHud`, `ClusterHudBrightness`, `ClusterHudOrientation`, `ClusterHudMirror`, `ClusterHudTheme`, `ClusterNaviMapTheme`, `ClusterNaviMapType`, `ClusterNaviMapFps` | TURZX 외부 HUD, 밝기, 화면 회전, 미러링과 지도 테마 |
| 외부 HUD·화면·카메라 | `ClusterHudEncoder`, `ClusterHudScreenMode`, `ClusterHudPanelLayout`, `ClusterHudCameraViewMode` | 인코더와 화면·카메라·좌우 패널 구성 |
| 외부 HUD·레이더 표시 | `ClusterHudRadarInfo`, `ClusterHudRadarDisplay`, `ClusterHudRadarSourceColor` | 외부 HUD의 레이더 정보와 색상 |
Expand Down
131 changes: 117 additions & 14 deletions opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,78 @@ def _hide_replaced_adas_service_warning(values):
values["FAULT_DAS"] = 0


LANE_LINE_UNSEEN = 14 # draws nothing on the Ioniq 5 PE cluster; undocumented on purpose, so a cluster update that changes it is noticed
# model laneLineProbs at low speed (10-18 rlogs, night): parking lots 0.01~0.04, city stops 0.13~0.22, highway ~1.0
LANE_HIDE_PROB, LANE_SHOW_PROB, LANE_HIDE_FRAMES = 0.08, 0.12, 100 # hide after 1 s below 0.08, show again from 0.12


def _lane_unseen(state, side, prob, frame):
hidden, low_since = state.get(side, (False, None))
if prob >= LANE_SHOW_PROB:
hidden, low_since = False, None
elif prob < LANE_HIDE_PROB:
low_since = frame if low_since is None else low_since
hidden = hidden or frame - low_since >= LANE_HIDE_FRAMES
else:
low_since = None # in between: keep the current state
state[side] = (hidden, low_since)
return hidden


# ClusterLaneTest = field, ClusterLaneTestValue = raw value (test only): DBC fields, or 0x162 bits the DBC does not name
CLUSTER_TEST_FIELDS = {1: "SPEEDLIMIT", 2: "SPEEDLIMIT_FLASH", 3: "SIGNS", 4: "SPEEDLIMIT_WEATHER", 5: "COUNTRY"} # 0x162
CLUSTER_TEST_FIELDS_161 = {6: "SLA_ICON", 12: "HDA_ICON", 13: "LFA_ICON", 14: "SETSPEED", 15: "SETSPEED_HUD", 16: "CAR_CIRCLE",
17: "DISTANCE", 18: "DISTANCE_CAR", 19: "DISTANCE_SPACING", 20: "DISTANCE_LEAD",
21: "ALERTS_4", 22: "ALERTS_5", 23: "BACKGROUND", 24: "LANE_HIGHLIGHT", 25: "LANE_ZOOM", 26: "CENTERLINE"}
CLUSTER_TEST_BITS = {7: tuple(range(53, 64)), 8: tuple(range(159, 163)), 9: tuple(range(183, 192)), 10: tuple(range(252, 256)),
11: (87, 111, 135, 212)}


CLUSTER_TEST_SWEEP = -1 # ClusterLaneTestValue -1: step the field every 1 s and show the step in the set speed number


def _cluster_test():
params = Params()
field = params.get_int("ClusterLaneTest")
return (field, params.get_int("ClusterLaneTestValue")) if field > 0 else (0, 0)


def _cluster_sweep(packer, field, frame):
# returns (value to send, number to show); bit groups step one bit at a time and show the bit number
state = create_ccnc_messages.__dict__.setdefault('_sweep', {})
if state.get('field') != field:
state.update(field=field, start=frame)
step = (frame - state['start']) // 100
if field in CLUSTER_TEST_BITS:
bits = CLUSTER_TEST_BITS[field]
i = step % (len(bits) + 1)
return (0, 0) if i == 0 else (1 << (i - 1), bits[i - 1])
if field in CLUSTER_TEST_FIELDS:
sig = packer.dbc.name_to_msg['CCNC_0x162'].sigs[CLUSTER_TEST_FIELDS[field]]
elif field in CLUSTER_TEST_FIELDS_161:
sig = packer.dbc.name_to_msg['ADRV_0x161'].sigs[CLUSTER_TEST_FIELDS_161[field]]
else:
return 0, None
value = step % (1 << sig.size)
return value, value


def _set_raw_bits(msg, bits, value):
addr, dat, bus = msg
d = bytearray(dat)
for i, b in enumerate(bits):
d[b // 8] = (d[b // 8] & ~(1 << (b % 8))) | (((value >> i) & 1) << (b % 8))
d[0:2] = hkg_can_fd_checksum(addr, None, d).to_bytes(2, 'little')
return addr, bytes(d), bus


def _dashed_lane_line(color, lane_line):
# 0x161 dashed codes seen on the Ioniq 5 PE cluster: 8 white, 10 green (no orange dashed)
if lane_line // 10 > 0 and lane_line % 10 in (0, 5): # camera: dashed / DLM inner dashed (color 0 = no lane info)
return {2: 8, 6: 10}.get(color, color)
return color


def _select_cluster_background(cruise_enabled, lat_active, paddle_pressed, paddle_mode, turning=False):
# Reuse the existing flashing-red background to identify an active model turn.
if (lat_active and turning) or (paddle_mode > 0 and paddle_pressed):
Expand Down Expand Up @@ -992,10 +1064,14 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
if HDA_LFA_SymSta == 0 and 0 < frame % 200 < 12:
values["LFA_BTN"] = 1

# The cluster's side objects, lead car and target come from stock SCC MAIN; keep it on from ignition.
# openpilot's own MAIN still follows the driver's button (manual_main_off_latched).
if not CS.MainMode_ACC and not interlock_active and 10 < frame % 200 <= 16:
values["ADAPTIVE_CRUISE_MAIN_BTN"] = 1

if CC.enabled and not interlock_active:
if not CS.MainMode_ACC:
if 10 < frame % 200 <= 16 and CS.out.vEgo > 3.:
values["ADAPTIVE_CRUISE_MAIN_BTN"] = 1
pass # pressed above
elif CS.ACCMode in [0, 4]:
if 10 < frame % 200 <= 16 and CS.out.vEgo > 3.:
values["CRUISE_BUTTONS"] = 2
Expand All @@ -1012,11 +1088,19 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
# --- 0x161/0x200/0x1ea/0x162 (frame%5) ---
if frame % 5 == 0:
lat_active = CC.latActive
test_field, test_value = _cluster_test()
sweep_display = None
if test_value == CLUSTER_TEST_SWEEP:
test_value, sweep_display = _cluster_sweep(packer, test_field, frame)
else:
create_ccnc_messages.__dict__.pop('_sweep', None)

if CS.adrv_0x161 is not None:
main_enabled = CS.out.cruiseState.available
cruise_enabled = CC.enabled
lat_enabled = CS.out.latEnabled
# steering pauses at standstill; keep the cluster's steering/lane-change icons as if it were active
lat_icon = lat_active or (cruise_enabled and lat_enabled and CS.out.standstill)
nav_active = hud_control.activeCarrot > 1
vehicle_navi_available = CS.out.vehicleNaviAvailable
nav_icon_available = nav_active or vehicle_navi_available
Expand All @@ -1038,12 +1122,12 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH)
values["vSetDis"] = int(set_speed_in_units + 0.5)

values["DISTANCE"] = 4 if hdp_active else hud_control.leadDistanceBars
values["DISTANCE_LEAD"] = 2 if cruise_enabled and lead_visible else 1 if main_enabled and lead_visible else 0
values["DISTANCE"] = hud_control.leadDistanceBars # real gap bars under the HDP colors too
values["DISTANCE_LEAD"] = (2 if cruise_enabled else 1) if lead_visible else 0
values["DISTANCE_CAR"] = 3 if hdp_active else 2 if cruise_enabled else 1 if main_enabled else 0
values["DISTANCE_SPACING"] = 5 if hdp_active else 1 if cruise_enabled else 0

values["TARGET"] = 1 if lead_visible and cruise_enabled else 0
values["TARGET"] = (1 if cruise_enabled else 3) if lead_visible else 0 # blue when engaged, white otherwise
values["TARGET_DISTANCE"] = lead_distance

values["BACKGROUND"] = _select_cluster_background(
Expand All @@ -1054,8 +1138,8 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,

values["NAV_ICON"] = 2 if nav_icon_available and cruise_enabled else 1 if main_enabled and nav_icon_available else 0
values["HDA_ICON"] = 5 if hdp_active else 2 if cruise_enabled else 1 if main_enabled else 0
values["LFA_ICON"] = 5 if hdp_active else 2 if lat_active else 1 if lat_enabled else 0
values["LKA_ICON"] = 4 if lat_active else 3 if lat_enabled else 0
values["LFA_ICON"] = 5 if hdp_active else 2 if lat_icon else 1 if lat_enabled else 0
values["LKA_ICON"] = 4 if lat_icon else 3 if lat_enabled else 0
values["FCA_ALT_ICON"] = 0

if values["ALERTS_2"] in [1, 2, 5, 6, 10, 21, 22]:
Expand All @@ -1071,6 +1155,14 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
values["ALERTS_3"] = 0
values["SOUNDS_3"] = 0

# carrot: with HDP on, a gap change shows the stock "distance N" popup (ALERTS_3 7~10) for 2 s
gap_bars = hud_control.leadDistanceBars
if hdp_active and gap_bars != getattr(create_ccnc_messages, '_gap_bars', gap_bars):
create_ccnc_messages._gap_popup_until = frame + 200
create_ccnc_messages._gap_bars = gap_bars
if frame < getattr(create_ccnc_messages, '_gap_popup_until', 0) and values["ALERTS_3"] == 0 and 1 <= gap_bars <= 4:
values["ALERTS_3"] = 6 + gap_bars

if values["ALERTS_5"] in [1, 2, 3, 4, 5]:
values["ALERTS_5"] = 0

Expand All @@ -1085,6 +1177,10 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
values["LANELINE_CURVATURE_DIRECTION"] = 1 if curvature < 0 and lat_active else 0

trailer_lane_change_blocked = CS.trailer_connected
lane_probs = md.laneLineProbs if md is not None and len(md.laneLineProbs) >= 3 else None
unseen = create_ccnc_messages.__dict__.setdefault('_lane_unseen', {})
left_seen = hud_control.leftLaneVisible and not (lane_probs is not None and _lane_unseen(unseen, 'L', lane_probs[1], frame))
right_seen = hud_control.rightLaneVisible and not (lane_probs is not None and _lane_unseen(unseen, 'R', lane_probs[2], frame))
if trailer_lane_change_blocked:
values["LANELINE_LEFT"] = 2 if hud_control.leftLaneVisible else 0
values["LANELINE_RIGHT"] = 2 if hud_control.rightLaneVisible else 0
Expand All @@ -1098,7 +1194,7 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
if hud_control.leftLaneDepart:
values["LANELINE_LEFT"] = 4 if (frame // 50) % 2 == 0 else 1
else:
values["LANELINE_LEFT"] = lane_color if hud_control.leftLaneVisible else 0
values["LANELINE_LEFT"] = _dashed_lane_line(lane_color, CS.out.leftLaneLine) if left_seen or lane_color == 4 else LANE_LINE_UNSEEN # orange stays

lane_color = 6 if md is not None and md.meta.laneChangeAvailableRight else 2
if lane_line_check >= 1:
Expand All @@ -1109,22 +1205,26 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
if hud_control.rightLaneDepart:
values["LANELINE_RIGHT"] = 4 if (frame // 50) % 2 == 0 else 1
else:
values["LANELINE_RIGHT"] = lane_color if hud_control.rightLaneVisible else 0
values["LANELINE_RIGHT"] = _dashed_lane_line(lane_color, CS.out.rightLaneLine) if right_seen or lane_color == 4 else LANE_LINE_UNSEEN

values["LCA_LEFT_ARROW"] = 2 if CS.out.leftBlinker else 0
values["LCA_RIGHT_ARROW"] = 2 if CS.out.rightBlinker else 0

if trailer_lane_change_blocked:
values["LCA_LEFT_ICON"] = 1 if lat_active else 0
values["LCA_RIGHT_ICON"] = 1 if lat_active else 0
values["LCA_LEFT_ICON"] = 1 if lat_icon else 0
values["LCA_RIGHT_ICON"] = 1 if lat_icon else 0
else:
values["LCA_LEFT_ICON"] = (1 if CS.out.leftBlindspot else 2) if lat_active else 0
values["LCA_RIGHT_ICON"] = (1 if CS.out.rightBlindspot else 2) if lat_active else 0
values["LCA_LEFT_ICON"] = (1 if CS.out.leftBlindspot else 2) if lat_icon else 0
values["LCA_RIGHT_ICON"] = (1 if CS.out.rightBlindspot else 2) if lat_icon else 0

values["LANE_LEFT"] = 0 if trailer_lane_change_blocked else 1 if desire in (1, 3) else 0
values["LANE_RIGHT"] = 0 if trailer_lane_change_blocked else 1 if desire in (2, 4) else 0

_apply_driver_monitoring_alert(values, hud_control, CS.adrv_0x161)
if test_field in CLUSTER_TEST_FIELDS_161:
values[CLUSTER_TEST_FIELDS_161[test_field]] = test_value
if sweep_display is not None:
values["vSetDis"] = min(sweep_display, 255)
ret.append(packer.make_can_msg("ADRV_0x161", CAN.ECAN, values, rx_counter = rx_counter))

if CS.adrv_0x200 is not None:
Expand Down Expand Up @@ -1165,7 +1265,10 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control,
values["FAULT_LSS"] = 0
values["FAULT_DAS"] = 0

ret.append(packer.make_can_msg("CCNC_0x162", CAN.ECAN, values, rx_counter=rx_counter))
if test_field in CLUSTER_TEST_FIELDS:
values[CLUSTER_TEST_FIELDS[test_field]] = test_value
msg = packer.make_can_msg("CCNC_0x162", CAN.ECAN, values, rx_counter=rx_counter)
ret.append(_set_raw_bits(msg, CLUSTER_TEST_BITS[test_field], test_value) if test_field in CLUSTER_TEST_BITS else msg)

# --- NEW_MSG_4B9 (corner radar keep-alive?) ---
if enable_corner_radar > 0:
Expand Down
Loading