From eedd73e522b56286e070cf26eddab8a8eac65ca5 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Wed, 9 Sep 2026 15:32:38 -0500 Subject: [PATCH] iPhone FoldGate --- opendbc_repo/opendbc/can/dbc.py | 2 +- opendbc_repo/opendbc/car/gm/carcontroller.py | 4 +- opendbc_repo/opendbc/car/gm/carstate.py | 35 +- opendbc_repo/opendbc/car/gm/gmcan.py | 12 +- opendbc_repo/opendbc/car/gm/interface.py | 22 +- .../car/gm/tests/test_carcontroller.py | 9 + opendbc_repo/opendbc/car/gm/tests/test_gm.py | 145 +- opendbc_repo/opendbc/car/gm/values.py | 8 + .../opendbc/car/hyundai/carcontroller.py | 13 +- opendbc_repo/opendbc/car/hyundai/interface.py | 19 +- .../opendbc/car/hyundai/radar_interface.py | 36 +- .../opendbc/car/hyundai/tests/test_hyundai.py | 82 +- opendbc_repo/opendbc/car/hyundai/values.py | 2 + .../opendbc/car/subaru/carcontroller.py | 6 +- opendbc_repo/opendbc/car/subaru/carstate.py | 6 +- .../opendbc/car/subaru/tests/test_subaru.py | 30 +- opendbc_repo/opendbc/car/tests/routes.py | 1 + .../opendbc/car/torque_data/override.toml | 1 + .../opendbc/car/toyota/carcontroller.py | 29 +- opendbc_repo/opendbc/car/toyota/carstate.py | 8 - opendbc_repo/opendbc/car/toyota/interface.py | 4 +- .../opendbc/car/toyota/tests/test_toyota.py | 48 +- opendbc_repo/opendbc/car/toyota/toyotacan.py | 32 - .../opendbc/car/volvo/carcontroller.py | 64 +- opendbc_repo/opendbc/car/volvo/carstate.py | 95 +- .../opendbc/car/volvo/fingerprints.py | 8 + opendbc_repo/opendbc/car/volvo/interface.py | 17 +- .../car/volvo/tests/test_c1_carstate.py | 57 + .../car/volvo/tests/test_controller.py | 70 +- opendbc_repo/opendbc/car/volvo/values.py | 42 + opendbc_repo/opendbc/car/volvo/volvocan.py | 41 + .../hyundai/hyundai_radar_210_21f.dbc | 1221 ++++++++++++++++ .../dbc/hyundai_radar_210_21f_generated.dbc | 1224 +++++++++++++++++ opendbc_repo/opendbc/safety/__init__.py | 1 + opendbc_repo/opendbc/safety/declarations.h | 1 + opendbc_repo/opendbc/safety/modes/toyota.h | 29 +- opendbc_repo/opendbc/safety/modes/volvo.h | 119 +- .../opendbc/safety/tests/test_toyota.py | 40 +- .../opendbc/safety/tests/test_volvo.py | 141 +- selfdrive/controls/controlsd.py | 3 - selfdrive/controls/lib/latcontrol_torque.py | 3 + .../controls/lib/latcontrol_vehicle_tunes.py | 34 +- selfdrive/controls/radard.py | 79 +- selfdrive/controls/tests/test_latcontrol.py | 20 +- selfdrive/controls/tests/test_leads.py | 60 + .../ui/tests/test_device_screen_settings.py | 147 ++ selfdrive/ui/ui_state.py | 111 +- starpilot/car/ford/lateral.py | 61 +- starpilot/car/ford/tests/test_lateral.py | 120 +- starpilot/common/starpilot_variables.py | 8 +- .../components/tools/device_settings.js | 4 +- .../the_galaxy/assets/mobile/js/params.js | 7 +- .../assets/mobile/js/views/SystemTools.js | 33 + .../the_galaxy/tests/test_ui_vue_frontend.py | 12 + 54 files changed, 4210 insertions(+), 216 deletions(-) create mode 100644 opendbc_repo/opendbc/car/volvo/tests/test_c1_carstate.py create mode 100644 opendbc_repo/opendbc/dbc/generator/hyundai/hyundai_radar_210_21f.dbc create mode 100644 opendbc_repo/opendbc/dbc/hyundai_radar_210_21f_generated.dbc create mode 100644 selfdrive/ui/tests/test_device_screen_settings.py diff --git a/opendbc_repo/opendbc/can/dbc.py b/opendbc_repo/opendbc/can/dbc.py index a8da9c2470..5bc995059e 100644 --- a/opendbc_repo/opendbc/can/dbc.py +++ b/opendbc_repo/opendbc/can/dbc.py @@ -194,7 +194,7 @@ def get_checksum_state(dbc_name: str) -> ChecksumState | None: return ChecksumState(4, 2, 3, 5, False, SignalType.HONDA_CHECKSUM, honda_checksum) elif dbc_name.startswith(("toyota_", "lexus_")): return ChecksumState(8, -1, 7, -1, False, SignalType.TOYOTA_CHECKSUM, toyota_checksum) - elif dbc_name.startswith("hyundai_canfd_generated"): + elif dbc_name.startswith(("hyundai_canfd_generated", "hyundai_radar_210_21f_generated")): return ChecksumState(16, -1, 0, -1, True, SignalType.HKG_CAN_FD_CHECKSUM, hkg_can_fd_checksum) elif dbc_name.startswith(("vw_mqb", "vw_mqbevo", "vw_meb")): return ChecksumState(8, 4, 0, 0, True, SignalType.VOLKSWAGEN_MQB_MEB_CHECKSUM, volkswagen_mqb_meb_checksum) diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index ca7da73bda..07a6131f7f 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -6,7 +6,7 @@ from opendbc.car.lateral import apply_driver_steer_torque_limits from opendbc.car.gm import gmcan from opendbc.car.common.conversions import Conversions as CV from opendbc.car.gm.values import ( - ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, SDGM_CAR, AccState, CanBus, CarControllerParams, + ASCM_INT, CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, DBC, EV_CAR, GM_AUTO_HOLD_CARS, SDGM_CAR, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, GMSafetyFlags, ) from opendbc.car.interfaces import CarControllerBase @@ -309,7 +309,7 @@ def supports_volt_auto_hold(CP, auto_hold_enabled: bool): auto_hold_enabled and getattr(CP, "openpilotLongitudinalControl", False) and stock_hold_safety_ready and - CP.carFingerprint in AUTO_HOLD_VOLT_CARS + CP.carFingerprint in GM_AUTO_HOLD_CARS ) diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index 9e0f3c1220..81145c7e72 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -32,6 +32,7 @@ STANDSTILL_THRESHOLD = 10 * 0.0311 VOLT_EBCM_BRAKE_PRESSED_THRESHOLD = 6 / 0xd0 AUTO_HOLD_MIN_DRIVE_TIME_S = 3.0 AUTO_HOLD_REGEN_RELEASE_COOLDOWN_S = 1.0 +ACC_STARTUP_FAULT_GRACE_PERIOD_S = 5.0 BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, CruiseButtons.MAIN: ButtonType.mainCruise, CruiseButtons.CANCEL: ButtonType.cancel} @@ -67,6 +68,24 @@ def update_auto_hold_drive_timers(in_drive_for_hold: bool, moving_for_hold: bool return auto_hold_drive_time, one_pedal_drive_time +def update_startup_acc_fault_suppression(car_fingerprint: str, system_power_mode: int, + previous_system_power_mode: int, timer: float, + acc_state: int, friction_brake_unavailable: bool) -> tuple[float, bool]: + if car_fingerprint != CAR.BUICK_LACROSSE: + return 0.0, False + + if system_power_mode == 2 and previous_system_power_mode != 2: + timer = ACC_STARTUP_FAULT_GRACE_PERIOD_S + elif system_power_mode != 2: + timer = 0.0 + + if timer <= 0.0 or acc_state != AccState.FAULTED: + return 0.0, False + + timer = max(timer - DT_CTRL, 0.0) + return timer, timer > 0.0 and not friction_brake_unavailable + + class CarState(CarStateBase): def __init__(self, CP, FPCP): super().__init__(CP, FPCP) @@ -105,6 +124,8 @@ class CarState(CarStateBase): self.lkas_previously_enabled = 0 self.lkas_enabled = 0 self.pcm_acc_status = AccState.OFF + self.system_power_mode = 0 + self.startup_acc_fault_suppression_timer = 0.0 self.stock_fcw_alert = 0 self.car_gps_config = get_car_gps_config(CP) self.car_gps_supported = self.car_gps_config is not None @@ -350,8 +371,18 @@ class CarState(CarStateBase): ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0 ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1 - ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or - pt_cp.vl["EBCMFrictionBrakeStatus"]["FrictionBrakeUnavailable"] == 1) + acc_state = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] + friction_brake_unavailable = pt_cp.vl["EBCMFrictionBrakeStatus"]["FrictionBrakeUnavailable"] == 1 + self.startup_acc_fault_suppression_timer, suppress_startup_acc_fault = update_startup_acc_fault_suppression( + self.CP.carFingerprint, + int(pt_cp.vl["BCMGeneralPlatformStatus"]["SystemPowerMode"]), + self.system_power_mode, + self.startup_acc_fault_suppression_timer, + acc_state, + friction_brake_unavailable, + ) + self.system_power_mode = int(pt_cp.vl["BCMGeneralPlatformStatus"]["SystemPowerMode"]) + ret.accFaulted = (acc_state == AccState.FAULTED and not suppress_startup_acc_fault) or friction_brake_unavailable ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL diff --git a/opendbc_repo/opendbc/car/gm/gmcan.py b/opendbc_repo/opendbc/car/gm/gmcan.py index 6a13e83b3d..fc063c95d3 100644 --- a/opendbc_repo/opendbc/car/gm/gmcan.py +++ b/opendbc_repo/opendbc/car/gm/gmcan.py @@ -31,6 +31,8 @@ BOLT_CC_DIRECTION_MEMORY_S = 1.5 VOLT_CC_CARS = { CAR.CHEVROLET_VOLT_CC, } +VOLT_CC_TARGET_DEADBAND_MPH = 5.0 +VOLT_CC_ACCEL_DEADBAND_MS2 = 0.15 def malibu_phase_map_for_button(button): @@ -344,7 +346,15 @@ def _create_volt_cc_spam_command(CS, actuators, ms_convert): speed_setpoint = int(round(CS.out.cruiseState.speed * ms_convert)) ego_speed = CS.out.vEgo * ms_convert - if accel == 0.0: + v_cruise_kph = float(getattr(CS.out, "vCruise", 0.0)) + if 0.0 < v_cruise_kph < 255.0: + is_metric = ms_convert == CV.MS_TO_KPH + target_setpoint = v_cruise_kph if is_metric else v_cruise_kph * CV.KPH_TO_MPH + target_deadband = VOLT_CC_TARGET_DEADBAND_MPH * (CV.MPH_TO_KPH if is_metric else 1.0) + if abs(target_setpoint - speed_setpoint) <= target_deadband: + return CruiseButtons.INIT, float("inf") + + if abs(accel) <= VOLT_CC_ACCEL_DEADBAND_MS2: return CruiseButtons.INIT, float("inf") if accel < 0.0: diff --git a/opendbc_repo/opendbc/car/gm/interface.py b/opendbc_repo/opendbc/car/gm/interface.py index 10329962c5..235dedd689 100755 --- a/opendbc_repo/opendbc/car/gm/interface.py +++ b/opendbc_repo/opendbc/car/gm/interface.py @@ -15,6 +15,7 @@ from opendbc.car.gm.values import ( CC_ONLY_CAR, CC_REGEN_PADDLE_CAR, EV_CAR, + GM_AUTO_HOLD_CARS, SDGM_CAR, CarControllerParams, CanBus, @@ -710,18 +711,19 @@ class CarInterface(CarInterfaceBase): if remote_start_boots_comma: ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_REMOTE_START_BOOTS_COMMA.value - volt_stock_friction_brake_safety = ( + gm_stock_friction_brake_safety = ( ret.openpilotLongitudinalControl and - (gm_auto_hold or volt_one_pedal_mode) and - candidate in { - CAR.CHEVROLET_VOLT, - CAR.CHEVROLET_VOLT_2019, - CAR.CHEVROLET_VOLT_ASCM, - CAR.CHEVROLET_VOLT_CAMERA, - } + ( + (gm_auto_hold and candidate in GM_AUTO_HOLD_CARS) or + (volt_one_pedal_mode and candidate in { + CAR.CHEVROLET_VOLT, + CAR.CHEVROLET_VOLT_2019, + CAR.CHEVROLET_VOLT_ASCM, + CAR.CHEVROLET_VOLT_CAMERA, + }) + ) ) - if volt_stock_friction_brake_safety: - # Reuse the paddle-scheduler safety bit as a Volt stock friction-brake + if gm_stock_friction_brake_safety: # marker on non-pedal paths. Auto hold and one-pedal can run while OP # longitudinal is configured but not currently active, so the bit must # be present regardless of the current long-control mode. Do not expose diff --git a/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py b/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py index 4b91ebb923..7d1327a2cb 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_carcontroller.py @@ -431,6 +431,15 @@ def test_volt_auto_hold_requires_toggle_supported_non_cc_only_volt_and_stock_saf ), True, ) + assert supports_volt_auto_hold( + SimpleNamespace( + carFingerprint=CAR.BUICK_LACROSSE, + openpilotLongitudinalControl=True, + networkLocation=CarParams.NetworkLocation.gateway, + safetyConfigs=stock_safety, + ), + True, + ) assert not supports_volt_auto_hold( SimpleNamespace( carFingerprint=CAR.CHEVROLET_VOLT, diff --git a/opendbc_repo/opendbc/car/gm/tests/test_gm.py b/opendbc_repo/opendbc/car/gm/tests/test_gm.py index a7e24c5354..db4c52c134 100644 --- a/opendbc_repo/opendbc/car/gm/tests/test_gm.py +++ b/opendbc_repo/opendbc/car/gm/tests/test_gm.py @@ -8,7 +8,12 @@ from opendbc.can import CANPacker, CANParser from opendbc.car import Bus, DT_CTRL, structs from opendbc.car.car_helpers import interfaces from opendbc.car.gm import gmcan -from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_buttons, update_auto_hold_drive_timers +from opendbc.car.gm.carstate import ( + CarState as GMCarState, + get_hard_cruise_buttons, + update_auto_hold_drive_timers, + update_startup_acc_fault_suppression, +) from opendbc.car.gm.carcontroller import ( VisualAlert, get_acc_dashboard_always_one, @@ -204,6 +209,50 @@ class TestBoltGps: assert all(message in parsers[Bus.pt].vl for message in CHEVROLET_BOLT_GPS_MESSAGES) +class TestGMCarState: + def test_lacrosse_startup_acc_fault_is_suppressed(self): + timer, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_LACROSSE, 2, 0, 0.0, 3, False, + ) + + assert suppressed + assert timer == pytest.approx(5.0 - DT_CTRL) + + timer, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_LACROSSE, 2, 2, timer, 0, False, + ) + + assert timer == 0.0 + assert not suppressed + + def test_lacrosse_persistent_acc_fault_is_reported_after_startup(self): + timer, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_LACROSSE, 2, 0, 0.0, 3, False, + ) + + for _ in range(int(5.0 / DT_CTRL)): + timer, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_LACROSSE, 2, 2, timer, 3, False, + ) + + assert timer == 0.0 + assert not suppressed + + def test_lacrosse_brake_unavailable_fault_is_never_suppressed(self): + _, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_LACROSSE, 2, 0, 0.0, 3, True, + ) + + assert not suppressed + + def test_startup_acc_fault_suppression_is_scoped_to_lacrosse(self): + _, suppressed = update_startup_acc_fault_suppression( + CAR.BUICK_REGAL, 2, 0, 0.0, 3, False, + ) + + assert not suppressed + + class TestGMInterface: def test_lacrosse_obd_and_ascm_integrations_remain_separate(self): obd_params = interfaces[CAR.BUICK_LACROSSE].get_params( @@ -521,6 +570,43 @@ class TestGMInterface: assert car_params.openpilotLongitudinalControl assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value + def test_buick_lacrosse_auto_hold_sets_stock_hold_safety_bit_with_op_long_enabled(self): + params = Params() + try: + params.put_bool("GMAutoHold", True) + car_params = interfaces[CAR.BUICK_LACROSSE].get_params( + CAR.BUICK_LACROSSE, + _empty_fingerprint(), + [], + alpha_long=False, + is_release=False, + docs=False, + starpilot_toggles=_test_starpilot_toggles(), + ) + finally: + params.remove("GMAutoHold") + + assert car_params.openpilotLongitudinalControl + assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value + + def test_buick_lacrosse_auto_hold_is_off_when_toggle_is_disabled(self): + params = Params() + try: + params.put_bool("GMAutoHold", False) + car_params = interfaces[CAR.BUICK_LACROSSE].get_params( + CAR.BUICK_LACROSSE, + _empty_fingerprint(), + [], + alpha_long=False, + is_release=False, + docs=False, + starpilot_toggles=_test_starpilot_toggles(), + ) + finally: + params.remove("GMAutoHold") + + assert not car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value + def test_volt_auto_hold_does_not_set_stock_hold_safety_bit_with_op_long_disabled(self): CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM] fingerprint = _empty_fingerprint() @@ -847,6 +933,63 @@ class TestGMCarController: assert len(msgs) == 1 + def test_volt_cc_redneck_holds_when_stock_setpoint_is_within_target_deadband(self): + packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_CC][Bus.pt]) + controller = SimpleNamespace(frame=int(2.0 / DT_CTRL), last_button_frame=0, apply_speed=0, malibu_button_phase=0) + cs = SimpleNamespace( + CP=SimpleNamespace( + carFingerprint=CAR.CHEVROLET_VOLT_CC, + flags=GMFlags.NO_CAMERA.value, + networkLocation=structs.CarParams.NetworkLocation.gateway, + minEnableSpeed=0.0, + ), + buttons_counter=2, + out=SimpleNamespace( + vEgo=100.0 * CV.KPH_TO_MS, + cruiseState=SimpleNamespace(speed=99.0 * CV.KPH_TO_MS), + vCruise=100.0, + ), + ) + + msgs = gmcan.create_gm_cc_spam_command( + packer, controller, cs, SimpleNamespace(accel=0.5), SimpleNamespace(is_metric=True), + ) + + assert msgs == [] + assert controller.apply_speed == 99 + + def test_volt_cc_redneck_catches_up_when_target_exceeds_deadband(self): + packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_CC][Bus.pt]) + controller = SimpleNamespace(frame=int(0.5 / DT_CTRL), last_button_frame=0, apply_speed=0, malibu_button_phase=0) + cs = SimpleNamespace( + CP=SimpleNamespace( + carFingerprint=CAR.CHEVROLET_VOLT_CC, + flags=GMFlags.NO_CAMERA.value, + networkLocation=structs.CarParams.NetworkLocation.gateway, + minEnableSpeed=0.0, + ), + buttons_counter=2, + out=SimpleNamespace( + vEgo=90.0 * CV.KPH_TO_MS, + cruiseState=SimpleNamespace(speed=90.0 * CV.KPH_TO_MS), + vCruise=100.0, + ), + ) + + msgs = gmcan.create_gm_cc_spam_command( + packer, controller, cs, SimpleNamespace(accel=0.5), SimpleNamespace(is_metric=True), + ) + + assert msgs == [] + + controller.frame = int(0.7 / DT_CTRL) + msgs = gmcan.create_gm_cc_spam_command( + packer, controller, cs, SimpleNamespace(accel=0.5), SimpleNamespace(is_metric=True), + ) + + assert len(msgs) == 1 + assert controller.apply_speed == 91 + def test_volt_cc_no_camera_redneck_spam_stays_on_powertrain_bus(self): packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_CC][Bus.pt]) controller = SimpleNamespace(frame=int(0.3 / DT_CTRL), last_button_frame=0, apply_speed=0, malibu_button_phase=0) diff --git a/opendbc_repo/opendbc/car/gm/values.py b/opendbc_repo/opendbc/car/gm/values.py index 05cd280ff8..6f2abb911a 100644 --- a/opendbc_repo/opendbc/car/gm/values.py +++ b/opendbc_repo/opendbc/car/gm/values.py @@ -533,6 +533,14 @@ EV_CAR = { CAR.CHEVROLET_MALIBU_HYBRID_CC, } +GM_AUTO_HOLD_CARS = { + CAR.CHEVROLET_VOLT, + CAR.CHEVROLET_VOLT_2019, + CAR.CHEVROLET_VOLT_ASCM, + CAR.CHEVROLET_VOLT_CAMERA, + CAR.BUICK_LACROSSE, +} + # We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) CAMERA_ACC_CAR = { CAR.CHEVROLET_BOLT_ACC_2022_2023, diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 4e22629680..44cdbd5590 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -11,7 +11,7 @@ from opendbc.car.common.conversions import Conversions as CV from opendbc.car.hyundai import hyundaicanfd, hyundaican from opendbc.car.hyundai.hyundaicanfd import CanBus from opendbc.car.hyundai.values import HyundaiFlags, HyundaiSafetyFlags, HyundaiStarPilotFlags, Buttons, CarControllerParams, CAR, CANFD_ANGLE_LONGITUDINAL_CAR, \ - CANFD_RADAR_LIVE_LONGITUDINAL_CAR, CANFD_ALT_BUTTONS_RESUME_CAR, kia_ev6_gt_line_longitudinal_tuning, \ + CANFD_RADAR_ECU_KEEPALIVE_CAR, CANFD_ALT_BUTTONS_RESUME_CAR, kia_ev6_gt_line_longitudinal_tuning, \ KIA_EV6_GT_LINE_LONG_TUNING_TESTING_GROUND_ID from opendbc.car.interfaces import CarControllerBase from opendbc.car.vehicle_model import VehicleModel @@ -860,7 +860,11 @@ class CarController(CarControllerBase): lka_steering = self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING longitudinal_active = bool(self.long_active_ecu and getattr(CC, "longActive", False)) - lfa_status_cars = (CAR.HYUNDAI_IONIQ_6, CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN) + lfa_status_cars = ( + CAR.HYUNDAI_IONIQ_6, + CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN, + CAR.KIA_EV6, + ) lfa_longitudinal_active = self.CP.openpilotLongitudinalControl \ if self.CP.carFingerprint in lfa_status_cars else longitudinal_active lka_steering_long = lka_steering and lfa_longitudinal_active @@ -892,8 +896,7 @@ class CarController(CarControllerBase): if angle_lkas_alt: steering_msg_active = bool(steering_msg_active and drive_gear) angle_lkas_alt_standstill_handoff = bool(getattr(CS.out, "standstill", False) and not CC.latActive) - forward_stock_lkas = (self.CP.carFingerprint in CANFD_ANGLE_LONGITUDINAL_CAR or - self.CP.carFingerprint == CAR.KIA_SPORTAGE_HEV_2026) and angle_lkas_alt and ( + forward_stock_lkas = self.CP.carFingerprint in CANFD_ANGLE_LONGITUDINAL_CAR and angle_lkas_alt and ( angle_lkas_alt_standstill_handoff or not (drive_gear and (CC.latActive or CC.enabled)) ) preserve_stock_lfa_status = preserve_stock_canfd_lfa_status(self.CP.carFingerprint) @@ -995,7 +998,7 @@ class CarController(CarControllerBase): # The front radar treats ADAS_DRV's 0x100 broadcast as its host heartbeat # and stops publishing object tracks when it disappears. radar_heartbeat_step = 1 if ccnc_angle_long else 4 - if self.CP.carFingerprint in CANFD_RADAR_LIVE_LONGITUDINAL_CAR and self.frame % radar_heartbeat_step == 0: + if self.CP.carFingerprint in CANFD_RADAR_ECU_KEEPALIVE_CAR and self.frame % radar_heartbeat_step == 0: can_sends.append(hyundaicanfd.create_accelerator_brake_alt_spoof(0, self.frame // radar_heartbeat_step, CS.out.brakePressed, CS.out.gasPressed, self.CP.carFingerprint)) diff --git a/opendbc_repo/opendbc/car/hyundai/interface.py b/opendbc_repo/opendbc/car/hyundai/interface.py index 9b9d4e7290..4e8a13b40b 100644 --- a/opendbc_repo/opendbc/car/hyundai/interface.py +++ b/opendbc_repo/opendbc/car/hyundai/interface.py @@ -8,6 +8,7 @@ from opendbc.car.hyundai.values import HyundaiFlags, CAR, CarControllerParams, \ CANFD_SECURITYACCESS_CAR, \ CANFD_ANGLE_LONGITUDINAL_CAR, \ CANFD_RADAR_LIVE_LONGITUDINAL_CAR, \ + CANFD_RADAR_ECU_KEEPALIVE_CAR, \ RADAR_LIVE_LONGITUDINAL_CAR, \ UNSUPPORTED_LONGITUDINAL_CAR, HyundaiSafetyFlags, \ LEGACY_LONGITUDINAL_CAR, \ @@ -27,6 +28,15 @@ from openpilot.starpilot.common.testing_grounds import testing_ground ButtonType = structs.CarState.ButtonEvent.Type Ecu = structs.CarParams.Ecu + +def get_communication_control_request(car_fingerprint): + if car_fingerprint in CANFD_RADAR_ECU_KEEPALIVE_CAR: + return bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, uds.CONTROL_TYPE.ENABLE_RX_DISABLE_TX, + uds.MESSAGE_TYPE.NORMAL]) + + return bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, 0x80 | uds.CONTROL_TYPE.DISABLE_RX_DISABLE_TX, + uds.MESSAGE_TYPE.NORMAL]) + # Cancel button can sometimes be ACC pause/resume button, main button can also enable on some cars ENABLE_BUTTONS = (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.cancel, ButtonType.mainCruise) @@ -353,14 +363,7 @@ class CarInterface(CarInterfaceBase): params = Params() if communication_control is None: - if CP.carFingerprint in CANFD_RADAR_LIVE_LONGITUDINAL_CAR: - # Don't use 0x80 suppress bit so we can read the ECU response. - # Use ENABLE_RX_DISABLE_TX (0x01) so the ECU can still receive from rear radars for BSM - # while blocking SCC TX. - communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, uds.CONTROL_TYPE.ENABLE_RX_DISABLE_TX, uds.MESSAGE_TYPE.NORMAL]) - else: - # 0x80 silences response for other cars (original behavior) - communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, 0x80 | uds.CONTROL_TYPE.DISABLE_RX_DISABLE_TX, uds.MESSAGE_TYPE.NORMAL]) + communication_control = get_communication_control_request(CP.carFingerprint) ecu_log(f"=== init() called: opLong={CP.openpilotLongitudinalControl}, flags=0x{CP.flags:x}, safetyParam={CP.safetyConfigs[-1].safetyParam} ===") diff --git a/opendbc_repo/opendbc/car/hyundai/radar_interface.py b/opendbc_repo/opendbc/car/hyundai/radar_interface.py index 9649b085e2..43526b0f05 100644 --- a/opendbc_repo/opendbc/car/hyundai/radar_interface.py +++ b/opendbc_repo/opendbc/car/hyundai/radar_interface.py @@ -19,6 +19,9 @@ MRR30_RADAR_START_ADDR = 0x210 MRR30_RADAR_MSG_COUNT = 16 MRR35_RADAR_START_ADDR = 0x3A5 MRR35_RADAR_MSG_COUNT = 32 +GV70_RADAR_START_ADDR = 0x210 +GV70_RADAR_MSG_COUNT = 16 +GV70_RADAR_DBC = "hyundai_radar_210_21f_generated" @dataclass(frozen=True) @@ -30,6 +33,7 @@ class RadarTrackConfig: frequency: int = 50 parser_msg_count: int | None = None expected_length: int | None = None + dbc_name: str | None = None @property def can_parser_msg_count(self) -> int: @@ -47,6 +51,10 @@ RADAR_TRACK_CONFIGS = { def get_radar_track_config(car_fingerprint, flags: int = 0) -> RadarTrackConfig | None: + if car_fingerprint == CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN: + return RadarTrackConfig(GV70_RADAR_START_ADDR, GV70_RADAR_MSG_COUNT, "gv70_210", bus=0, + frequency=20, expected_length=32, dbc_name=GV70_RADAR_DBC) + radar_dbc = DBC[car_fingerprint].get(Bus.radar) if car_fingerprint == CAR.GENESIS_G90 and radar_dbc == HYUNDAI_MANDO_FRONT_RADAR_DBC: return RadarTrackConfig(RADAR_START_ADDR, G90_RADAR_MSG_COUNT, "mando", parser_msg_count=RADAR_MSG_COUNT) @@ -65,6 +73,10 @@ def radar_tracks_available(radar_config: RadarTrackConfig | None, fingerprint) - if radar_config is None: return False + if radar_config.radar_type == "gv70_210": + return all(fingerprint[radar_config.bus].get(addr) == radar_config.expected_length + for addr in range(radar_config.start_addr, radar_config.start_addr + radar_config.msg_count)) + msg_len = fingerprint[radar_config.bus].get(radar_config.start_addr) if msg_len is None: return False @@ -78,7 +90,8 @@ def get_radar_can_parser(CP, radar_config): messages = [(f"RADAR_TRACK_{addr:x}", radar_config.frequency) for addr in range(radar_config.start_addr, radar_config.start_addr + radar_config.can_parser_msg_count)] - return CANParser(DBC[CP.carFingerprint][Bus.radar], messages, radar_config.bus) + dbc_name = radar_config.dbc_name or DBC[CP.carFingerprint][Bus.radar] + return CANParser(dbc_name, messages, radar_config.bus) class RadarInterface(RadarInterfaceBase): @@ -223,6 +236,27 @@ class RadarInterface(RadarInterfaceBase): del self.pts[track_key] continue + if radar_type == "gv70_210": + for i in ("1", "2"): + track_key = addr * 2 + int(i) - 1 + valid = msg[f"{i}_STATE"] in (3, 4) + if valid: + pt = self.pts.get(track_key) + if pt is None: + pt = structs.RadarData.RadarPoint() + pt.trackId = self.track_id + self.track_id += 1 + self.pts[track_key] = pt + pt.measured = True + pt.dRel = msg[f"{i}_LONG_DIST"] + pt.yRel = msg[f"{i}_LAT_DIST"] + pt.vRel = msg[f"{i}_REL_SPEED"] + pt.aRel = msg[f"{i}_REL_ACCEL"] + pt.yvRel = msg[f"{i}_REL_LAT_SPEED"] + elif track_key in self.pts: + del self.pts[track_key] + continue + if radar_type == "mrrevo14f": for i in ("1", "2"): track_key = addr * 2 + int(i) - 1 diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index e3a571adfe..ad3d320ff4 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -24,16 +24,17 @@ from opendbc.car.hyundai.carcontroller import CarController, CANCEL_BUTTON_DELAY clear_ioniq_6_torque_when_request_inactive from opendbc.car.hyundai.carstate import CarState, decode_canfd_camera_lead, decode_ioniq_6_blindspot_radar_state, \ get_canfd_cruise_available -from opendbc.car.hyundai.interface import CarInterface, KIA_EV9_ACCEL_MAX +from opendbc.car.hyundai.interface import CarInterface, KIA_EV9_ACCEL_MAX, get_communication_control_request from opendbc.car.hyundai import hyundaican, hyundaicanfd from opendbc.car.hyundai.hyundaicanfd import CanBus, hkg_can_fd_checksum from opendbc.car.hyundai.radar_interface import MRREVO14F_RADAR_START_ADDR, MRR30_RADAR_START_ADDR, MRR35_RADAR_START_ADDR, \ - RADAR_START_ADDR, get_radar_track_config + RADAR_START_ADDR, RadarInterface, get_radar_track_config, radar_tracks_available from opendbc.car.hyundai.values import CAMERA_SCC_CAR, CANFD_CAR, CAN_GEARS, CAR, CHECKSUM, DATE_FW_ECUS, DATELESS_FUZZY_CARS, \ HYBRID_CAR, EV_CAR, FW_QUERY_CONFIG, LEGACY_SAFETY_MODE_CAR, CANFD_FUZZY_WHITELIST, \ UNSUPPORTED_LONGITUDINAL_CAR, PLATFORM_CODE_ECUS, HYUNDAI_VERSION_REQUEST_LONG, \ LEGACY_LONGITUDINAL_CAR, DBC, HyundaiFlags, get_platform_codes, HyundaiSafetyFlags, \ - HyundaiStarPilotFlags, HyundaiStarPilotSafetyFlags, Buttons, CarControllerParams, kia_ev6_gt_line_longitudinal_tuning + HyundaiStarPilotFlags, HyundaiStarPilotSafetyFlags, Buttons, CarControllerParams, \ + CANFD_RADAR_ECU_KEEPALIVE_CAR, CANFD_RADAR_LIVE_LONGITUDINAL_CAR, kia_ev6_gt_line_longitudinal_tuning LongCtrlState = CarControl.Actuators.LongControlState from opendbc.car.hyundai.fingerprints import FW_VERSIONS @@ -129,6 +130,15 @@ def get_test_toggles() -> SimpleNamespace: class TestHyundaiFingerprint: + def test_ev6_uses_stock_hda2_communication_control_path(self): + stock_request = bytes([0x28, 0x83, 0x01]) + radar_keepalive_request = bytes([0x28, 0x01, 0x01]) + + assert CAR.KIA_EV6 in CANFD_RADAR_LIVE_LONGITUDINAL_CAR + assert CAR.KIA_EV6 not in CANFD_RADAR_ECU_KEEPALIVE_CAR + assert get_communication_control_request(CAR.KIA_EV6) == stock_request + assert get_communication_control_request(CAR.HYUNDAI_IONIQ_6) == radar_keepalive_request + def test_carnival_hev_low_speed_torque_rate_limits(self): CP = CarInterface.get_params(CAR.KIA_CARNIVAL_HEV_4TH_GEN, gen_empty_fingerprint(), [], False, False, False, None) @@ -426,6 +436,42 @@ class TestHyundaiFingerprint: assert CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.CANFD_LKA_STEERING assert CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.EV_GAS + gv70_radar_config = get_radar_track_config(CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN) + assert gv70_radar_config.radar_type == "gv70_210" + for addr in range(gv70_radar_config.start_addr, gv70_radar_config.start_addr + gv70_radar_config.msg_count): + gv70_fingerprint[gv70_radar_config.bus][addr] = gv70_radar_config.expected_length + assert radar_tracks_available(gv70_radar_config, gv70_fingerprint) + + CP = CarInterface.get_params(CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN, gv70_fingerprint, gv70_car_fw, + True, False, False, None) + assert not CP.radarUnavailable + + radar = RadarInterface(CP) + packer = CANPacker(gv70_radar_config.dbc_name) + messages = [] + for addr in range(gv70_radar_config.start_addr, gv70_radar_config.start_addr + gv70_radar_config.msg_count): + message = packer.make_can_msg(f"RADAR_TRACK_{addr:x}", 0, { + "1_STATE": 3, + "1_LONG_DIST": 25.0, + "1_LAT_DIST": 0.5, + "1_REL_SPEED": -2.0, + "1_REL_LAT_SPEED": 0.1, + "1_REL_ACCEL": -0.2, + }) + data = bytearray(message[1]) + checksum = hkg_can_fd_checksum(addr, None, data) + data[0] = checksum & 0xff + data[1] = (checksum >> 8) & 0xff + messages.append((message[0], bytes(data), message[2])) + radar_data = radar.update([(1, messages)]) + assert radar_data is not None + assert len(radar_data.points) == 16 + assert radar_data.points[0].dRel == pytest.approx(25.0) + + other_config = get_radar_track_config(CAR.HYUNDAI_IONIQ_5) + assert other_config.radar_type == "mrr30" + assert other_config.dbc_name is None + for candidate in HYUNDAI_NON_SCC_CARS: CP = CarInterface.get_params(candidate, gen_empty_fingerprint(), [], True, False, False, None) assert bool(CP.flags & HyundaiFlags.NON_SCC) @@ -2552,15 +2598,14 @@ class TestHyundaiFingerprint: if controller.packer.dbc.addr_to_msg[addr].name in ("LFA", "LKAS")] assert steering_names == [("LFA", can_bus.ECAN), ("LKAS", can_bus.ACAN)] - def test_ioniq_6_keeps_lfa_status_when_longitudinal_is_inactive(self): + @pytest.mark.parametrize("car", [CAR.HYUNDAI_IONIQ_6, CAR.KIA_EV6]) + def test_egmp_keeps_lfa_status_when_longitudinal_is_inactive(self, car): CP = CarParams.new_message() - CP.carFingerprint = CAR.HYUNDAI_IONIQ_6 + CP.carFingerprint = car CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.EV | HyundaiFlags.CANFD_LKA_STEERING) CP.openpilotLongitudinalControl = True controller = CarController(DBC[CP.carFingerprint], CP) - controller.frame = 1 - controller.long_active_ecu = False cc = SimpleNamespace( enabled=False, latActive=False, longActive=False, actuators=SimpleNamespace(longControlState=LongCtrlState.off), @@ -2568,12 +2613,15 @@ class TestHyundaiFingerprint: ) cs = SimpleNamespace( stock_lfa_msg=None, stock_lkas_msg=None, + left_blindspot_from_radar=False, right_blindspot_from_radar=False, out=SimpleNamespace(gearShifter=structs.CarState.GearShifter.park), ) - msgs = controller.create_canfd_msgs(0, False, 0.0, 0.0, 0.0, 0.0, False, - cc.hudControl, cs, cc, get_test_toggles(), lka_icon=1, lfa_icon=1) - assert any(addr == 0x12A for addr, _, _ in msgs) + controller.frame = 1 + for controller.long_active_ecu in (False, True): + msgs = controller.create_canfd_msgs(0, False, 0.0, 0.0, 0.0, 0.0, False, + cc.hudControl, cs, cc, get_test_toggles(), lka_icon=1, lfa_icon=1) + assert any(addr == 0x12A for addr, _, _ in msgs) def test_gv70_electrified_longitudinal_uses_hda2_scc_contract(self): CP = CarParams.new_message() @@ -2707,7 +2755,7 @@ class TestHyundaiFingerprint: assert len([msg for msg in msgs if msg[0] == 0x110]) == expected_lkas_msgs @pytest.mark.parametrize("standstill", [False, True]) - def test_sportage_angle_lkas_alt_forwards_stock_status_when_inactive(self, standstill): + def test_sportage_angle_lkas_alt_publishes_inactive_status(self, standstill): CP = CarParams.new_message() CP.carFingerprint = CAR.KIA_SPORTAGE_HEV_2026 CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.HYBRID | HyundaiFlags.CANFD_ANGLE_STEERING | @@ -2715,6 +2763,7 @@ class TestHyundaiFingerprint: CP.openpilotLongitudinalControl = False controller = CarController(DBC[CP.carFingerprint], CP) + can_bus = CanBus(CP) cc = SimpleNamespace(enabled=False, latActive=False, actuators=SimpleNamespace(longControlState=LongCtrlState.off), leftBlinker=False, rightBlinker=False, hudControl=SimpleNamespace()) @@ -2724,7 +2773,16 @@ class TestHyundaiFingerprint: msgs = controller.create_canfd_msgs(0, False, 0.0, 0.0, 0.0, 0.0, False, cc.hudControl, cs, cc, get_test_toggles(), lka_icon=1, lfa_icon=1) - assert not [msg for msg in msgs if msg[0] in (0x110, 0x12A)] + lkas_msgs = [msg for msg in msgs if msg[0] == 0x110] + assert len(lkas_msgs) == 1 + + parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("LKAS_ALT", 0)], can_bus.ACAN) + parser.update([(1, lkas_msgs)]) + assert parser.can_valid + assert parser.vl["LKAS_ALT"]["LKA_ICON"] == 1 + assert parser.vl["LKAS_ALT"]["LKA_SysIndReq"] == 1 + assert parser.vl["LKAS_ALT"]["LKA_RcgSta"] == 0 + assert parser.vl["LKAS_ALT"]["LKAS_ANGLE_ACTIVE"] == 1 def test_ev9_inactive_angle_steering_does_not_suppress_stock_lfa(self): CP = CarParams.new_message() diff --git a/opendbc_repo/opendbc/car/hyundai/values.py b/opendbc_repo/opendbc/car/hyundai/values.py index 0c74a6c041..b85531477f 100644 --- a/opendbc_repo/opendbc/car/hyundai/values.py +++ b/opendbc_repo/opendbc/car/hyundai/values.py @@ -1218,7 +1218,9 @@ CANFD_ALT_BUTTONS_RESUME_CAR = {CAR.KIA_CARNIVAL_2025, CAR.KIA_CARNIVAL_HEV_4TH_ CANFD_CORNER_RADAR_BSM_CAR = {CAR.HYUNDAI_IONIQ_6, CAR.HYUNDAI_IONIQ_5_PE, CAR.KIA_EV9} CANFD_RADAR_LIVE_LONGITUDINAL_CAR = { CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_5_PE, CAR.HYUNDAI_IONIQ_6, CAR.KIA_EV6, CAR.KIA_EV9, CAR.GENESIS_GV60_EV_1ST_GEN, + CAR.GENESIS_GV70_ELECTRIFIED_1ST_GEN, } +CANFD_RADAR_ECU_KEEPALIVE_CAR = CANFD_RADAR_LIVE_LONGITUDINAL_CAR - {CAR.KIA_EV6} RADAR_LIVE_LONGITUDINAL_CAR = CANFD_RADAR_LIVE_LONGITUDINAL_CAR | { CAR.HYUNDAI_IONIQ, CAR.HYUNDAI_KONA_EV_2022, diff --git a/opendbc_repo/opendbc/car/subaru/carcontroller.py b/opendbc_repo/opendbc/car/subaru/carcontroller.py index 3a5f8aa047..6e3edbc5b5 100644 --- a/opendbc_repo/opendbc/car/subaru/carcontroller.py +++ b/opendbc_repo/opendbc/car/subaru/carcontroller.py @@ -302,7 +302,7 @@ class CarController(CarControllerBase): lkas_available = CC.latActive and (not mads_only or mads_only_ok) and \ CS.out.gearShifter == structs.CarState.GearShifter.drive and not CS.out.standstill - manual_handoff = self._legacy_2025_manual_handoff(CS, lkas_available) + manual_handoff = self._legacy_2025_manual_handoff(CS, CC.latActive) lkas_active = lkas_available and not manual_handoff steer_target = self._legacy_2025_reclaim_target(CC.actuators.steeringAngleDeg) if lkas_active else CC.actuators.steeringAngleDeg @@ -325,7 +325,7 @@ class CarController(CarControllerBase): lkas_available = CC.latActive and (not mads_only or mads_only_ok) and \ CS.out.gearShifter == structs.CarState.GearShifter.drive and not CS.out.standstill - manual_handoff = self._angle_manual_handoff(CS, lkas_available) + manual_handoff = self._angle_manual_handoff(CS, CC.latActive) lkas_active = lkas_available and not manual_handoff if lkas_active and not self.angle_lkas_active: @@ -361,7 +361,7 @@ class CarController(CarControllerBase): lkas_available = CC.latActive and (not mads_only or mads_only_ok) and \ getattr(CS.out, "gearShifter", structs.CarState.GearShifter.drive) == structs.CarState.GearShifter.drive and \ not getattr(CS.out, "standstill", False) - manual_handoff = self._angle_manual_handoff(CS, lkas_available) + manual_handoff = self._angle_manual_handoff(CS, CC.latActive) lat_active = lkas_available and not self.driver_override and not manual_handoff if lat_active and not self.angle_lkas_active: self.apply_steer_last = CS.out.steeringAngleDeg diff --git a/opendbc_repo/opendbc/car/subaru/carstate.py b/opendbc_repo/opendbc/car/subaru/carstate.py index b5fe921055..395c33a625 100644 --- a/opendbc_repo/opendbc/car/subaru/carstate.py +++ b/opendbc_repo/opendbc/car/subaru/carstate.py @@ -85,14 +85,14 @@ class CarState(CarStateBase): if self.CP.flags & SubaruFlags.LKAS_ANGLE: ret.steeringAngleDeg = cp_angle.vl["Steering_2"]["Steering_Angle"] - steering_updated = len(cp_angle.vl_all["Steering_2"]["Steering_Angle"]) > 0 + steering_counter = cp_angle.vl["Steering_2"]["COUNTER"] else: ret.steeringAngleDeg = cp.vl["Steering_Torque"]["Steering_Angle"] - steering_updated = len(cp.vl_all["Steering_Torque"]["Steering_Angle"]) > 0 + steering_counter = cp.vl["Steering_Torque"].get("COUNTER", 0) if not (self.CP.flags & SubaruFlags.PREGLOBAL): # ideally we get this from the car, but unclear if it exists. diagnostic software doesn't even have it - ret.steeringRateDeg = self.angle_rate_calulator.update(ret.steeringAngleDeg, steering_updated) + ret.steeringRateDeg = self.angle_rate_calulator.update(ret.steeringAngleDeg, steering_counter) ret.steeringTorque = cp_angle.vl["Steering_Torque"]["Steer_Torque_Sensor"] ret.steeringTorqueEps = cp_angle.vl["Steering_Torque"]["Steer_Torque_Output"] diff --git a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py index 983aa42fa7..962e194f66 100644 --- a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py +++ b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py @@ -546,6 +546,25 @@ def test_ascent_2023_uses_gen2_angle_bus_layout(): assert controller.status_bus == CanBus.main +def test_ascent_steering_rate_retains_last_can_sample(): + CP = CarInterface.get_non_essential_params(CAR.SUBARU_ASCENT_2023) + car_state = CarState(CP, None) + parsers = car_state.get_can_parsers(CP) + toggles = SimpleNamespace(subaru_sng=False) + + parsers[Bus.pt].vl["Steering_2"]["Steering_Angle"] = 1.0 + parsers[Bus.pt].vl["Steering_2"]["COUNTER"] = 1 + car_state.update(parsers, toggles) + + parsers[Bus.pt].vl["Steering_2"]["Steering_Angle"] = 2.0 + parsers[Bus.pt].vl["Steering_2"]["COUNTER"] = 2 + state, _ = car_state.update(parsers, toggles) + assert state.steeringRateDeg == pytest.approx(50.0) + + state, _ = car_state.update(parsers, toggles) + assert state.steeringRateDeg == pytest.approx(50.0) + + def test_other_angle_platforms_keep_existing_bus_layout(): CP = CarInterface.get_non_essential_params(CAR.SUBARU_CROSSTREK_2025) parsers = CarState.get_can_parsers(CP) @@ -707,11 +726,20 @@ def test_ascent_angle_controller_blocks_parking_lot_aol_engagement(): CS.out.steeringRateDeg = 0.0 msg = controller.lateral_angle(CC, CS) parser.update([(2, [msg])]) + assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 0 + + for i in range(8): + msg = controller.lateral_angle(CC, CS) + parser.update([(3 + i, [msg])]) + assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 0 + + msg = controller.lateral_angle(CC, CS) + parser.update([(11, [msg])]) assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 1 CS.out.gearShifter = structs.CarState.GearShifter.reverse msg = controller.lateral_angle(CC, CS) - parser.update([(3, [msg])]) + parser.update([(12, [msg])]) assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Request"] == 0 assert parser.vl["ES_LKAS_ANGLE"]["LKAS_Output"] == pytest.approx(CS.out.steeringAngleDeg) diff --git a/opendbc_repo/opendbc/car/tests/routes.py b/opendbc_repo/opendbc/car/tests/routes.py index 387b7c75dd..7ba63c7e8f 100644 --- a/opendbc_repo/opendbc/car/tests/routes.py +++ b/opendbc_repo/opendbc/car/tests/routes.py @@ -108,6 +108,7 @@ non_tested_cars = [ TOYOTA.TOYOTA_RAV4H, # No recorded routes yet + VOLVO.VOLVO_V40, VOLVO.VOLVO_XC40_RECHARGE, VOLVO.VOLVO_S60_RECHARGE, VOLVO.POLESTAR_2, diff --git a/opendbc_repo/opendbc/car/torque_data/override.toml b/opendbc_repo/opendbc/car/torque_data/override.toml index e9bffa1908..862aec2c0a 100644 --- a/opendbc_repo/opendbc/car/torque_data/override.toml +++ b/opendbc_repo/opendbc/car/torque_data/override.toml @@ -145,6 +145,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "PORSCHE_MACAN_MK1" = [2.0, 2.0, 0.2] "VOLVO_XC40_RECHARGE" = [1.5, 1.5, 0.1] "VOLVO_S60_RECHARGE" = [1.5, 1.5, 0.1] +"VOLVO_V40" = [1.5, 1.5, 0.1] # Dashcam or fallback configured as ideal car "MOCK" = [10.0, 10, 0.0] diff --git a/opendbc_repo/opendbc/car/toyota/carcontroller.py b/opendbc_repo/opendbc/car/toyota/carcontroller.py index 959abdf965..531b2bf7be 100644 --- a/opendbc_repo/opendbc/car/toyota/carcontroller.py +++ b/opendbc_repo/opendbc/car/toyota/carcontroller.py @@ -40,6 +40,8 @@ TOYOTA_NO_LEAD_CRUISE_SIGN_FLIP_MIN_SET_SPEED_ERROR = 0.35 # m/s TOYOTA_RAV4_LAUNCH_PEDAL_BLEND_SPEED = 5.0 # m/s TOYOTA_RAV4_LAUNCH_PEDAL_SCALE = 0.11 TOYOTA_RAV4_LOW_SPEED_PEDAL_SCALE = 0.23 +TOYOTA_AUTO_HOLD_ACCEL = -1.0 +TOYOTA_AUTO_HOLD_ACTIVATION_FRAMES = 100 # LKA limits # EPS faults if you apply torque while the steering rate is above 100 deg/s for too long @@ -309,23 +311,24 @@ class CarController(CarControllerBase): self.last_standstill = CS.out.standstill - def create_auto_brake_hold_messages(self, CS: structs.CarState, brake_hold_allowed_timer: int = 100): - can_sends = [] - brake_hold_allowed = (CS.out.standstill and CS.out.cruiseState.available and + def update_auto_hold_state(self, CS: structs.CarState, cancel_requested: bool = False, + activation_frames: int = TOYOTA_AUTO_HOLD_ACTIVATION_FRAMES): + brake_hold_allowed = (not cancel_requested and CS.out.standstill and CS.out.cruiseState.available and not CS.out.gasPressed and not CS.out.cruiseState.enabled and CS.out.gearShifter not in (PARK, REVERSE)) if brake_hold_allowed and not self.brake_hold_active and CS.out.brakePressed: self._brake_hold_counter += 1 - self.brake_hold_active = self._brake_hold_counter > brake_hold_allowed_timer + self.brake_hold_active = self._brake_hold_counter > activation_frames elif not brake_hold_allowed: self._brake_hold_counter = 0 self.brake_hold_active = False - if self.frame % 2 == 0: - can_sends.append(toyotacan.create_brake_hold_command(self.packer, self.frame, CS.pre_collision_2, self.brake_hold_active)) + return self.brake_hold_active - return can_sends + def reset_auto_hold_state(self): + self._brake_hold_counter = 0 + self.brake_hold_active = False def update(self, CC, CS, now_nanos, starpilot_toggles): actuators = CC.actuators @@ -423,10 +426,9 @@ class CarController(CarControllerBase): self._update_standstill_request(CC, CS, actuators, starpilot_toggles) if supports_toyota_auto_hold(self.CP, getattr(starpilot_toggles, "toyota_auto_hold", False)): - can_sends.extend(self.create_auto_brake_hold_messages(CS)) - elif self.brake_hold_active: - self._brake_hold_counter = 0 - self.brake_hold_active = False + self.update_auto_hold_state(CS, pcm_cancel_cmd) + else: + self.reset_auto_hold_state() interceptor_gas_cmd = self._compute_interceptor_gas_cmd(CC, CS) @@ -534,6 +536,11 @@ class CarController(CarControllerBase): pcm_accel_cmd = float(np.clip(pcm_accel_cmd, self.params.ACCEL_MIN, self.params.ACCEL_MAX)) + if self.brake_hold_active: + pcm_accel_cmd = TOYOTA_AUTO_HOLD_ACCEL + self.permit_braking = True + self.standstill_req = True + main_accel_cmd = 0. if self.CP.flags & ToyotaFlags.SECOC.value else pcm_accel_cmd can_sends.append(toyotacan.create_accel_command(self.packer, main_accel_cmd, pcm_cancel_cmd, self.permit_braking, self.standstill_req, lead, CS.acc_type, fcw_alert, self.distance_button, diff --git a/opendbc_repo/opendbc/car/toyota/carstate.py b/opendbc_repo/opendbc/car/toyota/carstate.py index 6ae944bd19..06fdb039a2 100644 --- a/opendbc_repo/opendbc/car/toyota/carstate.py +++ b/opendbc_repo/opendbc/car/toyota/carstate.py @@ -90,8 +90,6 @@ class CarState(CarStateBase): self.has_can_filter = self.FPCP.flags & ToyotaStarPilotFlags.RADAR_CAN_FILTER.value self.has_SDSU = self.FPCP.flags & ToyotaStarPilotFlags.SMART_DSU.value self.has_ZSS = self.FPCP.flags & ToyotaStarPilotFlags.ZSS.value - self.auto_brake_hold = bool(self.CP.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value) - self.pre_collision_2 = {} def update(self, can_parsers, starpilot_toggles) -> structs.CarState: cp = can_parsers[Bus.pt] @@ -227,9 +225,6 @@ class CarState(CarStateBase): if self.CP.carFingerprint != CAR.TOYOTA_PRIUS_V: self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"]) - if self.auto_brake_hold: - self.pre_collision_2 = copy.copy(cp_cam.vl["PRE_COLLISION_2"]) - if self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR: self.pcm_follow_distance = cp.vl["PCM_CRUISE_2"]["PCM_FOLLOW_DISTANCE"] @@ -314,9 +309,6 @@ class CarState(CarStateBase): if CP.carFingerprint in DISTANCE_BUTTON_CAR: pt_messages.append(("PCM_CRUISE_4", 1)) - if CP.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value: - cam_messages.append(("PRE_COLLISION_2", 50)) - return { Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0), Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2), diff --git a/opendbc_repo/opendbc/car/toyota/interface.py b/opendbc_repo/opendbc/car/toyota/interface.py index 618b820d2b..71472bae1e 100644 --- a/opendbc_repo/opendbc/car/toyota/interface.py +++ b/opendbc_repo/opendbc/car/toyota/interface.py @@ -164,8 +164,8 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs[0].safetyParam |= ToyotaSafetyFlags.GAS_INTERCEPTOR.value toyota_auto_hold = Params(return_defaults=True).get_bool("ToyotaAutoHold") - if toyota_auto_hold and candidate in TOYOTA_AUTO_HOLD_CARS: - ret.alternativeExperience |= ALTERNATIVE_EXPERIENCE.ALLOW_AEB + if toyota_auto_hold and ret.openpilotLongitudinalControl and candidate in TOYOTA_AUTO_HOLD_CARS: + ret.alternativeExperience |= ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD ret.flags |= ToyotaFlags.AUTO_BRAKE_HOLD.value if not ret.openpilotLongitudinalControl: diff --git a/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py b/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py index 225a997bb1..72e026d69c 100644 --- a/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py +++ b/opendbc_repo/opendbc/car/toyota/tests/test_toyota.py @@ -196,7 +196,8 @@ class TestToyotaInterfaces: params.put_bool("ToyotaAutoHold", True) car_params = CarInterface.get_params( candidate, - {bus: {} for bus in range(8)}, + {bus: ({0x2FF: 8} if candidate in (CAR.TOYOTA_RAV4, CAR.TOYOTA_RAV4H) and bus == 0 else {}) + for bus in range(8)}, [], alpha_long=False, is_release=False, @@ -207,12 +208,13 @@ class TestToyotaInterfaces: params.remove("ToyotaAutoHold") assert car_params.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value - assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB + assert car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD + assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB can_parsers = CarState.get_can_parsers(car_params) car_state = CarState(car_params, SimpleNamespace(flags=0)) car_state.update(can_parsers, SimpleNamespace(cluster_offset=1.0)) - assert "PRE_COLLISION_2" in can_parsers[Bus.cam].vl + assert "PRE_COLLISION_2" not in can_parsers[Bus.cam].vl @pytest.mark.parametrize("candidate", [CAR.TOYOTA_CAMRY_TSS2, CAR.TOYOTA_RAV4, CAR.TOYOTA_RAV4H]) def test_auto_hold_is_disabled_by_default(self, candidate): @@ -229,7 +231,7 @@ class TestToyotaInterfaces: ) assert not car_params.flags & ToyotaFlags.AUTO_BRAKE_HOLD.value - assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALLOW_AEB + assert not car_params.alternativeExperience & ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD def test_prius_openpilot_long_uses_hybrid_long_defaults(self): car_params = CarInterface.get_params( @@ -744,6 +746,8 @@ class TestToyotaCarController: controller.standstill_req = standstill_req controller.last_standstill = last_standstill controller.accel = 0.0 + controller.brake_hold_active = False + controller._brake_hold_counter = 0 return controller @staticmethod @@ -806,9 +810,6 @@ class TestToyotaCarController: def test_toyota_auto_hold_latches_after_brake_press_until_gas(self): controller = self._make_controller() controller.packer = CANPacker(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt]) - controller.frame = 0 - controller.brake_hold_active = False - controller._brake_hold_counter = 0 cs = SimpleNamespace( out=SimpleNamespace( @@ -818,28 +819,22 @@ class TestToyotaCarController: brakePressed=True, gearShifter=structs.CarState.GearShifter.drive, ), - pre_collision_2={}, ) - controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0) + controller.update_auto_hold_state(cs, activation_frames=0) assert controller.brake_hold_active cs.out.brakePressed = False - controller.frame = 2 - controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0) + controller.update_auto_hold_state(cs, activation_frames=0) assert controller.brake_hold_active cs.out.gasPressed = True - controller.frame = 4 - controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0) + controller.update_auto_hold_state(cs, activation_frames=0) assert not controller.brake_hold_active def test_toyota_auto_hold_does_not_trigger_without_brake_press(self): controller = self._make_controller() controller.packer = CANPacker(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt]) - controller.frame = 0 - controller.brake_hold_active = False - controller._brake_hold_counter = 0 cs = SimpleNamespace( out=SimpleNamespace( standstill=True, @@ -848,10 +843,9 @@ class TestToyotaCarController: brakePressed=False, gearShifter=structs.CarState.GearShifter.drive, ), - pre_collision_2={}, ) - controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0) + controller.update_auto_hold_state(cs, activation_frames=0) assert not controller.brake_hold_active def test_prius_resume_request_releases_standstill_latch(self): @@ -991,12 +985,9 @@ class TestToyotaCarController: assert parser.can_valid assert parser.vl["ACC_CONTROL"]["ALLOW_LONG_PRESS"] == 1 - def test_auto_brake_hold_sends_modified_pre_collision_after_timer(self): + def test_auto_hold_uses_acc_control_brake_path(self): controller = self._make_controller() controller.packer = CANPacker(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt]) - controller.frame = 0 - controller.brake_hold_active = False - controller._brake_hold_counter = 0 cs = SimpleNamespace( out=SimpleNamespace( standstill=True, @@ -1005,16 +996,19 @@ class TestToyotaCarController: brakePressed=True, gearShifter=structs.CarState.GearShifter.drive, ), - pre_collision_2={}, ) - can_sends = controller.create_auto_brake_hold_messages(cs, brake_hold_allowed_timer=0) + controller.update_auto_hold_state(cs, activation_frames=0) + can_sends = [toyotacan.create_accel_command( + controller.packer, -1.0, False, True, True, False, 1, False, 0, False, + )] - parser = CANParser(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt], [("PRE_COLLISION_2", 0)], 0) + parser = CANParser(DBC[CAR.TOYOTA_CAMRY_TSS2][Bus.pt], [("ACC_CONTROL", 0)], 0) parser.update([(1, can_sends)]) assert controller.brake_hold_active - assert parser.vl["PRE_COLLISION_2"]["DSS1GDRV"] == -1.0 - assert parser.vl["PRE_COLLISION_2"]["PBRTRGR"] == 1 + assert parser.vl["ACC_CONTROL"]["ACCEL_CMD"] == -1.0 + assert parser.vl["ACC_CONTROL"]["PERMIT_BRAKING"] == 1 + assert parser.vl["ACC_CONTROL"]["RELEASE_STANDSTILL"] == 0 def test_interceptor_stop_and_go_holds_small_launch_at_standstill(self): controller = self._make_controller() diff --git a/opendbc_repo/opendbc/car/toyota/toyotacan.py b/opendbc_repo/opendbc/car/toyota/toyotacan.py index 43a7a8d383..2d6c1bdb17 100644 --- a/opendbc_repo/opendbc/car/toyota/toyotacan.py +++ b/opendbc_repo/opendbc/car/toyota/toyotacan.py @@ -89,38 +89,6 @@ def create_pcs_commands(packer, accel, active, mass): return [msg1, msg2] -def create_brake_hold_command(packer, frame, pre_collision_2, brake_hold_active): - values = {s: pre_collision_2[s] for s in [ - "DSS1GDRV", - "DS1STAT2", - "DS1STBK2", - "PCSWAR", - "PCSALM", - "PCSOPR", - "PCSABK", - "PBATRGR", - "PPTRGR", - "IBTRGR", - "CLEXTRGR", - "IRLT_REQ", - "BRKHLD", - "AVSTRGR", - "VGRSTRGR", - "PREFILL", - "PBRTRGR", - "PCSDIS", - "PBPREPMP", - ] if s in pre_collision_2} - - if brake_hold_active: - values = { - "DSS1GDRV": 0x3FF, - "PBRTRGR": frame % 730 < 727, - } - - return packer.make_can_msg("PRE_COLLISION_2", 0, values) - - def create_acc_cancel_command(packer): values = { "GAS_RELEASED": 0, diff --git a/opendbc_repo/opendbc/car/volvo/carcontroller.py b/opendbc_repo/opendbc/car/volvo/carcontroller.py index 350479eeeb..766b2e41cd 100644 --- a/opendbc_repo/opendbc/car/volvo/carcontroller.py +++ b/opendbc_repo/opendbc/car/volvo/carcontroller.py @@ -1,3 +1,5 @@ +from collections import deque + import numpy as np from opendbc.can.packer import CANPacker @@ -5,16 +7,20 @@ from opendbc.car import Bus from opendbc.car.interfaces import CarControllerBase from opendbc.car.lateral import apply_std_steer_angle_limits from opendbc.car.volvo.helpers import LCA3CounterSync -from opendbc.car.volvo.volvocan import (create_lca_message, create_pscm_message, create_lca_3_message, create_lca_2_message, create_lca_4_message, - create_lca_5_message, create_lca_6_message, create_lca_7_message, create_pscm_related_message) -from opendbc.car.volvo.values import CarControllerParams +from opendbc.car.volvo.volvocan import (create_c1_cancel, create_c1_pscm_message, create_c1_steering_control, create_lca_message, + create_pscm_message, create_lca_3_message, create_lca_2_message, create_lca_4_message, create_lca_5_message, + create_lca_6_message, create_lca_7_message, create_pscm_related_message) +from opendbc.car.volvo.values import CAR, CarControllerParams, VolvoC1PlatformConfig class CarController(CarControllerBase): def __init__(self, dbc_names, CP): super().__init__(dbc_names, CP) - self.packer = CANPacker(dbc_names[Bus.party]) + self.is_c1 = isinstance(CAR(CP.carFingerprint).config, VolvoC1PlatformConfig) + self.packer = CANPacker(dbc_names[Bus.pt] if self.is_c1 else dbc_names[Bus.party]) self.apply_angle_last = 0.0 # Track last applied steering angle + self.c1_torque_samples = deque(maxlen=CarControllerParams.C1_N_ZERO_TORQUE) + self.c1_recovery_until = -1 self.gear_acc = 60 self.lca_4_acc = 0 # Bresenham accumulator for 29 Hz @@ -62,6 +68,9 @@ class CarController(CarControllerBase): self.lca_auth_drv_mag_filt = 0.0 def update(self, CC, CS, now_nanos, starpilot_toggles): + if self.is_c1: + return self._update_c1(CC, CS) + can_sends = [] actuators = CC.actuators @@ -285,3 +294,50 @@ class CarController(CarControllerBase): self.frame += 1 self.last_lat_active = CC.latActive return new_actuators, can_sends + + def _update_c1(self, CC, CS): + can_sends = [] + actuators = CC.actuators + + if self.frame % 2 == 0: # stock FSM1 and PSCM1 messages are 50 Hz + requested_active = CC.latActive and CS.out.vEgo > self.CP.minSteerSpeed + recovering = requested_active and self.frame < self.c1_recovery_until + + if not requested_active: + self.c1_torque_samples.clear() + self.c1_recovery_until = -1 + elif recovering: + self.c1_torque_samples.clear() + else: + if self.c1_recovery_until >= 0: + self.c1_recovery_until = -1 + self.c1_torque_samples.clear() + self.c1_torque_samples.append(CS.c1_lka_torque) + if (len(self.c1_torque_samples) == CarControllerParams.C1_N_ZERO_TORQUE and + all(torque == 0 for torque in self.c1_torque_samples)): + self.c1_recovery_until = self.frame + 100 + self.c1_torque_samples.clear() + recovering = True + + lat_active = requested_active and not recovering + desired_angle = float(np.clip( + actuators.steeringAngleDeg, + CS.out.steeringAngleDeg - CarControllerParams.C1_ANGLE_ERROR, + CS.out.steeringAngleDeg + CarControllerParams.C1_ANGLE_ERROR, + )) + apply_angle = apply_std_steer_angle_limits( + desired_angle, self.apply_angle_last, CS.out.vEgoRaw, + CS.out.steeringAngleDeg, lat_active, CarControllerParams.C1_ANGLE_LIMITS, + ) + + can_sends.append(create_c1_pscm_message(self.packer, CS.c1_msg_pscm)) + can_sends.append(create_c1_steering_control(self.packer, apply_angle, lat_active)) + self.apply_angle_last = apply_angle + + if CC.cruiseControl.cancel and self.frame % 10 == 0: + can_sends.append(create_c1_cancel(self.packer)) + + new_actuators = actuators.as_builder() + new_actuators.steeringAngleDeg = self.apply_angle_last + self.frame += 1 + return new_actuators, can_sends diff --git a/opendbc_repo/opendbc/car/volvo/carstate.py b/opendbc_repo/opendbc/car/volvo/carstate.py index 9198e480b4..545ccc21cb 100644 --- a/opendbc_repo/opendbc/car/volvo/carstate.py +++ b/opendbc_repo/opendbc/car/volvo/carstate.py @@ -1,8 +1,9 @@ from cereal import custom -from opendbc.car import structs, Bus +from opendbc.car import Bus, ButtonType, create_button_events, structs from opendbc.can.parser import CANParser -from opendbc.car.volvo.values import DBC, VolvoSPAPlatformConfig, CAR +from opendbc.car.common.conversions import Conversions as CV from opendbc.car.interfaces import CarStateBase +from opendbc.car.volvo.values import CAR, DBC, VolvoC1PlatformConfig, VolvoSPAPlatformConfig GearShifter = structs.CarState.GearShifter TransmissionType = structs.CarParams.TransmissionType @@ -16,6 +17,7 @@ STEERING_PRESSED_THRESHOLD = 2 class CarState(CarStateBase): def __init__(self, CP, FPCP): super().__init__(CP, FPCP) + self.is_c1 = isinstance(CAR(CP.carFingerprint).config, VolvoC1PlatformConfig) self.is_spa = isinstance(CAR(CP.carFingerprint).config, VolvoSPAPlatformConfig) self.gas_pressed_prev = False self.dispatch_lca_2_msg = False @@ -34,8 +36,22 @@ class CarState(CarStateBase): self.msg_lca_4 = {} self.msg_lca_6 = {} self.msg_lca_7 = {} + self.c1_msg_pscm = {} + self.c1_lka_torque = 0 + self.c1_button_states = { + "ACCOnOffBtn": False, + "ACCStopBtn": False, + "ACCSetBtn": False, + "ACCResumeBtn": False, + "ACCMinusBtn": False, + "TimeGapIncreaseBtn": False, + "TimeGapDecreaseBtn": False, + } def update(self, can_parsers, starpilot_toggles) -> structs.CarState: + if self.is_c1: + return self._update_c1(can_parsers) + cp_main = can_parsers[Bus.main] cp_pt = can_parsers[Bus.pt] cp_party = can_parsers[Bus.party] @@ -137,8 +153,83 @@ class CarState(CarStateBase): fp_ret = custom.StarPilotCarState.new_message() return ret, fp_ret + def _update_c1(self, can_parsers): + cp = can_parsers[Bus.pt] + cp_cam = can_parsers[Bus.cam] + ret = structs.CarState() + + ret.vEgoRaw = cp.vl["VehicleSpeed1"]["VehicleSpeed"] * CV.KPH_TO_MS + ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) + ret.standstill = ret.vEgoRaw < 0.1 + + ret.steeringAngleDeg = cp.vl["PSCM1"]["SteeringAngleServo"] + ret.steeringTorque = cp.vl["PSCM1"]["LKATorque"] + ret.steeringPressed = False + + ret.gasPressed = cp.vl["PedalandBrake"]["AccPedal"] > 5.0 + ret.brakePressed = bool(cp.vl["PedalandBrake"]["BrakePedalActive2"] or + cp.vl["PedalandBrake"]["BrakePedalActive"]) + + ret.gearShifter = { + 0: GearShifter.park, + 1: GearShifter.reverse, + 2: GearShifter.neutral, + 3: GearShifter.drive, + }.get(int(cp.vl["TCM0"]["GearShifter"]), GearShifter.unknown) + + ret.cruiseState.available = bool(cp_cam.vl["FSM0"]["ACCStatusOnOff"]) + ret.cruiseState.enabled = bool(cp_cam.vl["FSM0"]["ACCStatusActive"]) + ret.cruiseState.speed = cp.vl["ACC"]["SpeedTargetACC"] * CV.KPH_TO_MS + ret.cruiseState.nonAdaptive = False + ret.cruiseState.standstill = ret.standstill + + turn_signal = int(cp.vl["MiscCarInfo"]["TurnSignal"]) + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_stalk( + 50, turn_signal == 1, turn_signal == 3) + ret.doorOpen = False + ret.seatbeltUnlatched = False + + button_types = { + "ACCOnOffBtn": ButtonType.mainCruise, + "ACCStopBtn": ButtonType.cancel, + "ACCSetBtn": ButtonType.setCruise, + "ACCResumeBtn": ButtonType.resumeCruise, + "ACCMinusBtn": ButtonType.decelCruise, + "TimeGapIncreaseBtn": ButtonType.gapAdjustCruise, + "TimeGapDecreaseBtn": ButtonType.gapAdjustCruise, + } + button_events = [] + for signal, button_type in button_types.items(): + pressed = bool(cp.vl["CCButtons"][signal]) + button_events.extend(create_button_events(pressed, self.c1_button_states[signal], {True: button_type})) + self.c1_button_states[signal] = pressed + ret.buttonEvents = button_events + + self.c1_msg_pscm = cp.vl["PSCM1"] + self.c1_lka_torque = int(cp.vl["PSCM1"]["LKATorque"]) + + fp_ret = custom.StarPilotCarState.new_message() + return ret, fp_ret + @staticmethod def get_can_parsers(CP): + if isinstance(CAR(CP.carFingerprint).config, VolvoC1PlatformConfig): + return { + Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [ + ("VehicleSpeed1", 50), + ("CCButtons", 100), + ("PSCM1", 50), + ("PedalandBrake", 100), + ("TCM0", 10), + ("ACC", 17), + ("MiscCarInfo", 25), + ], 0), + Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.cam], [ + ("FSM0", 100), + ("FSM1", 50), + ], 2), + } + return { Bus.main: CANParser(DBC[CP.carFingerprint][Bus.main], [], 0), Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 1), diff --git a/opendbc_repo/opendbc/car/volvo/fingerprints.py b/opendbc_repo/opendbc/car/volvo/fingerprints.py index df9d6e4180..a7e93baaa7 100644 --- a/opendbc_repo/opendbc/car/volvo/fingerprints.py +++ b/opendbc_repo/opendbc/car/volvo/fingerprints.py @@ -3,6 +3,14 @@ from opendbc.car.volvo.values import CAR FINGERPRINTS = { + CAR.VOLVO_V40: [ + # V40 2017 + {8: 8, 16: 8, 48: 8, 64: 8, 85: 8, 101: 8, 112: 8, 114: 8, 117: 8, 128: 8, 176: 8, 192: 8, 208: 8, 224: 8, 240: 8, 245: 8, 256: 8, 272: 8, 288: 8, 291: 8, 293: 8, 304: 8, 325: 8, 336: 8, 352: 8, 424: 8, 432: 8, 437: 8, 464: 8, 472: 8, 480: 8, 528: 8, 608: 8, 624: 8, 640: 8, 648: 8, 652: 8, 656: 8, 657: 8, 681: 8, 693: 8, 704: 8, 707: 8, 709: 8, 816: 8, 832: 8, 848: 8, 853: 8, 864: 8, 880: 8, 912: 8, 928: 8, 943: 8, 944: 8, 968: 8, 970: 8, 976: 8, 992: 8, 997: 8, 1024: 8, 1029: 8, 1061: 8, 1072: 8, 1409: 8}, + # V40 2015 + {8: 8, 16: 8, 64: 8, 85: 8, 101: 8, 112: 8, 114: 8, 117: 8, 128: 8, 176: 8, 192: 8, 224: 8, 240: 8, 245: 8, 256: 8, 272: 8, 288: 8, 291: 8, 293: 8, 304: 8, 325: 8, 336: 8, 424: 8, 432: 8, 437: 8, 464: 8, 472: 8, 480: 8, 528: 8, 608: 8, 648: 8, 652: 8, 656: 8, 657: 8, 681: 8, 693: 8, 704: 8, 707: 8, 709: 8, 816: 8, 832: 8, 864: 8, 880: 8, 912: 8, 928: 8, 943: 8, 944: 8, 968: 8, 970: 8, 976: 8, 992: 8, 997: 8, 1024: 8, 1029: 8, 1061: 8, 1072: 8, 1409: 8}, + # V40 2014 + {8: 8, 16: 8, 64: 8, 85: 8, 101: 8, 112: 8, 114: 8, 117: 8, 128: 8, 176: 8, 192: 8, 224: 8, 240: 8, 245: 8, 256: 8, 272: 8, 288: 8, 291: 8, 293: 8, 304: 8, 325: 8, 336: 8, 424: 8, 432: 8, 437: 8, 464: 8, 472: 8, 480: 8, 528: 8, 608: 8, 648: 8, 652: 8, 657: 8, 681: 8, 693: 8, 704: 8, 707: 8, 709: 8, 816: 8, 864: 8, 880: 8, 912: 8, 928: 8, 943: 8, 944: 8, 968: 8, 970: 8, 976: 8, 992: 8, 997: 8, 1024: 8, 1029: 8, 1072: 8, 1409: 8}, + ], CAR.VOLVO_XC40_RECHARGE: [{ 21: 8, 22: 8, 23: 8, 26: 8, 69: 8, 85: 8, 87: 8, 88: 8, 96: 8, 103: 8, 104: 8, 105: 8, 128: 8, 144: 8, 146: 8, 147: 8, 151: 8, 304: 8, 336: 8, 339: 8, 341: 8, 394: 8, 395: 8, 640: 8, 656: 8, 666: 8, 773: 8, 778: 8, 1072: 8, 1120: 8, 1302: 8, 1336: 8, 1407: 8, 1422: 8, 1423: 8, 1424: 8, 1425: 8, 1426: 8 }], diff --git a/opendbc_repo/opendbc/car/volvo/interface.py b/opendbc_repo/opendbc/car/volvo/interface.py index 3c1176009c..643cf5aa8a 100644 --- a/opendbc_repo/opendbc/car/volvo/interface.py +++ b/opendbc_repo/opendbc/car/volvo/interface.py @@ -2,11 +2,10 @@ from opendbc.car import structs, get_safety_config from opendbc.car.interfaces import CarInterfaceBase from opendbc.car.volvo.carcontroller import CarController from opendbc.car.volvo.carstate import CarState -from opendbc.car.volvo.values import VolvoSPAPlatformConfig, CAR +from opendbc.car.volvo.values import CAR, VolvoC1PlatformConfig, VolvoSafetyFlags, VolvoSPAPlatformConfig TransmissionType = structs.CarParams.TransmissionType -VOLVO_FLAG_SPA = 1 SAFETY_VOLVO = structs.CarParams.SafetyModel.volvo @@ -18,17 +17,20 @@ class CarInterface(CarInterfaceBase): def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, alpha_long, is_release, docs) -> structs.CarParams: ret.brand = 'volvo' + platform = CAR(candidate).config safety_param = 0 - if isinstance(CAR(candidate).config, VolvoSPAPlatformConfig): - safety_param = VOLVO_FLAG_SPA + if isinstance(platform, VolvoSPAPlatformConfig): + safety_param = VolvoSafetyFlags.SPA.value + elif isinstance(platform, VolvoC1PlatformConfig): + safety_param = VolvoSafetyFlags.C1.value ret.safetyConfigs = [get_safety_config(SAFETY_VOLVO, safety_param)] #ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.noOutput)] ret.dashcamOnly = False - ret.steerActuatorDelay = 0.3 + ret.steerActuatorDelay = 0.2 if isinstance(platform, VolvoC1PlatformConfig) else 0.3 ret.steerLimitTimer = 0.1 - ret.steerAtStandstill = True + ret.steerAtStandstill = not isinstance(platform, VolvoC1PlatformConfig) # Use angle-based steering control for Volvo CMA platform ret.steerControlType = structs.CarParams.SteerControlType.angle @@ -39,4 +41,7 @@ class CarInterface(CarInterfaceBase): ret.pcmCruise = True + if isinstance(platform, VolvoC1PlatformConfig): + ret.transmissionType = TransmissionType.automatic + return ret diff --git a/opendbc_repo/opendbc/car/volvo/tests/test_c1_carstate.py b/opendbc_repo/opendbc/car/volvo/tests/test_c1_carstate.py new file mode 100644 index 0000000000..0f4c7f0c58 --- /dev/null +++ b/opendbc_repo/opendbc/car/volvo/tests/test_c1_carstate.py @@ -0,0 +1,57 @@ +import pytest + +from cereal import custom +from opendbc.can.packer import CANPacker +from opendbc.car import Bus, ButtonType, CanData, structs +from opendbc.car.volvo.carstate import CarState +from opendbc.car.volvo.interface import CarInterface +from opendbc.car.volvo.values import CAR, DBC + + +def _can_data(msg): + address, data, bus = msg + return CanData(address, data, bus) + + +def test_c1_carstate_decodes_vehicle_and_cruise_signals(): + cp = CarInterface.get_non_essential_params(CAR.VOLVO_V40) + cs = CarState(cp, custom.StarPilotCarParams.new_message()) + parsers = CarState.get_can_parsers(cp) + packer = CANPacker(DBC[cp.carFingerprint][Bus.pt]) + + messages = [ + packer.make_can_msg("VehicleSpeed1", 0, {"VehicleSpeed": 72}), + packer.make_can_msg("CCButtons", 0, {"ACCStopBtn": 1, "ACCSetBtn": 1}), + packer.make_can_msg("PSCM1", 0, {"SteeringAngleServo": -12.5, "LKATorque": 7}), + packer.make_can_msg("PedalandBrake", 0, {"AccPedal": 6, "BrakePedalActive2": 1}), + packer.make_can_msg("TCM0", 0, {"GearShifter": 3}), + packer.make_can_msg("ACC", 0, {"SpeedTargetACC": 100}), + packer.make_can_msg("MiscCarInfo", 0, {"TurnSignal": 1}), + packer.make_can_msg("FSM0", 2, {"ACCStatusOnOff": 1, "ACCStatusActive": 1}), + packer.make_can_msg("FSM1", 2, {}), + ] + packets = [(1_000_000, [_can_data(msg) for msg in messages])] + for parser in parsers.values(): + parser.update(packets) + + ret, _ = cs.update(parsers, None) + assert ret.vEgoRaw == pytest.approx(20.0) + assert ret.steeringAngleDeg == pytest.approx(-12.5, abs=0.05) + assert ret.steeringTorque == 7 + assert ret.gasPressed and ret.brakePressed + assert ret.gearShifter == structs.CarState.GearShifter.drive + assert ret.cruiseState.available and ret.cruiseState.enabled + assert ret.cruiseState.speed == pytest.approx(100 / 3.6) + assert ret.leftBlinker and not ret.rightBlinker + assert len(ret.buttonEvents) == 2 + assert any(event.type == ButtonType.cancel and event.pressed for event in ret.buttonEvents) + assert any(event.type == ButtonType.setCruise and event.pressed for event in ret.buttonEvents) + + release = packer.make_can_msg("CCButtons", 0, {}) + packets = [(2_000_000, [_can_data(release)])] + for parser in parsers.values(): + parser.update(packets) + ret, _ = cs.update(parsers, None) + assert len(ret.buttonEvents) == 2 + assert any(event.type == ButtonType.cancel and not event.pressed for event in ret.buttonEvents) + assert any(event.type == ButtonType.setCruise and not event.pressed for event in ret.buttonEvents) diff --git a/opendbc_repo/opendbc/car/volvo/tests/test_controller.py b/opendbc_repo/opendbc/car/volvo/tests/test_controller.py index 5a73796fff..deae1d2b5c 100644 --- a/opendbc_repo/opendbc/car/volvo/tests/test_controller.py +++ b/opendbc_repo/opendbc/car/volvo/tests/test_controller.py @@ -4,7 +4,8 @@ from types import SimpleNamespace from opendbc.car.volvo.carcontroller import CarController from opendbc.car.volvo.helpers import checksum_lca_5_message from opendbc.car.volvo.interface import CarInterface -from opendbc.car.volvo.values import DBC +from opendbc.car.volvo.values import CAR, DBC +from opendbc.car.volvo.volvocan import create_c1_checksum def _zero_message(): @@ -67,3 +68,70 @@ def test_controller_relays_stock_lca5_angle_when_inactive(): if raw & (1 << 14): raw -= 1 << 15 assert abs(raw * 0.05596 - 12.0) < 0.1 + + +def _c1_state(): + return SimpleNamespace( + out=SimpleNamespace(steeringAngleDeg=10.0, vEgo=12.0, vEgoRaw=12.0), + c1_lka_torque=5, + c1_msg_pscm=_zero_message(), + ) + + +def test_c1_controller_emits_checked_steering_and_pscm_relay(): + cp = CarInterface.get_non_essential_params(CAR.VOLVO_V40) + controller = CarController(DBC[cp.carFingerprint], cp) + cc = SimpleNamespace( + latActive=True, + actuators=_Actuators(), + cruiseControl=SimpleNamespace(cancel=False), + ) + + actuators, can_sends = controller.update(cc, _c1_state(), 0, None) + assert [(msg[0], msg[2]) for msg in can_sends] == [(0x125, 2), (0xD0, 0)] + + fsm = can_sends[1][1] + assert fsm[7] & 0x3 == 3 + assert fsm[6] == create_c1_checksum(fsm) + assert 0.0 < actuators.steeringAngleDeg <= 2.0 + + +def test_c1_controller_sends_only_cancel_button(): + cp = CarInterface.get_non_essential_params(CAR.VOLVO_V40) + controller = CarController(DBC[cp.carFingerprint], cp) + cc = SimpleNamespace( + latActive=False, + actuators=_Actuators(), + cruiseControl=SimpleNamespace(cancel=True), + ) + + _, can_sends = controller.update(cc, _c1_state(), 0, None) + buttons = next(msg for msg in can_sends if msg[0] == 0x10) + assert buttons[2] == 0 + assert buttons[1][7] == 0x10 + assert buttons[1][6] == 0 + + +def test_c1_controller_temporarily_drops_steering_on_zero_torque_fault(): + cp = CarInterface.get_non_essential_params(CAR.VOLVO_V40) + controller = CarController(DBC[cp.carFingerprint], cp) + cs = _c1_state() + cs.c1_lka_torque = 0 + cc = SimpleNamespace( + latActive=True, + actuators=_Actuators(), + cruiseControl=SimpleNamespace(cancel=False), + ) + + directions = [] + for _ in range(23): + _, can_sends = controller.update(cc, cs, 0, None) + directions.extend(msg[1][7] & 0x3 for msg in can_sends if msg[0] == 0xD0) + + assert directions[:-1] == [3] * 11 + assert directions[-1] == 0 + + while controller.frame <= 122: + _, can_sends = controller.update(cc, cs, 0, None) + fsm = next(msg for msg in can_sends if msg[0] == 0xD0) + assert fsm[1][7] & 0x3 == 3 diff --git a/opendbc_repo/opendbc/car/volvo/values.py b/opendbc_repo/opendbc/car/volvo/values.py index 5b697bef0d..16cf7c5bbd 100644 --- a/opendbc_repo/opendbc/car/volvo/values.py +++ b/opendbc_repo/opendbc/car/volvo/values.py @@ -1,13 +1,23 @@ from dataclasses import dataclass, field +from enum import IntFlag from opendbc.car.structs import CarParams from opendbc.car import Bus, CarSpecs, DbcDict, PlatformConfig, Platforms from opendbc.car.lateral import AngleSteeringLimits +from opendbc.car.common.conversions import Conversions as CV from opendbc.car.docs_definitions import CarDocs, CarHarness, CarParts from opendbc.car.fw_query_definitions import FwQueryConfig Ecu = CarParams.Ecu +# C1 support is adapted from the original dragonpilot V40 port: +# https://github.com/dragonpilot/dragonpilot/commit/773dce507082d931236b64dca8024dce9625446f + + +class VolvoSafetyFlags(IntFlag): + SPA = 1 + C1 = 2 + class CarControllerParams: STEER_STEP = 1 # 100 Hz LCA command frequency (controlsd runs at 100 Hz) @@ -81,6 +91,19 @@ class CarControllerParams: ([0., 5., 25.], [5., 2., .3]), # rate down limits at different speeds ) + C1_STEER_NO = 0 + C1_STEER = 3 + C1_N_ZERO_TORQUE = 12 + C1_ANGLE_ERROR = 20.0 + C1_ANGLE_DELTA_BP = [0., 8.33, 13.89, 19.44, 25., 30.55, 36.1] + C1_ANGLE_DELTA_UP = [2., 1.2, .25, .20, .15, .10, .10] + C1_ANGLE_DELTA_DOWN = [2., 1.2, .25, .20, .15, .10, .10] + C1_ANGLE_LIMITS: AngleSteeringLimits = AngleSteeringLimits( + 359.9, + (C1_ANGLE_DELTA_BP, C1_ANGLE_DELTA_UP), + (C1_ANGLE_DELTA_BP, C1_ANGLE_DELTA_DOWN), + ) + @dataclass class VolvoCarDocs(CarDocs): @@ -105,7 +128,26 @@ class VolvoSPAPlatformConfig(PlatformConfig): }) +@dataclass +class VolvoC1PlatformConfig(PlatformConfig): + dbc_dict: DbcDict = field(default_factory=lambda: { + Bus.pt: 'volvo_v40_2017_pt', + Bus.cam: 'volvo_v40_2017_pt', + }) + + class CAR(Platforms): + VOLVO_V40 = VolvoC1PlatformConfig( + [VolvoCarDocs("Volvo V40 2013-19")], + CarSpecs( + mass=1610, + wheelbase=2.647, + steerRatio=14.7, + centerToFrontRatio=0.44, + minSteerSpeed=1.0 * CV.KPH_TO_MS, + ), + ) + VOLVO_XC40_RECHARGE = VolvoCMAPlatformConfig( [VolvoCarDocs("Volvo XC40 Recharge 2021-23")], CarSpecs( diff --git a/opendbc_repo/opendbc/car/volvo/volvocan.py b/opendbc_repo/opendbc/car/volvo/volvocan.py index 9f7f0753a9..963dc9c632 100644 --- a/opendbc_repo/opendbc/car/volvo/volvocan.py +++ b/opendbc_repo/opendbc/car/volvo/volvocan.py @@ -2,6 +2,47 @@ from opendbc.car.volvo.helpers import (checksum_lca_2_message, checksum_2_0x69_m checksum_2_pscm_related_message, checksum_lca_5_message) from opendbc.car.carlog import carlog + +def create_c1_pscm_message(packer, msg_pscm: dict): + values = { + "LKATorque": 0, + "SteeringAngleServo": msg_pscm["SteeringAngleServo"], + "byte0": msg_pscm["byte0"], + "byte3": msg_pscm["byte3"], + "byte4": msg_pscm["byte4"], + "byte7": msg_pscm["byte7"], + "LKAActive": int(msg_pscm["LKAActive"]) & 0xD, + } + return packer.make_can_msg("PSCM1", 2, values) + + +def create_c1_checksum(data: bytes) -> int: + angle_raw = ((data[4] & 0x3F) << 8) | data[5] + direction = data[7] & 0x3 + checksum_sum = (data[3] + direction + angle_raw + (angle_raw >> 8)) & 0xFF + return checksum_sum ^ 0xFF + + +def create_c1_steering_control(packer, apply_angle: float, lat_active: bool): + values = { + "SET_X_E3": 0xE3, + "SET_X_B4": 0xB4, + "SET_X_08": 0x08, + "TrqLim": 0, + "LKAAngleReq": apply_angle, + "LKASteerDirection": 3 if lat_active else 0, + "SET_X_25": 0x25, + "SET_X_02": 0x02, + } + data = packer.make_can_msg("FSM1", 0, values)[1] + values["Checksum"] = create_c1_checksum(data) + return packer.make_can_msg("FSM1", 0, values) + + +def create_c1_cancel(packer): + return packer.make_can_msg("CCButtons", 0, {"ACCStopBtn": 1}) + + def create_lca_message(packer, lat_active: bool, apply_angle: float, msg_lca: dict, authority_pos: int = 614, authority_neg: int = -614, overrides: dict | None = None): diff --git a/opendbc_repo/opendbc/dbc/generator/hyundai/hyundai_radar_210_21f.dbc b/opendbc_repo/opendbc/dbc/generator/hyundai/hyundai_radar_210_21f.dbc new file mode 100644 index 0000000000..13c688eb05 --- /dev/null +++ b/opendbc_repo/opendbc/dbc/generator/hyundai/hyundai_radar_210_21f.dbc @@ -0,0 +1,1221 @@ + +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + +BO_ 528 RADAR_TRACK_210: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 528 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 528 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 528 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 528 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 528 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 528 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 528 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 528 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 528 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 528 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 528 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 528 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 528 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 528 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 528 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 528 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 528 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 528 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 528 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 528 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 528 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 528 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 528 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 528 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 528 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 528 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 528 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 528 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 528 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 528 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 528 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 528 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 528 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 528 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 528 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 528 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 528 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 528 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 528 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 529 RADAR_TRACK_211: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 529 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 529 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 529 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 529 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 529 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 529 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 529 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 529 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 529 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 529 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 529 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 529 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 529 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 529 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 529 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 529 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 529 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 529 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 529 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 529 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 529 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 529 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 529 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 529 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 529 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 529 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 529 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 529 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 529 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 529 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 529 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 529 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 529 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 529 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 529 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 529 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 529 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 529 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 529 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 530 RADAR_TRACK_212: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 530 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 530 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 530 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 530 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 530 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 530 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 530 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 530 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 530 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 530 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 530 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 530 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 530 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 530 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 530 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 530 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 530 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 530 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 530 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 530 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 530 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 530 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 530 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 530 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 530 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 530 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 530 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 530 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 530 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 530 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 530 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 530 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 530 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 530 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 530 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 530 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 530 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 530 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 530 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 531 RADAR_TRACK_213: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 531 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 531 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 531 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 531 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 531 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 531 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 531 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 531 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 531 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 531 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 531 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 531 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 531 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 531 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 531 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 531 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 531 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 531 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 531 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 531 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 531 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 531 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 531 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 531 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 531 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 531 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 531 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 531 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 531 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 531 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 531 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 531 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 531 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 531 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 531 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 531 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 531 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 531 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 531 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 532 RADAR_TRACK_214: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 532 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 532 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 532 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 532 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 532 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 532 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 532 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 532 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 532 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 532 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 532 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 532 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 532 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 532 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 532 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 532 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 532 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 532 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 532 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 532 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 532 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 532 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 532 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 532 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 532 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 532 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 532 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 532 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 532 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 532 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 532 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 532 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 532 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 532 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 532 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 532 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 532 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 532 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 532 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 533 RADAR_TRACK_215: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 533 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 533 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 533 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 533 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 533 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 533 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 533 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 533 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 533 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 533 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 533 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 533 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 533 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 533 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 533 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 533 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 533 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 533 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 533 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 533 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 533 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 533 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 533 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 533 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 533 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 533 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 533 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 533 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 533 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 533 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 533 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 533 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 533 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 533 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 533 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 533 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 533 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 533 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 533 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 534 RADAR_TRACK_216: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 534 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 534 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 534 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 534 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 534 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 534 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 534 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 534 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 534 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 534 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 534 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 534 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 534 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 534 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 534 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 534 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 534 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 534 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 534 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 534 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 534 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 534 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 534 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 534 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 534 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 534 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 534 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 534 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 534 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 534 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 534 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 534 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 534 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 534 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 534 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 534 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 534 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 534 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 534 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 535 RADAR_TRACK_217: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 535 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 535 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 535 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 535 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 535 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 535 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 535 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 535 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 535 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 535 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 535 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 535 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 535 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 535 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 535 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 535 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 535 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 535 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 535 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 535 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 535 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 535 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 535 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 535 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 535 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 535 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 535 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 535 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 535 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 535 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 535 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 535 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 535 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 535 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 535 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 535 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 535 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 535 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 535 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 536 RADAR_TRACK_218: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 536 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 536 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 536 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 536 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 536 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 536 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 536 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 536 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 536 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 536 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 536 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 536 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 536 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 536 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 536 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 536 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 536 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 536 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 536 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 536 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 536 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 536 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 536 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 536 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 536 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 536 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 536 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 536 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 536 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 536 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 536 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 536 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 536 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 536 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 536 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 536 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 536 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 536 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 536 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 537 RADAR_TRACK_219: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 537 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 537 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 537 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 537 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 537 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 537 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 537 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 537 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 537 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 537 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 537 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 537 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 537 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 537 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 537 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 537 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 537 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 537 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 537 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 537 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 537 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 537 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 537 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 537 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 537 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 537 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 537 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 537 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 537 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 537 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 537 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 537 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 537 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 537 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 537 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 537 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 537 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 537 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 537 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 538 RADAR_TRACK_21a: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 538 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 538 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 538 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 538 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 538 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 538 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 538 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 538 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 538 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 538 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 538 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 538 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 538 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 538 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 538 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 538 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 538 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 538 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 538 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 538 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 538 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 538 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 538 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 538 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 538 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 538 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 538 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 538 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 538 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 538 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 538 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 538 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 538 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 538 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 538 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 538 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 538 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 538 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 538 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 539 RADAR_TRACK_21b: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 539 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 539 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 539 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 539 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 539 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 539 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 539 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 539 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 539 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 539 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 539 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 539 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 539 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 539 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 539 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 539 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 539 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 539 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 539 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 539 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 539 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 539 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 539 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 539 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 539 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 539 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 539 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 539 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 539 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 539 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 539 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 539 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 539 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 539 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 539 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 539 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 539 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 539 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 539 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 540 RADAR_TRACK_21c: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 540 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 540 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 540 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 540 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 540 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 540 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 540 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 540 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 540 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 540 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 540 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 540 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 540 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 540 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 540 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 540 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 540 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 540 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 540 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 540 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 540 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 540 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 540 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 540 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 540 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 540 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 540 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 540 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 540 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 540 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 540 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 540 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 540 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 540 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 540 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 540 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 540 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 540 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 540 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 541 RADAR_TRACK_21d: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 541 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 541 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 541 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 541 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 541 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 541 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 541 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 541 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 541 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 541 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 541 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 541 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 541 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 541 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 541 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 541 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 541 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 541 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 541 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 541 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 541 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 541 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 541 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 541 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 541 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 541 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 541 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 541 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 541 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 541 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 541 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 541 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 541 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 541 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 541 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 541 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 541 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 541 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 541 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 542 RADAR_TRACK_21e: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 542 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 542 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 542 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 542 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 542 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 542 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 542 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 542 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 542 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 542 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 542 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 542 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 542 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 542 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 542 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 542 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 542 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 542 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 542 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 542 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 542 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 542 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 542 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 542 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 542 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 542 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 542 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 542 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 542 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 542 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 542 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 542 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 542 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 542 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 542 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 542 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 542 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 542 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 542 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 543 RADAR_TRACK_21f: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 543 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 543 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 543 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 543 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 543 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 543 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 543 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 543 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 543 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 543 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 543 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 543 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 543 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 543 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 543 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 543 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 543 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 543 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 543 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 543 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 543 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 543 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 543 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 543 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 543 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 543 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 543 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 543 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 543 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 543 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 543 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 543 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 543 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 543 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 543 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 543 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 543 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 543 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 543 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; diff --git a/opendbc_repo/opendbc/dbc/hyundai_radar_210_21f_generated.dbc b/opendbc_repo/opendbc/dbc/hyundai_radar_210_21f_generated.dbc new file mode 100644 index 0000000000..5c13549b7e --- /dev/null +++ b/opendbc_repo/opendbc/dbc/hyundai_radar_210_21f_generated.dbc @@ -0,0 +1,1224 @@ +CM_ "AUTOGENERATED FILE, DO NOT EDIT"; + +CM_ "hyundai_radar_210_21f.dbc starts here"; + +VERSION "" + + +NS_ : + NS_DESC_ + CM_ + BA_DEF_ + BA_ + VAL_ + CAT_DEF_ + CAT_ + FILTER + BA_DEF_DEF_ + EV_DATA_ + ENVVAR_DATA_ + SGTYPE_ + SGTYPE_VAL_ + BA_DEF_SGTYPE_ + BA_SGTYPE_ + SIG_TYPE_REF_ + VAL_TABLE_ + SIG_GROUP_ + SIG_VALTYPE_ + SIGTYPE_VALTYPE_ + BO_TX_BU_ + BA_DEF_REL_ + BA_REL_ + BA_DEF_DEF_REL_ + BU_SG_REL_ + BU_EV_REL_ + BU_BO_REL_ + SG_MUL_VAL_ + +BS_: + +BU_: XXX + +BO_ 528 RADAR_TRACK_210: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 528 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 528 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 528 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 528 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 528 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 528 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 528 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 528 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 528 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 528 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 528 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 528 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 528 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 528 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 528 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 528 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 528 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 528 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 528 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 528 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 528 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 528 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 528 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 528 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 528 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 528 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 528 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 528 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 528 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 528 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 528 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 528 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 528 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 528 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 528 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 528 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 528 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 528 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 528 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 529 RADAR_TRACK_211: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 529 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 529 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 529 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 529 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 529 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 529 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 529 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 529 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 529 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 529 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 529 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 529 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 529 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 529 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 529 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 529 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 529 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 529 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 529 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 529 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 529 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 529 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 529 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 529 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 529 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 529 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 529 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 529 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 529 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 529 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 529 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 529 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 529 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 529 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 529 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 529 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 529 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 529 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 529 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 530 RADAR_TRACK_212: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 530 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 530 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 530 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 530 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 530 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 530 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 530 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 530 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 530 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 530 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 530 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 530 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 530 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 530 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 530 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 530 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 530 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 530 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 530 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 530 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 530 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 530 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 530 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 530 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 530 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 530 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 530 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 530 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 530 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 530 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 530 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 530 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 530 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 530 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 530 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 530 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 530 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 530 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 530 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 531 RADAR_TRACK_213: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 531 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 531 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 531 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 531 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 531 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 531 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 531 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 531 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 531 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 531 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 531 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 531 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 531 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 531 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 531 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 531 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 531 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 531 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 531 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 531 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 531 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 531 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 531 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 531 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 531 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 531 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 531 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 531 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 531 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 531 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 531 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 531 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 531 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 531 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 531 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 531 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 531 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 531 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 531 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 532 RADAR_TRACK_214: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 532 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 532 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 532 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 532 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 532 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 532 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 532 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 532 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 532 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 532 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 532 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 532 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 532 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 532 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 532 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 532 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 532 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 532 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 532 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 532 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 532 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 532 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 532 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 532 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 532 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 532 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 532 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 532 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 532 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 532 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 532 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 532 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 532 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 532 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 532 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 532 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 532 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 532 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 532 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 533 RADAR_TRACK_215: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 533 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 533 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 533 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 533 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 533 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 533 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 533 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 533 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 533 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 533 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 533 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 533 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 533 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 533 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 533 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 533 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 533 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 533 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 533 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 533 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 533 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 533 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 533 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 533 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 533 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 533 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 533 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 533 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 533 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 533 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 533 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 533 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 533 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 533 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 533 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 533 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 533 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 533 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 533 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 534 RADAR_TRACK_216: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 534 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 534 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 534 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 534 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 534 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 534 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 534 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 534 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 534 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 534 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 534 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 534 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 534 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 534 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 534 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 534 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 534 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 534 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 534 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 534 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 534 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 534 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 534 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 534 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 534 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 534 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 534 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 534 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 534 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 534 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 534 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 534 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 534 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 534 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 534 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 534 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 534 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 534 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 534 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 535 RADAR_TRACK_217: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 535 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 535 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 535 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 535 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 535 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 535 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 535 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 535 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 535 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 535 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 535 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 535 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 535 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 535 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 535 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 535 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 535 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 535 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 535 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 535 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 535 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 535 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 535 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 535 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 535 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 535 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 535 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 535 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 535 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 535 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 535 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 535 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 535 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 535 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 535 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 535 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 535 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 535 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 535 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 536 RADAR_TRACK_218: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 536 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 536 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 536 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 536 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 536 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 536 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 536 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 536 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 536 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 536 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 536 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 536 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 536 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 536 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 536 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 536 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 536 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 536 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 536 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 536 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 536 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 536 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 536 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 536 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 536 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 536 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 536 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 536 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 536 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 536 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 536 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 536 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 536 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 536 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 536 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 536 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 536 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 536 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 536 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 537 RADAR_TRACK_219: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 537 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 537 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 537 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 537 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 537 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 537 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 537 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 537 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 537 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 537 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 537 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 537 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 537 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 537 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 537 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 537 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 537 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 537 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 537 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 537 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 537 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 537 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 537 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 537 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 537 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 537 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 537 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 537 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 537 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 537 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 537 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 537 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 537 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 537 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 537 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 537 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 537 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 537 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 537 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 538 RADAR_TRACK_21a: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 538 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 538 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 538 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 538 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 538 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 538 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 538 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 538 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 538 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 538 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 538 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 538 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 538 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 538 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 538 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 538 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 538 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 538 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 538 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 538 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 538 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 538 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 538 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 538 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 538 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 538 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 538 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 538 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 538 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 538 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 538 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 538 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 538 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 538 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 538 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 538 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 538 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 538 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 538 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 539 RADAR_TRACK_21b: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 539 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 539 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 539 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 539 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 539 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 539 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 539 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 539 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 539 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 539 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 539 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 539 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 539 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 539 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 539 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 539 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 539 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 539 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 539 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 539 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 539 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 539 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 539 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 539 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 539 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 539 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 539 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 539 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 539 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 539 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 539 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 539 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 539 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 539 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 539 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 539 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 539 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 539 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 539 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 540 RADAR_TRACK_21c: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 540 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 540 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 540 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 540 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 540 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 540 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 540 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 540 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 540 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 540 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 540 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 540 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 540 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 540 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 540 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 540 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 540 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 540 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 540 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 540 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 540 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 540 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 540 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 540 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 540 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 540 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 540 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 540 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 540 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 540 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 540 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 540 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 540 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 540 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 540 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 540 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 540 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 540 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 540 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 541 RADAR_TRACK_21d: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 541 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 541 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 541 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 541 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 541 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 541 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 541 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 541 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 541 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 541 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 541 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 541 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 541 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 541 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 541 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 541 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 541 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 541 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 541 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 541 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 541 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 541 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 541 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 541 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 541 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 541 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 541 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 541 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 541 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 541 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 541 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 541 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 541 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 541 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 541 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 541 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 541 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 541 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 541 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 542 RADAR_TRACK_21e: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 542 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 542 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 542 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 542 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 542 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 542 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 542 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 542 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 542 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 542 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 542 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 542 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 542 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 542 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 542 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 542 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 542 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 542 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 542 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 542 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 542 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 542 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 542 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 542 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 542 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 542 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 542 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 542 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 542 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 542 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 542 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 542 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 542 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 542 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 542 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 542 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 542 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 542 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 542 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; + +BO_ 543 RADAR_TRACK_21f: 32 RADAR + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ 1_STATE_ALT : 25|2@0+ (1,0) [0|3] "" XXX + SG_ 1_MOTION_STATE : 29|3@0+ (1,0) [0|4] "" XXX + SG_ 1_TRACK_QUALITY : 38|7@0+ (1,0) [0|127] "" XXX + SG_ 1_AGE : 47|8@0+ (1,0) [0|255] "" XXX + SG_ 1_COAST_AGE : 51|4@0+ (1,0) [0|15] "" XXX + SG_ 1_STATE : 54|3@0+ (1,0) [0|7] "" XXX + SG_ 1_RCS : 63|8@0- (1,0) [-128|127] "" XXX + SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 1_NEW_SIGNAL_4 : 102|2@1+ (1,0) [0|2] "" XXX + SG_ 1_REL_LAT_SPEED : 104|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 1_REL_ACCEL : 118|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + SG_ 1_NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|1] "" XXX + SG_ 1_OBJECT_ID : 135|6@0+ (1,0) [0|63] "" XXX + SG_ 2_NEW_SIGNAL_18 : 137|2@0+ (1,0) [0|1] "" XXX + SG_ 2_OBJECT_ID : 143|6@0+ (1,0) [0|63] "" XXX + SG_ 2_STATE_ALT : 153|2@0+ (1,0) [0|3] "" XXX + SG_ 2_MOTION_STATE : 157|3@0+ (1,0) [0|4] "" XXX + SG_ 2_TRACK_QUALITY : 166|7@0+ (1,0) [0|127] "" XXX + SG_ 2_AGE : 175|8@0+ (1,0) [0|255] "" XXX + SG_ 2_COAST_AGE : 179|4@0+ (1,0) [0|15] "" XXX + SG_ 2_STATE : 182|3@0+ (1,0) [0|7] "" XXX + SG_ 2_RCS : 191|8@0- (1,0) [-128|127] "" XXX + SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|204.75] "m" XXX + SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [-102.4|102.35] "m" XXX + SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [-81.92|81.91] "m/s" XXX + SG_ 2_NEW_SIGNAL_4 : 230|2@1+ (1,0) [0|2] "" XXX + SG_ 2_REL_LAT_SPEED : 232|13@1- (0.01,0) [-40.96|40.95] "m/s" XXX + SG_ 2_REL_ACCEL : 246|10@1- (0.05,0) [-25.6|25.55] "m/s^2" XXX + +VAL_ 543 1_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 543 2_STATE_ALT 0 "EMPTY" 1 "TENTATIVE" 2 "MEASURED" 3 "COASTED" ; +VAL_ 543 1_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 543 2_MOTION_STATE 0 "UNKNOWN" 1 "STATIONARY" 2 "MOVING" 3 "STOPPED" 4 "ONCOMING" ; +VAL_ 543 1_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; +VAL_ 543 2_STATE 0 "EMPTY" 1 "TENTATIVE_1" 2 "TENTATIVE_2" 3 "MEASURED" 4 "COASTED" 7 "UNRESOLVED_TENTATIVE" ; + CM_ BO_ 543 "Hyundai/Kia 210-21F radar-track layout: 16 messages with two target slots per 32-byte message (32 tracks total). Two related dialects share the same position, velocity, age, coast-age, and compressed-state core. The detailed dialect also populates STATE, RCS, and NEW_SIGNAL_4; the compact Tucson/Sportage/Santa Cruz dialect leaves those fields zero and uses STATE_ALT. The dialect is independent of the logged raw bus and is not an HDA-level discriminator: HDA2-like routes carried the sustained stream on A-CAN mapped to bus 0, while non-HDA2 routes mapped A-CAN to bus 1. Compact targets populate per-slot NEW_SIGNAL_18/OBJECT_ID extension bytes at bytes 16 and 17; detailed platforms usually leave them zero. Byte 18 and bits 26, 30-31, 39, 55, and 117 remained zero. REL_LAT_SPEED has opposite sign conventions between the detailed and compact dialects. The HKG CAN-FD checksum matched every one of 13,210,543 checked frames."; +CM_ SG_ 543 1_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 543 1_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 543 1_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 543 1_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 543 1_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 543 1_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 543 1_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 543 1_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 543 1_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 543 1_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 543 1_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 543 1_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 543 1_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 543 1_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 543 1_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 543 2_STATE_ALT "Compressed lifecycle state: 0=empty, 1=tentative, 2=measured, 3=coasted."; +CM_ SG_ 543 2_MOTION_STATE "Ground-frame target-motion class: 0=unknown, 1=stationary, 2=moving, 3=stopped, and 4=oncoming. The stopped label is independently supported by related Hyundai BN7 radar and HMVS4 object DBCs. Values 3/4 were observed only on the compact dialect; the detailed dialect has no dedicated oncoming value."; +CM_ SG_ 543 2_TRACK_QUALITY "Unsigned 7-bit track quality/existence score. Detailed platforms share the same lifecycle-dependent distribution as the 3A5-3C4 layout; compact platforms use a higher calibration that falls as COAST_AGE increases. A related Hyundai object layout defines its 7-bit quality level as reliability, validity, or probability evidence; the raw radar scale is not confirmed to be a percentage."; +CM_ SG_ 543 2_AGE "Per-track alive age/lifetime count, observed 0-255. It normally increments on an update and may hold."; +CM_ SG_ 543 2_COAST_AGE "Prediction age: normally 0 while measured, then increments from 1 to 15 while coasted."; +CM_ SG_ 543 2_STATE "Detailed lifecycle state: 0=empty, 1/2=tentative acquisition, 3=measured, 4=coasted/predicted, 7=unresolved tentative. Values 5 and 6 were not observed; compact platforms leave this field zero."; +CM_ SG_ 543 2_RCS "Signed radar cross-section/return-strength value. Its distribution matches the 3A5-3C4 RCS field, and distance-controlled samples consistently increase from small to passenger to large targets. The raw unit is not calibrated; compact platforms leave it zero."; +CM_ SG_ 543 2_LONG_DIST "Longitudinal distance from the ego radar. Empty compact slots may contain the 204.75 m endpoint sentinel."; +CM_ SG_ 543 2_LAT_DIST "Lateral position relative to the ego axis."; +CM_ SG_ 543 2_REL_SPEED "Longitudinal speed relative to ego; negative means the target is moving longitudinally slower than ego."; +CM_ SG_ 543 2_NEW_SIGNAL_4 "Unknown category, observed 0-2 on detailed platforms. Compact platforms leave it zero."; +CM_ SG_ 543 2_REL_LAT_SPEED "Target lateral speed relative to the ego axis at 0.01 m/s per bit. The detailed dialect uses the decoded sign; compact platforms use the opposite sign."; +CM_ SG_ 543 2_REL_ACCEL "Target longitudinal acceleration relative to ego acceleration at 0.05 m/s^2 per bit."; +CM_ SG_ 543 2_NEW_SIGNAL_18 "Unknown compact-dialect per-target status area, observed only as 0/1; its second bit remained zero. Detailed platforms leave it zero."; +CM_ SG_ 543 2_OBJECT_ID "Strongly inferred compact-dialect persistent object identifier, observed 0-63. It held through 99.9% of consecutive same-track updates and changed when a slot acquired a replacement target. A related Hyundai BN7 radar DBC independently defines ObjectId as a global ID that remains constant while an object is tracked. Detailed platforms usually leave it zero."; +CM_ SG_ 543 CHECKSUM "16-bit HKG CAN-FD checksum using the CAN address as the data ID."; +CM_ SG_ 543 COUNTER "8-bit transmit-cycle counter. It covers 0-255 and wraps."; diff --git a/opendbc_repo/opendbc/safety/__init__.py b/opendbc_repo/opendbc/safety/__init__.py index c4621bb633..90b10c9607 100644 --- a/opendbc_repo/opendbc/safety/__init__.py +++ b/opendbc_repo/opendbc/safety/__init__.py @@ -11,3 +11,4 @@ class ALTERNATIVE_EXPERIENCE: ALWAYS_ON_LATERAL = 32 GM_REMAP_CANCEL_TO_DISTANCE = 64 + TOYOTA_AUTO_HOLD = 128 diff --git a/opendbc_repo/opendbc/safety/declarations.h b/opendbc_repo/opendbc/safety/declarations.h index 6da0763247..bfeb2a2813 100644 --- a/opendbc_repo/opendbc/safety/declarations.h +++ b/opendbc_repo/opendbc/safety/declarations.h @@ -339,6 +339,7 @@ extern bool gm_remote_start_boots_comma; #define ALT_EXP_ALWAYS_ON_LATERAL 32 #define ALT_EXP_GM_REMAP_CANCEL_TO_DISTANCE 64 +#define ALT_EXP_TOYOTA_AUTO_HOLD 128 extern int alternative_experience; diff --git a/opendbc_repo/opendbc/safety/modes/toyota.h b/opendbc_repo/opendbc/safety/modes/toyota.h index 8c9e8ad076..ab0705b88b 100644 --- a/opendbc_repo/opendbc/safety/modes/toyota.h +++ b/opendbc_repo/opendbc/safety/modes/toyota.h @@ -2,6 +2,8 @@ #include "opendbc/safety/declarations.h" +#define TOYOTA_AUTO_HOLD_ACCEL -1000 // -1.0 m/s^2 in ACC_CONTROL units + // Stock longitudinal #define TOYOTA_BASE_TX_MSGS \ {0x191, 0, 8, .check_relay = true}, {0x412, 0, 8, .check_relay = true}, {0x1D2, 0, 8, .check_relay = false}, /* LKAS + LTA + PCM cancel cmd */ \ @@ -277,7 +279,15 @@ static bool toyota_tx_hook(const CANPacket_t *msg) { // SecOC cars move accel to 0x183. Only allow inactive accel on 0x343 to match stock behavior violation = desired_accel != TOYOTA_LONG_LIMITS.inactive_accel; } - violation |= longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS); + + bool toyota_auto_hold = + !toyota_stock_longitudinal && + ((alternative_experience & ALT_EXP_TOYOTA_AUTO_HOLD) != 0) && + !vehicle_moving && !gas_pressed && acc_main_on && + (desired_accel == TOYOTA_AUTO_HOLD_ACCEL) && + GET_BIT(msg, 30U) && !GET_BIT(msg, 31U) && !GET_BIT(msg, 24U); + + violation |= !toyota_auto_hold && longitudinal_accel_checks(desired_accel, TOYOTA_LONG_LIMITS); // only ACC messages that cancel are allowed when openpilot is not controlling longitudinal if (toyota_stock_longitudinal) { @@ -394,12 +404,7 @@ static bool toyota_tx_hook(const CANPacket_t *msg) { tx = false; } - // Auto brake hold replaces the camera AEB message only while stopped. - if ((msg->addr == 0x344U) && ((alternative_experience & ALT_EXP_ALLOW_AEB) != 0)) { - if (vehicle_moving || gas_pressed || !acc_main_on) { - tx = false; - } - } else if ((msg->addr == 0x344U) && toyota_stock_longitudinal) { + if ((msg->addr == 0x344U) && toyota_stock_longitudinal) { tx = false; } } @@ -566,21 +571,11 @@ static safety_config toyota_init(uint16_t param) { return ret; } -static bool toyota_fwd_hook(int bus_num, int addr) { - bool block_msg = false; - if (bus_num == 2) { - block_msg = (addr == 0x344) && ((alternative_experience & ALT_EXP_ALLOW_AEB) != 0) && - !vehicle_moving && !gas_pressed && acc_main_on; - } - return block_msg; -} - const safety_hooks toyota_hooks = { .init = toyota_init, .rx = toyota_rx_hook, .rx_all = toyota_rx_all_hook, .tx = toyota_tx_hook, - .fwd = toyota_fwd_hook, .get_checksum = toyota_get_checksum, .compute_checksum = toyota_compute_checksum, .get_quality_flag_valid = toyota_get_quality_flag_valid, diff --git a/opendbc_repo/opendbc/safety/modes/volvo.h b/opendbc_repo/opendbc/safety/modes/volvo.h index e1a11676a1..f54906200c 100644 --- a/opendbc_repo/opendbc/safety/modes/volvo.h +++ b/opendbc_repo/opendbc/safety/modes/volvo.h @@ -2,9 +2,11 @@ #include "opendbc/safety/declarations.h" -// safetyParam: 0 = CMA (XC40 Recharge), 1 = SPA (S60 Recharge, Polestar 2) +// safetyParam: 0 = CMA (XC40 Recharge), 1 = SPA (S60 Recharge, Polestar 2), +// 2 = C1 (V40) // Polestar 2 is technically CMA, but appears to use SPA DBC for CAN 1 bus #define VOLVO_FLAG_SPA 1U +#define VOLVO_FLAG_C1 2U // Volvo CAN message addresses shared between CMA and SPA #define VOLVO_LCA_STEER 0x58U // TX from VCU1 to PSCM, LCA steering command (0x58) @@ -24,6 +26,15 @@ #define VOLVO_LCA_6 0x97U // TX LCA_6 message #define VOLVO_LCA_7 0x92U // TX LCA_7 message +// C1-specific addresses (V40). The V40 powertrain bus is bus 0 and its +// forward-camera bus is bus 2; bus 1 is unused by this port. +#define VOLVO_C1_BUTTONS 0x10U +#define VOLVO_C1_FSM_0 0x30U +#define VOLVO_C1_FSM_1 0xD0U +#define VOLVO_C1_PSCM_1 0x125U +#define VOLVO_C1_PEDAL_AND_BRAKE 0x55U +#define VOLVO_C1_SPEED 0x150U + // CMA-specific PT bus addresses #define VOLVO_CMA_BUS1_SPEED 0x70U // RX vehicle speed #define VOLVO_CMA_ECM_1 0x250U // RX accelerator pedal position @@ -44,6 +55,10 @@ #define VOLVO_MAX_ANGLE_CAN 9650 #define VOLVO_RELAY_ANGLE_TOLERANCE 54 // approximately 3 degrees +#define VOLVO_C1_ANGLE_DEG_TO_CAN 22.753128f +#define VOLVO_C1_MAX_ANGLE_CAN 8189 +#define VOLVO_C1_RELAY_ANGLE_TOLERANCE 2 + // CAN bus definitions for Volvo // Using same naming as carstate.py for consistency: main, pt, party @@ -54,6 +69,7 @@ // Runtime addresses set by volvo_init based on safetyParam static uint16_t volvo_ecm_1_addr; static uint16_t volvo_bus1_cruise_control_addr; +static bool volvo_c1; static int volvo_be_15(const CANPacket_t *msg, uint8_t byte) { return (int)(((uint16_t)(msg->data[byte] & 0x7FU) << 8U) | msg->data[byte + 1U]); @@ -67,6 +83,21 @@ static int volvo_lca_5_angle(const CANPacket_t *msg) { return to_signed(volvo_be_15(msg, 6U), 15); } +static int volvo_c1_pscm_angle(const CANPacket_t *msg) { + return (int)(((uint16_t)msg->data[5] << 8U) | msg->data[6]) - 32768; +} + +static int volvo_c1_fsm_angle(const CANPacket_t *msg) { + return (int)(((uint16_t)(msg->data[4] & 0x3FU) << 8U) | msg->data[5]) - 8192; +} + +static uint8_t volvo_c1_fsm_checksum(const CANPacket_t *msg) { + const uint16_t angle_raw = ((uint16_t)(msg->data[4] & 0x3FU) << 8U) | msg->data[5]; + const uint8_t direction = msg->data[7] & 0x3U; + const uint8_t checksum_sum = (msg->data[3] + direction + angle_raw + (angle_raw >> 8U)) & 0xFFU; + return checksum_sum ^ 0xFFU; +} + static const AngleSteeringLimits VOLVO_ANGLE_STEERING_LIMITS = { .max_angle = VOLVO_MAX_ANGLE_CAN, .angle_deg_to_can = VOLVO_ANGLE_DEG_TO_CAN, @@ -81,8 +112,51 @@ static const AngleSteeringLimits VOLVO_ANGLE_STEERING_LIMITS = { .frequency = 50U, }; +static const AngleSteeringLimits VOLVO_C1_ANGLE_STEERING_LIMITS = { + .max_angle = VOLVO_C1_MAX_ANGLE_CAN, + .angle_deg_to_can = VOLVO_C1_ANGLE_DEG_TO_CAN, + .angle_rate_up_lookup = { + {7.0f, 17.0f, 36.0f}, + {2.0f, 0.25f, 0.1f}, + }, + .angle_rate_down_lookup = { + {7.0f, 17.0f, 36.0f}, + {2.0f, 0.25f, 0.1f}, + }, + .max_angle_error = 455, // 20 degrees + .angle_error_min_speed = 0.0f, + .frequency = 50U, + .enforce_angle_error = true, +}; + static void volvo_rx_hook(const CANPacket_t *msg) { + if (volvo_c1) { + if (msg->bus == VOLVO_MAIN_BUS) { + if (msg->addr == VOLVO_C1_PSCM_1) { + update_sample(&angle_meas, volvo_c1_pscm_angle(msg)); + } + + if (msg->addr == VOLVO_C1_SPEED) { + const uint16_t speed_raw = ((uint16_t)msg->data[6] << 8U) | msg->data[7]; + const float speed = ((float)speed_raw * 0.01f) / 3.6f; + vehicle_moving = speed > 0.1f; + UPDATE_VEHICLE_SPEED(speed); + } + + if (msg->addr == VOLVO_C1_PEDAL_AND_BRAKE) { + const uint16_t gas_raw = ((uint16_t)(msg->data[1] & 0x3U) << 8U) | msg->data[2]; + gas_pressed = gas_raw > 50U; // DBC factor 0.1: greater than 5 percent + brake_pressed = GET_BIT(msg, 24U) || GET_BIT(msg, 38U); + } + } + + if ((msg->bus == VOLVO_PARTY_BUS) && (msg->addr == VOLVO_C1_FSM_0)) { + pcm_cruise_check(GET_BIT(msg, 58U)); + } + return; + } + // Main bus (bus 0) messages if (msg->bus == VOLVO_MAIN_BUS) { // Update brake pedal and cruise state from BCM2 @@ -158,6 +232,33 @@ static void volvo_rx_hook(const CANPacket_t *msg) { static bool volvo_tx_hook(const CANPacket_t *msg) { bool tx = true; + if (volvo_c1) { + if (msg->addr == VOLVO_C1_FSM_1) { + const int desired_angle = volvo_c1_fsm_angle(msg); + const uint8_t direction = msg->data[7] & 0x3U; + const bool steer_control_enabled = direction != 0U; + tx &= SAFETY_ABS(desired_angle) <= VOLVO_C1_MAX_ANGLE_CAN; + tx &= !steer_angle_cmd_checks(desired_angle, steer_control_enabled, VOLVO_C1_ANGLE_STEERING_LIMITS); + tx &= (direction == 0U) || (direction == 3U); + tx &= (msg->data[0] == 0xE3U) && (msg->data[1] == 0xB4U) && (msg->data[2] == 0x08U); + tx &= (msg->data[3] == 0x80U) && ((msg->data[4] & 0xC0U) == 0x80U) && ((msg->data[7] & 0xFCU) == 0x94U); + tx &= msg->data[6] == volvo_c1_fsm_checksum(msg); + } + + if (msg->addr == VOLVO_C1_PSCM_1) { + const int relayed_angle = volvo_c1_pscm_angle(msg); + const int measured_max = angle_meas.max + VOLVO_C1_RELAY_ANGLE_TOLERANCE; + const int measured_min = angle_meas.min - VOLVO_C1_RELAY_ANGLE_TOLERANCE; + tx &= !safety_max_limit_check(relayed_angle, measured_max, measured_min); + } + + // Only ACC cancel (byte 7 bit 4) may be synthesized. + if (msg->addr == VOLVO_C1_BUTTONS) { + tx &= ((msg->data[7] & 0xEFU) == 0U) && (msg->data[6] == 0U); + } + return tx; + } + // LCA_5 carries the actual angle command used by the controller. The stock // LCA frame also contains an angle-shaped field, but the imported controller // deliberately leaves that field at the observed vehicle value. @@ -255,6 +356,22 @@ static bool volvo_tx_hook(const CANPacket_t *msg) { static safety_config volvo_init(uint16_t param) { bool spa = GET_FLAG(param, VOLVO_FLAG_SPA); + volvo_c1 = GET_FLAG(param, VOLVO_FLAG_C1); + + if (volvo_c1) { + static const CanMsg VOLVO_C1_TX_MSGS[] = { + {VOLVO_C1_FSM_1, VOLVO_MAIN_BUS, 8, .check_relay = true}, + {VOLVO_C1_PSCM_1, VOLVO_PARTY_BUS, 8, .check_relay = true}, + {VOLVO_C1_BUTTONS, VOLVO_MAIN_BUS, 8, .check_relay = false}, + }; + static RxCheck volvo_c1_rx_checks[] = { + {.msg = {{VOLVO_C1_PSCM_1, VOLVO_MAIN_BUS, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, + {.msg = {{VOLVO_C1_FSM_0, VOLVO_PARTY_BUS, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, + {.msg = {{VOLVO_C1_PEDAL_AND_BRAKE, VOLVO_MAIN_BUS, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, + {.msg = {{VOLVO_C1_SPEED, VOLVO_MAIN_BUS, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, + }; + return BUILD_SAFETY_CFG(volvo_c1_rx_checks, VOLVO_C1_TX_MSGS); + } // Set PT bus addresses based on platform volvo_ecm_1_addr = spa ? VOLVO_SPA_ECM_1 : VOLVO_CMA_ECM_1; diff --git a/opendbc_repo/opendbc/safety/tests/test_toyota.py b/opendbc_repo/opendbc/safety/tests/test_toyota.py index 8a2beba248..55f75a66ed 100644 --- a/opendbc_repo/opendbc/safety/tests/test_toyota.py +++ b/opendbc_repo/opendbc/safety/tests/test_toyota.py @@ -97,29 +97,55 @@ class TestToyotaSafetyBase(common.CarSafetyTest, common.LongitudinalAccelSafetyT msg = libsafety_py.make_CANPacket(0x283, 0, bytes(dat)) self.assertEqual(not bad and not stock_longitudinal, self._tx(msg)) - def test_auto_brake_hold_aeb_replacement_only_at_standstill(self): - self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.ALLOW_AEB) - hold_msg = libsafety_py.make_CANPacket(0x344, 0, b"\xfd\x80\x00\x00\x00\x00\x00\xcc") + def test_auto_hold_acc_control_is_narrowly_allowed_only_at_standstill(self): + if (not self.LONGITUDINAL or + self.safety.get_current_safety_param() & (ToyotaSafetyFlags.STOCK_LONGITUDINAL.value | ToyotaSafetyFlags.SECOC.value)): + raise unittest.SkipTest("Toyota Auto Hold requires non-SecOC openpilot longitudinal control") + + self.safety.set_alternative_experience(ALTERNATIVE_EXPERIENCE.TOYOTA_AUTO_HOLD) + hold_msg = self.packer.make_can_msg_safety("ACC_CONTROL", 0, { + "ACCEL_CMD": -1.0, + "PERMIT_BRAKING": 1, + "RELEASE_STANDSTILL": 0, + "CANCEL_REQ": 0, + }) self._rx(self._speed_msg(0)) self._rx(self._toggle_aol(True)) self._rx(self._user_gas_msg(False)) + self.safety.set_controls_allowed(False) self.assertTrue(self._tx(hold_msg)) - self.assertEqual(-1, self.safety.safety_fwd_hook(2, 0x344)) + + self.assertFalse(self._tx(self.packer.make_can_msg_safety("ACC_CONTROL", 0, { + "ACCEL_CMD": -1.1, + "PERMIT_BRAKING": 1, + "RELEASE_STANDSTILL": 0, + }))) self._rx(self._speed_msg(1.0)) self.assertFalse(self._tx(hold_msg)) - self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344)) self._rx(self._speed_msg(0)) self._rx(self._user_gas_msg(True)) self.assertFalse(self._tx(hold_msg)) - self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344)) self._rx(self._user_gas_msg(False)) self._rx(self._toggle_aol(False)) self.assertFalse(self._tx(hold_msg)) - self.assertEqual(0, self.safety.safety_fwd_hook(2, 0x344)) + + def test_auto_hold_acc_control_is_blocked_without_toyota_hold_toggle(self): + hold_msg = self.packer.make_can_msg_safety("ACC_CONTROL", 0, { + "ACCEL_CMD": -1.0, + "PERMIT_BRAKING": 1, + "RELEASE_STANDSTILL": 0, + "CANCEL_REQ": 0, + }) + self._rx(self._speed_msg(0)) + self._rx(self._toggle_aol(True)) + self._rx(self._user_gas_msg(False)) + self.safety.set_controls_allowed(False) + self.safety.set_alternative_experience(0) + self.assertFalse(self._tx(hold_msg)) # Only allow LTA msgs with no actuation def test_lta_steer_cmd(self): diff --git a/opendbc_repo/opendbc/safety/tests/test_volvo.py b/opendbc_repo/opendbc/safety/tests/test_volvo.py index 43b9ae192c..cabbadbb2a 100644 --- a/opendbc_repo/opendbc/safety/tests/test_volvo.py +++ b/opendbc_repo/opendbc/safety/tests/test_volvo.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -Safety tests for Volvo CMA/SPA. +Safety tests for Volvo C1/CMA/SPA. The safety mode lives at ``opendbc/safety/modes/volvo.h`` and is parameterized by ``safetyParam``: @@ -8,14 +8,13 @@ by ``safetyParam``: - ``safetyParam == 0`` → CMA platform (Volvo XC40 Recharge) - ``safetyParam == VOLVO_FLAG_SPA`` → SPA platform (Volvo S60 Recharge, Polestar 2) + - ``safetyParam == VOLVO_FLAG_C1`` → C1 platform (Volvo V40) -The two platforms share LCA/PSCM/etc. addresses on the main and party buses -but use *different* PT-bus addresses and signal scales for ECM_1 and -BUS1_CRUISE_CONTROL. Vehicle speed is read from main-bus SPEED on both, so it -is not platform-dependent. This test file exercises both platforms through the -same generic ``CarSafetyTest`` harness so that any future divergence between -``carstate.py`` and ``volvo.h`` — e.g. a threshold drifting out of sync — is -caught on a laptop instead of in the car. +CMA and SPA share LCA/PSCM/etc. addresses on the main and party buses but use +different PT-bus addresses and signal scales. C1 uses the V40's legacy CAN +layout and its own safety allowlist. The tests exercise all three through the +generic ``CarSafetyTest`` harness so divergence between ``carstate.py`` and +``volvo.h`` is caught before running in a car. Companion to: ``opendbc/car/volvo/carstate.py`` (must agree on thresholds). """ @@ -25,13 +24,16 @@ import re import unittest from opendbc.car.volvo.interface import SAFETY_VOLVO +from opendbc.car.volvo.values import VolvoSafetyFlags +from opendbc.car.volvo.volvocan import create_c1_checksum, create_c1_steering_control from opendbc.safety.tests.libsafety import libsafety_py import opendbc.safety.tests.common as common from opendbc.safety.tests.common import CANPackerSafety -# Must match VOLVO_FLAG_SPA in opendbc/safety/modes/volvo.h -VOLVO_FLAG_SPA = 1 +# Must match the flags in opendbc/safety/modes/volvo.h +VOLVO_FLAG_SPA = VolvoSafetyFlags.SPA.value +VOLVO_FLAG_C1 = VolvoSafetyFlags.C1.value # Must match VOLVO_SPEED_TO_MS in volvo.h and SPEED_TO_MS in carstate.py VOLVO_SPEED_TO_MS = 0.003977 @@ -332,5 +334,124 @@ class TestVolvoSPA(TestVolvoSafetyBase): "BUS1_CRUISE_CONTROL", VOLVO_PT_BUS, values) +class TestVolvoC1(common.CarSafetyTest, common.AngleSteeringSafetyTest): + TX_MSGS = [[0xD0, VOLVO_MAIN_BUS], [0x125, VOLVO_PARTY_BUS], [0x10, VOLVO_MAIN_BUS]] + RELAY_MALFUNCTION_ADDRS = { + VOLVO_MAIN_BUS: (0xD0,), + VOLVO_PARTY_BUS: (0x125,), + } + FWD_BLACKLISTED_ADDRS = { + VOLVO_MAIN_BUS: [0x125], + VOLVO_PARTY_BUS: [0xD0], + } + STANDSTILL_THRESHOLD = 0.1 + GAS_PRESSED_THRESHOLD = 5.0 + + STEER_ANGLE_MAX = 359.9 + STEER_ANGLE_TEST_MAX = 350.0 + DEG_TO_CAN = 1 / 0.04395 + ANGLE_RATE_BP = [7.0, 17.0, 36.0] + ANGLE_RATE_UP = [2.0, 0.25, 0.1] + ANGLE_RATE_DOWN = [2.0, 0.25, 0.1] + + def setUp(self): + self.packer = CANPackerSafety("volvo_v40_2017_pt") + self.safety = libsafety_py.libsafety + self.safety.set_safety_hooks(SAFETY_VOLVO, VOLVO_FLAG_C1) + self.safety.init_tests() + + def _angle_cmd_msg(self, angle: float, enabled: bool, increment_timer: bool = True): + values = { + "SET_X_E3": 0xE3, + "SET_X_B4": 0xB4, + "SET_X_08": 0x08, + "LKAAngleReq": angle, + "LKASteerDirection": 3 if enabled else 0, + "TrqLim": 0, + "SET_X_25": 0x25, + "SET_X_02": 0x02, + } + + def fix_checksum(msg): + address, data, bus = msg + data = bytearray(data) + data[6] = create_c1_checksum(data) + return address, data, bus + + return self.packer.make_can_msg_safety("FSM1", VOLVO_MAIN_BUS, values, fix_checksum) + + def _angle_meas_msg(self, angle: float): + return self.packer.make_can_msg_safety( + "PSCM1", VOLVO_MAIN_BUS, {"SteeringAngleServo": angle}) + + def _speed_msg(self, speed): + return self.packer.make_can_msg_safety( + "VehicleSpeed1", VOLVO_MAIN_BUS, {"VehicleSpeed": speed * 3.6}) + + def _speed_msg_2(self, speed): + return None + + def _user_brake_msg(self, brake): + return self.packer.make_can_msg_safety( + "PedalandBrake", VOLVO_MAIN_BUS, {"BrakePedalActive2": bool(brake)}) + + def _user_gas_msg(self, gas): + return self.packer.make_can_msg_safety( + "PedalandBrake", VOLVO_MAIN_BUS, {"AccPedal": gas}) + + def _pcm_status_msg(self, enable): + return self.packer.make_can_msg_safety( + "FSM0", VOLVO_PARTY_BUS, {"ACCStatusActive": bool(enable)}) + + def test_cancel_button_only(self): + allowed = self.packer.make_can_msg_safety( + "CCButtons", VOLVO_MAIN_BUS, {"ACCStopBtn": 1}) + self.assertTrue(self._tx(allowed)) + + for signal in ("ACCOnOffBtn", "ACCSetBtn", "ACCResumeBtn", "ACCMinusBtn", + "TimeGapIncreaseBtn", "TimeGapDecreaseBtn"): + msg = self.packer.make_can_msg_safety("CCButtons", VOLVO_MAIN_BUS, {signal: 1}) + self.assertFalse(self._tx(msg), signal) + + def test_pscm_relay_cannot_invent_angle(self): + for _ in range(common.MAX_SAMPLE_VALS): + self._rx(self._angle_meas_msg(10)) + valid = self.packer.make_can_msg_safety( + "PSCM1", VOLVO_PARTY_BUS, {"SteeringAngleServo": 10}) + invalid = self.packer.make_can_msg_safety( + "PSCM1", VOLVO_PARTY_BUS, {"SteeringAngleServo": 20}) + self.assertTrue(self._tx(valid)) + self.assertFalse(self._tx(invalid)) + + def test_pscm_relay_preserves_full_lock_angle(self): + for angle in (-720, 500): + for _ in range(common.MAX_SAMPLE_VALS): + self._rx(self._angle_meas_msg(angle)) + relayed = self.packer.make_can_msg_safety( + "PSCM1", VOLVO_PARTY_BUS, {"SteeringAngleServo": angle}) + self.assertTrue(self._tx(relayed), angle) + + def test_steering_static_fields_and_checksum(self): + self.safety.set_controls_allowed(True) + self._reset_angle_measurement(0) + self._reset_speed_measurement(10) + self._set_prev_desired_angle(0) + valid = self._angle_cmd_msg(0, True) + self.assertTrue(self._tx(valid)) + + for byte_index in (0, 1, 2, 3, 4, 6, 7): + invalid = self._angle_cmd_msg(0, True) + invalid[0].data[byte_index] ^= 0x4 if byte_index in (4, 7) else 0x1 + self.assertFalse(self._tx(invalid), byte_index) + + def test_controller_steering_message_is_allowed(self): + self.safety.set_controls_allowed(True) + self._reset_angle_measurement(0) + self._reset_speed_measurement(10) + self._set_prev_desired_angle(0) + address, data, bus = create_c1_steering_control(self.packer, 0, True) + self.assertTrue(self._tx(libsafety_py.make_CANPacket(address, bus, data))) + + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index ecab7094ee..3174fac494 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -652,9 +652,6 @@ class Controls: elif CC.latActive and CS.steeringPressed and CS.steeringTorque * blinker_dir < 0.0 and \ self.curvature * blinker_dir > CURVATURE_HOLD_CONFIRM_MIN and \ self.turn_blinker_swept < CURVATURE_HOLD_CONFIRM_SWEPT: - # an active driver push into the signaled turn BEFORE the turn is made is fresh - # turn intent: re-arm the cycle even after a prior handoff. A long blinker-on - # approach can latch done on a trivial micro-handoff and lock out # nudge-to-commit ten seconds later at the real turn (0000087f seg 1: +418 haul # unassisted). The swept gate keeps a light same-direction touch during the # EXIT unwind from re-latching a large hold against the model's recentering diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 32156cef7b..9094e12ae1 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -632,6 +632,9 @@ class LatControlTorque(LatControl): output_torque *= get_kia_ev6_center_output_scale(setpoint, CS.vEgo) elif kia_carnival_active: output_torque *= kia_carnival_center_taper + output_torque *= get_kia_carnival_unwind_output_scale( + setpoint, measurement, desired_lateral_jerk, CS.vEgo, + ) output_torque *= get_kia_carnival_highway_transition_output_scale(setpoint, desired_lateral_jerk, CS.vEgo) elif palisade_active: output_torque *= get_palisade_center_output_scale(setpoint, CS.vEgo) diff --git a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py index f8235b7678..e7ebd21539 100644 --- a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py +++ b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py @@ -314,7 +314,7 @@ GENESIS_G70_LOW_SPEED_OUTPUT_LIMIT_LAT = 0.14 GENESIS_G70_LOW_SPEED_OUTPUT_LIMIT_LAT_WIDTH = 0.05 GENESIS_G70_LOW_SPEED_OUTPUT_LIMIT_SPEED = 6.0 GENESIS_G70_LOW_SPEED_OUTPUT_LIMIT_SPEED_WIDTH = 1.5 -GENESIS_G70_CURVE_UNWIND_OUTPUT_REDUCTION_MAX = 0.08 +GENESIS_G70_CURVE_UNWIND_OUTPUT_REDUCTION_MAX = 0.10 GENESIS_G70_CURVE_UNWIND_SPEED = 18.0 GENESIS_G70_CURVE_UNWIND_SPEED_WIDTH = 3.0 GENESIS_G70_CURVE_UNWIND_LAT = 0.25 @@ -629,6 +629,15 @@ KIA_CARNIVAL_UNWIND_FF_OVERSHOOT = 0.08 KIA_CARNIVAL_UNWIND_FF_OVERSHOOT_WIDTH = 0.06 KIA_CARNIVAL_UNWIND_FF_JERK = 0.45 KIA_CARNIVAL_UNWIND_FF_JERK_WIDTH = 0.20 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_MAX = 0.28 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED = 8.0 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_WIDTH = 2.0 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_CUTOFF = 16.0 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_CUTOFF_WIDTH = 2.5 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_OVERSHOOT = 0.25 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_OVERSHOOT_WIDTH = 0.15 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_JERK = 0.45 +KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_JERK_WIDTH = 0.20 TUCSON_4TH_GEN_CENTER_TAPER_MAX = 0.44 TUCSON_4TH_GEN_CENTER_TAPER_LAT = 0.28 @@ -2854,6 +2863,27 @@ def get_kia_carnival_unwind_ff_scale(setpoint: float, measured_lateral_accel: fl return 1.0 - (KIA_CARNIVAL_UNWIND_FF_REDUCTION_MAX * speed_weight * overshoot_weight * jerk_weight) +def get_kia_carnival_unwind_output_scale(setpoint: float, measured_lateral_accel: float, + desired_lateral_jerk: float, v_ego: float) -> float: + if (setpoint * desired_lateral_jerk >= 0.0 or + setpoint * measured_lateral_accel <= 0.0): + return 1.0 + + overshoot = max(abs(measured_lateral_accel) - abs(setpoint), 0.0) + if overshoot <= 0.0: + return 1.0 + + speed_weight = (_sigmoid((v_ego - KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED) / + KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_WIDTH) * + _sigmoid((KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_CUTOFF - v_ego) / + KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_SPEED_CUTOFF_WIDTH)) + overshoot_weight = _sigmoid((overshoot - KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_OVERSHOOT) / + KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_OVERSHOOT_WIDTH) + jerk_weight = _sigmoid((abs(desired_lateral_jerk) - KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_JERK) / + KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_JERK_WIDTH) + return 1.0 - (KIA_CARNIVAL_UNWIND_OUTPUT_DAMPING_MAX * speed_weight * overshoot_weight * jerk_weight) + + def _tucson_4th_gen_center_weights(desired_lateral_accel: float, v_ego: float) -> tuple[float, float]: speed_weight = _sigmoid((TUCSON_4TH_GEN_CENTER_TAPER_SPEED_MAX - v_ego) / TUCSON_4TH_GEN_CENTER_TAPER_SPEED_WIDTH) center_weight = _sigmoid((TUCSON_4TH_GEN_CENTER_TAPER_LAT - abs(desired_lateral_accel)) / TUCSON_4TH_GEN_CENTER_TAPER_LAT_WIDTH) @@ -3126,8 +3156,6 @@ def get_genesis_gv70_unwind_ff_scale(setpoint: float, measured_lateral_accel: fl return 1.0 overshoot = max(abs(measured_lateral_accel) - abs(setpoint), 0.0) - if overshoot <= 0.0: - return 1.0 overshoot_weight = _sigmoid((overshoot - GENESIS_GV70_UNWIND_FF_OVERSHOOT) / GENESIS_GV70_UNWIND_FF_OVERSHOOT_WIDTH) jerk_weight = _sigmoid((abs(desired_lateral_jerk) - GENESIS_GV70_UNWIND_FF_JERK) / diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 549a1ae2f7..f325d32637 100644 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -38,6 +38,10 @@ HONDA_BOSCH_A_CHALLENGER_STALE_CYCLES = 2 HONDA_BOSCH_A_GROSS_DISTANCE_STALE_CYCLES = 3 HONDA_BOSCH_A_GROSS_DISTANCE_M = 25.0 +POST_STANDSTILL_RADAR_LEAD_PERSISTENCE_FRAMES = 3 +POST_STANDSTILL_RADAR_LEAD_URGENT_TTC = 1.5 +POST_STANDSTILL_RADAR_LEAD_URGENT_DISTANCE = 1.5 + def is_bosch_a_radar_car(CP) -> bool: return CP.brand == "honda" and CP.carFingerprint in HONDA_BOSCH_A and not CP.radarUnavailable @@ -242,10 +246,17 @@ def g90_low_speed_radar_lead_sane(track: Track, v_ego: float) -> bool: def honda_bosch_a_low_speed_radar_lead_sane(track: Track, v_ego: float) -> bool: - """Require a few real Bosch sweeps before a radar-only low-speed takeover.""" return track.cnt >= HONDA_BOSCH_A_LOW_SPEED_MIN_COUNT and track.potential_low_speed_lead(v_ego) +def post_standstill_radar_lead_is_urgent(lead: dict[str, Any]) -> bool: + d_rel = float(lead.get("dRel", math.inf)) + v_rel = float(lead.get("vRel", 0.0)) + closing_speed = max(-v_rel, 0.0) + ttc = d_rel / closing_speed if closing_speed > 0.1 else math.inf + return d_rel <= POST_STANDSTILL_RADAR_LEAD_URGENT_DISTANCE or ttc <= POST_STANDSTILL_RADAR_LEAD_URGENT_TTC + + def track_matches_vision(track: Track, lead: capnp._DynamicStructReader, v_ego: float, *, dist_scale: float, dist_floor: float, vel_limit: float, y_std_scale: float, y_floor: float) -> bool: @@ -454,6 +465,11 @@ class RadarD: self.preferred_stale_track_ids = [-1, -1] self.preferred_challenger_stale_counts = [0, 0] self.preferred_gross_distance_stale_counts = [0, 0] + self._was_standstill = False + self._standstill_had_lead = False + self._post_standstill_gate_active = False + self._post_standstill_candidate_id = -1 + self._post_standstill_candidate_frames = 0 self.v_ego = 0.0 self.v_ego_hist = deque([0.0], maxlen=int(round(delay / DT_MDL)) + 1) @@ -525,9 +541,57 @@ class RadarD: self.prev_lead_track_ids[lead_index] = -1 self._reset_preferred_stale_evidence(lead_index) + def _prepare_post_standstill_gate(self, standstill: bool) -> None: + if standstill: + self._post_standstill_gate_active = False + self._post_standstill_candidate_id = -1 + self._post_standstill_candidate_frames = 0 + elif self._was_standstill and not self._standstill_had_lead: + self._post_standstill_gate_active = True + self._post_standstill_candidate_id = -1 + self._post_standstill_candidate_frames = 0 + + def _filter_post_standstill_lead(self, lead: dict[str, Any]) -> dict[str, Any]: + if not self._post_standstill_gate_active: + return lead + + model_lead = float(lead.get("modelProb", 0.0)) > float( + getattr(self.starpilot_toggles, "lead_detection_probability", 0.35)) + radar_only = bool(lead.get("status", False) and lead.get("radar", False) and not model_lead) + if not radar_only: + if lead.get("status", False): + self._post_standstill_gate_active = False + self._post_standstill_candidate_id = -1 + self._post_standstill_candidate_frames = 0 + return lead + + track_id = int(lead.get("radarTrackId", -1)) + if track_id == self._post_standstill_candidate_id: + self._post_standstill_candidate_frames += 1 + else: + self._post_standstill_candidate_id = track_id + self._post_standstill_candidate_frames = 1 + + persistent = self._post_standstill_candidate_frames >= POST_STANDSTILL_RADAR_LEAD_PERSISTENCE_FRAMES + if persistent or post_standstill_radar_lead_is_urgent(lead): + self._post_standstill_gate_active = False + return lead + + return {"status": False} + + def _remember_post_standstill_state(self, standstill: bool, lead_status: bool) -> None: + if standstill: + self._was_standstill = True + self._standstill_had_lead |= lead_status + else: + self._was_standstill = False + self._standstill_had_lead = False + def update(self, sm: messaging.SubMaster, rr: car.RadarData): self.ready = sm.seen['modelV2'] self.current_time = 1e-9 * max(sm.logMonoTime.values()) + standstill = bool(sm['carState'].standstill) + self._prepare_post_standstill_gate(standstill) if sm.recv_frame['carState'] != self.last_v_ego_frame: self.v_ego = sm['carState'].vEgo @@ -585,11 +649,12 @@ class RadarD: self._update_honda_bosch_a_preferred_staleness(i, leads_v3[i], self.lead_prob_filters[i].x) - self.radar_state.leadOne = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[0], model_v_ego, sm['modelV2'], - sm['carState'].standstill, sm['starpilotPlan'], self.starpilot_toggles, low_speed_override=True, - g90_radar_filter=self.g90_radar_filter, lead_prob=self.lead_prob_filters[0].x, - preferred_track_id=self.prev_lead_track_ids[0], - honda_bosch_a_radar=self.honda_bosch_a_radar) + lead_one = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[0], model_v_ego, sm['modelV2'], + standstill, sm['starpilotPlan'], self.starpilot_toggles, low_speed_override=True, + g90_radar_filter=self.g90_radar_filter, lead_prob=self.lead_prob_filters[0].x, + preferred_track_id=self.prev_lead_track_ids[0], + honda_bosch_a_radar=self.honda_bosch_a_radar) + self.radar_state.leadOne = self._filter_post_standstill_lead(lead_one) self.radar_state.leadTwo = get_lead(self.v_ego, self.ready, self.tracks, leads_v3[1], model_v_ego, sm['modelV2'], sm['carState'].standstill, sm['starpilotPlan'], self.starpilot_toggles, low_speed_override=False, g90_radar_filter=self.g90_radar_filter, lead_prob=self.lead_prob_filters[1].x, @@ -616,6 +681,8 @@ class RadarD: if self.ready: self.starpilot_radar_state.adjacentStopped = get_adjacent_stopped(self.tracks, sm['modelV2']) + self._remember_post_standstill_state(standstill, bool(self.radar_state.leadOne.status)) + self.starpilot_toggles = get_starpilot_toggles(sm) def publish(self, pm: messaging.PubMaster): diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 22c67822cf..358757eeb6 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -161,6 +161,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import ( get_kia_carnival_friction_threshold, get_kia_carnival_highway_transition_output_scale, get_kia_carnival_unwind_ff_scale, + get_kia_carnival_unwind_output_scale, get_kia_stinger_2022_center_taper_scale, get_kia_stinger_2022_friction_threshold, get_tucson_4th_gen_center_taper_scale, @@ -742,6 +743,17 @@ class TestLatControl: low_speed_exit = get_kia_carnival_unwind_ff_scale(0.31, 0.43, -0.88, 11.0) assert low_speed_exit < 0.90 + def test_kia_carnival_unwind_output_scale_is_bounded_and_phase_gated(self): + steady_turn = get_kia_carnival_unwind_output_scale(0.80, 0.90, 0.60, 11.0) + clean_unwind = get_kia_carnival_unwind_output_scale(0.20, 0.20, -1.5, 11.0) + overshooting_unwind = get_kia_carnival_unwind_output_scale(0.20, 0.90, -1.5, 11.0) + high_speed_overshoot = get_kia_carnival_unwind_output_scale(0.20, 0.90, -1.5, 25.0) + + assert steady_turn == pytest.approx(1.0) + assert clean_unwind == pytest.approx(1.0) + assert 0.70 < overshooting_unwind < 1.0 + assert high_speed_overshoot > overshooting_unwind + def test_genesis_g90_ff_scale_curve(self): assert get_genesis_g90_ff_scale(0.0, 0.0, 20.0) == 1.0 assert get_genesis_g90_ff_scale(0.5, 0.0, 20.0) > get_genesis_g90_ff_scale(-0.5, 0.0, 20.0) @@ -771,9 +783,13 @@ class TestLatControl: assert base > left_unwind > right_unwind def test_genesis_gv70_unwind_ff_scale(self): - assert get_genesis_gv70_unwind_ff_scale(-0.3, -0.3, 0.8, 15.0) == 1.0 + steady_unwind = get_genesis_gv70_unwind_ff_scale(-0.3, -0.3, 0.8, 15.0) + assert steady_unwind < 1.0 assert get_genesis_gv70_unwind_ff_scale(-0.3, 0.1, 0.8, 15.0) == 1.0 + assert get_genesis_gv70_unwind_ff_scale(-0.3, -0.3, -0.8, 15.0) == 1.0 + early_unwind = get_genesis_gv70_unwind_ff_scale(-0.7, -0.6, 0.8, 15.0) + assert early_unwind < 1.0 reduced = get_genesis_gv70_unwind_ff_scale(-0.2, -1.0, 1.0, 20.0) assert 0.6 < reduced < 1.0 assert get_genesis_gv70_unwind_ff_scale(-0.2, -1.0, -1.0, 20.0) == 1.0 @@ -967,7 +983,7 @@ class TestLatControl: get_genesis_g70_high_speed_transition_scale(0.0, 0.8, 65.0 * 0.44704) assert get_genesis_g70_high_speed_transition_scale(0.0, 0.8, 20.0 * 0.44704) > \ get_genesis_g70_high_speed_transition_scale(0.0, 0.8, 65.0 * 0.44704) - assert 0.90 < get_genesis_g70_curve_unwind_output_scale(0.7, -0.5, 25.0) < 1.0 + assert 0.88 < get_genesis_g70_curve_unwind_output_scale(0.7, -0.5, 25.0) < 1.0 assert get_genesis_g70_curve_unwind_output_scale(0.7, 0.5, 25.0) == 1.0 assert get_genesis_g70_angle_output_scale(55.0, 1.0) > get_genesis_g70_angle_output_scale(85.0, 1.0) assert get_genesis_g70_angle_output_scale(85.0, -1.0) == pytest.approx(1.0) diff --git a/selfdrive/controls/tests/test_leads.py b/selfdrive/controls/tests/test_leads.py index 144c3aa797..09a475b73b 100644 --- a/selfdrive/controls/tests/test_leads.py +++ b/selfdrive/controls/tests/test_leads.py @@ -12,6 +12,8 @@ from openpilot.selfdrive.controls.radard import ( DT_MDL, HONDA_BOSCH_A_RADAR_TS, RadarD, + POST_STANDSTILL_RADAR_LEAD_PERSISTENCE_FRAMES, + post_standstill_radar_lead_is_urgent, g90_low_speed_radar_lead_sane, g90_radar_lead_lateral_sane, has_slow_radar_tracks, @@ -106,6 +108,64 @@ class TestLeads: assert not has_slow_radar_tracks(normal_radar) assert not has_slow_radar_tracks(unavailable_radar) + @staticmethod + def make_radar_only_lead(track_id: int, d_rel: float = 8.0, v_rel: float = 0.0): + return { + "status": True, + "radar": True, + "modelProb": 0.0, + "radarTrackId": track_id, + "dRel": d_rel, + "vRel": v_rel, + } + + def test_post_standstill_radar_lead_requires_same_track_persistence(self): + radar = RadarD() + radar._post_standstill_gate_active = True + lead = self.make_radar_only_lead(42) + + assert not radar._filter_post_standstill_lead(lead)["status"] + assert not radar._filter_post_standstill_lead(lead)["status"] + assert radar._filter_post_standstill_lead(lead)["status"] + assert radar._post_standstill_candidate_frames == POST_STANDSTILL_RADAR_LEAD_PERSISTENCE_FRAMES + + def test_post_standstill_radar_lead_resets_for_new_track(self): + radar = RadarD() + radar._post_standstill_gate_active = True + + assert not radar._filter_post_standstill_lead(self.make_radar_only_lead(42))["status"] + assert not radar._filter_post_standstill_lead(self.make_radar_only_lead(43))["status"] + assert radar._post_standstill_candidate_frames == 1 + + def test_post_standstill_gate_only_arms_after_no_lead_stop(self): + radar = RadarD() + radar._remember_post_standstill_state(standstill=True, lead_status=False) + radar._prepare_post_standstill_gate(standstill=False) + assert radar._post_standstill_gate_active + + radar = RadarD() + radar._remember_post_standstill_state(standstill=True, lead_status=True) + radar._prepare_post_standstill_gate(standstill=False) + assert not radar._post_standstill_gate_active + + def test_post_standstill_model_lead_bypasses_gate(self): + radar = RadarD() + radar._post_standstill_gate_active = True + lead = self.make_radar_only_lead(42) + lead["modelProb"] = 0.9 + + assert radar._filter_post_standstill_lead(lead)["status"] + assert not radar._post_standstill_gate_active + + def test_post_standstill_urgent_radar_lead_bypasses_gate(self): + radar = RadarD() + radar._post_standstill_gate_active = True + lead = self.make_radar_only_lead(42, d_rel=3.0, v_rel=-2.1) + + assert post_standstill_radar_lead_is_urgent(lead) + assert radar._filter_post_standstill_lead(lead)["status"] + assert not radar._post_standstill_gate_active + @pytest.mark.skipif(platform.system() == "Darwin", reason="SocketEventHandle requires eventfd") def test_radar_fault(self): # if there's no radar-related can traffic, radard should either not respond or respond with an error diff --git a/selfdrive/ui/tests/test_device_screen_settings.py b/selfdrive/ui/tests/test_device_screen_settings.py new file mode 100644 index 0000000000..95907d62ed --- /dev/null +++ b/selfdrive/ui/tests/test_device_screen_settings.py @@ -0,0 +1,147 @@ +from types import SimpleNamespace + +from openpilot.selfdrive.ui import ui_state as ui_state_module + + +class FakeParams: + def __init__(self, **values): + self.values = values + + def get_bool(self, key, **_kwargs): + return bool(self.values.get(key, False)) + + def get_int(self, key, **_kwargs): + return int(self.values.get(key, 0)) + + +class PassthroughFilter: + def update(self, value): + return value + + +def make_device(monkeypatch, **overrides): + values = { + "ScreenManagement": True, + "ScreenBrightness": 35, + "ScreenBrightnessOnroad": 45, + "ScreenTimeout": 30, + "ScreenTimeoutOnroad": 10, + "StandbyMode": False, + } + values.update(overrides) + state = SimpleNamespace( + ui_params=FakeParams(**values), + status=ui_state_module.UIStatus.DISENGAGED, + started=False, + ignition=False, + light_sensor=-1.0, + sm={}, + ) + monkeypatch.setattr(ui_state_module, "ui_state", state) + monkeypatch.setattr(ui_state_module.gui_app, "big_ui", lambda: False) + monkeypatch.setattr(ui_state_module.gui_app, "_mouse_events", []) + device = ui_state_module.Device() + device._brightness_filter = PassthroughFilter() + return device, state + + +def test_manual_brightness_applies_to_current_device_state(monkeypatch): + device, state = make_device(monkeypatch) + + assert device._calculate_brightness() == 35 + + state.started = True + assert device._calculate_brightness() == 45 + + +def test_auto_brightness_preserves_existing_behavior(monkeypatch): + device, state = make_device(monkeypatch, ScreenBrightness=101, ScreenBrightnessOnroad=101) + + assert device._calculate_brightness() == ui_state_module.BACKLIGHT_OFFROAD + + state.started = True + state.light_sensor = -1.0 + assert device._calculate_brightness() == ui_state_module.BACKLIGHT_OFFROAD + + +def test_screen_management_off_ignores_custom_values(monkeypatch): + device, state = make_device(monkeypatch, ScreenManagement=False, ScreenBrightness=10, ScreenBrightnessOnroad=20, + StandbyMode=True) + + assert device._calculate_brightness() == ui_state_module.BACKLIGHT_OFFROAD + + state.started = True + device._interaction_time = 0 + assert device._calculate_brightness() == ui_state_module.BACKLIGHT_OFFROAD + assert device.interactive_timeout == 30 + + +def test_screen_settings_refresh_after_external_param_change(monkeypatch): + now = 100.0 + monkeypatch.setattr(ui_state_module.time, "monotonic", lambda: now) + device, state = make_device(monkeypatch) + state.started = True + state.ignition = True + device._ignition = True + device._interaction_time = now + 10 + + state.ui_params.values["ScreenBrightnessOnroad"] = 72 + state.ui_params.values["ScreenTimeoutOnroad"] = 25 + now += device.SCREEN_SETTINGS_REFRESH_INTERVAL + device._refresh_screen_settings() + + assert device._calculate_brightness() == 72 + assert device.interactive_timeout == 25 + assert device._interaction_time == now + 25 + + +def test_standby_blanks_after_timeout_and_touch_wakes(monkeypatch): + now = 100.0 + monkeypatch.setattr(ui_state_module.time, "monotonic", lambda: now) + device, state = make_device(monkeypatch, StandbyMode=True) + state.started = True + state.ignition = True + device._ignition = True + device._interaction_time = now - 1 + + assert device._calculate_brightness() == 0 + + monkeypatch.setattr(ui_state_module.gui_app, "_mouse_events", [SimpleNamespace(left_down=True)]) + device._update_wakefulness() + + assert device._interaction_time == now + 10 + assert device._calculate_brightness() == 45 + + +def test_hide_ui_blanks_after_timeout_and_touch_wakes(monkeypatch): + now = 100.0 + monkeypatch.setattr(ui_state_module.time, "monotonic", lambda: now) + device, state = make_device(monkeypatch, ScreenBrightnessOnroad=0) + state.started = True + state.ignition = True + device._ignition = True + device._interaction_time = now - 1 + + assert device._calculate_brightness() == 0 + + monkeypatch.setattr(ui_state_module.gui_app, "_mouse_events", [SimpleNamespace(left_down=True)]) + device._update_wakefulness() + + assert device._interaction_time == now + 10 + assert device._calculate_brightness() == 5 + + +def test_standby_wakes_for_visible_alert(monkeypatch): + now = 100.0 + monkeypatch.setattr(ui_state_module.time, "monotonic", lambda: now) + device, state = make_device(monkeypatch, StandbyMode=True) + state.started = True + state.ignition = True + device._ignition = True + device._interaction_time = now - 1 + device._visible_onroad_alert = lambda: True + + device._update_wakefulness() + + assert device._interaction_time == now + 10 + assert device._calculate_brightness() == 45 diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index 268e98c00c..e7f9fbfb74 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -297,6 +297,8 @@ class UIState: class Device: + SCREEN_SETTINGS_REFRESH_INTERVAL = 1.0 + def __init__(self): self._ignition = False self._interaction_time: float = -1 @@ -306,6 +308,16 @@ class Device: self._awake: bool = True self._params = ui_state.ui_params + self._screen_settings_refresh_time: float = 0.0 + self._screen_management = False + self._screen_brightness = 101 + self._screen_brightness_onroad = 101 + self._screen_timeout = 30 + self._screen_timeout_onroad = 30 + self._standby_mode = False + self._last_status = ui_state.status + self._refresh_screen_settings(force=True) + self._offroad_brightness: int = BACKLIGHT_OFFROAD self._last_brightness: int = 0 self._brightness_filter = FirstOrderFilter(BACKLIGHT_OFFROAD, 10.00, 1 / gui_app.target_fps) @@ -325,8 +337,8 @@ class Device: if self._override_interactive_timeout is not None: return self._override_interactive_timeout - timeout_onroad = self._params.get_int("ScreenTimeoutOnroad", return_default=True) - timeout_offroad = self._params.get_int("ScreenTimeout", return_default=True) + timeout_onroad = self._screen_timeout_onroad + timeout_offroad = self._screen_timeout if timeout_onroad <= 0: timeout_onroad = 10 if gui_app.big_ui() else 5 @@ -345,12 +357,54 @@ class Device: self._interactive_timeout_callbacks.append(callback) def update(self): + self._refresh_screen_settings() + # do initial reset if self._interaction_time <= 0: self._reset_interactive_timeout() - self._update_brightness() self._update_wakefulness() + self._update_brightness() + + def _refresh_screen_settings(self, force: bool = False) -> None: + now = time.monotonic() + if not force and now - self._screen_settings_refresh_time < self.SCREEN_SETTINGS_REFRESH_INTERVAL: + return + + previous = ( + self._screen_management, + self._screen_brightness, + self._screen_brightness_onroad, + self._screen_timeout, + self._screen_timeout_onroad, + self._standby_mode, + ) + + self._screen_management = self._params.get_bool("ScreenManagement") + if self._screen_management: + self._screen_brightness = min(max(self._params.get_int("ScreenBrightness", return_default=True), 0), 101) + self._screen_brightness_onroad = min(max(self._params.get_int("ScreenBrightnessOnroad", return_default=True), 0), 101) + self._screen_timeout = self._params.get_int("ScreenTimeout", return_default=True) + self._screen_timeout_onroad = self._params.get_int("ScreenTimeoutOnroad", return_default=True) + self._standby_mode = self._params.get_bool("StandbyMode") + else: + self._screen_brightness = 101 + self._screen_brightness_onroad = 101 + self._screen_timeout = 30 + self._screen_timeout_onroad = 30 + self._standby_mode = False + + self._screen_settings_refresh_time = now + current = ( + self._screen_management, + self._screen_brightness, + self._screen_brightness_onroad, + self._screen_timeout, + self._screen_timeout_onroad, + self._standby_mode, + ) + if previous != current and self._interaction_time > 0: + self._reset_interactive_timeout() def set_offroad_brightness(self, brightness: int | None): if brightness is None: @@ -358,6 +412,15 @@ class Device: self._offroad_brightness = min(max(brightness, 0), 100) def _update_brightness(self): + brightness = self._calculate_brightness() + + if brightness != self._last_brightness: + if self._brightness_thread is None or not self._brightness_thread.is_alive(): + self._brightness_thread = threading.Thread(target=HARDWARE.set_screen_brightness, args=(brightness,)) + self._brightness_thread.start() + self._last_brightness = brightness + + def _calculate_brightness(self) -> int: clipped_brightness = self._offroad_brightness if ui_state.started and ui_state.light_sensor >= 0: @@ -374,19 +437,26 @@ class Device: brightness = round(self._brightness_filter.update(clipped_brightness)) if not self._awake: brightness = 0 + elif ui_state.started and self._standby_mode and time.monotonic() > self._interaction_time: + brightness = 0 + elif ui_state.started and self._screen_brightness_onroad != 101: + brightness = max(5, self._screen_brightness_onroad) if time.monotonic() <= self._interaction_time else self._screen_brightness_onroad + elif not ui_state.started and self._screen_brightness != 101: + brightness = self._screen_brightness - if brightness != self._last_brightness: - if self._brightness_thread is None or not self._brightness_thread.is_alive(): - self._brightness_thread = threading.Thread(target=HARDWARE.set_screen_brightness, args=(brightness,)) - self._brightness_thread.start() - self._last_brightness = brightness + return brightness def _update_wakefulness(self): # Handle interactive timeout - ignition_just_turned_off = not ui_state.ignition and self._ignition + ignition_state_changed = ui_state.ignition != self._ignition self._ignition = ui_state.ignition - if ignition_just_turned_off or any(ev.left_down for ev in gui_app.mouse_events): + status_changed = ui_state.status != self._last_status and ui_state.status != UIStatus.OVERRIDE + self._last_status = ui_state.status + wake_for_onroad_event = (ui_state.started and self._standby_mode and self._screen_brightness_onroad != 0 and + (status_changed or self._visible_onroad_alert())) + + if ignition_state_changed or any(ev.left_down for ev in gui_app.mouse_events) or wake_for_onroad_event: self._reset_interactive_timeout() interaction_timeout = time.monotonic() > self._interaction_time @@ -397,6 +467,27 @@ class Device: self._set_awake(ui_state.ignition or not interaction_timeout or PC) + @staticmethod + def _visible_onroad_alert() -> bool: + if not ui_state.started: + return False + + sm = ui_state.sm + try: + selfdrive_state = sm["selfdriveState"] + if selfdrive_state.alertSize != log.SelfdriveState.AlertSize.none: + return True + if selfdrive_state.alertStatus != log.SelfdriveState.AlertStatus.normal: + return True + except Exception: + pass + + try: + starpilot_state = sm["starpilotSelfdriveState"] + return getattr(starpilot_state.alertSize, "raw", 0) != 0 + except Exception: + return False + def _set_awake(self, on: bool): if on != self._awake: self._awake = on diff --git a/starpilot/car/ford/lateral.py b/starpilot/car/ford/lateral.py index 42a36f7fdb..1da986882e 100644 --- a/starpilot/car/ford/lateral.py +++ b/starpilot/car/ford/lateral.py @@ -37,6 +37,14 @@ CURVATURE_LOOKAHEAD_MAX = 0.40 FORD_CURVATURE_LOOKAHEAD = { CAR.FORD_EXPLORER_MK6: 0.20, } +FORD_CONSERVATIVE_PREVIEW_CARS = frozenset({ + CAR.FORD_MUSTANG_MACH_E_MK1, +}) +FORD_MANUAL_TURN_LATCH_CARS = frozenset({ + CAR.FORD_MUSTANG_MACH_E_MK1, +}) +MANUAL_TURN_ENTRY_ANGLE_DEG = 12.0 +MANUAL_TURN_RECOVERY_SECONDS = 0.25 @dataclass(frozen=True) @@ -101,6 +109,8 @@ class FordLateralController: self.curvature_lane_change_factor = 0.85 self.human_turn = HumanTurnDetector() + self.manual_turn_latched = False + self.manual_turn_recovery_timer = 0.0 self.curvature_samples = deque(maxlen=max(2, round(0.3 / STEER_DT))) self.curvature_last = 0.0 self._frame = 0 @@ -151,8 +161,13 @@ class FordLateralController: def _current_curvature(CS) -> float: return -CS.out.yawRate / max(CS.out.vEgoRaw, 0.1) - def _blend_and_scale(self, desired: float, predicted: float, v_ego: float) -> tuple[float, int]: + def _blend_and_scale(self, desired: float, predicted: float, v_ego: float, current: float = 0.0) -> tuple[float, int]: blend = float(np.interp(abs(desired), [0.0, 0.001], [self.curvature_blend_low, self.curvature_blend_high])) + if self.CP.carFingerprint in FORD_CONSERVATIVE_PREVIEW_CARS: + if desired * predicted <= 0.0: + blend = 0.0 + elif current * predicted > 0.0 and abs(current) > abs(desired) and abs(predicted) > abs(desired): + blend *= abs(desired) / abs(predicted) requested = predicted * blend + desired * (1.0 - blend) lane_change, direction = self._lane_change() precision = 1 @@ -166,26 +181,62 @@ class FordLateralController: def _manual_turn(self, CC, CS) -> bool: if not CC.latActive: self.human_turn.reset() + self.manual_turn_latched = False + self.manual_turn_recovery_timer = 0.0 return False - return self.human_turn.update( + detected = self.human_turn.update( self.human_turn_enabled, CS.out.steeringPressed, CS.out.steeringAngleDeg) + if self.CP.carFingerprint not in FORD_MANUAL_TURN_LATCH_CARS: + return detected + + if not self.human_turn_enabled: + self.manual_turn_latched = False + self.manual_turn_recovery_timer = 0.0 + return False + + blinker_direction = float(CS.out.rightBlinker) - float(CS.out.leftBlinker) + driver_turning_with_signal = ( + CS.out.steeringPressed and abs(CS.out.steeringAngleDeg) >= MANUAL_TURN_ENTRY_ANGLE_DEG and + blinker_direction != 0.0 and not self._lane_change()[0] and + CS.out.steeringTorque * blinker_direction < 0.0 + ) + if detected or driver_turning_with_signal: + self.manual_turn_latched = True + + if not self.manual_turn_latched: + self.manual_turn_recovery_timer = 0.0 + return False + + if CS.out.steeringPressed or blinker_direction != 0.0: + self.manual_turn_recovery_timer = 0.0 + else: + self.manual_turn_recovery_timer += STEER_DT + if self.manual_turn_recovery_timer + 1e-9 >= MANUAL_TURN_RECOVERY_SECONDS: + self.manual_turn_latched = False + self.manual_turn_recovery_timer = 0.0 + + return self.manual_turn_latched def update(self, CC, CS, actuators) -> FordLateralResult: current = self._current_curvature(CS) if not CC.latActive: self.human_turn.reset() + self.manual_turn_latched = False + self.manual_turn_recovery_timer = 0.0 self.curvature_samples.clear() self.curvature_last = 0.0 return FordLateralResult() - if self._manual_turn(CC, CS) or CS.out.vEgoRaw < 0.1: + manual_turn = self._manual_turn(CC, CS) + if manual_turn or CS.out.vEgoRaw < 0.1: self.curvature_samples.clear() self.curvature_last = 0.0 - return FordLateralResult(active=True) + return FordLateralResult(active=not ( + manual_turn and self.CP.carFingerprint in FORD_MANUAL_TURN_LATCH_CARS)) v_ego = float(CS.out.vEgoRaw) predicted = self._predicted_curvature(v_ego, self._curvature_lookahead()) - requested, precision = self._blend_and_scale(float(actuators.curvature), predicted, v_ego) + requested, precision = self._blend_and_scale(float(actuators.curvature), predicted, v_ego, current) if v_ego > 9.0: requested = float(np.clip(requested, current - CarControllerParams.CURVATURE_ERROR, diff --git a/starpilot/car/ford/tests/test_lateral.py b/starpilot/car/ford/tests/test_lateral.py index 8529d6e5de..f6ee1304a5 100644 --- a/starpilot/car/ford/tests/test_lateral.py +++ b/starpilot/car/ford/tests/test_lateral.py @@ -32,12 +32,16 @@ def controller(monkeypatch): return controller -def car_state(speed=15.0, curvature=0.0, steering_pressed=False, steering_angle=0.0): +def car_state(speed=15.0, curvature=0.0, steering_pressed=False, steering_angle=0.0, + steering_torque=0.0, left_blinker=False, right_blinker=False): return SimpleNamespace(out=SimpleNamespace( vEgoRaw=speed, yawRate=-curvature * speed, steeringPressed=steering_pressed, steeringAngleDeg=steering_angle, + steeringTorque=steering_torque, + leftBlinker=left_blinker, + rightBlinker=right_blinker, )) @@ -114,6 +118,36 @@ def test_curvature_strategy_uses_learned_lookahead(controller, monkeypatch): assert lookaheads == [pytest.approx(0.38)] +def test_mach_e_preview_does_not_override_opposite_current_path(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + + requested, _ = controller._blend_and_scale(-0.0001, 0.002, 20.0) + + assert requested == pytest.approx(-0.0001) + + +def test_mach_e_preview_is_reduced_when_ahead_of_current_path(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + + requested, _ = controller._blend_and_scale(0.0005, 0.002, 20.0, current=0.0015) + + assert requested == pytest.approx(0.00065) + + +def test_mach_e_preview_remains_available_on_curve_entry(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + + requested, _ = controller._blend_and_scale(0.0005, 0.002, 20.0, current=0.0002) + + assert requested == pytest.approx(0.0011) + + +def test_non_mach_e_preview_blend_is_unchanged(controller): + requested, _ = controller._blend_and_scale(-0.0001, 0.002, 20.0, current=0.0015) + + assert requested == pytest.approx(0.00074) + + def test_lane_change_accepts_capnp_enum_wrappers(controller): controller.model = SimpleNamespace(meta=SimpleNamespace( laneChangeState=SimpleNamespace(raw=2), @@ -146,3 +180,87 @@ def test_curvature_manual_turn_keeps_session_active_with_neutral_command(control assert result.active assert result.curvature == 0.0 + + +def test_mach_e_signaled_manual_turn_yields_until_inputs_settle(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + controller.human_turn_enabled = True + CC = SimpleNamespace(latActive=True) + actuators = SimpleNamespace(curvature=0.006) + + result = controller.update(CC, car_state( + steering_pressed=True, steering_angle=-15.0, steering_torque=-2.0, + right_blinker=True), actuators) + assert not result.active + assert result.curvature == 0.0 + + result = controller.update(CC, car_state( + steering_pressed=True, steering_angle=5.0, steering_torque=2.0, + right_blinker=True), actuators) + assert not result.active + + for _ in range(4): + result = controller.update(CC, car_state(), actuators) + assert not result.active + + result = controller.update(CC, car_state(), actuators) + assert result.active + assert result.curvature > 0.0 + + +def test_mach_e_opposite_blinker_correction_does_not_start_manual_turn(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + + result = controller.update( + SimpleNamespace(latActive=True), + car_state(steering_pressed=True, steering_angle=-15.0, steering_torque=2.0, + right_blinker=True), + SimpleNamespace(curvature=0.001), + ) + + assert result.active + + +def test_mach_e_lane_change_nudge_does_not_start_manual_turn(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + controller.model = SimpleNamespace( + orientationRate=SimpleNamespace(z=[0.0] * 33), + meta=SimpleNamespace( + laneChangeState=SimpleNamespace(raw=2), + laneChangeDirection=SimpleNamespace(raw=2), + ), + ) + + result = controller.update( + SimpleNamespace(latActive=True), + car_state(steering_pressed=True, steering_angle=-15.0, steering_torque=-2.0, + right_blinker=True), + SimpleNamespace(curvature=0.001), + ) + + assert result.active + + +def test_mach_e_small_blinker_nudge_does_not_start_manual_turn(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + + result = controller.update( + SimpleNamespace(latActive=True), + car_state(steering_pressed=True, steering_angle=-5.0, steering_torque=-2.0, + right_blinker=True), + SimpleNamespace(curvature=0.001), + ) + + assert result.active + + +def test_mach_e_manual_turn_latch_resets_with_lateral_control(controller): + controller.CP.carFingerprint = CAR.FORD_MUSTANG_MACH_E_MK1 + actuators = SimpleNamespace(curvature=0.001) + turning = car_state( + steering_pressed=True, steering_angle=-15.0, steering_torque=-2.0, + right_blinker=True) + + assert not controller.update(SimpleNamespace(latActive=True), turning, actuators).active + assert not controller.update(SimpleNamespace(latActive=False), turning, actuators).active + assert controller.update(SimpleNamespace(latActive=True), car_state(), actuators).active diff --git a/starpilot/common/starpilot_variables.py b/starpilot/common/starpilot_variables.py index 767aaf9d56..f66d06cbfe 100644 --- a/starpilot/common/starpilot_variables.py +++ b/starpilot/common/starpilot_variables.py @@ -16,7 +16,7 @@ from cereal import car, custom, log from opendbc.car import gen_empty_fingerprint from opendbc.car.car_helpers import interfaces from opendbc.car.chrysler.values import JEEPS as CHRYSLER_JEEPS -from opendbc.car.gm.values import CAR as GM_CAR, EV_CAR as GM_EV_CAR, GMFlags +from opendbc.car.gm.values import CAR as GM_CAR, EV_CAR as GM_EV_CAR, GM_AUTO_HOLD_CARS, GMFlags from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR, EV_CAR as HYUNDAI_EV_CAR, HyundaiFlags, HyundaiStarPilotSafetyFlags from opendbc.car.interfaces import TORQUE_SUBSTITUTE_PATH, CarInterfaceBase, GearShifter from opendbc.car.mock.values import CAR as MOCK @@ -1406,7 +1406,7 @@ class StarPilotVariables: screen_management = self.get_value("ScreenManagement") toggle.screen_brightness = max(self.get_value("ScreenBrightness", cast=float, condition=screen_management), 1) - toggle.screen_brightness_onroad = self.get_value("ScreenBrightnessOnroad", cast=float, condition=(screen_management and not toggle.force_onroad), min=1) + toggle.screen_brightness_onroad = self.get_value("ScreenBrightnessOnroad", cast=float, condition=(screen_management and not toggle.force_onroad), min=0) toggle.screen_recorder = self.get_value("ScreenRecorder", condition=screen_management) or toggle.debug_mode toggle.screen_timeout = self.get_value("ScreenTimeout", cast=float, condition=screen_management) toggle.screen_timeout_onroad = self.get_value("ScreenTimeoutOnroad", cast=float, condition=screen_management) @@ -1600,9 +1600,9 @@ class StarPilotVariables: ) toggle.remote_start_boots_comma = self.get_value("RemoteStartBootsComma", condition=toggle.car_make == "gm") - gm_auto_hold_supported = toggle.car_model in LEGACY_VOLT_STOCK_ACC_CARS + gm_auto_hold_supported = toggle.car_model in GM_AUTO_HOLD_CARS toggle.gm_auto_hold = self.get_value("GMAutoHold", condition=gm_auto_hold_supported) - toggle.volt_one_pedal_mode = self.get_value("VoltOnePedalMode", condition=gm_auto_hold_supported) + toggle.volt_one_pedal_mode = self.get_value("VoltOnePedalMode", condition=toggle.car_model in LEGACY_VOLT_STOCK_ACC_CARS) toggle.volt_sng = self.get_value("VoltSNG", condition=toggle.car_model in LEGACY_VOLT_STOCK_ACC_CARS) diff --git a/starpilot/system/the_galaxy/assets/components/tools/device_settings.js b/starpilot/system/the_galaxy/assets/components/tools/device_settings.js index 064caa3e79..ec7c5cbc6c 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/device_settings.js +++ b/starpilot/system/the_galaxy/assets/components/tools/device_settings.js @@ -34,7 +34,7 @@ const VEHICLE_SETTING_MAKES = { RemoteStartBootsComma: GM_MAKES, HKGRemoteStartBootsComma: HKG_MAKES, VoltSNG: ["Chevrolet", "Holden"], - GMAutoHold: ["Chevrolet", "Holden"], + GMAutoHold: ["Buick", "Chevrolet", "Holden"], VoltOnePedalMode: ["Chevrolet", "Holden"], RemapCancelToDistance: ["Chevrolet", "Holden"], JeepBrakeHold: ["Jeep"], @@ -490,7 +490,7 @@ function numericBounds(param) { return { min: 1, max: 101, step: 1 } } if (param.key === "ScreenBrightnessOnroad") { - return { min: 1, max: 101, step: 1 } + return { min: 0, max: 101, step: 1 } } if (param.key === "LaneCenterOffset") { diff --git a/starpilot/system/the_galaxy/assets/mobile/js/params.js b/starpilot/system/the_galaxy/assets/mobile/js/params.js index acbc947065..04a3bbb23f 100644 --- a/starpilot/system/the_galaxy/assets/mobile/js/params.js +++ b/starpilot/system/the_galaxy/assets/mobile/js/params.js @@ -62,7 +62,7 @@ const VEHICLE_SETTING_MAKES = { RemoteStartBootsComma: ["Buick", "Cadillac", "Chevrolet", "GMC", "Holden"], HKGRemoteStartBootsComma: ["Genesis", "Hyundai", "Kia"], VoltSNG: ["Chevrolet", "Holden"], - GMAutoHold: ["Chevrolet", "Holden"], + GMAutoHold: ["Buick", "Chevrolet", "Holden"], VoltOnePedalMode: ["Chevrolet", "Holden"], RemapCancelToDistance: ["Chevrolet", "Holden"], JeepBrakeHold: ["Jeep"], @@ -140,9 +140,12 @@ export function numericBounds(param, values = {}) { const n = Number(value) return Number.isFinite(n) ? n : null } - if (param.key === "ScreenBrightness" || param.key === "ScreenBrightnessOnroad") { + if (param.key === "ScreenBrightness") { return { min: 1, max: 101, step: 1 } } + if (param.key === "ScreenBrightnessOnroad") { + return { min: 0, max: 101, step: 1 } + } if (param.key === "LaneCenterOffset") { return { min: -0.3, max: 0.3, step: 0.01 } } diff --git a/starpilot/system/the_galaxy/assets/mobile/js/views/SystemTools.js b/starpilot/system/the_galaxy/assets/mobile/js/views/SystemTools.js index 0970282c23..7b5955be63 100644 --- a/starpilot/system/the_galaxy/assets/mobile/js/views/SystemTools.js +++ b/starpilot/system/the_galaxy/assets/mobile/js/views/SystemTools.js @@ -26,6 +26,7 @@ export const SystemTools = { fastStatus: null, checkedForUpdates: false, busy: "", + autoUpdateBusy: false, profiles: [], profileBusy: "", } @@ -77,6 +78,7 @@ export const SystemTools = { const status = await api.getUpdateFastStatus() if (!status) throw new Error("Update status unavailable") this.fastStatus = status + this.isOnroad = !!status.isOnroad } catch (e) { this.fastStatus = null if (throwOnError) throw e @@ -195,6 +197,21 @@ export const SystemTools = { this.busy = "" } }, + async setAutomaticUpdates(enabled) { + if (this.autoUpdateBusy || this.isOnroad || this.fastStatus?.running || !this.fastStatus) return + const previous = !!this.fastStatus.automaticUpdates + this.autoUpdateBusy = true + this.fastStatus = { ...this.fastStatus, automaticUpdates: !!enabled } + try { + const payload = await api.updateParam({ key: "AutomaticUpdates", value: !!enabled, label: "Automatic Updates" }) + showSnackbar(payload?.message || `Automatic updates ${enabled ? "enabled" : "disabled"}.`) + } catch (e) { + this.fastStatus = { ...this.fastStatus, automaticUpdates: previous } + showSnackbar(e?.message || "Failed to update Automatic Updates.", "error") + } finally { + this.autoUpdateBusy = false + } + }, async applyFastUpdate() { if (this.busy || this.isOnroad) return if (this.fastStatus?.running) { showSnackbar("Fast update is already running."); return } @@ -301,6 +318,22 @@ export const SystemTools = { +