Compare commits

...

92 Commits

Author SHA1 Message Date
Michael Tawata 2d7fb4828e minimize standstill duration display for mici 2026-06-05 09:44:44 -07:00
firestar5683 71e6b0c88a Update modeld_v16.py 2026-06-05 09:44:44 -07:00
firestar5683 826775bb1f Project Hateno 2026-06-05 11:13:24 -05:00
firestarsdog e01d61feb9 BigUI WIP: Good chunk of vehicle settings 2026-06-05 03:17:23 -04:00
firestar5683 fee42e4d7b so that was a lie 2026-06-05 02:00:55 -05:00
firestar5683 038b83ac4a this outta be good 2026-06-04 23:52:55 -05:00
firestar5683 4c27f3cd5e Zikeji's Dilemma 2026-06-04 23:32:57 -05:00
firestar5683 2aaad84ab6 livin off energy drinks and Marlboro Reds 2026-06-04 23:32:16 -05:00
firestar5683 a1d338f35c Been workin all day just to keep my family fed 2026-06-04 23:09:43 -05:00
firestar5683 50bd4f121e Requiem For Rancid Remmy Rental Roadster 2026-06-04 15:16:33 -05:00
firestar5683 3d3f6ea888 build 2026-06-04 13:49:02 -05:00
firestar5683 e5cc74603a defaults 2026-06-04 13:46:40 -05:00
firestar5683 7da3d84053 build 2026-06-04 13:43:16 -05:00
firestar5683 47c2cc9990 stuff and things 2026-06-04 13:40:53 -05:00
whoisdomi 85e3e11c10 Radar for Leads Button 2026-06-04 13:40:53 -05:00
firestarsdog 840e4814d0 No-uh 2026-06-04 14:25:38 -04:00
firestar5683 42bcb717a4 ninininini 2026-06-03 23:31:27 -05:00
firestarsdog b515b285db slc diag script : dirty update to make runnable anywhere 2026-06-04 00:21:58 -04:00
firestar5683 7fb15f97ab v16 2026-06-03 22:14:00 -05:00
firestar5683 b202886c33 tiny dancer 2026-06-03 16:57:44 -05:00
firestar5683 e3e4542ef2 My Collar's Blue & My Neck's Red 2026-06-03 16:04:14 -05:00
firestar5683 3027988a4d Purple Monkey Balls 2026-06-03 15:03:40 -05:00
firestar5683 119fcb15a1 leady speedy 2026-06-03 13:39:40 -05:00
firestar5683 1b4e609b33 loopdy loop 2026-06-03 12:48:57 -05:00
firestar5683 c80365de78 mid day stuffs 2026-06-03 11:01:28 -05:00
firestar5683 3e591f311c i6 2026-06-03 07:50:13 -05:00
Michael Tawata 3118ff5c52 remove fp references and fix readme tagline 2026-06-02 23:55:39 -07:00
firestar5683 d0598334e4 Microslop 2026-06-02 21:47:09 -05:00
firestar5683 2f13d3846c i6 2026-06-02 21:44:56 -05:00
firestar5683 7558054914 build 2026-06-02 20:30:02 -05:00
firestar5683 71260b52d1 angle cleanup 2026-06-02 20:27:34 -05:00
firestarsdog f55046f6e9 BigUI WIP: Aethergauge 2026-06-02 19:16:34 -04:00
firestarsdog 3cf48ae3c8 BigUI WIP: Some CEM Stuff 2026-06-02 17:49:10 -04:00
firestar5683 e44e612465 build 2026-06-02 14:26:19 -05:00
whoisdomi 78e9b5139c Faster Leads for $300 Trebek, and say hi to your motha
Faster takeoffs after leads and green lights.
2026-06-02 14:12:21 -05:00
whoisdomi d2a8163f32 Human Lane Change ui fix
Toggled on, would show adjecent radar leads, even if that toggle was off.
Now gated to its toggle in developer ui.
2026-06-02 14:12:20 -05:00
firestar5683 9f30661f6d long planner / i5 / sonata 2026-06-02 11:18:34 -05:00
firestar5683 5632559e5a fcw 2026-06-02 10:31:16 -05:00
firestar5683 ae2f502767 g90 long 2026-06-02 00:29:10 -05:00
firestarsdog 669143a178 BUICK_LACROSSE_ASCM 2026-06-02 00:07:16 -04:00
firestar5683 54cb76ddfd build 2026-06-01 20:52:31 -05:00
whoisdomi fabf122627 Wheel controls qt fix 2026-06-01 20:50:11 -05:00
whoisdomi 3486c695b8 QT StarPilot Logo 2026-06-01 20:50:11 -05:00
whoisdomi 6eb513501d Fire Firehose 2026-06-01 20:50:11 -05:00
whoisdomi 45060a07b7 Add CC Main and LKAS buttons to Wheel Controls
Clean up so all buttons are handled from wheel controls
2026-06-01 20:50:11 -05:00
firestarsdog 7f5e78fd8f BigUI WIP: Delete Stuff 2026-06-01 02:51:51 -04:00
firestarsdog b178e67ae5 BigUI WIP: Scale up dialogs 2026-06-01 02:31:32 -04:00
firestarsdog 026c83fb1b BigUI WIP: Align System Settings, again... 2026-06-01 02:13:23 -04:00
firestarsdog c7b3251918 BigUI WIP: System Settings Bump 2026-06-01 01:46:36 -04:00
firestarsdog 14f94151a5 BigUP WIP: System Settings Pass 2026-06-01 01:19:50 -04:00
firestar5683 6dc473713c i5 2026-06-01 00:10:14 -05:00
firestarsdog 594f525c0c BigUI WIP: System Settings Cleanup Pass 2026-06-01 00:39:18 -04:00
firestar5683 2132a5ceb0 build 2026-05-31 21:06:39 -05:00
firestar5683 5d86b7ac5b IsRHD 2026-05-31 21:03:42 -05:00
firestarsdog 0e7123d632 BigUI WIP: Huh need this afterall 2026-05-31 16:56:39 -04:00
firestarsdog b96c9290f7 BigUI WIP: Settings Cleanup 2026-05-31 16:48:12 -04:00
firestarsdog 416b5e3cd2 BigUI WIP: System Settings update 2026-05-31 15:57:01 -04:00
firestar5683 8a3a872a93 build 2026-05-31 13:45:41 -05:00
firestar5683 6f5690618f param 2026-05-31 13:42:11 -05:00
firestarsdog fad4434104 Expose Python UI Screen Timeout Variables 2026-05-31 14:40:08 -04:00
firestarsdog 86359bacab BigUI WIP: Sounds Default=Auto 2026-05-31 14:00:03 -04:00
firestarsdog a7d8d7a544 BigUP WIP: Sound Polish 2026-05-31 13:53:06 -04:00
firestar5683 86d059bdb4 long 2026-05-31 12:37:09 -05:00
firestar5683 caa5f41b1e radars 2026-05-31 12:26:54 -05:00
firestar5683 fcda700625 nav fixes 2026-05-31 12:14:04 -05:00
firestarsdog cdca40f018 BigUI WIP: Sound Panel Alignment 2026-05-31 04:27:57 -04:00
firestarsdog 736c344cdd BigUI WIP: Sheep > Goat 2026-05-31 02:27:54 -04:00
firestarsdog a28250c81b BigUI WIP: Icons and removal of magic math 2026-05-31 02:14:32 -04:00
firestar5683 b406a1a9d8 nightly roundup 2026-05-31 00:55:43 -05:00
firestarsdog a44e306343 Hm.. XT5? lol 2026-05-30 23:00:45 -04:00
firestarsdog ecbed0f4f8 BigUI WIP: Remove dock lol 2026-05-30 21:31:43 -04:00
firestar5683 04273eefad above 2026-05-30 14:41:03 -05:00
firestar5683 bd5436c55f nav / planner / sonata buttons 2026-05-30 14:26:09 -05:00
firestarsdog 6ca397b840 BigUI WIP: Optimizations 2026-05-30 03:24:04 -04:00
firestarsdog cc2b53a6e9 BigUI WIP: Drop starpilot_icon 2026-05-29 18:10:59 -04:00
firestar5683 6c4717cc39 g90test 2026-05-29 16:07:34 -05:00
firestar5683 6afdc99dd5 redneck 2026-05-29 15:57:20 -05:00
firestarsdog 07fcbbdab8 BigUI WIP: Poof 2026-05-29 16:38:59 -04:00
firestar5683 d55d1bff69 fort hey 2026-05-29 14:42:42 -05:00
firestarsdog a80d3680d0 BigUI WIP: Remove icon code 2026-05-29 15:36:11 -04:00
firestar5683 9673c72d44 bleehhhhh 2026-05-29 14:29:49 -05:00
firestar5683 7051b79674 nav 2026-05-29 14:15:46 -05:00
elkoled e7fa0f51a6 comment
(cherry picked from commit 81fceadb7817b831e47e679a07f515b02950e6e8)
2026-05-29 13:56:21 -05:00
elkoled e9dc540f64 adjust fan setpoint
(cherry picked from commit 269d2189b2383fa5b7c0d5e7cab4fb527f29a636)
2026-05-29 13:56:18 -05:00
firestar5683 e26a91147d build 2026-05-29 13:50:51 -05:00
firestar5683 3de95a341a bokoblin loves mutton; I fix the button 2026-05-29 13:48:07 -05:00
firestar5683 dff6f898a8 done goofed 2026-05-29 12:07:46 -05:00
firestar5683 dfd614c31f build 2026-05-29 12:00:14 -05:00
whoisdomi 5020d33748 ui+selfdrived: pin UI after init, move selfdrived to core 5
Move the UI core-affinity pin to after MainWindow init so startup and
restart recovery can use all cores (pinning before init starved the
restarting UI on the contended little cores, stretching recovery from
~30s to minutes). Move selfdrived off the saturated core 4 onto core 5
so its 100 Hz loop is no longer starved, eliminating selfdrivedLagging.

Verified over a full drive: selfdrivedLagging=0, core4/core5 sustained
>=95% only 0.3%/1.2% of the time, UI restart recovery ~15s with the
device staying engaged, radar tracking unaffected.
2026-05-29 11:56:33 -05:00
firestarsdog bd687f353f BigUI WIP: Sine Bonis P1 2026-05-29 03:40:04 -04:00
firestar5683 ce19d2c5f0 Bat bat come under my hat 2026-05-29 01:18:27 -05:00
firestar5683 29ade037d3 Offer applies with enrollment and triple advantage 2026-05-29 00:55:19 -05:00
189 changed files with 14066 additions and 3941 deletions
+8 -7
View File
@@ -1,7 +1,7 @@
# StarPilot
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/firestar5683/StarPilot)
[![Discord](https://img.shields.io/discord/1137853399715549214?label=Discord)](https://firestar.link/discord)
[![Discord](https://img.shields.io/discord/1387432184121393333?label=Discord)](https://firestar.link/discord)
[![Last Updated](https://img.shields.io/github/last-commit/firestar5683/StarPilot/StarPilot)](https://github.com/firestar5683/StarPilot)
[![Wiki](https://img.shields.io/badge/Wiki-StarPilot-blue?logo=wiki)](https://wiki.firestar.link)
@@ -15,11 +15,11 @@ Openpilot provides
* Lane Change Assist
* Driver Monitoring *without wheel nags*
StarPilot adds support for many GM vehicles along with improved tuning,
especially for radar-less (camera only) vehicles.
StarPilot was formerly a GM targeted fork,
but [has expanded to offer Quality-Of-Life improvements for all](#features)!
StarPilot is built off of [StarPilot](https://github.com/FrogAi/StarPilot)
and supports the major features StarPilot offers.
StarPilot is built off of [FrogPilot](https://github.com/FrogAi/FrogPilot)
and supports the major features FrogPilot offers.
StarPilot has a vibrant, welcoming community [discord](https://firestar.link/discord).
Stop by to chat or ask questions!
@@ -32,9 +32,9 @@ installation guides, and software configuration.
## Features
* Full support for Comma C3, C3X, and C4
* C4 is currently in release testing. Join our fleet of C4 testers!
* Model switcher with all of comma's tinygrad driving models
* Special longitudinal planner tuning for VoACC (visual only, radar-less) vehicles
* Custom-tuned torque controllers for an expanding list of cars.
* Galaxy: StarPilot's portal to configure your comma device using your phone from anywhere.
Download models, change settings, update software, visualize live model outputs for tuning.
* Always On Lateral (full time steering assist)*
@@ -49,8 +49,9 @@ Download models, change settings, update software, visualize live model outputs
* ZSS support*
* High quality dashcam recordings*
* Enhanced tuning for CEM (dynamic experimental mode switching)
* And more!
\* [Inherited from StarPilot](https://github.com/FrogAi/StarPilot#openpilot-vs-starpilot)
\* [Inherited from FrogPilot](https://github.com/FrogAi/FrogPilot#openpilot-vs-frogpilot)
## GM-only Features
Binary file not shown.
+7 -2
View File
@@ -11,7 +11,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"AlwaysAllowUploads", {PERSISTENT, BOOL, "0"}},
{"AlwaysOnDM", {PERSISTENT, BOOL}},
{"ApiCache_Device", {PERSISTENT, STRING}},
{"ApiCache_FirehoseStats", {PERSISTENT, JSON}},
{"AssistNowToken", {PERSISTENT, STRING}},
{"AthenadPid", {PERSISTENT, INT}},
{"AthenadUploadQueue", {PERSISTENT, JSON}},
@@ -68,7 +67,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"IsMetric", {PERSISTENT, BOOL}},
{"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}},
{"IsOnroad", {PERSISTENT, BOOL}},
{"IsRHD", {PERSISTENT, BOOL}},
{"IsRhdDetected", {PERSISTENT, BOOL}},
{"IsRHDOverride", {PERSISTENT, BOOL}},
{"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}},
{"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}},
{"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}},
@@ -221,6 +222,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"CustomPersonalities", {PERSISTENT, BOOL, "0", "0", 2}},
{"CancelButtonControl", {PERSISTENT, INT, "1", "0", 2}},
{"CancelButtonControlsMigrated", {PERSISTENT, BOOL, "0", "0"}},
{"AOLLKASMigratedToButtonControl", {PERSISTENT, BOOL, "0", "0"}},
{"TrafficPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
{"AggressivePersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
{"StandardPersonalityProfile", {PERSISTENT, BOOL, "1", "1", 2}},
@@ -366,6 +368,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"LongitudinalTune", {PERSISTENT, BOOL, "1", "0", 0}},
{"LoudBlindspotAlert", {PERSISTENT, BOOL, "0", "0", 0}},
{"LowVoltageShutdown", {PERSISTENT, FLOAT, "11.8", "11.8", 3}},
{"MainCruiseButtonControl", {PERSISTENT, INT, "9", "9", 2}},
{"ManualUpdateInitiated", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
{"AMapKey1", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
{"AMapKey2", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
@@ -381,7 +384,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"MapSpeedLimit", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
{"NavDesiresAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
{"NavLongitudinalAllowed", {PERSISTENT, BOOL, "1", "0", 2}},
{"NavDestination", {PERSISTENT, STRING, "", ""}},
{"NavDestination", {PERSISTENT | CLEAR_ON_MANAGER_START, STRING, "", ""}},
{"NavInstructionCollapsed", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL, "0", "0"}},
{"NavInstructionState", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, JSON, "{}", "{}"}},
{"NextMapSpeedLimit", {CLEAR_ON_MANAGER_START, JSON, "{}", "{}"}},
{"VisionSpeedLimit", {CLEAR_ON_MANAGER_START, FLOAT, "0.0", "0.0"}},
@@ -443,6 +447,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"QOLLateral", {PERSISTENT, BOOL, "1", "0", 1}},
{"QOLLongitudinal", {PERSISTENT, BOOL, "1", "0", 1}},
{"QOLVisuals", {PERSISTENT, BOOL, "1", "0", 0}},
{"RadarTakeoffs", {PERSISTENT, BOOL, "1", "0", 2}},
{"RadarTracksUI", {PERSISTENT, BOOL, "0", "0", 3}},
{"RainbowPath", {PERSISTENT, BOOL, "0", "0", 1}},
{"RandomEvents", {PERSISTENT, BOOL, "0", "0", 1}},
Binary file not shown.
+2 -2
View File
@@ -133,8 +133,8 @@ class TestParams:
def test_params_get_type(self):
# json
self.params.put("ApiCache_FirehoseStats", {"a": 0})
assert self.params.get("ApiCache_FirehoseStats") == {"a": 0}
self.params.put("ApiCache_DriveStats", {"a": 0})
assert self.params.get("ApiCache_DriveStats") == {"a": 0}
# int
self.params.put("BootCount", 1441)
@@ -0,0 +1,8 @@
from opendbc.car.gm.values import AccState, CAR
def get_stock_cc_active_for_cancel(CP, CS):
stock_cc_active = CS.out.cruiseState.enabled or CS.pcm_acc_status != AccState.OFF
if CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL:
return CS.out.cruiseState.enabled
return stock_cc_active
@@ -213,10 +213,12 @@ FINGERPRINTS.update({
CAR.CHEVROLET_SUBURBAN: FINGERPRINTS[CAR.CHEVROLET_SUBURBAN_CC],
CAR.GMC_YUKON_CC: FINGERPRINTS[CAR.GMC_YUKON],
CAR.CADILLAC_XT6: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
CAR.CADILLAC_XT5: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
CAR.CHEVROLET_BLAZER: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
CAR.CHEVROLET_MALIBU_SDGM: FINGERPRINTS[CAR.CHEVROLET_MALIBU_CC],
CAR.BUICK_BABYENCLAVE: FINGERPRINTS[CAR.CHEVROLET_TRAVERSE],
CAR.CHEVROLET_SILVERADO_CC: FINGERPRINTS[CAR.CHEVROLET_SILVERADO],
CAR.BUICK_LACROSSE_ASCM: FINGERPRINTS[CAR.BUICK_LACROSSE],
})
FW_VERSIONS: dict[str, dict[tuple, list[bytes]]] = {
+12 -5
View File
@@ -410,8 +410,8 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.BUICK_LACROSSE:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate in (CAR.BUICK_LACROSSE, CAR.BUICK_LACROSSE_ASCM):
CarInterfaceBase.configure_torque_tune(CAR.BUICK_LACROSSE, ret.lateralTuning)
elif candidate == CAR.CADILLAC_ESCALADE:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
@@ -609,6 +609,12 @@ class CarInterface(CarInterfaceBase):
ret.startAccel = 1.15
ret.vEgoStarting = max(ret.vEgoStarting, 0.35)
if ret.openpilotLongitudinalControl and candidate in (CAR.CHEVROLET_SILVERADO, CAR.CHEVROLET_SILVERADO_CC) and not ret.enableGasInterceptorDEPRECATED:
ret.longitudinalTuning.kpBP = [0.0, 5.0, 15.0, 35.0]
ret.longitudinalTuning.kpV = [0.02, 0.03, 0.028, 0.022]
ret.longitudinalTuning.kiBP = [0.0, 5.0, 15.0, 35.0]
ret.longitudinalTuning.kiV = [0.28, 0.26, 0.20, 0.16]
elif candidate in CC_ONLY_CAR and not ret.enableGasInterceptorDEPRECATED:
ret.flags |= GMFlags.CC_LONG.value
ret.alphaLongitudinalAvailable = False
@@ -659,7 +665,6 @@ class CarInterface(CarInterfaceBase):
volt_stock_auto_hold_safety = (
gm_auto_hold and
not ret.openpilotLongitudinalControl and
candidate in {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
@@ -668,8 +673,10 @@ class CarInterface(CarInterfaceBase):
}
)
if volt_stock_auto_hold_safety:
# Reuse the paddle-scheduler safety bit as a stock-Volt auto-hold marker on
# non-pedal paths. The scheduler logic remains inactive without pedal-long.
# Reuse the paddle-scheduler safety bit as a Volt auto-hold marker on
# non-pedal paths. Hold can run while OP longitudinal is configured but
# not currently active, so the bit must be present regardless of the
# current long-control mode.
ret.safetyConfigs[0].safetyParam |= GMSafetyFlags.FLAG_GM_PANDA_PADDLE_SCHED.value
use_panda_3d1_sched = (
@@ -0,0 +1,387 @@
import sys
import types
from types import SimpleNamespace
fake_interfaces = types.ModuleType("opendbc.car.interfaces")
class _FakeCarControllerBase:
def __init__(self, dbc_names=None, CP=None):
self.CP = CP
fake_interfaces.CarControllerBase = _FakeCarControllerBase
sys.modules.setdefault("opendbc.car.interfaces", fake_interfaces)
fake_params = types.ModuleType("openpilot.common.params")
class _FakeParams:
pass
class _FakeUnknownKeyName(Exception):
pass
fake_params.Params = _FakeParams
fake_params.UnknownKeyName = _FakeUnknownKeyName
sys.modules.setdefault("openpilot.common.params", fake_params)
fake_testing_grounds = types.ModuleType("openpilot.starpilot.common.testing_grounds")
fake_testing_grounds.testing_ground = SimpleNamespace(use_1=False)
sys.modules.setdefault("openpilot.starpilot.common.testing_grounds", fake_testing_grounds)
from opendbc.car.gm.carcontroller import (
CarController,
estimate_auto_hold_brake,
get_adas_keepalive_step,
get_lka_steering_cmd_counter,
get_testing_ground_1_brake_switch_bias,
get_stock_cc_active_for_cancel,
should_activate_auto_hold,
should_send_stock_long_cancel,
should_spoof_dash_speed,
should_spoof_ecm_cruise_status,
supports_volt_auto_hold,
use_interceptor_sng_launch,
)
from opendbc.car.gm.values import AccState, CAR, GMFlags
from opendbc.car.structs import CarParams
def _cs(enabled, pcm_acc_status):
return SimpleNamespace(
out=SimpleNamespace(cruiseState=SimpleNamespace(enabled=enabled), accFaulted=False),
pcm_acc_status=pcm_acc_status,
)
def _sng_cs(v_ego, standstill, cruise_standstill):
return SimpleNamespace(
out=SimpleNamespace(
vEgo=v_ego,
standstill=standstill,
cruiseState=SimpleNamespace(standstill=cruise_standstill),
),
)
def _controller(car_fingerprint=CAR.CHEVROLET_BOLT_CC_2018_2021):
controller = CarController.__new__(CarController)
controller.CP = SimpleNamespace(carFingerprint=car_fingerprint)
controller.planner_regen_hold = False
controller.regen_paddle_pressed = False
controller.regen_paddle_timer = 0
controller.regen_press_counter = 0
controller.regen_release_counter = 0
controller.regen_min_on_frames = 0
controller.regen_min_off_frames = 0
controller.pedal_active_last = False
controller.pedal_steady = 0.0
controller.aego = 0.0
controller.maneuver_paddle_mode = "auto"
return controller
def test_gen1_bolt_pedal_cancel_uses_pcm_acc_status():
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_CC_2018_2021)
assert get_stock_cc_active_for_cancel(CP, _cs(False, AccState.ACTIVE))
def test_gen2_bolt_acc_pedal_cancel_uses_enabled_only():
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL)
assert not get_stock_cc_active_for_cancel(CP, _cs(False, AccState.ACTIVE))
def test_stock_cancel_is_suppressed_when_acc_is_faulted():
CP = SimpleNamespace(carFingerprint=CAR.CHEVROLET_VOLT_CAMERA)
cs = _cs(True, AccState.FAULTED)
cs.out.accFaulted = True
assert not get_stock_cc_active_for_cancel(CP, cs)
assert not should_send_stock_long_cancel(11, cs)
def test_stock_cancel_requires_delay_and_no_acc_fault():
cs = _cs(True, AccState.ACTIVE)
assert not should_send_stock_long_cancel(10, cs)
assert should_send_stock_long_cancel(11, cs)
def test_gen1_bolt_pedal_ecm_cruise_spoof_is_not_gated_by_dash_speed_toggle():
CP = SimpleNamespace(
carFingerprint=CAR.CHEVROLET_BOLT_CC_2018_2021,
enableGasInterceptorDEPRECATED=True,
flags=GMFlags.PEDAL_LONG.value,
openpilotLongitudinalControl=True,
)
assert not should_spoof_dash_speed(CP, SimpleNamespace(disable_openpilot_long=True, gm_pedal_longitudinal=True))
assert should_spoof_ecm_cruise_status(CP)
def test_gateway_keepalive_uses_gateway_cadence():
cp = SimpleNamespace(networkLocation=CarParams.NetworkLocation.gateway, flags=0)
assert get_adas_keepalive_step(cp, is_kaofui_car=True) == 100
assert get_adas_keepalive_step(cp, is_kaofui_car=False) == 200
def test_removed_camera_keepalive_uses_camera_cadence():
cp = SimpleNamespace(networkLocation=CarParams.NetworkLocation.fwdCamera, flags=GMFlags.NO_CAMERA.value)
assert get_adas_keepalive_step(cp, is_kaofui_car=True) == 100
def test_live_camera_path_does_not_send_pt_keepalive():
cp = SimpleNamespace(networkLocation=CarParams.NetworkLocation.fwdCamera, flags=0)
assert get_adas_keepalive_step(cp, is_kaofui_car=True) is None
def test_volt_auto_hold_requires_toggle_supported_non_cc_only_volt_and_stock_safety():
stock_safety = [SimpleNamespace(safetyParam=0x8000)]
no_safety = [SimpleNamespace(safetyParam=0)]
assert supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
openpilotLongitudinalControl=True,
networkLocation=CarParams.NetworkLocation.fwdCamera,
safetyConfigs=no_safety,
),
True,
)
assert not supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT_CC,
openpilotLongitudinalControl=True,
networkLocation=CarParams.NetworkLocation.fwdCamera,
safetyConfigs=no_safety,
),
True,
)
assert supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT,
openpilotLongitudinalControl=False,
networkLocation=CarParams.NetworkLocation.gateway,
safetyConfigs=stock_safety,
),
True,
)
assert supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT_2019,
openpilotLongitudinalControl=False,
networkLocation=CarParams.NetworkLocation.fwdCamera,
safetyConfigs=stock_safety,
),
True,
)
assert not supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT_2019,
openpilotLongitudinalControl=False,
networkLocation=CarParams.NetworkLocation.fwdCamera,
safetyConfigs=no_safety,
),
True,
)
assert not supports_volt_auto_hold(
SimpleNamespace(
carFingerprint=CAR.CHEVROLET_VOLT_CAMERA,
openpilotLongitudinalControl=True,
networkLocation=CarParams.NetworkLocation.fwdCamera,
safetyConfigs=no_safety,
),
False,
)
def test_auto_hold_brake_estimate_uses_driver_or_op_brake_and_clamps():
assert estimate_auto_hold_brake(0.0, 20.0) == 80
assert estimate_auto_hold_brake(20.0, 40.0) == 110
assert estimate_auto_hold_brake(20.0, 160.0) == 160
assert estimate_auto_hold_brake(100.0, 400.0) == 240
def test_auto_hold_activation_allows_direct_entry_from_stopped_brake_press():
assert should_activate_auto_hold(
True,
False,
False,
True,
True,
False,
False,
0.01,
)
def test_auto_hold_activation_stays_latched_after_brake_release():
assert should_activate_auto_hold(
True,
False,
True,
False,
True,
False,
False,
0.0,
)
def test_auto_hold_activation_blocks_when_long_is_active_or_motion_is_above_threshold():
assert not should_activate_auto_hold(
True,
True,
False,
True,
True,
True,
False,
0.0,
)
assert not should_activate_auto_hold(
True,
True,
False,
False,
False,
False,
0.03,
)
def test_auto_hold_activation_allows_standstill_even_if_speed_filter_is_slightly_above_threshold():
assert should_activate_auto_hold(
True,
True,
False,
False,
True,
False,
False,
0.05,
)
def test_calc_pedal_command_small_accel_deadband_keeps_creep_target_stable():
pos_controller = _controller()
neg_controller = _controller()
pos_pedal, pos_regen = pos_controller.calc_pedal_command(0.02, True, 0.3)
neg_pedal, neg_regen = neg_controller.calc_pedal_command(-0.02, True, 0.3)
assert not pos_regen
assert not neg_regen
assert pos_pedal == neg_pedal
def test_calc_pedal_command_creep_switch_does_not_snap_to_target():
controller = _controller()
controller.pedal_active_last = True
controller.pedal_steady = 0.18
controller.regen_press_counter = 20
pedal_gas, press_regen = controller.calc_pedal_command(-1.0, True, 0.5)
assert press_regen
assert pedal_gas > 0.15
def test_calc_pedal_command_softens_small_positive_follow_ramp_at_road_speed():
controller = _controller()
controller.pedal_active_last = True
controller.pedal_steady = 0.18
pedal_gas, press_regen = controller.calc_pedal_command(0.2, True, 18.0)
assert not press_regen
assert pedal_gas - 0.18 < 0.026
def test_calc_pedal_command_keeps_strong_positive_requests_responsive():
controller = _controller()
controller.pedal_active_last = True
controller.pedal_steady = 0.18
pedal_gas, press_regen = controller.calc_pedal_command(1.4, True, 18.0)
assert not press_regen
assert pedal_gas - 0.18 > 0.04
def test_use_interceptor_sng_launch_requires_actual_near_stop():
CP = SimpleNamespace(vEgoStarting=0.25)
assert use_interceptor_sng_launch(CP, _sng_cs(0.0, True, True))
assert use_interceptor_sng_launch(CP, _sng_cs(0.2, False, True))
assert not use_interceptor_sng_launch(CP, _sng_cs(1.2, False, True))
assert not use_interceptor_sng_launch(CP, _sng_cs(0.0, True, False))
def test_use_interceptor_sng_launch_extends_for_maneuver_mode():
CP = SimpleNamespace(vEgoStarting=0.25)
assert use_interceptor_sng_launch(CP, _sng_cs(1.2, False, True), maneuver_mode=True)
assert not use_interceptor_sng_launch(CP, _sng_cs(2.2, False, True), maneuver_mode=True)
def test_testing_ground_1_brake_switch_bias_is_softened_but_still_speed_scaled():
assert get_testing_ground_1_brake_switch_bias(0.0) == 40
assert get_testing_ground_1_brake_switch_bias(6.0) == 85
assert get_testing_ground_1_brake_switch_bias(15.0) == 130
assert get_testing_ground_1_brake_switch_bias(30.0) == 170
def test_lka_counter_uses_returned_loopback_counter():
cs = SimpleNamespace(
loopback_lka_steering_cmd_updated=True,
loopback_lka_steering_cmd_counter=2,
loopback_lka_steering_cmd_ts_nanos=1,
pt_lka_steering_cmd_counter=0,
)
assert get_lka_steering_cmd_counter(0, cs) == 3
def test_lka_counter_keeps_advancing_without_loopback_updates():
cs = SimpleNamespace(
loopback_lka_steering_cmd_updated=False,
loopback_lka_steering_cmd_counter=0,
loopback_lka_steering_cmd_ts_nanos=1,
pt_lka_steering_cmd_counter=0,
)
next_counter = 1
sent = []
for _ in range(6):
idx = get_lka_steering_cmd_counter(next_counter, cs)
sent.append(idx)
next_counter = (idx + 1) % 4
assert sent == [1, 2, 3, 0, 1, 2]
def test_lka_counter_only_seeds_from_pt_counter_once_without_loopback():
cs = SimpleNamespace(
loopback_lka_steering_cmd_updated=False,
loopback_lka_steering_cmd_counter=0,
loopback_lka_steering_cmd_ts_nanos=0,
pt_lka_steering_cmd_counter=0,
)
next_counter = -1
sent = []
for _ in range(6):
idx = get_lka_steering_cmd_counter(next_counter, cs)
sent.append(idx)
next_counter = (idx + 1) % 4
assert sent == [1, 2, 3, 0, 1, 2]
@@ -117,6 +117,21 @@ class TestGMInterface:
assert car_params.flags & GMFlags.NO_CAMERA.value
assert car_params.safetyConfigs[0].safetyParam & GMSafetyFlags.FLAG_GM_NO_CAMERA.value
def test_silverado_alpha_long_uses_trimmed_longitudinal_tune(self):
CarInterface = interfaces[CAR.CHEVROLET_SILVERADO]
fingerprint = _empty_fingerprint()
fingerprint[0] = FINGERPRINTS[CAR.CHEVROLET_SILVERADO][0].copy()
car_params = CarInterface.get_params(CAR.CHEVROLET_SILVERADO, fingerprint, [], alpha_long=True, is_release=False,
docs=False, starpilot_toggles=_test_starpilot_toggles())
assert car_params.openpilotLongitudinalControl
assert not car_params.enableGasInterceptorDEPRECATED
assert list(car_params.longitudinalTuning.kpBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
assert list(car_params.longitudinalTuning.kpV) == pytest.approx([0.02, 0.03, 0.028, 0.022])
assert list(car_params.longitudinalTuning.kiBP) == pytest.approx([0.0, 5.0, 15.0, 35.0])
assert list(car_params.longitudinalTuning.kiV) == pytest.approx([0.28, 0.26, 0.20, 0.16])
def test_volt_gateway_without_accel_pos_uses_brake_pedal_message(self):
CarInterface = interfaces[CAR.CHEVROLET_VOLT]
fingerprint = _empty_fingerprint()
@@ -132,6 +147,22 @@ class TestGMInterface:
assert "ECMAcceleratorPos" not in pt_parser.vl
assert "EBCMBrakePedalPosition" in pt_parser.vl
def test_volt_auto_hold_sets_stock_hold_safety_bit_with_op_long_enabled(self):
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
fingerprint = _empty_fingerprint()
fingerprint[0][0x2FF] = 8
params = Params()
try:
params.put_bool("GMAutoHold", True)
car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=True, 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
@parameterized.expand(VOLT_CARS)
def test_volt_bsm_is_enabled_without_fingerprint_match(self, car_model):
CarInterface = interfaces[car_model]
@@ -0,0 +1,52 @@
from opendbc.can import CANPacker
from opendbc.car.gm import gmcan
from opendbc.car.gm.values import CAR, DBC
class TestGMCan:
def setup_method(self):
self.packer = CANPacker(DBC[CAR.CHEVROLET_BOLT_ACC_2022_2023]["pt"])
def test_gas_regen_command_matches_starpilot_bolt_acc(self):
addr, dat, bus = gmcan.create_gas_regen_command(self.packer, 0, 5000, 1, True, False)
assert addr == 0x2CB
assert bus == 0
assert dat.hex() == "41429c4000bd63bf"
def test_gas_regen_command_preserves_always_one3_layout(self):
_, dat, _ = gmcan.create_gas_regen_command(self.packer, 0, 0, 1, True, False, include_always_one3=True)
assert dat.hex() == "4142800000bd7fff"
def test_gas_regen_command_encodes_high_bit_above_8191(self):
_, dat, _ = gmcan.create_gas_regen_command(self.packer, 0, 8848, 1, True, False)
decoded = ((dat[1] & 0x1) << 13) | (dat[2] << 5) | ((dat[3] & 0xF8) >> 3)
assert dat[1] & 0x1
assert decoded == 8848
def test_gas_regen_command_matches_starpilot_volt_2019(self):
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_2019]["pt"])
addr, dat, bus = gmcan.create_gas_regen_command(packer, 0, 5000, 1, True, False, include_always_one3=True, use_volt_layout=True)
assert addr == 0x2CB
assert bus == 0
assert dat.hex() == "41429c4000bd63bf"
def test_gas_regen_command_matches_starpilot_volt_ascm(self):
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_ASCM]["pt"])
addr, dat, bus = gmcan.create_gas_regen_command(packer, 0, 5000, 1, True, False, include_always_one3=True, use_volt_layout=True)
assert addr == 0x2CB
assert bus == 0
assert dat.hex() == "41429c4000bd63bf"
def test_gas_regen_command_matches_opgm_plain_volt_layout(self):
packer = CANPacker("gm_global_a_powertrain_generated")
addr, dat, bus = gmcan.create_gas_regen_command(packer, 0, 5000, 1, True, False, use_generated_layout=True)
assert addr == 0x2CB
assert bus == 0
assert dat.hex() == "41435c7000bca38f"
+5 -1
View File
@@ -279,6 +279,10 @@ class CAR(Platforms):
[GMCarDocs("Buick LaCrosse 2017-19", "Driver Confidence Package 2")],
GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4),
)
BUICK_LACROSSE_ASCM = GMPlatformConfig(
[GMCarDocs("Buick LaCrosse 2017-19 ASCM Harness")],
BUICK_LACROSSE.specs,
)
BUICK_REGAL = GMASCMPlatformConfig(
[GMCarDocs("Buick Regal Essence 2018")],
GMCarSpecs(mass=1714, wheelbase=2.83, steerRatio=14.4, centerToFrontRatio=0.4),
@@ -572,7 +576,7 @@ CC_REGEN_PADDLE_CAR = {
CAMERA_ACC_CAR.update(CC_ONLY_CAR)
# ASCM-INT paths are only enabled when SASCM (0x2FF) is detected at runtime
ASCM_INT = {CAR.CHEVROLET_VOLT_ASCM, CAR.GMC_ACADIA_ASCM, CAR.CHEVROLET_MALIBU_ASCM, CAR.CADILLAC_ESCALADE_ASCM}
ASCM_INT = {CAR.CHEVROLET_VOLT_ASCM, CAR.GMC_ACADIA_ASCM, CAR.CHEVROLET_MALIBU_ASCM, CAR.CADILLAC_ESCALADE_ASCM, CAR.BUICK_LACROSSE_ASCM}
STEER_THRESHOLD = 1.0
@@ -2,7 +2,8 @@ from dataclasses import dataclass
import numpy as np
from opendbc.can import CANPacker
from opendbc.car import Bus, DT_CTRL, make_tester_present_msg, structs
from opendbc.car import Bus, DT_CTRL, make_tester_present_msg, rate_limit, structs
from opendbc.car.common.filter_simple import FirstOrderFilter
from opendbc.car.lateral import apply_driver_steer_torque_limits, apply_steer_angle_limits_vm, common_fault_avoidance
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.hyundai import hyundaicanfd, hyundaican
@@ -61,6 +62,7 @@ REDNECK_BUTTON_COPIES = 2
REDNECK_BUTTON_COPIES_TIME = 7
REDNECK_BUTTON_COPIES_TIME_IMPERIAL = [REDNECK_BUTTON_COPIES_TIME + 3, 70]
REDNECK_BUTTON_COPIES_TIME_METRIC = [REDNECK_BUTTON_COPIES_TIME, 40]
ANGLE_SAFETY_BASELINE_MODEL = str(CAR.KIA_SPORTAGE_HEV_2026)
@dataclass
@@ -195,6 +197,28 @@ def update_genesis_g90_longitudinal_tuning(state: GenesisG90LongitudinalTuningSt
return state
def get_baseline_safety_cp():
from opendbc.car.hyundai.interface import CarInterface
return CarInterface.get_non_essential_params(ANGLE_SAFETY_BASELINE_MODEL)
def compute_torque_reduction_gain(steering_torque, v_ego, lat_active, last_gain):
if lat_active:
ceiling = np.interp(v_ego, [0.5, 1.5], [1.0, 0.85])
shelf = np.interp(v_ego, [2.0, 11.0], [0.45, 0.6])
floor = np.interp(v_ego, [2.0, 22.0], [0.1, 0.3])
bp1 = np.interp(v_ego, [2.0, 11.0], [75.0, 125.0])
bp2 = np.interp(v_ego, [2.0, 11.0], [125.0, 150.0])
bp3 = np.interp(v_ego, [2.0, 11.0], [175.0, 275.0])
bp4 = np.interp(v_ego, [2.0, 22.0], [400.0, 700.0])
target = np.interp(abs(steering_torque), [bp1, bp2, bp3, bp4], [ceiling, shelf, shelf, floor])
else:
target = 0.0
gain = rate_limit(target, last_gain, -0.014, 0.004)
return round(gain / 0.004) * 0.004
def process_hud_alert(enabled, fingerprint, hud_control):
sys_warning = (hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw))
@@ -227,6 +251,8 @@ class CarController(CarControllerBase):
self.packer = CANPacker(dbc_names[Bus.pt])
self.angle_limit_counter = 0
self.VM = VehicleModel(CP)
self.BASELINE_VM = VehicleModel(get_baseline_safety_cp()) if CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING else self.VM
self.angle_filter = FirstOrderFilter(0.0, 0.2, DT_CTRL)
self.accel_last = 0
self.apply_torque_last = 0
@@ -297,6 +323,7 @@ class CarController(CarControllerBase):
copies_xp = REDNECK_BUTTON_COPIES_TIME_METRIC if CS.is_metric else REDNECK_BUTTON_COPIES_TIME_IMPERIAL
copies = int(np.interp(REDNECK_BUTTON_COPIES_TIME, copies_xp, [1, REDNECK_BUTTON_COPIES]))
can_sends = [hyundaican.create_clu11(self.packer, self.frame, CS.clu11, send_button, self.CP)] * copies
CS.redneck_last_sent_button = getattr(CS, "redneck_send_button", 0)
if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15:
self.last_button_frame = self.frame
@@ -318,6 +345,7 @@ class CarController(CarControllerBase):
hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, (CS.buttons_counter + button_counter_offset) % 0xF, send_button)
for _ in range(20)
]
CS.redneck_last_sent_button = getattr(CS, "redneck_send_button", 0)
self.last_button_frame = self.frame
return can_sends
@@ -326,32 +354,41 @@ class CarController(CarControllerBase):
hud_control = CC.hudControl
lka_icon, lfa_icon = self._update_dash_icon_state(CC)
self.params = CarControllerParams(self.CP, CS.out.vEgoRaw)
if not self.CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING:
self.params = CarControllerParams(self.CP, CS.out.vEgoRaw)
apply_angle = CS.out.steeringAngleDeg
if self.CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING:
v_ego_raw = CS.out.vEgoRaw
desired_angle = float(np.clip(actuators.steeringAngleDeg,
-self.params.ANGLE_LIMITS.STEER_ANGLE_MAX,
self.params.ANGLE_LIMITS.STEER_ANGLE_MAX))
apply_angle = apply_steer_angle_limits_vm(desired_angle, self.apply_angle_last, CS.out.vEgoRaw,
self.angle_filter.update_alpha(float(np.interp(CS.out.vEgo, [5.0, 10.0, 20.0], [0.2, 0.1, 0.0])))
desired_angle = self.angle_filter.update(desired_angle)
apply_angle = apply_steer_angle_limits_vm(desired_angle, self.apply_angle_last, v_ego_raw,
CS.out.steeringAngleDeg, CC.latActive, self.params, self.VM)
if CS.out.steeringPressed and abs(CS.out.steeringTorque) > self.params.STEER_THRESHOLD:
apply_torque = self.params.ANGLE_MIN_TORQUE_REDUCTION_GAIN
elif CC.latActive and CS.out.vEgoRaw < 0.3:
apply_torque = self.params.ANGLE_ACTIVE_TORQUE_REDUCTION_GAIN
else:
apply_torque = self.params.ANGLE_MAX_TORQUE_REDUCTION_GAIN if CC.latActive else 0.0
if str(self.CP.carFingerprint) != ANGLE_SAFETY_BASELINE_MODEL:
apply_angle = apply_steer_angle_limits_vm(apply_angle or desired_angle, self.apply_angle_last, v_ego_raw,
CS.out.steeringAngleDeg, CC.latActive, self.params, self.BASELINE_VM)
apply_steer_req = CC.latActive and apply_torque > 0.0
apply_torque = compute_torque_reduction_gain(CS.out.steeringTorque, v_ego_raw, CC.latActive, self.apply_torque_last)
apply_steer_req = CC.latActive and apply_torque != 0.0
torque_fault = False
if apply_angle is None:
apply_torque = 0.0
apply_torque = 0
apply_angle = CS.out.steeringAngleDeg
apply_steer_req = False
self.apply_angle_last = apply_angle
if not CC.latActive:
self.apply_angle_last = float(np.clip(CS.out.steeringAngleDeg,
-self.params.ANGLE_LIMITS.STEER_ANGLE_MAX,
self.params.ANGLE_LIMITS.STEER_ANGLE_MAX))
self.angle_filter.x = self.apply_angle_last
else:
# steering torque
new_torque = int(round(actuators.torque * self.params.STEER_MAX))
@@ -376,6 +413,7 @@ class CarController(CarControllerBase):
accel = accel_cmd
stopping = actuators.longControlState == LongCtrlState.stopping
set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH)
CS.redneck_last_sent_button = 0
can_sends = []
+53 -6
View File
@@ -8,7 +8,7 @@ from opendbc.car import Bus, create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, HyundaiStarPilotFlags, HyundaiStarPilotSafetyFlags, CAR, DBC, Buttons, CarControllerParams, \
hyundai_cancel_button_enables_cruise
hyundai_cancel_button_enables_cruise, ALT_BUS_LDA_BUTTON_CARS, ALT_BUS_LDA_BUTTON_SWL_STAT_CARS
from opendbc.car.interfaces import CarStateBase
ButtonType = structs.CarState.ButtonEvent.Type
@@ -25,6 +25,7 @@ BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: Bu
IONIQ_6_BLINDSPOT_RIGHT_MASK = 0x08
IONIQ_6_BLINDSPOT_LEFT_MASK = 0x10
CANFD_CAMERA_LEAD_MIN_DISTANCE = 0.1
ALT_BUS_LDA_BUTTON_BURST_DEBOUNCE_NS = int(1.3e9)
def get_non_scc_cruise_signals(CP) -> tuple[str, str, str, str, str, str]:
@@ -74,6 +75,8 @@ class CarState(CarStateBase):
self.cruise_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
self.main_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
self.lda_button = 0
self.lda_button_raw = 0
self.lda_button_last_raw_rise_ts_nanos = 0
self.left_paddle = 0
self.mode_button = 0
self.custom_button = 0
@@ -171,9 +174,44 @@ class CarState(CarStateBase):
return False
def create_alt_bus_lda_button_events(self, cp_source: CANParser) -> list[structs.CarState.ButtonEvent]:
if self.CP.carFingerprint in ALT_BUS_LDA_BUTTON_SWL_STAT_CARS:
raw_lda_button = int(cp_source.vl["CLU13"]["CF_Clu_SWL_Stat"] == 4)
raw_lda_button_ts_nanos = cp_source.ts_nanos["CLU13"]["CF_Clu_SWL_Stat"]
else:
raw_lda_button = int(cp_source.vl["CLU13"]["CF_Clu_LdwsLkasSW"])
raw_lda_button_ts_nanos = cp_source.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"]
button_events: list[structs.CarState.ButtonEvent] = []
# Some alt-bus LKAS button layouts pulse several times per physical press burst.
# Collapse each burst into a single synthetic press/release pair.
if raw_lda_button and not self.lda_button_raw:
if self.lda_button_last_raw_rise_ts_nanos == 0 or \
raw_lda_button_ts_nanos - self.lda_button_last_raw_rise_ts_nanos > ALT_BUS_LDA_BUTTON_BURST_DEBOUNCE_NS:
button_events = [
structs.CarState.ButtonEvent(pressed=True, type=ButtonType.lkas),
structs.CarState.ButtonEvent(pressed=False, type=ButtonType.lkas),
]
self.lda_button_last_raw_rise_ts_nanos = raw_lda_button_ts_nanos
self.lda_button_raw = raw_lda_button
return button_events
def create_lkas_button_events(self, cp: CANParser, prev_lda_button: int) -> list[structs.CarState.ButtonEvent]:
# Some classic HKG platforms publish the LKAS button on the cluster bus instead of BCM_PO_11.
if cp.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"] > 0:
self.lda_button = int(cp.vl["CLU13"]["CF_Clu_LdwsLkasSW"])
elif cp.ts_nanos["BCM_PO_11"]["LDA_BTN"] > 0:
self.lda_button = int(cp.vl["BCM_PO_11"]["LDA_BTN"])
else:
self.lda_button = 0
return create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas})
def update(self, can_parsers, starpilot_toggles) -> structs.CarState:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
cp_alt = can_parsers.get(Bus.alt)
if self.CP.flags & HyundaiFlags.CANFD:
return self.update_canfd(can_parsers)
@@ -307,14 +345,17 @@ class CarState(CarStateBase):
prev_cruise_buttons = self.cruise_buttons[-1]
prev_main_buttons = self.main_buttons[-1]
prev_lda_button = self.lda_button
lkas_button_events = []
self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"])
self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"])
if self.FPCP.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON:
self.lda_button = cp.vl["BCM_PO_11"]["LDA_BTN"]
if self.CP.carFingerprint in ALT_BUS_LDA_BUTTON_CARS and cp_alt is not None and cp_alt.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"] > 0:
lkas_button_events = self.create_alt_bus_lda_button_events(cp_alt)
else:
lkas_button_events = self.create_lkas_button_events(cp, prev_lda_button)
ret.buttonEvents = [*self.create_cruise_button_events(self.cruise_buttons[-1], prev_cruise_buttons),
*create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise}),
*create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas})]
*lkas_button_events]
ret.blockPcmEnable = not self.recent_button_interaction()
@@ -525,11 +566,17 @@ class CarState(CarStateBase):
if CP.flags & HyundaiFlags.CANFD:
return self.get_can_parsers_canfd(CP)
msgs = []
msgs = [
("BCM_PO_11", 0),
("CLU13", 0),
]
if CP.flags & HyundaiFlags.NON_SCC and not (CP.flags & HyundaiFlags.NON_SCC_NO_FCA):
msgs.append(("FCA11", 0)) # Non-SCC trims can stop publishing FCA11; don't let it poison canValid
return {
parsers = {
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], msgs, 0),
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], 2),
}
if CP.carFingerprint in ALT_BUS_LDA_BUTTON_CARS:
parsers[Bus.alt] = CANParser(DBC[CP.carFingerprint][Bus.pt], [("CLU13", 0)], 1)
return parsers
@@ -1536,12 +1536,18 @@ FW_VERSIONS = {
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00OS MDPS C 1.00 1.05 56310J9030\x00 4OSDC105',
b'\xf1\x00OS MDPS C 1.00 1.04 56310J9030\x00 4OSDC104',
b'\xf1\x00OS MDPS C 1.00 1.05 56310/J9500 4OSDC105',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00OS9 LKAS AT USA LHD 1.00 1.00 95740-J9200 g30',
b'\xf1\x00OS9 LKAS AT AUS RHD 1.00 1.00 95740-J9200 g30',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00OS__ FCA --CUP 1.00 1.00 95655-J9100 ',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x006T6J0_C2\x00\x006T6K1051\x00\x00TOS4N20NS2\x00\x00\x00\x00',
b'\xf1\x006U2V0_C2\x00\x006U2V1051\x00\x00DOS4T16AS2\x00\x00\x00\x00',
],
},
CAR.KIA_FORTE_2019_NON_SCC: {
@@ -24,6 +24,7 @@ ENABLE_BUTTONS = (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.can
# Track when ECU disable happened - used to permanently suppress CAN errors from disabled ECU
ECU_DISABLE_TIMESTAMP = 0.0
KONA_NON_SCC_FCA_RADAR_ADDR = 0x602
def apply_platform_longitudinal_params(ret: structs.CarParams) -> None:
@@ -45,6 +46,18 @@ def apply_ecu_disable_failure_fallback(CP: structs.CarParams, params) -> None:
CP.pcmCruise = True
def detect_kona_non_scc_radar_fca(candidate, fingerprint, car_fw) -> bool:
if candidate != CAR.HYUNDAI_KONA_NON_SCC:
return False
if any(fw.ecu == Ecu.fwdRadar for fw in car_fw):
return True
# Some non-SCC Kona trims have FCA radar tracks without SCC. Use PT FCA11
# status on those cars; camera-bus FCA11 is not continuously published.
return KONA_NON_SCC_FCA_RADAR_ADDR in fingerprint[1]
class CarInterface(CarInterfaceBase):
CarState = CarState
CarController = CarController
@@ -136,6 +149,8 @@ class CarInterface(CarInterfaceBase):
# These cars use the FCA11 message for the AEB and FCW signals, all others use SCC12
if 0x38d in fingerprint[CAN.ECAN] or 0x38d in fingerprint[CAN.CAM]:
ret.flags |= HyundaiFlags.USE_FCA.value
if detect_kona_non_scc_radar_fca(candidate, fingerprint, car_fw):
ret.flags |= HyundaiFlags.NON_SCC_RADAR_FCA.value
if ret.flags & HyundaiFlags.LEGACY:
# these cars require a special panda safety mode due to missing counters and checksums in the messages
@@ -2,14 +2,19 @@ import math
from dataclasses import dataclass
from opendbc.can import CANParser
from opendbc.can.dbc import DBC as DBCReader
from opendbc.can.parser import get_raw_value
from opendbc.car import Bus, structs
from opendbc.car.interfaces import RadarInterfaceBase
from opendbc.car.hyundai.values import CAR, DBC, HYUNDAI_MANDO_FRONT_RADAR_DBC, HYUNDAI_MRR30_RADAR_DBC, \
HYUNDAI_MRR35_RADAR_DBC
from opendbc.car.hyundai.values import CAR, DBC, HYUNDAI_MANDO_FRONT_RADAR_DBC, HYUNDAI_MRREVO14F_RADAR_DBC, \
HYUNDAI_MRR30_RADAR_DBC, HYUNDAI_MRR35_RADAR_DBC
from openpilot.common.swaglog import cloudlog
RADAR_START_ADDR = 0x500
RADAR_MSG_COUNT = 32
G90_RADAR_MSG_COUNT = 64
MRREVO14F_RADAR_START_ADDR = 0x602
MRREVO14F_RADAR_MSG_COUNT = 16
MRR30_RADAR_START_ADDR = 0x210
MRR30_RADAR_MSG_COUNT = 16
MRR35_RADAR_START_ADDR = 0x3A5
@@ -23,11 +28,17 @@ class RadarTrackConfig:
radar_type: str
bus: int = 1
frequency: int = 50
parser_msg_count: int | None = None
@property
def can_parser_msg_count(self) -> int:
return self.parser_msg_count if self.parser_msg_count is not None else self.msg_count
RADAR_TRACK_CONFIGS = {
HYUNDAI_MANDO_FRONT_RADAR_DBC: RadarTrackConfig(RADAR_START_ADDR, RADAR_MSG_COUNT, "mando"),
HYUNDAI_MRR30_RADAR_DBC: RadarTrackConfig(MRR30_RADAR_START_ADDR, MRR30_RADAR_MSG_COUNT, "mrr30"),
HYUNDAI_MRREVO14F_RADAR_DBC: RadarTrackConfig(MRREVO14F_RADAR_START_ADDR, MRREVO14F_RADAR_MSG_COUNT, "mrrevo14f"),
HYUNDAI_MRR30_RADAR_DBC: RadarTrackConfig(MRR30_RADAR_START_ADDR, MRR30_RADAR_MSG_COUNT, "mrr30", bus=0),
HYUNDAI_MRR35_RADAR_DBC: RadarTrackConfig(MRR35_RADAR_START_ADDR, MRR35_RADAR_MSG_COUNT, "mrr35", bus=0, frequency=20),
}
@@ -36,6 +47,8 @@ RADAR_TRACK_CONFIGS = {
def get_radar_track_config(car_fingerprint) -> RadarTrackConfig | None:
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)
return RADAR_TRACK_CONFIGS.get(radar_dbc)
@@ -43,7 +56,8 @@ def get_radar_can_parser(CP, radar_config):
if radar_config is None:
return None
messages = [(f"RADAR_TRACK_{addr:x}", radar_config.frequency) for addr in range(radar_config.start_addr, radar_config.start_addr + radar_config.msg_count)]
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)
@@ -52,8 +66,15 @@ class RadarInterface(RadarInterfaceBase):
super().__init__(CP)
self.radar_config = get_radar_track_config(CP.carFingerprint)
self.updated_messages = set()
self.trigger_msg = (self.radar_config.start_addr + self.radar_config.msg_count - 1) if self.radar_config is not None else RADAR_START_ADDR
self.trigger_msg = (self.radar_config.start_addr + self.radar_config.can_parser_msg_count - 1
if self.radar_config is not None else RADAR_START_ADDR)
self.track_id = 0
self.g90_extended_mando = (CP.carFingerprint == CAR.GENESIS_G90 and self.radar_config is not None and
self.radar_config.msg_count > self.radar_config.can_parser_msg_count)
self.g90_mando_signals = []
if self.g90_extended_mando:
radar_dbc = DBCReader(DBC[CP.carFingerprint][Bus.radar])
self.g90_mando_signals = list(radar_dbc.addr_to_msg[RADAR_START_ADDR].sigs.values())
self.radar_off_can = CP.radarUnavailable
# Probe whether radar tracks still exist on the Ioniq 6 while OP long is active,
@@ -70,7 +91,7 @@ class RadarInterface(RadarInterfaceBase):
if self.radar_config is not None:
self.track_addrs = [(addr, f"RADAR_TRACK_{addr:x}")
for addr in range(self.radar_config.start_addr,
self.radar_config.start_addr + self.radar_config.msg_count)]
self.radar_config.start_addr + self.radar_config.can_parser_msg_count)]
def update(self, can_strings):
if self.ioniq_6_radar_probe and self.rcp is not None and not self.ioniq_6_radar_probe_logged:
@@ -93,6 +114,8 @@ class RadarInterface(RadarInterfaceBase):
vls = self.rcp.update(can_strings)
self.updated_messages.update(vls)
if self.g90_extended_mando:
self._update_g90_extended_mando_tracks(can_strings)
if self.trigger_msg not in self.updated_messages:
return None
@@ -102,6 +125,46 @@ class RadarInterface(RadarInterfaceBase):
return rr
def _decode_g90_mando_values(self, dat: bytes):
vals = {}
for sig in self.g90_mando_signals:
raw = get_raw_value(dat, sig)
if sig.is_signed:
raw -= ((raw >> (sig.size - 1)) & 1) * (1 << sig.size)
vals[sig.name] = raw * sig.factor + sig.offset
return vals
def _update_g90_extended_mando_tracks(self, can_strings):
if self.radar_config is None:
return
start_addr = self.radar_config.start_addr + self.radar_config.can_parser_msg_count
end_addr = self.radar_config.start_addr + self.radar_config.msg_count
for _, frames in can_strings:
for address, dat, src in frames:
if src != self.radar_config.bus or not (start_addr <= address < end_addr) or len(dat) < 8:
continue
self.updated_messages.add(address)
msg = self._decode_g90_mando_values(dat)
valid = msg["STATE"] in (3, 4)
if valid:
if address not in self.pts:
self.pts[address] = structs.RadarData.RadarPoint()
self.pts[address].trackId = self.track_id
self.track_id += 1
azimuth = math.radians(msg["AZIMUTH"])
self.pts[address].measured = True
self.pts[address].dRel = math.cos(azimuth) * msg["LONG_DIST"]
self.pts[address].yRel = 0.5 * -math.sin(azimuth) * msg["LONG_DIST"]
self.pts[address].vRel = msg["REL_SPEED"]
self.pts[address].aRel = msg["REL_ACCEL"]
self.pts[address].yvRel = float("nan")
elif address in self.pts:
del self.pts[address]
def _update(self, updated_messages):
ret = structs.RadarData()
if self.rcp is None:
@@ -140,6 +203,27 @@ class RadarInterface(RadarInterfaceBase):
del self.pts[track_key]
continue
if radar_type == "mrrevo14f":
for i in ("1", "2"):
track_key = addr * 2 + int(i) - 1
valid = msg[f"{i}_DISTANCE"] != 255.75
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}_DISTANCE"]
pt.yRel = msg[f"{i}_LATERAL"]
pt.vRel = msg[f"{i}_SPEED"]
pt.aRel = float("nan")
pt.yvRel = float("nan")
elif track_key in self.pts:
del self.pts[track_key]
continue
if radar_type == "mrr35":
# Most of the 32 channels are empty each frame. Only allocate a point
# when the channel is valid; drop it otherwise. Avoids the per-frame
@@ -14,7 +14,8 @@ from opendbc.car.hyundai.carstate import CarState, decode_canfd_camera_lead, dec
from opendbc.car.hyundai.interface import CarInterface
from opendbc.car.hyundai import hyundaican, hyundaicanfd
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.radar_interface import MRR30_RADAR_START_ADDR, MRR35_RADAR_START_ADDR, RADAR_START_ADDR, get_radar_track_config
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
from opendbc.car.hyundai.values import CAMERA_SCC_CAR, CANFD_CAR, CAN_GEARS, CAR, CHECKSUM, DATE_FW_ECUS, \
HYBRID_CAR, EV_CAR, FW_QUERY_CONFIG, LEGACY_SAFETY_MODE_CAR, CANFD_FUZZY_WHITELIST, \
UNSUPPORTED_LONGITUDINAL_CAR, PLATFORM_CODE_ECUS, HYUNDAI_VERSION_REQUEST_LONG, \
@@ -120,7 +121,22 @@ class TestHyundaiFingerprint:
assert bool(CP.flags & HyundaiFlags.CANFD_LKA_STEERING) == lka_steering
# radar available
for candidate in (CAR.HYUNDAI_SONATA, CAR.GENESIS_G90):
for candidate in (
CAR.HYUNDAI_IONIQ,
CAR.HYUNDAI_IONIQ_EV_LTD,
CAR.HYUNDAI_SANTA_FE,
CAR.HYUNDAI_SANTA_FE_2022,
CAR.HYUNDAI_SANTA_FE_HEV_2022,
CAR.HYUNDAI_SANTA_FE_PHEV_2022,
CAR.HYUNDAI_SONATA,
CAR.HYUNDAI_SONATA_HYBRID,
CAR.KIA_K5_HEV_2020,
CAR.KIA_NIRO_EV,
CAR.KIA_NIRO_PHEV,
CAR.KIA_NIRO_PHEV_2022,
CAR.GENESIS_G70_2020,
CAR.GENESIS_G90,
):
assert get_radar_track_config(candidate).start_addr == RADAR_START_ADDR
for radar in (True, False):
fingerprint = gen_empty_fingerprint()
@@ -129,16 +145,24 @@ class TestHyundaiFingerprint:
CP = CarInterface.get_params(candidate, fingerprint, [], False, False, False, None)
assert CP.radarUnavailable != radar
assert get_radar_track_config(CAR.HYUNDAI_SONATA_HYBRID).msg_count == 32
assert get_radar_track_config(CAR.GENESIS_G90).msg_count == 64
assert get_radar_track_config(CAR.GENESIS_G90).can_parser_msg_count == 32
fingerprint = gen_empty_fingerprint()
fingerprint[1][RADAR_START_ADDR] = 8
CP = CarInterface.get_params(CAR.GENESIS_G90, fingerprint, [], True, False, False, None)
assert CP.openpilotLongitudinalControl
assert not CP.radarUnavailable
for candidate in (CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SONATA_HYBRID, CAR.GENESIS_G90):
CP = CarInterface.get_params(candidate, fingerprint, [], True, False, False, None)
assert CP.openpilotLongitudinalControl
assert not CP.radarUnavailable
for candidate, radar_addr in (
(CAR.HYUNDAI_KONA_EV_2022, MRREVO14F_RADAR_START_ADDR),
(CAR.HYUNDAI_IONIQ_5, MRR30_RADAR_START_ADDR),
(CAR.HYUNDAI_IONIQ_5_N, MRR30_RADAR_START_ADDR),
(CAR.KIA_EV6, MRR30_RADAR_START_ADDR),
(CAR.KIA_EV6_2025, MRR30_RADAR_START_ADDR),
(CAR.GENESIS_GV60_EV_1ST_GEN, MRR30_RADAR_START_ADDR),
(CAR.HYUNDAI_KONA_EV_2ND_GEN, MRR35_RADAR_START_ADDR),
(CAR.HYUNDAI_IONIQ_6, MRR35_RADAR_START_ADDR),
(CAR.HYUNDAI_IONIQ_9, MRR35_RADAR_START_ADDR),
@@ -152,6 +176,8 @@ class TestHyundaiFingerprint:
CP = CarInterface.get_params(candidate, fingerprint, [], False, False, False, None)
assert CP.radarUnavailable != radar
assert get_radar_track_config(CAR.HYUNDAI_KONA_EV_2022).bus == 1
assert get_radar_track_config(CAR.HYUNDAI_IONIQ_5).bus == 0
assert get_radar_track_config(CAR.HYUNDAI_IONIQ_6).start_addr == MRR35_RADAR_START_ADDR
fingerprint = gen_empty_fingerprint()
fingerprint[1][MRR35_RADAR_START_ADDR] = 24
@@ -245,6 +271,14 @@ class TestHyundaiFingerprint:
sonata = CarInterface.get_params(CAR.HYUNDAI_SONATA, fingerprint, [], False, False, False, None)
assert sonata.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON
fingerprint = gen_empty_fingerprint()
fingerprint[0][0x50C] = 8
forte_non_scc = CarInterface.get_params(CAR.KIA_FORTE_2021_NON_SCC, fingerprint, [], False, False, False, None)
assert forte_non_scc.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON
g90 = CarInterface.get_params(CAR.GENESIS_G90, gen_empty_fingerprint(), [], False, False, False, None)
assert g90.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON
sonata_without_lda = CarInterface.get_params(CAR.HYUNDAI_SONATA, gen_empty_fingerprint(), [], False, False, False, None)
assert not (sonata_without_lda.safetyConfigs[-1].safetyParam & HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON)
@@ -255,6 +289,21 @@ class TestHyundaiFingerprint:
elantra_hev = CarInterface.get_params(CAR.HYUNDAI_ELANTRA_HEV_2022_NON_SCC, gen_empty_fingerprint(), [], True, False, False, None)
assert elantra_hev.flags & HyundaiFlags.HYBRID
kona = CarInterface.get_params(CAR.HYUNDAI_KONA_NON_SCC, gen_empty_fingerprint(), [], True, False, False, None)
assert not (kona.flags & HyundaiFlags.NON_SCC_RADAR_FCA)
assert kona.radarUnavailable
fingerprint = gen_empty_fingerprint()
fingerprint[0][0x38d] = 8
fingerprint[1][MRREVO14F_RADAR_START_ADDR] = 8
kona_radar_fca = CarInterface.get_params(CAR.HYUNDAI_KONA_NON_SCC, fingerprint, [], True, False, False, None)
assert kona_radar_fca.flags & HyundaiFlags.NON_SCC_RADAR_FCA
assert not kona_radar_fca.radarUnavailable
car_fw = [CarParams.CarFw(ecu=Ecu.fwdRadar, fwVersion=b"", address=0x7d0, brand="hyundai")]
kona_radar_fw = CarInterface.get_params(CAR.HYUNDAI_KONA_NON_SCC, gen_empty_fingerprint(), car_fw, True, False, False, None)
assert kona_radar_fw.flags & HyundaiFlags.NON_SCC_RADAR_FCA
forte_2019 = CarInterface.get_params(CAR.KIA_FORTE_2019_NON_SCC, gen_empty_fingerprint(), [], True, False, False, None)
assert forte_2019.flags & HyundaiFlags.NON_SCC_NO_FCA
assert not (forte_2019.flags & HyundaiFlags.NON_SCC_RADAR_FCA)
@@ -310,6 +359,46 @@ class TestHyundaiFingerprint:
assert canfd_alt_buttons_cp.flags & HyundaiFlags.CANFD_ALT_BUTTONS
assert not canfd_alt_buttons_fpcp.redneckCruiseAvailable
def test_hyundai_full_long_keeps_redneck_cruise_disabled(self, monkeypatch):
class FakeParams:
def __init__(self, *args, **kwargs):
pass
@staticmethod
def get_bool(key):
return key == "RedneckCruise"
toggles = get_test_toggles()
monkeypatch.setattr("opendbc.car.interfaces.Params", FakeParams)
for candidate in (CAR.HYUNDAI_SONATA, CAR.KIA_FORTE):
CP = CarInterface.get_params(candidate, gen_empty_fingerprint(), [], True, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(candidate, gen_empty_fingerprint(), [], CP, toggles)
assert CP.openpilotLongitudinalControl
assert not FPCP.redneckCruiseAvailable
assert FPCP.pcmCruiseSpeed
def test_hyundai_scc_stock_long_keeps_redneck_cruise_disabled(self, monkeypatch):
class FakeParams:
def __init__(self, *args, **kwargs):
pass
@staticmethod
def get_bool(key):
return key == "RedneckCruise"
toggles = get_test_toggles()
monkeypatch.setattr("opendbc.car.interfaces.Params", FakeParams)
for candidate in (CAR.HYUNDAI_SONATA, CAR.KIA_FORTE, CAR.HYUNDAI_IONIQ_6):
CP = CarInterface.get_params(candidate, gen_empty_fingerprint(), [], False, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(candidate, gen_empty_fingerprint(), [], CP, toggles)
assert not CP.openpilotLongitudinalControl
assert not FPCP.redneckCruiseAvailable
assert FPCP.pcmCruiseSpeed
def test_palisade_2023_pause_resume_button_maps_to_enable(self):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.HYUNDAI_PALISADE_2023, gen_empty_fingerprint(), [], True, False, False, toggles)
@@ -413,6 +502,24 @@ class TestHyundaiFingerprint:
def test_kona_ev_non_scc_has_no_dedicated_fw_coverage(self):
assert CAR.HYUNDAI_KONA_EV_NON_SCC not in FW_VERSIONS
def test_kona_non_scc_fca_radar_fw_is_optional(self):
fw_versions = FW_VERSIONS[CAR.HYUNDAI_KONA_NON_SCC]
car_fw = [
CarParams.CarFw(
ecu=ecu,
fwVersion=versions[0],
address=address,
subAddress=0 if sub_address is None else sub_address,
brand="hyundai",
)
for (ecu, address, sub_address), versions in fw_versions.items()
if ecu != Ecu.fwdRadar
]
exact, matches = match_fw_to_car(car_fw, "", allow_exact=True, allow_fuzzy=False, log=False)
assert exact
assert CAR.HYUNDAI_KONA_NON_SCC in matches
def test_kia_forte_2019_non_scc_does_not_require_fca11_or_scc12(self):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.KIA_FORTE_2019_NON_SCC, gen_empty_fingerprint(), [], True, False, False, toggles)
@@ -530,6 +637,78 @@ class TestHyundaiFingerprint:
ret = update(0, 3)
assert any(be.type == ButtonType.altButton2 and not be.pressed for be in ret.buttonEvents)
def test_forte_non_scc_clu13_lkas_button_event(self):
toggles = get_test_toggles()
fingerprint = gen_empty_fingerprint()
fingerprint[0][0x50C] = 8
CP = CarInterface.get_params(CAR.KIA_FORTE_2021_NON_SCC, fingerprint, [], False, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(CAR.KIA_FORTE_2021_NON_SCC, fingerprint, [], CP, toggles)
car_state = CarState(CP, FPCP)
can_parsers = car_state.get_can_parsers(CP)
packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
def update(lkas_button: int, frame: int):
msg = packer.make_can_msg("CLU13", 0, {
"CF_Clu_LdwsLkasSW": lkas_button,
})
can_parsers[Bus.pt].update([(frame, [msg])])
return car_state.update(can_parsers, toggles)[0]
update(0, 1)
ret = update(1, 2)
assert any(be.type == ButtonType.lkas and be.pressed for be in ret.buttonEvents)
ret = update(0, 3)
assert any(be.type == ButtonType.lkas and not be.pressed for be in ret.buttonEvents)
def test_sonata_hybrid_uses_alt_bus_lkas_parser(self):
toggles = get_test_toggles()
fingerprint = gen_empty_fingerprint()
fingerprint[0][0x391] = 8
fingerprint[1][0x50C] = 8
CP = CarInterface.get_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], False, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], CP, toggles)
car_state = CarState(CP, FPCP)
can_parsers = car_state.get_can_parsers(CP)
assert Bus.alt in can_parsers
def test_sonata_hybrid_alt_bus_clu13_lkas_button_event(self):
toggles = get_test_toggles()
fingerprint = gen_empty_fingerprint()
fingerprint[0][0x391] = 8
fingerprint[1][0x50C] = 8
CP = CarInterface.get_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], False, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], CP, toggles)
car_state = CarState(CP, FPCP)
can_parsers = car_state.get_can_parsers(CP)
packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
def update(lkas_button: int, frame: int):
msg = packer.make_can_msg("CLU13", 1, {
"CF_Clu_SWL_Stat": lkas_button,
})
can_parsers[Bus.alt].update([(frame, [msg])])
return car_state.update(can_parsers, toggles)[0]
update(0, 1)
ret = update(4, 2)
assert any(be.type == ButtonType.lkas and be.pressed for be in ret.buttonEvents)
assert any(be.type == ButtonType.lkas and not be.pressed for be in ret.buttonEvents)
def test_genesis_g90_does_not_use_alt_bus_lkas_parser(self):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.GENESIS_G90, gen_empty_fingerprint(), [], False, False, False, toggles)
FPCP = CarInterface.get_starpilot_params(CAR.GENESIS_G90, gen_empty_fingerprint(), [], CP, toggles)
car_state = CarState(CP, FPCP)
can_parsers = car_state.get_can_parsers(CP)
assert Bus.alt not in can_parsers
def test_ioniq_6_longitudinal_params_match_canfd_tune(self):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles)
@@ -988,11 +1167,11 @@ class TestHyundaiFingerprint:
assert parser.vl["FCA12"]["FCA_DrvSetState"] == 2
assert parser.vl["FCA12"]["FCA_USM"] == 2
def test_sportage_angle_steering_uses_lfa_and_adas_cmd_with_send_lfa(self):
def test_angle_steering_uses_lfa_and_adas_cmd_with_send_lfa(self):
fingerprint = gen_empty_fingerprint()
cam_can = CanBus(None, fingerprint).CAM
fingerprint[cam_can][0xCB] = 24
CP = CarInterface.get_params(CAR.KIA_SPORTAGE_HEV_2026, fingerprint, [], False, False, False, None)
CP = CarInterface.get_params(CAR.HYUNDAI_SANTA_FE_HEV_5TH_GEN, fingerprint, [], False, False, False, None)
assert CP.flags & HyundaiFlags.SEND_LFA
assert CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING
@@ -1295,34 +1474,6 @@ class TestHyundaiFingerprint:
]
assert hyundaicanfd.create_ioniq_6_cluster_lane_change_messages(can_bus, 5, "none") == []
def test_sportage_angle_jerk_override_is_scoped(self):
sportage = CarParams.new_message()
sportage.carFingerprint = CAR.KIA_SPORTAGE_HEV_2026
sportage.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_ANGLE_STEERING)
comparison_angle = CarParams.new_message()
comparison_angle.carFingerprint = CAR.KIA_EV6
comparison_angle.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_ANGLE_STEERING)
ioniq6 = CarParams.new_message()
ioniq6.carFingerprint = CAR.HYUNDAI_IONIQ_6
ioniq6.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING | HyundaiFlags.CANFD_LKA_STEERING_ALT)
sportage_params = CarControllerParams(sportage)
sportage_low_speed_params = CarControllerParams(sportage, vEgoRaw=5.0)
sportage_high_speed_params = CarControllerParams(sportage, vEgoRaw=20.0)
comparison_params = CarControllerParams(comparison_angle)
ioniq6_params = CarControllerParams(ioniq6)
assert sportage_params.ANGLE_LIMITS.MAX_LATERAL_JERK < comparison_params.ANGLE_LIMITS.MAX_LATERAL_JERK
assert sportage_high_speed_params.ANGLE_LIMITS.MAX_LATERAL_JERK == sportage_params.ANGLE_LIMITS.MAX_LATERAL_JERK
assert sportage_low_speed_params.ANGLE_LIMITS.MAX_LATERAL_JERK > sportage_high_speed_params.ANGLE_LIMITS.MAX_LATERAL_JERK
assert sportage_low_speed_params.ANGLE_LIMITS.MAX_LATERAL_JERK < comparison_params.ANGLE_LIMITS.MAX_LATERAL_JERK
assert sportage_params.ANGLE_LIMITS.STEER_ANGLE_MAX > comparison_params.ANGLE_LIMITS.STEER_ANGLE_MAX
assert sportage_params.ANGLE_LIMITS.MAX_LATERAL_ACCEL > comparison_params.ANGLE_LIMITS.MAX_LATERAL_ACCEL
assert sportage_params.ANGLE_LIMITS.MAX_ANGLE_RATE > comparison_params.ANGLE_LIMITS.MAX_ANGLE_RATE
assert comparison_params.ANGLE_LIMITS.MAX_LATERAL_JERK == ioniq6_params.ANGLE_LIMITS.MAX_LATERAL_JERK
def test_ioniq_5_canfd_aux_messages_are_optional(self):
toggles = get_test_toggles()
fingerprint = gen_empty_fingerprint()
+49 -36
View File
@@ -1,9 +1,9 @@
import re
from dataclasses import dataclass, field, replace
from dataclasses import dataclass, field
from enum import IntFlag
from opendbc.car import ACCELERATION_DUE_TO_GRAVITY, Bus, CarSpecs, DbcDict, PlatformConfig, Platforms, uds
from opendbc.car.lateral import AngleSteeringLimits, ISO_LATERAL_ACCEL, ISO_LATERAL_JERK
from opendbc.car.lateral import AngleSteeringLimits, ISO_LATERAL_ACCEL
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.structs import CarParams
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts, SupportType
@@ -11,14 +11,8 @@ from opendbc.car.fw_query_definitions import FwQueryConfig, Request, p16
Ecu = CarParams.Ecu
AVERAGE_ROAD_ROLL = 0.06 # conservative roll margin used by Hyundai CAN-FD angle steering safety
SPORTAGE_HEV_2026_MAX_LATERAL_ACCEL = 3.6
SPORTAGE_HEV_2026_BASE_LATERAL_JERK = 3.25
SPORTAGE_HEV_2026_LOW_SPEED_JERK_BOOST = 0.55
SPORTAGE_HEV_2026_LOW_SPEED_JERK_SPEED = 11.0
SPORTAGE_HEV_2026_LOW_SPEED_JERK_WIDTH = 5.0
SPORTAGE_HEV_2026_MAX_ANGLE_RATE = 6.5
SPORTAGE_HEV_2026_STEER_ANGLE_MAX = 220.0
HYUNDAI_MANDO_FRONT_RADAR_DBC = "hyundai_kia_mando_front_radar_generated"
HYUNDAI_MRREVO14F_RADAR_DBC = "hyundai_mrrevo14f_radar_generated"
HYUNDAI_MRR30_RADAR_DBC = "hyundai_mrr30_radar_generated"
HYUNDAI_MRR35_RADAR_DBC = "hyundai_mrr35_radar_generated"
@@ -27,16 +21,13 @@ class CarControllerParams:
ACCEL_MIN = -3.5 # m/s
ACCEL_MAX = 3.5 # m/s
ANGLE_LIMITS: AngleSteeringLimits = AngleSteeringLimits(
180,
360,
([], []),
([], []),
MAX_LATERAL_ACCEL=ISO_LATERAL_ACCEL + (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL),
MAX_LATERAL_JERK=ISO_LATERAL_JERK + (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL),
MAX_LATERAL_JERK=3.0 + (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL),
MAX_ANGLE_RATE=5,
)
ANGLE_MAX_TORQUE_REDUCTION_GAIN = 1.0
ANGLE_MIN_TORQUE_REDUCTION_GAIN = 0.6
ANGLE_ACTIVE_TORQUE_REDUCTION_GAIN = 0.6
def __init__(self, CP, vEgoRaw=100.):
self.ANGLE_LIMITS = self.ANGLE_LIMITS
@@ -63,21 +54,6 @@ class CarControllerParams:
if CP.flags & HyundaiFlags.CANFD_ANGLE_STEERING:
self.STEER_THRESHOLD = 175
# The Sportage angle port still needs more authority in real turns than the
# fully calmed branch-wide ceiling allows, but the old low-speed jerk boost
# made the 3-20 degree band angry and ping-pongy as the car slowed down.
# Split the difference:
# - keep a calmer low-speed boost that fades out earlier
# - give the car a little more true turn headroom through accel/rate limits
if CP.carFingerprint == CAR.KIA_SPORTAGE_HEV_2026:
sportage_low_speed_weight = min(max((SPORTAGE_HEV_2026_LOW_SPEED_JERK_SPEED - vEgoRaw) / SPORTAGE_HEV_2026_LOW_SPEED_JERK_WIDTH, 0.0), 1.0)
sportage_lateral_jerk = SPORTAGE_HEV_2026_BASE_LATERAL_JERK + (SPORTAGE_HEV_2026_LOW_SPEED_JERK_BOOST * sportage_low_speed_weight)
self.ANGLE_LIMITS = replace(self.ANGLE_LIMITS,
STEER_ANGLE_MAX=SPORTAGE_HEV_2026_STEER_ANGLE_MAX,
MAX_LATERAL_ACCEL=SPORTAGE_HEV_2026_MAX_LATERAL_ACCEL + (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL),
MAX_LATERAL_JERK=sportage_lateral_jerk + (ACCELERATION_DUE_TO_GRAVITY * AVERAGE_ROAD_ROLL),
MAX_ANGLE_RATE=SPORTAGE_HEV_2026_MAX_ANGLE_RATE)
# To determine the limit for your car, find the maximum value that the stock LKAS will request.
# If the max stock LKAS request is <384, add your car to this list.
elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.HYUNDAI_ELANTRA, CAR.HYUNDAI_ELANTRA_GT_I30, CAR.HYUNDAI_IONIQ,
@@ -224,9 +200,12 @@ class HyundaiNonSccCarDocs(CarDocs):
@dataclass
class HyundaiPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_kia_generic"})
radar_dbc: str | None = None
def init(self):
if self.flags & HyundaiFlags.MANDO_RADAR:
if self.radar_dbc is not None:
self.dbc_dict = {Bus.pt: "hyundai_kia_generic", Bus.radar: self.radar_dbc}
elif self.flags & HyundaiFlags.MANDO_RADAR:
self.dbc_dict = {Bus.pt: "hyundai_kia_generic", Bus.radar: HYUNDAI_MANDO_FRONT_RADAR_DBC}
if self.flags & HyundaiFlags.MIN_STEER_32_MPH:
@@ -250,8 +229,12 @@ class HyundaiCanFDPlatformConfig(PlatformConfig):
@dataclass
class HyundaiNonSccPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "hyundai_kia_generic"})
radar_dbc: str | None = None
def init(self):
if self.radar_dbc is not None:
self.dbc_dict = {Bus.pt: "hyundai_kia_generic", Bus.radar: self.radar_dbc}
self.flags |= HyundaiFlags.NON_SCC
if self.flags & HyundaiFlags.MIN_STEER_32_MPH:
@@ -313,7 +296,7 @@ class CAR(Platforms):
HYUNDAI_IONIQ = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Ioniq Hybrid 2017-19", car_parts=CarParts.common([CarHarness.hyundai_c]))],
CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385),
flags=HyundaiFlags.HYBRID | HyundaiFlags.MIN_STEER_32_MPH,
flags=HyundaiFlags.HYBRID | HyundaiFlags.MIN_STEER_32_MPH | HyundaiFlags.MANDO_RADAR,
)
HYUNDAI_IONIQ_HEV_2022 = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Ioniq Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_h]))],
@@ -369,6 +352,7 @@ class CAR(Platforms):
[HyundaiCarDocs("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o]))],
CarSpecs(mass=1743, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385),
flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.EV | HyundaiFlags.ALT_LIMITS,
radar_dbc=HYUNDAI_MRREVO14F_RADAR_DBC,
)
HYUNDAI_KONA_EV_2ND_GEN = HyundaiCanFDPlatformConfig(
[
@@ -400,17 +384,17 @@ class CAR(Platforms):
[HyundaiCarDocs("Hyundai Santa Fe 2021-23", "All", video="https://youtu.be/VnHzSTygTS4",
car_parts=CarParts.common([CarHarness.hyundai_l]))],
HYUNDAI_SANTA_FE.specs,
flags=HyundaiFlags.CHECKSUM_CRC8,
flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8,
)
HYUNDAI_SANTA_FE_HEV_2022 = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))],
HYUNDAI_SANTA_FE.specs,
flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID,
flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID,
)
HYUNDAI_SANTA_FE_PHEV_2022 = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))],
HYUNDAI_SANTA_FE.specs,
flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID,
flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID,
)
HYUNDAI_SANTA_FE_HEV_5TH_GEN = HyundaiCanFDPlatformConfig(
[
@@ -749,6 +733,7 @@ class CAR(Platforms):
],
CarSpecs(mass=2055, wheelbase=2.9, steerRatio=16, tireStiffnessFactor=0.65),
flags=HyundaiFlags.EV,
radar_dbc=HYUNDAI_MRR30_RADAR_DBC,
)
KIA_EV6_2025 = HyundaiCanFDPlatformConfig(
[
@@ -783,6 +768,7 @@ class CAR(Platforms):
],
CarSpecs(mass=2205, wheelbase=2.9, steerRatio=17.6),
flags=HyundaiFlags.EV,
radar_dbc=HYUNDAI_MRR30_RADAR_DBC,
)
GENESIS_G70 = HyundaiPlatformConfig(
[HyundaiCarDocs("Genesis G70 2018", "All", car_parts=CarParts.common([CarHarness.hyundai_f]))],
@@ -875,6 +861,7 @@ class CAR(Platforms):
[HyundaiNonSccCarDocs("Hyundai Kona Non-SCC 2019", car_parts=CarParts.common([CarHarness.hyundai_b]))],
HYUNDAI_KONA.specs,
flags=HyundaiFlags.ALT_LIMITS,
radar_dbc=HYUNDAI_MRREVO14F_RADAR_DBC,
)
HYUNDAI_KONA_EV_NON_SCC = HyundaiNonSccPlatformConfig(
[HyundaiNonSccCarDocs("Hyundai Kona Electric Non-SCC 2019", car_parts=CarParts.common([CarHarness.hyundai_g]))],
@@ -920,6 +907,22 @@ CANCEL_BUTTON_ENABLE_CARS = frozenset({
})
# These classic HKG platforms publish the LKAS button on CLU13 over the alt bus.
# Keep G90 excluded until its alt-bus path is route-proven without the recent
# engage/disengage regression.
ALT_BUS_LDA_BUTTON_CARS = frozenset({
CAR.HYUNDAI_SONATA,
CAR.HYUNDAI_SONATA_HYBRID,
})
# On these Sonata layouts the alt-bus LKAS button pulses through the CLU13
# steering-wheel-status field instead of the dedicated LKAS bit.
ALT_BUS_LDA_BUTTON_SWL_STAT_CARS = frozenset({
CAR.HYUNDAI_SONATA,
CAR.HYUNDAI_SONATA_HYBRID,
})
def hyundai_cancel_button_enables_cruise(car_fingerprint) -> bool:
return car_fingerprint in CANCEL_BUTTON_ENABLE_CARS
@@ -1081,6 +1084,7 @@ FW_QUERY_CONFIG = FwQueryConfig(
Ecu.abs: [CAR.HYUNDAI_PALISADE, CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SANTA_FE_2022, CAR.KIA_K5_2021, CAR.HYUNDAI_ELANTRA_2021,
CAR.HYUNDAI_SANTA_FE, CAR.HYUNDAI_KONA_EV_2022, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_CUSTIN_1ST_GEN, CAR.KIA_SORENTO,
CAR.KIA_CEED, CAR.KIA_SELTOS],
Ecu.fwdRadar: [CAR.HYUNDAI_KONA_NON_SCC],
},
extra_ecus=[
(Ecu.adas, 0x730, None), # ADAS Driving ECU on platforms with LKA steering
@@ -1110,8 +1114,17 @@ CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC) # TODO: merge with
# CAN-FD cars with ADAS ECUs that work with the communication-control path.
CANFD_SECURITYACCESS_CAR = {CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_6, CAR.HYUNDAI_KONA_EV_2ND_GEN}
CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE) - CANFD_SECURITYACCESS_CAR # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR
CANFD_RADAR_LIVE_LONGITUDINAL_CAR = {CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_6}
RADAR_LIVE_LONGITUDINAL_CAR = CANFD_RADAR_LIVE_LONGITUDINAL_CAR | {CAR.GENESIS_G90}
CANFD_RADAR_LIVE_LONGITUDINAL_CAR = {CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_6, CAR.KIA_EV6, CAR.GENESIS_GV60_EV_1ST_GEN}
RADAR_LIVE_LONGITUDINAL_CAR = CANFD_RADAR_LIVE_LONGITUDINAL_CAR | {
CAR.HYUNDAI_IONIQ,
CAR.HYUNDAI_KONA_EV_2022,
CAR.HYUNDAI_SANTA_FE_2022,
CAR.HYUNDAI_SANTA_FE_HEV_2022,
CAR.HYUNDAI_SANTA_FE_PHEV_2022,
CAR.HYUNDAI_SONATA,
CAR.HYUNDAI_SONATA_HYBRID,
CAR.GENESIS_G90,
}
CAMERA_SCC_CAR = CAR.with_flags(HyundaiFlags.CAMERA_SCC)
+14 -5
View File
@@ -20,7 +20,7 @@ from opendbc.car.common.simple_kalman import KF1D, get_kalman_gain
from opendbc.car.gm.values import CAR as GM
from opendbc.car.honda.values import CAR as HONDA, HONDA_BOSCH, HondaFlags, HondaSafetyFlags, HondaStarPilotFlags
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import CAR as HYUNDAI, CANFD_CAR, HyundaiFlags, HyundaiStarPilotFlags, HyundaiStarPilotSafetyFlags
from opendbc.car.hyundai.values import CAR as HYUNDAI, CANFD_CAR, HyundaiFlags, HyundaiStarPilotFlags, HyundaiStarPilotSafetyFlags, ALT_BUS_LDA_BUTTON_CARS
from opendbc.car.mock.values import CAR as MOCK
from opendbc.car.toyota.values import CAR as TOYOTA, NO_DSU_CAR, TSS2_CAR, UNSUPPORTED_DSU_CAR, ToyotaStarPilotFlags, ToyotaSafetyFlags
from opendbc.car.values import PLATFORMS
@@ -199,6 +199,7 @@ class CarInterfaceBase(ABC):
def get_starpilot_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[structs.CarParams.CarFw], CP: structs.CarParams, starpilot_toggles: SimpleNamespace):
fp_ret = custom.StarPilotCarParams.new_message()
fp_ret.pcmCruiseSpeed = True
params = Params(return_defaults=True)
platform = PLATFORMS[candidate]
@@ -228,14 +229,22 @@ class CarInterfaceBase(ABC):
if 0x1FA in fingerprint[CAN.ECAN]:
fp_ret.flags |= HyundaiStarPilotFlags.SPEED_LIMIT_AVAILABLE.value
fp_ret.redneckCruiseAvailable = not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS)
if fp_ret.redneckCruiseAvailable and Params(return_defaults=True).get_bool("RedneckCruise") and \
fp_ret.redneckCruiseAvailable = bool(CP.flags & HyundaiFlags.NON_SCC) and not bool(CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS)
if fp_ret.redneckCruiseAvailable and params.get_bool("RedneckCruise") and \
not CP.openpilotLongitudinalControl:
fp_ret.pcmCruiseSpeed = False
if 0x391 in fingerprint[0] or CP.flags & HyundaiFlags.CAN_CANFD_BLENDED:
hyundai_has_lda_button = (
0x391 in fingerprint[0] or
0x50C in fingerprint[0] or
candidate in ALT_BUS_LDA_BUTTON_CARS or
bool(CP.flags & HyundaiFlags.CAN_CANFD_BLENDED)
)
if hyundai_has_lda_button:
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.HAS_LDA_BUTTON.value
if starpilot_toggles.always_on_lateral_lkas:
# LKASButtonControl == 9 means BUTTON_FUNCTIONS["AOL_TOGGLE"] in starpilot_variables.
if params.get_bool("AlwaysOnLateral") and params.get_int("LKASButtonControl") == 9:
fp_ret.safetyConfigs[-1].safetyParam |= HyundaiStarPilotSafetyFlags.AOL_LKAS_ON_ENGAGE.value
elif platform in TOYOTA:
fp_ret.canUsePedal = not CP.autoResumeSng
@@ -65,6 +65,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"HONDA_E" = "HONDA_CIVIC_BOSCH"
"BUICK_LACROSSE" = "CHEVROLET_VOLT"
"BUICK_LACROSSE_ASCM" = "CHEVROLET_VOLT"
"BUICK_REGAL" = "CHEVROLET_VOLT"
"CADILLAC_ESCALADE_ASCM" = "CADILLAC_ESCALADE"
"CADILLAC_ESCALADE_ESV" = "CHEVROLET_VOLT"
@@ -25,7 +25,7 @@ ACCEL_WINDUP_LIMIT = 4.0 * DT_CTRL * 3 # m/s^2 / frame
ACCEL_WINDDOWN_LIMIT = -4.0 * DT_CTRL * 3 # m/s^2 / frame
ACCEL_PID_UNWIND = 0.03 * DT_CTRL * 3 # m/s^2 / frame
PRIUS_INTEGRAL_MISMATCH_UNWIND = 8.0
PRIUS_POSITIVE_FEEDFORWARD_SCALE = 0.5
PRIUS_POSITIVE_FEEDFORWARD_SCALE = 0.7
MAX_PITCH_COMPENSATION = 1.5 # m/s^2
TOYOTA_COAST_BRAKE_MIN_SPEED = 15.0 # m/s
@@ -142,6 +142,25 @@ def limit_interceptor_stopping_accel(pcm_accel_cmd: float, target_accel: float,
return max(pcm_accel_cmd, max(stop_floor, planner_floor))
def limit_prius_stopping_accel(pcm_accel_cmd: float, target_accel: float, stopping: bool, v_ego: float, lead_visible: bool) -> float:
if not stopping or pcm_accel_cmd >= 0.0 or v_ego >= 1.5:
return pcm_accel_cmd
# Prius can hold onto a stale full negative stop command at standstill even after the
# planner has already softened. Keep enough brake to hold the stop, but let the command
# unwind toward the live planner target so launches are not delayed and stop transitions
# are less abrupt.
if target_accel <= -1.8:
return pcm_accel_cmd
stop_floor = float(np.interp(v_ego,
[0.0, 0.2, 0.5, 0.9, 1.5],
[-0.96, -1.00, -1.08, -1.18, -1.35] if lead_visible else [-0.84, -0.88, -0.96, -1.08, -1.24]))
target_buffer = float(np.interp(v_ego, [0.0, 0.5, 1.5], [0.06, 0.10, 0.16]))
planner_floor = float(target_accel) - target_buffer
return max(pcm_accel_cmd, max(stop_floor, planner_floor))
class CarController(CarControllerBase):
def __init__(self, dbc_names, CP):
super().__init__(dbc_names, CP)
@@ -410,6 +429,8 @@ class CarController(CarControllerBase):
if self.CP.enableGasInterceptorDEPRECATED:
pcm_accel_cmd = limit_interceptor_pcm_accel(pcm_accel_cmd, actuators.accel, stopping, CS.out.vEgo)
pcm_accel_cmd = limit_interceptor_stopping_accel(pcm_accel_cmd, actuators.accel, stopping, CS.out.vEgo, bool(hud_control.leadVisible))
elif self.CP.carFingerprint == CAR.TOYOTA_PRIUS:
pcm_accel_cmd = limit_prius_stopping_accel(pcm_accel_cmd, actuators.accel, stopping, CS.out.vEgo, lead)
pcm_accel_cmd = float(np.clip(pcm_accel_cmd, self.params.ACCEL_MIN, self.params.ACCEL_MAX))
@@ -7,7 +7,8 @@ from opendbc.can import CANPacker, CANParser
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict
from opendbc.car.toyota import toyotacan
from opendbc.car.toyota.carcontroller import CarController, limit_interceptor_pcm_accel, limit_interceptor_stopping_accel, update_permit_braking
from opendbc.car.toyota.carcontroller import CarController, limit_interceptor_pcm_accel, limit_interceptor_stopping_accel, \
limit_prius_stopping_accel, update_permit_braking
from opendbc.car.toyota.carstate import calculate_interceptor_gas_pressed
from opendbc.car.toyota.fingerprints import FW_VERSIONS
from opendbc.car.toyota.interface import CarInterface
@@ -252,6 +253,14 @@ class TestToyotaCarController:
assert update_permit_braking(False, 0.10, True, True, 25.0, False) is True
assert update_permit_braking(False, 0.10, False, False, 25.0, False) is True
def test_prius_stopping_accel_unwinds_stale_stop_hold(self):
limited = limit_prius_stopping_accel(-3.28, -0.05, True, 0.0, True)
assert -1.5 < limited < 0.0
def test_prius_stopping_accel_keeps_hard_stop_commands(self):
limited = limit_prius_stopping_accel(-3.28, -2.0, True, 0.0, True)
assert limited == -3.28
def test_sng_hack_clears_existing_standstill_latch(self):
controller = self._make_controller(standstill_req=True, last_standstill=True)
@@ -1 +0,0 @@
_*generated.dbc
@@ -0,0 +1,189 @@
CM_ "Generated from _stellantis_common.dbc"
BO_ 35 STEERING: 8 XXX
SG_ STEERING_ANGLE : 5|14@0+ (0.5,-2048) [-2048|2047] "deg" XXX
SG_ STEERING_RATE : 21|14@0+ (0.5,-2048) [-2048|2047] "deg/s" XXX
SG_ STEERING_ANGLE_HP : 48|4@1+ (0.1,-0.4) [-0.4|0.4] "deg" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 37 ECM_1: 8 XXX
SG_ ENGINE_RPM : 7|16@0+ (1,0) [0|65535] "" XXX
SG_ ENGINE_TORQUE : 20|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ EXPECTED_ENGINE_TORQUE : 36|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 181 ECM_TRQ: 8 XXX
SG_ ENGINE_TORQ_MAX : 4|13@0+ (.25,-500) [-500|1547.5] "NM" XXX
SG_ ENGINE_TORQ_MIN : 20|13@0+ (.25,-500) [-500|1547.5] "NM" XXX
BO_ 121 ESP_8: 8 XXX
SG_ BRK_PRESSURE : 3|12@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Stopped : 7|1@0+ (1,0) [0|1] "" XXX
SG_ BRAKE_PEDAL : 19|12@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Speed : 39|16@0+ (0.0078125,0) [0|511.984375] "km/h" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 123 ECM_2: 7 XXX
SG_ ACC_TORQUE_REQ_ENABLE : 5|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_ENABLE : 6|1@1+ (1,0) [0|0] "" XXX
SG_ TCM_TORQUE_REQ_ENABLE : 7|1@1+ (1,0) [0|0] "" XXX
SG_ Accelerator_Position : 16|8@1+ (0.4,0) [0|100] "%" XXX
SG_ CRUISE_OVERRIDE : 31|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 47|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 55|8@0+ (1,0) [0|0] "" XXX
BO_ 131 ESP_1: 8 XXX
SG_ Brake_State : 0|2@1+ (1,0) [0|0] "" XXX
SG_ Brake_Pedal_State : 2|2@1+ (1,0) [0|0] "" XXX
SG_ ACC_Engaged : 15|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_Enabled : 23|1@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Speed : 33|10@0+ (0.5,0) [0|511] "km/h" XXX
SG_ ACC_OFF_REQ : 39|2@0+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ BRAKE_PRESSED_ACC : 6|1@0+ (1,0) [0|3] "" XXX
BO_ 113 ESP_2: 8 ESC
SG_ ESC_TORQUE_REQ : 4|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ ACC_TORQUE_REQ_ENABLE : 5|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_MAX : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_MIN : 7|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_TORQUE_REQ : 20|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ TCS_ACTIVE : 21|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_TORQUE_REQ_MAX : 22|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_BRK_PREP : 40|1@1+ (1,0) [0|0] "" XXX
SG_ DISABLE_FUEL_SHUTOFF : 47|1@1+ (1,0) [0|0] "" XXX
SG_ DAS_REQ_ACTIVE : 48|3@1+ (1,0) [0|0] "" XXX
SG_ COLLISION_BRK_PREP : 51|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX
BO_ 139 ESP_6: 8 XXX
SG_ WHEEL_SPEED_FL : 5|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_SPEED_FR : 21|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_SPEED_RL : 37|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_MOVING_1 : 38|1@0+ (1,0) [0|1] "" XXX
SG_ WHEEL_SPEED_RR : 53|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_MOVING_2 : 54|1@0+ (1,0) [0|1] "" XXX
BO_ 147 Transmission_Status: 8 XXX
SG_ Gear_State : 2|3@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 464 ORC_1: 8 XXX
SG_ SEATBELT_DRIVER_UNLATCHED : 13|1@0+ (1,0) [0|1] "" XXX
BO_ 153 DAS_3: 8 XXX
SG_ ENGINE_TORQUE_REQUEST : 4|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ ENGINE_TORQUE_REQUEST_MAX : 7|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_STANDSTILL : 5|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_GO : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_DECEL : 19|12@0+ (0.004885,-16) [-16|4] "m/s2" XXX
SG_ ACC_AVAILABLE : 20|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_ACTIVE : 21|1@0+ (1,0) [0|1] "" XXX
SG_ DISABLE_FUEL_SHUTOFF : 23|1@1+ (1,0) [0|0] "" XXX
SG_ GR_MAX_REQ : 32|4@1+ (1,0) [0|0] "" XXX
SG_ ACC_DECEL_REQ : 36|3@1+ (1,0) [0|0] "" XXX
SG_ ACC_FAULTED : 46|2@1+ (1,0) [0|0] "" XXX
SG_ COLLISION_BRK_PREP : 48|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_BRK_PREP : 49|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 232 DAS_4: 8 XXX
SG_ ACC_SET_SPEED_KPH : 15|8@0+ (1,0) [0|3] "km/h" XXX
SG_ ACC_SET_SPEED_MPH : 23|8@0+ (1,0) [0|3] "mph" XXX
SG_ ACC_DISTANCE_CONFIG_1 : 1|2@0+ (1,0) [0|3] "" XXX
SG_ ACC_DISTANCE_CONFIG_2 : 41|2@0+ (1,0) [0|3] "" XXX
SG_ SPEED_DIGITAL : 63|8@0+ (1,0) [0|255] "mph" XXX
SG_ ACC_STATE : 38|3@0+ (1,0) [0|7] "" XXX
SG_ FCW_OFF : 25|2@0+ (1,0) [0|3] "" XXX
SG_ FCW_ERROR : 27|2@0+ (1,0) [0|3] "" XXX
SG_ FCW_BRAKE_ENABLED : 29|1@0+ (1,0) [0|1] "" XXX
SG_ FCW_BRAKE_DISABLED : 47|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_FAULTED : 50|1@0+ (1,0) [0|1] "" XXX
BO_ 49 EPS_2: 8 XXX
SG_ LKAS_STATE : 23|4@0+ (1,0) [0|15] "" XXX
SG_ COLUMN_TORQUE : 2|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ TORQUE_OVERLAY_STATUS : 6|4@0+ (1,0) [0|15] "" XXX
SG_ EPS_TORQUE_MOTOR_RAW : 19|12@0+ (1,-2048) [-2048|2047] "" XXX
SG_ EPS_TORQUE_MOTOR : 34|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ LKAS_TEMPORARY_FAULT : 38|1@0+ (1,0) [0|1] "" XXX
SG_ AUTO_PARK_HAS_CONTROL_2 : 51|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 157 ECM_5: 8 XXX
SG_ Accelerator_Position : 0|8@1+ (0.4,0) [0|100] "%" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 177 CRUISE_BUTTONS: 3 XXX
SG_ ACC_Cancel : 0|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Distance_Dec : 1|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Accel : 2|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Decel : 3|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Resume : 4|1@0+ (1,0) [0|1] "" XXX
SG_ Cruise_OnOff : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_OnOff : 7|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Distance_Inc : 8|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 23|8@0+ (1,0) [0|255] "" XXX
BO_ 163 DAS_5: 8 XXX
SG_ FCW_STATE : 2|1@1+ (1,0) [0|0] "" XXX
SG_ FCW_DISTANCE : 3|2@1+ (1,0) [0|0] "" XXX
SG_ ACCFCW_MESSAGE : 12|4@1+ (1,0) [0|0] "" XXX
SG_ SET_SPEED_KPH : 24|8@1+ (1,0) [0|250] "km/h" XXX
SG_ WHEEL_TORQUE_REQUEST : 38|15@0+ (1,-7767) [-7767|24999] "Nm" XXX
SG_ WHEEL_TORQUE_REQUEST_ACTIVE : 39|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 213 EPB_1: 3 XXX
SG_ PARKING_BRAKE_STATUS : 11|3@0+ (1,0) [0|7] "" XXX
SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 23|8@0+ (1,0) [0|255] "" XXX
BO_ 250 DAS_6: 8 XXX
SG_ LKAS_ICON_COLOR : 1|2@0+ (1,0) [0|3] "" XXX
SG_ LKAS_LANE_LINES : 19|4@0+ (1,0) [0|1] "" XXX
SG_ LKAS_ALERTS : 27|4@0+ (1,0) [0|1] "" XXX
SG_ CAR_MODEL : 15|8@0+ (1,0) [0|255] "" XXX
SG_ AUTO_HIGH_BEAM_ON : 47|1@1+ (1,0) [0|0] "" XXX
SG_ LKAS_DISABLED : 56|1@1+ (1,0) [0|0] "" XXX
BO_ 720 BSM_1: 6 XXX
SG_ RIGHT_STATUS : 5|1@0+ (1,0) [0|1] "" XXX
SG_ LEFT_STATUS : 2|1@0+ (1,0) [0|1] "" XXX
BO_ 792 STEERING_LEVERS: 8 XXX
SG_ TURN_SIGNALS : 0|2@1+ (1,0) [0|3] "" XXX
SG_ HIGH_BEAM_PRESSED : 2|1@0+ (1,0) [0|3] "" XXX
BO_ 657 BCM_1: 8 XXX
SG_ DOOR_OPEN_FL : 17|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_FR : 18|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_RL : 19|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_RR : 20|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_TRUNK : 22|1@0+ (1,0) [0|1] "" XXX
SG_ PARKING_BRAKE_SWITCH : 23|1@0+ (1,0) [0|1] "" XXX
SG_ TURN_LIGHT_LEFT : 31|1@0+ (1,0) [0|1] "" XXX
SG_ TURN_LIGHT_RIGHT : 30|1@0+ (1,0) [0|1] "" XXX
SG_ HIGH_BEAM_DISPLAY : 58|1@0+ (1,0) [0|1] "" XXX
VAL_ 131 ACC_OFF_REQ 2 "PERMANENT" 1 "TEMPORARY" 0 "NONE"
VAL_ 147 Gear_State 4 "D" 2 "N" 1 "R" 0 "P" ;
VAL_ 213 PARKING_BRAKE_STATUS 3 "RELEASING" 2 "APPLYING" 1 "APPLIED" 0 "OFF" ;
CM_ SG_ 258 STEERING_ANGLE_HP "Steering angle high precision";
CM_ SG_ 264 ENGINE_TORQUE "Effective engine torque";
CM_ SG_ 264 EXPECTED_ENGINE_TORQUE "Expected Engine Torque based on target engine speed";
CM_ SG_ 678 LKAS_ICON_COLOR "3 is yellow, 2 is green, 1 is white, 0 is null";
CM_ SG_ 678 LKAS_LANE_LINES "0x01 transparent lines, 0x02 left white, 0x03 right white, 0x04 left yellow with car on top, 0x05 left yellow with car on top, 0x06 both white, 0x07 left yellow, 0x08 left yellow right white, 0x09 right yellow, 0x0a right yellow left white, 0x0b left yellow with car on top right white, 0x0c right yellow with car on top left white, (0x00, 0x0d, 0x0e, 0x0f) null";
CM_ SG_ 678 LKAS_ALERTS "(0x01, 0x02) lane sense off, (0x03, 0x04, 0x06) place hands on steering wheel, 0x07 lane departure detected + place hands on steering wheel, (0x08, 0x09) lane sense unavailable + clean front windshield, 0x0b lane sense and auto high beam unavailable + clean front windshield, 0x0c lane sense unavailable + service required, (0x00, 0x05, 0x0a, 0x0d, 0x0e, 0x0f) null";
@@ -0,0 +1,189 @@
CM_ "Generated from _stellantis_common.dbc"
BO_ 258 STEERING: 8 XXX
SG_ STEERING_ANGLE : 5|14@0+ (0.5,-2048) [-2048|2047] "deg" XXX
SG_ STEERING_RATE : 21|14@0+ (0.5,-2048) [-2048|2047] "deg/s" XXX
SG_ STEERING_ANGLE_HP : 48|4@1+ (0.1,-0.4) [-0.4|0.4] "deg" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 264 ECM_1: 8 XXX
SG_ ENGINE_RPM : 7|16@0+ (1,0) [0|65535] "" XXX
SG_ ENGINE_TORQUE : 20|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ EXPECTED_ENGINE_TORQUE : 36|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 280 ECM_TRQ: 8 XXX
SG_ ENGINE_TORQ_MAX : 4|13@0+ (.25,-500) [-500|1547.5] "NM" XXX
SG_ ENGINE_TORQ_MIN : 20|13@0+ (.25,-500) [-500|1547.5] "NM" XXX
BO_ 284 ESP_8: 8 XXX
SG_ BRK_PRESSURE : 3|12@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Stopped : 7|1@0+ (1,0) [0|1] "" XXX
SG_ BRAKE_PEDAL : 19|12@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Speed : 39|16@0+ (0.0078125,0) [0|511.984375] "km/h" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 288 ECM_2: 7 XXX
SG_ ACC_TORQUE_REQ_ENABLE : 5|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_ENABLE : 6|1@1+ (1,0) [0|0] "" XXX
SG_ TCM_TORQUE_REQ_ENABLE : 7|1@1+ (1,0) [0|0] "" XXX
SG_ Accelerator_Position : 16|8@1+ (0.4,0) [0|100] "%" XXX
SG_ CRUISE_OVERRIDE : 31|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 47|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 55|8@0+ (1,0) [0|0] "" XXX
BO_ 320 ESP_1: 8 XXX
SG_ Brake_State : 0|2@1+ (1,0) [0|0] "" XXX
SG_ Brake_Pedal_State : 2|2@1+ (1,0) [0|0] "" XXX
SG_ ACC_Engaged : 15|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_Enabled : 23|1@0+ (1,0) [0|1] "" XXX
SG_ Vehicle_Speed : 33|10@0+ (0.5,0) [0|511] "km/h" XXX
SG_ ACC_OFF_REQ : 39|2@0+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
SG_ BRAKE_PRESSED_ACC : 6|1@0+ (1,0) [0|3] "" XXX
BO_ 268 ESP_2: 8 ESC
SG_ ESC_TORQUE_REQ : 4|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ ACC_TORQUE_REQ_ENABLE : 5|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_MAX : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ESC_TORQUE_REQ_MIN : 7|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_TORQUE_REQ : 20|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ TCS_ACTIVE : 21|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_TORQUE_REQ_MAX : 22|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_BRK_PREP : 40|1@1+ (1,0) [0|0] "" XXX
SG_ DISABLE_FUEL_SHUTOFF : 47|1@1+ (1,0) [0|0] "" XXX
SG_ DAS_REQ_ACTIVE : 48|3@1+ (1,0) [0|0] "" XXX
SG_ COLLISION_BRK_PREP : 51|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|0] "" XXX
BO_ 344 ESP_6: 8 XXX
SG_ WHEEL_SPEED_FL : 5|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_SPEED_FR : 21|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_SPEED_RL : 37|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_MOVING_1 : 38|1@0+ (1,0) [0|1] "" XXX
SG_ WHEEL_SPEED_RR : 53|14@0+ (0.5,0) [0|8191] "rpm" XXX
SG_ WHEEL_MOVING_2 : 54|1@0+ (1,0) [0|1] "" XXX
BO_ 368 Transmission_Status: 8 XXX
SG_ Gear_State : 2|3@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 464 ORC_1: 8 XXX
SG_ SEATBELT_DRIVER_UNLATCHED : 13|1@0+ (1,0) [0|1] "" XXX
BO_ 500 DAS_3: 8 XXX
SG_ ENGINE_TORQUE_REQUEST : 4|13@0+ (0.25,-500) [-500|1547.5] "Nm" XXX
SG_ ENGINE_TORQUE_REQUEST_MAX : 7|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_STANDSTILL : 5|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_GO : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_DECEL : 19|12@0+ (0.004885,-16) [-16|4] "m/s2" XXX
SG_ ACC_AVAILABLE : 20|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_ACTIVE : 21|1@0+ (1,0) [0|1] "" XXX
SG_ DISABLE_FUEL_SHUTOFF : 23|1@1+ (1,0) [0|0] "" XXX
SG_ GR_MAX_REQ : 32|4@1+ (1,0) [0|0] "" XXX
SG_ ACC_DECEL_REQ : 36|3@1+ (1,0) [0|0] "" XXX
SG_ ACC_FAULTED : 46|2@1+ (1,0) [0|0] "" XXX
SG_ COLLISION_BRK_PREP : 48|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_BRK_PREP : 49|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 501 DAS_4: 8 XXX
SG_ ACC_SET_SPEED_KPH : 15|8@0+ (1,0) [0|3] "km/h" XXX
SG_ ACC_SET_SPEED_MPH : 23|8@0+ (1,0) [0|3] "mph" XXX
SG_ ACC_DISTANCE_CONFIG_1 : 1|2@0+ (1,0) [0|3] "" XXX
SG_ ACC_DISTANCE_CONFIG_2 : 41|2@0+ (1,0) [0|3] "" XXX
SG_ SPEED_DIGITAL : 63|8@0+ (1,0) [0|255] "mph" XXX
SG_ ACC_STATE : 38|3@0+ (1,0) [0|7] "" XXX
SG_ FCW_OFF : 25|2@0+ (1,0) [0|3] "" XXX
SG_ FCW_ERROR : 27|2@0+ (1,0) [0|3] "" XXX
SG_ FCW_BRAKE_ENABLED : 29|1@0+ (1,0) [0|1] "" XXX
SG_ FCW_BRAKE_DISABLED : 47|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_FAULTED : 50|1@0+ (1,0) [0|1] "" XXX
BO_ 544 EPS_2: 8 XXX
SG_ LKAS_STATE : 23|4@0+ (1,0) [0|15] "" XXX
SG_ COLUMN_TORQUE : 2|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ TORQUE_OVERLAY_STATUS : 6|4@0+ (1,0) [0|15] "" XXX
SG_ EPS_TORQUE_MOTOR_RAW : 19|12@0+ (1,-2048) [-2048|2047] "" XXX
SG_ EPS_TORQUE_MOTOR : 34|11@0+ (1,-1024) [-1024|1023] "" XXX
SG_ LKAS_TEMPORARY_FAULT : 38|1@0+ (1,0) [0|1] "" XXX
SG_ AUTO_PARK_HAS_CONTROL_2 : 51|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 559 ECM_5: 8 XXX
SG_ Accelerator_Position : 0|8@1+ (0.4,0) [0|100] "%" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 570 CRUISE_BUTTONS: 3 XXX
SG_ ACC_Cancel : 0|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Distance_Dec : 1|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Accel : 2|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Decel : 3|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Resume : 4|1@0+ (1,0) [0|1] "" XXX
SG_ Cruise_OnOff : 6|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_OnOff : 7|1@1+ (1,0) [0|0] "" XXX
SG_ ACC_Distance_Inc : 8|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 23|8@0+ (1,0) [0|255] "" XXX
BO_ 625 DAS_5: 8 XXX
SG_ FCW_STATE : 2|1@1+ (1,0) [0|0] "" XXX
SG_ FCW_DISTANCE : 3|2@1+ (1,0) [0|0] "" XXX
SG_ ACCFCW_MESSAGE : 12|4@1+ (1,0) [0|0] "" XXX
SG_ SET_SPEED_KPH : 24|8@1+ (1,0) [0|250] "km/h" XXX
SG_ WHEEL_TORQUE_REQUEST : 38|15@0+ (1,-7767) [-7767|24999] "Nm" XXX
SG_ WHEEL_TORQUE_REQUEST_ACTIVE : 39|1@1+ (1,0) [0|0] "" XXX
SG_ COUNTER : 55|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX
BO_ 669 EPB_1: 3 XXX
SG_ PARKING_BRAKE_STATUS : 11|3@0+ (1,0) [0|7] "" XXX
SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 23|8@0+ (1,0) [0|255] "" XXX
BO_ 629 DAS_6: 8 XXX
SG_ LKAS_ICON_COLOR : 1|2@0+ (1,0) [0|3] "" XXX
SG_ LKAS_LANE_LINES : 19|4@0+ (1,0) [0|1] "" XXX
SG_ LKAS_ALERTS : 27|4@0+ (1,0) [0|1] "" XXX
SG_ CAR_MODEL : 15|8@0+ (1,0) [0|255] "" XXX
SG_ AUTO_HIGH_BEAM_ON : 47|1@1+ (1,0) [0|0] "" XXX
SG_ LKAS_DISABLED : 56|1@1+ (1,0) [0|0] "" XXX
BO_ 720 BSM_1: 6 XXX
SG_ RIGHT_STATUS : 5|1@0+ (1,0) [0|1] "" XXX
SG_ LEFT_STATUS : 2|1@0+ (1,0) [0|1] "" XXX
BO_ 792 STEERING_LEVERS: 8 XXX
SG_ TURN_SIGNALS : 0|2@1+ (1,0) [0|3] "" XXX
SG_ HIGH_BEAM_PRESSED : 2|1@0+ (1,0) [0|3] "" XXX
BO_ 820 BCM_1: 8 XXX
SG_ DOOR_OPEN_FL : 17|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_FR : 18|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_RL : 19|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_RR : 20|1@0+ (1,0) [0|1] "" XXX
SG_ DOOR_OPEN_TRUNK : 22|1@0+ (1,0) [0|1] "" XXX
SG_ PARKING_BRAKE_SWITCH : 23|1@0+ (1,0) [0|1] "" XXX
SG_ TURN_LIGHT_LEFT : 31|1@0+ (1,0) [0|1] "" XXX
SG_ TURN_LIGHT_RIGHT : 30|1@0+ (1,0) [0|1] "" XXX
SG_ HIGH_BEAM_DISPLAY : 58|1@0+ (1,0) [0|1] "" XXX
VAL_ 320 ACC_OFF_REQ 2 "PERMANENT" 1 "TEMPORARY" 0 "NONE"
VAL_ 368 Gear_State 4 "D" 2 "N" 1 "R" 0 "P" ;
VAL_ 669 PARKING_BRAKE_STATUS 3 "RELEASING" 2 "APPLYING" 1 "APPLIED" 0 "OFF" ;
CM_ SG_ 258 STEERING_ANGLE_HP "Steering angle high precision";
CM_ SG_ 264 ENGINE_TORQUE "Effective engine torque";
CM_ SG_ 264 EXPECTED_ENGINE_TORQUE "Expected Engine Torque based on target engine speed";
CM_ SG_ 678 LKAS_ICON_COLOR "3 is yellow, 2 is green, 1 is white, 0 is null";
CM_ SG_ 678 LKAS_LANE_LINES "0x01 transparent lines, 0x02 left white, 0x03 right white, 0x04 left yellow with car on top, 0x05 left yellow with car on top, 0x06 both white, 0x07 left yellow, 0x08 left yellow right white, 0x09 right yellow, 0x0a right yellow left white, 0x0b left yellow with car on top right white, 0x0c right yellow with car on top left white, (0x00, 0x0d, 0x0e, 0x0f) null";
CM_ SG_ 678 LKAS_ALERTS "(0x01, 0x02) lane sense off, (0x03, 0x04, 0x06) place hands on steering wheel, 0x07 lane departure detected + place hands on steering wheel, (0x08, 0x09) lane sense unavailable + clean front windshield, 0x0b lane sense and auto high beam unavailable + clean front windshield, 0x0c lane sense unavailable + service required, (0x00, 0x05, 0x0a, 0x0d, 0x0e, 0x0f) null";
@@ -1,2 +0,0 @@
hyundai_kia_mando_front_radar.dbc
hyundai_kia_mando_corner_radar.dbc
@@ -0,0 +1,371 @@
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_ 256 RADAR_POINTS_METADATA_0x100: 64 RADAR
SG_ SIGNAL_1 : 0|32@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_2 : 32|32@1+ (1,0) [0|65535] "" XXX
SG_ SIGNAL_3 : 64|4@1+ (1,0) [0|15] "" XXX
SG_ SIGNAL_4 : 68|4@1+ (1,0) [0|15] "" XXX
SG_ RADAR_POINT_COUNT : 72|8@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_6 : 80|7@1+ (0.015625,0) [0|3] "" XXX
SG_ SIGNAL_7 : 87|1@1+ (1,0) [0|1] "" XXX
SG_ SIGNAL_8 : 88|3@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_9 : 91|5@1+ (0.0625,0) [0|31] "" XXX
SG_ SIGNAL_10 : 96|8@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_11 : 104|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_12 : 111|2@1+ (1,0) [0|65535] "" XXX
SG_ SIGNAL_13 : 113|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_14 : 120|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_15 : 127|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_16 : 130|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_17 : 133|2@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_18 : 134|1@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_19 : 135|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_20 : 138|8@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_21 : 146|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_22 : 148|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_23 : 149|4@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_24 : 153|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_25 : 154|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_26 : 157|2@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_27 : 158|7@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_28 : 165|7@1+ (0.015625,0) [0|31] "" XXX
SG_ SIGNAL_29 : 172|7@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_30 : 179|7@1+ (0.015625,0) [0|1] "" XXX
SG_ SIGNAL_31 : 186|4@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_32 : 190|14@1+ (0.015625,0) [0|15] "" XXX
SG_ SIGNAL_33 : 204|11@1+ (0.03125,0) [0|8191] "" XXX
SG_ SIGNAL_34 : 215|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_35 : 217|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_36 : 224|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_37 : 230|6@1+ (0.2,0) [0|31] "" XXX
SG_ SIGNAL_38 : 236|6@1+ (0.2,0) [0|7] "" XXX
SG_ SIGNAL_39 : 242|8@1+ (1,-90) [0|255] "" XXX
SG_ SIGNAL_40 : 250|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_41 : 256|8@1+ (0.25,0) [0|255] "" XXX
SG_ SIGNAL_42 : 264|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_43 : 267|12@1+ (0.01,0) [0|31] "" XXX
SG_ SIGNAL_44 : 279|32@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_45 : 311|1@1+ (1,0) [0|1] "" XXX
SG_ SIGNAL_46 : 312|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_47 : 314|32@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_48 : 346|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_49 : 352|7@1+ (0.25,0) [0|127] "" XXX
SG_ SIGNAL_50 : 359|6@1+ (0.03125,0) [0|31] "" XXX
SG_ SIGNAL_51 : 365|10@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_52 : 375|10@1+ (0.125,0) [0|63] "" XXX
SG_ SIGNAL_53 : 385|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_54 : 392|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_55 : 399|8@1+ (0.00390625,0) [0|31] "" XXX
SG_ SIGNAL_56 : 407|10@1+ (0.125,0) [0|63] "" XXX
SG_ SIGNAL_57 : 417|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_58 : 418|1@1+ (1,0) [0|3] "" XXX
BO_ 512 RADAR_POINTS_METADATA_0x200: 64 RADAR
SG_ SIGNAL_1 : 0|32@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_2 : 32|32@1+ (1,0) [0|65535] "" XXX
SG_ SIGNAL_3 : 64|4@1+ (1,0) [0|15] "" XXX
SG_ SIGNAL_4 : 68|4@1+ (1,0) [0|15] "" XXX
SG_ RADAR_POINT_COUNT : 72|8@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_6 : 80|7@1+ (0.015625,0) [0|3] "" XXX
SG_ SIGNAL_7 : 87|1@1+ (1,0) [0|1] "" XXX
SG_ SIGNAL_8 : 88|3@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_9 : 91|5@1+ (0.0625,0) [0|31] "" XXX
SG_ SIGNAL_10 : 96|8@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_11 : 104|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_12 : 111|2@1+ (1,0) [0|65535] "" XXX
SG_ SIGNAL_13 : 113|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_14 : 120|7@1+ (0.015625,0) [0|127] "" XXX
SG_ SIGNAL_15 : 127|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_16 : 130|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_17 : 133|2@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_18 : 134|1@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_19 : 135|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_20 : 138|8@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_21 : 146|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_22 : 148|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_23 : 149|4@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_24 : 153|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_25 : 154|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_26 : 157|2@0+ (1,0) [0|3] "" XXX
SG_ SIGNAL_27 : 158|7@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_28 : 165|7@1+ (0.015625,0) [0|31] "" XXX
SG_ SIGNAL_29 : 172|7@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_30 : 179|7@1+ (0.015625,0) [0|1] "" XXX
SG_ SIGNAL_31 : 186|4@1+ (1,0) [0|7] "" XXX
SG_ SIGNAL_32 : 190|14@1+ (0.015625,0) [0|15] "" XXX
SG_ SIGNAL_33 : 204|11@1+ (0.03125,0) [0|8191] "" XXX
SG_ SIGNAL_34 : 215|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_35 : 217|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_36 : 224|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_37 : 230|6@1+ (0.2,0) [0|31] "" XXX
SG_ SIGNAL_38 : 236|6@1+ (0.2,0) [0|7] "" XXX
SG_ SIGNAL_39 : 242|8@1+ (1,-90) [0|255] "" XXX
SG_ SIGNAL_40 : 250|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_41 : 256|8@1+ (0.25,0) [0|255] "" XXX
SG_ SIGNAL_42 : 264|3@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_43 : 267|12@1+ (0.01,0) [0|31] "" XXX
SG_ SIGNAL_44 : 279|32@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_45 : 311|1@1+ (1,0) [0|1] "" XXX
SG_ SIGNAL_46 : 312|2@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_47 : 314|32@1+ (1,0) [0|255] "" XXX
SG_ SIGNAL_48 : 346|6@1+ (1,0) [0|63] "" XXX
SG_ SIGNAL_49 : 352|7@1+ (0.25,0) [0|127] "" XXX
SG_ SIGNAL_50 : 359|6@1+ (0.03125,0) [0|31] "" XXX
SG_ SIGNAL_51 : 365|10@1+ (0.125,0) [0|3] "" XXX
SG_ SIGNAL_52 : 375|10@1+ (0.125,0) [0|63] "" XXX
SG_ SIGNAL_53 : 385|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_54 : 392|7@1+ (1,0) [0|127] "" XXX
SG_ SIGNAL_55 : 399|8@1+ (0.00390625,0) [0|31] "" XXX
SG_ SIGNAL_56 : 407|10@1+ (0.125,0) [0|63] "" XXX
SG_ SIGNAL_57 : 417|1@1+ (1,0) [0|3] "" XXX
SG_ SIGNAL_58 : 418|1@1+ (1,0) [0|3] "" XXX
BO_ 257 RADAR_POINTS_0x101: 64 RADAR
SG_ MESSAGE_ID : 0|5@1+ (1,0) [0|31] "" XXX
SG_ LAYOUT_ID : 5|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_DISTANCE : 7|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_1_SIGNAL_2 : 21|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_3 : 23|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_1_REL_VELOCITY : 31|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_1_SIGNAL_5 : 44|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_6 : 46|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_AZIMUTH : 48|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_1_SIGNAL_8 : 60|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_9 : 62|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_10 : 63|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_1_SIGNAL_11 : 70|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_12 : 71|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_1_SIGNAL_13 : 77|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_14 : 79|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_1_SIGNAL_15 : 87|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_16 : 88|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_17 : 90|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_1_SIGNAL_18 : 93|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_1_SIGNAL_19 : 99|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_1_SIGNAL_20 : 107|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_DISTANCE : 108|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_2_SIGNAL_2 : 122|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_3 : 124|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_2_REL_VELOCITY : 132|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_2_SIGNAL_5 : 145|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_6 : 147|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_AZIMUTH : 149|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_2_SIGNAL_8 : 161|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_9 : 163|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_10 : 164|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_2_SIGNAL_11 : 171|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_12 : 172|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_2_SIGNAL_13 : 178|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_14 : 180|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_2_SIGNAL_15 : 188|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_16 : 189|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_17 : 191|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_2_SIGNAL_18 : 194|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_2_SIGNAL_19 : 200|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_2_SIGNAL_20 : 208|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_DISTANCE : 209|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_3_SIGNAL_2 : 223|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_3 : 225|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_3_REL_VELOCITY : 233|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_3_SIGNAL_5 : 246|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_6 : 248|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_AZIMUTH : 250|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_3_SIGNAL_8 : 262|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_9 : 264|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_10 : 265|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_3_SIGNAL_11 : 272|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_12 : 273|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_3_SIGNAL_13 : 279|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_14 : 281|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_3_SIGNAL_15 : 289|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_16 : 290|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_17 : 292|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_3_SIGNAL_18 : 295|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_3_SIGNAL_19 : 301|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_3_SIGNAL_20 : 309|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_DISTANCE : 310|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_4_SIGNAL_2 : 324|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_3 : 326|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_4_REL_VELOCITY : 334|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_4_SIGNAL_5 : 347|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_6 : 349|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_AZIMUTH : 351|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_4_SIGNAL_8 : 363|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_9 : 365|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_10 : 366|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_4_SIGNAL_11 : 373|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_12 : 374|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_4_SIGNAL_13 : 380|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_14 : 382|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_4_SIGNAL_15 : 390|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_16 : 391|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_17 : 393|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_4_SIGNAL_18 : 396|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_4_SIGNAL_19 : 402|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_4_SIGNAL_20 : 410|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_DISTANCE : 411|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_5_SIGNAL_2 : 425|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_3 : 427|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_5_REL_VELOCITY : 435|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_5_SIGNAL_5 : 448|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_6 : 450|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_AZIMUTH : 452|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_5_SIGNAL_8 : 464|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_9 : 466|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_10 : 467|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_5_SIGNAL_11 : 474|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_12 : 475|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_5_SIGNAL_13 : 481|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_14 : 483|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_5_SIGNAL_15 : 491|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_16 : 492|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_17 : 494|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_5_SIGNAL_18 : 497|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_5_SIGNAL_19 : 503|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_5_SIGNAL_20 : 511|1@1+ (1,0) [0|1] "" XXX
BO_ 513 RADAR_POINTS_0x201: 64 RADAR
SG_ MESSAGE_ID : 0|5@1+ (1,0) [0|31] "" XXX
SG_ LAYOUT_ID : 5|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_DISTANCE : 7|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_1_SIGNAL_2 : 21|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_3 : 23|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_1_REL_VELOCITY : 31|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_1_SIGNAL_5 : 44|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_6 : 46|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_AZIMUTH : 48|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_1_SIGNAL_8 : 60|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_9 : 62|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_10 : 63|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_1_SIGNAL_11 : 70|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_12 : 71|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_1_SIGNAL_13 : 77|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_14 : 79|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_1_SIGNAL_15 : 87|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_1_SIGNAL_16 : 88|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_1_SIGNAL_17 : 90|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_1_SIGNAL_18 : 93|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_1_SIGNAL_19 : 99|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_1_SIGNAL_20 : 107|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_DISTANCE : 108|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_2_SIGNAL_2 : 122|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_3 : 124|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_2_REL_VELOCITY : 132|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_2_SIGNAL_5 : 145|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_6 : 147|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_AZIMUTH : 149|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_2_SIGNAL_8 : 161|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_9 : 163|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_10 : 164|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_2_SIGNAL_11 : 171|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_12 : 172|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_2_SIGNAL_13 : 178|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_14 : 180|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_2_SIGNAL_15 : 188|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_2_SIGNAL_16 : 189|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_2_SIGNAL_17 : 191|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_2_SIGNAL_18 : 194|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_2_SIGNAL_19 : 200|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_2_SIGNAL_20 : 208|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_DISTANCE : 209|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_3_SIGNAL_2 : 223|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_3 : 225|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_3_REL_VELOCITY : 233|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_3_SIGNAL_5 : 246|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_6 : 248|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_AZIMUTH : 250|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_3_SIGNAL_8 : 262|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_9 : 264|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_10 : 265|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_3_SIGNAL_11 : 272|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_12 : 273|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_3_SIGNAL_13 : 279|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_14 : 281|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_3_SIGNAL_15 : 289|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_3_SIGNAL_16 : 290|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_3_SIGNAL_17 : 292|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_3_SIGNAL_18 : 295|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_3_SIGNAL_19 : 301|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_3_SIGNAL_20 : 309|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_DISTANCE : 310|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_4_SIGNAL_2 : 324|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_3 : 326|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_4_REL_VELOCITY : 334|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_4_SIGNAL_5 : 347|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_6 : 349|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_AZIMUTH : 351|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_4_SIGNAL_8 : 363|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_9 : 365|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_10 : 366|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_4_SIGNAL_11 : 373|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_12 : 374|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_4_SIGNAL_13 : 380|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_14 : 382|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_4_SIGNAL_15 : 390|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_4_SIGNAL_16 : 391|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_4_SIGNAL_17 : 393|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_4_SIGNAL_18 : 396|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_4_SIGNAL_19 : 402|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_4_SIGNAL_20 : 410|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_DISTANCE : 411|14@1+ (0.015625,0) [0|255.984375] "" XXX
SG_ POINT_5_SIGNAL_2 : 425|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_3 : 427|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_5_REL_VELOCITY : 435|13@1+ (0.03125,-66) [-66|189.96875] "" XXX
SG_ POINT_5_SIGNAL_5 : 448|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_6 : 450|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_AZIMUTH : 452|12@1+ (0.001953125,-3.998046875) [-3.998046875|4.0] "" XXX
SG_ POINT_5_SIGNAL_8 : 464|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_9 : 466|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_10 : 467|7@1+ (1,0) [0|127] "" XXX
SG_ POINT_5_SIGNAL_11 : 474|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_12 : 475|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_5_SIGNAL_13 : 481|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_14 : 483|8@1+ (0.001953125,-0.248046875) [-0.248046875|0.25] "" XXX
SG_ POINT_5_SIGNAL_15 : 491|1@1+ (1,0) [0|1] "" XXX
SG_ POINT_5_SIGNAL_16 : 492|2@1+ (1,0) [0|3] "" XXX
SG_ POINT_5_SIGNAL_17 : 494|3@1+ (1,0) [0|7] "" XXX
SG_ POINT_5_SIGNAL_18 : 497|6@1+ (1,0) [0|63] "" XXX
SG_ POINT_5_SIGNAL_19 : 503|8@1+ (1,0) [0|255] "" XXX
SG_ POINT_5_SIGNAL_20 : 511|1@1+ (1,0) [0|1] "" XXX
BO_ 260 RADAR_POINTS_CHECKSUM_0x104: 3 RADAR
SG_ CRC16 : 0|16@1+ (1,0) [0|65535] "" XXX
BO_ 516 RADAR_POINTS_CHECKSUM_0x204: 3 RADAR
SG_ CRC16 : 0|16@1+ (1,0) [0|65535] "" XXX
@@ -0,0 +1,422 @@
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_ 1280 RADAR_TRACK_500: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1281 RADAR_TRACK_501: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1282 RADAR_TRACK_502: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1283 RADAR_TRACK_503: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1284 RADAR_TRACK_504: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1285 RADAR_TRACK_505: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1286 RADAR_TRACK_506: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1287 RADAR_TRACK_507: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1288 RADAR_TRACK_508: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1289 RADAR_TRACK_509: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1290 RADAR_TRACK_50a: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1291 RADAR_TRACK_50b: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1292 RADAR_TRACK_50c: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1293 RADAR_TRACK_50d: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1294 RADAR_TRACK_50e: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1295 RADAR_TRACK_50f: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1296 RADAR_TRACK_510: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1297 RADAR_TRACK_511: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1298 RADAR_TRACK_512: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1299 RADAR_TRACK_513: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1300 RADAR_TRACK_514: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1301 RADAR_TRACK_515: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1302 RADAR_TRACK_516: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1303 RADAR_TRACK_517: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1304 RADAR_TRACK_518: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1305 RADAR_TRACK_519: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1306 RADAR_TRACK_51a: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1307 RADAR_TRACK_51b: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1308 RADAR_TRACK_51c: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1309 RADAR_TRACK_51d: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1310 RADAR_TRACK_51e: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
BO_ 1311 RADAR_TRACK_51f: 8 RADAR
SG_ UNKNOWN_1 : 7|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 12|10@0- (0.2,0) [-102.4|102.2] "" XXX
SG_ STATE : 15|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 18|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ REL_ACCEL : 33|10@0- (0.02,0) [-10.24|10.22] "" XXX
SG_ ZEROS : 37|4@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 38|1@0+ (1,0) [0|1] "" XXX
SG_ STATE_3 : 39|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
SG_ STATE_2 : 55|2@0+ (1,0) [0|3] "" XXX
@@ -0,0 +1,421 @@
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
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_COUNTER_255 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ 1_STATE_ALT : 51|4@0+ (1,0) [0|15] "" XXX
SG_ 1_STATE : 55|4@0+ (1,0) [0|15] "" XXX
SG_ 1_NEW_SIGNAL_3 : 63|8@0- (1,0) [0|255] "" XXX
SG_ 1_LONG_DIST : 64|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 1_LAT_DIST : 76|12@1- (0.05,0) [0|4095] "" XXX
SG_ 1_REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ 1_NEW_SIGNAL_1 : 102|2@1+ (1,0) [0|3] "" XXX
SG_ 1_LAT_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ 1_REL_ACCEL : 118|10@1- (1,0) [0|1023] "" XXX
SG_ 2_COUNTER_255 : 175|8@0+ (1,0) [0|255] "" XXX
SG_ 2_STATE_ALT : 179|4@0+ (1,0) [0|15] "" XXX
SG_ 2_STATE : 183|4@0+ (1,0) [0|15] "" XXX
SG_ 2_NEW_SIGNAL_3 : 191|8@0- (1,0) [0|255] "" XXX
SG_ 2_LONG_DIST : 192|12@1+ (0.05,0) [0|4095] "" XXX
SG_ 2_LAT_DIST : 204|12@1- (0.05,0) [0|4095] "" XXX
SG_ 2_REL_SPEED : 216|14@1- (0.01,0) [0|65535] "" XXX
SG_ 2_NEW_SIGNAL_1 : 230|2@1+ (1,0) [0|3] "" XXX
SG_ 2_LAT_ACCEL : 232|13@1- (1,0) [0|8191] "" XXX
SG_ 2_REL_ACCEL : 246|10@1- (1,0) [0|1023] "" XXX
@@ -0,0 +1,997 @@
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_ 933 RADAR_TRACK_3a5: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 934 RADAR_TRACK_3a6: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 935 RADAR_TRACK_3a7: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 936 RADAR_TRACK_3a8: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 937 RADAR_TRACK_3a9: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 938 RADAR_TRACK_3aa: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 939 RADAR_TRACK_3ab: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 940 RADAR_TRACK_3ac: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 941 RADAR_TRACK_3ad: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 942 RADAR_TRACK_3ae: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 943 RADAR_TRACK_3af: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 944 RADAR_TRACK_3b0: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 945 RADAR_TRACK_3b1: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 946 RADAR_TRACK_3b2: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 947 RADAR_TRACK_3b3: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 948 RADAR_TRACK_3b4: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 949 RADAR_TRACK_3b5: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 950 RADAR_TRACK_3b6: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 951 RADAR_TRACK_3b7: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 952 RADAR_TRACK_3b8: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 953 RADAR_TRACK_3b9: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 954 RADAR_TRACK_3ba: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 955 RADAR_TRACK_3bb: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 956 RADAR_TRACK_3bc: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 957 RADAR_TRACK_3bd: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 958 RADAR_TRACK_3be: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 959 RADAR_TRACK_3bf: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 960 RADAR_TRACK_3c0: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 961 RADAR_TRACK_3c1: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 962 RADAR_TRACK_3c2: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 963 RADAR_TRACK_3c3: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
BO_ 964 RADAR_TRACK_3c4: 24 RADAR
SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_1 : 25|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_3 : 28|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER_3 : 31|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_2 : 38|7@0- (1,0) [0|127] "" XXX
SG_ COUNTER_256 : 47|8@0+ (1,0) [0|255] "" XXX
SG_ NEW_SIGNAL_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ STATE : 54|3@0+ (1,0) [0|7] "" XXX
SG_ NEW_SIGNAL_8 : 62|7@0- (1,0) [0|127] "" XXX
SG_ LONG_DIST : 63|12@1+ (0.05,0) [0|8191] "m" XXX
SG_ LAT_DIST : 76|12@1- (0.05,0) [0|127] "" XXX
SG_ REL_SPEED : 88|14@1- (0.01,0) [0|16383] "" XXX
SG_ NEW_SIGNAL_4 : 103|2@0+ (1,0) [0|3] "" XXX
SG_ LAT_DIST_ACCEL : 104|13@1- (1,0) [0|8191] "" XXX
SG_ REL_ACCEL : 118|10@1- (0.02,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_18 : 129|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_5 : 133|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_10 : 138|5@1+ (1,0) [0|31] "" XXX
SG_ NEW_SIGNAL_11 : 149|6@0+ (1,0) [0|63] "" XXX
SG_ NEW_SIGNAL_7 : 152|10@1+ (1,0) [0|1023] "" XXX
SG_ NEW_SIGNAL_9 : 162|9@1- (1,0) [0|511] "" XXX
SG_ NEW_SIGNAL_13 : 175|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_12 : 179|4@0+ (1,0) [0|15] "" XXX
SG_ NEW_SIGNAL_14 : 181|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_15 : 183|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_16 : 185|2@0+ (1,0) [0|3] "" XXX
SG_ NEW_SIGNAL_17 : 187|2@0+ (1,0) [0|3] "" XXX
@@ -0,0 +1,251 @@
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_ 1537 RADAR_LEAD: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1538 RADAR_TRACK_602: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1539 RADAR_TRACK_603: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1540 RADAR_TRACK_604: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1541 RADAR_TRACK_605: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1542 RADAR_TRACK_606: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1543 RADAR_TRACK_607: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1544 RADAR_TRACK_608: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1545 RADAR_TRACK_609: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1546 RADAR_TRACK_60a: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1547 RADAR_TRACK_60b: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1548 RADAR_TRACK_60c: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1549 RADAR_TRACK_60d: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1550 RADAR_TRACK_60e: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1551 RADAR_TRACK_60f: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1552 RADAR_TRACK_610: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1553 RADAR_TRACK_611: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1554 RADAR_ALT_612: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1555 RADAR_ALT_613: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1556 RADAR_ALT_614: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1557 RADAR_ALT_615: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1558 RADAR_ALT_616: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1559 RADAR_ALT_617: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
import os
if __name__ == "__main__":
dbc_name = os.path.basename(__file__).replace(".py", ".dbc")
hyundai_path = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(hyundai_path, dbc_name), "w", encoding="utf-8") as f:
f.write("""
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_ 1537 RADAR_LEAD: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
""")
for a in range(0x602, 0x602 + 16):
f.write(f"""
BO_ {a} RADAR_TRACK_{a:x}: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
""")
for a in range(0x612, 0x612 + 6):
f.write(f"""
BO_ {a} RADAR_ALT_{a:x}: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
""")
@@ -1 +0,0 @@
rivian_mando_front_radar.dbc
@@ -0,0 +1,358 @@
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_ 1280 RADAR_TRACK_500: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1281 RADAR_TRACK_501: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1282 RADAR_TRACK_502: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1283 RADAR_TRACK_503: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1284 RADAR_TRACK_504: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1285 RADAR_TRACK_505: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1286 RADAR_TRACK_506: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1287 RADAR_TRACK_507: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1288 RADAR_TRACK_508: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1289 RADAR_TRACK_509: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1290 RADAR_TRACK_50a: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1291 RADAR_TRACK_50b: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1292 RADAR_TRACK_50c: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1293 RADAR_TRACK_50d: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1294 RADAR_TRACK_50e: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1295 RADAR_TRACK_50f: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1296 RADAR_TRACK_510: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1297 RADAR_TRACK_511: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1298 RADAR_TRACK_512: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1299 RADAR_TRACK_513: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1300 RADAR_TRACK_514: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1301 RADAR_TRACK_515: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1302 RADAR_TRACK_516: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1303 RADAR_TRACK_517: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1304 RADAR_TRACK_518: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1305 RADAR_TRACK_519: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1306 RADAR_TRACK_51a: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1307 RADAR_TRACK_51b: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1308 RADAR_TRACK_51c: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1309 RADAR_TRACK_51d: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1310 RADAR_TRACK_51e: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
BO_ 1311 RADAR_TRACK_51f: 8 RADAR
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 11|4@0+ (1,0) [0|15] "" XXX
SG_ UNKNOWN_1 : 23|8@0- (1,0) [-128|127] "" XXX
SG_ AZIMUTH : 28|10@0- (0.1,0) [-61.2|62.1] "" XXX
SG_ STATE : 31|3@0+ (1,0) [0|7] "" XXX
SG_ LONG_DIST : 34|11@0+ (0.1,0) [0|204.7] "" XXX
SG_ STATE_2 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ REL_SPEED : 53|14@0- (0.01,0) [-81.92|81.92] "" XXX
@@ -1 +0,0 @@
*.dbc
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,254 @@
CM_ "AUTOGENERATED FILE, DO NOT EDIT";
CM_ "hyundai_mrrevo14f_radar.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_ 1537 RADAR_LEAD: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1538 RADAR_TRACK_602: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1539 RADAR_TRACK_603: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1540 RADAR_TRACK_604: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1541 RADAR_TRACK_605: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1542 RADAR_TRACK_606: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1543 RADAR_TRACK_607: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1544 RADAR_TRACK_608: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1545 RADAR_TRACK_609: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1546 RADAR_TRACK_60a: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1547 RADAR_TRACK_60b: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1548 RADAR_TRACK_60c: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1549 RADAR_TRACK_60d: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1550 RADAR_TRACK_60e: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1551 RADAR_TRACK_60f: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1552 RADAR_TRACK_610: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1553 RADAR_TRACK_611: 8 RADAR
SG_ 1_DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 1_LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 1_SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ 2_DISTANCE : 31|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ 2_LATERAL : 41|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ 2_SPEED : 52|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ COUNTER : 62|2@1+ (1,0) [0|3] "" XXX
BO_ 1554 RADAR_ALT_612: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1555 RADAR_ALT_613: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1556 RADAR_ALT_614: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1557 RADAR_ALT_615: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1558 RADAR_ALT_616: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
BO_ 1559 RADAR_ALT_617: 8 RADAR
SG_ DISTANCE : 0|10@1+ (0.25,0) [0|255.75] "" XXX
SG_ LATERAL : 10|11@1+ (0.03,-30.705) [-30.705|30.705] "" XXX
SG_ SPEED : 21|10@1+ (0.25,-128) [-128|127.75] "" XXX
SG_ ID : 31|9@1+ (1,0) [0|511] "" XXX
SG_ SOMETHING_1 : 42|8@1+ (1,-128) [-128|127] "" XXX
SG_ SOMETHING_2 : 50|6@1+ (1,-32) [-32|31] "" XXX
SG_ COUNTER : 56|4@1+ (1,0) [0|15] "" XXX
SG_ CHECKSUM : 63|4@0+ (1,0) [0|15] "" XXX
+7 -1
View File
@@ -56,7 +56,9 @@ const LongitudinalLimits HYUNDAI_LONG_LIMITS = {
{.msg = {{0x91, 0, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \
#define HYUNDAI_LDA_BUTTON_ADDR_CHECK \
{.msg = {{0x391, 0, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \
{.msg = {{0x391, 0, 8, 100U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, \
{0x50C, 0, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, \
{0x50C, 1, 8, 50U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}}}, \
#define HYUNDAI_NON_SCC_HEV_ADDR_CHECK \
{.msg = {{0x595U, 0, 8, 10U, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \
@@ -226,6 +228,10 @@ static void hyundai_rx_hook(const CANPacket_t *msg) {
if (msg->addr == 0x391U) {
hyundai_lkas_button_check(GET_BIT(msg, 4U));
}
if ((msg->addr == 0x50CU) && ((msg->bus == 0U) || (msg->bus == 1U))) {
hyundai_lkas_button_check(GET_BIT(msg, 56U));
}
}
hyundai_common_reset_acc_main_on_mismatches();
@@ -190,7 +190,7 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) {
.has_steer_req_tolerance = true,
};
const AngleSteeringLimits HYUNDAI_CANFD_ANGLE_STEERING_LIMITS = {
.max_angle = 1800,
.max_angle = 3600,
.angle_deg_to_can = 10,
.frequency = 100U,
};
@@ -230,9 +230,16 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) {
int desired_angle = (msg->data[11] << 6U) | (msg->data[10] >> 2U);
desired_angle = to_signed(desired_angle, 14);
// ADAS_ACIAnglTqRedcGainVal: bit 96, 8 bits, unsigned. Raw 0-250 valid, 251-255 reserved.
const uint8_t gain_raw = msg->data[12];
bool gain_violation = gain_raw > 250U;
if (!steer_angle_req && (gain_raw != 0U)) {
gain_violation = true;
}
if (steer_angle_cmd_checks_vm(desired_angle, steer_angle_req,
HYUNDAI_CANFD_ANGLE_STEERING_LIMITS,
HYUNDAI_CANFD_ANGLE_STEERING_PARAMS)) {
HYUNDAI_CANFD_ANGLE_STEERING_PARAMS) || gain_violation) {
tx = false;
}
} else {
@@ -174,7 +174,7 @@ class TestHyundaiCanfdAngleSteering(HyundaiButtonBase, common.CarSafetyTest):
BUTTONS_TX_BUS = 2
LATERAL_FREQUENCY = 100
STANDSTILL_THRESHOLD = 12
STEER_ANGLE_MAX = 180
STEER_ANGLE_MAX = 360
DEG_TO_CAN = 10
GAS_MSG = ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL")
SAFETY_PARAM = HyundaiSafetyFlags.CANFD_ANGLE_STEERING | HyundaiSafetyFlags.CAMERA_SCC | HyundaiSafetyFlags.HYBRID_GAS
@@ -248,7 +248,7 @@ class TestHyundaiCanfdAngleSteering(HyundaiButtonBase, common.CarSafetyTest):
checksum = sig_checksum.calc_checksum(addr, sig_checksum, dat)
_set_value(dat, sig_checksum, checksum)
def _angle_cmd_msg(self, angle, enabled, increment_timer=True):
def _angle_cmd_msg(self, angle, enabled, increment_timer=True, gain_raw=250):
if increment_timer:
self.safety.set_timer(self.angle_cmd_cnt * int(1e6 / self.LATERAL_FREQUENCY))
self.angle_cmd_cnt += 1
@@ -272,7 +272,7 @@ class TestHyundaiCanfdAngleSteering(HyundaiButtonBase, common.CarSafetyTest):
dat[9] = (dat[9] & ~0x30) | (((2 if enabled else 1) & 0x3) << 4)
dat[10] = (dat[10] & 0x03) | ((desired_angle & 0x3F) << 2)
dat[11] = (desired_angle >> 6) & 0xFF
dat[12] = 250 if enabled else 0
dat[12] = gain_raw if enabled or gain_raw != 250 else 0
self._update_checksum(addr, dat)
return libsafety_py.make_CANPacket(addr, 0, bytes(dat))
@@ -335,6 +335,19 @@ class TestHyundaiCanfdAngleSteering(HyundaiButtonBase, common.CarSafetyTest):
self.assertFalse(self._tx(self._angle_cmd_msg(0, True, increment_timer=False)))
self.assertTrue(self._tx(self._angle_cmd_msg(0, True, increment_timer=False)))
def test_angle_torque_reduction_gain_limits(self):
if self.__class__.__name__ != "TestHyundaiCanfdAngleSteering":
return
self.safety.set_controls_allowed(True)
self._reset_speed_measurement(1)
self._set_prev_desired_angle(0)
self.assertTrue(self._tx(self._angle_cmd_msg(0, True, gain_raw=250)))
self._set_prev_desired_angle(0)
self.assertFalse(self._tx(self._angle_cmd_msg(0, True, gain_raw=251)))
self._set_prev_desired_angle(0)
self.assertFalse(self._tx(self._angle_cmd_msg(0, False, gain_raw=1)))
class TestHyundaiCanfdAngleSteeringLfaAlt(TestHyundaiCanfdAngleSteering):
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
extern const uint8_t gitversion[19];
const uint8_t gitversion[19] = "DEV-f06c82b2-DEBUG";
const uint8_t gitversion[19] = "DEV-e5cc7460-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
DEV-f06c82b2-DEBUG
DEV-e5cc7460-DEBUG
+72 -11
View File
@@ -28,6 +28,7 @@ import time
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from pathlib import Path
import types
from typing import Any, Optional
from urllib.parse import parse_qs, urlparse
@@ -35,6 +36,16 @@ import requests
# ── StarPilot / openpilot imports ──────────────────────────────────────────
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
# smbus2 is a hardware I2C library only present on comma's tici device.
# On PC it's never installed, and SMBus is never called (the TICI flag is
# False). Stub it so the eager import chain in openpilot.system.hardware
# succeeds without installing tici-only platform dependencies.
_smbus2 = types.ModuleType('smbus2')
_smbus2.SMBus = None
sys.modules['smbus2'] = _smbus2
from openpilot.common.constants import CV
from openpilot.tools.lib.auth import login as oauth_login
from openpilot.tools.lib.auth_config import get_token, set_token
@@ -126,6 +137,16 @@ class ScsSample:
decel_pressed: bool
@dataclass
class LeadSample:
"""One radarState lead-vehicle event from the log."""
log_mono_time: int
has_lead: bool
d_rel: float # metres ahead
v_lead: float # m/s absolute speed of lead
@dataclass
class GpsSample:
"""One gpsLocationExternal event from the log."""
@@ -240,6 +261,12 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=JWT_HELP,
)
p.add_argument(
"route_pos",
nargs="?",
default=None,
help="Route name (positional format alternative)."
)
p.add_argument(
"--route",
default=None,
@@ -257,7 +284,10 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
default=False,
help="Display speeds in km/h (default: mph).",
)
return p.parse_args(argv)
args = p.parse_args(argv)
if args.route_pos:
args.route = args.route_pos
return args
def resolve_route_identifier(raw: str) -> str:
@@ -297,6 +327,8 @@ def resolve_route_identifier(raw: str) -> str:
"Expected: dongle_id|log_id (16 hex chars | identifier)"
)
dongle, log_id, suffix = m.group(1), m.group(2), m.group(3) or ""
if suffix:
suffix = re.sub(r"^/(\d+)/(\d+)$", r"/\1:\2", suffix)
return f"{dongle}/{log_id}{suffix}"
@@ -354,18 +386,19 @@ def parse_route_logs(
list[CarSample],
list[GpsSample],
list[ScsSample],
list[LeadSample],
list[int],
]:
"""Use LogReader to parse qlog and extract all speed-related messages.
Returns (mapd_events, splan_events, car_events, gps_events, scs_events, segments).
Returns (mapd_events, splan_events, car_events, gps_events, scs_events, lead_events, segments).
"""
mapd_events: list[MapdSample] = []
splan_events: list[SplanSample] = []
car_events: list[CarSample] = []
gps_events: list[GpsSample] = []
scs_events: list[ScsSample] = []
segments_found: set[int] = set()
lead_events: list[LeadSample] = []
segments_found: set[int] = set()
seg_of_msg: dict[int, int] = {}
@@ -448,6 +481,17 @@ def parse_route_logs(
decel_pressed=bool(s.decelPressed),
)
)
elif which == "radarState":
r = msg.radarState
lead = r.leadOne
lead_events.append(
LeadSample(
log_mono_time=t,
has_lead=bool(lead.status),
d_rel=float(lead.dRel or 0),
v_lead=float(lead.vLead or 0),
)
)
if not all_msgs:
print("Warning: no messages found in route logs.", file=sys.stderr)
@@ -472,7 +516,7 @@ def parse_route_logs(
segments = sorted(segments_found) if segments_found else [0]
return mapd_events, splan_events, car_events, gps_events, scs_events, segments
return mapd_events, splan_events, car_events, gps_events, scs_events, lead_events, segments
# ============================================================================
@@ -874,9 +918,10 @@ def detect_changes(
osm_ways: dict[int, OsmWay],
gps_timeline: list[tuple[float, float, float]],
base_time_ns: int,
lead_events: list[LeadSample] | None = None,
) -> list[ChangeRow]:
"""Walk starpilotPlan events to detect every SLC state transition,
correlating with mapd, carState, and starpilotCarState for full context.
correlating with mapd, carState, starpilotCarState, and radarState for full context.
Produces a timeline of SLC decisions: limits, overrides, prompts, lookaheads.
"""
@@ -888,6 +933,9 @@ def detect_changes(
mapd_sorted = (
sorted(mapd_events, key=lambda e: e.log_mono_time) if mapd_events else []
)
lead_sorted = (
sorted(lead_events, key=lambda e: e.log_mono_time) if lead_events else []
)
prev_slc = -1.0
prev_source_key = ""
@@ -910,6 +958,7 @@ def detect_changes(
m = _nearest(mapd_sorted, t_ns)
c = _nearest(car_events, t_ns)
s = _nearest(scs_events, t_ns)
lv = _nearest(lead_sorted, t_ns) if lead_sorted else None
mapd_sl = m.speed_limit if m else 0
mapd_next = m.next_speed_limit if m else 0
@@ -920,6 +969,9 @@ def detect_changes(
gas = bool(c.gas_pressed) if c else False
accel = bool(s.accel_pressed) if s else False
decel = bool(s.decel_pressed) if s else False
has_lead = bool(lv.has_lead) if lv else False
lead_d_rel = lv.d_rel if lv and lv.has_lead else 0.0
lead_v = lv.v_lead if lv and lv.has_lead else 0.0
lat, lon = gps_at_time(t_ns, gps_timeline) if gps_timeline else (0, 0)
osm_sl, osm_name = (
@@ -1001,11 +1053,17 @@ def detect_changes(
detail = f"gas pressed: {v_ego * KPH_TO_MPH * MS_TO_KPH:.0f} > {slc * KPH_TO_MPH * MS_TO_KPH:.0f}"
if accel:
detail += " (accel)"
if has_lead:
detail += f" [lead {lead_d_rel:.0f}m ahead]"
elif ov_end and not limit_changed and has_lead and not gas:
event_type = "OVERRIDE CLEAR"
detail = f"ACC decel behind lead ({lead_d_rel:.0f}m, {lead_v * KPH_TO_MPH * MS_TO_KPH:.0f} mph) — not driver brake"
elif ov_end and not limit_changed:
if ov_phase:
event_type = "OVERRIDE CLEAR"
detail = "override ended"
detail = "override ended" + (f" [lead {lead_d_rel:.0f}m, {lead_v * KPH_TO_MPH * MS_TO_KPH:.0f} mph]" if has_lead else "")
elif active_ov and ov_phase != "active":
event_type = "OVERRIDE ACTIVE"
@@ -1014,6 +1072,8 @@ def detect_changes(
elif stale_ov and ov_phase != "stale":
event_type = "STALE OVERRIDE"
detail = f"overridden > {slc * KPH_TO_MPH * MS_TO_KPH:.0f}, v_ego={v_ego * KPH_TO_MPH * MS_TO_KPH:.0f}"
if has_lead:
detail += f" [ACC: lead {lead_d_rel:.0f}m, {lead_v * KPH_TO_MPH * MS_TO_KPH:.0f} mph]"
elif source_changed:
event_type = "SOURCE"
@@ -1091,14 +1151,14 @@ def fmt_speed(mps: float, use_mph: bool, width: int = 5) -> str:
def print_header(
route_name: str, mapd_n: int, splan_n: int, gps_n: int, scs_n: int
route_name: str, mapd_n: int, splan_n: int, gps_n: int, scs_n: int, lead_n: int = 0
) -> None:
sep = "=" * 82
print(f"\n{sep}")
print(f" SLC / mapd Diagnostic Timeline")
print(f" Route: {route_name}")
print(
f" Events: mapdOut={mapd_n} | starpilotPlan={splan_n} | starpilotCarState={scs_n} | GPS={gps_n}"
f" Events: mapdOut={mapd_n} | starpilotPlan={splan_n} | starpilotCarState={scs_n} | GPS={gps_n} | radarState={lead_n}"
)
print(f"{sep}")
@@ -1197,7 +1257,7 @@ def main(argv: list[str] | None = None) -> int:
print(f"\nProcessing route: {canonical}", file=sys.stderr)
# ── Parse qlog ──────────────────────────────────────────────────
mapd_ev, splan_ev, car_ev, gps_ev, scs_ev, segments = parse_route_logs(
mapd_ev, splan_ev, car_ev, gps_ev, scs_ev, lead_ev, segments = parse_route_logs(
canonical
)
@@ -1226,11 +1286,12 @@ def main(argv: list[str] | None = None) -> int:
# ── Detect changes ──────────────────────────────────────────
rows = detect_changes(
mapd_ev, splan_ev, car_ev, scs_ev, osm_ways, gps_timeline, base_time
mapd_ev, splan_ev, car_ev, scs_ev, osm_ways, gps_timeline, base_time,
lead_events=lead_ev,
)
# ── Output ─────────────────────────────────────────────────
print_header(canonical, len(mapd_ev), len(splan_ev), len(gps_ev), len(scs_ev))
print_header(canonical, len(mapd_ev), len(splan_ev), len(gps_ev), len(scs_ev), len(lead_ev))
print_table(rows, not args.kmh)
stale = sum(1 for r in rows if r.stale)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+1
View File
@@ -47,6 +47,7 @@ GM_STANDSTILL_BRAKE_CAMERA_CARS = {
GM_CAR.CHEVROLET_VOLT_CC,
GM_CAR.CHEVROLET_MALIBU,
GM_CAR.CHEVROLET_MALIBU_ASCM,
GM_CAR.BUICK_LACROSSE_ASCM,
GM_CAR.CHEVROLET_MALIBU_SDGM,
GM_CAR.CHEVROLET_MALIBU_CC,
GM_CAR.CHEVROLET_MALIBU_HYBRID_CC,
+96 -15
View File
@@ -22,7 +22,7 @@ from opendbc.safety import ALTERNATIVE_EXPERIENCE
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
from openpilot.common.constants import CV
from openpilot.selfdrive.car.cruise import VCruiseHelper, IMPERIAL_INCREMENT, V_CRUISE_MAX, V_CRUISE_MIN
from openpilot.selfdrive.car.redneck_cruise import RedneckCruise
from openpilot.selfdrive.car.redneck_cruise import RedneckCruise, SEND_BUTTON_DECREASE, SEND_BUTTON_INCREASE, select_redneck_target_speed
from openpilot.selfdrive.car.car_specific import MockCarState
from openpilot.starpilot.common.starpilot_variables import get_starpilot_toggles, update_starpilot_toggles
@@ -30,6 +30,8 @@ from openpilot.starpilot.controls.starpilot_card import StarPilotCard
REPLAY = "REPLAY" in os.environ
OPENPILOT_LEAD_MIN_DISTANCE = 0.1
REDNECK_DECREASE_LOOKAHEAD_POINTS = 10
REDNECK_AUTO_BUTTON_FILTER_FRAMES = int(0.3 / DT_CTRL)
EventName = log.OnroadEvent.EventName
@@ -73,6 +75,14 @@ class Car:
FPCP: custom.StarPilotCarParams
class _ButtonEventFilteredCarState:
def __init__(self, car_state: car.CarState, button_events):
self._car_state = car_state
self.buttonEvents = button_events
def __getattr__(self, name: str):
return getattr(self._car_state, name)
def __init__(self, CI=None, RI=None) -> None:
self.can_sock = messaging.sub_sock('can', timeout=20)
self.sm = messaging.SubMaster(['pandaStates', 'carControl', 'onroadEvents', 'radarState', 'longitudinalPlan'])
@@ -165,8 +175,12 @@ class Car:
self.params.put_nonblocking("CarParamsPersistent", cp_bytes)
self.mock_carstate = MockCarState()
self.v_cruise_helper = VCruiseHelper(self.CP)
self.redneck_cruise = RedneckCruise(self.CP, self.FPCP) if self.CP.brand == "hyundai" else None
self.v_cruise_helper = VCruiseHelper(self.CP, self.FPCP)
self.redneck_cruise = RedneckCruise(self.CP, self.FPCP) if self.CP.brand == "hyundai" and self.FPCP.redneckCruiseAvailable and not self.FPCP.pcmCruiseSpeed else None
self.redneck_button_event_filter_frames = {
int(ButtonType.accelCruise): 0,
int(ButtonType.decelCruise): 0,
}
self.is_metric = self.params.get_bool("IsMetric")
self.safe_mode = self.params.get_bool("SafeMode")
@@ -215,6 +229,9 @@ class Car:
self.sm.update(0)
self._advance_redneck_button_feedback_filter()
filtered_CS = self._get_button_event_filtered_state(CS)
can_rcv_valid = len(can_strs) > 0
# Check for CAN timeout
@@ -230,7 +247,7 @@ class Car:
)
if not preap_software_cruise:
self.v_cruise_helper.update_v_cruise(
CS,
filtered_CS,
self.sm['carControl'].enabled,
self.is_metric,
self.sm['starpilotPlan'].speedLimitChanged,
@@ -266,9 +283,9 @@ class Car:
CS.vCruise = float(self.v_cruise_helper.v_cruise_kph)
CS.vCruiseCluster = float(self.v_cruise_helper.v_cruise_cluster_kph)
if any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in CS.buttonEvents):
if any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in filtered_CS.buttonEvents):
self.resume_prev_button = True
elif any(be.type in (ButtonType.decelCruise, ButtonType.setCruise) for be in CS.buttonEvents):
elif any(be.type in (ButtonType.decelCruise, ButtonType.setCruise) for be in filtered_CS.buttonEvents):
self.resume_prev_button = False
FPCS = self.starpilot_card.update(CS, FPCS, self.sm, self.starpilot_toggles)
@@ -345,6 +362,7 @@ class Car:
self._update_redneck_cruise(CS, CC)
self._update_openpilot_lead_state(CC)
self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos, self.starpilot_toggles)
self._record_redneck_button_feedback_filter()
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))
self.CC_prev = CC
@@ -373,19 +391,82 @@ class Car:
if self.redneck_cruise is None:
return
send_button, v_target = self.redneck_cruise.run(CS, CC, self._get_redneck_target_speed(), self.is_metric)
filtered_CS = self._get_button_event_filtered_state(CS)
v_target_ms, lead_present = self._get_redneck_target_speed(CS)
send_button, v_target = self.redneck_cruise.run(filtered_CS, CC, v_target_ms, self.is_metric, lead_present=lead_present)
self.CI.CS.redneck_send_button = send_button
self.CI.CS.redneck_v_target = v_target
def _get_redneck_target_speed(self) -> float:
if self.sm.seen['longitudinalPlan'] and self.sm.valid['longitudinalPlan']:
speeds = self.sm['longitudinalPlan'].speeds
if len(speeds) > 0:
target_speed = float(speeds[0])
if math.isfinite(target_speed):
return target_speed
def _get_redneck_target_speed(self, CS: car.CarState) -> tuple[float, bool]:
starpilot_target_speed = 0.0
allow_plan_decrease = False
lead_present = False
lookahead_points = REDNECK_DECREASE_LOOKAHEAD_POINTS
if self.sm.seen['starpilotPlan'] and self.sm.valid['starpilotPlan']:
starpilot_target_speed = float(self.sm['starpilotPlan'].vCruise)
return float(self.sm['starpilotPlan'].vCruise)
plan_speeds = []
if self.sm.seen['longitudinalPlan'] and self.sm.valid['longitudinalPlan']:
longitudinal_plan = self.sm['longitudinalPlan']
plan_speeds = [float(speed) for speed in longitudinal_plan.speeds if math.isfinite(float(speed))]
lead_present = bool(longitudinal_plan.hasLead)
allow_plan_decrease = bool(lead_present or longitudinal_plan.shouldStop or
str(longitudinal_plan.longitudinalPlanSource) != "cruise")
if lead_present and len(plan_speeds) > 0:
lookahead_points = len(plan_speeds)
return select_redneck_target_speed(
float(getattr(CS, "vCruise", 0.0)),
float(CS.cruiseState.speedCluster),
starpilot_target_speed,
plan_speeds,
lookahead_points,
allow_plan_decrease=allow_plan_decrease,
lead_present=lead_present,
), lead_present
def _advance_redneck_button_feedback_filter(self) -> None:
if self.redneck_cruise is None:
return
for button_type in self.redneck_button_event_filter_frames:
self.redneck_button_event_filter_frames[button_type] = max(0, self.redneck_button_event_filter_frames[button_type] - 1)
def _get_filtered_redneck_button_events(self, CS: car.CarState):
if self.redneck_cruise is None or len(CS.buttonEvents) == 0:
return CS.buttonEvents
if not any(self.redneck_button_event_filter_frames.values()):
return CS.buttonEvents
filtered_button_events = []
filtered_any = False
for event in CS.buttonEvents:
button_type = event.type.raw if hasattr(event.type, "raw") else int(event.type)
if self.redneck_button_event_filter_frames.get(button_type, 0) > 0:
filtered_any = True
continue
filtered_button_events.append(event)
return filtered_button_events if filtered_any else CS.buttonEvents
def _get_button_event_filtered_state(self, CS: car.CarState):
filtered_button_events = self._get_filtered_redneck_button_events(CS)
if filtered_button_events is CS.buttonEvents:
return CS
return self._ButtonEventFilteredCarState(CS, filtered_button_events)
def _record_redneck_button_feedback_filter(self) -> None:
if self.redneck_cruise is None:
return
sent_button = int(getattr(self.CI.CS, "redneck_last_sent_button", 0) or 0)
if sent_button == SEND_BUTTON_INCREASE:
self.redneck_button_event_filter_frames[int(ButtonType.accelCruise)] = REDNECK_AUTO_BUTTON_FILTER_FRAMES
elif sent_button == SEND_BUTTON_DECREASE:
self.redneck_button_event_filter_frames[int(ButtonType.decelCruise)] = REDNECK_AUTO_BUTTON_FILTER_FRAMES
self.CI.CS.redneck_last_sent_button = 0
def step(self):
CS, RD, FPCS = self.state_update()
+22 -7
View File
@@ -32,7 +32,7 @@ CRUISE_INTERVAL_SIGN = {
class VCruiseHelper:
def __init__(self, CP):
def __init__(self, CP, FPCP=None):
self.CP = CP
self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET
@@ -41,6 +41,9 @@ class VCruiseHelper:
self.button_change_states = {btn: {"standstill": False, "enabled": False} for btn in self.button_timers}
self.gm_cc_only = self.CP.carFingerprint in CC_ONLY_CAR and self.CP.flags & GMFlags.CC_LONG.value
self.redneck_non_pcm = bool(FPCP is not None and
getattr(FPCP, "redneckCruiseAvailable", False) and
not getattr(FPCP, "pcmCruiseSpeed", True))
def _get_short_press_delta(self, is_metric, starpilot_toggles: SimpleNamespace) -> float:
base_delta = 1. if is_metric else IMPERIAL_INCREMENT
@@ -50,6 +53,15 @@ class VCruiseHelper:
def _get_cruise_delta_interval(interval: float | None) -> float:
return interval if isinstance(interval, (int, float)) and interval > 0 else 1.0
def _get_cruise_delta_intervals(self, starpilot_toggles: SimpleNamespace) -> tuple[float, float]:
short_interval = self._get_cruise_delta_interval(getattr(starpilot_toggles, "cruise_increase", None))
long_interval = self._get_cruise_delta_interval(getattr(starpilot_toggles, "cruise_increase_long", None))
if getattr(starpilot_toggles, "reverse_cruise_increase", False):
return long_interval, short_interval
return short_interval, long_interval
@property
def v_cruise_initialized(self):
return self.v_cruise_kph != V_CRUISE_UNSET
@@ -58,7 +70,7 @@ class VCruiseHelper:
self.v_cruise_kph_last = self.v_cruise_kph
if CS.cruiseState.available:
if self.gm_cc_only or not self.CP.pcmCruise:
if self.gm_cc_only or self.redneck_non_pcm or not self.CP.pcmCruise:
# if stock cruise is completely disabled, then we can use our own set speed logic
self._update_v_cruise_non_pcm(CS, enabled, is_metric, speed_limit_changed, starpilot_toggles)
self.v_cruise_cluster_kph = self.v_cruise_kph
@@ -116,8 +128,8 @@ class VCruiseHelper:
if not self.button_change_states[button_type]["enabled"]:
return
delta_interval = starpilot_toggles.cruise_increase_long if long_press else starpilot_toggles.cruise_increase
v_cruise_delta_interval = self._get_cruise_delta_interval(delta_interval)
short_interval, long_interval = self._get_cruise_delta_intervals(starpilot_toggles)
v_cruise_delta_interval = long_interval if long_press else short_interval
v_cruise_delta = v_cruise_delta * v_cruise_delta_interval
if v_cruise_delta_interval % 5 == 0 and self.v_cruise_kph % v_cruise_delta != 0: # partial interval
self.v_cruise_kph = CRUISE_NEAREST_FUNC[button_type](self.v_cruise_kph / v_cruise_delta) * v_cruise_delta
@@ -145,19 +157,22 @@ class VCruiseHelper:
def initialize_v_cruise(self, CS, experimental_mode: bool, resume_prev_button: bool,
starpilot_toggles: SimpleNamespace, desired_speed_limit: float = 0.0) -> None:
# initializing is handled by the PCM
if self.CP.pcmCruise and not self.gm_cc_only:
if self.CP.pcmCruise and not (self.gm_cc_only or self.redneck_non_pcm):
return
engage_floor_kph = max(V_CRUISE_MIN, 7.0 * CV.MPH_TO_KPH)
resume_pressed = any(b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for b in CS.buttonEvents)
remembered_resume = resume_prev_button and (self.gm_cc_only or self.redneck_non_pcm)
if (any(b.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for b in CS.buttonEvents)
and self.v_cruise_initialized or (self.gm_cc_only and resume_prev_button)):
if self.v_cruise_initialized and (resume_pressed or remembered_resume):
self.v_cruise_kph = self.v_cruise_kph_last
elif desired_speed_limit > 0 and getattr(starpilot_toggles, "set_speed_limit", False):
# Respect the exact SLC limit+offset on engage instead of snapping upward to
# the custom cruise-button interval.
initialized_speed_limit_kph = round(desired_speed_limit * CV.MS_TO_KPH, 1)
self.v_cruise_kph = float(np.clip(initialized_speed_limit_kph, V_CRUISE_MIN, V_CRUISE_MAX))
elif self.redneck_non_pcm and CS.cruiseState.speedCluster > 0:
self.v_cruise_kph = float(np.clip(CS.cruiseState.speedCluster * CV.MS_TO_KPH, V_CRUISE_MIN, V_CRUISE_MAX))
else:
self.v_cruise_kph = int(round(np.clip(CS.vEgo * CV.MS_TO_KPH, engage_floor_kph, V_CRUISE_MAX)))
+22
View File
@@ -0,0 +1,22 @@
from opendbc.car import structs
def hyundai_openpilot_longitudinal_acc_req_feedback(CP: structs.CarParams) -> bool:
return CP.brand == 'hyundai' and CP.openpilotLongitudinalControl and not CP.pcmCruise
def should_cancel_stock_cruise(CP: structs.CarParams, cruise_enabled: bool, controls_enabled: bool) -> bool:
if not cruise_enabled:
return False
if not controls_enabled:
return True
return not CP.pcmCruise and not hyundai_openpilot_longitudinal_acc_req_feedback(CP)
def should_flag_cruise_mismatch(CP: structs.CarParams, cruise_enabled: bool, controls_enabled: bool,
effective_pcm_cruise: bool) -> bool:
if not cruise_enabled:
return False
if not controls_enabled:
return True
return not effective_pcm_cruise and not hyundai_openpilot_longitudinal_acc_req_feedback(CP)
+84 -27
View File
@@ -10,7 +10,11 @@ SEND_BUTTON_INCREASE = 1
SEND_BUTTON_DECREASE = 2
HYST_GAP = 0.0
INACTIVE_TIMER = 0.4
INCREASE_INACTIVE_TIMER = 0.4
DECREASE_INACTIVE_TIMER = 0.1
LEAD_INCREASE_INACTIVE_TIMER = 0.1
LEAD_RECOVERY_LOOKAHEAD_POINTS = 4
LEAD_COAST_BUFFER_MS = 1.0 * CV.MPH_TO_MS
CRUISE_BUTTON_TIMERS = {
int(ButtonType.decelCruise): 0,
@@ -22,6 +26,32 @@ CRUISE_BUTTON_TIMERS = {
}
def select_redneck_target_speed(v_cruise_kph: float, speed_cluster_ms: float,
starpilot_target_speed_ms: float, plan_speeds_ms: list[float],
lookahead_points: int, allow_plan_decrease: bool = True,
lead_present: bool = False) -> float:
target_speed_ms = float(speed_cluster_ms)
if v_cruise_kph > 0:
target_speed_ms = float(v_cruise_kph) * CV.KPH_TO_MS
elif starpilot_target_speed_ms > 0:
target_speed_ms = float(starpilot_target_speed_ms)
if allow_plan_decrease and len(plan_speeds_ms) > 0:
if lead_present and plan_speeds_ms[0] > speed_cluster_ms:
recovery_lookahead_points = min(len(plan_speeds_ms), LEAD_RECOVERY_LOOKAHEAD_POINTS)
recovery_target_speed_ms = max(speed_cluster_ms, min(plan_speeds_ms[:recovery_lookahead_points]))
return min(target_speed_ms, recovery_target_speed_ms)
decrease_target_speed_ms = min(plan_speeds_ms[:lookahead_points])
if lead_present and decrease_target_speed_ms < speed_cluster_ms:
decrease_target_speed_ms = max(0.0, decrease_target_speed_ms - LEAD_COAST_BUFFER_MS)
if decrease_target_speed_ms < target_speed_ms:
return decrease_target_speed_ms
return target_speed_ms
def get_minimum_set_speed(is_metric: bool) -> int:
return 30 if is_metric else 20
@@ -80,43 +110,70 @@ class RedneckCruise:
button_pressed = any(timer > 0 for timer in self.cruise_button_timers.values())
self.is_ready = CC.enabled and not CC.cruiseControl.override and not CC.cruiseControl.cancel and not CC.cruiseControl.resume and not button_pressed
def _update_state_machine(self) -> int:
self.pre_active_timer = max(0, self.pre_active_timer - 1)
def _desired_state(self) -> str:
if self.v_target > self.v_cruise_cluster:
return "increasing"
if self.v_target < self.v_cruise_cluster and self.v_cruise_cluster > self.v_cruise_min:
return "decreasing"
return "holding"
if self.state != "inactive":
if not self.is_ready:
self.state = "inactive"
elif self.state == "preActive":
@staticmethod
def _get_pre_active_frames(state: str, lead_present: bool) -> int:
if state == "decreasing":
timer = DECREASE_INACTIVE_TIMER
elif lead_present:
timer = LEAD_INCREASE_INACTIVE_TIMER
else:
timer = INCREASE_INACTIVE_TIMER
return int(timer / DT_CTRL)
def _arm_pre_active(self, desired_state: str, lead_present: bool) -> None:
if desired_state == "holding":
self.state = "holding"
self.pre_active_timer = 0
return
self.state = "preActive"
self.pre_active_timer = self._get_pre_active_frames(desired_state, lead_present)
def _update_state_machine(self, lead_present: bool) -> int:
desired_state = self._desired_state()
if not self.is_ready:
self.state = "inactive"
self.pre_active_timer = 0
elif self.state == "inactive":
if not self.is_ready_prev:
self._arm_pre_active(desired_state, lead_present)
elif self.state == "preActive":
if desired_state == "holding":
self.state = "holding"
self.pre_active_timer = 0
else:
desired_frames = self._get_pre_active_frames(desired_state, lead_present)
self.pre_active_timer = max(0, min(self.pre_active_timer, desired_frames) - 1)
if self.pre_active_timer <= 0:
if self.v_target == self.v_cruise_cluster:
self.state = "holding"
elif self.v_target > self.v_cruise_cluster:
self.state = "increasing"
elif self.v_target < self.v_cruise_cluster and self.v_cruise_cluster > self.v_cruise_min:
self.state = "decreasing"
elif self.state == "holding":
if self.v_target != self.v_cruise_cluster:
self.state = "preActive"
elif self.state == "increasing":
if self.v_target <= self.v_cruise_cluster:
self.state = "holding"
elif self.state == "decreasing":
if self.v_target >= self.v_cruise_cluster or self.v_cruise_cluster <= self.v_cruise_min:
self.state = "holding"
elif self.is_ready and not self.is_ready_prev:
self.pre_active_timer = int(INACTIVE_TIMER / DT_CTRL)
self.state = "preActive"
self.state = desired_state
elif self.state == "holding":
if desired_state != "holding":
self._arm_pre_active(desired_state, lead_present)
elif self.state != desired_state:
if desired_state == "holding":
self.state = "holding"
else:
self._arm_pre_active(desired_state, lead_present)
return self._send_button_for_state(self.state)
def run(self, CS: car.CarState, CC: car.CarControl, v_target_ms: float, is_metric: bool) -> tuple[int, int]:
def run(self, CS: car.CarState, CC: car.CarControl, v_target_ms: float, is_metric: bool,
lead_present: bool = False) -> tuple[int, int]:
if self.FPCP.pcmCruiseSpeed or not self.FPCP.redneckCruiseAvailable:
self._reset()
return SEND_BUTTON_NONE, 0
self._update_calculations(CS, v_target_ms, is_metric)
self._update_readiness(CS, CC)
send_button = self._update_state_machine()
send_button = self._update_state_machine(lead_present)
self.is_ready_prev = self.is_ready
return send_button, self.v_target
+41
View File
@@ -0,0 +1,41 @@
from cereal import car
from openpilot.selfdrive.car.cruise_state import should_cancel_stock_cruise, should_flag_cruise_mismatch
def make_cp(brand="hyundai", op_long=True, pcm_cruise=False):
cp = car.CarParams.new_message()
cp.brand = brand
cp.openpilotLongitudinalControl = op_long
cp.pcmCruise = pcm_cruise
return cp
def test_hyundai_openpilot_long_does_not_cancel_active_acc_req_feedback():
cp = make_cp()
assert not should_cancel_stock_cruise(cp, cruise_enabled=True, controls_enabled=True)
assert not should_flag_cruise_mismatch(cp, cruise_enabled=True, controls_enabled=True, effective_pcm_cruise=False)
def test_hyundai_openpilot_long_still_flags_cruise_when_controls_disabled():
cp = make_cp()
assert should_cancel_stock_cruise(cp, cruise_enabled=True, controls_enabled=False)
assert should_flag_cruise_mismatch(cp, cruise_enabled=True, controls_enabled=False, effective_pcm_cruise=False)
def test_non_hyundai_openpilot_long_behavior_is_unchanged():
cp = make_cp(brand="toyota")
assert should_cancel_stock_cruise(cp, cruise_enabled=True, controls_enabled=True)
assert should_flag_cruise_mismatch(cp, cruise_enabled=True, controls_enabled=True, effective_pcm_cruise=False)
def test_pcm_cruise_behavior_is_unchanged():
cp = make_cp(op_long=False, pcm_cruise=True)
assert not should_cancel_stock_cruise(cp, cruise_enabled=True, controls_enabled=True)
assert should_cancel_stock_cruise(cp, cruise_enabled=True, controls_enabled=False)
assert not should_flag_cruise_mismatch(cp, cruise_enabled=True, controls_enabled=True, effective_pcm_cruise=True)
assert should_flag_cruise_mismatch(cp, cruise_enabled=True, controls_enabled=False, effective_pcm_cruise=True)
+97
View File
@@ -55,6 +55,7 @@ class TestVCruiseHelper:
cruise_increase=1,
cruise_increase_long=5,
is_metric=False,
reverse_cruise_increase=False,
set_speed_limit=False,
)
self.reset_cruise_speed_state()
@@ -304,3 +305,99 @@ class TestVCruiseHelper:
)
assert self.v_cruise_helper.v_cruise_kph == pytest.approx(initial_v_cruise_kph + IMPERIAL_INCREMENT)
class TestVCruiseHelperRedneck:
def setup_method(self):
self.CP = car.CarParams(pcmCruise=True)
self.FPCP = SimpleNamespace(pcmCruiseSpeed=False, redneckCruiseAvailable=True)
self.v_cruise_helper = VCruiseHelper(self.CP, self.FPCP)
self.starpilot_toggles = SimpleNamespace(
cruise_increase=1,
cruise_increase_long=5,
is_metric=False,
reverse_cruise_increase=False,
set_speed_limit=False,
)
def test_initialize_v_cruise_uses_cluster_speed(self):
cs = car.CarState(
vEgo=55 * CV.MPH_TO_MS,
cruiseState={"speedCluster": 62 * CV.MPH_TO_MS},
)
self.v_cruise_helper.initialize_v_cruise(cs, experimental_mode=False, resume_prev_button=False,
starpilot_toggles=self.starpilot_toggles)
assert self.v_cruise_helper.v_cruise_kph == pytest.approx(62 * CV.MPH_TO_KPH)
assert self.v_cruise_helper.v_cruise_cluster_kph == pytest.approx(62 * CV.MPH_TO_KPH)
def test_update_v_cruise_does_not_follow_stock_pcm_speed(self):
cs = car.CarState(
vEgo=55 * CV.MPH_TO_MS,
cruiseState={"speedCluster": 62 * CV.MPH_TO_MS},
)
self.v_cruise_helper.initialize_v_cruise(cs, experimental_mode=False, resume_prev_button=False,
starpilot_toggles=self.starpilot_toggles)
update_cs = car.CarState(
cruiseState={"available": True, "speed": 50 * CV.MPH_TO_MS, "speedCluster": 50 * CV.MPH_TO_MS},
)
self.v_cruise_helper.update_v_cruise(update_cs, enabled=True, is_metric=False,
speed_limit_changed=False, starpilot_toggles=self.starpilot_toggles)
assert self.v_cruise_helper.v_cruise_kph == pytest.approx(62 * CV.MPH_TO_KPH)
assert self.v_cruise_helper.v_cruise_cluster_kph == pytest.approx(62 * CV.MPH_TO_KPH)
def test_resume_keeps_previous_internal_max_speed(self):
engage_cs = car.CarState(
vEgo=75 * CV.MPH_TO_MS,
cruiseState={"speedCluster": 75 * CV.MPH_TO_MS},
)
self.v_cruise_helper.initialize_v_cruise(engage_cs, experimental_mode=False, resume_prev_button=False,
starpilot_toggles=self.starpilot_toggles)
disabled_cs = car.CarState(
cruiseState={"available": True, "speedCluster": 38 * CV.MPH_TO_MS},
)
self.v_cruise_helper.update_v_cruise(disabled_cs, enabled=False, is_metric=False,
speed_limit_changed=False, starpilot_toggles=self.starpilot_toggles)
resume_cs = car.CarState(
vEgo=38 * CV.MPH_TO_MS,
cruiseState={"speedCluster": 38 * CV.MPH_TO_MS},
)
self.v_cruise_helper.initialize_v_cruise(resume_cs, experimental_mode=False, resume_prev_button=True,
starpilot_toggles=self.starpilot_toggles)
assert self.v_cruise_helper.v_cruise_kph == pytest.approx(75 * CV.MPH_TO_KPH)
assert self.v_cruise_helper.v_cruise_cluster_kph == pytest.approx(75 * CV.MPH_TO_KPH)
def test_reverse_cruise_increase_swaps_short_and_long_press_intervals(self):
self.enable(55 * CV.MPH_TO_MS, experimental_mode=False)
initial_v_cruise_kph = self.v_cruise_helper.v_cruise_kph
self.starpilot_toggles.cruise_increase = 1
self.starpilot_toggles.cruise_increase_long = 5
self.starpilot_toggles.reverse_cruise_increase = True
pressed_cs = car.CarState(cruiseState={"available": True})
pressed_cs.buttonEvents = [ButtonEvent(type=ButtonType.accelCruise, pressed=True)]
self.v_cruise_helper.update_v_cruise(
pressed_cs,
enabled=True,
is_metric=False,
speed_limit_changed=False,
starpilot_toggles=self.starpilot_toggles,
)
released_cs = car.CarState(cruiseState={"available": True})
released_cs.buttonEvents = [ButtonEvent(type=ButtonType.accelCruise, pressed=False)]
self.v_cruise_helper.update_v_cruise(
released_cs,
enabled=True,
is_metric=False,
speed_limit_changed=False,
starpilot_toggles=self.starpilot_toggles,
)
reversed_interval = 5 * IMPERIAL_INCREMENT
expected_kph = math.ceil(initial_v_cruise_kph / reversed_interval) * reversed_interval
assert self.v_cruise_helper.v_cruise_kph == pytest.approx(expected_kph)
+112 -3
View File
@@ -5,11 +5,14 @@ from cereal import car
from openpilot.common.constants import CV
from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car.redneck_cruise import (
INACTIVE_TIMER,
DECREASE_INACTIVE_TIMER,
INCREASE_INACTIVE_TIMER,
LEAD_INCREASE_INACTIVE_TIMER,
RedneckCruise,
SEND_BUTTON_DECREASE,
SEND_BUTTON_INCREASE,
SEND_BUTTON_NONE,
select_redneck_target_speed,
)
@@ -39,8 +42,9 @@ class TestRedneckCruise(unittest.TestCase):
def _button_event(button_type, pressed):
return SimpleNamespace(type=button_type, pressed=pressed)
def _run_until_active(self, target_mph, speed_cluster_mph=20.0, button_events=None, override=False, cancel=False, resume=False):
frames = int(INACTIVE_TIMER / DT_CTRL) + 2
def _run_until_active(self, target_mph, speed_cluster_mph=20.0, button_events=None,
override=False, cancel=False, resume=False, lead_present=False):
frames = int(max(INCREASE_INACTIVE_TIMER, DECREASE_INACTIVE_TIMER) / DT_CTRL) + 2
send_button = SEND_BUTTON_NONE
v_target = 0
for _ in range(frames):
@@ -49,10 +53,25 @@ class TestRedneckCruise(unittest.TestCase):
self._new_control(override=override, cancel=cancel, resume=resume),
target_mph * CV.MPH_TO_MS,
is_metric=False,
lead_present=lead_present,
)
button_events = None
return send_button, v_target
def _frames_until_button(self, target_mph, speed_cluster_mph, lead_present=False):
frames = int(INCREASE_INACTIVE_TIMER / DT_CTRL) + 4
for frame in range(frames):
send_button, _ = self.redneck.run(
self._new_state(speed_cluster_mph=speed_cluster_mph),
self._new_control(),
target_mph * CV.MPH_TO_MS,
is_metric=False,
lead_present=lead_present,
)
if send_button != SEND_BUTTON_NONE:
return frame
return None
def test_increases_cluster_speed_toward_target(self):
send_button, v_target = self._run_until_active(target_mph=25.0, speed_cluster_mph=20.0)
self.assertEqual(SEND_BUTTON_INCREASE, send_button)
@@ -63,6 +82,25 @@ class TestRedneckCruise(unittest.TestCase):
self.assertEqual(SEND_BUTTON_DECREASE, send_button)
self.assertEqual(20, v_target)
def test_decrease_activates_faster_than_increase(self):
decrease_frame = self._frames_until_button(target_mph=20.0, speed_cluster_mph=25.0)
self.redneck = RedneckCruise(self.CP, self.FPCP)
increase_frame = self._frames_until_button(target_mph=25.0, speed_cluster_mph=20.0)
self.assertIsNotNone(decrease_frame)
self.assertIsNotNone(increase_frame)
self.assertLess(decrease_frame, increase_frame)
def test_lead_increase_activates_faster_than_free_cruise_increase(self):
free_cruise_frame = self._frames_until_button(target_mph=25.0, speed_cluster_mph=20.0, lead_present=False)
self.redneck = RedneckCruise(self.CP, self.FPCP)
lead_frame = self._frames_until_button(target_mph=25.0, speed_cluster_mph=20.0, lead_present=True)
self.assertIsNotNone(free_cruise_frame)
self.assertIsNotNone(lead_frame)
self.assertLess(lead_frame, free_cruise_frame)
self.assertLessEqual(lead_frame, int(LEAD_INCREASE_INACTIVE_TIMER / DT_CTRL))
def test_suppresses_output_during_manual_cruise_button_use(self):
button_event = self._button_event(ButtonType.accelCruise, True)
send_button, _ = self._run_until_active(target_mph=25.0, speed_cluster_mph=20.0, button_events=[button_event])
@@ -85,6 +123,77 @@ class TestRedneckCruise(unittest.TestCase):
self.assertEqual(SEND_BUTTON_NONE, send_button)
self.assertEqual(0, v_target)
def test_target_speed_returns_internal_max_when_plan_only_wants_to_speed_back_up(self):
target_speed = select_redneck_target_speed(
120.0,
77.0 * CV.MPH_TO_MS,
0.0,
[78.3 * CV.MPH_TO_MS, 78.2 * CV.MPH_TO_MS, 78.1 * CV.MPH_TO_MS],
10,
)
self.assertAlmostEqual(120.0 * CV.KPH_TO_MS, target_speed)
def test_target_speed_ignores_plan_drift_during_free_cruise(self):
target_speed = select_redneck_target_speed(
104.4,
63.0 * CV.MPH_TO_MS,
0.0,
[62.55 * CV.MPH_TO_MS, 62.44 * CV.MPH_TO_MS, 62.36 * CV.MPH_TO_MS],
10,
allow_plan_decrease=False,
)
self.assertAlmostEqual(104.4 * CV.KPH_TO_MS, target_speed)
def test_target_speed_returns_plan_minimum_when_slowing_down(self):
target_speed = select_redneck_target_speed(
120.0,
75.0 * CV.MPH_TO_MS,
0.0,
[74.0 * CV.MPH_TO_MS, 72.0 * CV.MPH_TO_MS, 71.0 * CV.MPH_TO_MS],
10,
allow_plan_decrease=True,
)
self.assertAlmostEqual(71.0 * CV.MPH_TO_MS, target_speed)
def test_target_speed_uses_longer_horizon_and_buffer_for_lead_slowdown(self):
target_speed = select_redneck_target_speed(
120.0,
75.0 * CV.MPH_TO_MS,
0.0,
[74.9 * CV.MPH_TO_MS, 74.6 * CV.MPH_TO_MS, 74.2 * CV.MPH_TO_MS, 73.8 * CV.MPH_TO_MS,
73.4 * CV.MPH_TO_MS, 73.0 * CV.MPH_TO_MS, 72.6 * CV.MPH_TO_MS, 72.2 * CV.MPH_TO_MS,
71.8 * CV.MPH_TO_MS, 71.4 * CV.MPH_TO_MS, 71.0 * CV.MPH_TO_MS],
11,
allow_plan_decrease=True,
lead_present=True,
)
self.assertLess(target_speed, 71.4 * CV.MPH_TO_MS)
def test_target_speed_uses_near_term_recovery_for_lead_speedup(self):
target_speed = select_redneck_target_speed(
120.0,
55.0 * CV.MPH_TO_MS,
0.0,
[57.15 * CV.MPH_TO_MS, 56.9 * CV.MPH_TO_MS, 56.4 * CV.MPH_TO_MS, 55.8 * CV.MPH_TO_MS,
54.88 * CV.MPH_TO_MS, 52.0 * CV.MPH_TO_MS, 50.15 * CV.MPH_TO_MS],
10,
allow_plan_decrease=True,
lead_present=True,
)
self.assertAlmostEqual(55.8 * CV.MPH_TO_MS, target_speed)
def test_target_speed_stays_on_lead_target_when_cluster_drops_below_it(self):
target_speed = select_redneck_target_speed(
76.9,
32.9 * CV.MPH_TO_MS,
47.8 * CV.MPH_TO_MS,
[37.3 * CV.MPH_TO_MS, 37.2 * CV.MPH_TO_MS, 37.1 * CV.MPH_TO_MS],
10,
allow_plan_decrease=True,
lead_present=True,
)
self.assertAlmostEqual(37.1 * CV.MPH_TO_MS, target_speed)
if __name__ == "__main__":
unittest.main()
+49 -6
View File
@@ -23,6 +23,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import (
get_bolt_2017_steer_ratio_scale,
)
from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.car.cruise_state import should_cancel_stock_cruise
from openpilot.selfdrive.modeld.modeld import LAT_SMOOTH_SECONDS
from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose
@@ -46,6 +47,30 @@ def get_gm_hud_set_speed(set_speed_ms: float, starpilot_toggles) -> float:
return spoofed_speed
def get_torque_control_params(CP, torque_params, starpilot_toggles, use_live_params: bool) -> tuple[float, float, float]:
torque_tune = CP.lateralTuning.torque
lat_accel_factor = torque_tune.latAccelFactor
lat_accel_offset = torque_tune.latAccelOffset
friction = torque_tune.friction
use_custom_lat_accel = getattr(starpilot_toggles, "use_custom_latAccelFactor", False)
use_custom_friction = getattr(starpilot_toggles, "use_custom_friction", False)
if use_live_params:
if not use_custom_lat_accel:
lat_accel_factor = torque_params.latAccelFactorFiltered
lat_accel_offset = torque_params.latAccelOffsetFiltered
if not use_custom_friction:
friction = torque_params.frictionCoefficientFiltered
if use_custom_lat_accel:
lat_accel_factor = starpilot_toggles.latAccelFactor
if use_custom_friction:
friction = starpilot_toggles.friction
return lat_accel_factor, lat_accel_offset, friction
class Controls:
def __init__(self) -> None:
self.params = Params()
@@ -82,6 +107,8 @@ class Controls:
self.sm = self.sm.extend(['liveDelay', 'starpilotCarState', 'starpilotPlan'])
self.starpilot_toggles = get_starpilot_toggles()
self.ecu_disable_failed = False
self.ecu_disable_failed_checked = not self.CP.openpilotLongitudinalControl
if self.CP.lateralTuning.which() == "torque" and (self.starpilot_toggles.nnff or self.starpilot_toggles.nnff_lite):
self.LaC = LatControlNNFF(self.CP, self.CI, DT_CTRL)
@@ -102,6 +129,16 @@ class Controls:
self.starpilot_toggles = get_starpilot_toggles(self.sm)
def update_ecu_disable_failed(self):
if self.ecu_disable_failed_checked:
return
# ControlsReady is set after CarInterface.init(), where Hyundai ECU disable
# writes EcuDisableFailed. Once init has completed, the value is stable.
if self.params.get_bool("ControlsReady"):
self.ecu_disable_failed = self.params.get_bool("EcuDisableFailed")
self.ecu_disable_failed_checked = True
def state_control(self):
CS = self.sm['carState']
@@ -121,9 +158,15 @@ class Controls:
# Update Torque Params
if self.CP.lateralTuning.which() == 'torque':
torque_params = self.sm['liveTorqueParameters']
if self.sm.all_checks(['liveTorqueParameters']) and (torque_params.useParams or self.starpilot_toggles.force_auto_tune):
self.LaC.update_live_torque_params(torque_params.latAccelFactorFiltered, torque_params.latAccelOffsetFiltered,
torque_params.frictionCoefficientFiltered)
force_auto_tune = getattr(self.starpilot_toggles, "force_auto_tune", False)
use_live_params = self.sm.all_checks(['liveTorqueParameters']) and (torque_params.useParams or force_auto_tune)
use_custom_torque_params = (
getattr(self.starpilot_toggles, "use_custom_latAccelFactor", False) or
getattr(self.starpilot_toggles, "use_custom_friction", False)
)
if use_live_params or use_custom_torque_params:
lat_accel_factor, lat_accel_offset, friction = get_torque_control_params(self.CP, torque_params, self.starpilot_toggles, use_live_params)
self.LaC.update_live_torque_params(lat_accel_factor, lat_accel_offset, friction)
long_plan = self.sm['longitudinalPlan']
model_v2 = self.sm['modelV2']
@@ -140,8 +183,8 @@ class Controls:
self.sm['starpilotPlan'].lateralCheck)
# EcuDisableFailed is set when car started in READY mode (ECU disable was rejected)
# Disable longitudinal so stock ACC works instead
ecu_disable_failed = self.params.get_bool("EcuDisableFailed")
CC.longActive = CC.enabled and not any(e.overrideLongitudinal for e in self.sm['onroadEvents']) and not self.sm['starpilotCarState'].pauseLongitudinal and self.CP.openpilotLongitudinalControl and not ecu_disable_failed
self.update_ecu_disable_failed()
CC.longActive = CC.enabled and not any(e.overrideLongitudinal for e in self.sm['onroadEvents']) and not self.sm['starpilotCarState'].pauseLongitudinal and self.CP.openpilotLongitudinalControl and not self.ecu_disable_failed
actuators = CC.actuators
actuators.longControlState = self.LoC.long_control_state
@@ -233,7 +276,7 @@ class Controls:
CC.enabled,
self.sm['starpilotCarState'].alwaysOnLateralEnabled,
)
cancel_requested = CS.cruiseState.enabled and (not CC.enabled or not self.CP.pcmCruise)
cancel_requested = should_cancel_stock_cruise(self.CP, CS.cruiseState.enabled, CC.enabled)
CC.cruiseControl.cancel = cancel_requested and not pacifica_hybrid_aol
legacy_resume_hack = False
+27 -3
View File
@@ -14,6 +14,8 @@ LANE_CHANGE_SPEED_MIN = 20 * CV.MPH_TO_MS
LANE_CHANGE_TIME_MAX = 10.
NAV_TURN_DISTANCE_SPEED_BREAKPOINTS = [0.0, 5.0, 10.0]
NAV_TURN_DISTANCE_BREAKPOINTS = [20.0, 25.0, 30.0]
NAV_KEEP_DISTANCE_SPEED_BREAKPOINTS = [0.0, 15.0, 30.0]
NAV_KEEP_DISTANCE_BREAKPOINTS = [25.0, 90.0, 160.0]
DESIRES = {
LaneChangeDirection.none: {
@@ -116,17 +118,39 @@ class DesireHelper:
return distance <= float(np.interp(carstate.vEgo, NAV_TURN_DISTANCE_SPEED_BREAKPOINTS, NAV_TURN_DISTANCE_BREAKPOINTS))
@staticmethod
def _nav_keep_is_imminent(carstate, maneuver_distance):
try:
distance = float(maneuver_distance)
except (TypeError, ValueError):
return False
return distance <= float(np.interp(carstate.vEgo, NAV_KEEP_DISTANCE_SPEED_BREAKPOINTS, NAV_KEEP_DISTANCE_BREAKPOINTS))
@staticmethod
def _nav_effective_modifier(nav_instruction_state, carstate, maneuver_distance):
modifier = str(nav_instruction_state.get("maneuverModifier", ""))
maneuver_type = str(nav_instruction_state.get("maneuverType", ""))
active_lane_direction = str(nav_instruction_state.get("activeLaneDirection", ""))
if modifier in ("left", "right") and maneuver_type in ("off ramp", "fork") and DesireHelper._nav_keep_is_imminent(carstate, maneuver_distance):
if active_lane_direction in ("slightLeft", "left"):
return "slightLeft"
if active_lane_direction in ("slightRight", "right"):
return "slightRight"
return modifier
def _navigation_desire(self, carstate, lateral_active, starpilotPlan, starpilot_toggles):
self._update_nav_params()
if not self.nav_desires_allowed or not lateral_active or not bool(self._nav_instruction_state.get("valid", False)):
return log.Desire.none
modifier = str(self._nav_instruction_state.get("maneuverModifier", ""))
maneuver_distance = self._nav_instruction_state.get("maneuverDistance", 0.0)
modifier = self._nav_effective_modifier(self._nav_instruction_state, carstate, maneuver_distance)
if modifier == "":
return log.Desire.none
maneuver_distance = self._nav_instruction_state.get("maneuverDistance", 0.0)
if modifier == "slightLeft":
lane_change_direction = LaneChangeDirection.left
desired_lane_width = starpilotPlan.laneWidthLeft
+348 -35
View File
@@ -6,6 +6,7 @@ from cereal import log
from opendbc.car.gm.values import CAR as GM_CAR
from opendbc.car.honda.values import CAR as HONDA_CAR, HondaFlags
from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR
from opendbc.car.toyota.values import CAR as TOYOTA_CAR
from opendbc.car.lateral import get_friction
from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY, CV
from openpilot.common.filter_simple import FirstOrderFilter
@@ -113,6 +114,10 @@ VOLT_STANDARD_CARS = (
GENESIS_G90_CARS = (
HYUNDAI_CAR.GENESIS_G90,
)
PALISADE_CARS = (
HYUNDAI_CAR.HYUNDAI_PALISADE,
HYUNDAI_CAR.HYUNDAI_PALISADE_2023,
)
IONIQ_5_CARS = (
HYUNDAI_CAR.HYUNDAI_IONIQ_5,
)
@@ -126,6 +131,9 @@ IONIQ_6_CARS = (
SONATA_HYBRID_CARS = (
HYUNDAI_CAR.HYUNDAI_SONATA_HYBRID,
)
SONATA_CARS = (
HYUNDAI_CAR.HYUNDAI_SONATA,
)
ELANTRA_NON_SCC_CARS = (
HYUNDAI_CAR.HYUNDAI_ELANTRA_2022_NON_SCC,
HYUNDAI_CAR.HYUNDAI_ELANTRA_HEV_2022_NON_SCC,
@@ -136,6 +144,9 @@ KIA_EV6_CARS = (
KIA_FORTE_CARS = (
HYUNDAI_CAR.KIA_FORTE,
)
PRIUS_CARS = (
TOYOTA_CAR.TOYOTA_PRIUS,
)
BOLT_2017_LATERAL_TESTING_GROUND_ID = testing_ground.id_3
BOLT_2017_STEER_RATIO_TEST_SCALE = 1.045
@@ -268,6 +279,29 @@ SONATA_HYBRID_LOW_SPEED_CENTER_TAPER_LAT_WIDTH = 0.02
SONATA_HYBRID_LOW_SPEED_CENTER_TAPER_SPEED_MAX = 7.5
SONATA_HYBRID_LOW_SPEED_CENTER_TAPER_SPEED_WIDTH = 1.0
SONATA_FF_REDUCTION_LEFT = 0.04
SONATA_FF_REDUCTION_RIGHT = 0.26
SONATA_FF_ONSET = 0.18
SONATA_FF_ONSET_WIDTH = 0.08
SONATA_FF_CUTOFF = 1.40
SONATA_FF_CUTOFF_WIDTH = 0.42
SONATA_TRANSITION_SPEED = 8.5
SONATA_PHASE_SCALE = 0.12
SONATA_TURN_IN_BOOST_LEFT = 0.18
SONATA_TURN_IN_BOOST_RIGHT = 0.00
SONATA_UNWIND_TAPER_LEFT = 0.28
SONATA_UNWIND_TAPER_RIGHT = 0.00
SONATA_CENTER_TAPER_MAX = 0.04
SONATA_CENTER_TAPER_LAT = 0.15
SONATA_CENTER_TAPER_LAT_WIDTH = 0.025
SONATA_CENTER_TAPER_SPEED = 22.0
SONATA_CENTER_TAPER_SPEED_WIDTH = 2.5
SONATA_LOW_SPEED_CENTER_TAPER_MAX = 0.08
SONATA_LOW_SPEED_CENTER_TAPER_LAT = 0.10
SONATA_LOW_SPEED_CENTER_TAPER_LAT_WIDTH = 0.02
SONATA_LOW_SPEED_CENTER_TAPER_SPEED_MAX = 7.0
SONATA_LOW_SPEED_CENTER_TAPER_SPEED_WIDTH = 1.0
ELANTRA_NON_SCC_FF_ADJUST_LEFT = 0.02
ELANTRA_NON_SCC_FF_ADJUST_RIGHT = -0.02
ELANTRA_NON_SCC_FF_ONSET = 0.14
@@ -294,12 +328,43 @@ KIA_FORTE_TURN_IN_BOOST_LEFT = 0.10
KIA_FORTE_TURN_IN_BOOST_RIGHT = 0.00
KIA_FORTE_UNWIND_TAPER_LEFT = 0.26
KIA_FORTE_UNWIND_TAPER_RIGHT = 0.04
KIA_FORTE_CRAWL_TURN_IN_FF_BOOST_LEFT = 0.10
KIA_FORTE_CRAWL_TURN_IN_FF_BOOST_RIGHT = 0.14
KIA_FORTE_CRAWL_TURN_IN_FF_SPEED = 4.5
KIA_FORTE_CRAWL_TURN_IN_FF_SPEED_WIDTH = 0.8
KIA_FORTE_CRAWL_TURN_IN_FF_LAT = 0.10
KIA_FORTE_CRAWL_TURN_IN_FF_LAT_WIDTH = 0.05
KIA_FORTE_CENTER_TAPER_MAX = 0.14
KIA_FORTE_CENTER_TAPER_LAT = 0.16
KIA_FORTE_CENTER_TAPER_LAT_WIDTH = 0.03
KIA_FORTE_CENTER_TAPER_SPEED = 24.0
KIA_FORTE_CENTER_TAPER_SPEED_WIDTH = 2.5
PALISADE_BASE_LAT_ACCEL_FACTOR_MULT = 0.98
PALISADE_FF_GAIN_LEFT = 0.14
PALISADE_FF_GAIN_RIGHT = 0.12
PALISADE_FF_ONSET = 0.08
PALISADE_FF_ONSET_WIDTH = 0.04
PALISADE_FF_CUTOFF = 1.25
PALISADE_FF_CUTOFF_WIDTH = 0.36
PALISADE_TRANSITION_SPEED = 9.0
PALISADE_PHASE_SCALE = 0.11
PALISADE_TURN_IN_BOOST_LEFT = 0.34
PALISADE_TURN_IN_BOOST_RIGHT = 0.24
PALISADE_UNWIND_TAPER_LEFT = 0.18
PALISADE_UNWIND_TAPER_RIGHT = 0.30
PALISADE_FRICTION_MULT = 1.02
PALISADE_FRICTION_LAT_RISE = 0.20
PALISADE_FRICTION_JERK_RISE = 0.24
PALISADE_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.18
PALISADE_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.14
PALISADE_UNWIND_THRESHOLD_INCREASE_LEFT = 0.14
PALISADE_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.22
PALISADE_TURN_IN_FRICTION_BOOST_LEFT = 0.08
PALISADE_TURN_IN_FRICTION_BOOST_RIGHT = 0.06
PALISADE_UNWIND_FRICTION_REDUCTION_LEFT = 0.12
PALISADE_UNWIND_FRICTION_REDUCTION_RIGHT = 0.20
GENESIS_G90_LATERAL_TESTING_GROUND_ID = testing_ground.id_4
GENESIS_G90_FF_GAIN_LEFT = 0.32
GENESIS_G90_FF_GAIN_RIGHT = 0.16
@@ -330,26 +395,26 @@ IONIQ_5_FF_ONSET = 0.10
IONIQ_5_FF_ONSET_WIDTH = 0.05
IONIQ_5_FF_CUTOFF = 1.20
IONIQ_5_FF_CUTOFF_WIDTH = 0.30
IONIQ_5_TRANSITION_SPEED = 11.0
IONIQ_5_TRANSITION_SPEED = 12.5
IONIQ_5_PHASE_SCALE = 0.10
IONIQ_5_FF_REDUCTION_LEFT = 0.14
IONIQ_5_FF_REDUCTION_RIGHT = 0.18
IONIQ_5_TURN_IN_BOOST_LEFT = 0.04
IONIQ_5_TURN_IN_BOOST_RIGHT = 0.00
IONIQ_5_UNWIND_TAPER_LEFT = 0.52
IONIQ_5_UNWIND_TAPER_RIGHT = 0.82
IONIQ_5_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.05
IONIQ_5_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.00
IONIQ_5_UNWIND_THRESHOLD_INCREASE_LEFT = 0.24
IONIQ_5_FF_REDUCTION_LEFT = 0.12
IONIQ_5_FF_REDUCTION_RIGHT = 0.22
IONIQ_5_TURN_IN_BOOST_LEFT = 0.14
IONIQ_5_TURN_IN_BOOST_RIGHT = 0.06
IONIQ_5_UNWIND_TAPER_LEFT = 0.76
IONIQ_5_UNWIND_TAPER_RIGHT = 0.86
IONIQ_5_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.08
IONIQ_5_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.05
IONIQ_5_UNWIND_THRESHOLD_INCREASE_LEFT = 0.36
IONIQ_5_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.38
IONIQ_5_TURN_IN_FRICTION_BOOST_LEFT = 0.02
IONIQ_5_TURN_IN_FRICTION_BOOST_RIGHT = 0.00
IONIQ_5_UNWIND_FRICTION_REDUCTION_LEFT = 0.22
IONIQ_5_UNWIND_FRICTION_REDUCTION_RIGHT = 0.32
IONIQ_5_CENTER_TAPER_MAX = 0.08
IONIQ_5_CENTER_TAPER_LAT = 0.16
IONIQ_5_TURN_IN_FRICTION_BOOST_LEFT = 0.04
IONIQ_5_TURN_IN_FRICTION_BOOST_RIGHT = 0.03
IONIQ_5_UNWIND_FRICTION_REDUCTION_LEFT = 0.34
IONIQ_5_UNWIND_FRICTION_REDUCTION_RIGHT = 0.34
IONIQ_5_CENTER_TAPER_MAX = 0.14
IONIQ_5_CENTER_TAPER_LAT = 0.12
IONIQ_5_CENTER_TAPER_LAT_WIDTH = 0.03
IONIQ_5_CENTER_TAPER_SPEED = 20.0
IONIQ_5_CENTER_TAPER_SPEED = 16.0
IONIQ_5_CENTER_TAPER_SPEED_WIDTH = 2.5
IONIQ_EV_OLD_BASE_LAT_ACCEL_FACTOR_MULT = 1.16
@@ -425,11 +490,17 @@ IONIQ_6_DIRECTIONAL_TAPER_UNWIND_FLOOR_LEFT = 0.10
IONIQ_6_DIRECTIONAL_TAPER_UNWIND_FLOOR_RIGHT = 0.04
IONIQ_6_DIRECTIONAL_TAPER_JERK_ONSET = 0.60
IONIQ_6_DIRECTIONAL_TAPER_JERK_WIDTH = 0.14
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF = 0.62
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_SPEED = 17.0
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_SPEED_WIDTH = 2.0
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_LAT = 0.45
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_LAT_WIDTH = 0.14
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF = 0.98
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_SPEED = 11.2
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_SPEED_WIDTH = 1.5
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_LAT = 0.10
IONIQ_6_DIRECTIONAL_TAPER_LOW_SPEED_RELIEF_LAT_WIDTH = 0.06
IONIQ_6_CRAWL_TURN_IN_FF_BOOST_LEFT = 0.12
IONIQ_6_CRAWL_TURN_IN_FF_BOOST_RIGHT = 0.16
IONIQ_6_CRAWL_TURN_IN_FF_SPEED = 4.5
IONIQ_6_CRAWL_TURN_IN_FF_SPEED_WIDTH = 0.8
IONIQ_6_CRAWL_TURN_IN_FF_LAT = 0.10
IONIQ_6_CRAWL_TURN_IN_FF_LAT_WIDTH = 0.05
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_LAT_START = 0.82
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_LAT_WIDTH = 0.12
IONIQ_6_HEAVY_DIRECTIONAL_TAPER_BASE_LEFT = 0.10
@@ -443,29 +514,29 @@ IONIQ_6_OUTPUT_DIRECTIONAL_TAPER_BLEND = 0.97
KIA_EV6_LATERAL_TESTING_GROUND_ID = testing_ground.id_6
KIA_EV6_LATERAL_TESTING_GROUND_VARIANT = "C"
KIA_EV6_FF_GAIN_LEFT = 0.07
KIA_EV6_FF_GAIN_RIGHT = 0.075
KIA_EV6_FF_GAIN_LEFT = 0.06
KIA_EV6_FF_GAIN_RIGHT = 0.07
KIA_EV6_FF_ONSET = 0.08
KIA_EV6_FF_ONSET_WIDTH = 0.04
KIA_EV6_FF_CUTOFF = 0.60
KIA_EV6_FF_CUTOFF_WIDTH = 0.14
KIA_EV6_TRANSITION_SPEED = 11.0
KIA_EV6_PHASE_SCALE = 0.09
KIA_EV6_TURN_IN_BOOST_LEFT = 0.14
KIA_EV6_TURN_IN_BOOST_RIGHT = 0.16
KIA_EV6_UNWIND_TAPER_LEFT = 0.40
KIA_EV6_UNWIND_TAPER_RIGHT = 0.36
KIA_EV6_TURN_IN_BOOST_LEFT = 0.18
KIA_EV6_TURN_IN_BOOST_RIGHT = 0.12
KIA_EV6_UNWIND_TAPER_LEFT = 0.48
KIA_EV6_UNWIND_TAPER_RIGHT = 0.46
KIA_EV6_FRICTION_MULT = 1.01
KIA_EV6_FRICTION_LAT_RISE = 0.18
KIA_EV6_FRICTION_JERK_RISE = 0.22
KIA_EV6_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.10
KIA_EV6_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.14
KIA_EV6_UNWIND_THRESHOLD_INCREASE_LEFT = 0.22
KIA_EV6_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.18
KIA_EV6_TURN_IN_FRICTION_BOOST_LEFT = 0.03
KIA_EV6_UNWIND_THRESHOLD_INCREASE_LEFT = 0.28
KIA_EV6_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.24
KIA_EV6_TURN_IN_FRICTION_BOOST_LEFT = 0.04
KIA_EV6_TURN_IN_FRICTION_BOOST_RIGHT = 0.05
KIA_EV6_UNWIND_FRICTION_REDUCTION_LEFT = 0.22
KIA_EV6_UNWIND_FRICTION_REDUCTION_RIGHT = 0.16
KIA_EV6_UNWIND_FRICTION_REDUCTION_LEFT = 0.28
KIA_EV6_UNWIND_FRICTION_REDUCTION_RIGHT = 0.22
KIA_EV6_CENTER_TAPER_MAX = 0.08
KIA_EV6_CENTER_TAPER_LAT = 0.16
KIA_EV6_CENTER_TAPER_LAT_WIDTH = 0.035
@@ -496,6 +567,28 @@ VOLT_PLEXY_TURN_IN_FRICTION_BOOST_LEFT = 0.08
VOLT_PLEXY_TURN_IN_FRICTION_BOOST_RIGHT = 0.06
VOLT_PLEXY_UNWIND_FRICTION_REDUCTION_LEFT = 0.16
VOLT_PLEXY_UNWIND_FRICTION_REDUCTION_RIGHT = 0.40
PRIUS_TRANSITION_SPEED = 10.0
PRIUS_PHASE_SCALE = 0.09
PRIUS_FF_GAIN_LEFT = 0.10
PRIUS_FF_GAIN_RIGHT = 0.14
PRIUS_FF_ONSET = 0.16
PRIUS_FF_ONSET_WIDTH = 0.08
PRIUS_FF_CUTOFF = 1.25
PRIUS_FF_CUTOFF_WIDTH = 0.30
PRIUS_FRICTION_LAT_RISE = 0.18
PRIUS_FRICTION_JERK_RISE = 0.22
PRIUS_TURN_IN_BOOST_LEFT = 0.48
PRIUS_TURN_IN_BOOST_RIGHT = 0.62
PRIUS_UNWIND_TAPER_LEFT = 0.44
PRIUS_UNWIND_TAPER_RIGHT = 0.72
PRIUS_TURN_IN_THRESHOLD_REDUCTION_LEFT = 0.18
PRIUS_TURN_IN_THRESHOLD_REDUCTION_RIGHT = 0.24
PRIUS_UNWIND_THRESHOLD_INCREASE_LEFT = 0.28
PRIUS_UNWIND_THRESHOLD_INCREASE_RIGHT = 0.44
PRIUS_TURN_IN_FRICTION_BOOST_LEFT = 0.08
PRIUS_TURN_IN_FRICTION_BOOST_RIGHT = 0.12
PRIUS_UNWIND_FRICTION_REDUCTION_LEFT = 0.14
PRIUS_UNWIND_FRICTION_REDUCTION_RIGHT = 0.24
def _sigmoid(x: float) -> float:
@@ -512,6 +605,74 @@ def get_friction_threshold(v_ego: float) -> float:
return float(np.interp(v_ego, [1 * CV.MPH_TO_MS, 20 * CV.MPH_TO_MS, 75 * CV.MPH_TO_MS], [0.16, 0.19, 0.27]))
def _prius_sigmoid(x: float) -> float:
return _sigmoid(x)
def _prius_low_speed_factor(v_ego: float) -> float:
return 1.0 / (1.0 + (max(v_ego, 0.0) / PRIUS_TRANSITION_SPEED) ** 2)
def _prius_transition_phase(desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
return math.tanh((desired_lateral_accel * desired_lateral_jerk) / PRIUS_PHASE_SCALE)
def _prius_side_value(desired_lateral_accel: float, left_value: float, right_value: float) -> float:
return left_value if desired_lateral_accel >= 0.0 else right_value
def _prius_transition_envelope(v_ego: float, desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
lat_factor = 1.0 - math.exp(-abs(desired_lateral_accel) / PRIUS_FRICTION_LAT_RISE)
jerk_factor = 1.0 - math.exp(-abs(desired_lateral_jerk) / PRIUS_FRICTION_JERK_RISE)
return _prius_low_speed_factor(v_ego) * lat_factor * jerk_factor
def get_prius_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: float, v_ego: float) -> float:
if desired_lateral_accel == 0.0:
return 1.0
gain = _prius_side_value(desired_lateral_accel, PRIUS_FF_GAIN_LEFT, PRIUS_FF_GAIN_RIGHT)
abs_lateral_accel = abs(desired_lateral_accel)
onset = _prius_sigmoid((abs_lateral_accel - PRIUS_FF_ONSET) / PRIUS_FF_ONSET_WIDTH)
cutoff = _prius_sigmoid((PRIUS_FF_CUTOFF - abs_lateral_accel) / PRIUS_FF_CUTOFF_WIDTH)
extra_scale = gain * onset * cutoff
phase = _prius_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
low_speed_factor = _prius_low_speed_factor(v_ego)
turn_in_boost = 1.0 + (_prius_side_value(desired_lateral_accel, PRIUS_TURN_IN_BOOST_LEFT, PRIUS_TURN_IN_BOOST_RIGHT) *
turn_in_weight * (0.35 + 0.65 * low_speed_factor))
unwind_taper = 1.0 - (_prius_side_value(desired_lateral_accel, PRIUS_UNWIND_TAPER_LEFT, PRIUS_UNWIND_TAPER_RIGHT) *
unwind_weight * (0.35 + 0.65 * low_speed_factor))
return 1.0 + (extra_scale * turn_in_boost * max(unwind_taper, 0.0))
def get_prius_friction_threshold(v_ego: float, desired_lateral_accel: float = 0.0, desired_lateral_jerk: float = 0.0) -> float:
base_threshold = get_friction_threshold(v_ego)
transition_envelope = _prius_transition_envelope(v_ego, desired_lateral_accel, desired_lateral_jerk)
phase = _prius_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
threshold_scale = 1.0 - (_prius_side_value(desired_lateral_accel, PRIUS_TURN_IN_THRESHOLD_REDUCTION_LEFT, PRIUS_TURN_IN_THRESHOLD_REDUCTION_RIGHT) *
transition_envelope * turn_in_weight)
threshold_scale += (_prius_side_value(desired_lateral_accel, PRIUS_UNWIND_THRESHOLD_INCREASE_LEFT, PRIUS_UNWIND_THRESHOLD_INCREASE_RIGHT) *
transition_envelope * unwind_weight)
return base_threshold * min(max(threshold_scale, 0.86), 1.16)
def get_prius_friction_scale(v_ego: float, desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
transition_envelope = _prius_transition_envelope(v_ego, desired_lateral_accel, desired_lateral_jerk)
phase = _prius_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
friction_scale = 1.0
friction_scale += (_prius_side_value(desired_lateral_accel, PRIUS_TURN_IN_FRICTION_BOOST_LEFT, PRIUS_TURN_IN_FRICTION_BOOST_RIGHT) *
transition_envelope * turn_in_weight)
friction_scale -= (_prius_side_value(desired_lateral_accel, PRIUS_UNWIND_FRICTION_REDUCTION_LEFT, PRIUS_UNWIND_FRICTION_REDUCTION_RIGHT) *
transition_envelope * unwind_weight)
return min(max(friction_scale, 0.90), 1.14)
def civic_bosch_modified_lateral_testing_ground_active() -> bool:
return testing_ground.use("8", "B")
@@ -993,6 +1154,53 @@ def get_sonata_hybrid_center_taper_scale(desired_lateral_accel: float, v_ego: fl
return 1.0 - reduction
def _sonata_sigmoid(x: float) -> float:
return _sigmoid(x)
def _sonata_low_speed_factor(v_ego: float) -> float:
return 1.0 / (1.0 + (max(v_ego, 0.0) / SONATA_TRANSITION_SPEED) ** 2)
def _sonata_transition_phase(desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
return math.tanh((desired_lateral_accel * desired_lateral_jerk) / SONATA_PHASE_SCALE)
def _sonata_side_value(desired_lateral_accel: float, left_value: float, right_value: float) -> float:
return left_value if desired_lateral_accel >= 0.0 else right_value
def get_sonata_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: float, v_ego: float) -> float:
if desired_lateral_accel == 0.0:
return 1.0
abs_lateral_accel = abs(desired_lateral_accel)
onset = _sonata_sigmoid((abs_lateral_accel - SONATA_FF_ONSET) / SONATA_FF_ONSET_WIDTH)
cutoff = _sonata_sigmoid((SONATA_FF_CUTOFF - abs_lateral_accel) / SONATA_FF_CUTOFF_WIDTH)
base_reduction = _sonata_side_value(desired_lateral_accel, SONATA_FF_REDUCTION_LEFT, SONATA_FF_REDUCTION_RIGHT) * onset * cutoff
phase = _sonata_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
low_speed_factor = _sonata_low_speed_factor(v_ego)
turn_in_boost = 1.0 + (_sonata_side_value(desired_lateral_accel, SONATA_TURN_IN_BOOST_LEFT, SONATA_TURN_IN_BOOST_RIGHT) *
turn_in_weight * low_speed_factor)
unwind_taper = 1.0 - (_sonata_side_value(desired_lateral_accel, SONATA_UNWIND_TAPER_LEFT, SONATA_UNWIND_TAPER_RIGHT) *
unwind_weight * (0.35 + 0.65 * low_speed_factor))
return (1.0 - base_reduction) * turn_in_boost * max(unwind_taper, 0.0)
def get_sonata_center_taper_scale(desired_lateral_accel: float, v_ego: float) -> float:
speed_weight = _sonata_sigmoid((v_ego - SONATA_CENTER_TAPER_SPEED) / SONATA_CENTER_TAPER_SPEED_WIDTH)
center_weight = _sonata_sigmoid((SONATA_CENTER_TAPER_LAT - abs(desired_lateral_accel)) / SONATA_CENTER_TAPER_LAT_WIDTH)
reduction = SONATA_CENTER_TAPER_MAX * speed_weight * center_weight
low_speed_weight = _sonata_sigmoid((SONATA_LOW_SPEED_CENTER_TAPER_SPEED_MAX - v_ego) /
SONATA_LOW_SPEED_CENTER_TAPER_SPEED_WIDTH)
low_speed_center_weight = _sonata_sigmoid((SONATA_LOW_SPEED_CENTER_TAPER_LAT - abs(desired_lateral_accel)) /
SONATA_LOW_SPEED_CENTER_TAPER_LAT_WIDTH)
reduction += SONATA_LOW_SPEED_CENTER_TAPER_MAX * low_speed_weight * low_speed_center_weight
return 1.0 - reduction
def _elantra_non_scc_sigmoid(x: float) -> float:
return _sigmoid(x)
@@ -1067,7 +1275,15 @@ def get_kia_forte_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: f
turn_in_weight * (0.35 + 0.65 * low_speed_factor))
unwind_taper = 1.0 - (_kia_forte_side_value(desired_lateral_accel, KIA_FORTE_UNWIND_TAPER_LEFT, KIA_FORTE_UNWIND_TAPER_RIGHT) *
unwind_weight * (0.35 + 0.65 * low_speed_factor))
return (1.0 - base_reduction) * turn_in_boost * max(unwind_taper, 0.0)
crawl_turn_in_scale = 0.0
if desired_lateral_accel * desired_lateral_jerk > 0.0:
crawl_speed_weight = _kia_forte_sigmoid((KIA_FORTE_CRAWL_TURN_IN_FF_SPEED - max(v_ego, 0.0)) /
KIA_FORTE_CRAWL_TURN_IN_FF_SPEED_WIDTH)
crawl_lat_weight = _kia_forte_sigmoid((abs_lateral_accel - KIA_FORTE_CRAWL_TURN_IN_FF_LAT) /
KIA_FORTE_CRAWL_TURN_IN_FF_LAT_WIDTH)
crawl_turn_in_scale = _kia_forte_side_value(desired_lateral_accel, KIA_FORTE_CRAWL_TURN_IN_FF_BOOST_LEFT,
KIA_FORTE_CRAWL_TURN_IN_FF_BOOST_RIGHT) * crawl_speed_weight * crawl_lat_weight
return ((1.0 - base_reduction) * turn_in_boost * max(unwind_taper, 0.0)) + crawl_turn_in_scale
def get_kia_forte_center_taper_scale(desired_lateral_accel: float, v_ego: float) -> float:
@@ -1077,6 +1293,74 @@ def get_kia_forte_center_taper_scale(desired_lateral_accel: float, v_ego: float)
return 1.0 - reduction
def _palisade_sigmoid(x: float) -> float:
return _sigmoid(x)
def _palisade_low_speed_factor(v_ego: float) -> float:
return 1.0 / (1.0 + (max(v_ego, 0.0) / PALISADE_TRANSITION_SPEED) ** 2)
def _palisade_transition_phase(desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
return math.tanh((desired_lateral_accel * desired_lateral_jerk) / PALISADE_PHASE_SCALE)
def _palisade_side_value(desired_lateral_accel: float, left_value: float, right_value: float) -> float:
return left_value if desired_lateral_accel >= 0.0 else right_value
def _palisade_transition_envelope(v_ego: float, desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
lat_factor = 1.0 - math.exp(-abs(desired_lateral_accel) / PALISADE_FRICTION_LAT_RISE)
jerk_factor = 1.0 - math.exp(-abs(desired_lateral_jerk) / PALISADE_FRICTION_JERK_RISE)
return _palisade_low_speed_factor(v_ego) * lat_factor * jerk_factor
def get_palisade_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: float, v_ego: float) -> float:
if desired_lateral_accel == 0.0:
return 1.0
gain = _palisade_side_value(desired_lateral_accel, PALISADE_FF_GAIN_LEFT, PALISADE_FF_GAIN_RIGHT)
abs_lateral_accel = abs(desired_lateral_accel)
onset = _palisade_sigmoid((abs_lateral_accel - PALISADE_FF_ONSET) / PALISADE_FF_ONSET_WIDTH)
cutoff = _palisade_sigmoid((PALISADE_FF_CUTOFF - abs_lateral_accel) / PALISADE_FF_CUTOFF_WIDTH)
extra_scale = gain * onset * cutoff
phase = _palisade_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
low_speed_factor = _palisade_low_speed_factor(v_ego)
turn_in_boost = 1.0 + (_palisade_side_value(desired_lateral_accel, PALISADE_TURN_IN_BOOST_LEFT, PALISADE_TURN_IN_BOOST_RIGHT) *
turn_in_weight * (0.35 + 0.65 * low_speed_factor))
unwind_taper = 1.0 - (_palisade_side_value(desired_lateral_accel, PALISADE_UNWIND_TAPER_LEFT, PALISADE_UNWIND_TAPER_RIGHT) *
unwind_weight * (0.35 + 0.65 * low_speed_factor))
return 1.0 + (extra_scale * turn_in_boost * max(unwind_taper, 0.0))
def get_palisade_friction_threshold(v_ego: float, desired_lateral_accel: float = 0.0, desired_lateral_jerk: float = 0.0) -> float:
base_threshold = get_friction_threshold(v_ego)
transition_envelope = _palisade_transition_envelope(v_ego, desired_lateral_accel, desired_lateral_jerk)
phase = _palisade_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
threshold_scale = 1.0 - (_palisade_side_value(desired_lateral_accel, PALISADE_TURN_IN_THRESHOLD_REDUCTION_LEFT, PALISADE_TURN_IN_THRESHOLD_REDUCTION_RIGHT) *
transition_envelope * turn_in_weight)
threshold_scale += (_palisade_side_value(desired_lateral_accel, PALISADE_UNWIND_THRESHOLD_INCREASE_LEFT, PALISADE_UNWIND_THRESHOLD_INCREASE_RIGHT) *
transition_envelope * unwind_weight)
return base_threshold * min(max(threshold_scale, 0.84), 1.14)
def get_palisade_friction_scale(v_ego: float, desired_lateral_accel: float, desired_lateral_jerk: float) -> float:
transition_envelope = _palisade_transition_envelope(v_ego, desired_lateral_accel, desired_lateral_jerk)
phase = _palisade_transition_phase(desired_lateral_accel, desired_lateral_jerk)
turn_in_weight = max(phase, 0.0)
unwind_weight = max(-phase, 0.0)
friction_scale = PALISADE_FRICTION_MULT
friction_scale += (_palisade_side_value(desired_lateral_accel, PALISADE_TURN_IN_FRICTION_BOOST_LEFT, PALISADE_TURN_IN_FRICTION_BOOST_RIGHT) *
transition_envelope * turn_in_weight)
friction_scale -= (_palisade_side_value(desired_lateral_accel, PALISADE_UNWIND_FRICTION_REDUCTION_LEFT, PALISADE_UNWIND_FRICTION_REDUCTION_RIGHT) *
transition_envelope * unwind_weight)
return min(max(friction_scale, 0.92), 1.12)
def genesis_g90_lateral_testing_ground_active() -> bool:
return testing_ground.use(GENESIS_G90_LATERAL_TESTING_GROUND_ID)
@@ -1309,7 +1593,15 @@ def get_ioniq_6_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: flo
turn_in_weight * low_speed_factor)
unwind_taper = 1.0 - (_ioniq_6_side_value(desired_lateral_accel, IONIQ_6_UNWIND_TAPER_LEFT, IONIQ_6_UNWIND_TAPER_RIGHT) *
unwind_weight * (0.30 + 0.70 * low_speed_factor))
return (1.0 + (extra_scale * turn_in_boost * max(unwind_taper, 0.0))) * get_ioniq_6_directional_taper_scale(desired_lateral_accel, desired_lateral_jerk, v_ego)
crawl_turn_in_scale = 0.0
if desired_lateral_accel * desired_lateral_jerk > 0.0:
crawl_speed_weight = _ioniq_6_sigmoid((IONIQ_6_CRAWL_TURN_IN_FF_SPEED - max(v_ego, 0.0)) /
IONIQ_6_CRAWL_TURN_IN_FF_SPEED_WIDTH)
crawl_lat_weight = _ioniq_6_sigmoid((abs_lateral_accel - IONIQ_6_CRAWL_TURN_IN_FF_LAT) /
IONIQ_6_CRAWL_TURN_IN_FF_LAT_WIDTH)
crawl_turn_in_scale = _ioniq_6_side_value(desired_lateral_accel, IONIQ_6_CRAWL_TURN_IN_FF_BOOST_LEFT,
IONIQ_6_CRAWL_TURN_IN_FF_BOOST_RIGHT) * crawl_speed_weight * crawl_lat_weight
return (1.0 + crawl_turn_in_scale + (extra_scale * turn_in_boost * max(unwind_taper, 0.0))) * get_ioniq_6_directional_taper_scale(desired_lateral_accel, desired_lateral_jerk, v_ego)
def get_ioniq_6_friction_threshold(v_ego: float, desired_lateral_accel: float = 0.0, desired_lateral_jerk: float = 0.0) -> float:
@@ -1577,9 +1869,12 @@ class LatControlTorque(LatControl):
self.is_bolt_2017 = CP.carFingerprint in BOLT_2017_CARS
self.is_volt_standard = CP.carFingerprint in VOLT_STANDARD_CARS
self.is_genesis_g90 = CP.carFingerprint in GENESIS_G90_CARS
self.is_palisade = CP.carFingerprint in PALISADE_CARS
self.is_prius = CP.carFingerprint in PRIUS_CARS
self.is_ioniq_5 = CP.carFingerprint in IONIQ_5_CARS
self.is_ioniq_ev_old = CP.carFingerprint in IONIQ_EV_OLD_CARS
self.is_ioniq_6 = CP.carFingerprint in IONIQ_6_CARS
self.is_sonata = CP.carFingerprint in SONATA_CARS
self.is_sonata_hybrid = CP.carFingerprint in SONATA_HYBRID_CARS
self.is_elantra_non_scc = CP.carFingerprint in ELANTRA_NON_SCC_CARS
self.is_kia_forte = CP.carFingerprint in KIA_FORTE_CARS
@@ -1593,6 +1888,8 @@ class LatControlTorque(LatControl):
self.torque_ff_scale_neg = 1.0
self.torque_deadzone_boost = float(getattr(self.torque_params, "kfDEPRECATED", 0.0))
self.torque_ki_mult = 1.0
if self.is_palisade:
self.torque_params.latAccelFactor *= PALISADE_BASE_LAT_ACCEL_FACTOR_MULT
if self.is_ioniq_5:
self.torque_params.latAccelFactor *= IONIQ_5_BASE_LAT_ACCEL_FACTOR_MULT
if self.is_ioniq_ev_old:
@@ -1620,6 +1917,8 @@ class LatControlTorque(LatControl):
self.pid._k_i = [self.pid._k_i[0], [k * self.torque_ki_mult for k in self.pid._k_i[1]]]
def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction):
if self.is_palisade:
latAccelFactor *= PALISADE_BASE_LAT_ACCEL_FACTOR_MULT
if self.is_ioniq_5:
latAccelFactor *= IONIQ_5_BASE_LAT_ACCEL_FACTOR_MULT
if self.is_ioniq_ev_old:
@@ -1703,9 +2002,12 @@ class LatControlTorque(LatControl):
bolt_2018_2021_tuned_path_active = self.is_bolt_2018_2021
volt_standard_test_active = self.is_volt_standard and volt_standard_lateral_testing_ground_active()
genesis_g90_test_active = self.is_genesis_g90 and genesis_g90_lateral_testing_ground_active()
palisade_active = self.is_palisade
prius_active = self.is_prius
ioniq_5_active = self.is_ioniq_5
ioniq_ev_old_active = self.is_ioniq_ev_old
ioniq_6_active = self.is_ioniq_6
sonata_active = self.is_sonata
sonata_hybrid_active = self.is_sonata_hybrid
elantra_non_scc_active = self.is_elantra_non_scc
kia_forte_active = self.is_kia_forte
@@ -1715,6 +2017,7 @@ class LatControlTorque(LatControl):
volt_standard_center_taper = get_volt_standard_center_taper_scale(setpoint, CS.vEgo) if volt_standard_test_active else 1.0
ioniq_ev_old_center_taper = get_ioniq_ev_old_center_taper_scale(setpoint, CS.vEgo) if ioniq_ev_old_active else 1.0
ioniq_6_center_taper = get_ioniq_6_center_taper_scale(setpoint, CS.vEgo) if ioniq_6_active else 1.0
sonata_center_taper = get_sonata_center_taper_scale(setpoint, CS.vEgo) if sonata_active else 1.0
sonata_hybrid_center_taper = get_sonata_hybrid_center_taper_scale(setpoint, CS.vEgo) if sonata_hybrid_active else 1.0
kia_forte_center_taper = get_kia_forte_center_taper_scale(setpoint, CS.vEgo) if kia_forte_active else 1.0
kia_ev6_center_taper = get_kia_ev6_center_taper_scale(setpoint, CS.vEgo) if kia_ev6_test_active else 1.0
@@ -1739,6 +2042,14 @@ class LatControlTorque(LatControl):
ff *= get_genesis_g90_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo)
friction_threshold = get_genesis_g90_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk)
friction_scale = get_genesis_g90_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk)
elif palisade_active:
ff *= get_palisade_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo)
friction_threshold = get_palisade_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk)
friction_scale = get_palisade_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk)
elif prius_active:
ff *= get_prius_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo)
friction_threshold = get_prius_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk)
friction_scale = get_prius_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk)
elif ioniq_5_active:
ff *= get_ioniq_5_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) * ioniq_5_center_taper
friction_threshold = get_ioniq_5_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk)
@@ -1752,6 +2063,8 @@ class LatControlTorque(LatControl):
friction_threshold = get_ioniq_6_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk) / max(ioniq_6_center_taper, 1e-3)
friction_scale = get_ioniq_6_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk)
friction_scale = 1.0 + ((friction_scale - 1.0) * ioniq_6_center_taper)
elif sonata_active:
ff *= get_sonata_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) * sonata_center_taper
elif sonata_hybrid_active:
ff *= get_sonata_hybrid_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) * sonata_hybrid_center_taper
elif elantra_non_scc_active:
@@ -79,6 +79,13 @@ FAR_RADAR_LEAD_ACCEL_TAPER_FULL_GAP_EXCESS = 25.0
FAR_RADAR_LEAD_ACCEL_TAPER_FULL_GAP_GAIN = 0.9
RADARLESS_MATCHED_FOLLOW_CRUISE_HYSTERESIS_MIN = 2.5
RADARLESS_MATCHED_FOLLOW_CRUISE_HYSTERESIS_GAIN = 0.10
NEAR_DUPLICATE_LEAD_SOURCE_MIN_SPEED = 20.0
NEAR_DUPLICATE_LEAD_SOURCE_MIN_MODEL_PROB = 0.9
NEAR_DUPLICATE_LEAD_SOURCE_MAX_LEAD_BRAKE = 0.35
NEAR_DUPLICATE_LEAD_SOURCE_MAX_DREL_DIFF = 1.5
NEAR_DUPLICATE_LEAD_SOURCE_MAX_VREL_DIFF = 0.35
NEAR_DUPLICATE_LEAD_SOURCE_HYSTERESIS_MIN = 0.75
NEAR_DUPLICATE_LEAD_SOURCE_HYSTERESIS_MAX = 1.5
# Function to get parameter value based on current speed
def get_speed_based_param(speed_mph, param_array):
@@ -492,9 +499,9 @@ class LongitudinalMpc:
# Adjust filter time constants for complex scenes
if abs(filter_time_factor - getattr(self, 'prev_filter_time_factor', 1.0)) > 0.05:
new_filter_time = self.current_filter_time * filter_time_factor
current_a = self.lead_a_filter.x if hasattr(self.lead_a_filter, 'x') else 0.0
current_v = self.lead_v_filter.x if hasattr(self.lead_v_filter, 'x') else 0.0
new_filter_time = self.current_filter_time * filter_time_factor
self.lead_a_filter = FirstOrderFilter(current_a, new_filter_time, self.dt)
self.lead_v_filter = FirstOrderFilter(current_v, new_filter_time, self.dt)
self.prev_filter_time_factor = filter_time_factor
@@ -583,6 +590,43 @@ class LongitudinalMpc:
return max(RADARLESS_MATCHED_FOLLOW_CRUISE_HYSTERESIS_MIN,
RADARLESS_MATCHED_FOLLOW_CRUISE_HYSTERESIS_GAIN * float(v_ego))
@staticmethod
def leads_are_near_duplicates(lead_one, lead_two, v_ego):
if lead_one is None or lead_two is None or not lead_one.status or not lead_two.status:
return False
if float(v_ego) < NEAR_DUPLICATE_LEAD_SOURCE_MIN_SPEED:
return False
if bool(getattr(lead_one, "radar", False)) or bool(getattr(lead_two, "radar", False)):
return False
if float(getattr(lead_one, "modelProb", 0.0)) < NEAR_DUPLICATE_LEAD_SOURCE_MIN_MODEL_PROB:
return False
if float(getattr(lead_two, "modelProb", 0.0)) < NEAR_DUPLICATE_LEAD_SOURCE_MIN_MODEL_PROB:
return False
if max(0.0, -float(getattr(lead_one, "aLeadK", 0.0))) > NEAR_DUPLICATE_LEAD_SOURCE_MAX_LEAD_BRAKE:
return False
if max(0.0, -float(getattr(lead_two, "aLeadK", 0.0))) > NEAR_DUPLICATE_LEAD_SOURCE_MAX_LEAD_BRAKE:
return False
return (
abs(float(lead_one.dRel) - float(lead_two.dRel)) <= NEAR_DUPLICATE_LEAD_SOURCE_MAX_DREL_DIFF and
abs(float(lead_one.vRel) - float(lead_two.vRel)) <= NEAR_DUPLICATE_LEAD_SOURCE_MAX_VREL_DIFF
)
def get_near_duplicate_lead_source_hysteresis(self, prev_source, lead_one, lead_two, v_ego):
if prev_source not in ("lead0", "lead1"):
return 0.0, 0.0
if not self.leads_are_near_duplicates(lead_one, lead_two, v_ego):
return 0.0, 0.0
hysteresis = float(np.interp(
float(v_ego),
[NEAR_DUPLICATE_LEAD_SOURCE_MIN_SPEED, 35.0],
[NEAR_DUPLICATE_LEAD_SOURCE_HYSTERESIS_MIN, NEAR_DUPLICATE_LEAD_SOURCE_HYSTERESIS_MAX],
))
if prev_source == "lead0":
return 0.0, hysteresis
return hysteresis, 0.0
def set_accel_limits(self, min_a, max_a):
# TODO this sets a max accel limit, but the minimum limit is only for cruise decel
# needs refactor
@@ -590,12 +634,12 @@ class LongitudinalMpc:
self.max_a = max_a
def update(self, radarstate, v_cruise, x, v, a, j, danger_factor, t_follow,
personality=log.LongitudinalPersonality.standard, tracking_lead=True):
personality=log.LongitudinalPersonality.standard, tracking_lead=True,
optional_far_lead_comfort=True):
v_ego = self.x0[1]
lead_one = radarstate.leadOne
lead_two = radarstate.leadTwo
self.status = tracking_lead and (lead_one.status or lead_two.status)
lead_xv_0 = self.process_lead(lead_one, tracking_lead, t_follow=t_follow)
lead_xv_1 = self.process_lead(lead_two, tracking_lead, t_follow=t_follow)
@@ -622,14 +666,19 @@ class LongitudinalMpc:
v_upper)
cruise_obstacle = np.cumsum(T_DIFFS * v_cruise_clipped) + get_safe_obstacle_distance(v_cruise_clipped, t_follow)
prev_source = self.source
if prev_source == 'lead0':
cruise_obstacle += self.get_radarless_matched_follow_cruise_hysteresis(lead_one, v_ego, t_follow)
elif prev_source == 'lead1':
cruise_obstacle += self.get_radarless_matched_follow_cruise_hysteresis(lead_two, v_ego, t_follow)
if tracking_lead and lead_one.status:
if optional_far_lead_comfort:
if prev_source == 'lead0':
cruise_obstacle += self.get_radarless_matched_follow_cruise_hysteresis(lead_one, v_ego, t_follow)
elif prev_source == 'lead1':
cruise_obstacle += self.get_radarless_matched_follow_cruise_hysteresis(lead_two, v_ego, t_follow)
if optional_far_lead_comfort and tracking_lead and lead_one.status:
desired_gap = desired_follow_distance(v_ego, lead_one.vLead, t_follow)
closing_speed = max(0.0, v_ego - lead_one.vLead)
cruise_obstacle += get_tracked_lead_catchup_bias(v_ego, lead_one.dRel, desired_gap, closing_speed, v_cruise=v_cruise)
if optional_far_lead_comfort:
lead_0_bias, lead_1_bias = self.get_near_duplicate_lead_source_hysteresis(prev_source, lead_one, lead_two, v_ego)
lead_0_obstacle = lead_0_obstacle + lead_0_bias
lead_1_obstacle = lead_1_obstacle + lead_1_bias
x_obstacles = np.column_stack([lead_0_obstacle, lead_1_obstacle, cruise_obstacle])
self.source = SOURCES[np.argmin(x_obstacles[0])]
+411 -30
View File
@@ -12,6 +12,7 @@ from openpilot.starpilot.common.model_versions import is_tinygrad_model_version
from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import LongitudinalMpc
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import desired_follow_distance
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import should_trigger_planner_fcw
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import STOP_DISTANCE
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import T_IDXS as T_IDXS_MPC
from openpilot.selfdrive.controls.lib.lead_behavior import is_radarless_matched_follow_window
@@ -34,16 +35,24 @@ RAW_LEAD_SAFETY_TTC = 7.0
RAW_LEAD_SAFETY_DISTANCE = 40.0
STANDSTILL_LEAD_NUDGE_ACCEL = 0.05
STANDSTILL_LEAD_NUDGE_MIN_SPEED = 0.0
STANDSTILL_LEAD_DEPART_MIN_ACCEL = 0.20
STANDSTILL_LEAD_DEPART_MIN_ACCEL = 0.35
STANDSTILL_LEAD_DEPART_MAX_EGO_SPEED = 1.5
STANDSTILL_LEAD_DEPART_MIN_LEAD_SPEED = 0.6
STANDSTILL_LEAD_DEPART_MIN_GAP_MARGIN = 1.5
STANDSTILL_LEAD_DEPART_MIN_GAP_MARGIN = 0.8
STANDSTILL_LEAD_DEPART_MIN_MODEL_ACCEL = 0.08
LEAD_DEPART_CONFIDENT_MIN_GAP = 3.75
LEAD_DEPART_CONFIDENT_MAX_GAP = 5.25
LEAD_DEPART_CONFIDENT_MIN_LEAD_SPEED = 0.5
LEAD_DEPART_CONFIDENT_MIN_LEAD_DELTA = 0.45
LEAD_DEPART_CONFIDENT_MIN_LEAD_ACCEL = 0.35
LEAD_DEPART_CONFIDENT_MIN_LEAD_SPEED = 0.3
LEAD_DEPART_CONFIDENT_MIN_LEAD_DELTA = 0.25
LEAD_DEPART_CONFIDENT_MIN_LEAD_ACCEL = 0.2
RADAR_DEPART_CONFLICT_MAX_EGO_SPEED = 1.6
RADAR_DEPART_CONFLICT_MIN_RADAR_LATERAL = 1.5
RADAR_DEPART_CONFLICT_MAX_RADAR_DISTANCE = 18.0
RADAR_DEPART_CONFLICT_MIN_MODEL_PROB = 0.95
RADAR_DEPART_CONFLICT_MAX_MODEL_DISTANCE = 18.0
RADAR_DEPART_CONFLICT_MAX_MODEL_LATERAL = 0.9
RADAR_DEPART_CONFLICT_MAX_MODEL_LEAD_SPEED = 2.0
RADAR_DEPART_CONFLICT_MAX_DISTANCE_MISMATCH = 4.0
LEAD_DEPART_ACCEL_HOLD_TIME = 1.2
LEAD_DEPART_ACCEL_HOLD_MAX_EGO_SPEED = 1.5
LEAD_DEPART_ACCEL_HOLD_MIN_LEAD_SPEED = 0.6
@@ -185,6 +194,17 @@ LOW_SPEED_FOLLOW_TRANSITION_PREV_ACCEL_MIN = 0.18
LOW_SPEED_FOLLOW_TRANSITION_TARGET_BRAKE_MIN = -0.18
LOW_SPEED_FOLLOW_TRANSITION_MAX_BRAKE = 0.14
LOW_SPEED_FOLLOW_TRANSITION_MIN_BRAKE = 0.08
CRUISE_TRACKED_LEAD_ACCEL_CAP_MIN_SPEED = 10.0
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_SPEED = 20.0
CRUISE_TRACKED_LEAD_ACCEL_CAP_MIN_MODEL_PROB = 0.85
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_LEAD_BRAKE = 0.25
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_PULLAWAY_SPEED = 1.0
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_GAP_BUFFER_MIN = 12.0
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_GAP_BUFFER_GAIN = 0.9
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_LATERAL_OFFSET = 1.15
CRUISE_TRACKED_LEAD_ACCEL_CAP_UNRESOLVED_MIN_CLOSING_SPEED = 1.5
CRUISE_TRACKED_LEAD_ACCEL_CAP_UNRESOLVED_MAX_LEAD_DELTA = 0.25
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_ACCEL = 0.18
# Uncertainty-based filter disable thresholds
UNCERT_SLOPE_TRIG = 0.12 # per second
@@ -224,6 +244,44 @@ FAR_LEAD_COMFORT_BRAKE_CAP_FULL_HEADWAY_MARGIN = 1.00
FAR_LEAD_COMFORT_BRAKE_CAP_MIN_DECEL = 0.05
FAR_LEAD_COMFORT_BRAKE_CAP_MAX_DECEL = 0.18
FAR_LEAD_COMFORT_BRAKE_CAP_FULL_RELAX_DECEL = 0.05
MATCHED_FOLLOW_TRANSITION_MIN_SPEED = 20.0
MATCHED_FOLLOW_TRANSITION_MIN_HEADWAY_MARGIN = 0.25
MATCHED_FOLLOW_TRANSITION_FULL_HEADWAY_MARGIN = 0.75
MATCHED_FOLLOW_TRANSITION_MIN_MODEL_PROB = 0.9
MATCHED_FOLLOW_TRANSITION_MAX_LEAD_BRAKE = 0.18
MATCHED_FOLLOW_TRANSITION_MAX_CLOSING_SPEED = 1.75
MATCHED_FOLLOW_TRANSITION_MIN_TTC = 12.0
MATCHED_FOLLOW_TRANSITION_MIN_POSITIVE_STEP = 0.08
MATCHED_FOLLOW_TRANSITION_MAX_POSITIVE_STEP = 0.18
MATCHED_FOLLOW_TRANSITION_MIN_NEGATIVE_STEP = 0.08
MATCHED_FOLLOW_TRANSITION_MAX_NEGATIVE_STEP = 0.16
MATCHED_FOLLOW_TRANSITION_SIGN_CROSS_STEP = 0.10
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_SPEED = 10.0
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_SPEED = MATCHED_FOLLOW_TRANSITION_MIN_SPEED
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_HEADWAY_MARGIN = 0.45
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_FULL_HEADWAY_MARGIN = 1.00
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_MODEL_PROB = 0.98
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_LEAD_BRAKE = 0.08
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_CLOSING_SPEED = 1.25
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_TTC = 18.0
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_POSITIVE_STEP = 0.06
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_POSITIVE_STEP = 0.10
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_NEGATIVE_STEP = 0.05
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_NEGATIVE_STEP = 0.08
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_SIGN_CROSS_STEP = 0.06
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_TARGET = -0.12
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_DELTA_A = 0.12
NEAR_DUPLICATE_LEAD_TRANSITION_MIN_SPEED = 20.0
NEAR_DUPLICATE_LEAD_TRANSITION_MIN_MODEL_PROB = 0.95
NEAR_DUPLICATE_LEAD_TRANSITION_MAX_LEAD_BRAKE = 0.35
NEAR_DUPLICATE_LEAD_TRANSITION_MAX_CLOSING_SPEED = 3.5
NEAR_DUPLICATE_LEAD_TRANSITION_MIN_TTC = 8.0
NEAR_DUPLICATE_LEAD_TRANSITION_MIN_HEADWAY_BELOW_TARGET = 0.45
NEAR_DUPLICATE_LEAD_TRANSITION_MAX_HEADWAY_ABOVE_TARGET = 0.85
NEAR_DUPLICATE_LEAD_TRANSITION_MIN_DELTA_A = 0.35
NEAR_DUPLICATE_LEAD_TRANSITION_POSITIVE_STEP = 0.22
NEAR_DUPLICATE_LEAD_TRANSITION_NEGATIVE_STEP = 0.32
NEAR_DUPLICATE_LEAD_TRANSITION_SIGN_CROSS_STEP = 0.18
TRACKED_VISION_MODEL_FLOOR_MIN_SPEED = 10.0
TRACKED_VISION_MODEL_FLOOR_MIN_MODEL_PROB = 0.95
TRACKED_VISION_MODEL_FLOOR_MIN_MODEL_DECEL = 0.80
@@ -295,6 +353,14 @@ def limit_accel_in_turns(v_ego, angle_steers, a_target, CP):
return [a_target[0], min(a_target[1], a_x_allowed)]
def should_publish_planner_fcw(crash_cnt: int, car_state, radar_state) -> bool:
return (
crash_cnt > 2 and
not car_state.standstill and
should_trigger_planner_fcw(radar_state.leadOne, float(car_state.vEgo))
)
def get_vehicle_min_accel(CP, v_ego):
# Planner-side physical decel capability estimate for GM pedal-long paths.
if getattr(CP, "carName", "") == "gm" and getattr(CP, "enableGasInterceptorDEPRECATED", False):
@@ -913,11 +979,8 @@ class LongitudinalPlanner:
return False
lead_radar = bool(getattr(lead, "radar", False))
if lead_radar:
return False
lead_prob = float(getattr(lead, "modelProb", 0.0))
if lead_prob < LEAD_DEPART_ACCEL_HOLD_MIN_MODEL_PROB:
lead_prob = float(getattr(lead, "modelProb", 1.0 if lead_radar else 0.0))
if not lead_radar and lead_prob < LEAD_DEPART_ACCEL_HOLD_MIN_MODEL_PROB:
return False
lead_speed = max(float(lead.vLead), 0.0)
@@ -931,6 +994,63 @@ class LongitudinalPlanner:
lead_accel >= LEAD_DEPART_CONFIDENT_MIN_LEAD_ACCEL
)
@staticmethod
def get_centered_model_lead(model_data):
try:
leads = model_data.leadsV3
except Exception:
return None
best_candidate = None
for i in range(3):
try:
lead = leads[i]
prob = float(lead.prob)
x = float(lead.x[0])
y = float(lead.y[0])
v = float(lead.v[0])
except Exception:
continue
if (
prob < RADAR_DEPART_CONFLICT_MIN_MODEL_PROB or
x <= 0.0 or
x > RADAR_DEPART_CONFLICT_MAX_MODEL_DISTANCE or
abs(y) > RADAR_DEPART_CONFLICT_MAX_MODEL_LATERAL or
max(v, 0.0) > RADAR_DEPART_CONFLICT_MAX_MODEL_LEAD_SPEED
):
continue
if best_candidate is None or x < best_candidate[0]:
best_candidate = (x, y, v, prob)
return best_candidate
def has_offcenter_radar_depart_conflict(self, sm):
if float(getattr(sm["carState"], "vEgo", 0.0)) > RADAR_DEPART_CONFLICT_MAX_EGO_SPEED:
return False
centered_model_lead = self.get_centered_model_lead(sm["modelV2"])
if centered_model_lead is None:
return False
centered_model_dist = float(centered_model_lead[0])
for lead in (self.lead_one, self.lead_two):
if not lead.status or not bool(getattr(lead, "radar", False)):
continue
lead_dist = float(getattr(lead, "dRel", 0.0))
if lead_dist <= 0.0 or lead_dist > RADAR_DEPART_CONFLICT_MAX_RADAR_DISTANCE:
continue
if abs(float(getattr(lead, "yRel", 0.0))) < RADAR_DEPART_CONFLICT_MIN_RADAR_LATERAL:
continue
if abs(lead_dist - centered_model_dist) > RADAR_DEPART_CONFLICT_MAX_DISTANCE_MISMATCH:
continue
return True
return False
def get_lead_depart_accel_floor(self, lead, v_ego, model_desired_accel):
if lead is None or not lead.status:
return None
@@ -1045,6 +1165,61 @@ class LongitudinalPlanner:
))
return -cap_decel
def get_cruise_tracking_lead_accel_cap(self, lead, v_ego, t_follow, current_source, tracking_lead_active):
if lead is None or not lead.status or current_source != "cruise":
return None
if not (CRUISE_TRACKED_LEAD_ACCEL_CAP_MIN_SPEED <= float(v_ego) <= CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_SPEED):
return None
lead_prob = float(getattr(lead, "modelProb", 1.0 if bool(getattr(lead, "radar", False)) else 0.0))
if not bool(getattr(lead, "radar", False)) and lead_prob < CRUISE_TRACKED_LEAD_ACCEL_CAP_MIN_MODEL_PROB:
return None
lead_brake = max(0.0, -float(getattr(lead, "aLeadK", 0.0)))
if lead_brake > CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_LEAD_BRAKE:
return None
if abs(float(getattr(lead, "yRel", 0.0))) > CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_LATERAL_OFFSET:
return None
lead_delta = float(lead.vLead) - float(v_ego)
if lead_delta > CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_PULLAWAY_SPEED:
return None
closing_speed = max(float(v_ego) - float(lead.vLead), 0.0)
raw_close_lead = self.raw_close_lead_needs_control(lead, v_ego)
unresolved_slow_lead = (
closing_speed >= CRUISE_TRACKED_LEAD_ACCEL_CAP_UNRESOLVED_MIN_CLOSING_SPEED and
lead_delta <= CRUISE_TRACKED_LEAD_ACCEL_CAP_UNRESOLVED_MAX_LEAD_DELTA
)
if not tracking_lead_active and not raw_close_lead and not unresolved_slow_lead:
return None
desired_gap = float(desired_follow_distance(v_ego, lead.vLead, t_follow))
gap_error = float(lead.dRel) - desired_gap
gap_buffer = max(CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_GAP_BUFFER_MIN,
CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_GAP_BUFFER_GAIN * float(v_ego))
if gap_error > gap_buffer:
return None
base_cap = float(np.interp(
lead_delta,
[-1.5, -0.5, 0.0, 0.5, CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_PULLAWAY_SPEED],
[0.0, 0.04, 0.08, 0.12, 0.16],
))
if raw_close_lead:
base_cap = min(base_cap, float(np.interp(closing_speed, [0.5, 1.5, 3.5], [0.10, 0.05, 0.0])))
else:
base_cap = min(base_cap, float(np.interp(closing_speed, [0.0, 1.0, 2.0], [0.18, 0.12, 0.06])))
if gap_error <= 0.0:
return max(0.0, base_cap)
gap_factor = float(np.clip(gap_error / max(gap_buffer, 0.1), 0.0, 1.0))
cap = min(CRUISE_TRACKED_LEAD_ACCEL_CAP_MAX_ACCEL, base_cap + 0.06 * gap_factor)
return max(0.0, cap)
def lead_is_matched_follow_window(self, lead, v_ego, base_t_follow):
if lead is None or not lead.status or v_ego < STEADY_FOLLOW_SMOOTHING_MIN_SPEED:
return False
@@ -1086,17 +1261,15 @@ class LongitudinalPlanner:
return self.lead_two
return None
def get_follow_control_lead(self, lead_control_active, v_ego, t_follow):
matched_follow_lead = self.get_matched_follow_control_lead(v_ego, t_follow)
if matched_follow_lead is not None:
return matched_follow_lead
def get_follow_control_lead(self, lead_control_active, v_ego, t_follow, *, allow_optional_far_lead_logic=True):
if allow_optional_far_lead_logic:
matched_follow_lead = self.get_matched_follow_control_lead(v_ego, t_follow)
if matched_follow_lead is not None:
return matched_follow_lead
if not lead_control_active:
return None
if self.mpc.source == 'lead1' and self.lead_is_matched_follow_window(self.lead_two, v_ego, t_follow):
return self.lead_two
if self.lead_one.status:
return self.lead_one
if self.lead_two.status:
@@ -1188,6 +1361,150 @@ class LongitudinalPlanner:
))
return -max(0.0, cap_decel - relax_decel)
def get_matched_follow_transition_target(self, lead, v_ego, base_t_follow, prev_output_a_target, output_a_target,
current_source, tracking_lead_active):
if lead is None or not lead.status:
return None
low_speed_extension_active = (
bool(tracking_lead_active) and
current_source == "cruise" and
LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_SPEED <= float(v_ego) < LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_SPEED
)
if float(v_ego) < MATCHED_FOLLOW_TRANSITION_MIN_SPEED and not low_speed_extension_active:
return None
lead_prob = float(getattr(lead, "modelProb", 0.0))
min_model_prob = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_MODEL_PROB if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MIN_MODEL_PROB
if lead_prob < min_model_prob:
return None
lead_brake = max(0.0, -float(getattr(lead, "aLeadK", 0.0)))
max_lead_brake = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_LEAD_BRAKE if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MAX_LEAD_BRAKE
if lead_brake > max_lead_brake:
return None
relative_speed = float(v_ego) - float(lead.vLead)
if not (STEADY_FOLLOW_BRAKE_CAP_MIN_REL_SPEED <= relative_speed <= STEADY_FOLLOW_SMOOTHING_MAX_CLOSING_SPEED):
return None
closing_speed = max(0.0, relative_speed)
max_closing_speed = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_CLOSING_SPEED if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MAX_CLOSING_SPEED
if closing_speed > max_closing_speed:
return None
ttc = float(lead.dRel) / max(closing_speed, 0.1) if closing_speed > 0.1 else float("inf")
min_ttc = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_TTC if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MIN_TTC
if ttc < min_ttc:
return None
actual_headway = float(lead.dRel) / max(float(v_ego), 1e-3)
headway_margin = actual_headway - float(base_t_follow)
min_headway_margin = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_HEADWAY_MARGIN if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MIN_HEADWAY_MARGIN
full_headway_margin = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_FULL_HEADWAY_MARGIN if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_FULL_HEADWAY_MARGIN
if headway_margin < min_headway_margin:
return None
if actual_headway > float(base_t_follow) + STEADY_FOLLOW_BRAKE_CAP_MAX_HEADWAY_ABOVE_TARGET:
return None
target_delta = float(output_a_target) - float(prev_output_a_target)
if low_speed_extension_active:
if float(prev_output_a_target) < LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_TARGET:
return None
if float(output_a_target) < LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_TARGET:
return None
if abs(target_delta) < LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_DELTA_A:
return None
elif abs(target_delta) < 1e-3:
return None
headway_factor = float(np.clip(
(headway_margin - min_headway_margin) /
max(full_headway_margin - min_headway_margin, 1e-3),
0.0,
1.0,
))
min_positive_step = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_POSITIVE_STEP if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MIN_POSITIVE_STEP
max_positive_step = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_POSITIVE_STEP if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MAX_POSITIVE_STEP
positive_step = float(np.interp(
max(float(lead.vLead) - float(v_ego), 0.0),
[0.0, 1.0],
[min_positive_step, max_positive_step],
))
min_negative_step = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MIN_NEGATIVE_STEP if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MIN_NEGATIVE_STEP
max_negative_step = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_MAX_NEGATIVE_STEP if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_MAX_NEGATIVE_STEP
negative_step = float(np.interp(
closing_speed,
[0.0, max_closing_speed],
[min_negative_step, max_negative_step],
))
# The more space we still have, the less abrupt the comfort path should be.
positive_step = float(np.interp(headway_factor, [0.0, 1.0], [positive_step, min_positive_step]))
negative_step = float(np.interp(headway_factor, [0.0, 1.0], [negative_step, min_negative_step]))
if float(prev_output_a_target) * float(output_a_target) < 0.0:
sign_cross_step = LOW_SPEED_MATCHED_FOLLOW_TRANSITION_SIGN_CROSS_STEP if low_speed_extension_active else MATCHED_FOLLOW_TRANSITION_SIGN_CROSS_STEP
positive_step = min(positive_step, sign_cross_step)
negative_step = min(negative_step, sign_cross_step)
lower = float(prev_output_a_target) - negative_step
upper = float(prev_output_a_target) + positive_step
smoothed_target = float(np.clip(output_a_target, lower, upper))
return smoothed_target if abs(smoothed_target - float(output_a_target)) > 1e-6 else None
def get_near_duplicate_lead_transition_target(self, lead, v_ego, base_t_follow,
prev_output_a_target, output_a_target,
current_source, tracking_lead_active):
if lead is None or not lead.status:
return None
if current_source not in ("lead0", "lead1") and not tracking_lead_active:
return None
if not (self.lead_one.status and self.lead_two.status):
return None
if not self.mpc.leads_are_near_duplicates(self.lead_one, self.lead_two, v_ego):
return None
if float(v_ego) < NEAR_DUPLICATE_LEAD_TRANSITION_MIN_SPEED:
return None
lead_prob = float(getattr(lead, "modelProb", 0.0))
if bool(getattr(lead, "radar", False)) or lead_prob < NEAR_DUPLICATE_LEAD_TRANSITION_MIN_MODEL_PROB:
return None
lead_brake = max(0.0, -float(getattr(lead, "aLeadK", 0.0)))
if lead_brake > NEAR_DUPLICATE_LEAD_TRANSITION_MAX_LEAD_BRAKE:
return None
relative_speed = float(v_ego) - float(lead.vLead)
closing_speed = max(0.0, relative_speed)
if closing_speed > NEAR_DUPLICATE_LEAD_TRANSITION_MAX_CLOSING_SPEED:
return None
ttc = float(lead.dRel) / max(closing_speed, 0.1) if closing_speed > 0.1 else float("inf")
if ttc < NEAR_DUPLICATE_LEAD_TRANSITION_MIN_TTC:
return None
actual_headway = float(lead.dRel) / max(float(v_ego), 1e-3)
if actual_headway < max(0.0, float(base_t_follow) - NEAR_DUPLICATE_LEAD_TRANSITION_MIN_HEADWAY_BELOW_TARGET):
return None
if actual_headway > float(base_t_follow) + NEAR_DUPLICATE_LEAD_TRANSITION_MAX_HEADWAY_ABOVE_TARGET:
return None
target_delta = float(output_a_target) - float(prev_output_a_target)
if abs(target_delta) < NEAR_DUPLICATE_LEAD_TRANSITION_MIN_DELTA_A:
return None
positive_step = NEAR_DUPLICATE_LEAD_TRANSITION_POSITIVE_STEP
negative_step = NEAR_DUPLICATE_LEAD_TRANSITION_NEGATIVE_STEP
if float(prev_output_a_target) * float(output_a_target) < 0.0:
positive_step = min(positive_step, NEAR_DUPLICATE_LEAD_TRANSITION_SIGN_CROSS_STEP)
negative_step = min(negative_step, NEAR_DUPLICATE_LEAD_TRANSITION_SIGN_CROSS_STEP)
lower = float(prev_output_a_target) - negative_step
upper = float(prev_output_a_target) + positive_step
smoothed_target = float(np.clip(output_a_target, lower, upper))
return smoothed_target if abs(smoothed_target - float(output_a_target)) > 1e-6 else None
def get_tracked_vision_model_brake_floor(self, lead, v_ego, accel_min, t_follow, model_desired):
if lead is None or not lead.status or bool(getattr(lead, "radar", False)):
return None
@@ -1560,9 +1877,11 @@ class LongitudinalPlanner:
dec_mpc_mode = self.get_mpc_mode()
if not self.mlsim:
self.mpc.mode = dec_mpc_mode
optional_far_lead_comfort = getattr(starpilot_toggles, "coast_up_to_leads", True)
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j,
sm['starpilotPlan'].dangerFactor, effective_t_follow,
personality=personality, tracking_lead=lead_control_active)
personality=personality, tracking_lead=lead_control_active,
optional_far_lead_comfort=optional_far_lead_comfort)
self.a_desired_trajectory_full = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.a_solution)
self.v_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.v_solution)
@@ -1570,7 +1889,7 @@ class LongitudinalPlanner:
self.j_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC[:-1], self.mpc.j_solution)
# TODO counter is only needed because radar is glitchy, remove once radar is gone
self.fcw = self.mpc.crash_cnt > 2 and not sm['carState'].standstill
self.fcw = should_publish_planner_fcw(self.mpc.crash_cnt, sm['carState'], sm['radarState'])
if self.fcw:
cloudlog.info("FCW triggered")
@@ -1715,7 +2034,8 @@ class LongitudinalPlanner:
standstill_nudge_gap = max(float(getattr(starpilot_toggles, "stop_distance", STOP_DISTANCE)), STOP_DISTANCE) - 0.5
moving_leads = [lead for lead in (self.lead_one, self.lead_two)
if lead.status and lead.vLead > STANDSTILL_LEAD_NUDGE_MIN_SPEED and lead.dRel >= standstill_nudge_gap]
if lead.status and
lead.vLead > STANDSTILL_LEAD_NUDGE_MIN_SPEED and lead.dRel >= standstill_nudge_gap]
confident_depart_ready = any(self.is_confident_lead_depart(lead, float(sm['carState'].vEgo))
for lead in (self.lead_one, self.lead_two))
lead_depart_ready = any(
@@ -1724,14 +2044,17 @@ class LongitudinalPlanner:
lead.dRel >= standstill_nudge_gap + STANDSTILL_LEAD_DEPART_MIN_GAP_MARGIN
for lead in (self.lead_one, self.lead_two)
)
depart_safety_veto = (not bool(getattr(starpilot_toggles, "radar_takeoffs", False))
and self.has_offcenter_radar_depart_conflict(sm))
if lead_control_active and sm['carState'].standstill and moving_leads:
if lead_control_active and sm['carState'].standstill and moving_leads and not depart_safety_veto:
output_a_target = max(output_a_target, STANDSTILL_LEAD_NUDGE_ACCEL)
if (
lead_control_active and
sm['carState'].standstill and
(confident_depart_ready or lead_depart_ready) and
not depart_safety_veto and
not bool(getattr(sm['starpilotPlan'], 'forcingStop', False)) and
not bool(getattr(sm['starpilotPlan'], 'redLight', False)) and
(confident_depart_ready or model_desired_accel >= STANDSTILL_LEAD_DEPART_MIN_MODEL_ACCEL)
@@ -1740,14 +2063,14 @@ class LongitudinalPlanner:
output_should_stop = False
output_a_target = max(output_a_target, STANDSTILL_LEAD_DEPART_MIN_ACCEL)
if lead_control_active and lead_depart_ready and not output_should_stop and float(sm['carState'].vEgo) <= STANDSTILL_LEAD_DEPART_MAX_EGO_SPEED:
if lead_control_active and lead_depart_ready and not depart_safety_veto and not output_should_stop and float(sm['carState'].vEgo) <= STANDSTILL_LEAD_DEPART_MAX_EGO_SPEED:
output_a_target = max(output_a_target, STANDSTILL_LEAD_DEPART_MIN_ACCEL)
if output_should_stop or bool(getattr(sm['starpilotPlan'], 'forcingStop', False)) or bool(getattr(sm['starpilotPlan'], 'redLight', False)):
if depart_safety_veto or output_should_stop or bool(getattr(sm['starpilotPlan'], 'forcingStop', False)) or bool(getattr(sm['starpilotPlan'], 'redLight', False)):
self.lead_depart_accel_hold_until = 0.0
lead_depart_accel_floor = None
if lead_control_active and not output_should_stop:
if lead_control_active and not output_should_stop and not depart_safety_veto:
lead_depart_accel_floors = [
floor for floor in (
self.get_lead_depart_accel_floor(self.lead_one, scene_v_ego, model_desired_accel),
@@ -1831,7 +2154,12 @@ class LongitudinalPlanner:
if vision_brake_cap_active:
output_accel_min = min(output_accel_min, vision_cap_accel_min)
follow_control_lead = self.get_follow_control_lead(lead_control_active, scene_v_ego, effective_t_follow)
follow_control_lead = self.get_follow_control_lead(
lead_control_active,
scene_v_ego,
effective_t_follow,
allow_optional_far_lead_logic=optional_far_lead_comfort,
)
if follow_control_lead is not None and not panic_bypass:
if not output_should_stop and not vision_low_speed_stop_active:
tracked_vision_model_brake_floor = self.get_tracked_vision_model_brake_floor(
@@ -1845,10 +2173,11 @@ class LongitudinalPlanner:
self.a_desired = min(self.a_desired, tracked_vision_model_brake_floor)
output_a_target = min(output_a_target, tracked_vision_model_brake_floor)
matched_follow_brake_cap = self.get_matched_follow_brake_cap(follow_control_lead, scene_v_ego, effective_t_follow)
if matched_follow_brake_cap is not None:
self.a_desired = max(self.a_desired, matched_follow_brake_cap)
output_a_target = max(output_a_target, matched_follow_brake_cap)
if optional_far_lead_comfort:
matched_follow_brake_cap = self.get_matched_follow_brake_cap(follow_control_lead, scene_v_ego, effective_t_follow)
if matched_follow_brake_cap is not None:
self.a_desired = max(self.a_desired, matched_follow_brake_cap)
output_a_target = max(output_a_target, matched_follow_brake_cap)
if not close_lead_caps and not output_should_stop and not vision_low_speed_stop_active:
low_speed_transition_brake_cap = self.get_low_speed_follow_transition_brake_cap(
@@ -1863,7 +2192,7 @@ class LongitudinalPlanner:
output_a_target = max(output_a_target, low_speed_transition_brake_cap)
comfort_lead = self.lead_two if self.mpc.source == 'lead1' and self.lead_two.status else self.lead_one
if comfort_lead is not None and not panic_bypass:
if optional_far_lead_comfort and comfort_lead is not None and not panic_bypass:
far_lead_brake_cap = self.get_far_lead_brake_cap(comfort_lead, scene_v_ego, effective_t_follow)
if far_lead_brake_cap is not None:
self.a_desired = max(self.a_desired, far_lead_brake_cap)
@@ -1880,6 +2209,52 @@ class LongitudinalPlanner:
self.a_desired = max(self.a_desired, tracked_vision_model_brake_cap)
output_a_target = max(output_a_target, tracked_vision_model_brake_cap)
if optional_far_lead_comfort and follow_control_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
matched_follow_transition_target = self.get_matched_follow_transition_target(
follow_control_lead,
scene_v_ego,
effective_t_follow,
prev_output_a_target,
output_a_target,
self.mpc.source,
bool(getattr(sm["starpilotPlan"], "trackingLead", False)),
)
if matched_follow_transition_target is not None:
if matched_follow_transition_target < output_a_target:
self.a_desired = min(self.a_desired, matched_follow_transition_target)
else:
self.a_desired = max(self.a_desired, matched_follow_transition_target)
output_a_target = matched_follow_transition_target
if optional_far_lead_comfort and comfort_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
near_duplicate_transition_target = self.get_near_duplicate_lead_transition_target(
comfort_lead,
scene_v_ego,
effective_t_follow,
prev_output_a_target,
output_a_target,
self.mpc.source,
bool(getattr(sm["starpilotPlan"], "trackingLead", False)),
)
if near_duplicate_transition_target is not None:
if near_duplicate_transition_target < output_a_target:
self.a_desired = min(self.a_desired, near_duplicate_transition_target)
else:
self.a_desired = max(self.a_desired, near_duplicate_transition_target)
output_a_target = near_duplicate_transition_target
if follow_control_lead is not None and not panic_bypass and not output_should_stop and not vision_low_speed_stop_active:
cruise_tracking_lead_accel_cap = self.get_cruise_tracking_lead_accel_cap(
follow_control_lead,
scene_v_ego,
effective_t_follow,
self.mpc.source,
tracking_lead,
)
if cruise_tracking_lead_accel_cap is not None:
self.a_desired = min(self.a_desired, cruise_tracking_lead_accel_cap)
output_a_target = min(output_a_target, cruise_tracking_lead_accel_cap)
output_accel_max = no_throttle_output_max if not self.allow_throttle else accel_limits_turns[1]
output_a_target = float(np.clip(output_a_target, output_accel_min, output_accel_max))
@@ -1899,6 +2274,12 @@ class LongitudinalPlanner:
self.a_desired = min(self.a_desired, close_release_hold_cap)
output_a_target = min(output_a_target, close_release_hold_cap)
if depart_safety_veto:
self.a_desired = min(self.a_desired, 0.0)
output_a_target = min(output_a_target, 0.0)
if sm['carState'].standstill:
output_should_stop = True
if lead_depart_accel_hold_active:
output_a_target = max(output_a_target, lead_depart_accel_floor)
+34 -8
View File
@@ -27,6 +27,8 @@ V_EGO_STATIONARY = 4. # no stationary object flag below this speed
RADAR_TO_CENTER = 2.7 # (deprecated) RADAR is ~ 2.7m ahead from center of car
RADAR_TO_CAMERA = 1.52 # RADAR is ~ 1.5m ahead from center of mesh frame
G90_RADAR_LOW_SPEED_MAX_DIST = 12.0
G90_RADAR_LOW_SPEED_MAX_Y = 0.6
class KalmanParams:
@@ -127,7 +129,21 @@ def laplacian_pdf(x: float, mu: float, b: float):
return math.exp(-abs(x-mu)/b)
def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_data: capnp._DynamicStructReader, tracks: dict[int, Track], starpilot_toggles: SimpleNamespace):
def g90_radar_lead_lateral_sane(track: Track) -> bool:
# The G90 extended radar channels can report close side ghosts in tight turns.
# Keep the gate tight at close range, then widen gradually with distance.
max_y = min(6.0, 1.5 + 0.08 * max(track.dRel, 0.0))
return abs(track.yRel) <= max_y
def g90_low_speed_radar_lead_sane(track: Track, v_ego: float) -> bool:
return (track.cnt >= 3 and v_ego < 3.0 and
0.75 < track.dRel < G90_RADAR_LOW_SPEED_MAX_DIST and
abs(track.yRel) < G90_RADAR_LOW_SPEED_MAX_Y)
def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_data: capnp._DynamicStructReader, tracks: dict[int, Track],
starpilot_toggles: SimpleNamespace, g90_radar_filter: bool = False):
if model_data.meta.laneChangeState == LaneChangeState.laneChangeStarting and getattr(starpilot_toggles, "human_lane_changes", False):
direction = model_data.meta.laneChangeDirection
if direction == LaneChangeDirection.left:
@@ -135,6 +151,9 @@ def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_
elif direction == LaneChangeDirection.right:
tracks = {k: v for k, v in tracks.items() if v.yRel < 0}
if g90_radar_filter:
tracks = {k: v for k, v in tracks.items() if g90_radar_lead_lateral_sane(v)}
if not tracks:
return None
@@ -180,12 +199,12 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa
def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capnp._DynamicStructReader,
model_v_ego: float, model_data: capnp._DynamicStructReader, standstill: bool,
starpilot_plan: capnp._DynamicStructReader, starpilot_toggles: SimpleNamespace,
low_speed_override: bool = True) -> dict[str, Any]:
low_speed_override: bool = True, g90_radar_filter: bool = False) -> dict[str, Any]:
lead_detection_probability = float(getattr(starpilot_toggles, "lead_detection_probability", 0.35))
# Determine leads, this is where the essential logic happens
if len(tracks) > 0 and ready and lead_msg.prob > lead_detection_probability:
track = match_vision_to_track(v_ego, lead_msg, model_data, tracks, starpilot_toggles)
track = match_vision_to_track(v_ego, lead_msg, model_data, tracks, starpilot_toggles, g90_radar_filter)
else:
track = None
@@ -196,7 +215,10 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn
lead_dict = get_RadarState_from_vision(lead_msg, v_ego, model_v_ego)
if low_speed_override:
low_speed_tracks = [c for c in tracks.values() if c.potential_low_speed_lead(v_ego)]
if g90_radar_filter:
low_speed_tracks = [c for c in tracks.values() if g90_low_speed_radar_lead_sane(c, v_ego)]
else:
low_speed_tracks = [c for c in tracks.values() if c.potential_low_speed_lead(v_ego)]
if len(low_speed_tracks) > 0:
closest_track = min(low_speed_tracks, key=lambda c: c.dRel)
@@ -225,11 +247,12 @@ def get_adjacent_lead(tracks: dict[int, Track], standstill: bool, model_data: ca
class RadarD:
def __init__(self, radar_ts: float = DT_MDL, delay: float = 0.0):
def __init__(self, radar_ts: float = DT_MDL, delay: float = 0.0, g90_radar_filter: bool = False):
self.current_time = 0.0
self.tracks: dict[int, Track] = {}
self.kalman_params = KalmanParams(radar_ts)
self.g90_radar_filter = g90_radar_filter
self.v_ego = 0.0
self.v_ego_hist = deque([0.0], maxlen=int(round(delay / DT_MDL)) + 1)
@@ -286,9 +309,11 @@ class RadarD:
leads_v3 = sm['modelV2'].leadsV3
if len(leads_v3) > 1:
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)
sm['carState'].standstill, sm['starpilotPlan'], self.starpilot_toggles, low_speed_override=True,
g90_radar_filter=self.g90_radar_filter)
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)
sm['carState'].standstill, sm['starpilotPlan'], self.starpilot_toggles, low_speed_override=False,
g90_radar_filter=self.g90_radar_filter)
if self.ready and (self.starpilot_toggles.adjacent_lead_tracking or self.starpilot_toggles.human_lane_changes):
self.starpilot_radar_state.leadLeft = get_adjacent_lead(self.tracks, sm['carState'].standstill, sm['modelV2'], left=True)
@@ -328,7 +353,8 @@ def main() -> None:
if not 0.01 < radar_ts < 0.2:
radar_ts = DT_MDL
RD = RadarD(radar_ts=radar_ts, delay=CP.radarDelay)
g90_radar_filter = CP.brand == "hyundai" and CP.carFingerprint == "GENESIS_G90"
RD = RadarD(radar_ts=radar_ts, delay=CP.radarDelay, g90_radar_filter=g90_radar_filter)
sm = sm.extend(['starpilotPlan'])
pm = pm.extend(['starpilotRadarState'])
+136 -7
View File
@@ -40,6 +40,12 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import (
get_genesis_g90_friction_scale,
get_genesis_g90_friction_threshold,
get_elantra_non_scc_ff_scale,
get_palisade_ff_scale,
get_palisade_friction_scale,
get_palisade_friction_threshold,
get_prius_ff_scale,
get_prius_friction_scale,
get_prius_friction_threshold,
get_ioniq_5_ff_scale,
get_ioniq_5_friction_scale,
get_ioniq_5_friction_threshold,
@@ -58,6 +64,8 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import (
get_kia_ev6_ff_scale,
get_kia_ev6_friction_scale,
get_kia_ev6_friction_threshold,
get_sonata_center_taper_scale,
get_sonata_ff_scale,
get_sonata_hybrid_center_taper_scale,
get_sonata_hybrid_ff_scale,
get_volt_standard_center_taper_scale,
@@ -240,6 +248,26 @@ class TestLatControl:
assert get_sonata_hybrid_center_taper_scale(0.0, 3.0) < get_sonata_hybrid_center_taper_scale(0.0, 10.0)
assert get_sonata_hybrid_center_taper_scale(0.0, 30.0) < get_sonata_hybrid_center_taper_scale(0.20, 30.0) <= 1.0
def test_sonata_ff_scale_curve(self):
assert get_sonata_ff_scale(0.0, 0.0, 20.0) == 1.0
steady_left = get_sonata_ff_scale(0.45, 0.0, 8.0)
steady_right = get_sonata_ff_scale(-0.45, 0.0, 8.0)
turn_in_left = get_sonata_ff_scale(0.45, 0.8, 8.0)
turn_in_right = get_sonata_ff_scale(-0.45, -0.8, 8.0)
unwind_left = get_sonata_ff_scale(0.45, -0.8, 8.0)
unwind_right = get_sonata_ff_scale(-0.45, 0.8, 8.0)
assert steady_left < 1.0
assert steady_right < steady_left
assert turn_in_left > steady_left
assert turn_in_right == pytest.approx(steady_right)
assert unwind_left < steady_left
assert unwind_right == pytest.approx(steady_right)
def test_sonata_center_taper_curve(self):
assert get_sonata_center_taper_scale(0.0, 30.0) < get_sonata_center_taper_scale(0.0, 15.0)
assert get_sonata_center_taper_scale(0.0, 3.0) < get_sonata_center_taper_scale(0.0, 10.0)
assert get_sonata_center_taper_scale(0.0, 30.0) < get_sonata_center_taper_scale(0.20, 30.0) <= 1.0
def test_elantra_non_scc_ff_scale_curve(self):
assert get_elantra_non_scc_ff_scale(0.0, 0.0, 20.0) == 1.0
steady_left = get_elantra_non_scc_ff_scale(0.45, 0.0, 8.0)
@@ -268,10 +296,13 @@ class TestLatControl:
assert steady_left < 1.0
assert steady_right < steady_left
assert turn_in_left > steady_left
assert turn_in_right == pytest.approx(steady_right)
assert turn_in_right > steady_right
assert unwind_left < steady_left
assert unwind_right < steady_right
assert unwind_right > unwind_left
assert get_kia_forte_ff_scale(0.30, 0.60, 3.0) > get_kia_forte_ff_scale(0.30, 0.60, 6.0)
assert get_kia_forte_ff_scale(0.30, 0.60, 6.0) > get_kia_forte_ff_scale(0.30, 0.60, 12.0)
assert get_kia_forte_ff_scale(0.30, -0.60, 3.0) < get_kia_forte_ff_scale(0.30, 0.60, 3.0)
def test_kia_forte_center_taper_curve(self):
assert get_kia_forte_center_taper_scale(0.0, 30.0) < get_kia_forte_center_taper_scale(0.0, 15.0)
@@ -305,6 +336,74 @@ class TestLatControl:
assert left_turn_in > right_turn_in > base
assert base > left_unwind > right_unwind
def test_palisade_ff_scale_curve(self):
assert get_palisade_ff_scale(0.0, 0.0, 20.0) == 1.0
steady_left = get_palisade_ff_scale(0.6, 0.0, 8.0)
steady_right = get_palisade_ff_scale(-0.6, 0.0, 8.0)
turn_in_left = get_palisade_ff_scale(0.6, 0.8, 8.0)
turn_in_right = get_palisade_ff_scale(-0.6, -0.8, 8.0)
unwind_left = get_palisade_ff_scale(0.6, -0.8, 8.0)
unwind_right = get_palisade_ff_scale(-0.6, 0.8, 8.0)
assert steady_left > 1.0
assert steady_right > 1.0
assert turn_in_left > steady_left
assert turn_in_right > steady_right
assert unwind_left < steady_left
assert unwind_right < steady_right
assert unwind_right < unwind_left
def test_palisade_friction_threshold_curve(self):
base = get_friction_threshold(6.0)
left_turn_in = get_palisade_friction_threshold(6.0, 0.7, 0.8)
right_turn_in = get_palisade_friction_threshold(6.0, -0.7, -0.8)
left_unwind = get_palisade_friction_threshold(6.0, 0.7, -0.8)
right_unwind = get_palisade_friction_threshold(6.0, -0.7, 0.8)
assert left_turn_in < right_turn_in < base < left_unwind < right_unwind
def test_palisade_friction_scale_curve(self):
base = get_palisade_friction_scale(25.0, 0.7, 0.8)
left_turn_in = get_palisade_friction_scale(6.0, 0.7, 0.8)
right_turn_in = get_palisade_friction_scale(6.0, -0.7, -0.8)
left_unwind = get_palisade_friction_scale(6.0, 0.7, -0.8)
right_unwind = get_palisade_friction_scale(6.0, -0.7, 0.8)
assert left_turn_in > right_turn_in > base
assert base > left_unwind > right_unwind
def test_prius_ff_scale_curve(self):
assert get_prius_ff_scale(0.0, 0.0, 20.0) == 1.0
steady_left = get_prius_ff_scale(0.7, 0.0, 8.0)
steady_right = get_prius_ff_scale(-0.7, 0.0, 8.0)
turn_in_left = get_prius_ff_scale(0.7, 0.8, 8.0)
turn_in_right = get_prius_ff_scale(-0.7, -0.8, 8.0)
unwind_left = get_prius_ff_scale(0.7, -0.8, 8.0)
unwind_right = get_prius_ff_scale(-0.7, 0.8, 8.0)
assert steady_left > 1.0
assert steady_right > steady_left
assert turn_in_left > steady_left
assert turn_in_right > steady_right
assert unwind_left < steady_left
assert unwind_right < steady_right
assert unwind_right < unwind_left
def test_prius_friction_curves(self):
base_threshold = get_friction_threshold(12.0)
left_turn_in_threshold = get_prius_friction_threshold(6.0, 0.7, 0.8)
right_turn_in_threshold = get_prius_friction_threshold(6.0, -0.7, -0.8)
left_unwind_threshold = get_prius_friction_threshold(6.0, 0.7, -0.8)
right_unwind_threshold = get_prius_friction_threshold(6.0, -0.7, 0.8)
assert left_turn_in_threshold < base_threshold
assert right_turn_in_threshold < left_turn_in_threshold
assert left_unwind_threshold > base_threshold
assert right_unwind_threshold >= left_unwind_threshold
base_scale = get_prius_friction_scale(25.0, 0.7, 0.8)
left_turn_in_scale = get_prius_friction_scale(6.0, 0.7, 0.8)
right_turn_in_scale = get_prius_friction_scale(6.0, -0.7, -0.8)
left_unwind_scale = get_prius_friction_scale(6.0, 0.7, -0.8)
right_unwind_scale = get_prius_friction_scale(6.0, -0.7, 0.8)
assert right_turn_in_scale > left_turn_in_scale > base_scale
assert base_scale > left_unwind_scale > right_unwind_scale
def test_ioniq_5_ff_scale_curve(self):
assert get_ioniq_5_ff_scale(0.0, 0.0, 20.0) == 1.0
steady_left = get_ioniq_5_ff_scale(0.7, 0.0, 12.0)
@@ -316,7 +415,7 @@ class TestLatControl:
assert steady_left < 1.0
assert steady_right < steady_left
assert turn_in_left > steady_left
assert turn_in_right >= steady_right
assert turn_in_right > steady_right
assert unwind_left < steady_left
assert unwind_right < unwind_left
@@ -327,7 +426,7 @@ class TestLatControl:
unwind_left_threshold = get_ioniq_5_friction_threshold(12.0, 0.7, -0.8)
unwind_right_threshold = get_ioniq_5_friction_threshold(12.0, -0.7, 0.8)
assert turn_in_left_threshold < base
assert turn_in_right_threshold == pytest.approx(base)
assert turn_in_left_threshold < turn_in_right_threshold < base
assert unwind_left_threshold > base
assert unwind_right_threshold > unwind_left_threshold
@@ -335,10 +434,9 @@ class TestLatControl:
turn_in_right_scale = get_ioniq_5_friction_scale(12.0, -0.7, -0.8)
unwind_left_scale = get_ioniq_5_friction_scale(12.0, 0.7, -0.8)
unwind_right_scale = get_ioniq_5_friction_scale(12.0, -0.7, 0.8)
assert turn_in_left_scale > 1.0
assert turn_in_right_scale == pytest.approx(1.0)
assert turn_in_left_scale > turn_in_right_scale > 1.0
assert unwind_left_scale < 1.0
assert unwind_right_scale < unwind_left_scale
assert unwind_right_scale <= unwind_left_scale
def test_ioniq_5_center_taper_curve(self):
assert get_ioniq_5_center_taper_scale(0.0, 25.0) < get_ioniq_5_center_taper_scale(0.0, 10.0)
@@ -362,6 +460,9 @@ class TestLatControl:
assert get_ioniq_6_ff_scale(-0.4, -0.7, 8.0) >= get_ioniq_6_ff_scale(-0.4, 0.0, 8.0) >= get_ioniq_6_ff_scale(-0.4, 0.7, 8.0)
assert get_ioniq_6_ff_scale(-1.2, 0.0, 20.0) < get_ioniq_6_ff_scale(1.2, 0.0, 20.0) < 1.0
assert get_ioniq_6_ff_scale(-1.2, 0.7, 20.0) <= get_ioniq_6_ff_scale(-1.2, 0.0, 20.0)
assert get_ioniq_6_ff_scale(0.30, 0.60, 3.0) > get_ioniq_6_ff_scale(0.30, 0.60, 6.0)
assert get_ioniq_6_ff_scale(0.30, 0.60, 6.0) > get_ioniq_6_ff_scale(0.30, 0.60, 12.0)
assert get_ioniq_6_ff_scale(0.30, -0.60, 3.0) < get_ioniq_6_ff_scale(0.30, 0.60, 3.0)
def test_ioniq_6_directional_taper_curve(self):
assert get_ioniq_6_directional_taper_scale(0.0, 0.0) == 1.0
@@ -376,6 +477,14 @@ class TestLatControl:
assert get_ioniq_6_directional_taper_scale(-1.2, -0.40, 8.0) > get_ioniq_6_directional_taper_scale(-1.2, -0.40, 25.0)
assert get_ioniq_6_directional_taper_scale(1.2, 0.40, 8.0) > get_ioniq_6_directional_taper_scale(1.2, 0.40, 25.0)
assert get_ioniq_6_directional_taper_scale(-1.2, 0.7, 8.0) == pytest.approx(get_ioniq_6_directional_taper_scale(-1.2, 0.7, 25.0), abs=0.02)
assert get_ioniq_6_directional_taper_scale(-0.18, -0.40, 3.0) > get_ioniq_6_directional_taper_scale(-0.18, -0.40, 9.0)
assert get_ioniq_6_directional_taper_scale(-0.18, -0.40, 9.0) > get_ioniq_6_directional_taper_scale(-0.18, -0.40, 20.0)
assert get_ioniq_6_directional_taper_scale(-0.50, -0.40, 3.0) > get_ioniq_6_directional_taper_scale(-0.50, -0.40, 6.0)
assert get_ioniq_6_directional_taper_scale(-0.50, -0.40, 6.0) > get_ioniq_6_directional_taper_scale(-0.50, -0.40, 9.0)
assert get_ioniq_6_directional_taper_scale(-0.50, -0.40, 9.0) > get_ioniq_6_directional_taper_scale(-0.50, -0.40, 20.0)
assert get_ioniq_6_directional_taper_scale(-0.70, -0.70, 6.0) > get_ioniq_6_directional_taper_scale(-0.70, -0.70, 12.0)
assert get_ioniq_6_directional_taper_scale(-0.70, -0.70, 12.0) > get_ioniq_6_directional_taper_scale(-0.70, -0.70, 20.0)
assert get_ioniq_6_directional_taper_scale(0.30, 0.60, 5.0) > get_ioniq_6_directional_taper_scale(0.30, 0.60, 12.0)
def test_ioniq_6_output_taper_curve(self):
assert get_ioniq_6_output_taper_scale(0.0, 0.0, 25.0) < get_ioniq_6_output_taper_scale(0.0, 0.0, 8.0) <= 1.0
@@ -426,7 +535,7 @@ class TestLatControl:
right_turn_in = get_kia_ev6_friction_threshold(6.0, -0.5, -0.8)
left_unwind = get_kia_ev6_friction_threshold(6.0, 0.5, -0.8)
right_unwind = get_kia_ev6_friction_threshold(6.0, -0.5, 0.8)
assert right_turn_in < left_turn_in < base < right_unwind < left_unwind
assert right_turn_in < left_turn_in < base < right_unwind <= left_unwind
def test_kia_ev6_friction_scale_curve(self):
base = get_kia_ev6_friction_scale(25.0, 0.5, 0.8)
@@ -491,6 +600,26 @@ class TestLatControl:
assert lac_log.active
def test_palisade_default_update_path(self):
controller, VM, CS, params, starpilot_toggles = self._build_torque_controller(HYUNDAI.HYUNDAI_PALISADE_2023)
CarInterface = interfaces[HYUNDAI.HYUNDAI_PALISADE_2023]
CP = CarInterface.get_non_essential_params(HYUNDAI.HYUNDAI_PALISADE_2023)
_, _, lac_log = controller.update(True, CS, VM, params, False, 0.0025, False, 0.2, None, None, starpilot_toggles)
assert lac_log.active
assert controller.torque_params.latAccelFactor == pytest.approx(CP.lateralTuning.torque.latAccelFactor * 0.98)
def test_sonata_default_update_path(self):
controller, VM, CS, params, starpilot_toggles = self._build_torque_controller(HYUNDAI.HYUNDAI_SONATA)
CarInterface = interfaces[HYUNDAI.HYUNDAI_SONATA]
CP = CarInterface.get_non_essential_params(HYUNDAI.HYUNDAI_SONATA)
_, _, lac_log = controller.update(True, CS, VM, params, False, 0.0025, False, 0.2, None, None, starpilot_toggles)
assert lac_log.active
assert controller.torque_params.latAccelFactor == pytest.approx(CP.lateralTuning.torque.latAccelFactor)
def test_ioniq_5_default_update_path(self):
controller, VM, CS, params, starpilot_toggles = self._build_torque_controller(HYUNDAI.HYUNDAI_IONIQ_5)
CarInterface = interfaces[HYUNDAI.HYUNDAI_IONIQ_5]
+17
View File
@@ -1,10 +1,27 @@
from types import SimpleNamespace
import cereal.messaging as messaging
from opendbc.car.toyota.values import CAR as TOYOTA
from openpilot.selfdrive.test.process_replay import replay_process_with_name
from openpilot.selfdrive.controls.radard import g90_low_speed_radar_lead_sane, g90_radar_lead_lateral_sane
class TestLeads:
def test_g90_radar_filters_side_tracks(self):
side_track = SimpleNamespace(dRel=13.0, yRel=-10.38, cnt=10)
centered_track = SimpleNamespace(dRel=10.8, yRel=-0.21, cnt=5)
close_side_ghost = SimpleNamespace(dRel=2.2, yRel=2.41, cnt=10)
close_centered_track = SimpleNamespace(dRel=2.2, yRel=1.2, cnt=10)
far_low_speed_track = SimpleNamespace(dRel=15.5, yRel=0.58, cnt=5)
assert not g90_radar_lead_lateral_sane(side_track)
assert g90_radar_lead_lateral_sane(centered_track)
assert not g90_radar_lead_lateral_sane(close_side_ghost)
assert g90_radar_lead_lateral_sane(close_centered_track)
assert g90_low_speed_radar_lead_sane(centered_track, 2.0)
assert not g90_low_speed_radar_lead_sane(far_low_speed_track, 3.5)
def test_radar_fault(self):
# if there's no radar-related can traffic, radard should either not respond or respond with an error
# this is tightly coupled with underlying car radar_interface implementation, but it's a good sanity check
@@ -11,13 +11,13 @@ from opendbc.car.honda.values import CAR
import openpilot.selfdrive.controls.lib.longitudinal_planner as longitudinal_planner_module
from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState
from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N
from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner, get_coast_accel, get_vehicle_min_accel
from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner, get_coast_accel, get_vehicle_min_accel, should_publish_planner_fcw
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import soften_far_radar_lead_accel, should_trigger_planner_fcw
from openpilot.selfdrive.modeld.constants import ModelConstants, Plan
def make_lead(*, status: bool, d_rel: float = 200.0, v_lead: float = 0.0, a_lead: float = 0.0,
radar: bool = False, model_prob: float = 0.0):
radar: bool = False, model_prob: float = 0.0, y_rel: float = 0.0):
lead = log.RadarState.LeadData.new_message()
lead.status = status
lead.dRel = d_rel
@@ -26,6 +26,7 @@ def make_lead(*, status: bool, d_rel: float = 200.0, v_lead: float = 0.0, a_lead
lead.aLeadK = a_lead
lead.vRel = 0.0
lead.aRel = 0.0
lead.yRel = y_rel
lead.modelProb = model_prob
lead.radar = radar
return lead
@@ -33,6 +34,7 @@ def make_lead(*, status: bool, d_rel: float = 200.0, v_lead: float = 0.0, a_lead
def make_model(v_ego: float, desired_accel: float, gas_press_prob: float = 1.0, brake_press_prob: float = 0.0):
model = log.ModelDataV2.new_message()
model.init('leadsV3', 3)
t_idxs = ModelConstants.T_IDXS
model.position.x = [float(v_ego * t) for t in t_idxs]
@@ -57,6 +59,15 @@ def make_model(v_ego: float, desired_accel: float, gas_press_prob: float = 1.0,
return model
def set_model_lead(model, idx: int, *, prob: float, x0: float, y0: float, v0: float, a0: float = 0.0):
lead = model.leadsV3[idx]
lead.prob = float(prob)
lead.x = [float(x0)]
lead.y = [float(y0)]
lead.v = [float(v0)]
lead.a = [float(a0)]
def make_sm(v_ego: float, desired_accel: float, min_accel: float, *, experimental_mode: bool = True,
tracking_lead: bool = False, lead_one=None, lead_two=None,
gas_press_prob: float = 1.0, brake_press_prob: float = 0.0, disable_throttle: bool = False):
@@ -100,7 +111,7 @@ def make_sm(v_ego: float, desired_accel: float, min_accel: float, *, experimenta
}
def make_toggles(model_version: str = "v11"):
def make_toggles(model_version: str = "v11", radar_takeoffs: bool = False):
return SimpleNamespace(
taco_tune=False,
classic_model=False,
@@ -108,6 +119,7 @@ def make_toggles(model_version: str = "v11"):
model_version=model_version,
stop_distance=6.0,
vEgoStopping=0.5,
radar_takeoffs=radar_takeoffs,
)
@@ -225,6 +237,22 @@ def test_planner_fcw_keeps_real_low_speed_closing_alerts():
)
def test_publish_planner_fcw_suppresses_crawl_speed_false_positive():
car_state = SimpleNamespace(vEgo=0.29, standstill=False)
radar_state = SimpleNamespace(
leadOne=make_lead(status=True, d_rel=7.55, v_lead=0.033, a_lead=0.0, radar=False, model_prob=0.99),
)
assert not should_publish_planner_fcw(3, car_state, radar_state)
def test_publish_planner_fcw_keeps_real_current_close_closing_alert():
car_state = SimpleNamespace(vEgo=1.6, standstill=False)
radar_state = SimpleNamespace(
leadOne=make_lead(status=True, d_rel=1.8, v_lead=0.0, a_lead=0.0, radar=False, model_prob=0.99),
)
assert should_publish_planner_fcw(3, car_state, radar_state)
def test_vision_lead_approach_cap_brakes_before_hard_cap():
v_ego = 21.535
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
@@ -1216,6 +1244,126 @@ def test_standstill_moving_lead_depart_accel_hold_cancels_if_lead_brakes(model_v
assert planner.output_a_target < 0.1
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_standstill_radar_depart_kept_when_radar_lead_is_centered(model_version):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=0.0)
sm = make_sm(
0.0,
desired_accel=0.45,
min_accel=-0.5,
experimental_mode=False,
tracking_lead=False,
lead_one=make_lead(status=True, d_rel=11.2, v_lead=0.63, a_lead=0.36, radar=True, model_prob=0.998, y_rel=0.2),
)
sm["carState"].standstill = True
sm["controlsState"].longControlState = LongCtrlState.stopping
sm["starpilotPlan"].vCruise = 10.0
sm["modelV2"].action.shouldStop = False
set_model_lead(sm["modelV2"], 0, prob=0.999, x0=12.2, y0=0.03, v0=0.4)
planner.update(sm, make_toggles(model_version))
assert planner.output_a_target >= longitudinal_planner_module.STANDSTILL_LEAD_DEPART_MIN_ACCEL
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_standstill_radar_depart_blocks_offcenter_radar_conflict(model_version):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=0.0)
sm = make_sm(
0.0,
desired_accel=0.45,
min_accel=-0.5,
experimental_mode=False,
tracking_lead=False,
lead_one=make_lead(status=True, d_rel=11.2, v_lead=0.63, a_lead=0.36, radar=True, model_prob=0.998, y_rel=2.3),
)
sm["carState"].standstill = True
sm["controlsState"].longControlState = LongCtrlState.stopping
sm["starpilotPlan"].vCruise = 10.0
sm["modelV2"].action.shouldStop = False
set_model_lead(sm["modelV2"], 0, prob=0.999, x0=12.2, y0=0.03, v0=0.4)
planner.update(sm, make_toggles(model_version))
assert planner.output_a_target < longitudinal_planner_module.STANDSTILL_LEAD_DEPART_MIN_ACCEL
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_low_speed_radar_depart_hold_blocks_offcenter_radar_conflict(model_version):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=1.25)
sm = make_sm(
1.25,
desired_accel=0.20,
min_accel=-0.5,
experimental_mode=False,
tracking_lead=False,
lead_one=make_lead(status=True, d_rel=9.95, v_lead=0.43, a_lead=0.44, radar=True, model_prob=0.999, y_rel=2.2),
)
sm["carState"].standstill = False
sm["controlsState"].longControlState = LongCtrlState.pid
sm["starpilotPlan"].vCruise = 10.0
sm["modelV2"].action.shouldStop = False
set_model_lead(sm["modelV2"], 0, prob=0.999, x0=11.4, y0=0.0, v0=0.2)
planner.update(sm, make_toggles(model_version))
assert planner.output_a_target < longitudinal_planner_module.STANDSTILL_LEAD_DEPART_MIN_ACCEL
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_standstill_radar_takeoffs_toggle_bypasses_offcenter_veto(model_version):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=0.0)
sm = make_sm(
0.0,
desired_accel=0.45,
min_accel=-0.5,
experimental_mode=False,
tracking_lead=False,
lead_one=make_lead(status=True, d_rel=11.2, v_lead=0.63, a_lead=0.36, radar=True, model_prob=0.998, y_rel=2.3),
)
sm["carState"].standstill = True
sm["controlsState"].longControlState = LongCtrlState.stopping
sm["starpilotPlan"].vCruise = 10.0
sm["modelV2"].action.shouldStop = False
set_model_lead(sm["modelV2"], 0, prob=0.999, x0=12.2, y0=0.03, v0=0.4)
planner.update(sm, make_toggles(model_version, radar_takeoffs=True))
assert planner.output_a_target >= longitudinal_planner_module.STANDSTILL_LEAD_DEPART_MIN_ACCEL
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_low_speed_radar_takeoffs_toggle_bypasses_offcenter_veto(model_version):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=1.25)
sm = make_sm(
1.25,
desired_accel=0.20,
min_accel=-0.5,
experimental_mode=False,
tracking_lead=False,
lead_one=make_lead(status=True, d_rel=9.95, v_lead=0.43, a_lead=0.44, radar=True, model_prob=0.999, y_rel=2.2),
)
sm["carState"].standstill = False
sm["controlsState"].longControlState = LongCtrlState.pid
sm["starpilotPlan"].vCruise = 10.0
sm["modelV2"].action.shouldStop = False
set_model_lead(sm["modelV2"], 0, prob=0.999, x0=11.4, y0=0.0, v0=0.2)
planner.update(sm, make_toggles(model_version, radar_takeoffs=True))
assert planner.output_a_target >= 0.0
@pytest.mark.parametrize("model_version", ["v11", "v12", "v13", "v14", "v15"])
def test_acc_mode_damps_far_radar_mild_lead_brake_more_than_close_brake(model_version):
far_v_ego = 29.26
@@ -1702,6 +1850,19 @@ def test_follow_control_lead_prefers_active_lead1_for_matched_follow():
assert follow_lead is planner.lead_two
def test_follow_control_lead_disables_optional_matched_follow_override():
v_ego = 23.3
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
planner.lead_one = make_lead(status=True, d_rel=80.0, v_lead=20.0, radar=False, model_prob=0.6)
planner.lead_two = make_lead(status=True, d_rel=49.9, v_lead=21.9, radar=False, model_prob=0.98)
planner.mpc.source = "lead1"
follow_lead = planner.get_follow_control_lead(True, v_ego, 1.45, allow_optional_far_lead_logic=False)
assert follow_lead is planner.lead_one
def test_follow_control_lead_keeps_matched_follow_lead_without_tracking_latch():
v_ego = 27.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
@@ -1713,6 +1874,17 @@ def test_follow_control_lead_keeps_matched_follow_lead_without_tracking_latch():
assert follow_lead is planner.lead_one
def test_follow_control_lead_requires_real_lead_control_when_optional_logic_disabled():
v_ego = 27.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
planner.lead_one = make_lead(status=True, d_rel=61.99, v_lead=27.63, radar=False, model_prob=0.99)
follow_lead = planner.get_follow_control_lead(False, v_ego, 1.45, allow_optional_far_lead_logic=False)
assert follow_lead is None
def test_far_lead_soft_brake_cap_limits_high_confidence_distant_vision_lead():
v_ego = 32.37
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
@@ -1724,3 +1896,254 @@ def test_far_lead_soft_brake_cap_limits_high_confidence_distant_vision_lead():
assert cap is not None
assert cap > -0.2
assert cap < -0.05
def test_matched_follow_transition_target_damps_large_comfort_sign_flip():
v_ego = 20.3
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=45.6, v_lead=19.19, a_lead=0.0, radar=False, model_prob=0.99)
smoothed = planner.get_matched_follow_transition_target(
lead,
v_ego,
1.45,
prev_output_a_target=0.12,
output_a_target=-0.40,
current_source="cruise",
tracking_lead_active=True,
)
assert smoothed is not None
assert smoothed > -0.05
assert smoothed < 0.12
def test_matched_follow_transition_target_skips_urgent_closure():
v_ego = 31.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=35.0, v_lead=28.0, a_lead=0.0, radar=False, model_prob=0.99)
smoothed = planner.get_matched_follow_transition_target(
lead,
v_ego,
1.45,
prev_output_a_target=0.10,
output_a_target=-0.60,
current_source="cruise",
tracking_lead_active=True,
)
assert smoothed is None
def test_matched_follow_transition_target_damps_low_speed_tracking_cruise_throttle_jitter():
v_ego = 14.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=31.1, v_lead=14.5, a_lead=0.0, radar=False, model_prob=0.999)
smoothed = planner.get_matched_follow_transition_target(
lead,
v_ego,
1.45,
prev_output_a_target=0.08,
output_a_target=0.46,
current_source="cruise",
tracking_lead_active=True,
)
assert smoothed is not None
assert smoothed == pytest.approx(0.14, abs=1e-6)
def test_matched_follow_transition_target_skips_low_speed_without_tracking():
v_ego = 14.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=31.1, v_lead=14.5, a_lead=0.0, radar=False, model_prob=0.999)
smoothed = planner.get_matched_follow_transition_target(
lead,
v_ego,
1.45,
prev_output_a_target=0.08,
output_a_target=0.46,
current_source="cruise",
tracking_lead_active=False,
)
assert smoothed is None
def test_matched_follow_transition_target_skips_low_speed_real_braking():
v_ego = 14.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=29.0, v_lead=13.6, a_lead=0.0, radar=False, model_prob=0.999)
smoothed = planner.get_matched_follow_transition_target(
lead,
v_ego,
1.45,
prev_output_a_target=0.08,
output_a_target=-0.30,
current_source="cruise",
tracking_lead_active=True,
)
assert smoothed is None
def test_cruise_tracking_lead_accel_cap_limits_mid_speed_follow_nibble():
v_ego = 16.2
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=33.4, v_lead=16.0, a_lead=0.0, radar=False, model_prob=0.99, y_rel=0.12)
cap = planner.get_cruise_tracking_lead_accel_cap(
lead,
v_ego,
1.45,
current_source="cruise",
tracking_lead_active=True,
)
assert cap is not None
assert 0.05 <= cap <= 0.10
def test_cruise_tracking_lead_accel_cap_blocks_unresolved_raw_close_lead_burst():
v_ego = 17.6
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=41.9, v_lead=14.2, a_lead=0.0, radar=True, model_prob=0.99, y_rel=-0.97)
cap = planner.get_cruise_tracking_lead_accel_cap(
lead,
v_ego,
1.45,
current_source="cruise",
tracking_lead_active=False,
)
assert cap is not None
assert 0.0 <= cap <= 0.05
def test_cruise_tracking_lead_accel_cap_skips_when_lead_clearly_pulls_away():
v_ego = 14.5
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead = make_lead(status=True, d_rel=35.0, v_lead=16.0, a_lead=0.0, radar=False, model_prob=0.99, y_rel=0.1)
cap = planner.get_cruise_tracking_lead_accel_cap(
lead,
v_ego,
1.45,
current_source="cruise",
tracking_lead_active=True,
)
assert cap is None
def test_near_duplicate_lead_source_hysteresis_prefers_previous_source():
v_ego = 27.0
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead_one = make_lead(status=True, d_rel=46.2, v_lead=25.5, a_lead=-0.05, radar=False, model_prob=0.99)
lead_two = make_lead(status=True, d_rel=46.8, v_lead=25.55, a_lead=-0.03, radar=False, model_prob=0.99)
lead_0_bias, lead_1_bias = planner.mpc.get_near_duplicate_lead_source_hysteresis("lead0", lead_one, lead_two, v_ego)
assert lead_0_bias == 0.0
assert lead_1_bias > 0.0
def test_near_duplicate_lead_source_hysteresis_skips_distinct_leads():
v_ego = 27.0
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead_one = make_lead(status=True, d_rel=41.0, v_lead=23.8, a_lead=0.0, radar=False, model_prob=0.99)
lead_two = make_lead(status=True, d_rel=48.0, v_lead=25.4, a_lead=0.0, radar=False, model_prob=0.99)
lead_0_bias, lead_1_bias = planner.mpc.get_near_duplicate_lead_source_hysteresis("lead0", lead_one, lead_two, v_ego)
assert lead_0_bias == 0.0
assert lead_1_bias == 0.0
def test_near_duplicate_lead_transition_target_damps_same_source_sign_flip():
v_ego = 25.0
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead_one = make_lead(status=True, d_rel=44.6, v_lead=24.05, a_lead=-0.03, radar=False, model_prob=0.99)
lead_two = make_lead(status=True, d_rel=45.1, v_lead=24.0, a_lead=-0.04, radar=False, model_prob=0.99)
lead_one.vRel = -0.95
lead_two.vRel = -1.00
planner.lead_one = lead_one
planner.lead_two = lead_two
smoothed = planner.get_near_duplicate_lead_transition_target(
lead_two,
v_ego,
1.45,
prev_output_a_target=-1.10,
output_a_target=0.13,
current_source="lead1",
tracking_lead_active=True,
)
assert smoothed is not None
assert smoothed == pytest.approx(-0.92, abs=1e-6)
def test_near_duplicate_lead_transition_target_damps_tracking_cruise_sign_flip():
v_ego = 25.0
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead_one = make_lead(status=True, d_rel=44.6, v_lead=24.05, a_lead=-0.03, radar=False, model_prob=0.99)
lead_two = make_lead(status=True, d_rel=45.1, v_lead=24.0, a_lead=-0.04, radar=False, model_prob=0.99)
lead_one.vRel = -0.95
lead_two.vRel = -1.00
planner.lead_one = lead_one
planner.lead_two = lead_two
smoothed = planner.get_near_duplicate_lead_transition_target(
lead_two,
v_ego,
1.45,
prev_output_a_target=-1.10,
output_a_target=0.13,
current_source="cruise",
tracking_lead_active=True,
)
assert smoothed is not None
assert smoothed == pytest.approx(-0.92, abs=1e-6)
def test_near_duplicate_lead_transition_target_skips_plain_cruise_without_tracking():
v_ego = 25.0
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
planner = LongitudinalPlanner(CP, init_v=v_ego)
lead_one = make_lead(status=True, d_rel=44.6, v_lead=24.05, a_lead=-0.03, radar=False, model_prob=0.99)
lead_two = make_lead(status=True, d_rel=45.1, v_lead=24.0, a_lead=-0.04, radar=False, model_prob=0.99)
lead_one.vRel = -0.95
lead_two.vRel = -1.00
planner.lead_one = lead_one
planner.lead_two = lead_two
smoothed = planner.get_near_duplicate_lead_transition_target(
lead_two,
v_ego,
1.45,
prev_output_a_target=-1.10,
output_a_target=0.13,
current_source="cruise",
tracking_lead_active=False,
)
assert smoothed is None
@@ -93,6 +93,52 @@ def test_nav_desires_turn_right_waits_until_turn_is_close():
assert helper.desire == log.Desire.none
def test_nav_desires_off_ramp_lane_guidance_becomes_keep_right():
helper = DesireHelper()
helper.nav_desires_allowed = True
helper._update_nav_params = lambda: None
helper._nav_instruction_state = {
"valid": True,
"maneuverType": "off ramp",
"maneuverModifier": "right",
"activeLaneDirection": "slightRight",
"maneuverDistance": 120.0,
}
helper.update(
make_car_state(vEgo=22.5),
True,
0.0,
make_plan(laneWidthRight=4.2),
make_toggles(nudgeless=True),
)
assert helper.desire == log.Desire.keepRight
def test_nav_desires_off_ramp_lane_guidance_waits_until_split_is_close():
helper = DesireHelper()
helper.nav_desires_allowed = True
helper._update_nav_params = lambda: None
helper._nav_instruction_state = {
"valid": True,
"maneuverType": "off ramp",
"maneuverModifier": "right",
"activeLaneDirection": "slightRight",
"maneuverDistance": 300.0,
}
helper.update(
make_car_state(vEgo=22.5),
True,
0.0,
make_plan(laneWidthRight=4.2),
make_toggles(nudgeless=True),
)
assert helper.desire == log.Desire.none
def test_nav_desires_do_not_override_lane_change_state_machine():
helper = DesireHelper()
helper.nav_desires_allowed = True
@@ -114,11 +114,129 @@ def test_new_source_limit_clears_override_until_gas_release():
assert controller.overridden_speed == pytest.approx(mph(65))
assert controller.override_slc
# --- Dropout / Fallback Test Condition ---
controller.starpilot_toggles = make_toggles(slc_fallback_set_speed=True)
# No limit available → falls back to v_cruise (75 mph) with source "None".
# Override persists because target_to_use resolves to last_valid_limit (45 mph) which is
# below overridden_speed (65 mph) — the sticky override_slc chain stays True.
controller.update_limits(0.0, datetime.now(timezone.utc), False, mph(75), mph(65), sm)
controller.update_override(mph(75), 0.0, mph(65), 0.0, sm)
assert controller.target == pytest.approx(mph(75))
assert controller.source == "None"
assert controller.overridden_speed == pytest.approx(mph(65))
assert controller.override_slc
# Recovery to a confirmed limit (55 mph) clears the override: this is a genuinely new
# speed zone (55 != last_valid 45), so clear_override_for_source_limit fires correctly.
controller.update_limits(mph(55), datetime.now(timezone.utc), False, mph(75), mph(65), sm)
controller.update_override(mph(75), 0.0, mph(65), 0.0, sm)
assert controller.target == pytest.approx(mph(55))
assert controller.source == "Dashboard"
assert controller.overridden_speed == 0
assert not controller.override_slc
# --- Override Clipping Check (set-speed fallback) ---
# Separate controller: active override, then fallback to v_cruise that is BELOW the override.
# overridden_speed clips to v_cruise (override_slc stays True via sticky chain, but
# np.clip clamps overridden_speed to the new target+offset).
clip_controller = make_controller(slc_fallback_set_speed=True)
try:
clip_controller.source = "Dashboard"
clip_controller.target = mph(55)
clip_controller.previous_source = "Dashboard"
clip_controller.previous_target = mph(55)
clip_controller.last_valid_limit = mph(55)
clip_controller.override_slc = True
clip_controller.overridden_speed = mph(65)
sm_no_gas = make_sm(gas_pressed=False)
# v_cruise = 30 mph (below last_valid 55), so target_to_use returns mph(30).
# override_slc sticky: overridden_speed=65 > 30+0=30 > 0 — still True from chain.
# np.clip(65, 30, 30) = 30, so overridden_speed clips to mph(30).
clip_controller.update_limits(0.0, datetime.now(timezone.utc), False, mph(30), mph(30), sm_no_gas)
clip_controller.update_override(mph(30), 0.0, mph(30), 0.0, sm_no_gas)
assert clip_controller.target == pytest.approx(mph(30))
# Clipped to v_cruise — not locked at mph(55) or mph(65)
assert clip_controller.overridden_speed == pytest.approx(mph(30))
assert clip_controller.override_slc
finally:
clip_controller.shutdown()
# --- Lost Speed Limit (no fallback) clears target to 0 ---
# When all limit sources drop to 0 with no fallback, target becomes 0
# and override_slc is False (target_to_use=0, chain evaluates False).
lost_controller = make_controller(slc_fallback_set_speed=False, slc_fallback_previous_speed_limit=False)
try:
lost_controller.source = "Dashboard"
lost_controller.target = mph(45)
lost_controller.previous_source = "Dashboard"
lost_controller.previous_target = mph(45)
sm_on = make_sm(gas_pressed=False)
lost_controller.update_limits(0.0, datetime.now(timezone.utc), False, mph(75), mph(65), sm_on)
lost_controller.update_override(mph(75), 0.0, mph(65), 0.0, sm_on)
assert lost_controller.target == 0
assert lost_controller.overridden_speed == 0
assert not lost_controller.override_slc
finally:
lost_controller.shutdown()
finally:
controller.shutdown()
def test_unconfirmed_lower_limit_keeps_existing_override():
# First, verify startup behavior where target is 0 and priority limit is detected
startup_controller = make_controller(
speed_limit_priority1="Dashboard",
slc_fallback_previous_speed_limit=True,
)
try:
startup_controller.previous_target = mph(55)
startup_controller.previous_source = "Dashboard"
startup_controller.target = 0
sm = make_sm(gas_pressed=False)
startup_controller.update_limits(mph(45), datetime.now(timezone.utc), False, mph(75), mph(65), sm)
assert startup_controller.target == pytest.approx(mph(45))
assert startup_controller.source == "Dashboard"
finally:
startup_controller.shutdown()
# Verify Bug 3: Fallback transitions should bypass confirmation checks
fallback_confirm_controller = make_controller(
slc_fallback_set_speed=True,
speed_limit_confirmation_higher=True
)
try:
fallback_confirm_controller.source = "Dashboard"
fallback_confirm_controller.target = mph(35)
fallback_confirm_controller.previous_target = mph(35)
sm = make_sm(gas_pressed=False)
fallback_confirm_controller.update_limits(0.0, datetime.now(timezone.utc), False, mph(60), mph(35), sm)
assert fallback_confirm_controller.target == pytest.approx(mph(60))
assert fallback_confirm_controller.source == "None"
assert fallback_confirm_controller.unconfirmed_speed_limit == 0
finally:
fallback_confirm_controller.shutdown()
# Verify Bug 1: Boundaries are correctly mapped and not falling back to 0
boundary_controller = make_controller()
boundary_controller.starpilot_toggles.speed_limit_offset1 = 1.0
boundary_controller.starpilot_toggles.speed_limit_offset2 = 2.0
# Exact boundary speed: 11.2 m/s is the *start* of band 2 (2534 mph range).
# With low <= target < high: 11.2 <= 11.2 < 15.2 → True → maps to offset2 (not 0).
offset = boundary_controller.get_offset(11.2)
assert offset != 0.0
controller = make_controller(speed_limit_confirmation_lower=True)
try:
controller.source = "Dashboard"
+342 -342
View File
@@ -45,326 +45,326 @@ const static double MAHA_THRESH_31 = 3.8414588206941227;
* *
* This file is part of 'ekf' *
******************************************************************************/
void err_fun(double *nom_x, double *delta_x, double *out_4387195160971747702) {
out_4387195160971747702[0] = delta_x[0] + nom_x[0];
out_4387195160971747702[1] = delta_x[1] + nom_x[1];
out_4387195160971747702[2] = delta_x[2] + nom_x[2];
out_4387195160971747702[3] = delta_x[3] + nom_x[3];
out_4387195160971747702[4] = delta_x[4] + nom_x[4];
out_4387195160971747702[5] = delta_x[5] + nom_x[5];
out_4387195160971747702[6] = delta_x[6] + nom_x[6];
out_4387195160971747702[7] = delta_x[7] + nom_x[7];
out_4387195160971747702[8] = delta_x[8] + nom_x[8];
void err_fun(double *nom_x, double *delta_x, double *out_2765937094321424100) {
out_2765937094321424100[0] = delta_x[0] + nom_x[0];
out_2765937094321424100[1] = delta_x[1] + nom_x[1];
out_2765937094321424100[2] = delta_x[2] + nom_x[2];
out_2765937094321424100[3] = delta_x[3] + nom_x[3];
out_2765937094321424100[4] = delta_x[4] + nom_x[4];
out_2765937094321424100[5] = delta_x[5] + nom_x[5];
out_2765937094321424100[6] = delta_x[6] + nom_x[6];
out_2765937094321424100[7] = delta_x[7] + nom_x[7];
out_2765937094321424100[8] = delta_x[8] + nom_x[8];
}
void inv_err_fun(double *nom_x, double *true_x, double *out_7707264064834051115) {
out_7707264064834051115[0] = -nom_x[0] + true_x[0];
out_7707264064834051115[1] = -nom_x[1] + true_x[1];
out_7707264064834051115[2] = -nom_x[2] + true_x[2];
out_7707264064834051115[3] = -nom_x[3] + true_x[3];
out_7707264064834051115[4] = -nom_x[4] + true_x[4];
out_7707264064834051115[5] = -nom_x[5] + true_x[5];
out_7707264064834051115[6] = -nom_x[6] + true_x[6];
out_7707264064834051115[7] = -nom_x[7] + true_x[7];
out_7707264064834051115[8] = -nom_x[8] + true_x[8];
void inv_err_fun(double *nom_x, double *true_x, double *out_1382255689110899984) {
out_1382255689110899984[0] = -nom_x[0] + true_x[0];
out_1382255689110899984[1] = -nom_x[1] + true_x[1];
out_1382255689110899984[2] = -nom_x[2] + true_x[2];
out_1382255689110899984[3] = -nom_x[3] + true_x[3];
out_1382255689110899984[4] = -nom_x[4] + true_x[4];
out_1382255689110899984[5] = -nom_x[5] + true_x[5];
out_1382255689110899984[6] = -nom_x[6] + true_x[6];
out_1382255689110899984[7] = -nom_x[7] + true_x[7];
out_1382255689110899984[8] = -nom_x[8] + true_x[8];
}
void H_mod_fun(double *state, double *out_7178605602671138983) {
out_7178605602671138983[0] = 1.0;
out_7178605602671138983[1] = 0.0;
out_7178605602671138983[2] = 0.0;
out_7178605602671138983[3] = 0.0;
out_7178605602671138983[4] = 0.0;
out_7178605602671138983[5] = 0.0;
out_7178605602671138983[6] = 0.0;
out_7178605602671138983[7] = 0.0;
out_7178605602671138983[8] = 0.0;
out_7178605602671138983[9] = 0.0;
out_7178605602671138983[10] = 1.0;
out_7178605602671138983[11] = 0.0;
out_7178605602671138983[12] = 0.0;
out_7178605602671138983[13] = 0.0;
out_7178605602671138983[14] = 0.0;
out_7178605602671138983[15] = 0.0;
out_7178605602671138983[16] = 0.0;
out_7178605602671138983[17] = 0.0;
out_7178605602671138983[18] = 0.0;
out_7178605602671138983[19] = 0.0;
out_7178605602671138983[20] = 1.0;
out_7178605602671138983[21] = 0.0;
out_7178605602671138983[22] = 0.0;
out_7178605602671138983[23] = 0.0;
out_7178605602671138983[24] = 0.0;
out_7178605602671138983[25] = 0.0;
out_7178605602671138983[26] = 0.0;
out_7178605602671138983[27] = 0.0;
out_7178605602671138983[28] = 0.0;
out_7178605602671138983[29] = 0.0;
out_7178605602671138983[30] = 1.0;
out_7178605602671138983[31] = 0.0;
out_7178605602671138983[32] = 0.0;
out_7178605602671138983[33] = 0.0;
out_7178605602671138983[34] = 0.0;
out_7178605602671138983[35] = 0.0;
out_7178605602671138983[36] = 0.0;
out_7178605602671138983[37] = 0.0;
out_7178605602671138983[38] = 0.0;
out_7178605602671138983[39] = 0.0;
out_7178605602671138983[40] = 1.0;
out_7178605602671138983[41] = 0.0;
out_7178605602671138983[42] = 0.0;
out_7178605602671138983[43] = 0.0;
out_7178605602671138983[44] = 0.0;
out_7178605602671138983[45] = 0.0;
out_7178605602671138983[46] = 0.0;
out_7178605602671138983[47] = 0.0;
out_7178605602671138983[48] = 0.0;
out_7178605602671138983[49] = 0.0;
out_7178605602671138983[50] = 1.0;
out_7178605602671138983[51] = 0.0;
out_7178605602671138983[52] = 0.0;
out_7178605602671138983[53] = 0.0;
out_7178605602671138983[54] = 0.0;
out_7178605602671138983[55] = 0.0;
out_7178605602671138983[56] = 0.0;
out_7178605602671138983[57] = 0.0;
out_7178605602671138983[58] = 0.0;
out_7178605602671138983[59] = 0.0;
out_7178605602671138983[60] = 1.0;
out_7178605602671138983[61] = 0.0;
out_7178605602671138983[62] = 0.0;
out_7178605602671138983[63] = 0.0;
out_7178605602671138983[64] = 0.0;
out_7178605602671138983[65] = 0.0;
out_7178605602671138983[66] = 0.0;
out_7178605602671138983[67] = 0.0;
out_7178605602671138983[68] = 0.0;
out_7178605602671138983[69] = 0.0;
out_7178605602671138983[70] = 1.0;
out_7178605602671138983[71] = 0.0;
out_7178605602671138983[72] = 0.0;
out_7178605602671138983[73] = 0.0;
out_7178605602671138983[74] = 0.0;
out_7178605602671138983[75] = 0.0;
out_7178605602671138983[76] = 0.0;
out_7178605602671138983[77] = 0.0;
out_7178605602671138983[78] = 0.0;
out_7178605602671138983[79] = 0.0;
out_7178605602671138983[80] = 1.0;
void H_mod_fun(double *state, double *out_6175643942212596402) {
out_6175643942212596402[0] = 1.0;
out_6175643942212596402[1] = 0.0;
out_6175643942212596402[2] = 0.0;
out_6175643942212596402[3] = 0.0;
out_6175643942212596402[4] = 0.0;
out_6175643942212596402[5] = 0.0;
out_6175643942212596402[6] = 0.0;
out_6175643942212596402[7] = 0.0;
out_6175643942212596402[8] = 0.0;
out_6175643942212596402[9] = 0.0;
out_6175643942212596402[10] = 1.0;
out_6175643942212596402[11] = 0.0;
out_6175643942212596402[12] = 0.0;
out_6175643942212596402[13] = 0.0;
out_6175643942212596402[14] = 0.0;
out_6175643942212596402[15] = 0.0;
out_6175643942212596402[16] = 0.0;
out_6175643942212596402[17] = 0.0;
out_6175643942212596402[18] = 0.0;
out_6175643942212596402[19] = 0.0;
out_6175643942212596402[20] = 1.0;
out_6175643942212596402[21] = 0.0;
out_6175643942212596402[22] = 0.0;
out_6175643942212596402[23] = 0.0;
out_6175643942212596402[24] = 0.0;
out_6175643942212596402[25] = 0.0;
out_6175643942212596402[26] = 0.0;
out_6175643942212596402[27] = 0.0;
out_6175643942212596402[28] = 0.0;
out_6175643942212596402[29] = 0.0;
out_6175643942212596402[30] = 1.0;
out_6175643942212596402[31] = 0.0;
out_6175643942212596402[32] = 0.0;
out_6175643942212596402[33] = 0.0;
out_6175643942212596402[34] = 0.0;
out_6175643942212596402[35] = 0.0;
out_6175643942212596402[36] = 0.0;
out_6175643942212596402[37] = 0.0;
out_6175643942212596402[38] = 0.0;
out_6175643942212596402[39] = 0.0;
out_6175643942212596402[40] = 1.0;
out_6175643942212596402[41] = 0.0;
out_6175643942212596402[42] = 0.0;
out_6175643942212596402[43] = 0.0;
out_6175643942212596402[44] = 0.0;
out_6175643942212596402[45] = 0.0;
out_6175643942212596402[46] = 0.0;
out_6175643942212596402[47] = 0.0;
out_6175643942212596402[48] = 0.0;
out_6175643942212596402[49] = 0.0;
out_6175643942212596402[50] = 1.0;
out_6175643942212596402[51] = 0.0;
out_6175643942212596402[52] = 0.0;
out_6175643942212596402[53] = 0.0;
out_6175643942212596402[54] = 0.0;
out_6175643942212596402[55] = 0.0;
out_6175643942212596402[56] = 0.0;
out_6175643942212596402[57] = 0.0;
out_6175643942212596402[58] = 0.0;
out_6175643942212596402[59] = 0.0;
out_6175643942212596402[60] = 1.0;
out_6175643942212596402[61] = 0.0;
out_6175643942212596402[62] = 0.0;
out_6175643942212596402[63] = 0.0;
out_6175643942212596402[64] = 0.0;
out_6175643942212596402[65] = 0.0;
out_6175643942212596402[66] = 0.0;
out_6175643942212596402[67] = 0.0;
out_6175643942212596402[68] = 0.0;
out_6175643942212596402[69] = 0.0;
out_6175643942212596402[70] = 1.0;
out_6175643942212596402[71] = 0.0;
out_6175643942212596402[72] = 0.0;
out_6175643942212596402[73] = 0.0;
out_6175643942212596402[74] = 0.0;
out_6175643942212596402[75] = 0.0;
out_6175643942212596402[76] = 0.0;
out_6175643942212596402[77] = 0.0;
out_6175643942212596402[78] = 0.0;
out_6175643942212596402[79] = 0.0;
out_6175643942212596402[80] = 1.0;
}
void f_fun(double *state, double dt, double *out_2416599425795193412) {
out_2416599425795193412[0] = state[0];
out_2416599425795193412[1] = state[1];
out_2416599425795193412[2] = state[2];
out_2416599425795193412[3] = state[3];
out_2416599425795193412[4] = state[4];
out_2416599425795193412[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
out_2416599425795193412[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
out_2416599425795193412[7] = state[7];
out_2416599425795193412[8] = state[8];
void f_fun(double *state, double dt, double *out_2437881867604815540) {
out_2437881867604815540[0] = state[0];
out_2437881867604815540[1] = state[1];
out_2437881867604815540[2] = state[2];
out_2437881867604815540[3] = state[3];
out_2437881867604815540[4] = state[4];
out_2437881867604815540[5] = dt*((-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]))*state[6] - 9.8100000000000005*state[8] + stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*state[1]) + (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*state[4])) + state[5];
out_2437881867604815540[6] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*state[4])) + state[6];
out_2437881867604815540[7] = state[7];
out_2437881867604815540[8] = state[8];
}
void F_fun(double *state, double dt, double *out_6761986232654706930) {
out_6761986232654706930[0] = 1;
out_6761986232654706930[1] = 0;
out_6761986232654706930[2] = 0;
out_6761986232654706930[3] = 0;
out_6761986232654706930[4] = 0;
out_6761986232654706930[5] = 0;
out_6761986232654706930[6] = 0;
out_6761986232654706930[7] = 0;
out_6761986232654706930[8] = 0;
out_6761986232654706930[9] = 0;
out_6761986232654706930[10] = 1;
out_6761986232654706930[11] = 0;
out_6761986232654706930[12] = 0;
out_6761986232654706930[13] = 0;
out_6761986232654706930[14] = 0;
out_6761986232654706930[15] = 0;
out_6761986232654706930[16] = 0;
out_6761986232654706930[17] = 0;
out_6761986232654706930[18] = 0;
out_6761986232654706930[19] = 0;
out_6761986232654706930[20] = 1;
out_6761986232654706930[21] = 0;
out_6761986232654706930[22] = 0;
out_6761986232654706930[23] = 0;
out_6761986232654706930[24] = 0;
out_6761986232654706930[25] = 0;
out_6761986232654706930[26] = 0;
out_6761986232654706930[27] = 0;
out_6761986232654706930[28] = 0;
out_6761986232654706930[29] = 0;
out_6761986232654706930[30] = 1;
out_6761986232654706930[31] = 0;
out_6761986232654706930[32] = 0;
out_6761986232654706930[33] = 0;
out_6761986232654706930[34] = 0;
out_6761986232654706930[35] = 0;
out_6761986232654706930[36] = 0;
out_6761986232654706930[37] = 0;
out_6761986232654706930[38] = 0;
out_6761986232654706930[39] = 0;
out_6761986232654706930[40] = 1;
out_6761986232654706930[41] = 0;
out_6761986232654706930[42] = 0;
out_6761986232654706930[43] = 0;
out_6761986232654706930[44] = 0;
out_6761986232654706930[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
out_6761986232654706930[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
out_6761986232654706930[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_6761986232654706930[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_6761986232654706930[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
out_6761986232654706930[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
out_6761986232654706930[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
out_6761986232654706930[52] = dt*stiffness_front*state[0]/(mass*state[1]);
out_6761986232654706930[53] = -9.8100000000000005*dt;
out_6761986232654706930[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
out_6761986232654706930[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
out_6761986232654706930[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_6761986232654706930[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_6761986232654706930[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
out_6761986232654706930[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
out_6761986232654706930[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
out_6761986232654706930[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_6761986232654706930[62] = 0;
out_6761986232654706930[63] = 0;
out_6761986232654706930[64] = 0;
out_6761986232654706930[65] = 0;
out_6761986232654706930[66] = 0;
out_6761986232654706930[67] = 0;
out_6761986232654706930[68] = 0;
out_6761986232654706930[69] = 0;
out_6761986232654706930[70] = 1;
out_6761986232654706930[71] = 0;
out_6761986232654706930[72] = 0;
out_6761986232654706930[73] = 0;
out_6761986232654706930[74] = 0;
out_6761986232654706930[75] = 0;
out_6761986232654706930[76] = 0;
out_6761986232654706930[77] = 0;
out_6761986232654706930[78] = 0;
out_6761986232654706930[79] = 0;
out_6761986232654706930[80] = 1;
void F_fun(double *state, double dt, double *out_3645925778664752399) {
out_3645925778664752399[0] = 1;
out_3645925778664752399[1] = 0;
out_3645925778664752399[2] = 0;
out_3645925778664752399[3] = 0;
out_3645925778664752399[4] = 0;
out_3645925778664752399[5] = 0;
out_3645925778664752399[6] = 0;
out_3645925778664752399[7] = 0;
out_3645925778664752399[8] = 0;
out_3645925778664752399[9] = 0;
out_3645925778664752399[10] = 1;
out_3645925778664752399[11] = 0;
out_3645925778664752399[12] = 0;
out_3645925778664752399[13] = 0;
out_3645925778664752399[14] = 0;
out_3645925778664752399[15] = 0;
out_3645925778664752399[16] = 0;
out_3645925778664752399[17] = 0;
out_3645925778664752399[18] = 0;
out_3645925778664752399[19] = 0;
out_3645925778664752399[20] = 1;
out_3645925778664752399[21] = 0;
out_3645925778664752399[22] = 0;
out_3645925778664752399[23] = 0;
out_3645925778664752399[24] = 0;
out_3645925778664752399[25] = 0;
out_3645925778664752399[26] = 0;
out_3645925778664752399[27] = 0;
out_3645925778664752399[28] = 0;
out_3645925778664752399[29] = 0;
out_3645925778664752399[30] = 1;
out_3645925778664752399[31] = 0;
out_3645925778664752399[32] = 0;
out_3645925778664752399[33] = 0;
out_3645925778664752399[34] = 0;
out_3645925778664752399[35] = 0;
out_3645925778664752399[36] = 0;
out_3645925778664752399[37] = 0;
out_3645925778664752399[38] = 0;
out_3645925778664752399[39] = 0;
out_3645925778664752399[40] = 1;
out_3645925778664752399[41] = 0;
out_3645925778664752399[42] = 0;
out_3645925778664752399[43] = 0;
out_3645925778664752399[44] = 0;
out_3645925778664752399[45] = dt*(stiffness_front*(-state[2] - state[3] + state[7])/(mass*state[1]) + (-stiffness_front - stiffness_rear)*state[5]/(mass*state[4]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[6]/(mass*state[4]));
out_3645925778664752399[46] = -dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(mass*pow(state[1], 2));
out_3645925778664752399[47] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_3645925778664752399[48] = -dt*stiffness_front*state[0]/(mass*state[1]);
out_3645925778664752399[49] = dt*((-1 - (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*pow(state[4], 2)))*state[6] - (-stiffness_front*state[0] - stiffness_rear*state[0])*state[5]/(mass*pow(state[4], 2)));
out_3645925778664752399[50] = dt*(-stiffness_front*state[0] - stiffness_rear*state[0])/(mass*state[4]) + 1;
out_3645925778664752399[51] = dt*(-state[4] + (-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(mass*state[4]));
out_3645925778664752399[52] = dt*stiffness_front*state[0]/(mass*state[1]);
out_3645925778664752399[53] = -9.8100000000000005*dt;
out_3645925778664752399[54] = dt*(center_to_front*stiffness_front*(-state[2] - state[3] + state[7])/(rotational_inertia*state[1]) + (-center_to_front*stiffness_front + center_to_rear*stiffness_rear)*state[5]/(rotational_inertia*state[4]) + (-pow(center_to_front, 2)*stiffness_front - pow(center_to_rear, 2)*stiffness_rear)*state[6]/(rotational_inertia*state[4]));
out_3645925778664752399[55] = -center_to_front*dt*stiffness_front*(-state[2] - state[3] + state[7])*state[0]/(rotational_inertia*pow(state[1], 2));
out_3645925778664752399[56] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_3645925778664752399[57] = -center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_3645925778664752399[58] = dt*(-(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])*state[5]/(rotational_inertia*pow(state[4], 2)) - (-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])*state[6]/(rotational_inertia*pow(state[4], 2)));
out_3645925778664752399[59] = dt*(-center_to_front*stiffness_front*state[0] + center_to_rear*stiffness_rear*state[0])/(rotational_inertia*state[4]);
out_3645925778664752399[60] = dt*(-pow(center_to_front, 2)*stiffness_front*state[0] - pow(center_to_rear, 2)*stiffness_rear*state[0])/(rotational_inertia*state[4]) + 1;
out_3645925778664752399[61] = center_to_front*dt*stiffness_front*state[0]/(rotational_inertia*state[1]);
out_3645925778664752399[62] = 0;
out_3645925778664752399[63] = 0;
out_3645925778664752399[64] = 0;
out_3645925778664752399[65] = 0;
out_3645925778664752399[66] = 0;
out_3645925778664752399[67] = 0;
out_3645925778664752399[68] = 0;
out_3645925778664752399[69] = 0;
out_3645925778664752399[70] = 1;
out_3645925778664752399[71] = 0;
out_3645925778664752399[72] = 0;
out_3645925778664752399[73] = 0;
out_3645925778664752399[74] = 0;
out_3645925778664752399[75] = 0;
out_3645925778664752399[76] = 0;
out_3645925778664752399[77] = 0;
out_3645925778664752399[78] = 0;
out_3645925778664752399[79] = 0;
out_3645925778664752399[80] = 1;
}
void h_25(double *state, double *unused, double *out_319074315832850169) {
out_319074315832850169[0] = state[6];
void h_25(double *state, double *unused, double *out_1347552076965832871) {
out_1347552076965832871[0] = state[6];
}
void H_25(double *state, double *unused, double *out_3655624952681647306) {
out_3655624952681647306[0] = 0;
out_3655624952681647306[1] = 0;
out_3655624952681647306[2] = 0;
out_3655624952681647306[3] = 0;
out_3655624952681647306[4] = 0;
out_3655624952681647306[5] = 0;
out_3655624952681647306[6] = 1;
out_3655624952681647306[7] = 0;
out_3655624952681647306[8] = 0;
void H_25(double *state, double *unused, double *out_6035190491488835800) {
out_6035190491488835800[0] = 0;
out_6035190491488835800[1] = 0;
out_6035190491488835800[2] = 0;
out_6035190491488835800[3] = 0;
out_6035190491488835800[4] = 0;
out_6035190491488835800[5] = 0;
out_6035190491488835800[6] = 1;
out_6035190491488835800[7] = 0;
out_6035190491488835800[8] = 0;
}
void h_24(double *state, double *unused, double *out_5734853090591072423) {
out_5734853090591072423[0] = state[4];
out_5734853090591072423[1] = state[5];
void h_24(double *state, double *unused, double *out_7176999251413506765) {
out_7176999251413506765[0] = state[4];
out_7176999251413506765[1] = state[5];
}
void H_24(double *state, double *unused, double *out_1429917168702778744) {
out_1429917168702778744[0] = 0;
out_1429917168702778744[1] = 0;
out_1429917168702778744[2] = 0;
out_1429917168702778744[3] = 0;
out_1429917168702778744[4] = 1;
out_1429917168702778744[5] = 0;
out_1429917168702778744[6] = 0;
out_1429917168702778744[7] = 0;
out_1429917168702778744[8] = 0;
out_1429917168702778744[9] = 0;
out_1429917168702778744[10] = 0;
out_1429917168702778744[11] = 0;
out_1429917168702778744[12] = 0;
out_1429917168702778744[13] = 0;
out_1429917168702778744[14] = 1;
out_1429917168702778744[15] = 0;
out_1429917168702778744[16] = 0;
out_1429917168702778744[17] = 0;
void H_24(double *state, double *unused, double *out_6210520902369554390) {
out_6210520902369554390[0] = 0;
out_6210520902369554390[1] = 0;
out_6210520902369554390[2] = 0;
out_6210520902369554390[3] = 0;
out_6210520902369554390[4] = 1;
out_6210520902369554390[5] = 0;
out_6210520902369554390[6] = 0;
out_6210520902369554390[7] = 0;
out_6210520902369554390[8] = 0;
out_6210520902369554390[9] = 0;
out_6210520902369554390[10] = 0;
out_6210520902369554390[11] = 0;
out_6210520902369554390[12] = 0;
out_6210520902369554390[13] = 0;
out_6210520902369554390[14] = 1;
out_6210520902369554390[15] = 0;
out_6210520902369554390[16] = 0;
out_6210520902369554390[17] = 0;
}
void h_30(double *state, double *unused, double *out_8212013810717373528) {
out_8212013810717373528[0] = state[4];
void h_30(double *state, double *unused, double *out_2798183469594716038) {
out_2798183469594716038[0] = state[4];
}
void H_30(double *state, double *unused, double *out_3784963899824887376) {
out_3784963899824887376[0] = 0;
out_3784963899824887376[1] = 0;
out_3784963899824887376[2] = 0;
out_3784963899824887376[3] = 0;
out_3784963899824887376[4] = 1;
out_3784963899824887376[5] = 0;
out_3784963899824887376[6] = 0;
out_3784963899824887376[7] = 0;
out_3784963899824887376[8] = 0;
void H_30(double *state, double *unused, double *out_881499850002780955) {
out_881499850002780955[0] = 0;
out_881499850002780955[1] = 0;
out_881499850002780955[2] = 0;
out_881499850002780955[3] = 0;
out_881499850002780955[4] = 1;
out_881499850002780955[5] = 0;
out_881499850002780955[6] = 0;
out_881499850002780955[7] = 0;
out_881499850002780955[8] = 0;
}
void h_26(double *state, double *unused, double *out_5233056995331332443) {
out_5233056995331332443[0] = state[7];
void h_26(double *state, double *unused, double *out_7428563492211452550) {
out_7428563492211452550[0] = state[7];
}
void H_26(double *state, double *unused, double *out_2998770888571335402) {
out_2998770888571335402[0] = 0;
out_2998770888571335402[1] = 0;
out_2998770888571335402[2] = 0;
out_2998770888571335402[3] = 0;
out_2998770888571335402[4] = 0;
out_2998770888571335402[5] = 0;
out_2998770888571335402[6] = 0;
out_2998770888571335402[7] = 1;
out_2998770888571335402[8] = 0;
void H_26(double *state, double *unused, double *out_8670050263346659592) {
out_8670050263346659592[0] = 0;
out_8670050263346659592[1] = 0;
out_8670050263346659592[2] = 0;
out_8670050263346659592[3] = 0;
out_8670050263346659592[4] = 0;
out_8670050263346659592[5] = 0;
out_8670050263346659592[6] = 0;
out_8670050263346659592[7] = 1;
out_8670050263346659592[8] = 0;
}
void h_27(double *state, double *unused, double *out_3355860367277182854) {
out_3355860367277182854[0] = state[3];
void h_27(double *state, double *unused, double *out_3654121190695012774) {
out_3654121190695012774[0] = state[3];
}
void H_27(double *state, double *unused, double *out_5959727211625312287) {
out_5959727211625312287[0] = 0;
out_5959727211625312287[1] = 0;
out_5959727211625312287[2] = 0;
out_5959727211625312287[3] = 1;
out_5959727211625312287[4] = 0;
out_5959727211625312287[5] = 0;
out_5959727211625312287[6] = 0;
out_5959727211625312287[7] = 0;
out_5959727211625312287[8] = 0;
void H_27(double *state, double *unused, double *out_8339292750432500781) {
out_8339292750432500781[0] = 0;
out_8339292750432500781[1] = 0;
out_8339292750432500781[2] = 0;
out_8339292750432500781[3] = 1;
out_8339292750432500781[4] = 0;
out_8339292750432500781[5] = 0;
out_8339292750432500781[6] = 0;
out_8339292750432500781[7] = 0;
out_8339292750432500781[8] = 0;
}
void h_29(double *state, double *unused, double *out_7630324942183480437) {
out_7630324942183480437[0] = state[1];
void h_29(double *state, double *unused, double *out_2203489798066129607) {
out_2203489798066129607[0] = state[1];
}
void H_29(double *state, double *unused, double *out_3274732555510495192) {
out_3274732555510495192[0] = 0;
out_3274732555510495192[1] = 1;
out_3274732555510495192[2] = 0;
out_3274732555510495192[3] = 0;
out_3274732555510495192[4] = 0;
out_3274732555510495192[5] = 0;
out_3274732555510495192[6] = 0;
out_3274732555510495192[7] = 0;
out_3274732555510495192[8] = 0;
void H_29(double *state, double *unused, double *out_5654298094317683686) {
out_5654298094317683686[0] = 0;
out_5654298094317683686[1] = 1;
out_5654298094317683686[2] = 0;
out_5654298094317683686[3] = 0;
out_5654298094317683686[4] = 0;
out_5654298094317683686[5] = 0;
out_5654298094317683686[6] = 0;
out_5654298094317683686[7] = 0;
out_5654298094317683686[8] = 0;
}
void h_28(double *state, double *unused, double *out_4299370220178845289) {
out_4299370220178845289[0] = state[0];
void h_28(double *state, double *unused, double *out_3781022243733688039) {
out_3781022243733688039[0] = state[0];
}
void H_28(double *state, double *unused, double *out_1311102283945168941) {
out_1311102283945168941[0] = 1;
out_1311102283945168941[1] = 0;
out_1311102283945168941[2] = 0;
out_1311102283945168941[3] = 0;
out_1311102283945168941[4] = 0;
out_1311102283945168941[5] = 0;
out_1311102283945168941[6] = 0;
out_1311102283945168941[7] = 0;
out_1311102283945168941[8] = 0;
void H_28(double *state, double *unused, double *out_3690667822752357435) {
out_3690667822752357435[0] = 1;
out_3690667822752357435[1] = 0;
out_3690667822752357435[2] = 0;
out_3690667822752357435[3] = 0;
out_3690667822752357435[4] = 0;
out_3690667822752357435[5] = 0;
out_3690667822752357435[6] = 0;
out_3690667822752357435[7] = 0;
out_3690667822752357435[8] = 0;
}
void h_31(double *state, double *unused, double *out_594268378117356058) {
out_594268378117356058[0] = state[8];
void h_31(double *state, double *unused, double *out_5423283149384518065) {
out_5423283149384518065[0] = state[8];
}
void H_31(double *state, double *unused, double *out_3624978990804686878) {
out_3624978990804686878[0] = 0;
out_3624978990804686878[1] = 0;
out_3624978990804686878[2] = 0;
out_3624978990804686878[3] = 0;
out_3624978990804686878[4] = 0;
out_3624978990804686878[5] = 0;
out_3624978990804686878[6] = 0;
out_3624978990804686878[7] = 0;
out_3624978990804686878[8] = 1;
void H_31(double *state, double *unused, double *out_6004544529611875372) {
out_6004544529611875372[0] = 0;
out_6004544529611875372[1] = 0;
out_6004544529611875372[2] = 0;
out_6004544529611875372[3] = 0;
out_6004544529611875372[4] = 0;
out_6004544529611875372[5] = 0;
out_6004544529611875372[6] = 0;
out_6004544529611875372[7] = 0;
out_6004544529611875372[8] = 1;
}
#include <eigen3/Eigen/Dense>
#include <iostream>
@@ -518,68 +518,68 @@ void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) {
update<1, 3, 0>(in_x, in_P, h_31, H_31, NULL, in_z, in_R, in_ea, MAHA_THRESH_31);
}
void car_err_fun(double *nom_x, double *delta_x, double *out_4387195160971747702) {
err_fun(nom_x, delta_x, out_4387195160971747702);
void car_err_fun(double *nom_x, double *delta_x, double *out_2765937094321424100) {
err_fun(nom_x, delta_x, out_2765937094321424100);
}
void car_inv_err_fun(double *nom_x, double *true_x, double *out_7707264064834051115) {
inv_err_fun(nom_x, true_x, out_7707264064834051115);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_1382255689110899984) {
inv_err_fun(nom_x, true_x, out_1382255689110899984);
}
void car_H_mod_fun(double *state, double *out_7178605602671138983) {
H_mod_fun(state, out_7178605602671138983);
void car_H_mod_fun(double *state, double *out_6175643942212596402) {
H_mod_fun(state, out_6175643942212596402);
}
void car_f_fun(double *state, double dt, double *out_2416599425795193412) {
f_fun(state, dt, out_2416599425795193412);
void car_f_fun(double *state, double dt, double *out_2437881867604815540) {
f_fun(state, dt, out_2437881867604815540);
}
void car_F_fun(double *state, double dt, double *out_6761986232654706930) {
F_fun(state, dt, out_6761986232654706930);
void car_F_fun(double *state, double dt, double *out_3645925778664752399) {
F_fun(state, dt, out_3645925778664752399);
}
void car_h_25(double *state, double *unused, double *out_319074315832850169) {
h_25(state, unused, out_319074315832850169);
void car_h_25(double *state, double *unused, double *out_1347552076965832871) {
h_25(state, unused, out_1347552076965832871);
}
void car_H_25(double *state, double *unused, double *out_3655624952681647306) {
H_25(state, unused, out_3655624952681647306);
void car_H_25(double *state, double *unused, double *out_6035190491488835800) {
H_25(state, unused, out_6035190491488835800);
}
void car_h_24(double *state, double *unused, double *out_5734853090591072423) {
h_24(state, unused, out_5734853090591072423);
void car_h_24(double *state, double *unused, double *out_7176999251413506765) {
h_24(state, unused, out_7176999251413506765);
}
void car_H_24(double *state, double *unused, double *out_1429917168702778744) {
H_24(state, unused, out_1429917168702778744);
void car_H_24(double *state, double *unused, double *out_6210520902369554390) {
H_24(state, unused, out_6210520902369554390);
}
void car_h_30(double *state, double *unused, double *out_8212013810717373528) {
h_30(state, unused, out_8212013810717373528);
void car_h_30(double *state, double *unused, double *out_2798183469594716038) {
h_30(state, unused, out_2798183469594716038);
}
void car_H_30(double *state, double *unused, double *out_3784963899824887376) {
H_30(state, unused, out_3784963899824887376);
void car_H_30(double *state, double *unused, double *out_881499850002780955) {
H_30(state, unused, out_881499850002780955);
}
void car_h_26(double *state, double *unused, double *out_5233056995331332443) {
h_26(state, unused, out_5233056995331332443);
void car_h_26(double *state, double *unused, double *out_7428563492211452550) {
h_26(state, unused, out_7428563492211452550);
}
void car_H_26(double *state, double *unused, double *out_2998770888571335402) {
H_26(state, unused, out_2998770888571335402);
void car_H_26(double *state, double *unused, double *out_8670050263346659592) {
H_26(state, unused, out_8670050263346659592);
}
void car_h_27(double *state, double *unused, double *out_3355860367277182854) {
h_27(state, unused, out_3355860367277182854);
void car_h_27(double *state, double *unused, double *out_3654121190695012774) {
h_27(state, unused, out_3654121190695012774);
}
void car_H_27(double *state, double *unused, double *out_5959727211625312287) {
H_27(state, unused, out_5959727211625312287);
void car_H_27(double *state, double *unused, double *out_8339292750432500781) {
H_27(state, unused, out_8339292750432500781);
}
void car_h_29(double *state, double *unused, double *out_7630324942183480437) {
h_29(state, unused, out_7630324942183480437);
void car_h_29(double *state, double *unused, double *out_2203489798066129607) {
h_29(state, unused, out_2203489798066129607);
}
void car_H_29(double *state, double *unused, double *out_3274732555510495192) {
H_29(state, unused, out_3274732555510495192);
void car_H_29(double *state, double *unused, double *out_5654298094317683686) {
H_29(state, unused, out_5654298094317683686);
}
void car_h_28(double *state, double *unused, double *out_4299370220178845289) {
h_28(state, unused, out_4299370220178845289);
void car_h_28(double *state, double *unused, double *out_3781022243733688039) {
h_28(state, unused, out_3781022243733688039);
}
void car_H_28(double *state, double *unused, double *out_1311102283945168941) {
H_28(state, unused, out_1311102283945168941);
void car_H_28(double *state, double *unused, double *out_3690667822752357435) {
H_28(state, unused, out_3690667822752357435);
}
void car_h_31(double *state, double *unused, double *out_594268378117356058) {
h_31(state, unused, out_594268378117356058);
void car_h_31(double *state, double *unused, double *out_5423283149384518065) {
h_31(state, unused, out_5423283149384518065);
}
void car_H_31(double *state, double *unused, double *out_3624978990804686878) {
H_31(state, unused, out_3624978990804686878);
void car_H_31(double *state, double *unused, double *out_6004544529611875372) {
H_31(state, unused, out_6004544529611875372);
}
void car_predict(double *in_x, double *in_P, double *in_Q, double dt) {
predict(in_x, in_P, in_Q, dt);
+21 -21
View File
@@ -9,27 +9,27 @@ void car_update_27(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void car_update_29(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_28(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_update_31(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void car_err_fun(double *nom_x, double *delta_x, double *out_4387195160971747702);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_7707264064834051115);
void car_H_mod_fun(double *state, double *out_7178605602671138983);
void car_f_fun(double *state, double dt, double *out_2416599425795193412);
void car_F_fun(double *state, double dt, double *out_6761986232654706930);
void car_h_25(double *state, double *unused, double *out_319074315832850169);
void car_H_25(double *state, double *unused, double *out_3655624952681647306);
void car_h_24(double *state, double *unused, double *out_5734853090591072423);
void car_H_24(double *state, double *unused, double *out_1429917168702778744);
void car_h_30(double *state, double *unused, double *out_8212013810717373528);
void car_H_30(double *state, double *unused, double *out_3784963899824887376);
void car_h_26(double *state, double *unused, double *out_5233056995331332443);
void car_H_26(double *state, double *unused, double *out_2998770888571335402);
void car_h_27(double *state, double *unused, double *out_3355860367277182854);
void car_H_27(double *state, double *unused, double *out_5959727211625312287);
void car_h_29(double *state, double *unused, double *out_7630324942183480437);
void car_H_29(double *state, double *unused, double *out_3274732555510495192);
void car_h_28(double *state, double *unused, double *out_4299370220178845289);
void car_H_28(double *state, double *unused, double *out_1311102283945168941);
void car_h_31(double *state, double *unused, double *out_594268378117356058);
void car_H_31(double *state, double *unused, double *out_3624978990804686878);
void car_err_fun(double *nom_x, double *delta_x, double *out_2765937094321424100);
void car_inv_err_fun(double *nom_x, double *true_x, double *out_1382255689110899984);
void car_H_mod_fun(double *state, double *out_6175643942212596402);
void car_f_fun(double *state, double dt, double *out_2437881867604815540);
void car_F_fun(double *state, double dt, double *out_3645925778664752399);
void car_h_25(double *state, double *unused, double *out_1347552076965832871);
void car_H_25(double *state, double *unused, double *out_6035190491488835800);
void car_h_24(double *state, double *unused, double *out_7176999251413506765);
void car_H_24(double *state, double *unused, double *out_6210520902369554390);
void car_h_30(double *state, double *unused, double *out_2798183469594716038);
void car_H_30(double *state, double *unused, double *out_881499850002780955);
void car_h_26(double *state, double *unused, double *out_7428563492211452550);
void car_H_26(double *state, double *unused, double *out_8670050263346659592);
void car_h_27(double *state, double *unused, double *out_3654121190695012774);
void car_H_27(double *state, double *unused, double *out_8339292750432500781);
void car_h_29(double *state, double *unused, double *out_2203489798066129607);
void car_H_29(double *state, double *unused, double *out_5654298094317683686);
void car_h_28(double *state, double *unused, double *out_3781022243733688039);
void car_H_28(double *state, double *unused, double *out_3690667822752357435);
void car_h_31(double *state, double *unused, double *out_5423283149384518065);
void car_H_31(double *state, double *unused, double *out_6004544529611875372);
void car_predict(double *in_x, double *in_P, double *in_Q, double dt);
void car_set_mass(double x);
void car_set_rotational_inertia(double x);
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -5,18 +5,18 @@ void pose_update_4(double *in_x, double *in_P, double *in_z, double *in_R, doubl
void pose_update_10(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea);
void pose_err_fun(double *nom_x, double *delta_x, double *out_8207359146711228947);
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_8369219426901598353);
void pose_H_mod_fun(double *state, double *out_7202306802530511060);
void pose_f_fun(double *state, double dt, double *out_4961001892384611064);
void pose_F_fun(double *state, double dt, double *out_4383751150204030030);
void pose_h_4(double *state, double *unused, double *out_878843833946471253);
void pose_H_4(double *state, double *unused, double *out_7970215192388091303);
void pose_h_10(double *state, double *unused, double *out_1191517594273352576);
void pose_H_10(double *state, double *unused, double *out_7914634342859917414);
void pose_h_13(double *state, double *unused, double *out_5300060524255047032);
void pose_H_13(double *state, double *unused, double *out_7264255055989127512);
void pose_h_14(double *state, double *unused, double *out_3965460404426586337);
void pose_H_14(double *state, double *unused, double *out_6513288024981975784);
void pose_err_fun(double *nom_x, double *delta_x, double *out_2822233615381903085);
void pose_inv_err_fun(double *nom_x, double *true_x, double *out_3556797172859207138);
void pose_H_mod_fun(double *state, double *out_4158952900173024917);
void pose_f_fun(double *state, double dt, double *out_4480310224533440205);
void pose_F_fun(double *state, double dt, double *out_2252133042369597057);
void pose_h_4(double *state, double *unused, double *out_1225931617160521679);
void pose_H_4(double *state, double *unused, double *out_3404791898118312310);
void pose_h_10(double *state, double *unused, double *out_8314558572170779017);
void pose_H_10(double *state, double *unused, double *out_3543553484029179274);
void pose_h_13(double *state, double *unused, double *out_7492025966781743409);
void pose_H_13(double *state, double *unused, double *out_4205839310198388619);
void pose_h_14(double *state, double *unused, double *out_8444019918627598165);
void pose_H_14(double *state, double *unused, double *out_6487580330413684606);
void pose_predict(double *in_x, double *in_P, double *in_Q, double dt);
}
+167 -210
View File
@@ -4,114 +4,106 @@ import atexit
import os
import pickle
import time
from collections import defaultdict, namedtuple
from functools import partial
from collections import namedtuple
import numpy as np
def _patch_tinygrad_fetch_fw():
import hashlib
import pathlib
import zstandard
from tinygrad import helpers
original_fetch_fw = getattr(helpers, "fetch_fw", None)
if original_fetch_fw is None:
_orig = getattr(helpers, "fetch_fw", None)
if _orig is None:
return
def fetch_fw(path, name, sha256):
firmware_path = pathlib.Path(f"/lib/firmware/{path}/{name}.zst")
if firmware_path.is_file():
blob = zstandard.ZstdDecompressor().stream_reader(firmware_path.read_bytes()).read()
p = pathlib.Path(f"/lib/firmware/{path}/{name}.zst")
if p.is_file():
blob = zstandard.ZstdDecompressor().stream_reader(p.read_bytes()).read()
if hashlib.sha256(blob).hexdigest() == sha256:
return blob
return original_fetch_fw(path, name, sha256)
return _orig(path, name, sha256)
helpers.fetch_fw = fetch_fw
_patch_tinygrad_fetch_fw()
from tinygrad.tensor import Tensor
from tinygrad.helpers import Context
from tinygrad.device import Device
from tinygrad.engine.jit import TinyJit
from tinygrad.helpers import Context
from tinygrad.tensor import Tensor
NV12Frame = namedtuple("NV12Frame", ["width", "height", "stride", "y_height", "uv_height", "size"])
WARP_INPUTS = ["img_q", "big_img_q", "tfm", "big_tfm"]
POLICY_INPUTS = ["feat_q", "desire_q", "desire", "traffic_convention", "action_t"]
NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size'])
WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm']
POLICY_INPUTS = ['feat_q', 'desire_q', 'desire', 'traffic_convention', 'action_t']
WARP_DEV = os.getenv("WARP_DEV")
UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32)
UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX)
WARP_DEV = os.getenv('WARP_DEV')
def make_random_images(keys, shape, device=None):
return {key: Tensor.randint(shape, low=0, high=256, dtype="uint8", device=device).realize() for key in keys}
return {k: Tensor.randint(shape, low=0, high=256, dtype='uint8', device=device).realize() for k in keys}
class _BlobTensorInputs(dict):
_backing_arrays: dict[str, np.ndarray]
def make_random_blob_images(keys, size, device=None):
keepalive: list[np.ndarray] = []
def _make_random_blob_images():
nonlocal keepalive
keepalive = []
tensors = {}
for key in keys:
frame_np = (32 * np.random.randn(size).astype(np.float32) + 128).clip(0, 255).astype(np.uint8)
keepalive.append(frame_np)
# Match runtime's Tensor.from_blob camera input ABI so TinyJit captures the same view shape.
tensors[key] = Tensor.from_blob(frame_np.ctypes.data, (size,), dtype='uint8', device=device).realize()
return tensors
return _make_random_blob_images
def make_random_blob_images(keys, shape, device=None):
blob_shape = shape if isinstance(shape, tuple) else (shape,)
backing_arrays = {
key: np.random.randint(0, 256, size=blob_shape, dtype=np.uint8)
for key in keys
}
inputs = _BlobTensorInputs({
key: Tensor.from_blob(array.ctypes.data, array.shape, dtype="uint8", device=device).realize()
for key, array in backing_arrays.items()
})
# Keep the numpy storage alive for the duration of the JIT capture/replay call.
inputs._backing_arrays = backing_arrays
return inputs
def warp_perspective_tinygrad(src_flat, M_inv, dst_shape, src_shape, stride_pad, border_fill_val=None):
w_dst, h_dst = dst_shape
h_src, w_src = src_shape
x = Tensor.arange(w_dst, device=WARP_DEV).reshape(1, w_dst).expand(h_dst, w_dst).reshape(-1)
y = Tensor.arange(h_dst, device=WARP_DEV).reshape(h_dst, 1).expand(h_dst, w_dst).reshape(-1)
def warp_perspective_tinygrad(src_flat, matrix_inverse, dst_shape, src_shape, stride_pad, border_fill_val=None):
width_dst, height_dst = dst_shape
height_src, width_src = src_shape
x = Tensor.arange(width_dst, device=WARP_DEV).reshape(1, width_dst).expand(height_dst, width_dst).reshape(-1)
y = Tensor.arange(height_dst, device=WARP_DEV).reshape(height_dst, 1).expand(height_dst, width_dst).reshape(-1)
# Inline 3x3 matmul as elementwise to avoid reduce ops and enable fusion with gather.
src_x = matrix_inverse[0, 0] * x + matrix_inverse[0, 1] * y + matrix_inverse[0, 2]
src_y = matrix_inverse[1, 0] * x + matrix_inverse[1, 1] * y + matrix_inverse[1, 2]
src_w = matrix_inverse[2, 0] * x + matrix_inverse[2, 1] * y + matrix_inverse[2, 2]
# inline 3x3 matmul as elementwise to avoid reduce op (enables fusion with gather)
src_x = M_inv[0, 0] * x + M_inv[0, 1] * y + M_inv[0, 2]
src_y = M_inv[1, 0] * x + M_inv[1, 1] * y + M_inv[1, 2]
src_w = M_inv[2, 0] * x + M_inv[2, 1] * y + M_inv[2, 2]
src_x = src_x / src_w
src_y = src_y / src_w
x_round = Tensor.round(src_x)
y_round = Tensor.round(src_y)
x_nn_clipped = x_round.clip(0, width_src - 1).cast("int")
y_nn_clipped = y_round.clip(0, height_src - 1).cast("int")
idx = y_nn_clipped * (width_src + stride_pad) + x_nn_clipped
x_nn_clipped = x_round.clip(0, w_src - 1).cast('int')
y_nn_clipped = y_round.clip(0, h_src - 1).cast('int')
idx = y_nn_clipped * (w_src + stride_pad) + x_nn_clipped
sampled = src_flat[idx]
if border_fill_val is None:
return sampled
in_bounds = ((x_round >= 0) & (x_round <= width_src - 1) &
(y_round >= 0) & (y_round <= height_src - 1)).cast(sampled.dtype)
in_bounds = ((x_round >= 0) & (x_round <= w_src - 1) &
(y_round >= 0) & (y_round <= h_src - 1)).cast(sampled.dtype)
return sampled * in_bounds + Tensor(border_fill_val, dtype=sampled.dtype) * (1 - in_bounds)
def frames_to_tensor(frames):
height = (frames.shape[0] * 2) // 3
width = frames.shape[1]
return Tensor.cat(
frames[0:height:2, 0::2],
frames[1:height:2, 0::2],
frames[0:height:2, 1::2],
frames[1:height:2, 1::2],
frames[height:height + height // 4].reshape((height // 2, width // 2)),
frames[height + height // 4:height + height // 2].reshape((height // 2, width // 2)),
dim=0,
).reshape((6, height // 2, width // 2))
H = (frames.shape[0] * 2) // 3
W = frames.shape[1]
in_img1 = Tensor.cat(frames[0:H:2, 0::2],
frames[1:H:2, 0::2],
frames[0:H:2, 1::2],
frames[1:H:2, 1::2],
frames[H:H+H//4].reshape((H//2, W//2)),
frames[H+H//4:H+H//2].reshape((H//2, W//2)), dim=0).reshape((6, H//2, W//2))
return in_img1
def make_frame_prepare(nv12: NV12Frame, model_w, model_h):
@@ -119,81 +111,65 @@ def make_frame_prepare(nv12: NV12Frame, model_w, model_h):
uv_offset = stride * y_height
stride_pad = stride - cam_w
def frame_prepare_tinygrad(input_frame, matrix_inverse):
# UV_SCALE @ M_inv @ UV_SCALE_INV simplifies to elementwise scaling.
matrix_inverse_uv = matrix_inverse * Tensor([[1.0, 1.0, 0.5], [1.0, 1.0, 0.5], [2.0, 2.0, 1.0]], device=WARP_DEV)
# Deinterleave NV12 UV plane (UVUV... -> separate U, V).
def frame_prepare_tinygrad(input_frame, M_inv):
# UV_SCALE @ M_inv @ UV_SCALE_INV simplifies to elementwise scaling
M_inv_uv = M_inv * Tensor([[1.0, 1.0, 0.5], [1.0, 1.0, 0.5], [2.0, 2.0, 1.0]], device=WARP_DEV)
# deinterleave NV12 UV plane (UVUV... -> separate U, V)
uv = input_frame[uv_offset:uv_offset + uv_height * stride].reshape(uv_height, stride)
with Context(SPLIT_REDUCEOP=0):
y = warp_perspective_tinygrad(
input_frame[:cam_h * stride],
matrix_inverse,
(model_w, model_h),
(cam_h, cam_w),
stride_pad,
).realize()
u = warp_perspective_tinygrad(
uv[:cam_h // 2, :cam_w:2].flatten(),
matrix_inverse_uv,
(model_w // 2, model_h // 2),
(cam_h // 2, cam_w // 2),
0,
).realize()
v = warp_perspective_tinygrad(
uv[:cam_h // 2, 1:cam_w:2].flatten(),
matrix_inverse_uv,
(model_w // 2, model_h // 2),
(cam_h // 2, cam_w // 2),
0,
).realize()
y = warp_perspective_tinygrad(input_frame[:cam_h*stride],
M_inv, (model_w, model_h),
(cam_h, cam_w), stride_pad).realize()
u = warp_perspective_tinygrad(uv[:cam_h//2, :cam_w:2].flatten(),
M_inv_uv, (model_w//2, model_h//2),
(cam_h//2, cam_w//2), 0).realize()
v = warp_perspective_tinygrad(uv[:cam_h//2, 1:cam_w:2].flatten(),
M_inv_uv, (model_w//2, model_h//2),
(cam_h//2, cam_w//2), 0).realize()
yuv = y.cat(u).cat(v).reshape((model_h * 3 // 2, model_w))
return frames_to_tensor(yuv)
tensor = frames_to_tensor(yuv)
return tensor
return frame_prepare_tinygrad
def make_tensor_inputs(vision_input_shapes, policy_input_shapes, frame_skip, device):
img = vision_input_shapes["img"]
def make_warp_input_queues(vision_input_shapes, frame_skip, device):
img = vision_input_shapes['img'] # (1, 12, 128, 256)
n_frames = img[1] // 6
img_buf_shape = (frame_skip * (n_frames - 1) + 1, 6, img[2], img[3])
features_buffer = policy_input_shapes["features_buffer"]
desire_pulse = policy_input_shapes["desire_pulse"]
return {
"img_q": Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(),
"big_img_q": Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(),
"feat_q": Tensor(
np.zeros((frame_skip * (features_buffer[1] - 1) + 1, features_buffer[0], features_buffer[2]), dtype=np.float32),
device=device,
).contiguous().realize(),
"desire_q": Tensor(
np.zeros((frame_skip * desire_pulse[1], desire_pulse[0], desire_pulse[2]), dtype=np.float32),
device=device,
).contiguous().realize(),
}
def make_npy_inputs(policy_input_shapes):
desire_pulse = policy_input_shapes["desire_pulse"]
traffic_convention = policy_input_shapes["traffic_convention"]
npy = {
"desire": np.zeros(desire_pulse[2], dtype=np.float32),
"traffic_convention": np.zeros(traffic_convention, dtype=np.float32),
"tfm": np.zeros((3, 3), dtype=np.float32),
"big_tfm": np.zeros((3, 3), dtype=np.float32),
'tfm': np.zeros((3, 3), dtype=np.float32),
'big_tfm': np.zeros((3, 3), dtype=np.float32),
}
if "action_t" in policy_input_shapes:
npy["action_t"] = np.zeros(policy_input_shapes["action_t"], dtype=np.float32)
npy_tensors = {key: Tensor(value, device="NPY").realize() for key, value in npy.items()}
return npy, npy_tensors
input_queues = {
'img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(),
'big_img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(),
**{k: Tensor(v, device='NPY').realize() for k, v in npy.items()},
}
return input_queues, npy
def make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, device):
tensor_inputs = make_tensor_inputs(vision_input_shapes, policy_input_shapes, frame_skip, device)
npy, npy_tensors = make_npy_inputs(policy_input_shapes)
return {**tensor_inputs, **npy_tensors}, npy
input_queues, npy = make_warp_input_queues(vision_input_shapes, frame_skip, device)
fb = policy_input_shapes['features_buffer'] # (1, 25, 512)
dp = policy_input_shapes['desire_pulse'] # (1, 25, 8)
tc = policy_input_shapes['traffic_convention'] # (1, 2)
#TODO action_t is hardcoded to match tc for future compatibility
at = tc
policy_npy = {
'desire': np.zeros(dp[2], dtype=np.float32),
'traffic_convention': np.zeros(tc, dtype=np.float32),
'action_t': np.zeros(at, dtype=np.float32),
}
npy.update(policy_npy)
input_queues.update({
'feat_q': Tensor(np.zeros((frame_skip * (fb[1] - 1) + 1, fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(),
'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(),
**{k: Tensor(v, device='NPY').realize() for k, v in policy_npy.items()},
})
return input_queues, npy
def shift_and_sample(buf, new_val, sample_fn):
@@ -223,44 +199,39 @@ def make_warp(nv12, model_w, model_h, frame_skip):
img = shift_and_sample(img_q, warped_frame, sample_skip_fn)
big_img = shift_and_sample(big_img_q, warped_big_frame, sample_skip_fn)
return img, big_img
return warp_enqueue
def make_run_policy(vision_runner, off_policy_runner, on_policy_runner, vision_features_slice, frame_skip):
def make_run_policy(model_runners, model_metadata, frame_skip):
sample_desire_fn = partial(sample_desire, frame_skip=frame_skip)
sample_skip_fn = partial(sample_skip, frame_skip=frame_skip)
vision_features_slice = model_metadata['vision']['output_slices']['hidden_state']
def run_policy(img, big_img, feat_q, desire_q, desire, traffic_convention, action_t):
desire = desire.to(Device.DEFAULT)
traffic_convention = traffic_convention.to(Device.DEFAULT)
action_t = action_t.to(Device.DEFAULT)
Tensor.realize(desire, traffic_convention, action_t)
desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn)
vision_out = next(iter(vision_runner({"img": img, "big_img": big_img}).values())).cast("float32")
vision_out = next(iter(model_runners['vision']({'img': img, 'big_img': big_img}).values())).cast('float32')
new_feat = vision_out[:, vision_features_slice].reshape(1, -1).unsqueeze(0)
feat_buf = shift_and_sample(feat_q, new_feat, sample_skip_fn)
inputs = {
"features_buffer": feat_buf,
"desire_pulse": desire_buf,
"traffic_convention": traffic_convention,
"action_t": action_t,
'features_buffer': feat_buf,
'desire_pulse': desire_buf,
'traffic_convention': traffic_convention,
'action_t': action_t,
}
on_policy_out = next(iter(on_policy_runner(inputs).values())).cast("float32")
off_policy_out = next(iter(off_policy_runner(inputs).values())).cast("float32")
on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32')
off_policy_out = next(iter(model_runners['off_policy'](inputs).values())).cast('float32')
return vision_out, on_policy_out, off_policy_out
return run_policy
def compile_jit(jit, make_random_inputs, input_keys, frame_skip, vision_metadata, policy_metadata):
vision_input_shapes = vision_metadata["input_shapes"]
policy_input_shapes = policy_metadata["input_shapes"]
seed = 42
def compile_jit(jit, make_random_inputs, input_keys, make_queues):
SEED = 42
validation_rtol = 5e-3 if Device.DEFAULT == "QCOM" else 0.0
validation_atol = 5e-3 if Device.DEFAULT == "QCOM" else 0.0
@@ -271,118 +242,104 @@ def compile_jit(jit, make_random_inputs, input_keys, frame_skip, vision_metadata
return np.allclose(lhs, rhs, rtol=validation_rtol, atol=validation_atol, equal_nan=True)
return np.array_equal(lhs, rhs)
def random_inputs_run(fn, current_seed, test_val=None, test_buffers=None, expect_match=True):
input_queues, npy = make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, Device.DEFAULT)
np.random.seed(current_seed)
Tensor.manual_seed(current_seed)
def random_inputs_run(fn, seed, test_val=None, test_buffers=None, expect_match=True):
input_queues, npy = make_queues(Device.DEFAULT)
np.random.seed(seed)
Tensor.manual_seed(seed)
testing = test_val is not None or test_buffers is not None
n_runs = 1 if testing else 3
for idx in range(n_runs):
for value in npy.values():
value[:] = np.random.randn(*value.shape).astype(value.dtype)
for i in range(n_runs):
for v in npy.values():
v[:] = np.random.randn(*v.shape).astype(v.dtype)
Device.default.synchronize()
random_inputs = make_random_inputs()
start = time.perf_counter()
outs = fn(**{key: input_queues[key] for key in input_keys}, **random_inputs)
mid = time.perf_counter()
st = time.perf_counter()
outs = fn(**{k: input_queues[k] for k in input_keys}, **random_inputs)
mt = time.perf_counter()
Device.default.synchronize()
end = time.perf_counter()
print(f" [{idx + 1}/{n_runs}] enqueue {(mid - start) * 1e3:6.2f} ms -- total {(end - start) * 1e3:6.2f} ms")
et = time.perf_counter()
print(f" [{i+1}/{n_runs}] enqueue {(mt-st)*1e3:6.2f} ms -- total {(et-st)*1e3:6.2f} ms")
if idx == 0:
val = [np.copy(value.numpy()) for value in outs]
buffers = [np.copy(value.numpy().copy()) for value in input_queues.values()]
if i == 0:
val = [np.copy(v.numpy()) for v in outs]
buffers = [np.copy(v.numpy().copy()) for v in input_queues.values()]
if Device.DEFAULT != "QCOM":
if test_val is not None:
match = all(arrays_match(lhs, rhs) for lhs, rhs in zip(val, test_val, strict=True))
assert match == expect_match, f"outputs {'differ from' if expect_match else 'match'} baseline (seed={current_seed})"
match = all(arrays_match(a, b) for a, b in zip(val, test_val, strict=True))
assert match == expect_match, f"outputs {'differ from' if expect_match else 'match'} baseline (seed={seed})"
if test_buffers is not None:
match = all(arrays_match(lhs, rhs) for lhs, rhs in zip(buffers, test_buffers, strict=True))
assert match == expect_match, f"buffers {'differ from' if expect_match else 'match'} baseline (seed={current_seed})"
match = all(arrays_match(a, b) for a, b in zip(buffers, test_buffers, strict=True))
assert match == expect_match, f"buffers {'differ from' if expect_match else 'match'} baseline (seed={seed})"
return val, buffers
print("capture + replay")
test_val, test_buffers = random_inputs_run(jit, seed)
print("pickle round trip")
print('capture + replay')
test_val, test_buffers = random_inputs_run(jit, SEED)
print('pickle round trip')
jit = pickle.loads(pickle.dumps(jit))
random_inputs_run(jit, seed, test_val, test_buffers, expect_match=True)
random_inputs_run(jit, seed + 1, test_val, test_buffers, expect_match=False)
random_inputs_run(jit, SEED, test_val, test_buffers, expect_match=True)
random_inputs_run(jit, SEED+1, test_val, test_buffers, expect_match=False)
return jit
def _parse_size(size):
width, height = size.lower().split("x")
return int(width), int(height)
def _parse_size(s):
w, h = s.lower().split('x')
return int(w), int(h)
def read_file_chunked_to_shm(path):
from openpilot.common.file_chunker import read_file_chunked
from openpilot.system.hardware.hw import Paths
shm_path = os.path.join(Paths.shm_path(), os.path.basename(path))
atexit.register(lambda: os.path.exists(shm_path) and os.remove(shm_path))
with open(shm_path, "wb") as f:
with open(shm_path, 'wb') as f:
f.write(read_file_chunked(path))
return shm_path
if __name__ == "__main__":
from tinygrad.nn.onnx import OnnxRunner
from openpilot.selfdrive.modeld.get_model_metadata import make_metadata_dict
from openpilot.system.camerad.cameras.nv12_info import get_nv12_info
from openpilot.selfdrive.modeld.get_model_metadata import make_metadata_dict
p = argparse.ArgumentParser()
p.add_argument('--model-size', type=_parse_size, required=True, help='model input WxH')
p.add_argument('--camera-resolutions', type=_parse_size, nargs='+', required=True,
help='camera resolutions WxH (one or more)')
p.add_argument('--vision-onnx', required=True)
p.add_argument('--off-policy-onnx', required=True)
p.add_argument('--on-policy-onnx', required=True)
p.add_argument('--output', required=True)
p.add_argument('--frame-skip', type=int, required=True)
args = p.parse_args()
parser = argparse.ArgumentParser()
parser.add_argument("--model-size", type=_parse_size, required=True, help="model input WxH")
parser.add_argument("--camera-resolutions", type=_parse_size, nargs="+", required=True, help="camera resolutions WxH (one or more)")
parser.add_argument("--vision-onnx", required=True)
parser.add_argument("--off-policy-onnx", required=True)
parser.add_argument("--on-policy-onnx", required=True)
parser.add_argument("--output", required=True)
parser.add_argument("--frame-skip", type=int, required=True)
args = parser.parse_args()
out = defaultdict(dict)
vision_path = read_file_chunked_to_shm(args.vision_onnx)
off_policy_path = read_file_chunked_to_shm(args.off_policy_onnx)
on_policy_path = read_file_chunked_to_shm(args.on_policy_onnx)
model_paths = {
'vision': read_file_chunked_to_shm(args.vision_onnx),
'off_policy': read_file_chunked_to_shm(args.off_policy_onnx),
'on_policy': read_file_chunked_to_shm(args.on_policy_onnx),
}
model_w, model_h = args.model_size
vision_runner = OnnxRunner(vision_path)
off_policy_runner = OnnxRunner(off_policy_path)
on_policy_runner = OnnxRunner(on_policy_path)
vision_metadata = make_metadata_dict(vision_path)
off_policy_metadata = make_metadata_dict(off_policy_path)
on_policy_metadata = make_metadata_dict(on_policy_path)
assert off_policy_metadata["input_shapes"] == on_policy_metadata["input_shapes"]
model_runners = {name: OnnxRunner(path) for name, path in model_paths.items()}
out = {'metadata': {name: make_metadata_dict(path) for name, path in model_paths.items()}}
run_policy_jit = TinyJit(
make_run_policy(
vision_runner,
off_policy_runner,
on_policy_runner,
vision_metadata["output_slices"]["hidden_state"],
args.frame_skip,
),
prune=True,
)
assert out['metadata']['off_policy']['input_shapes'] == out['metadata']['on_policy']['input_shapes']
out["metadata"]["vision"] = vision_metadata
out["metadata"]["off_policy"] = off_policy_metadata
out["metadata"]["on_policy"] = on_policy_metadata
out["tensor_inputs"] = make_tensor_inputs(vision_metadata["input_shapes"], on_policy_metadata["input_shapes"], args.frame_skip, Device.DEFAULT)
run_policy_jit = TinyJit(make_run_policy(model_runners, out['metadata'], args.frame_skip), prune=True)
make_random_model_inputs = partial(make_random_images, keys=["img", "big_img"], shape=vision_metadata["input_shapes"]["img"])
out["run_policy"] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, args.frame_skip, vision_metadata, on_policy_metadata)
make_policy_queues = partial(make_input_queues, out['metadata']['vision']['input_shapes'],
out['metadata']['on_policy']['input_shapes'], args.frame_skip)
make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['vision']['input_shapes']['img'])
out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS,
make_policy_queues)
for cam_w, cam_h in args.camera_resolutions:
nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h))
# Capture warp against blob-backed frames so the JIT ABI matches runtime VisionBuf inputs.
make_random_warp_inputs = partial(make_random_blob_images, keys=["frame", "big_frame"], shape=nv12.size, device=WARP_DEV)
make_random_warp_inputs = make_random_blob_images(keys=['frame', 'big_frame'], size=nv12.size, device=WARP_DEV)
warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True)
out[(cam_w, cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, args.frame_skip, vision_metadata, on_policy_metadata)
make_warp_queues = partial(make_warp_input_queues, out['metadata']['vision']['input_shapes'], args.frame_skip)
out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues)
with open(args.output, "wb") as f:
pickle.dump(out, f)

Some files were not shown because too many files have changed in this diff Show More