diff --git a/.gitignore b/.gitignore index d7bdf08d9..57c4c0258 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ a.out *.class *.pyxbldc *.vcd - +*.qm config.json clcache compile_commands.json diff --git a/README.md b/README.md index 3999235a3..bb1534527 100755 --- a/README.md +++ b/README.md @@ -42,8 +42,9 @@ I encourage users to consider purchasing a [comma 3](https://shop.comma.ai) for * Services are not optimized for resource usage, and using all services may result in overheating issues. * Language files can only be generated in a PC due to missing Qt5 tools. * webjoystick is disabled as it requires additional python modules. (aiohttp and others) -* Starting from August 7th, 2023, comma has removed ESP/GPS support from Pandas. You can find more details about this change in this link. +* Starting from August 7th, 2023, comma has removed ESP/GPS support from Pandas. You can find more details about this change in this [link](https://github.com/commaai/panda/commit/c66b98b2a67441faa4cfcd36c3c9d9f90474cd08). * Going forward, I will focus solely on maintaining the safety aspects of the code, ensuring that vehicle support and safety declarations remain up to date. +* For safety concern, End-to-End / vision only longitudinal control only available in 0.8.16 driving model. ## Configuration diff --git a/cereal/visionipc/visionipc_pyx.so b/cereal/visionipc/visionipc_pyx.so index 2ac0509a2..532ad5697 100755 Binary files a/cereal/visionipc/visionipc_pyx.so and b/cereal/visionipc/visionipc_pyx.so differ diff --git a/common/kalman/simple_kalman.py b/common/kalman/simple_kalman.py index 31ad76c5b..cd3b5a1df 100644 --- a/common/kalman/simple_kalman.py +++ b/common/kalman/simple_kalman.py @@ -1,3 +1,12 @@ -# pylint: skip-file from openpilot.common.kalman.simple_kalman_impl import KF1D as KF1D assert KF1D +import numpy as np + +def get_kalman_gain(dt, A, C, Q, R, iterations=100): + P = np.zeros_like(Q) + for _ in range(iterations): + P = A.dot(P).dot(A.T) + dt * Q + S = C.dot(P).dot(C.T) + R + K = P.dot(C.T).dot(np.linalg.inv(S)) + P = (np.eye(len(P)) - K.dot(C)).dot(P) + return K diff --git a/common/params_pyx.so b/common/params_pyx.so index cea41c313..200ffc8a5 100755 Binary files a/common/params_pyx.so and b/common/params_pyx.so differ diff --git a/common/version.h b/common/version.h index 1b7d313db..728f44ec6 100644 --- a/common/version.h +++ b/common/version.h @@ -1 +1 @@ -#define COMMA_VERSION "2023.09.19" +#define COMMA_VERSION "2023.11.23" diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index c1353dff8..d07002822 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -195,6 +195,12 @@ function two_init { echo "Installing spidev.cpython-38.so..." cp -f "$LIB_PATH/spidev.cpython-38.so" "$PY_LIB_DEST/" fi + # StrEnum in values.py + MODULE="strenum" + if [ ! -d "$PY_LIB_DEST/$MODULE" ]; then + echo "Installing $MODULE..." + tar -zxvf "$LIB_PATH/$MODULE.tar.gz" -C "$PY_LIB_DEST/" + fi mount -o remount,r /system # osm server diff --git a/launch_env.sh b/launch_env.sh index baf1a0a3a..afa5c4107 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="8.2" + export AGNOS_VERSION="7.1" fi if [ -z "$REQUIRED_NEOS_VERSION" ]; then diff --git a/opendbc/Dockerfile b/opendbc/Dockerfile index f1eecae1c..59e7bc438 100644 --- a/opendbc/Dockerfile +++ b/opendbc/Dockerfile @@ -49,9 +49,9 @@ RUN git config --global --add safe.directory '*' WORKDIR /project RUN git clone https://github.com/commaai/cereal.git /project/cereal && \ cd /project/cereal && \ - git checkout aed9fd278a704816aba11f4473aafefc281ed2bc && \ + git checkout 82bca3a9714b73c05414fdf848b6016a0ffac17d && \ rm -rf .git && \ - scons -j$(nproc) + scons -j$(nproc) --minimal COPY SConstruct . COPY ./site_scons /project/site_scons diff --git a/opendbc/can/common.pxd b/opendbc/can/common.pxd index 4f62ba2a1..477f71b2d 100644 --- a/opendbc/can/common.pxd +++ b/opendbc/can/common.pxd @@ -67,7 +67,7 @@ cdef extern from "common.h": cdef cppclass CANParser: bool can_valid bool bus_timeout - CANParser(int, string, vector[pair[uint32_t, int]]) + CANParser(int, string, vector[pair[uint32_t, int]]) except + void update_strings(vector[string]&, vector[SignalValue]&, bool) except + cdef cppclass CANPacker: diff --git a/opendbc/can/common_dbc.h b/opendbc/can/common_dbc.h index e8c27278c..ef4c98c80 100644 --- a/opendbc/can/common_dbc.h +++ b/opendbc/can/common_dbc.h @@ -5,8 +5,6 @@ #include #include -#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) - struct SignalPackValue { std::string name; double value; diff --git a/opendbc/can/libdbc.so b/opendbc/can/libdbc.so index f081f4ab2..2633a863f 100755 Binary files a/opendbc/can/libdbc.so and b/opendbc/can/libdbc.so differ diff --git a/opendbc/can/packer_pyx.so b/opendbc/can/packer_pyx.so index 843ab9e9b..6eedc0e13 100755 Binary files a/opendbc/can/packer_pyx.so and b/opendbc/can/packer_pyx.so differ diff --git a/opendbc/can/parser_pyx.so b/opendbc/can/parser_pyx.so index f0c000ac9..aaa9f0120 100755 Binary files a/opendbc/can/parser_pyx.so and b/opendbc/can/parser_pyx.so differ diff --git a/opendbc/generator/gm/gm_global_a_powertrain.dbc b/opendbc/generator/gm/gm_global_a_powertrain.dbc index a453db41f..fbe0bd397 100644 --- a/opendbc/generator/gm/gm_global_a_powertrain.dbc +++ b/opendbc/generator/gm/gm_global_a_powertrain.dbc @@ -156,12 +156,13 @@ BO_ 489 EBCMVehicleDynamic: 8 K17_EBCM SG_ YawRate : 35|12@0- (0.625,0) [0|1] "" NEO SG_ YawRate2 : 51|12@0- (0.0625,0) [-2047|2047] "grad/s" NEO -BO_ 352 VehicleIgnition: 5 XXX - SG_ Ignition : 7|32@0+ (1,0) [0|4294967295] "" XXX +BO_ 352 BCMImmobilizer: 5 K9_BCM + SG_ ImmobilizerInfo : 7|32@0+ (1,0) [0|4294967295] "" XXX -BO_ 497 VehicleIgnitionAlt: 8 XXX - SG_ Ignition : 5|1@0+ (1,0) [0|1] "" XXX - SG_ ParkBrake : 36|1@0+ (1,0) [0|3] "" XXX +BO_ 497 BCMGeneralPlatformStatus: 8 K9_BCM + SG_ SystemPowerMode : 1|2@0+ (1,0) [0|3] "" XXX + SG_ SystemBackUpPowerMode : 5|2@0+ (1,0) [0|3] "" XXX + SG_ ParkBrakeSwActive : 36|1@0+ (1,0) [0|3] "" XXX BO_ 501 ECMPRDNL2: 8 K20_ECM SG_ TransmissionState : 48|4@1+ (1,0) [0|7] "" NEO @@ -174,7 +175,7 @@ BO_ 532 BRAKE_RELATED: 6 XXX BO_ 560 EPBStatus: 8 EPB SG_ EPBClosed : 12|1@0+ (1,0) [0|1] "" NEO -BO_ 562 EBCMFrictionBrakeStatus: 8 XXX +BO_ 562 EBCMFrictionBrakeStatus: 8 K17_EBCM SG_ FrictionBrakeUnavailable : 46|1@0+ (1,0) [0|1] "" XXX BO_ 608 SPEED_RELATED: 8 XXX @@ -296,11 +297,12 @@ CM_ BU_ K124_ASCM "Active Safety Control Module"; CM_ SG_ 381 MSG17D_AccPower "Need to investigate"; CM_ BO_ 190 "Length varies from 6 to 8 bytes by car"; CM_ SG_ 190 GasPedalAndAcc "ACC baseline is 62"; -CM_ SG_ 352 Ignition "Non-zero when ignition is on"; +CM_ SG_ 352 ImmobilizerInfo "Non-zero when ignition or accessory mode"; CM_ SG_ 451 GasPedalAndAcc2 "ACC baseline is 62"; CM_ SG_ 481 ACCAlwaysOne "Usually 1 if the car is equipped with ACC"; CM_ SG_ 562 FrictionBrakeUnavailable "1 when ACC brake control is unavailable. Stays high if brake command messages are blocked for a period of time"; -CM_ SG_ 497 Ignition "Describes ignition + preconditioning mode, noisy"; +CM_ SG_ 497 SystemPowerMode "Describes ignition"; +CM_ SG_ 497 SystemBackUpPowerMode "Describes ignition + preconditioning mode, noisy"; CM_ SG_ 501 PRNDL2 "When ManualMode is Active, Value is 13=L1 12=L2 11=L3 ... 4=L10"; CM_ SG_ 532 UserBrakePressure "can be lower than other brake position signals when the brakes are pre-filled from ACC braking and the user presses on the brakes. user-only pressure?"; CM_ SG_ 608 ClusterSpeed "Cluster speed signal seems to match dash on newer cars, but is a lower rate and can be noisier."; @@ -315,6 +317,8 @@ BA_DEF_DEF_ "BusType" ""; BA_ "BusType" "CAN"; BA_ "ProtocolType" "GMLAN"; BA_ "UseGMParameterIDs" 0; +VAL_ 497 SystemPowerMode 3 "Crank Request" 2 "Run" 1 "Accessory" 0 "Off"; +VAL_ 497 SystemBackUpPowerMode 3 "Crank Request" 2 "Run" 1 "Accessory" 0 "Off"; VAL_ 481 DistanceButton 1 "Active" 0 "Inactive" ; VAL_ 481 LKAButton 1 "Active" 0 "Inactive" ; VAL_ 481 ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; diff --git a/opendbc/generator/subaru/_subaru_global.dbc b/opendbc/generator/subaru/_subaru_global.dbc index 030ddc837..ed79d4777 100644 --- a/opendbc/generator/subaru/_subaru_global.dbc +++ b/opendbc/generator/subaru/_subaru_global.dbc @@ -242,6 +242,14 @@ BO_ 802 ES_LKAS_State: 8 XXX SG_ LKAS_Alert : 32|5@1+ (1,0) [0|31] "" XXX SG_ Signal3 : 37|27@1+ (1,0) [0|1] "" XXX +BO_ 803 ES_Infotainment: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX + SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX + SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX + BO_ 722 AC_State: 8 XXX SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX diff --git a/opendbc/generator/subaru/_subaru_preglobal_2015.dbc b/opendbc/generator/subaru/_subaru_preglobal_2015.dbc index 060efea00..2cc56e1d4 100644 --- a/opendbc/generator/subaru/_subaru_preglobal_2015.dbc +++ b/opendbc/generator/subaru/_subaru_preglobal_2015.dbc @@ -123,10 +123,11 @@ BO_ 338 Stalk: 8 XXX BO_ 352 ES_Brake: 8 XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX - SG_ Brake_Light : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Lights : 20|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Fault : 21|1@1+ (1,0) [0|1] "" XXX - SG_ Brake_On : 22|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 22|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 23|1@1+ (1,0) [0|1] "" XXX + SG_ SET_1 : 45|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX @@ -135,7 +136,7 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal1 : 12|4@1+ (1,0) [0|15] "" XXX SG_ Car_Follow : 16|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 17|3@1+ (1,0) [0|7] "" XXX - SG_ Brake_On : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 20|1@1+ (1,0) [0|1] "" XXX SG_ Distance_Swap : 21|1@1+ (1,0) [0|1] "" XXX SG_ Standstill : 22|1@1+ (1,0) [0|1] "" XXX SG_ Signal3 : 23|1@1+ (1,0) [0|1] "" XXX @@ -150,10 +151,10 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal7 : 51|5@1+ (1,0) [0|31] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX -BO_ 354 ES_RPM: 8 XXX +BO_ 354 ES_Status: 8 XXX SG_ Brake : 8|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 9|1@1+ (1,0) [0|1] "" XXX - SG_ RPM : 16|16@1+ (1,0) [0|65535] "" XXX + SG_ Cruise_RPM : 16|16@1+ (1,0) [0|65535] "" XXX SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX diff --git a/opendbc/generator/subaru/subaru_global_2017.dbc b/opendbc/generator/subaru/subaru_global_2017.dbc index bef6e224f..62c7934b7 100644 --- a/opendbc/generator/subaru/subaru_global_2017.dbc +++ b/opendbc/generator/subaru/subaru_global_2017.dbc @@ -53,14 +53,6 @@ BO_ 576 CruiseControl: 8 XXX SG_ Cruise_Activated : 41|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 42|22@1+ (1,0) [0|4194303] "" XXX -BO_ 803 ES_Infotainment: 8 XXX - SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX - SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX - SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX - SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX - SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX - SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX - CM_ SG_ 545 Cruise_Throttle "RPM-like output signal"; CM_ SG_ 545 Cruise_EPB "1 = Electric Parking Brake set"; CM_ SG_ 545 Distance_Swap "Switch from Close to Far distance"; diff --git a/opendbc/gm_global_a_powertrain_generated.dbc b/opendbc/gm_global_a_powertrain_generated.dbc index d83f035dc..6ecb36f2f 100644 --- a/opendbc/gm_global_a_powertrain_generated.dbc +++ b/opendbc/gm_global_a_powertrain_generated.dbc @@ -176,12 +176,13 @@ BO_ 489 EBCMVehicleDynamic: 8 K17_EBCM SG_ YawRate : 35|12@0- (0.625,0) [0|1] "" NEO SG_ YawRate2 : 51|12@0- (0.0625,0) [-2047|2047] "grad/s" NEO -BO_ 352 VehicleIgnition: 5 XXX - SG_ Ignition : 7|32@0+ (1,0) [0|4294967295] "" XXX +BO_ 352 BCMImmobilizer: 5 K9_BCM + SG_ ImmobilizerInfo : 7|32@0+ (1,0) [0|4294967295] "" XXX -BO_ 497 VehicleIgnitionAlt: 8 XXX - SG_ Ignition : 5|1@0+ (1,0) [0|1] "" XXX - SG_ ParkBrake : 36|1@0+ (1,0) [0|3] "" XXX +BO_ 497 BCMGeneralPlatformStatus: 8 K9_BCM + SG_ SystemPowerMode : 1|2@0+ (1,0) [0|3] "" XXX + SG_ SystemBackUpPowerMode : 5|2@0+ (1,0) [0|3] "" XXX + SG_ ParkBrakeSwActive : 36|1@0+ (1,0) [0|3] "" XXX BO_ 501 ECMPRDNL2: 8 K20_ECM SG_ TransmissionState : 48|4@1+ (1,0) [0|7] "" NEO @@ -194,7 +195,7 @@ BO_ 532 BRAKE_RELATED: 6 XXX BO_ 560 EPBStatus: 8 EPB SG_ EPBClosed : 12|1@0+ (1,0) [0|1] "" NEO -BO_ 562 EBCMFrictionBrakeStatus: 8 XXX +BO_ 562 EBCMFrictionBrakeStatus: 8 K17_EBCM SG_ FrictionBrakeUnavailable : 46|1@0+ (1,0) [0|1] "" XXX BO_ 608 SPEED_RELATED: 8 XXX @@ -316,11 +317,12 @@ CM_ BU_ K124_ASCM "Active Safety Control Module"; CM_ SG_ 381 MSG17D_AccPower "Need to investigate"; CM_ BO_ 190 "Length varies from 6 to 8 bytes by car"; CM_ SG_ 190 GasPedalAndAcc "ACC baseline is 62"; -CM_ SG_ 352 Ignition "Non-zero when ignition is on"; +CM_ SG_ 352 ImmobilizerInfo "Non-zero when ignition or accessory mode"; CM_ SG_ 451 GasPedalAndAcc2 "ACC baseline is 62"; CM_ SG_ 481 ACCAlwaysOne "Usually 1 if the car is equipped with ACC"; CM_ SG_ 562 FrictionBrakeUnavailable "1 when ACC brake control is unavailable. Stays high if brake command messages are blocked for a period of time"; -CM_ SG_ 497 Ignition "Describes ignition + preconditioning mode, noisy"; +CM_ SG_ 497 SystemPowerMode "Describes ignition"; +CM_ SG_ 497 SystemBackUpPowerMode "Describes ignition + preconditioning mode, noisy"; CM_ SG_ 501 PRNDL2 "When ManualMode is Active, Value is 13=L1 12=L2 11=L3 ... 4=L10"; CM_ SG_ 532 UserBrakePressure "can be lower than other brake position signals when the brakes are pre-filled from ACC braking and the user presses on the brakes. user-only pressure?"; CM_ SG_ 608 ClusterSpeed "Cluster speed signal seems to match dash on newer cars, but is a lower rate and can be noisier."; @@ -335,6 +337,8 @@ BA_DEF_DEF_ "BusType" ""; BA_ "BusType" "CAN"; BA_ "ProtocolType" "GMLAN"; BA_ "UseGMParameterIDs" 0; +VAL_ 497 SystemPowerMode 3 "Crank Request" 2 "Run" 1 "Accessory" 0 "Off"; +VAL_ 497 SystemBackUpPowerMode 3 "Crank Request" 2 "Run" 1 "Accessory" 0 "Off"; VAL_ 481 DistanceButton 1 "Active" 0 "Inactive" ; VAL_ 481 LKAButton 1 "Active" 0 "Inactive" ; VAL_ 481 ACCButtons 6 "Cancel" 5 "Main" 3 "Set" 2 "Resume" 1 "None" ; diff --git a/opendbc/hyundai_canfd.dbc b/opendbc/hyundai_canfd.dbc index f873a4b41..8d2759452 100644 --- a/opendbc/hyundai_canfd.dbc +++ b/opendbc/hyundai_canfd.dbc @@ -65,7 +65,7 @@ BO_ 80 LKAS: 16 XXX SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_1 : 80|1@0+ (1,0) [0|1] "" XXX + SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_3 : 111|8@0+ (1,0) [0|255] "" XXX SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX @@ -137,7 +137,7 @@ BO_ 272 LKAS_ALT: 32 XXX SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_1 : 80|1@0+ (1,0) [0|1] "" XXX + SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_3 : 111|8@0+ (1,0) [0|255] "" XXX SG_ FCA_SYSWARN : 40|1@0+ (1,0) [0|1] "" XXX @@ -160,7 +160,7 @@ BO_ 298 LFA: 16 ADRV SG_ LKA_ASSIST : 62|1@1+ (1,0) [0|1] "" XXX SG_ LKA_MODE : 24|3@1+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_2 : 70|2@0+ (1,0) [0|3] "" XXX - SG_ SET_ME_1 : 80|1@0+ (1,0) [0|1] "" XXX + SG_ HAS_LANE_SAFETY : 80|1@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_3 : 111|8@0+ (1,0) [0|255] "" XXX BO_ 304 GEAR_SHIFTER: 16 XXX @@ -470,7 +470,10 @@ BO_ 676 CAM_0x2a4: 24 XXX SG_ BYTE4 : 32|8@1+ (1,0) [0|255] "" XXX SG_ BYTE5 : 40|8@1+ (1,0) [0|255] "" XXX SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX - SG_ BYTE7 : 56|8@1+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_LINE : 56|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0 : 58|2@1+ (1,0) [0|3] "" XXX + SG_ RIGHT_LANE_LINE : 60|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0_2 : 62|2@1+ (1,0) [0|3] "" XXX SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX @@ -504,11 +507,55 @@ BO_ 702 CAM_0x2be: 32 CAMERA SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX +BO_ 736 MANUAL_SPEED_LIMIT_ASSIST: 32 XXX + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ MSLA_STATUS : 26|2@1+ (1,0) [0|3] "" XXX + SG_ MSLA_ENABLED : 38|1@1+ (1,0) [0|1] "" XXX + SG_ MAX_SPEED : 55|8@0+ (1,0) [0|255] "" XXX + SG_ MAX_SPEED_COPY : 144|8@1+ (1,0) [0|255] "" XXX + BO_ 837 ADRV_0x345: 8 ADRV SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX SG_ SET_ME_15 : 24|8@1+ (1,0) [0|255] "" XXX +BO_ 866 CAM_0x362: 32 CAMERA + SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX + SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE3 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE4 : 32|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE5 : 40|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE6 : 48|8@1+ (1,0) [0|255] "" XXX + SG_ LEFT_LANE_LINE : 56|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0 : 58|2@1+ (1,0) [0|3] "" XXX + SG_ RIGHT_LANE_LINE : 60|2@1+ (1,0) [0|3] "" XXX + SG_ SET_ME_0_2 : 62|2@1+ (1,0) [0|3] "" XXX + SG_ BYTE8 : 64|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE9 : 72|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE10 : 80|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE11 : 88|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE12 : 96|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE13 : 104|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE14 : 112|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE15 : 120|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE16 : 128|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE17 : 136|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE18 : 144|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE19 : 152|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE20 : 160|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE21 : 168|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE22 : 176|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE23 : 184|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE24 : 192|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE25 : 200|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE26 : 208|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE27 : 216|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE28 : 224|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE29 : 232|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE30 : 240|8@1+ (1,0) [0|255] "" XXX + SG_ BYTE31 : 248|8@1+ (1,0) [0|255] "" XXX + BO_ 961 BLINKER_STALKS: 8 XXX SG_ COUNTER_ALT : 15|4@0+ (1,0) [0|15] "" XXX SG_ CHECKSUM_MAYBE : 7|8@0+ (1,0) [0|255] "" XXX @@ -534,6 +581,9 @@ BO_ 1043 BLINKERS: 8 XXX SG_ COUNTER_ALT : 15|4@0+ (1,0) [0|15] "" XXX SG_ LEFT_LAMP : 20|1@0+ (1,0) [0|1] "" XXX SG_ RIGHT_LAMP : 22|1@0+ (1,0) [0|1] "" XXX + SG_ LEFT_LAMP_ALT : 59|1@0+ (1,0) [0|1] "" XXX + SG_ RIGHT_LAMP_ALT : 61|1@0+ (1,0) [0|1] "" XXX + SG_ USE_ALT_LAMP : 62|1@0+ (1,0) [0|1] "" XXX BO_ 1240 CLUSTER_INFO: 8 XXX SG_ DISTANCE_UNIT : 0|1@1+ (1,0) [0|1] "" XXX @@ -609,8 +659,11 @@ BO_ 1264 LOCAL_TIME: 8 XXX SG_ SECONDS : 31|8@0+ (1,0) [0|59] "" XXX CM_ 272 "Alternative LKAS message, used on cars such as 2023 Ioniq 6, 2nd gen Kona. Matches LKAS except size is 32 bytes"; +CM_ 676 "Contains signals with detailed lane line information. Used by ADAS ECU on HDA 2 vehicles to operate LFA."; +CM_ 866 "Contains signals with detailed lane line information. Used by ADAS ECU on HDA 2 vehicles to operate LFA. Used on cars that use message 272."; CM_ 1043 "Lamp signals do not seem universal on cars that use LKAS_ALT, but stalk signals do."; +CM_ SG_ 80 HAS_LANE_SAFETY "If 0, hides LKAS 'Lane Safety' menu from vehicle settings"; CM_ SG_ 96 BRAKE_PRESSURE "User applied brake pedal pressure. Ramps from computer applied pressure on falling edge of cruise. Cruise cancels if !=0"; CM_ SG_ 101 BRAKE_POSITION "User applied brake pedal position, max is ~700. Signed on some vehicles"; CM_ SG_ 373 PROBABLY_EQUIP "aeb equip?"; @@ -619,9 +672,15 @@ CM_ SG_ 373 DriverBraking "Likely derived from BRAKE->BRAKE_POSITION"; CM_ SG_ 373 DriverBrakingLowSens "Higher threshold version of DriverBraking"; CM_ SG_ 352 SET_ME_9 "has something to do with AEB settings"; CM_ SG_ 416 VSetDis "set speed in display units"; +CM_ SG_ 676 LEFT_LANE_LINE "Left lane line confidence"; +CM_ SG_ 676 RIGHT_LANE_LINE "Right lane line confidence"; +CM_ SG_ 736 MAX_SPEED "Display units. Restricts car from driving above this speed unless accelerator pedal is depressed beyond pressure point"; +CM_ SG_ 866 LEFT_LANE_LINE "Left lane line confidence"; +CM_ SG_ 866 RIGHT_LANE_LINE "Right lane line confidence"; CM_ SG_ 961 COUNTER_ALT "only increments on change"; CM_ SG_ 1041 COUNTER_ALT "only increments on change"; CM_ SG_ 1043 COUNTER_ALT "only increments on change"; +CM_ SG_ 1043 USE_ALT_LAMP "likely 1 on cars that use alt lamp signals"; VAL_ 53 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ; VAL_ 64 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ; VAL_ 69 GEAR 0 "P" 5 "D" 6 "N" 7 "R" ; @@ -645,6 +704,11 @@ VAL_ 426 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 VAL_ 463 CRUISE_BUTTONS 0 "none" 1 "res_accel" 2 "set_decel" 3 "gap_distance" 4 "pause_resume" ; VAL_ 463 RIGHT_PADDLE 0 "Not Pulled" 1 "Pulled"; VAL_ 463 LEFT_PADDLE 0 "Not Pulled" 1 "Pulled"; +VAL_ 676 LEFT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; +VAL_ 676 RIGHT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; +VAL_ 736 MSLA_STATUS 0 "disabled" 1 "active" 2 "paused"; +VAL_ 866 LEFT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; +VAL_ 866 RIGHT_LANE_LINE 0 "Not Detected" 1 "Low Confidence" 2 "Medium Confidence" 3 "High Confidence"; VAL_ 1041 DRIVER_DOOR 0 "Closed" 1 "Opened"; VAL_ 1041 PASSENGER_DOOR 0 "Closed" 1 "Opened"; VAL_ 1041 DRIVER_REAR_DOOR 0 "Closed" 1 "Opened"; diff --git a/opendbc/hyundai_kia_generic.dbc b/opendbc/hyundai_kia_generic.dbc index f1af8f9d2..3031c4bc2 100644 --- a/opendbc/hyundai_kia_generic.dbc +++ b/opendbc/hyundai_kia_generic.dbc @@ -1645,6 +1645,7 @@ BO_ 1348 Navi_HU: 8 XXX CM_ "BO_ E_EMS11: All (plug-in) hybrids use this gas signal: CR_Vcu_AccPedDep_Pos, and all EVs use the Accel_Pedal_Pos signal. See hyundai/values.py for a specific car list"; CM_ SG_ 871 CF_Lvr_IsgState "Idle Stop and Go"; +CM_ SG_ 1056 SCCInfoDisplay "Goes to 1 for a second while transitioning from Cruise Control to No Message"; CM_ SG_ 1348 SpeedLim_Nav_Clu "Speed limit displayed on Nav, Cluster and HUD"; VAL_ 274 CUR_GR 1 "D" 2 "D" 3 "D" 4 "D" 5 "D" 6 "D" 7 "D" 8 "D" 14 "R" 0 "P"; @@ -1654,6 +1655,7 @@ VAL_ 882 Elect_Gear_Shifter 5 "D" 8 "S" 6 "N" 7 "R" 0 "P"; VAL_ 905 ACCMode 0 "off" 1 "enabled" 2 "driver_override" 3 "off_maybe_fault" 4 "cancelled"; VAL_ 909 CF_VSM_Warn 2 "FCW" 3 "AEB"; VAL_ 916 ACCEnable 0 "SCC ready" 1 "SCC temp fault" 2 "SCC permanent fault" 3 "SCC permanent fault, communication issue"; +VAL_ 1056 SCCInfoDisplay 0 "No Message" 2 "Cruise Control" 3 "Lost Lead" 4 "Standstill"; VAL_ 1057 ACCMode 0 "off" 1 "enabled" 2 "driver_override" 3 "off_maybe_fault"; VAL_ 1157 HDA_Icon_State 0 "no_hda" 1 "white_hda" 2 "green_hda"; VAL_ 1157 LFA_SysWarning 0 "no_message" 1 "switching_to_hda" 2 "switching_to_scc" 3 "lfa_error" 4 "check_hda" 5 "keep_hands_on_wheel_orange" 6 "keep_hands_on_wheel_red"; diff --git a/opendbc/mazda_2017.dbc b/opendbc/mazda_2017.dbc index 5a5c40ef0..a6f6e80d2 100644 --- a/opendbc/mazda_2017.dbc +++ b/opendbc/mazda_2017.dbc @@ -224,6 +224,8 @@ BO_ 1088 CAM_LANEINFO: 8 XXX SG_ LINE_VISIBLE : 0|1@0+ (1,0) [0|3] "" XXX SG_ LDW_WARN_RL : 58|1@0+ (1,0) [0|1] "" XXX SG_ LDW_WARN_LL : 57|1@0+ (1,0) [0|1] "" XXX + SG_ TJA : 38|3@0+ (1,0) [0|7] "" XXX + SG_ TJA_TRANSITION : 27|2@0+ (1,0) [0|63] "" XXX BO_ 1479 NEW_MSG_470: 8 XXX @@ -569,6 +571,8 @@ BO_ 535 CURVE_CTRS: 8 XXX BO_ 540 CRZ_CTRL: 8 XXX SG_ NEW_SIGNAL_6 : 10|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_9 : 31|1@0+ (1,0) [0|255] "" XXX + SG_ ACC_GAS_MAYBE2 : 29|1@0+ (1,0) [0|1] "" XXX SG_ HANDS_OFF_STEERING : 48|1@0+ (1,0) [0|1] "" XXX SG_ HANDS_ON_STEER_WARN : 59|4@0+ (1,0) [0|255] "" XXX SG_ CRZ_ACTIVE : 3|1@0+ (1,0) [0|1] "" XXX @@ -576,7 +580,9 @@ BO_ 540 CRZ_CTRL: 8 XXX SG_ DISTANCE_SETTING : 20|3@0+ (1,0) [0|7] "" XXX SG_ MSG_1_INV : 1|1@0+ (1,0) [0|1] "" XXX SG_ MSG_1_COPY : 9|1@0+ (1,0) [0|1] "" XXX + SG_ ACC_GAS_MAYBE : 23|1@0+ (1,0) [0|31] "" XXX SG_ ACC_ACTIVE_2 : 52|1@0+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_10 : 30|1@0+ (1,0) [0|1] "" XXX SG_ MSG_1 : 0|1@0+ (1,0) [0|3] "" XXX SG_ 5_SEC_DISABLE_TIMER : 45|3@0+ (1,0) [0|7] "" XXX SG_ NEW_SIGNAL_3 : 13|1@0+ (1,0) [0|3] "" XXX @@ -716,6 +722,12 @@ BO_ 1143 BSM: 8 XXX SG_ NEW_SIGNAL_1 : 32|1@0+ (1,0) [0|1] "" XXX SG_ REAR_CT_ALERT : 23|5@0+ (1,0) [0|63] "" XXX +BO_ 480 ACCEL_TEST: 8 XXX + SG_ ACCEL_COMMAND : 7|32@0- (1,0) [-2147483647|2147483647] "" XXX + SG_ ENABLED : 32|1@0+ (1,0) [0|1] "" XXX + SG_ STARTING : 40|1@0+ (1,0) [0|1] "" XXX + SG_ STOPPING : 48|1@0+ (1,0) [0|1] "" XXX + BO_ 1361 KEY_POSITION: 8 XXX BO_ 1283 KEY_POSITION2: 8 XXX @@ -775,6 +787,8 @@ CM_ SG_ 1157 LKAS_SENSETIVITY "0 low, 1 high"; CM_ SG_ 1157 LANEE_DEPARTURE_ALERT "1 off, 2 on"; CM_ SG_ 1157 WARNING "1 Rare, 0 often"; CM_ SG_ 1088 LANE_LINES "0 LKAS disabled, 1 no lines, 2 two lines, 3 left line, 4 right line"; +CM_ SG_ 1088 TJA "2: crz not active, 3: TJA not allowed, 4: TJA allowed"; +CM_ SG_ 1088 TJA_TRANSITION "3: if TJA signal is 3, otherwise set to 0"; CM_ SG_ 1045 ABS_MALFUNCTION "off: 0, solid: 1, slow blink: 2, fast blink: 3"; CM_ SG_ 120 VEHICLE_ACC_X "Vehicle acceleration of X-axis wrt. NED frame."; CM_ SG_ 120 VEHICLE_ACC_Y "Vehicle acceleration of Y-axis wrt. NED frame."; diff --git a/opendbc/subaru_forester_2017_generated.dbc b/opendbc/subaru_forester_2017_generated.dbc index 1455c691e..3ba563e81 100644 --- a/opendbc/subaru_forester_2017_generated.dbc +++ b/opendbc/subaru_forester_2017_generated.dbc @@ -127,10 +127,11 @@ BO_ 338 Stalk: 8 XXX BO_ 352 ES_Brake: 8 XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX - SG_ Brake_Light : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Lights : 20|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Fault : 21|1@1+ (1,0) [0|1] "" XXX - SG_ Brake_On : 22|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 22|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 23|1@1+ (1,0) [0|1] "" XXX + SG_ SET_1 : 45|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX @@ -139,7 +140,7 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal1 : 12|4@1+ (1,0) [0|15] "" XXX SG_ Car_Follow : 16|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 17|3@1+ (1,0) [0|7] "" XXX - SG_ Brake_On : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 20|1@1+ (1,0) [0|1] "" XXX SG_ Distance_Swap : 21|1@1+ (1,0) [0|1] "" XXX SG_ Standstill : 22|1@1+ (1,0) [0|1] "" XXX SG_ Signal3 : 23|1@1+ (1,0) [0|1] "" XXX @@ -154,10 +155,10 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal7 : 51|5@1+ (1,0) [0|31] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX -BO_ 354 ES_RPM: 8 XXX +BO_ 354 ES_Status: 8 XXX SG_ Brake : 8|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 9|1@1+ (1,0) [0|1] "" XXX - SG_ RPM : 16|16@1+ (1,0) [0|65535] "" XXX + SG_ Cruise_RPM : 16|16@1+ (1,0) [0|65535] "" XXX SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX diff --git a/opendbc/subaru_global_2017_generated.dbc b/opendbc/subaru_global_2017_generated.dbc index b293d9d48..319764fc9 100644 --- a/opendbc/subaru_global_2017_generated.dbc +++ b/opendbc/subaru_global_2017_generated.dbc @@ -246,6 +246,14 @@ BO_ 802 ES_LKAS_State: 8 XXX SG_ LKAS_Alert : 32|5@1+ (1,0) [0|31] "" XXX SG_ Signal3 : 37|27@1+ (1,0) [0|1] "" XXX +BO_ 803 ES_Infotainment: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX + SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX + SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX + BO_ 722 AC_State: 8 XXX SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX @@ -351,14 +359,6 @@ BO_ 576 CruiseControl: 8 XXX SG_ Cruise_Activated : 41|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 42|22@1+ (1,0) [0|4194303] "" XXX -BO_ 803 ES_Infotainment: 8 XXX - SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX - SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX - SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX - SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX - SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX - SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX - CM_ SG_ 545 Cruise_Throttle "RPM-like output signal"; CM_ SG_ 545 Cruise_EPB "1 = Electric Parking Brake set"; CM_ SG_ 545 Distance_Swap "Switch from Close to Far distance"; diff --git a/opendbc/subaru_global_2020_hybrid_generated.dbc b/opendbc/subaru_global_2020_hybrid_generated.dbc index a285a1c8b..99087eb22 100644 --- a/opendbc/subaru_global_2020_hybrid_generated.dbc +++ b/opendbc/subaru_global_2020_hybrid_generated.dbc @@ -246,6 +246,14 @@ BO_ 802 ES_LKAS_State: 8 XXX SG_ LKAS_Alert : 32|5@1+ (1,0) [0|31] "" XXX SG_ Signal3 : 37|27@1+ (1,0) [0|1] "" XXX +BO_ 803 ES_Infotainment: 8 XXX + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX + SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX + SG_ LKAS_Blue_Lines : 15|4@0+ (1,0) [0|15] "" XXX + SG_ Signal1 : 19|4@0+ (1,0) [0|15] "" XXX + SG_ LKAS_State_Infotainment : 22|3@0+ (1,0) [0|7] "" XXX + SG_ Signal2 : 24|1@0+ (1,0) [0|1] "" XXX + BO_ 722 AC_State: 8 XXX SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX diff --git a/opendbc/subaru_outback_2015_generated.dbc b/opendbc/subaru_outback_2015_generated.dbc index 6f97c8908..4a6a0d3c0 100644 --- a/opendbc/subaru_outback_2015_generated.dbc +++ b/opendbc/subaru_outback_2015_generated.dbc @@ -127,10 +127,11 @@ BO_ 338 Stalk: 8 XXX BO_ 352 ES_Brake: 8 XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX - SG_ Brake_Light : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Lights : 20|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Fault : 21|1@1+ (1,0) [0|1] "" XXX - SG_ Brake_On : 22|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 22|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 23|1@1+ (1,0) [0|1] "" XXX + SG_ SET_1 : 45|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX @@ -139,7 +140,7 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal1 : 12|4@1+ (1,0) [0|15] "" XXX SG_ Car_Follow : 16|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 17|3@1+ (1,0) [0|7] "" XXX - SG_ Brake_On : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 20|1@1+ (1,0) [0|1] "" XXX SG_ Distance_Swap : 21|1@1+ (1,0) [0|1] "" XXX SG_ Standstill : 22|1@1+ (1,0) [0|1] "" XXX SG_ Signal3 : 23|1@1+ (1,0) [0|1] "" XXX @@ -154,10 +155,10 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal7 : 51|5@1+ (1,0) [0|31] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX -BO_ 354 ES_RPM: 8 XXX +BO_ 354 ES_Status: 8 XXX SG_ Brake : 8|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 9|1@1+ (1,0) [0|1] "" XXX - SG_ RPM : 16|16@1+ (1,0) [0|65535] "" XXX + SG_ Cruise_RPM : 16|16@1+ (1,0) [0|65535] "" XXX SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX diff --git a/opendbc/subaru_outback_2019_generated.dbc b/opendbc/subaru_outback_2019_generated.dbc index 908a9fdd3..2493ad4d3 100644 --- a/opendbc/subaru_outback_2019_generated.dbc +++ b/opendbc/subaru_outback_2019_generated.dbc @@ -127,10 +127,11 @@ BO_ 338 Stalk: 8 XXX BO_ 352 ES_Brake: 8 XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX - SG_ Brake_Light : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Lights : 20|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Fault : 21|1@1+ (1,0) [0|1] "" XXX - SG_ Brake_On : 22|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 22|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 23|1@1+ (1,0) [0|1] "" XXX + SG_ SET_1 : 45|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX @@ -139,7 +140,7 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal1 : 12|4@1+ (1,0) [0|15] "" XXX SG_ Car_Follow : 16|1@1+ (1,0) [0|1] "" XXX SG_ Signal2 : 17|3@1+ (1,0) [0|7] "" XXX - SG_ Brake_On : 20|1@1+ (1,0) [0|1] "" XXX + SG_ Cruise_Brake_Active : 20|1@1+ (1,0) [0|1] "" XXX SG_ Distance_Swap : 21|1@1+ (1,0) [0|1] "" XXX SG_ Standstill : 22|1@1+ (1,0) [0|1] "" XXX SG_ Signal3 : 23|1@1+ (1,0) [0|1] "" XXX @@ -154,10 +155,10 @@ BO_ 353 ES_Distance: 8 XXX SG_ Signal7 : 51|5@1+ (1,0) [0|31] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX -BO_ 354 ES_RPM: 8 XXX +BO_ 354 ES_Status: 8 XXX SG_ Brake : 8|1@1+ (1,0) [0|1] "" XXX SG_ Cruise_Activated : 9|1@1+ (1,0) [0|1] "" XXX - SG_ RPM : 16|16@1+ (1,0) [0|65535] "" XXX + SG_ Cruise_RPM : 16|16@1+ (1,0) [0|65535] "" XXX SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX SG_ COUNTER : 48|3@1+ (1,0) [0|7] "" XXX diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index 8f17c1f09..6d23a8e79 100755 Binary files a/panda/board/obj/bootstub.panda.bin and b/panda/board/obj/bootstub.panda.bin differ diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index f1307755c..054ce544b 100644 Binary files a/panda/board/obj/panda.bin.signed and b/panda/board/obj/panda.bin.signed differ diff --git a/panda/python/__init__.py b/panda/python/__init__.py index eca9a8a87..f2a743609 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -185,6 +185,7 @@ class Panda: GMLAN_CAN2 = 1 GMLAN_CAN3 = 2 + USB_PIDS = (0xddee, 0xddcc) REQUEST_IN = usb1.ENDPOINT_IN | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE REQUEST_OUT = usb1.ENDPOINT_OUT | usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE @@ -208,9 +209,9 @@ class Panda: HEALTH_STRUCT = struct.Struct(" float: return val_steady -def create_button_event(cur_but: int, prev_but: int, buttons_dict: Dict[int, capnp.lib.capnp._EnumModule], - unpressed: int = 0) -> capnp.lib.capnp._DynamicStructBuilder: - if cur_but != unpressed: - be = car.CarState.ButtonEvent(pressed=True) - but = cur_but - else: - be = car.CarState.ButtonEvent(pressed=False) - but = prev_but - be.type = buttons_dict.get(but, ButtonType.unknown) - return be +def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: Dict[int, capnp.lib.capnp._EnumModule], + unpressed_btn: int = 0) -> List[capnp.lib.capnp._DynamicStructBuilder]: + events: List[capnp.lib.capnp._DynamicStructBuilder] = [] + + if cur_btn == prev_btn: + return events + + # Add events for button presses, multiple when a button switches without going to unpressed + for pressed, btn in ((False, prev_btn), (True, cur_btn)): + if btn != unpressed_btn: + events.append(car.CarState.ButtonEvent(pressed=pressed, + type=buttons_dict.get(btn, ButtonType.unknown))) + return events def gen_empty_fingerprint(): - return {i: {} for i in range(0, 8)} + return {i: {} for i in range(8)} # these params were derived for the Civic and used to calculate params for other cars @@ -232,4 +235,4 @@ class CanSignalRateCalculator: self.previous_counter = current_counter self.previous_value = current_value - return self.rate \ No newline at end of file + return self.rate diff --git a/selfdrive/car/body/interface.py b/selfdrive/car/body/interface.py index bf33eea38..12a2d5f30 100644 --- a/selfdrive/car/body/interface.py +++ b/selfdrive/car/body/interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import math from cereal import car from openpilot.common.realtime import DT_CTRL diff --git a/selfdrive/car/body/radar_interface.py b/selfdrive/car/body/radar_interface.py index b461fcd5f..e654bd61f 100644 --- a/selfdrive/car/body/radar_interface.py +++ b/selfdrive/car/body/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): diff --git a/selfdrive/car/body/values.py b/selfdrive/car/body/values.py index 56d972381..306d90691 100644 --- a/selfdrive/car/body/values.py +++ b/selfdrive/car/body/values.py @@ -1,3 +1,4 @@ +from strenum import StrEnum from typing import Dict from cereal import car @@ -21,7 +22,7 @@ class CarControllerParams: pass -class CAR: +class CAR(StrEnum): BODY = "COMMA BODY" diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 4c948afee..1fd01e4c6 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,4 +1,5 @@ import os +import time from typing import Callable, Dict, List, Optional, Tuple from cereal import car @@ -65,9 +66,8 @@ def load_interfaces(brand_names): def _get_interface_names() -> Dict[str, List[str]]: # returns a dict of brand name and its respective models brand_names = {} - for brand_name, model_names in get_interface_attr("CAR").items(): - model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")] - brand_names[brand_name] = model_names + for brand_name, brand_models in get_interface_attr("CAR").items(): + brand_names[brand_name] = [model.value for model in brand_models] return brand_names @@ -130,14 +130,15 @@ def fingerprint(logcan, sendcan, num_pandas): fixed_fingerprint = dp_car_assigned.strip() skip_fw_query = True + start_time = time.monotonic() if not skip_fw_query: # Vin query only reliably works through OBDII bus = 1 cached_params = params.get("CarParamsCache") if cached_params is not None: - cached_params = car.CarParams.from_bytes(cached_params) # with car.CarParams.from_bytes(cached_params) as cached_params: + cached_params = car.CarParams.from_bytes(cached_params) if cached_params.carName == "mock": cached_params = None @@ -171,6 +172,8 @@ def fingerprint(logcan, sendcan, num_pandas): set_obd_multiplexing(params, False) params.put_bool("FirmwareQueryDone", True) + fw_query_time = time.monotonic() - start_time + # CAN fingerprint # drain CAN socket so we get the latest messages messaging.drain_sock_raw(logcan) @@ -191,7 +194,7 @@ def fingerprint(logcan, sendcan, num_pandas): cloudlog.event("fingerprinted", car_fingerprint=car_fingerprint, source=source, fuzzy=not exact_match, cached=cached, fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), vin_rx_addr=vin_rx_addr, fingerprints=finger, - error=True) + fw_query_time=fw_query_time, error=True) return car_fingerprint, finger, vin, car_fw, source, exact_match diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index a568f927b..050eb41b1 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,7 +1,7 @@ from opendbc.can.packer import CANPacker from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car import apply_meas_steer_torque_limits -from openpilot.selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons +from openpilot.selfdrive.car.chrysler import chryslercan from openpilot.selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams, ChryslerFlags @@ -31,17 +31,18 @@ class CarController: # ACC cancellation if CC.cruiseControl.cancel: self.last_button_frame = self.frame - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) + can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) # ACC resume from standstill elif CC.cruiseControl.resume: self.last_button_frame = self.frame - can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) + can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) # HUD alerts if self.frame % 25 == 0: if CS.lkas_car_model != -1: - can_sends.append(create_lkas_hud(self.packer, self.CP, lkas_active, CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model, CS.auto_high_beam)) + can_sends.append(chryslercan.create_lkas_hud(self.packer, self.CP, lkas_active, CC.hudControl.visualAlert, + self.hud_count, CS.lkas_car_model, CS.auto_high_beam)) self.hud_count += 1 # steering @@ -72,7 +73,7 @@ class CarController: apply_steer = 0 self.apply_steer_last = apply_steer - can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_control_bit)) + can_sends.append(chryslercan.create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_control_bit)) self.frame += 1 diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 657ada270..f957997e9 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,5 +1,6 @@ # ruff: noqa: E501 from enum import IntFlag +from strenum import StrEnum from dataclasses import dataclass, field from typing import Dict, List, Optional, Union @@ -16,7 +17,7 @@ class ChryslerFlags(IntFlag): HIGHER_MIN_STEERING_SPEED = 1 -class CAR: +class CAR(StrEnum): # Chrysler PACIFICA_2017_HYBRID = "CHRYSLER PACIFICA HYBRID 2017" PACIFICA_2018_HYBRID = "CHRYSLER PACIFICA HYBRID 2018" diff --git a/selfdrive/car/disable_ecu.py b/selfdrive/car/disable_ecu.py index 1a1252327..c11075342 100755 --- a/selfdrive/car/disable_ecu.py +++ b/selfdrive/car/disable_ecu.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 from openpilot.selfdrive.car.isotp_parallel_query import IsoTpParallelQuery from openpilot.system.swaglog import cloudlog diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 3319ba31c..880404fec 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -85,6 +85,7 @@ class CarHarness(EnumBase): bosch_a = BaseCarHarness("Honda Bosch A connector") bosch_b = BaseCarHarness("Honda Bosch B connector") toyota_a = BaseCarHarness("Toyota A connector") + toyota_b = BaseCarHarness("Toyota B connector") subaru_a = BaseCarHarness("Subaru A connector") subaru_b = BaseCarHarness("Subaru B connector") subaru_c = BaseCarHarness("Subaru C connector") @@ -110,6 +111,7 @@ class CarHarness(EnumBase): hyundai_o = BaseCarHarness("Hyundai O connector") hyundai_p = BaseCarHarness("Hyundai P connector") hyundai_q = BaseCarHarness("Hyundai Q connector") + hyundai_r = BaseCarHarness("Hyundai R connector") custom = BaseCarHarness("Developer connector") obd_ii = BaseCarHarness("OBD-II connector", parts=[Cable.long_obdc_cable, Cable.long_obdc_cable], has_connector=False) gm = BaseCarHarness("GM connector") @@ -121,9 +123,9 @@ class CarHarness(EnumBase): class Device(EnumBase): - three = BasePart("comma three", parts=[Mount.mount, Cable.right_angle_obd_c_cable_1_5ft]) - # variant of comma three with angled mounts - three_angled_mount = BasePart("comma three", parts=[Mount.angled_mount_8_degrees, Cable.right_angle_obd_c_cable_1_5ft]) + threex = BasePart("comma 3X", parts=[Mount.mount, Cable.right_angle_obd_c_cable_1_5ft]) + # variant of comma 3X with angled mounts + threex_angled_mount = BasePart("comma 3X", parts=[Mount.angled_mount_8_degrees, Cable.right_angle_obd_c_cable_1_5ft]) red_panda = BasePart("red panda") @@ -147,7 +149,7 @@ class PartType(Enum): tool = Tool -DEFAULT_CAR_PARTS: List[EnumBase] = [Device.three] +DEFAULT_CAR_PARTS: List[EnumBase] = [Device.threex] @dataclass @@ -174,8 +176,8 @@ CarFootnote = namedtuple("CarFootnote", ["text", "column", "docs_only", "shop_fo class CommonFootnote(Enum): EXP_LONG_AVAIL = CarFootnote( - "Experimental openpilot longitudinal control is available behind a toggle; " + - "the toggle is only available in non-release branches such as `devel` or `master-ci`. ", + "openpilot Longitudinal Control (Alpha) is available behind a toggle; " + + "the toggle is only available in non-release branches such as `devel` or `master-ci`.", Column.LONGITUDINAL, docs_only=True) EXP_LONG_DSU = CarFootnote( "By default, this car will use the stock Adaptive Cruise Control (ACC) for longitudinal control. " + diff --git a/selfdrive/car/ford/carcontroller.py b/selfdrive/car/ford/carcontroller.py index 86008c635..fe9ee404a 100644 --- a/selfdrive/car/ford/carcontroller.py +++ b/selfdrive/car/ford/carcontroller.py @@ -2,8 +2,7 @@ from cereal import car from openpilot.common.numpy_fast import clip from opendbc.can.packer import CANPacker from openpilot.selfdrive.car import apply_std_steer_angle_limits -from openpilot.selfdrive.car.ford.fordcan import CanBus, create_acc_msg, create_acc_ui_msg, create_button_msg, \ - create_lat_ctl_msg, create_lat_ctl2_msg, create_lka_msg, create_lkas_ui_msg +from openpilot.selfdrive.car.ford import fordcan from openpilot.selfdrive.car.ford.values import CANFD_CAR, CarControllerParams LongCtrlState = car.CarControl.Actuators.LongControlState @@ -27,7 +26,7 @@ class CarController: self.CP = CP self.VM = VM self.packer = CANPacker(dbc_name) - self.CAN = CanBus(CP) + self.CAN = fordcan.CanBus(CP) self.frame = 0 self.apply_curvature_last = 0 @@ -47,15 +46,15 @@ class CarController: ### acc buttons ### if CC.cruiseControl.cancel: - can_sends.append(create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, cancel=True)) - can_sends.append(create_button_msg(self.packer, self.CAN.main, CS.buttons_stock_values, cancel=True)) + can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, cancel=True)) + can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.main, CS.buttons_stock_values, cancel=True)) elif CC.cruiseControl.resume and (self.frame % CarControllerParams.BUTTONS_STEP) == 0: - can_sends.append(create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, resume=True)) - can_sends.append(create_button_msg(self.packer, self.CAN.main, CS.buttons_stock_values, resume=True)) + can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, resume=True)) + can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.main, CS.buttons_stock_values, resume=True)) # if stock lane centering isn't off, send a button press to toggle it off # the stock system checks for steering pressed, and eventually disengages cruise control elif CS.acc_tja_status_stock_values["Tja_D_Stat"] != 0 and (self.frame % CarControllerParams.ACC_UI_STEP) == 0: - can_sends.append(create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, tja_toggle=True)) + can_sends.append(fordcan.create_button_msg(self.packer, self.CAN.camera, CS.buttons_stock_values, tja_toggle=True)) ### lateral control ### # send steer msg at 20Hz @@ -73,13 +72,13 @@ class CarController: # TODO: extended mode mode = 1 if CC.latActive else 0 counter = (self.frame // CarControllerParams.STEER_STEP) % 0xF - can_sends.append(create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter)) + can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter)) else: - can_sends.append(create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -apply_curvature, 0.)) + can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -apply_curvature, 0.)) # send lka msg at 33Hz if (self.frame % CarControllerParams.LKA_STEP) == 0: - can_sends.append(create_lka_msg(self.packer, self.CAN)) + can_sends.append(fordcan.create_lka_msg(self.packer, self.CAN)) ### longitudinal control ### # send acc msg at 50Hz @@ -91,16 +90,16 @@ class CarController: gas = CarControllerParams.INACTIVE_GAS stopping = CC.actuators.longControlState == LongCtrlState.stopping - can_sends.append(create_acc_msg(self.packer, self.CAN, CC.longActive, gas, accel, stopping)) + can_sends.append(fordcan.create_acc_msg(self.packer, self.CAN, CC.longActive, gas, accel, stopping)) ### ui ### send_ui = (self.main_on_last != main_on) or (self.lkas_enabled_last != CC.latActive) or (self.steer_alert_last != steer_alert) # send lkas ui msg at 1Hz or if ui state changes if (self.frame % CarControllerParams.LKAS_UI_STEP) == 0 or send_ui: - can_sends.append(create_lkas_ui_msg(self.packer, self.CAN, main_on, CC.latActive, steer_alert, hud_control, CS.lkas_status_stock_values)) + can_sends.append(fordcan.create_lkas_ui_msg(self.packer, self.CAN, main_on, CC.latActive, steer_alert, hud_control, CS.lkas_status_stock_values)) # send acc ui msg at 5Hz or if ui state changes if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui: - can_sends.append(create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive, + can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive, fcw_alert, CS.out.cruiseState.standstill, hud_control, CS.acc_tja_status_stock_values)) diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index 755d7d1d0..3045c317f 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from cereal import car from panda import Panda from openpilot.common.conversions import Conversions as CV diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index 69c826c37..cfec06a17 100644 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from math import cos, sin from cereal import car from opendbc.can.parser import CANParser diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index 8968d1dc2..6221e95a5 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -1,6 +1,7 @@ from collections import defaultdict from dataclasses import dataclass, field from enum import Enum +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -40,7 +41,7 @@ class CarControllerParams: pass -class CAR: +class CAR(StrEnum): BRONCO_SPORT_MK1 = "FORD BRONCO SPORT 1ST GEN" ESCAPE_MK4 = "FORD ESCAPE 4TH GEN" EXPLORER_MK6 = "FORD EXPLORER 6TH GEN" @@ -78,7 +79,7 @@ class FordCarInfo(CarInfo): def init_make(self, CP: car.CarParams): if CP.carFingerprint in (CAR.BRONCO_SPORT_MK1, CAR.MAVERICK_MK1): - self.car_parts = CarParts([Device.three_angled_mount, CarHarness.ford_q3]) + self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.ford_q3]) CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = { @@ -265,7 +266,9 @@ FW_VERSIONS = { b'NZ6A-14C204-AAA\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'NZ6A-14C204-PA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'NZ6A-14C204-ZA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PZ6A-14C204-BE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PZ6A-14C204-JC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PZ6A-14C204-JE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, } diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 8585e9f20..89c1a3596 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -98,7 +98,7 @@ class CarState(CarStateBase): ret.leftBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1 ret.rightBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2 - ret.parkingBrake = pt_cp.vl["VehicleIgnitionAlt"]["ParkBrake"] == 1 + ret.parkingBrake = pt_cp.vl["BCMGeneralPlatformStatus"]["ParkBrakeSwActive"] == 1 ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0 ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1 ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or @@ -135,7 +135,7 @@ class CarState(CarStateBase): ("PSCMStatus", 10), ("ESPStatus", 10), ("BCMDoorBeltStatus", 10), - ("VehicleIgnitionAlt", 10), + ("BCMGeneralPlatformStatus", 10), ("EBCMWheelSpdFront", 20), ("EBCMWheelSpdRear", 20), ("EBCMFrictionBrakeStatus", 20), diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index b383ee854..d887d0689 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -4,7 +4,7 @@ from math import fabs, exp from panda import Panda from openpilot.common.conversions import Conversions as CV -from openpilot.selfdrive.car import create_button_event, get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD @@ -257,13 +257,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback) - if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: - buttonEvents = [create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS)] - # Handle ACCButtons changing buttons mid-press - if self.CS.cruise_buttons != CruiseButtons.UNPRESS and self.CS.prev_cruise_buttons != CruiseButtons.UNPRESS: - buttonEvents.append(create_button_event(CruiseButtons.UNPRESS, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS)) - - ret.buttonEvents = buttonEvents + # Don't add event if transitioning from INIT, unless it's to an actual button + if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT: + ret.buttonEvents = create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, + unpressed_btn=CruiseButtons.UNPRESS) # The ECM allows enabling on falling edge of set, but only rising edge of resume events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low, diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index d12c21dc2..1cc34c03e 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -2,6 +2,7 @@ from collections import defaultdict from dataclasses import dataclass from enum import Enum +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -61,7 +62,7 @@ class CarControllerParams: self.BRAKE_LOOKUP_V = [self.MAX_BRAKE, 0.] -class CAR: +class CAR(StrEnum): HOLDEN_ASTRA = "HOLDEN ASTRA RS-V BK 2017" VOLT = "CHEVROLET VOLT PREMIER 2017" CADILLAC_ATS = "CADILLAC ATS Premium Performance 2018" diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index cdda01ad4..54a2306f6 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -5,13 +5,12 @@ from openpilot.common.conversions import Conversions as CV from openpilot.common.numpy_fast import interp from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, \ HONDA_BOSCH_ALT_BRAKE_SIGNAL, HONDA_BOSCH_RADARLESS -from openpilot.selfdrive.car import create_button_event, get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.disable_ecu import disable_ecu from openpilot.common.params import Params - ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName TransmissionType = car.CarParams.TransmissionType @@ -310,15 +309,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) - buttonEvents = [] - - if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: - buttonEvents.append(create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT)) - - if self.CS.cruise_setting != self.CS.prev_cruise_setting: - buttonEvents.append(create_button_event(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1})) - - ret.buttonEvents = buttonEvents + ret.buttonEvents = [ + *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT), + *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1}), + ] # events events = self.create_common_events(ret, pcm_enable=False) diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index f42e39998..a04be8230 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -1,5 +1,6 @@ from dataclasses import dataclass from enum import Enum, IntFlag +from strenum import StrEnum from typing import Dict, List, Optional, Union from cereal import car @@ -72,7 +73,7 @@ VISUAL_HUD = { } -class CAR: +class CAR(StrEnum): ACCORD = "HONDA ACCORD 2018" ACCORDH = "HONDA ACCORD HYBRID 2018" CIVIC = "HONDA CIVIC 2016" @@ -1361,6 +1362,7 @@ FW_VERSIONS = { b'78109-T6Z-A910\x00\x00', b'78109-T6Z-AA10\x00\x00', b'78109-T6Z-C620\x00\x00', + b'78109-T6Z-C910\x00\x00', b'78109-TJZ-A510\x00\x00', ], (Ecu.srs, 0x18da53f1, None): [ diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 1ff211e86..0b5f724ab 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -110,9 +110,10 @@ class CarController: # steering control can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_steer)) - # disable LFA on HDA2 + # prevent LFA from activating on HDA2 by sending "no lane lines detected" to ADAS ECU if self.frame % 5 == 0 and hda2: - can_sends.append(hyundaicanfd.create_cam_0x2a4(self.packer, self.CAN, CS.cam_0x2a4)) + can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.hda2_lfa_block_msg, + self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING)) # LFA and HDA icons if self.frame % 5 == 0 and (not hda2 or hda2_long): @@ -131,26 +132,7 @@ class CarController: self.accel_last = accel else: # button presses - if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: - # cruise cancel - if CC.cruiseControl.cancel: - if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: - can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info)) - self.last_button_frame = self.frame - else: - for _ in range(20): - can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL)) - self.last_button_frame = self.frame - - # cruise standstill resume - elif CC.cruiseControl.resume: - if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: - # TODO: resume for alt button cars - pass - else: - for _ in range(20): - can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL)) - self.last_button_frame = self.frame + can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False)) else: can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, apply_steer_req, torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled, @@ -158,15 +140,7 @@ class CarController: left_lane_warning, right_lane_warning)) if not self.CP.openpilotLongitudinalControl: - if CC.cruiseControl.cancel: - can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint)) - elif CC.cruiseControl.resume: - # send resume at a max freq of 10Hz - if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: - # send 25 messages at a time to increases the likelihood of resume being accepted - can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25) - if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15: - self.last_button_frame = self.frame + can_sends.extend(self.create_button_messages(CC, CS, use_clu11=True)) if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl: # TODO: unclear if this is needed @@ -195,3 +169,39 @@ class CarController: self.frame += 1 return new_actuators, can_sends + + def create_button_messages(self, CC: car.CarControl, CS: car.CarState, use_clu11: bool): + can_sends = [] + if use_clu11: + if CC.cruiseControl.cancel: + can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint)) + elif CC.cruiseControl.resume: + # send resume at a max freq of 10Hz + if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: + # send 25 messages at a time to increases the likelihood of resume being accepted + can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25) + if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15: + self.last_button_frame = self.frame + else: + if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: + # cruise cancel + if CC.cruiseControl.cancel: + if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: + can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info)) + self.last_button_frame = self.frame + else: + for _ in range(20): + can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL)) + self.last_button_frame = self.frame + + # cruise standstill resume + elif CC.cruiseControl.resume: + if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: + # TODO: resume for alt button cars + pass + else: + for _ in range(20): + can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL)) + self.last_button_frame = self.frame + + return can_sends diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index ee35bf666..bd3ef828f 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -105,10 +105,12 @@ class CarState(CarStateBase): ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0 ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False + ret.cruiseState.nonAdaptive = False else: ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0 ret.cruiseState.standstill = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 4. + ret.cruiseState.nonAdaptive = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 2. # Shows 'Cruise Control' on dash ret.cruiseState.speed = cp_cruise.vl["SCC11"]["VSetDis"] * speed_conv # TODO: Find brake pressure @@ -130,12 +132,12 @@ class CarState(CarStateBase): # Gear Selection via Cluster - For those Kia/Hyundai which are not fully discovered, we can use the Cluster Indicator for Gear Selection, # as this seems to be standard over all cars, but is not the preferred method. - if self.CP.carFingerprint in CAN_GEARS["use_cluster_gears"]: + if self.CP.carFingerprint in (HYBRID_CAR | EV_CAR): + gear = cp.vl["ELECT_GEAR"]["Elect_Gear_Shifter"] + elif self.CP.carFingerprint in CAN_GEARS["use_cluster_gears"]: gear = cp.vl["CLU15"]["CF_Clu_Gear"] elif self.CP.carFingerprint in CAN_GEARS["use_tcu_gears"]: gear = cp.vl["TCU12"]["CUR_GR"] - elif self.CP.carFingerprint in CAN_GEARS["use_elect_gears"]: - gear = cp.vl["ELECT_GEAR"]["Elect_Gear_Shifter"] else: gear = cp.vl["LVR12"]["CF_Lvr_Gear"] @@ -202,8 +204,12 @@ class CarState(CarStateBase): ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > self.params.STEER_THRESHOLD, 5) ret.steerFaultTemporary = cp.vl["MDPS"]["LKA_FAULT"] != 0 - ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"]["LEFT_LAMP"], - cp.vl["BLINKERS"]["RIGHT_LAMP"]) + # TODO: alt signal usage may be described by cp.vl['BLINKERS']['USE_ALT_LAMP'] + left_blinker_sig, right_blinker_sig = "LEFT_LAMP", "RIGHT_LAMP" + if self.CP.carFingerprint == CAR.KONA_EV_2ND_GEN: + left_blinker_sig, right_blinker_sig = "LEFT_LAMP_ALT", "RIGHT_LAMP_ALT" + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][left_blinker_sig], + cp.vl["BLINKERS"][right_blinker_sig]) if self.CP.enableBsm: ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FL_INDICATOR"] != 0 ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FR_INDICATOR"] != 0 @@ -222,6 +228,13 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp_cruise_info.vl["SCC_CONTROL"]["VSetDis"] * speed_factor self.cruise_info = copy.copy(cp_cruise_info.vl["SCC_CONTROL"]) + # Manual Speed Limit Assist is a feature that replaces non-adaptive cruise control on EV CAN FD platforms. + # It limits the vehicle speed, overridable by pressing the accelerator past a certain point. + # The car will brake, but does not respect positive acceleration commands in this mode + # TODO: find this message on ICE & HYBRID cars + cruise control signals (if exists) + if self.CP.carFingerprint in EV_CAR: + ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1 + self.prev_cruise_buttons = self.cruise_buttons[-1] self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"]) @@ -229,7 +242,8 @@ class CarState(CarStateBase): ret.accFaulted = cp.vl["TCS"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED if self.CP.flags & HyundaiFlags.CANFD_HDA2: - self.cam_0x2a4 = copy.copy(cp_cam.vl["CAM_0x2a4"]) + self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING + else cp_cam.vl["CAM_0x2a4"]) return ret @@ -271,12 +285,12 @@ class CarState(CarStateBase): ("EMS16", 100), ] - if CP.carFingerprint in CAN_GEARS["use_cluster_gears"]: + if CP.carFingerprint in (HYBRID_CAR | EV_CAR): + messages.append(("ELECT_GEAR", 20)) + elif CP.carFingerprint in CAN_GEARS["use_cluster_gears"]: pass elif CP.carFingerprint in CAN_GEARS["use_tcu_gears"]: messages.append(("TCU12", 100)) - elif CP.carFingerprint in CAN_GEARS["use_elect_gears"]: - messages.append(("ELECT_GEAR", 20)) else: messages.append(("LVR12", 100)) @@ -305,7 +319,6 @@ class CarState(CarStateBase): def get_can_parser_canfd(self, CP): messages = [ (self.gear_msg_canfd, 100), - (self.cruise_btns_msg_canfd, 50), (self.accelerator_msg_canfd, 100), ("WHEEL_SPEEDS", 100), ("STEERING_SENSORS", 100), @@ -316,6 +329,16 @@ class CarState(CarStateBase): ("DOORS_SEATBELTS", 4), ] + if CP.carFingerprint in EV_CAR: + messages += [ + ("MANUAL_SPEED_LIMIT_ASSIST", 10), + ] + + if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): + messages += [ + ("CRUISE_BUTTONS", 50) + ] + if CP.enableBsm: messages += [ ("BLINDSPOTS_REAR_CORNERS", 20), @@ -332,7 +355,8 @@ class CarState(CarStateBase): def get_cam_can_parser_canfd(CP): messages = [] if CP.flags & HyundaiFlags.CANFD_HDA2: - messages += [("CAM_0x2a4", 20)] + block_lfa_msg = "CAM_0x362" if CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else "CAM_0x2a4" + messages += [(block_lfa_msg, 20)] elif CP.flags & HyundaiFlags.CANFD_CAMERA_SCC: messages += [ ("SCC_CONTROL", 50), diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py index 008397402..bc29aeb98 100644 --- a/selfdrive/car/hyundai/hyundaican.py +++ b/selfdrive/car/hyundai/hyundaican.py @@ -37,7 +37,8 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, - CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED): + CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED, + CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.CUSTIN_1ST_GEN): values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1) values["CF_Lkas_LdwsOpt_USM"] = 2 diff --git a/selfdrive/car/hyundai/hyundaicanfd.py b/selfdrive/car/hyundai/hyundaicanfd.py index 7aca5b850..a35fcb777 100644 --- a/selfdrive/car/hyundai/hyundaicanfd.py +++ b/selfdrive/car/hyundai/hyundaicanfd.py @@ -46,25 +46,32 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_steer): "LKA_ASSIST": 0, "STEER_REQ": 1 if lat_active else 0, "STEER_MODE": 0, - "SET_ME_1": 0, + "HAS_LANE_SAFETY": 0, # hide LKAS settings "NEW_SIGNAL_1": 0, "NEW_SIGNAL_2": 0, } if CP.flags & HyundaiFlags.CANFD_HDA2: + hda2_lkas_msg = "LKAS_ALT" if CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING else "LKAS" if CP.openpilotLongitudinalControl: ret.append(packer.make_can_msg("LFA", CAN.ECAN, values)) - ret.append(packer.make_can_msg("LKAS", CAN.ACAN, values)) + ret.append(packer.make_can_msg(hda2_lkas_msg, CAN.ACAN, values)) else: ret.append(packer.make_can_msg("LFA", CAN.ECAN, values)) return ret -def create_cam_0x2a4(packer, CAN, cam_0x2a4): - values = {f"BYTE{i}": cam_0x2a4[f"BYTE{i}"] for i in range(3, 24)} - values['COUNTER'] = cam_0x2a4['COUNTER'] - values["BYTE7"] = 0 - return packer.make_can_msg("CAM_0x2a4", CAN.ACAN, values) +def create_suppress_lfa(packer, CAN, hda2_lfa_block_msg, hda2_alt_steering): + suppress_msg = "CAM_0x362" if hda2_alt_steering else "CAM_0x2a4" + msg_bytes = 32 if hda2_alt_steering else 24 + + values = {f"BYTE{i}": hda2_lfa_block_msg[f"BYTE{i}"] for i in range(3, msg_bytes) if i != 7} + values["COUNTER"] = hda2_lfa_block_msg["COUNTER"] + values["SET_ME_0"] = 0 + values["SET_ME_0_2"] = 0 + values["LEFT_LANE_LINE"] = 0 + values["RIGHT_LANE_LINE"] = 0 + return packer.make_can_msg(suppress_msg, CAN.ACAN, values) def create_buttons(packer, CP, CAN, cnt, btn): values = { diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 828ebe2ac..0508f78b9 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from cereal import car from panda import Panda from openpilot.common.conversions import Conversions as CV @@ -7,7 +6,7 @@ from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, UNSUPPORTED_LONGITUDINAL_CAR, \ Buttons from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR -from openpilot.selfdrive.car import create_button_event, get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.disable_ecu import disable_ecu @@ -31,7 +30,8 @@ class CarInterface(CarInterfaceBase): # These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. - ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, CAR.IONIQ_6} + # FIXME: the Optima Hybrid 2017 uses a different SCC12 checksum + ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, } ret.dashcamOnly = False if ret.dashcamOnly and params.get_bool("dp_car_dashcam_mode_removal") else ret.dashcamOnly hda2 = Ecu.adas in [fw.ecu for fw in car_fw] @@ -41,6 +41,8 @@ class CarInterface(CarInterfaceBase): # detect HDA2 with ADAS Driving ECU if hda2: ret.flags |= HyundaiFlags.CANFD_HDA2.value + if 0x110 in fingerprint[CAN.CAM]: + ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value else: # non-HDA2 if 0x1cf not in fingerprint[CAN.ECAN]: @@ -66,7 +68,11 @@ class CarInterface(CarInterfaceBase): ret.steerLimitTimer = 0.4 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - if candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): + if candidate in (CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN): + ret.mass = 1600. if candidate == CAR.AZERA_6TH_GEN else 1675. # ICE is ~average of 2.5L and 3.5L + ret.wheelbase = 2.885 + ret.steerRatio = 14.5 + elif candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): ret.mass = 3982. * CV.LB_TO_KG ret.wheelbase = 2.766 # Values from optimizer @@ -107,10 +113,10 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 3.01 ret.steerRatio = 16.5 ret.minSteerSpeed = 60 * CV.KPH_TO_MS - elif candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022): - ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425., CAR.KONA_EV_2022: 1743.}.get(candidate, 1275.) - ret.wheelbase = 2.6 - ret.steerRatio = 13.42 # Spec + elif candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022, CAR.KONA_EV_2ND_GEN): + ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425., CAR.KONA_EV_2022: 1743., CAR.KONA_EV_2ND_GEN: 1740.}.get(candidate, 1275.) + ret.wheelbase = {CAR.KONA_EV_2ND_GEN: 2.66, }.get(candidate, 2.6) + ret.steerRatio = {CAR.KONA_EV_2ND_GEN: 13.6, }.get(candidate, 13.42) # Spec ret.tireStiffnessFactor = 0.385 elif candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV_2019, CAR.IONIQ_HEV_2022, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV): ret.mass = 1490. # weight per hyundai site https://www.hyundaiusa.com/ioniq-electric/specifications.aspx @@ -119,6 +125,11 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFactor = 0.385 if candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV_2019): ret.minSteerSpeed = 32 * CV.MPH_TO_MS + elif candidate in (CAR.IONIQ_5, CAR.IONIQ_6): + ret.mass = 1948 + ret.wheelbase = 2.97 + ret.steerRatio = 14.26 + ret.tireStiffnessFactor = 0.65 elif candidate == CAR.VELOSTER: ret.mass = 2917. * CV.LB_TO_KG ret.wheelbase = 2.80 @@ -139,6 +150,10 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 3.000 # steering ratio according to Hyundai News https://www.hyundainews.com/assets/documents/original/48035-2022SantaCruzProductGuideSpecsv2081521.pdf ret.steerRatio = 14.2 + elif candidate == CAR.CUSTIN_1ST_GEN: + ret.mass = 1690. # from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0 + ret.wheelbase = 3.055 + ret.steerRatio = 17.0 # from learner # Kia elif candidate == CAR.KIA_SORENTO: @@ -160,7 +175,7 @@ class CarInterface(CarInterfaceBase): ret.mass = 1700. # weight from SX and above trims, average of FWD and AWD versions ret.wheelbase = 2.756 ret.steerRatio = 13.6 # steering ratio according to Kia News https://www.kiamedia.com/us/en/models/sportage/2023/specifications - elif candidate in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.KIA_OPTIMA_H): + elif candidate in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL): ret.mass = 3558. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 @@ -191,11 +206,6 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.9 ret.steerRatio = 16. ret.tireStiffnessFactor = 0.65 - elif candidate in (CAR.IONIQ_5, CAR.IONIQ_6): - ret.mass = 1948 - ret.wheelbase = 2.97 - ret.steerRatio = 14.26 - ret.tireStiffnessFactor = 0.65 elif candidate == CAR.KIA_SPORTAGE_HYBRID_5TH_GEN: ret.mass = 1767. # SX Prestige trim support only ret.wheelbase = 2.756 @@ -213,6 +223,10 @@ class CarInterface(CarInterfaceBase): ret.mass = 2087. ret.wheelbase = 3.09 ret.steerRatio = 14.23 + elif candidate == CAR.KIA_K8_HEV_1ST_GEN: + ret.mass = 1630. # https://carprices.ae/brands/kia/2023/k8/1.6-turbo-hybrid + ret.wheelbase = 2.895 + ret.steerRatio = 13.27 # guesstimate from K5 platform # Genesis elif candidate == CAR.GENESIS_GV60_EV_1ST_GEN: @@ -280,6 +294,8 @@ class CarInterface(CarInterfaceBase): if ret.flags & HyundaiFlags.CANFD_HDA2: ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CANFD_HDA2 + if ret.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING: + ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING if ret.flags & HyundaiFlags.CANFD_ALT_BUTTONS: ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CANFD_ALT_BUTTONS if ret.flags & HyundaiFlags.CANFD_CAMERA_SCC: @@ -328,13 +344,8 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) - if self.CS.CP.openpilotLongitudinalControl and self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: - buttonEvents = [create_button_event(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)] - # Handle CF_Clu_CruiseSwState changing buttons mid-press - if self.CS.cruise_buttons[-1] != 0 and self.CS.prev_cruise_buttons != 0: - buttonEvents.append(create_button_event(0, self.CS.prev_cruise_buttons, BUTTONS_DICT)) - - ret.buttonEvents = buttonEvents + if self.CS.CP.openpilotLongitudinalControl: + ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) # On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons diff --git a/selfdrive/car/hyundai/radar_interface.py b/selfdrive/car/hyundai/radar_interface.py index e1cae9ffa..526005098 100644 --- a/selfdrive/car/hyundai/radar_interface.py +++ b/selfdrive/car/hyundai/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import math from cereal import car @@ -9,6 +8,7 @@ from openpilot.selfdrive.car.hyundai.values import DBC RADAR_START_ADDR = 0x500 RADAR_MSG_COUNT = 32 +# POC for parsing corner radars: https://github.com/commaai/openpilot/pull/24221/ def get_radar_can_parser(CP): if DBC[CP.carFingerprint]['radar'] is None: diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 5f5b48dba..22025524f 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -2,6 +2,7 @@ import re from dataclasses import dataclass from enum import Enum, IntFlag +from strenum import StrEnum from typing import Dict, List, Optional, Set, Tuple, Union from cereal import car @@ -39,7 +40,7 @@ class CarControllerParams: # If the max stock LKAS request is <384, add your car to this list. elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.ELANTRA, CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_PHEV, - CAR.KIA_OPTIMA_H, CAR.KIA_SORENTO): + CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.KIA_SORENTO): self.STEER_MAX = 255 # these cars have significantly more torque than most HKG; limit to 70% of max @@ -64,10 +65,13 @@ class HyundaiFlags(IntFlag): CANFD_ALT_GEARS_2 = 64 SEND_LFA = 128 USE_FCA = 256 + CANFD_HDA2_ALT_STEERING = 512 -class CAR: +class CAR(StrEnum): # Hyundai + AZERA_6TH_GEN = "HYUNDAI AZERA 6TH GEN" + AZERA_HEV_6TH_GEN = "HYUNDAI AZERA HYBRID 6TH GEN" ELANTRA = "HYUNDAI ELANTRA 2017" ELANTRA_2021 = "HYUNDAI ELANTRA 2021" ELANTRA_HEV_2021 = "HYUNDAI ELANTRA HYBRID 2021" @@ -81,6 +85,7 @@ class CAR: KONA = "HYUNDAI KONA 2020" KONA_EV = "HYUNDAI KONA ELECTRIC 2019" KONA_EV_2022 = "HYUNDAI KONA ELECTRIC 2022" + KONA_EV_2ND_GEN = "HYUNDAI KONA ELECTRIC 2ND GEN" KONA_HEV = "HYUNDAI KONA HYBRID 2020" SANTA_FE = "HYUNDAI SANTA FE 2019" SANTA_FE_2022 = "HYUNDAI SANTA FE 2022" @@ -97,11 +102,13 @@ class CAR: TUCSON_4TH_GEN = "HYUNDAI TUCSON 4TH GEN" TUCSON_HYBRID_4TH_GEN = "HYUNDAI TUCSON HYBRID 4TH GEN" SANTA_CRUZ_1ST_GEN = "HYUNDAI SANTA CRUZ 1ST GEN" + CUSTIN_1ST_GEN = "HYUNDAI CUSTIN 1ST GEN" # Kia KIA_FORTE = "KIA FORTE E 2018 & GT 2021" KIA_K5_2021 = "KIA K5 2021" KIA_K5_HEV_2020 = "KIA K5 HYBRID 2020" + KIA_K8_HEV_1ST_GEN = "KIA K8 HYBRID 1ST GEN" KIA_NIRO_EV = "KIA NIRO EV 2020" KIA_NIRO_EV_2ND_GEN = "KIA NIRO EV 2ND GEN" KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019" @@ -110,6 +117,7 @@ class CAR: KIA_OPTIMA_G4 = "KIA OPTIMA 4TH GEN" KIA_OPTIMA_G4_FL = "KIA OPTIMA 4TH GEN FACELIFT" KIA_OPTIMA_H = "KIA OPTIMA HYBRID 2017 & SPORTS 2019" + KIA_OPTIMA_H_G4_FL = "KIA OPTIMA HYBRID 4TH GEN FACELIFT" KIA_SELTOS = "KIA SELTOS 2021" KIA_SPORTAGE_5TH_GEN = "KIA SPORTAGE 5TH GEN" KIA_SORENTO = "KIA SORENTO GT LINE 2018" @@ -135,9 +143,9 @@ class CAR: class Footnote(Enum): CANFD = CarFootnote( - "Requires a comma 3X or CAN FD panda kit " + - "for this CAN FD car.", - Column.MODEL, shop_footnote=True) + "Requires a CAN FD panda kit if not using " + + "comma 3X for this CAN FD car.", + Column.MODEL, shop_footnote=False) @dataclass @@ -150,6 +158,8 @@ class HyundaiCarInfo(CarInfo): CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { + CAR.AZERA_6TH_GEN: HyundaiCarInfo("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + CAR.AZERA_HEV_6TH_GEN: HyundaiCarInfo("Hyundai Azera Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), CAR.ELANTRA: [ HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])), HyundaiCarInfo("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), @@ -171,16 +181,19 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", car_parts=CarParts.common([CarHarness.hyundai_b])), CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g])), - CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022", car_parts=CarParts.common([CarHarness.hyundai_o])), + CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o])), CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", - car_parts=CarParts.common([CarHarness.hyundai_i])), # TODO: check packages + car_parts=CarParts.common([CarHarness.hyundai_i])), # TODO: check packages + # TODO: this is the 2024 US MY, not yet released + CAR.KONA_EV_2ND_GEN: HyundaiCarInfo("Hyundai Kona Electric (with HDA II, Korea only) 2023", video_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw", + car_parts=CarParts.common([CarHarness.hyundai_r])), CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", car_parts=CarParts.common([CarHarness.hyundai_d])), CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-23", "All", video_link="https://youtu.be/VnHzSTygTS4", - car_parts=CarParts.common([CarHarness.hyundai_l])), + car_parts=CarParts.common([CarHarness.hyundai_l])), CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), - CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), + CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-23", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", - car_parts=CarParts.common([CarHarness.hyundai_a])), + car_parts=CarParts.common([CarHarness.hyundai_a])), CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e])), CAR.TUCSON: [ HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_l])), @@ -198,8 +211,6 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { HyundaiCarInfo("Hyundai Ioniq 5 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), ], CAR.IONIQ_6: [ - # TODO: unknown - HyundaiCarInfo("Hyundai Ioniq 6 (without HDA II) 2023", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_k])), HyundaiCarInfo("Hyundai Ioniq 6 (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])), ], CAR.TUCSON_4TH_GEN: [ @@ -208,14 +219,16 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { ], CAR.TUCSON_HYBRID_4TH_GEN: HyundaiCarInfo("Hyundai Tucson Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_n])), CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2022-23", car_parts=CarParts.common([CarHarness.hyundai_n])), + CAR.CUSTIN_1ST_GEN: HyundaiCarInfo("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), # Kia CAR.KIA_FORTE: [ HyundaiCarInfo("Kia Forte 2019-21", car_parts=CarParts.common([CarHarness.hyundai_g])), HyundaiCarInfo("Kia Forte 2023", car_parts=CarParts.common([CarHarness.hyundai_e])), ], - CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", car_parts=CarParts.common([CarHarness.hyundai_a])), - CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_a])), + CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a])), + CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a])), + CAR.KIA_K8_HEV_1ST_GEN: HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), CAR.KIA_NIRO_EV: [ HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])), @@ -232,17 +245,16 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { ], CAR.KIA_NIRO_HEV_2ND_GEN: HyundaiCarInfo("Kia Niro Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_a])), CAR.KIA_OPTIMA_G4: HyundaiCarInfo("Kia Optima 2017", "Advanced Smart Cruise Control", - car_parts=CarParts.common([CarHarness.hyundai_b])), # TODO: may support 2016, 2018 + car_parts=CarParts.common([CarHarness.hyundai_b])), # TODO: may support 2016, 2018 CAR.KIA_OPTIMA_G4_FL: HyundaiCarInfo("Kia Optima 2019-20", car_parts=CarParts.common([CarHarness.hyundai_g])), - CAR.KIA_OPTIMA_H: [ - HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control"), # TODO: may support adjacent years - HyundaiCarInfo("Kia Optima Hybrid 2019"), - ], + # TODO: may support adjacent years. may have a non-zero minimum steering speed + CAR.KIA_OPTIMA_H: HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c])), + CAR.KIA_OPTIMA_H_G4_FL: HyundaiCarInfo("Kia Optima Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_h])), CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", car_parts=CarParts.common([CarHarness.hyundai_a])), CAR.KIA_SPORTAGE_5TH_GEN: HyundaiCarInfo("Kia Sportage 2023", car_parts=CarParts.common([CarHarness.hyundai_n])), CAR.KIA_SORENTO: [ - HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", - car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control & LKAS", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", + car_parts=CarParts.common([CarHarness.hyundai_e])), HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])), ], CAR.KIA_SORENTO_4TH_GEN: HyundaiCarInfo("Kia Sorento 2021-23", car_parts=CarParts.common([CarHarness.hyundai_k])), @@ -259,7 +271,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = { HyundaiCarInfo("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])) ], CAR.KIA_CARNIVAL_4TH_GEN: [ - HyundaiCarInfo("Kia Carnival 2023", car_parts=CarParts.common([CarHarness.hyundai_a])), + HyundaiCarInfo("Kia Carnival 2023-24", car_parts=CarParts.common([CarHarness.hyundai_a])), HyundaiCarInfo("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k])) ], @@ -389,8 +401,8 @@ def match_fw_to_car_fuzzy(live_fw_versions) -> Set[str]: # to distinguish between hybrid and ICE. All EVs so far are either exclusively # electric or specify electric in the platform code. # TODO: whitelist platforms that we've seen hybrid and ICE versions of that have these specifiers - fuzzy_platform_blacklist = set(CANFD_CAR - EV_CAR) - candidates = set() + fuzzy_platform_blacklist = {str(c) for c in set(CANFD_CAR - EV_CAR)} + candidates: Set[str] = set() for candidate, fws in FW_VERSIONS.items(): # Keep track of ECUs which pass all checks (platform codes, within date range) @@ -458,6 +470,7 @@ PART_NUMBER_FW_PATTERN = re.compile(b'(?<=[0-9][.,][0-9]{2} )([0-9]{5}[-/]?[A-Z] # TODO: use abs, it has the platform code and part number on many platforms PLATFORM_CODE_ECUS = [Ecu.fwdRadar, Ecu.fwdCamera, Ecu.eps] # So far we've only seen dates in fwdCamera +# TODO: there are date codes in the ABS firmware versions in hex DATE_FW_ECUS = [Ecu.fwdCamera] FW_QUERY_CONFIG = FwQueryConfig( @@ -521,6 +534,40 @@ FW_QUERY_CONFIG = FwQueryConfig( ) FW_VERSIONS = { + CAR.AZERA_6TH_GEN: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00IG__ SCC F-CU- 1.00 1.00 99110-G8100 ', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00IG MDPS C 1.00 1.02 56310G8510\x00 4IGSC103', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00IG MFC AT MES LHD 1.00 1.04 99211-G8100 200511', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00bcsh8p54 U912\x00\x00\x00\x00\x00\x00SIG0M35MH0\xa4 |.', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x81641KA051\x00\x00\x00\x00\x00\x00\x00\x00', + ], + }, + CAR.AZERA_HEV_6TH_GEN: { + (Ecu.fwdCamera, 0x7C4, None): [ + b'\xf1\x00IGH MFC AT KOR LHD 1.00 1.02 99211-G8100 191029', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00IG MDPS C 1.00 1.00 56310M9600\x00 4IHSC100', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00IGhe SCC FHCUP 1.00 1.00 99110-M9100 ', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x006T7N0_C2\x00\x006T7VA051\x00\x00TIGSH24KA1\xc7\x85\xe2`', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x816H590051\x00\x00\x00\x00\x00\x00\x00\x00', + ], + }, CAR.HYUNDAI_GENESIS: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00DH LKAS 1.1 -150210', @@ -575,11 +622,13 @@ FW_VERSIONS = { b'\xf1\x00AE MDPS C 1.00 1.01 56310/G2510 4APHC101', b'\xf1\x00AE MDPS C 1.00 1.01 56310/G2560 4APHC101', b'\xf1\x00AE MDPS C 1.00 1.01 56310G2510\x00 4APHC101', + b'\xf1\x00AE MDPS C 1.00 1.01 56310/G2310 4APHC101', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00AEP MFC AT USA LHD 1.00 1.01 95740-G2600 190819', b'\xf1\x00AEP MFC AT EUR RHD 1.00 1.01 95740-G2600 190819', b'\xf1\x00AEP MFC AT USA LHD 1.00 1.00 95740-G2700 201027', + b'\xf1\x00AEP MFC AT EUR LHD 1.00 1.01 95740-G2600 190819', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x816H6F6051\x00\x00\x00\x00\x00\x00\x00\x00', @@ -592,6 +641,7 @@ FW_VERSIONS = { b'\xf1\x816U3J9051\x00\x00\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00PAE0G16NL2\x00\x00\x00\x00', b'\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00PAE0G16NL0\x00\x00\x00\x00', b'\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00PAE0G16NL2\xad\xeb\xabt', + b'\xf1\x006U3H1_C2\x00\x006U3J8051\x00\x00PAETG16UL0\x00\x00\x00\x00', ], }, CAR.IONIQ_EV_2020: { @@ -915,6 +965,7 @@ FW_VERSIONS = { b'\xf1\x00TM ESC \x04 102!\x04\x05 58910-S2GA0', b'\xf1\x00TM ESC \x04 101 \x08\x04 58910-S2GA0', b'\xf1\x00TM ESC \x02 103"\x07\x08 58910-S2GA0', + b'\xf1\x00TM ESC 103!\x030 58910-S1MA0', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M1_0a0_L50', @@ -928,12 +979,15 @@ FW_VERSIONS = { b'\xf1\x81HM6M2_0a0_G00', b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M1_0a0_J10', b'\xf1\x8739101-2STN8\xf1\x81HM6M1_0a0_M00', + b'\xf1\x87 \xf1\x81 ', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00TM MDPS C 1.00 1.02 56370-S2AA0 0B19', b'\xf1\x00TM MDPS C 1.00 1.01 56310-S1AB0 4TSDC101', + b'\xf1\x00TM MDPS C 1.00 1.01 56310-S1EB0 4TSDC101', ], (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00TM MFC AT MES LHD 1.00 1.05 99211-S1500 220126', b'\xf1\x00TMA MFC AT MEX LHD 1.00 1.01 99211-S2500 210205', b'\xf1\x00TMA MFC AT USA LHD 1.00 1.00 99211-S2500 200720', b'\xf1\x00TM MFC AT EUR LHD 1.00 1.03 99211-S1500 210224', @@ -987,20 +1041,45 @@ FW_VERSIONS = { CAR.SANTA_FE_PHEV_2022: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x8799110CL500\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ', + b'\xf1\x00TMhe SCC FHCUP 1.00 1.01 99110-CL500 ', ], (Ecu.eps, 0x7d4, None): [ b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLAC0 4TSHC102', b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLEC0 4TSHC102', + b'\xf1\x00TM MDPS C 1.00 1.02 56310CLEC0\x00 4TSHC102', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00TMP MFC AT USA LHD 1.00 1.03 99211-S1500 210224', + b'\xf1\x00TMP MFC AT USA LHD 1.00 1.06 99211-S1500 220727', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA0o\x88^\xbe', b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea', + b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x87391312MTF0', + b'\xf1\x87391312MTF1', + ], + }, + CAR.CUSTIN_1ST_GEN: { + (Ecu.abs, 0x7d1, None): [ + b'\xf1\x00KU ESC \x01 101!\x02\x03 58910-O3200', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00KU__ SCC F-CUP 1.00 1.01 99110-O3000 ', + ], + (Ecu.eps, 0x7d4, None): [ + b'\xf1\x00KU MDPS C 1.00 1.01 56310/O3100 4KUCC101', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00KU2 MFC AT CHN LHD 1.00 1.02 99211-O3000 220923', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x87391212MEC0', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00bcsh8p54 U928\x00\x00\x00\x00\x00\x00SKU0T15KB2\x92U\xf9M', ], }, CAR.KIA_STINGER: { @@ -1328,16 +1407,22 @@ FW_VERSIONS = { b'\xf1\x8799110L2100\xf1\x00DL3_ SCC F-CUP 1.00 1.03 99110-L2100 ', b'\xf1\x8799110L2100\xf1\x00DL3_ SCC FHCUP 1.00 1.03 99110-L2100 ', b'\xf1\x00DL3_ SCC F-CUP 1.00 1.03 99110-L2100 ', + b'\xf1\x00DL3_ SCC FHCUP 1.00 1.03 99110-L2100 ', + b'\xf1\x00DL3_ SCC FHCUP 1.00 1.04 99110-L2100 ', ], (Ecu.eps, 0x7D4, None): [ b'\xf1\x8756310-L3110\xf1\000DL3 MDPS C 1.00 1.01 56310-L3110 4DLAC101', b'\xf1\x8756310-L3220\xf1\x00DL3 MDPS C 1.00 1.01 56310-L3220 4DLAC101', b'\xf1\x8757700-L3000\xf1\x00DL3 MDPS R 1.00 1.02 57700-L3000 4DLAP102', b'\xf1\x00DL3 MDPS C 1.00 1.01 56310-L3220 4DLAC101', + b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L2220 4DLDC102', + b'\xf1\x00DL3 MDPS C 1.00 1.02 56310L3220\x00 4DLAC102', ], (Ecu.fwdCamera, 0x7C4, None): [ b'\xf1\x00DL3 MFC AT USA LHD 1.00 1.03 99210-L3000 200915', b'\xf1\x00DL3 MFC AT USA LHD 1.00 1.04 99210-L3000 210208', + b'\xf1\x00DL3 MFC AT KOR LHD 1.00 1.04 99210-L2000 210527', + b'\xf1\x00DL3 MFC AT USA LHD 1.00 1.05 99210-L3000 211222', ], (Ecu.abs, 0x7D1, None): [ b'\xf1\000DL ESC \006 101 \004\002 58910-L3200', @@ -1345,11 +1430,15 @@ FW_VERSIONS = { b'\xf1\x8758910-L3800\xf1\x00DL ESC \t 101 \x07\x02 58910-L3800', b'\xf1\x8758910-L3600\xf1\x00DL ESC \x03 100 \x08\x02 58910-L3600', b'\xf1\x00DL ESC \t 100 \x06\x02 58910-L3800', + b'\xf1\x00DL ESC \x01 104 \x07\x12 58910-L2200', + b'\xf1\x00DL ESC \x06 103"\x08\x06 58910-L3200', ], (Ecu.engine, 0x7E0, None): [ b'\xf1\x87391212MKT0', b'\xf1\x87391212MKV0', b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x82DLDWN5TMDCXXXJ1B', + b'\xf1\x81HM6M2_0a0_DQ0', + b'\xf1\x87391212MKT3', ], (Ecu.transmission, 0x7E1, None): [ b'\xf1\000bcsh8p54 U913\000\000\000\000\000\000TDL2T16NB1ia\v\xb8', @@ -1358,6 +1447,8 @@ FW_VERSIONS = { b'\xf1\x87SCMSAA8572454GK1\x87x\x87\x88Vf\x86hgwvwvwwgvwwgT?\xfb\xff\x97fo\xffH\xb8\xf1\x81U913\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00TDL4T16NB05\x94t\x18', b'\xf1\x87954A02N300\x00\x00\x00\x00\x00\xf1\x81T02730A1 \xf1\x00T02601BL T02730A1 WDL3T25XXX730NS2b\x1f\xb8%', b'\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00TDL4T16NB05\x94t\x18', + b'\xf1\x00HT6TA261BLHT6TAB00A1SDL0C20KS0\x00\x00\x00\x00\x00\x00\\\x9f\xa5\x15', + b'\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00TDL2T16NB2.\x13\xf6\xed', ], }, CAR.KIA_K5_HEV_2020: { @@ -1366,15 +1457,18 @@ FW_VERSIONS = { ], (Ecu.eps, 0x7D4, None): [ b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L7000 4DLHC102', + b'\xf1\x00DL3 MDPS C 1.00 1.02 56310-L7220 4DLHC102', ], (Ecu.fwdCamera, 0x7C4, None): [ b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.02 99210-L2000 200309', + b'\xf1\x00DL3HMFC AT KOR LHD 1.00 1.04 99210-L2000 210527', ], (Ecu.engine, 0x7E0, None): [ b'\xf1\x87391162JLA0', ], (Ecu.transmission, 0x7E1, None): [ b'\xf1\x00PSBG2323 E08\x00\x00\x00\x00\x00\x00\x00TDL2H20KA2\xe3\xc6cz', + b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TDL2H20KA5T\xf2\xc9\xc2', ], }, CAR.KONA_EV: { @@ -1410,26 +1504,37 @@ FW_VERSIONS = { b'\xf1\x8758520-K4010\xf1\x00OS IEB \x04 101 \x11\x13 58520-K4010', b'\xf1\x8758520-K4010\xf1\x00OS IEB \x03 101 \x11\x13 58520-K4010', b'\xf1\x00OS IEB \r 102"\x05\x16 58520-K4010', - # TODO: these return from the MULTI request, above return from LONG - b'\x01\x04\x7f\xff\xff\xf8\xff\xff\x00\x00\x01\xd3\x00\x00\x00\x00\xff\xb7\xff\xee\xff\xe0\x00\xc0\xc0\xfc\xd5\xfc\x00\x00U\x10\xffP\xf5\xff\xfd\x00\x00\x00\x00\xfc\x00\x01', - b'\x01\x04\x7f\xff\xff\xf8\xff\xff\x00\x00\x01\xdb\x00\x00\x00\x00\xff\xb1\xff\xd9\xff\xd2\x00\xc0\xc0\xfc\xd5\xfc\x00\x00U\x10\xff\xd6\xf5\x00\x06\x00\x00\x00\x14\xfd\x00\x04', - b'\x01\x04\x7f\xff\xff\xf8\xff\xff\x00\x00\x01\xd3\x00\x00\x00\x00\xff\xb7\xff\xf4\xff\xd9\x00\xc0', + b'\xf1\x00OS IEB \x02 102"\x05\x16 58520-K4010', + b'\xf1\x00OS IEB \x03 102"\x05\x16 58520-K4010', ], (Ecu.fwdCamera, 0x7C4, None): [ b'\xf1\x00OSP LKA AT CND LHD 1.00 1.02 99211-J9110 802', b'\xf1\x00OSP LKA AT EUR RHD 1.00 1.02 99211-J9110 802', b'\xf1\x00OSP LKA AT AUS RHD 1.00 1.04 99211-J9200 904', b'\xf1\x00OSP LKA AT EUR LHD 1.00 1.04 99211-J9200 904', + b'\xf1\x00OSP LKA AT EUR RHD 1.00 1.04 99211-J9200 904', + b'\xf1\x00OSP LKA AT USA LHD 1.00 1.04 99211-J9200 904', ], (Ecu.eps, 0x7D4, None): [ b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4260\x00 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4970 4OEPC102', b'\xf1\x00OSP MDPS C 1.00 1.02 56310/K4271 4OEPC102', + b'\xf1\x00OSP MDPS C 1.00 1.02 56310-K4271 4OEPC102', + b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4971\x00 4OEPC102', + b'\xf1\x00OSP MDPS C 1.00 1.02 56310K4261\x00 4OEPC102', ], (Ecu.fwdRadar, 0x7D0, None): [ b'\xf1\x00YB__ FCA ----- 1.00 1.01 99110-K4500 \x00\x00\x00', ], }, + CAR.KONA_EV_2ND_GEN: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00SXev RDR ----- 1.00 1.00 99110-BF000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00SX2EMFC AT KOR LHD 1.00 1.00 99211-BF000 230410', + ], + }, CAR.KIA_NIRO_EV: { (Ecu.fwdRadar, 0x7D0, None): [ b'\xf1\x00DEev SCC F-CUP 1.00 1.00 99110-Q4000 ', @@ -1578,6 +1683,25 @@ FW_VERSIONS = { b'\xf1\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x816T6B8051\x00\x00\xf1\x006T6H0_C2\x00\x006T6B8051\x00\x00TJFSG24NH27\xa7\xc2\xb4', ], }, + CAR.KIA_OPTIMA_H: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00JFhe SCC FNCUP 1.00 1.00 96400-A8000 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00JFP LKAS AT EUR LHD 1.00 1.03 95895-A8100 160711', + ], + }, + CAR.KIA_OPTIMA_H_G4_FL: { + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00JFhe SCC FHCUP 1.00 1.01 99110-A8500 ', + ], + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00JFH MFC AT KOR LHD 1.00 1.01 95895-A8200 180323', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xf1\x816H6D1051\x00\x00\x00\x00\x00\x00\x00\x00', + ], + }, CAR.ELANTRA: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00PD LKAS AT USA LHD 1.01 1.01 95740-G3100 A54', @@ -1790,6 +1914,7 @@ FW_VERSIONS = { b'\xf1\x00CE__ RDR ----- 1.00 1.01 99110-KL000 ', ], (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00CE MFC AT EUR LHD 1.00 1.03 99211-KL000 221011', b'\xf1\x00CE MFC AT USA LHD 1.00 1.04 99211-KL000 221213', ], }, @@ -1809,10 +1934,12 @@ FW_VERSIONS = { b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9220 14K', b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9100 14A', b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9250 14W', + b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 2.02 99211-N9000 14E', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NX4__ 1.00 1.00 99110-N9100 ', b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ', + b'\xf1\x00NX4__ 1.00 1.01 99110-N9000 ', ], }, CAR.KIA_SPORTAGE_HYBRID_5TH_GEN: { @@ -1838,6 +1965,7 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1030 662', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1040 663', + b'\xf1\x00NQ5 FR_CMR AT AUS RHD 1.00 1.00 99211-P1040 663', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NQ5__ 1.00 1.02 99110-P1000 ', @@ -1871,10 +1999,12 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00MQ4 MFC AT USA LHD 1.00 1.05 99210-R5000 210623', b'\xf1\x00MQ4 MFC AT USA LHD 1.00 1.03 99210-R5000 200903', + b'\xf1\x00MQ4 MFC AT USA LHD 1.00 1.00 99210-R5100 221019', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00MQ4_ SCC FHCUP 1.00 1.06 99110-P2000 ', b'\xf1\x00MQ4_ SCC F-CUP 1.00 1.06 99110-P2000 ', + b'\xf1\x00MQ4_ SCC FHCUP 1.00 1.08 99110-P2000 ', ], }, CAR.KIA_NIRO_HEV_2ND_GEN: { @@ -1898,46 +2028,54 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00KA4 MFC AT USA LHD 1.00 1.06 99210-R0000 220221', b'\xf1\x00KA4CMFC AT CHN LHD 1.00 1.01 99211-I4000 210525', + b'\xf1\x00KA4 MFC AT USA LHD 1.00 1.00 99210-R0100 230105', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00KA4_ SCC FHCUP 1.00 1.03 99110-R0000 ', b'\xf1\x00KA4c SCC FHCUP 1.00 1.01 99110-I4000 ', + b'\xf1\x00KA4_ SCC FHCUP 1.00 1.00 99110-R0100 ', ], }, CAR.KIA_SORENTO_HEV_4TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00MQ4HMFC AT KOR LHD 1.00 1.12 99210-P2000 230331', + b'\xf1\x00MQ4HMFC AT USA LHD 1.00 1.11 99210-P2000 211217', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00MQhe SCC FHCUP 1.00 1.07 99110-P4000 ', ], }, + CAR.KIA_K8_HEV_1ST_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00GL3HMFC AT KOR LHD 1.00 1.03 99211-L8000 210907', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00GL3_ RDR ----- 1.00 1.02 99110-L8000 ', + ], + }, } CHECKSUM = { "crc8": [CAR.SANTA_FE, CAR.SONATA, CAR.PALISADE, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, - CAR.SONATA_HYBRID, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.KIA_K5_HEV_2020], + CAR.SONATA_HYBRID, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, + CAR.KIA_K5_HEV_2020, CAR.CUSTIN_1ST_GEN], "6B": [CAR.KIA_SORENTO, CAR.HYUNDAI_GENESIS], } CAN_GEARS = { - # which message has the gear + # which message has the gear. hybrid and EV use ELECT_GEAR "use_cluster_gears": {CAR.ELANTRA, CAR.KONA}, "use_tcu_gears": {CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON}, - "use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, - CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, - CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, - CAR.KONA_EV_2022, CAR.KIA_K5_HEV_2020}, } CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.TUCSON_4TH_GEN, CAR.TUCSON_HYBRID_4TH_GEN, CAR.KIA_SPORTAGE_HYBRID_5TH_GEN, CAR.SANTA_CRUZ_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_NIRO_HEV_2ND_GEN, CAR.KIA_NIRO_EV_2ND_GEN, - CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN} + CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KONA_EV_2ND_GEN, CAR.KIA_K8_HEV_1ST_GEN} # The radar does SCC on these cars when HDA I, rather than the camera CANFD_RADAR_SCC_CAR = {CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.GENESIS_GV80, - CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN} + CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KONA_EV_2ND_GEN, CAR.IONIQ_6} # The camera does SCC on these cars, rather than the radar CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } @@ -1946,21 +2084,26 @@ CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.TUCSON_HYBRID_4TH_GEN, CAR.KIA_SPORTAGE_HYBRID_5TH_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.KIA_K5_HEV_2020, CAR.KIA_NIRO_HEV_2ND_GEN, - CAR.KIA_SORENTO_HEV_4TH_GEN} + CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.KIA_K8_HEV_1ST_GEN, + CAR.AZERA_HEV_6TH_GEN} EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KONA_EV_2022, - CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.GENESIS_GV60_EV_1ST_GEN} + CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KONA_EV_2ND_GEN} # these cars require a special panda safety mode due to missing counters and checksums in the messages -LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_OPTIMA_G4, - CAR.VELOSTER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022} +LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.KIA_OPTIMA_G4, + CAR.VELOSTER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022, + CAR.KIA_OPTIMA_H} # these cars have not been verified to work with longitudinal yet - radar disable, sending correct messages, etc. -UNSUPPORTED_LONGITUDINAL_CAR = LEGACY_SAFETY_MODE_CAR | {CAR.KIA_NIRO_PHEV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA_G4_FL} +UNSUPPORTED_LONGITUDINAL_CAR = LEGACY_SAFETY_MODE_CAR | {CAR.KIA_NIRO_PHEV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA_G4_FL, + CAR.KIA_OPTIMA_H_G4_FL} # If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points. # If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py DBC = { + CAR.AZERA_6TH_GEN: dbc_dict('hyundai_kia_generic', None), + CAR.AZERA_HEV_6TH_GEN: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA_2021: dbc_dict('hyundai_kia_generic', None), CAR.ELANTRA_HEV_2021: dbc_dict('hyundai_kia_generic', None), @@ -1984,6 +2127,7 @@ DBC = { CAR.KIA_OPTIMA_G4: dbc_dict('hyundai_kia_generic', None), CAR.KIA_OPTIMA_G4_FL: dbc_dict('hyundai_kia_generic', None), CAR.KIA_OPTIMA_H: dbc_dict('hyundai_kia_generic', None), + CAR.KIA_OPTIMA_H_G4_FL: dbc_dict('hyundai_kia_generic', None), CAR.KIA_SELTOS: dbc_dict('hyundai_kia_generic', None), CAR.KIA_SORENTO: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format CAR.KIA_STINGER: dbc_dict('hyundai_kia_generic', None), @@ -2020,4 +2164,7 @@ DBC = { CAR.GENESIS_GV80: dbc_dict('hyundai_canfd', None), CAR.KIA_CARNIVAL_4TH_GEN: dbc_dict('hyundai_canfd', None), CAR.KIA_SORENTO_HEV_4TH_GEN: dbc_dict('hyundai_canfd', None), + CAR.KONA_EV_2ND_GEN: dbc_dict('hyundai_canfd', None), + CAR.KIA_K8_HEV_1ST_GEN: dbc_dict('hyundai_canfd', None), + CAR.CUSTIN_1ST_GEN: dbc_dict('hyundai_kia_generic', None), } diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 92b392fc0..004adad3b 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -1,13 +1,14 @@ import yaml import os import time +import numpy as np from abc import abstractmethod, ABC from typing import Any, Dict, Optional, Tuple, List, Callable from cereal import car from openpilot.common.basedir import BASEDIR from openpilot.common.conversions import Conversions as CV -from openpilot.common.kalman.simple_kalman import KF1D +from openpilot.common.kalman.simple_kalman import KF1D, get_kalman_gain from openpilot.common.numpy_fast import clip from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG @@ -335,12 +336,13 @@ class CarStateBase(ABC): self.cluster_speed_hyst_gap = 0.0 self.cluster_min_speed = 0.0 # min speed before dropping to 0 - # Q = np.matrix([[0.0, 0.0], [0.0, 100.0]]) - # R = 0.3 - self.v_ego_kf = KF1D(x0=[[0.0], [0.0]], - A=[[1.0, DT_CTRL], [0.0, 1.0]], - C=[1.0, 0.0], - K=[[0.17406039], [1.65925647]]) + Q = [[0.0, 0.0], [0.0, 100.0]] + R = 0.3 + A = [[1.0, DT_CTRL], [0.0, 1.0]] + C = [[1.0, 0.0]] + x0=[[0.0], [0.0]] + K = get_kalman_gain(DT_CTRL, np.array(A), np.array(C), np.array(Q), R) + self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K) def update_speed_kf(self, v_ego_raw): if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 0230be229..168ddd49e 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -1,4 +1,5 @@ from dataclasses import dataclass, field +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -25,7 +26,7 @@ class CarControllerParams: pass -class CAR: +class CAR(StrEnum): CX5 = "MAZDA CX-5" CX9 = "MAZDA CX-9" MAZDA3 = "MAZDA 3" @@ -46,7 +47,7 @@ CAR_INFO: Dict[str, Union[MazdaCarInfo, List[MazdaCarInfo]]] = { CAR.MAZDA3: MazdaCarInfo("Mazda 3 2017-18"), CAR.MAZDA6: MazdaCarInfo("Mazda 6 2017-20"), CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021-23", video_link="https://youtu.be/dA3duO4a0O4"), - CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022-23"), + CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022-24"), } @@ -97,6 +98,7 @@ FW_VERSIONS = { b'K131-67XK2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.abs, 0x760, None): [ + b'KGWD-437K2-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'KSD5-437K2-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x706, None): [ @@ -110,6 +112,7 @@ FW_VERSIONS = { b'SH51-21PS1-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXDL-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXFG-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PXFG-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, CAR.CX5: { diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index d36f972a8..c7821bdb9 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -1,61 +1,35 @@ #!/usr/bin/env python3 from cereal import car -from openpilot.system.swaglog import cloudlog import cereal.messaging as messaging -from openpilot.selfdrive.car import get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase - -# mocked car interface to work with chffrplus +# mocked car interface for dashcam mode class CarInterface(CarInterfaceBase): def __init__(self, CP, CarController, CarState): super().__init__(CP, CarController, CarState) - cloudlog.debug("Using Mock Car Interface") - - self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal']) - self.speed = 0. - self.prev_speed = 0. + self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal']) @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "mock" - ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput)] ret.mass = 1700. ret.wheelbase = 2.70 ret.centerToFront = ret.wheelbase * 0.5 - ret.steerRatio = 13. # reasonable - + ret.steerRatio = 13. return ret - # returns a car.CarState def _update(self, c): self.sm.update(0) gps_sock = 'gpsLocationExternal' if self.sm.rcv_frame['gpsLocationExternal'] > 1 else 'gpsLocation' - if self.sm.updated[gps_sock]: - self.prev_speed = self.speed - self.speed = self.sm[gps_sock].speed - # create message ret = car.CarState.new_message() - - # speeds - ret.vEgo = self.speed - ret.vEgoRaw = self.speed - - ret.aEgo = self.speed - self.prev_speed - ret.brakePressed = ret.aEgo < -0.5 - - ret.standstill = self.speed < 0.01 - ret.wheelSpeeds.fl = self.speed - ret.wheelSpeeds.fr = self.speed - ret.wheelSpeeds.rl = self.speed - ret.wheelSpeeds.rr = self.speed + ret.vEgo = self.sm[gps_sock].speed + ret.vEgoRaw = self.sm[gps_sock].speed return ret def apply(self, c, now_nanos): - # in mock no carcontrols actuators = car.CarControl.Actuators.new_message() return actuators, [] diff --git a/selfdrive/car/mock/radar_interface.py b/selfdrive/car/mock/radar_interface.py index b461fcd5f..e654bd61f 100755 --- a/selfdrive/car/mock/radar_interface.py +++ b/selfdrive/car/mock/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): diff --git a/selfdrive/car/mock/values.py b/selfdrive/car/mock/values.py index 8426041b3..0823109e5 100644 --- a/selfdrive/car/mock/values.py +++ b/selfdrive/car/mock/values.py @@ -1,9 +1,10 @@ +from strenum import StrEnum from typing import Dict, List, Optional, Union from openpilot.selfdrive.car.docs_definitions import CarInfo -class CAR: +class CAR(StrEnum): MOCK = 'mock' diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 3d6b6cb70..aedcaa188 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python3 from cereal import car +from panda import Panda from openpilot.selfdrive.car import get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.nissan.values import CAR @@ -31,7 +31,7 @@ class CarInterface(CarInterfaceBase): ret.centerToFront = ret.wheelbase * 0.44 elif candidate == CAR.ALTIMA: # Altima has EPS on C-CAN unlike the others that have it on V-CAN - ret.safetyConfigs[0].safetyParam = 1 # EPS is on alternate bus + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_NISSAN_ALT_EPS_BUS ret.mass = 1492 ret.wheelbase = 2.824 ret.centerToFront = ret.wheelbase * 0.44 diff --git a/selfdrive/car/nissan/radar_interface.py b/selfdrive/car/nissan/radar_interface.py index b461fcd5f..e654bd61f 100644 --- a/selfdrive/car/nissan/radar_interface.py +++ b/selfdrive/car/nissan/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): diff --git a/selfdrive/car/nissan/values.py b/selfdrive/car/nissan/values.py index 979e09eb6..067217f70 100644 --- a/selfdrive/car/nissan/values.py +++ b/selfdrive/car/nissan/values.py @@ -1,5 +1,6 @@ # ruff: noqa: E501 from dataclasses import dataclass, field +from strenum import StrEnum from typing import Dict, List, Optional, Union from cereal import car @@ -21,7 +22,7 @@ class CarControllerParams: pass -class CAR: +class CAR(StrEnum): XTRAIL = "NISSAN X-TRAIL 2017" LEAF = "NISSAN LEAF 2018" # Leaf with ADAS ECU found behind instrument cluster instead of glovebox diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index aef830e2f..19304efdb 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -1,9 +1,13 @@ from openpilot.common.numpy_fast import clip, interp from opendbc.can.packer import CANPacker -from openpilot.selfdrive.car import apply_driver_steer_torque_limits +from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance from openpilot.selfdrive.car.subaru import subarucan -from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, CanBus, CarControllerParams, SubaruFlags -from openpilot.selfdrive.car.subaru.values import HYBRID_CARS +from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, HYBRID_CARS, STEER_RATE_LIMITED, CanBus, CarControllerParams, SubaruFlags + +# FIXME: These limits aren't exact. The real limit is more than likely over a larger time period and +# involves the total steering angle change rather than rate, but these limits work well for now +MAX_STEER_RATE = 25 # deg/s +MAX_STEER_RATE_FRAMES = 7 # tx control frames needed before torque can be cut class CarController: @@ -13,6 +17,7 @@ class CarController: self.frame = 0 self.cruise_button_prev = 0 + self.steer_rate_counter = 0 self.p = CarControllerParams(CP) self.packer = CANPacker(DBC[CP.carFingerprint]['pt']) @@ -37,9 +42,17 @@ class CarController: apply_steer = 0 if self.CP.carFingerprint in PREGLOBAL_CARS: - can_sends.append(subarucan.create_preglobal_steering_control(self.packer, apply_steer, CC.latActive)) + can_sends.append(subarucan.create_preglobal_steering_control(self.packer, self.frame // self.p.STEER_STEP, apply_steer, CC.latActive)) else: - can_sends.append(subarucan.create_steering_control(self.packer, apply_steer, CC.latActive)) + apply_steer_req = CC.latActive + + if self.CP.carFingerprint in STEER_RATE_LIMITED: + # Steering rate fault prevention + self.steer_rate_counter, apply_steer_req = \ + common_fault_avoidance(abs(CS.out.steeringRateDeg) > MAX_STEER_RATE, apply_steer_req, + self.steer_rate_counter, MAX_STEER_RATE_FRAMES) + + can_sends.append(subarucan.create_steering_control(self.packer, apply_steer, apply_steer_req)) self.apply_steer_last = apply_steer @@ -81,29 +94,30 @@ class CarController: else: if self.frame % 10 == 0: - can_sends.append(subarucan.create_es_dashstatus(self.packer, CS.es_dashstatus_msg, CC.enabled, self.CP.openpilotLongitudinalControl, + can_sends.append(subarucan.create_es_dashstatus(self.packer, self.frame // 10, CS.es_dashstatus_msg, CC.enabled, self.CP.openpilotLongitudinalControl, CC.longActive, hud_control.leadVisible)) - can_sends.append(subarucan.create_es_lkas_state(self.packer, CS.es_lkas_state_msg, CC.enabled, hud_control.visualAlert, + can_sends.append(subarucan.create_es_lkas_state(self.packer, self.frame // 10, CS.es_lkas_state_msg, CC.enabled, hud_control.visualAlert, hud_control.leftLaneVisible, hud_control.rightLaneVisible, hud_control.leftLaneDepart, hud_control.rightLaneDepart)) if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: - can_sends.append(subarucan.create_es_infotainment(self.packer, CS.es_infotainment_msg, hud_control.visualAlert)) + can_sends.append(subarucan.create_es_infotainment(self.packer, self.frame // 10, CS.es_infotainment_msg, hud_control.visualAlert)) if self.CP.openpilotLongitudinalControl: if self.frame % 5 == 0: - can_sends.append(subarucan.create_es_status(self.packer, CS.es_status_msg, self.CP.openpilotLongitudinalControl, CC.longActive, cruise_rpm)) + can_sends.append(subarucan.create_es_status(self.packer, self.frame // 5, CS.es_status_msg, + self.CP.openpilotLongitudinalControl, CC.longActive, cruise_rpm)) - can_sends.append(subarucan.create_es_brake(self.packer, CS.es_brake_msg, CC.enabled, cruise_brake)) + can_sends.append(subarucan.create_es_brake(self.packer, self.frame // 5, CS.es_brake_msg, CC.enabled, cruise_brake)) - can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, 0, pcm_cancel_cmd, + can_sends.append(subarucan.create_es_distance(self.packer, self.frame // 5, CS.es_distance_msg, 0, pcm_cancel_cmd, self.CP.openpilotLongitudinalControl, cruise_brake > 0, cruise_throttle)) else: if pcm_cancel_cmd: if self.CP.carFingerprint not in HYBRID_CARS: bus = CanBus.alt if self.CP.carFingerprint in GLOBAL_GEN2 else CanBus.main - can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, bus, pcm_cancel_cmd)) + can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg["COUNTER"] + 1, CS.es_distance_msg, bus, pcm_cancel_cmd)) new_actuators = actuators.copy() new_actuators.steer = self.apply_steer_last / self.p.STEER_MAX diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index 9c46305c1..c8a6dfe1e 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -4,9 +4,8 @@ from opendbc.can.can_define import CANDefine from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser -from openpilot.selfdrive.car.subaru.values import DBC, CAR, GLOBAL_GEN2, PREGLOBAL_CARS, CanBus, SubaruFlags +from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, HYBRID_CARS, CanBus, SubaruFlags from openpilot.selfdrive.car import CanSignalRateCalculator -from openpilot.selfdrive.car.subaru.values import HYBRID_CARS class CarState(CarStateBase): @@ -25,7 +24,7 @@ class CarState(CarStateBase): ret.gasPressed = ret.gas > 1e-5 if self.car_fingerprint in PREGLOBAL_CARS: - ret.brakePressed = cp.vl["Brake_Pedal"]["Brake_Pedal"] > 2 + ret.brakePressed = cp.vl["Brake_Pedal"]["Brake_Pedal"] > 0 else: cp_brakes = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp ret.brakePressed = cp_brakes.vl["Brake_Status"]["Brake"] == 1 @@ -101,17 +100,18 @@ class CarState(CarStateBase): self.es_brake_msg = copy.copy(cp_es_brake.vl["ES_Brake"]) cp_es_status = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam - if self.car_fingerprint not in HYBRID_CARS: # Hybrid cars don't have es_distance, need a replacement + # TODO: Hybrid cars don't have ES_Distance, need a replacement + if self.car_fingerprint not in HYBRID_CARS: # 8 is known AEB, there are a few other values related to AEB we ignore ret.stockAeb = (cp_es_distance.vl["ES_Brake"]["AEB_Status"] == 8) and \ - (cp_es_distance.vl["ES_Brake"]["Brake_Pressure"] != 0) - self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"]) + (cp_es_distance.vl["ES_Brake"]["Brake_Pressure"] != 0) self.es_status_msg = copy.copy(cp_es_status.vl["ES_Status"]) self.cruise_control_msg = copy.copy(cp_cruise.vl["CruiseControl"]) if self.car_fingerprint not in HYBRID_CARS: self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"]) + self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"]) if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: self.es_infotainment_msg = copy.copy(cp_cam.vl["ES_Infotainment"]) @@ -144,6 +144,16 @@ class CarState(CarStateBase): return messages + @staticmethod + def get_common_preglobal_body_messages(): + messages = [ + ("CruiseControl", 50), + ("Wheel_Speeds", 50), + ("Dash_State2", 1), + ] + + return messages + @staticmethod def get_can_parser(CP): messages = [ @@ -166,29 +176,8 @@ class CarState(CarStateBase): if CP.carFingerprint not in PREGLOBAL_CARS: if CP.carFingerprint not in GLOBAL_GEN2: messages += CarState.get_common_global_body_messages(CP) - - messages += [ - ("Dashlights", 10), - ("BodyInfo", 10), - ] else: - messages += [ - ("Wheel_Speeds", 50), - ("Dash_State2", 1), - ] - - if CP.carFingerprint == CAR.FORESTER_PREGLOBAL: - messages += [ - ("Dashlights", 20), - ("BodyInfo", 1), - ("CruiseControl", 50), - ] - - if CP.carFingerprint in (CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018): - messages += [ - ("Dashlights", 10), - ("CruiseControl", 50), - ] + messages += CarState.get_common_preglobal_body_messages() return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.main) diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 53aa67b48..107467cbf 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from cereal import car from panda import Panda from openpilot.selfdrive.car import get_safety_config @@ -14,9 +13,9 @@ class CarInterface(CarInterfaceBase): ret.carName = "subaru" ret.radarUnavailable = True # for HYBRID CARS to be upstreamed, we need: - # - replacement for ES_Distance so we can cancel the cruise control - # - to find the Cruise_Activated bit from the car - # - proper panda safety setup (use the correct cruise_activated bit, throttle from Throttle_Hybrid, etc) + # - replacement for ES_Distance so we can cancel the cruise control + # - to find the Cruise_Activated bit from the car + # - proper panda safety setup (use the correct cruise_activated bit, throttle from Throttle_Hybrid, etc) ret.dashcamOnly = candidate in (PREGLOBAL_CARS | LKAS_ANGLE | HYBRID_CARS) ret.autoResumeSng = False @@ -44,7 +43,7 @@ class CarInterface(CarInterfaceBase): else: CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - if candidate == CAR.ASCENT: + if candidate in (CAR.ASCENT, CAR.ASCENT_2023): ret.mass = 2031. ret.wheelbase = 2.89 ret.centerToFront = ret.wheelbase * 0.5 @@ -83,7 +82,7 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 17 ret.steerActuatorDelay = 0.1 - elif candidate in (CAR.FORESTER, CAR.FORESTER_2022): + elif candidate in (CAR.FORESTER, CAR.FORESTER_2022, CAR.FORESTER_HYBRID): ret.mass = 1568. ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 diff --git a/selfdrive/car/subaru/radar_interface.py b/selfdrive/car/subaru/radar_interface.py index b461fcd5f..e654bd61f 100644 --- a/selfdrive/car/subaru/radar_interface.py +++ b/selfdrive/car/subaru/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): diff --git a/selfdrive/car/subaru/subarucan.py b/selfdrive/car/subaru/subarucan.py index 890473a24..57c1ae774 100644 --- a/selfdrive/car/subaru/subarucan.py +++ b/selfdrive/car/subaru/subarucan.py @@ -16,16 +16,15 @@ def create_steering_control(packer, apply_steer, steer_req): def create_steering_status(packer): return packer.make_can_msg("ES_LKAS_State", 0, {}) -def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd, long_enabled = False, brake_cmd = False, cruise_throttle = 0): +def create_es_distance(packer, frame, es_distance_msg, bus, pcm_cancel_cmd, long_enabled = False, brake_cmd = False, cruise_throttle = 0): values = {s: es_distance_msg[s] for s in [ "CHECKSUM", - "COUNTER", "Signal1", "Cruise_Fault", "Cruise_Throttle", "Signal2", "Car_Follow", - "Signal3", + "Low_Speed_Follow", "Cruise_Soft_Disable", "Signal7", "Cruise_Brake_Active", @@ -39,7 +38,8 @@ def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd, long_enable "Cruise_Resume", "Signal6", ]} - values["COUNTER"] = (values["COUNTER"] + 1) % 0x10 + + values["COUNTER"] = frame % 0x10 if long_enabled: values["Cruise_Throttle"] = cruise_throttle @@ -57,10 +57,9 @@ def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd, long_enable return packer.make_can_msg("ES_Distance", bus, values) -def create_es_lkas_state(packer, es_lkas_state_msg, enabled, visual_alert, left_line, right_line, left_lane_depart, right_lane_depart): +def create_es_lkas_state(packer, frame, es_lkas_state_msg, enabled, visual_alert, left_line, right_line, left_lane_depart, right_lane_depart): values = {s: es_lkas_state_msg[s] for s in [ "CHECKSUM", - "COUNTER", "LKAS_Alert_Msg", "Signal1", "LKAS_ACTIVE", @@ -77,6 +76,8 @@ def create_es_lkas_state(packer, es_lkas_state_msg, enabled, visual_alert, left_ "Signal3", ]} + values["COUNTER"] = frame % 0x10 + # Filter the stock LKAS "Keep hands on wheel" alert if values["LKAS_Alert_Msg"] == 1: values["LKAS_Alert_Msg"] = 0 @@ -119,10 +120,9 @@ def create_es_lkas_state(packer, es_lkas_state_msg, enabled, visual_alert, left_ return packer.make_can_msg("ES_LKAS_State", CanBus.main, values) -def create_es_dashstatus(packer, dashstatus_msg, enabled, long_enabled, long_active, lead_visible): +def create_es_dashstatus(packer, frame, dashstatus_msg, enabled, long_enabled, long_active, lead_visible): values = {s: dashstatus_msg[s] for s in [ "CHECKSUM", - "COUNTER", "PCB_Off", "LDW_Off", "Signal1", @@ -150,6 +150,8 @@ def create_es_dashstatus(packer, dashstatus_msg, enabled, long_enabled, long_act "Cruise_State", ]} + values["COUNTER"] = frame % 0x10 + if enabled and long_active: values["Cruise_State"] = 0 values["Cruise_Activated"] = 1 @@ -165,10 +167,9 @@ def create_es_dashstatus(packer, dashstatus_msg, enabled, long_enabled, long_act return packer.make_can_msg("ES_DashStatus", CanBus.main, values) -def create_es_brake(packer, es_brake_msg, enabled, brake_value): +def create_es_brake(packer, frame, es_brake_msg, enabled, brake_value): values = {s: es_brake_msg[s] for s in [ "CHECKSUM", - "COUNTER", "Signal1", "Brake_Pressure", "AEB_Status", @@ -179,6 +180,8 @@ def create_es_brake(packer, es_brake_msg, enabled, brake_value): "Signal3", ]} + values["COUNTER"] = frame % 0x10 + if enabled: values["Cruise_Activated"] = 1 @@ -190,10 +193,9 @@ def create_es_brake(packer, es_brake_msg, enabled, brake_value): return packer.make_can_msg("ES_Brake", CanBus.main, values) -def create_es_status(packer, es_status_msg, long_enabled, long_active, cruise_rpm): +def create_es_status(packer, frame, es_status_msg, long_enabled, long_active, cruise_rpm): values = {s: es_status_msg[s] for s in [ "CHECKSUM", - "COUNTER", "Signal1", "Cruise_Fault", "Cruise_RPM", @@ -204,6 +206,8 @@ def create_es_status(packer, es_status_msg, long_enabled, long_active, cruise_rp "Signal3", ]} + values["COUNTER"] = frame % 0x10 + if long_enabled: values["Cruise_RPM"] = cruise_rpm @@ -213,16 +217,18 @@ def create_es_status(packer, es_status_msg, long_enabled, long_active, cruise_rp return packer.make_can_msg("ES_Status", CanBus.main, values) -def create_es_infotainment(packer, es_infotainment_msg, visual_alert): +def create_es_infotainment(packer, frame, es_infotainment_msg, visual_alert): # Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts values = {s: es_infotainment_msg[s] for s in [ "CHECKSUM", - "COUNTER", "LKAS_State_Infotainment", "LKAS_Blue_Lines", "Signal1", "Signal2", ]} + + values["COUNTER"] = frame % 0x10 + if values["LKAS_State_Infotainment"] in (3, 4): values["LKAS_State_Infotainment"] = 0 @@ -239,13 +245,14 @@ def create_es_infotainment(packer, es_infotainment_msg, visual_alert): # *** Subaru Pre-global *** -def subaru_preglobal_checksum(packer, values, addr): +def subaru_preglobal_checksum(packer, values, addr, checksum_byte=7): dat = packer.make_can_msg(addr, 0, values)[2] - return (sum(dat[:7])) % 256 + return (sum(dat[:checksum_byte]) + sum(dat[checksum_byte+1:])) % 256 -def create_preglobal_steering_control(packer, apply_steer, steer_req): +def create_preglobal_steering_control(packer, frame, apply_steer, steer_req): values = { + "COUNTER": frame % 0x08, "LKAS_Command": apply_steer, "LKAS_Active": steer_req, } @@ -260,7 +267,7 @@ def create_preglobal_es_distance(packer, cruise_button, es_distance_msg): "Signal1", "Car_Follow", "Signal2", - "Brake_On", + "Cruise_Brake_Active", "Distance_Swap", "Standstill", "Signal3", diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 4cc1df975..7ee3be026 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -1,5 +1,6 @@ from dataclasses import dataclass, field from enum import Enum, IntFlag +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -63,14 +64,16 @@ class CanBus: camera = 2 -class CAR: +class CAR(StrEnum): # Global platform ASCENT = "SUBARU ASCENT LIMITED 2019" + ASCENT_2023 = "SUBARU ASCENT 2023" IMPREZA = "SUBARU IMPREZA LIMITED 2019" IMPREZA_2020 = "SUBARU IMPREZA SPORT 2020" FORESTER = "SUBARU FORESTER 2019" OUTBACK = "SUBARU OUTBACK 6TH GEN" CROSSTREK_HYBRID = "SUBARU CROSSTREK HYBRID 2020" + FORESTER_HYBRID = "SUBARU FORESTER HYBRID 2020" LEGACY = "SUBARU LEGACY 7TH GEN" FORESTER_2022 = "SUBARU FORESTER 2022" OUTBACK_2023 = "SUBARU OUTBACK 7TH GEN" @@ -112,7 +115,8 @@ CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { SubaruCarInfo("Subaru XV 2020-21"), ], # TODO: is there an XV and Impreza too? - CAR.CROSSTREK_HYBRID: SubaruCarInfo("Subaru Crosstrek Hybrid 2020"), + CAR.CROSSTREK_HYBRID: SubaruCarInfo("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b])), + CAR.FORESTER_HYBRID: SubaruCarInfo("Subaru Forester Hybrid 2020"), CAR.FORESTER: SubaruCarInfo("Subaru Forester 2019-21", "All"), CAR.FORESTER_PREGLOBAL: SubaruCarInfo("Subaru Forester 2017-18"), CAR.LEGACY_PREGLOBAL: SubaruCarInfo("Subaru Legacy 2015-18"), @@ -120,6 +124,7 @@ CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { CAR.OUTBACK_PREGLOBAL_2018: SubaruCarInfo("Subaru Outback 2018-19"), CAR.FORESTER_2022: SubaruCarInfo("Subaru Forester 2022", "All", car_parts=CarParts.common([CarHarness.subaru_c])), CAR.OUTBACK_2023: SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), + CAR.ASCENT_2023: SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), } SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ @@ -134,6 +139,7 @@ FW_QUERY_CONFIG = FwQueryConfig( [StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE], ), # Some Eyesight modules fail on TESTER_PRESENT_REQUEST + # TODO: check if this resolves the fingerprinting issue for the 2023 Ascent and other new Subaru cars Request( [SUBARU_VERSION_REQUEST], [SUBARU_VERSION_RESPONSE], @@ -175,6 +181,23 @@ FW_VERSIONS = { b'\x01\xfe\xfa\x00\x00', ], }, + CAR.ASCENT_2023: { + (Ecu.abs, 0x7b0, None): [ + b'\xa5 #\x03\x00', + ], + (Ecu.eps, 0x746, None): [ + b'%\xc0\xd0\x11', + ], + (Ecu.fwdCamera, 0x787, None): [ + b'\x05!\x08\x1dK\x05!\x08\x01/', + ], + (Ecu.engine, 0x7a2, None): [ + b'\xe5,\xa0P\x07', + ], + (Ecu.transmission, 0x7a3, None): [ + b'\x04\xfe\xf3\x00\x00', + ], + }, CAR.LEGACY: { (Ecu.abs, 0x7b0, None): [ b'\xa1\\ x04\x01', @@ -288,6 +311,7 @@ FW_VERSIONS = { b'\xa2 !`\000', b'\xf1\x00\xb2\x06\x04', b'\xa2 `\x00', + b'\xa2 !3\x00', ], (Ecu.eps, 0x746, None): [ b'\x9a\xc0\000\000', @@ -301,6 +325,8 @@ FW_VERSIONS = { b'\x00\x00eq\x1f@ "', b'\x00\x00eq\x00\x00\x00\x00', b'\x00\x00e\x8f\x00\x00\x00\x00', + b'\x00\x00e\x92\x00\x00\x00\x00', + b'\x00\x00e\xa4\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'\xca!ap\a', @@ -308,6 +334,7 @@ FW_VERSIONS = { b'\xca!`0\a', b'\xcc\"f0\a', b'\xcc!fp\a', + b'\xcc!`p\x07', b'\xca!f@\x07', b'\xca!fp\x07', b'\xf3"f@\x07', @@ -315,10 +342,12 @@ FW_VERSIONS = { b'\xf3"fp\x07', b'\xe6"f0\x07', b'\xe6"fp\x07', + b'\xe6!`@\x07', ], (Ecu.transmission, 0x7e1, None): [ b'\xe6\xf5\004\000\000', b'\xe6\xf5$\000\000', + b'\xe7\xf5\x04\x00\x00', b'\xe7\xf6B0\000', b'\xe7\xf5D0\000', b'\xf1\x00\xd7\x10@', @@ -326,6 +355,7 @@ FW_VERSIONS = { b'\xe9\xf6F0\x00', b'\xe9\xf5B0\x00', b'\xe9\xf6B0\x00', + b'\xe9\xf5"\x00\x00', ], }, CAR.CROSSTREK_HYBRID: { @@ -389,6 +419,23 @@ FW_VERSIONS = { b'\x1a\xe6F1\x00', ], }, + CAR.FORESTER_HYBRID: { + (Ecu.abs, 0x7b0, None): [ + b'\xa3 \x19T\x00', + ], + (Ecu.eps, 0x746, None): [ + b'\x8d\xc2\x00\x00', + ], + (Ecu.fwdCamera, 0x787, None): [ + b'\x00\x00eY\x1f@ !', + ], + (Ecu.engine, 0x7e0, None): [ + b'\xd2\xa1`r\x07', + ], + (Ecu.transmission, 0x7e1, None): [ + b'\x1b\xa7@a\x00', + ], + }, CAR.FORESTER_PREGLOBAL: { (Ecu.abs, 0x7b0, None): [ b'\x7d\x97\x14\x40', @@ -625,30 +672,36 @@ FW_VERSIONS = { }, CAR.OUTBACK_2023: { (Ecu.abs, 0x7b0, None): [ + b'\xa1 #\x14\x00', b'\xa1 #\x17\x00', ], (Ecu.eps, 0x746, None): [ + b'+\xc0\x10\x11\x00', b'+\xc0\x12\x11\x00', ], (Ecu.fwdCamera, 0x787, None): [ b'\t!\x08\x046\x05!\x08\x01/', ], (Ecu.engine, 0x7a2, None): [ + b'\xed,\xa0q\x07', b'\xed,\xa2q\x07', ], (Ecu.transmission, 0x7a3, None): [ b'\xa8\x8e\xf41\x00', + b'\xa8\xfe\xf41\x00', ] } } DBC = { CAR.ASCENT: dbc_dict('subaru_global_2017_generated', None), + CAR.ASCENT_2023: dbc_dict('subaru_global_2017_generated', None), CAR.IMPREZA: dbc_dict('subaru_global_2017_generated', None), CAR.IMPREZA_2020: dbc_dict('subaru_global_2017_generated', None), CAR.FORESTER: dbc_dict('subaru_global_2017_generated', None), CAR.FORESTER_2022: dbc_dict('subaru_global_2017_generated', None), CAR.OUTBACK: dbc_dict('subaru_global_2017_generated', None), + CAR.FORESTER_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None), CAR.CROSSTREK_HYBRID: dbc_dict('subaru_global_2020_hybrid_generated', None), CAR.OUTBACK_2023: dbc_dict('subaru_global_2017_generated', None), CAR.LEGACY: dbc_dict('subaru_global_2017_generated', None), @@ -658,7 +711,11 @@ DBC = { CAR.OUTBACK_PREGLOBAL_2018: dbc_dict('subaru_outback_2019_generated', None), } -LKAS_ANGLE = {CAR.FORESTER_2022, CAR.OUTBACK_2023} -GLOBAL_GEN2 = {CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023} +LKAS_ANGLE = {CAR.FORESTER_2022, CAR.OUTBACK_2023, CAR.ASCENT_2023} +GLOBAL_GEN2 = {CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023, CAR.ASCENT_2023} PREGLOBAL_CARS = {CAR.FORESTER_PREGLOBAL, CAR.LEGACY_PREGLOBAL, CAR.OUTBACK_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018} -HYBRID_CARS = {CAR.CROSSTREK_HYBRID, } \ No newline at end of file +HYBRID_CARS = {CAR.CROSSTREK_HYBRID, CAR.FORESTER_HYBRID} + +# Cars that temporarily fault when steering angle rate is greater than some threshold. +# Appears to be all cars that started production after 2020 +STEER_RATE_LIMITED = GLOBAL_GEN2 | {CAR.IMPREZA_2020} diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py index ed9c59cca..4210c4b85 100755 --- a/selfdrive/car/tesla/interface.py +++ b/selfdrive/car/tesla/interface.py @@ -7,7 +7,6 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.common.params import Params - class CarInterface(CarInterfaceBase): @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): diff --git a/selfdrive/car/tesla/values.py b/selfdrive/car/tesla/values.py index 15283ae4b..fee8d127f 100644 --- a/selfdrive/car/tesla/values.py +++ b/selfdrive/car/tesla/values.py @@ -1,5 +1,6 @@ # ruff: noqa: E501 from collections import namedtuple +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -12,7 +13,7 @@ Ecu = car.CarParams.Ecu Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) -class CAR: +class CAR(StrEnum): AP1_MODELS = 'TESLA AP1 MODEL S' AP2_MODELS = 'TESLA AP2 MODEL S' diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index a447fc21b..787b5d631 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -1,19 +1,25 @@ #!/usr/bin/env python3 +import os import math import unittest import hypothesis.strategies as st -from hypothesis import given, settings +from hypothesis import Phase, given, settings import importlib from parameterized import parameterized -from cereal import car +from cereal import car, messaging from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car import gen_empty_fingerprint from openpilot.selfdrive.car.car_helpers import interfaces from openpilot.selfdrive.car.fingerprints import all_known_cars +from openpilot.selfdrive.car.fw_versions import FW_VERSIONS from openpilot.selfdrive.car.interfaces import get_interface_attr from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator +ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()}) + +MAX_EXAMPLES = int(os.environ.get('MAX_EXAMPLES', '5')) + def get_fuzzy_car_interface_args(draw: DrawType) -> dict: # Fuzzy CAN fingerprints and FW versions to test more states of the CarInterface @@ -21,12 +27,8 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict: st.integers(min_value=0, max_value=64)) for key in gen_empty_fingerprint()}) - # just the most important fields - car_fw_strategy = st.lists(st.fixed_dictionaries({ - 'ecu': st.sampled_from(list(car.CarParams.Ecu.schema.enumerants.keys())), - # TODO: only use reasonable addrs for the paired ecu and brand/platform - 'address': st.integers(min_value=0, max_value=0x800), - })) + # only pick from possible ecus to reduce search space + car_fw_strategy = st.lists(st.sampled_from(ALL_ECUS)) params_strategy = st.fixed_dictionaries({ 'fingerprints': fingerprint_strategy, @@ -35,14 +37,21 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict: }) params: dict = draw(params_strategy) - params['car_fw'] = [car.CarParams.CarFw(**fw) for fw in params['car_fw']] + params['car_fw'] = [car.CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0) for fw in params['car_fw']] return params class TestCarInterfaces(unittest.TestCase): + @classmethod + def setUpClass(cls): + os.environ['NO_RADAR_SLEEP'] = '1' + + # FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause + # many generated examples to overrun when max_examples > ~20, don't use it @parameterized.expand([(car,) for car in sorted(all_known_cars())]) - @settings(max_examples=5) + @settings(max_examples=MAX_EXAMPLES, deadline=None, + phases=(Phase.reuse, Phase.generate, Phase.shrink)) @given(data=st.data()) def test_car_interfaces(self, car_name, data): CarInterface, CarController, CarState = interfaces[car_name] @@ -78,9 +87,6 @@ class TestCarInterfaces(unittest.TestCase): self.assertTrue(not math.isnan(tune.torque.kf) and tune.torque.kf > 0) self.assertTrue(not math.isnan(tune.torque.friction) and tune.torque.friction > 0) - elif tune.which() == 'indi': - self.assertTrue(len(tune.indi.outerLoopGainV)) - cc_msg = FuzzyGenerator.get_random_msg(data.draw, car.CarControl, real_floats=True) # Run car interface now_nanos = 0 @@ -110,6 +116,12 @@ class TestCarInterfaces(unittest.TestCase): hasattr(radar_interface, '_update') and hasattr(radar_interface, 'trigger_msg'): radar_interface._update([radar_interface.trigger_msg]) + # Test radar fault + if not car_params.radarUnavailable and radar_interface.rcp is not None: + cans = [messaging.new_message('can', 1).to_bytes() for _ in range(5)] + rr = radar_interface.update(cans) + self.assertTrue(rr is None or len(rr.errors) > 0) + def test_interface_attrs(self): """Asserts basic behavior of interface attribute getter""" num_brands = len(get_interface_attr('CAR')) diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index 372484fa6..b8c929968 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -10,6 +10,7 @@ NISSAN ROGUE 2019: [.nan, 1.5, .nan] # New subarus angle based controllers SUBARU FORESTER 2022: [.nan, 3.0, .nan] SUBARU OUTBACK 7TH GEN: [.nan, 3.0, .nan] +SUBARU ASCENT 2023: [.nan, 3.0, .nan] # Toyota LTA also has torque TOYOTA RAV4 2023: [.nan, 3.0, .nan] @@ -56,6 +57,12 @@ KIA CARNIVAL 4TH GEN: [1.75, 1.75, 0.15] GMC ACADIA DENALI 2018: [1.6, 1.6, 0.2] LEXUS IS 2023: [2.0, 2.0, 0.1] KIA SORENTO HYBRID 4TH GEN: [2.5, 2.5, 0.1] +HYUNDAI KONA ELECTRIC 2ND GEN: [2.5, 2.5, 0.1] +HYUNDAI IONIQ 6 2023: [2.5, 2.5, 0.1] +HYUNDAI AZERA 6TH GEN: [1.8, 1.8, 0.1] +HYUNDAI AZERA HYBRID 6TH GEN: [1.8, 1.8, 0.1] +KIA K8 HYBRID 1ST GEN: [2.5, 2.5, 0.1] +HYUNDAI CUSTIN 1ST GEN: [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car mock: [10.0, 10, 0.0] diff --git a/selfdrive/car/torque_data/params.yaml b/selfdrive/car/torque_data/params.yaml index 800507d91..86984525e 100644 --- a/selfdrive/car/torque_data/params.yaml +++ b/selfdrive/car/torque_data/params.yaml @@ -45,15 +45,12 @@ KIA K5 2021: [2.405339728085138, 1.460032270828705, 0.11650989850813716] KIA NIRO EV 2020: [2.9215954981365337, 2.1500583840260044, 0.09236802474810267] KIA SORENTO GT LINE 2018: [2.464854685101844, 1.5335274218367956, 0.12056170567599558] KIA STINGER GT2 2018: [2.7499043387418967, 1.849652021986449, 0.12048334239559202] -LEXUS ES 2019: [1.935835, 2.134803912579666, 0.093439] -LEXUS ES HYBRID 2019: [2.135678, 1.863360677810788, 0.109627] -LEXUS NX 2018: [2.302625600642627, 2.1382378491466625, 0.14986840878892838] +LEXUS ES 2019: [2.0357564999999997, 1.999082295195227, 0.101533] +LEXUS NX 2018: [2.3525924753753613, 1.9731412277641067, 0.15168101064205927] LEXUS NX 2020: [2.4331999786982936, 2.1045680431705414, 0.14099899317761067] -LEXUS NX HYBRID 2018: [2.4025593501080955, 1.8080446063815507, 0.15349361249519017] LEXUS RX 2016: [1.5876816543130423, 1.0427699298523752, 0.21334066732397142] -LEXUS RX 2020: [1.5228812994274734, 1.431102486563665, 0.164117] +LEXUS RX 2020: [1.5375561442049257, 1.343166476215164, 0.1931062001527557] LEXUS RX HYBRID 2017: [1.6984261557042386, 1.3211501880159107, 0.1820354534928893] -LEXUS RX HYBRID 2020: [1.5522309889823778, 1.255230465866663, 0.2220954003055114] MAZDA CX-9 2021: [1.7601682915983443, 1.0889677335154337, 0.17713792194297195] SKODA SUPERB 3RD GEN: [1.166437404652981, 1.1686163012668165, 0.12194533036948708] SUBARU FORESTER 2019: [3.6617001649776793, 2.342197172531713, 0.11075960785398745] @@ -69,8 +66,7 @@ TOYOTA CAMRY 2021: [2.446083, 2.3476510120007434, 0.121615] TOYOTA CAMRY HYBRID 2018: [1.996333, 1.7996193116697359, 0.112565] TOYOTA CAMRY HYBRID 2021: [2.263582, 2.3901492458927986, 0.115257] TOYOTA COROLLA 2017: [3.117154369115421, 1.8438132575043773, 0.12289685869250652] -TOYOTA COROLLA HYBRID TSS2 2019: [1.9079729107361805, 1.8118712531729109, 0.22251440891543514] -TOYOTA COROLLA TSS2 2019: [2.0742917676766712, 1.9258612322678952, 0.16888685704519352] +TOYOTA COROLLA TSS2 2019: [1.991132339206426, 1.868866242720403, 0.19570063298031432] TOYOTA HIGHLANDER 2017: [1.8696367437248915, 1.626293990451463, 0.17485372210240796] TOYOTA HIGHLANDER 2020: [2.022340166827233, 1.6183134804881791, 0.14592306380054457] TOYOTA HIGHLANDER HYBRID 2018: [1.752033, 1.6433903296845025, 0.144600] @@ -79,13 +75,10 @@ TOYOTA MIRAI 2021: [2.506899832157829, 1.7417213930750164, 0.20182618449440565] TOYOTA PRIUS 2017: [1.60, 1.5023147650693636, 0.151515] TOYOTA PRIUS TSS2 2021: [1.972600, 1.9104337425537743, 0.170968] TOYOTA RAV4 2017: [2.085695074355425, 2.2142832316984733, 0.13339165270103975] -TOYOTA RAV4 2019: [2.331293, 2.0993589721530252, 0.129822] -TOYOTA RAV4 2019 8965: [2.5084506298290377, 2.4216520504763475, 0.11992835265067918] -TOYOTA RAV4 2019 x02: [2.7209621987605024, 2.2148637653781593, 0.10862567142268198] +TOYOTA RAV4 2019: [2.279239424615458, 2.087101966779332, 0.13682208413446817] +TOYOTA RAV4 2019 8965: [2.3080951748210854, 2.1189367835820603, 0.12942102328134028] +TOYOTA RAV4 2019 x02: [2.762293266024922, 2.243615865975329, 0.11113568178327986] TOYOTA RAV4 HYBRID 2017: [1.9796257271652042, 1.7503987331707576, 0.14628860048885406] -TOYOTA RAV4 HYBRID 2019: [2.2271858492309153, 2.074844961405639, 0.14382216826893632] -TOYOTA RAV4 HYBRID 2019 8965: [2.1077397198131336, 1.8162215166877735, 0.13891369391200137] -TOYOTA RAV4 HYBRID 2019 x02: [2.803624333289342, 2.272367966572498, 0.11364569214387774] TOYOTA RAV4 HYBRID 2022: [2.241883248393209, 1.9304407208090029, 0.112174] TOYOTA RAV4 HYBRID 2022 x02: [3.044930631831037, 2.3979189796380918, 0.14023209146703736] TOYOTA SIENNA 2018: [1.689726, 1.3208264576110418, 0.140456] diff --git a/selfdrive/car/torque_data/substitute.yaml b/selfdrive/car/torque_data/substitute.yaml index dced8aa19..9decbbfa0 100644 --- a/selfdrive/car/torque_data/substitute.yaml +++ b/selfdrive/car/torque_data/substitute.yaml @@ -8,13 +8,11 @@ TOYOTA ALPHARD HYBRID 2021 : TOYOTA SIENNA 2018 TOYOTA ALPHARD 2020: TOYOTA SIENNA 2018 TOYOTA PRIUS v 2017 : TOYOTA PRIUS 2017 TOYOTA RAV4 2022: TOYOTA RAV4 HYBRID 2022 -TOYOTA C-HR HYBRID 2018: TOYOTA C-HR 2018 TOYOTA C-HR HYBRID 2022: TOYOTA C-HR 2021 LEXUS IS 2018: LEXUS NX 2018 LEXUS CT HYBRID 2018 : LEXUS NX 2018 LEXUS ES 2018: TOYOTA CAMRY HYBRID 2018 LEXUS ES HYBRID 2018: TOYOTA CAMRY HYBRID 2018 -LEXUS NX HYBRID 2020: LEXUS NX 2020 LEXUS RC 2020: LEXUS NX 2020 TOYOTA AVALON HYBRID 2019: TOYOTA AVALON 2019 TOYOTA AVALON HYBRID 2022: TOYOTA AVALON 2022 @@ -22,6 +20,7 @@ TOYOTA AVALON HYBRID 2022: TOYOTA AVALON 2022 KIA OPTIMA 4TH GEN: HYUNDAI SONATA 2020 KIA OPTIMA 4TH GEN FACELIFT: HYUNDAI SONATA 2020 KIA OPTIMA HYBRID 2017 & SPORTS 2019: HYUNDAI SONATA 2020 +KIA OPTIMA HYBRID 4TH GEN FACELIFT: HYUNDAI SONATA 2020 KIA FORTE E 2018 & GT 2021: HYUNDAI SONATA 2020 KIA CEED INTRO ED 2019: HYUNDAI SONATA 2020 KIA SELTOS 2021: HYUNDAI SONATA 2020 @@ -34,7 +33,6 @@ HYUNDAI KONA ELECTRIC 2022: HYUNDAI KONA ELECTRIC 2019 HYUNDAI IONIQ HYBRID 2017-2019: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ HYBRID 2020-2022: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ ELECTRIC 2020: HYUNDAI IONIQ PLUG-IN HYBRID 2019 -HYUNDAI IONIQ 6 2023: HYUNDAI IONIQ 5 2022 HYUNDAI ELANTRA 2017: HYUNDAI SONATA 2019 HYUNDAI ELANTRA HYBRID 2021: HYUNDAI SONATA 2020 HYUNDAI TUCSON 2019: HYUNDAI SANTA FE 2019 @@ -77,6 +75,7 @@ SEAT LEON 3RD GEN: VOLKSWAGEN GOLF 7TH GEN SEAT ATECA 1ST GEN: VOLKSWAGEN GOLF 7TH GEN SUBARU CROSSTREK HYBRID 2020: SUBARU IMPREZA SPORT 2020 +SUBARU FORESTER HYBRID 2020: SUBARU IMPREZA SPORT 2020 SUBARU LEGACY 7TH GEN: SUBARU OUTBACK 6TH GEN # Old subarus don't have much data guessing it's like low torque impreza @@ -85,6 +84,3 @@ SUBARU OUTBACK 2015 - 2017: SUBARU IMPREZA LIMITED 2019 SUBARU FORESTER 2017 - 2018: SUBARU IMPREZA LIMITED 2019 SUBARU LEGACY 2015 - 2018: SUBARU IMPREZA LIMITED 2019 SUBARU ASCENT LIMITED 2019: SUBARU FORESTER 2019 - -# custom -HONDA CR-V HYBRID 2019 w/ BSM: HONDA CR-V HYBRID 2019 diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index e245354c4..9a69881f7 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -2,9 +2,7 @@ from cereal import car from openpilot.common.numpy_fast import clip, interp from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \ create_gas_interceptor_command, make_can_msg -from openpilot.selfdrive.car.toyota.toyotacan import create_steer_command, create_ui_command, \ - create_accel_command, create_acc_cancel_command, \ - create_fcw_command, create_lta_steer_command +from openpilot.selfdrive.car.toyota import toyotacan from openpilot.selfdrive.car.toyota.values import CAR, STATIC_DSU_MSGS, NO_STOP_TIMER_CAR, TSS2_CAR, \ MIN_ACC_SPEED, PEDAL_TRANSITION, CarControllerParams, ToyotaFlags, \ UNSUPPORTED_DSU_CAR @@ -34,6 +32,22 @@ UNLOCK_CMD = b'\x40\x05\x30\x11\x00\x40\x00\x00' LOCK_CMD = b'\x40\x05\x30\x11\x00\x80\x00\x00' LOCK_AT_SPEED = 10 * CV.KPH_TO_MS +# Blindspot codes +LEFT_BLINDSPOT = b'\x41' +RIGHT_BLINDSPOT = b'\x42' + +def set_blindspot_debug_mode(lr,enable): + if enable: + m = lr + b'\x02\x10\x60\x00\x00\x00\x00' + else: + m = lr + b'\x02\x10\x01\x00\x00\x00\x00' + return make_can_msg(0x750, m, 0) + + +def poll_blindspot_status(lr): + m = lr + b'\x02\x21\x69\x00\x00\x00\x00' + return make_can_msg(0x750, m, 0) + class CarController: def __init__(self, dbc_name, CP, VM): self.CP = CP @@ -57,6 +71,18 @@ class CarController: self.dp_toyota_auto_unlock = p.get_bool("dp_toyota_auto_unlock") self.dp_toyota_sng = p.get_bool("dp_toyota_sng") + # dp - bsm + self.dp_toyota_enhanced_bsm = p.get_bool("dp_toyota_enhanced_bsm") + self._blindspot_debug_enabled_left = False + self._blindspot_debug_enabled_right = False + self._blindspot_frame = 0 + if self.CP.carFingerprint in TSS2_CAR: # tss2 can do higher hz then tss1 and can be on at all speed/standstill + self._blindspot_rate = 2 + self._blindspot_always_on = True + else: + self._blindspot_rate = 20 + self._blindspot_always_on = False + def update(self, CC, CS, now_nanos): actuators = CC.actuators @@ -73,15 +99,54 @@ class CarController: if not CS.out.doorOpen: gear = CS.out.gearShifter if gear == GearShifter.park and self.dp_toyota_auto_lock_gear_prev != gear: - if self.dp_toyota_auto_lock: + if self.dp_toyota_auto_unlock: can_sends.append(make_can_msg(0x750, UNLOCK_CMD, 0)) self.dp_toyota_auto_lock_once = False elif gear == GearShifter.drive and not self.dp_toyota_auto_lock_once and CS.out.vEgo >= LOCK_AT_SPEED: - if self.dp_toyota_auto_unlock: + if self.dp_toyota_auto_lock: can_sends.append(make_can_msg(0x750, LOCK_CMD, 0)) self.dp_toyota_auto_lock_once = True self.dp_toyota_auto_lock_gear_prev = gear + # Enable blindspot debug mode once (@arne182) + # let's keep all the commented out code for easy debug purpose for future. + if self.dp_toyota_enhanced_bsm: + #if self.frame > 200: + #left bsm + if not self._blindspot_debug_enabled_left: + if (self._blindspot_always_on or (CS.out.leftBlinker and CS.out.vEgo > 6)): # eagle eye camera will stop working if right bsm is switched on under 6m/s + can_sends.append(set_blindspot_debug_mode(LEFT_BLINDSPOT, True)) + self._blindspot_debug_enabled_left = True + # print("bsm debug left, on") + else: + if not self._blindspot_always_on and not CS.out.leftBlinker and self.frame - self._blindspot_frame > 50: + can_sends.append(set_blindspot_debug_mode(LEFT_BLINDSPOT, False)) + self._blindspot_debug_enabled_left = False + # print("bsm debug left, off") + if self.frame % self._blindspot_rate == 0: + can_sends.append(poll_blindspot_status(LEFT_BLINDSPOT)) + if CS.out.leftBlinker: + self._blindspot_frame = self.frame + # print(self._blindspot_frame) + # print("bsm poll left") + #right bsm + if not self._blindspot_debug_enabled_right: + if (self._blindspot_always_on or (CS.out.rightBlinker and CS.out.vEgo > 6)): # eagle eye camera will stop working if right bsm is switched on under 6m/s + can_sends.append(set_blindspot_debug_mode(RIGHT_BLINDSPOT, True)) + self._blindspot_debug_enabled_right = True + # print("bsm debug right, on") + else: + if not self._blindspot_always_on and not CS.out.rightBlinker and self.frame - self._blindspot_frame > 50: + can_sends.append(set_blindspot_debug_mode(RIGHT_BLINDSPOT, False)) + self._blindspot_debug_enabled_right = False + # print("bsm debug right, off") + if self.frame % self._blindspot_rate == self._blindspot_rate/2: + can_sends.append(poll_blindspot_status(RIGHT_BLINDSPOT)) + if CS.out.rightBlinker: + self._blindspot_frame = self.frame + # print(self._blindspot_frame) + # print("bsm poll right") + # *** steer torque *** new_steer = int(round(actuators.steer * self.params.STEER_MAX)) apply_steer = apply_meas_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.params) @@ -115,13 +180,13 @@ class CarController: # toyota can trace shows this message at 42Hz, with counter adding alternatively 1 and 2; # sending it at 100Hz seem to allow a higher rate limit, as the rate limit seems imposed # on consecutive messages - can_sends.append(create_steer_command(self.packer, apply_steer, apply_steer_req)) + can_sends.append(toyotacan.create_steer_command(self.packer, apply_steer, apply_steer_req)) if self.frame % 2 == 0 and self.CP.carFingerprint in TSS2_CAR: lta_active = lat_active and self.CP.steerControlType == SteerControlType.angle full_torque_condition = (abs(CS.out.steeringTorqueEps) < self.params.STEER_MAX and abs(CS.out.steeringTorque) < MAX_DRIVER_TORQUE_ALLOWANCE) setme_x64 = 100 if lta_active and full_torque_condition else 0 - can_sends.append(create_lta_steer_command(self.packer, self.last_angle if lta_active else 0, lta_active, self.frame // 2, setme_x64)) + can_sends.append(toyotacan.create_lta_steer_command(self.packer, self.last_angle, lta_active, self.frame // 2, setme_x64)) # *** gas and brake *** if self.CP.enableGasInterceptor and CC.longActive: @@ -157,18 +222,22 @@ class CarController: self.last_standstill = CS.out.standstill + # handle UI messages + fcw_alert = hud_control.visualAlert == VisualAlert.fcw + steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw) + # we can spam can to cancel the system even if we are using lat only control if (self.frame % 3 == 0 and self.CP.openpilotLongitudinalControl) or pcm_cancel_cmd: lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged # Lexus IS uses a different cancellation message if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR: - can_sends.append(create_acc_cancel_command(self.packer)) + can_sends.append(toyotacan.create_acc_cancel_command(self.packer)) elif self.CP.openpilotLongitudinalControl: - can_sends.append(create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type)) + can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert)) self.accel = pcm_accel_cmd else: - can_sends.append(create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type)) + can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False)) if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl: # send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd. @@ -181,9 +250,6 @@ class CarController: # ui mesg is at 1Hz but we send asap if: # - there is something to display # - there is something to stop displaying - fcw_alert = hud_control.visualAlert == VisualAlert.fcw - steer_alert = hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw) - send_ui = False if ((fcw_alert or steer_alert) and not self.alert_active) or \ (not (fcw_alert or steer_alert) and self.alert_active): @@ -194,12 +260,12 @@ class CarController: send_ui = True if self.frame % 20 == 0 or send_ui: - can_sends.append(create_ui_command(self.packer, steer_alert, pcm_cancel_cmd, hud_control.leftLaneVisible, - hud_control.rightLaneVisible, hud_control.leftLaneDepart, - hud_control.rightLaneDepart, CC.enabled, CS.lkas_hud)) + can_sends.append(toyotacan.create_ui_command(self.packer, steer_alert, pcm_cancel_cmd, hud_control.leftLaneVisible, + hud_control.rightLaneVisible, hud_control.leftLaneDepart, + hud_control.rightLaneDepart, CC.enabled, CS.lkas_hud)) if (self.frame % 100 == 0 or send_ui) and (self.CP.enableDsu or self.CP.flags & ToyotaFlags.DISABLE_RADAR.value): - can_sends.append(create_fcw_command(self.packer, fcw_alert)) + can_sends.append(toyotacan.create_fcw_command(self.packer, fcw_alert)) # *** static msgs *** for addr, cars, bus, fr_step, vl in STATIC_DSU_MSGS: diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index c96df6f10..a436c6583 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -11,6 +11,8 @@ from openpilot.selfdrive.car.interfaces import CarStateBase from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \ TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR +from openpilot.common.params import Params + SteerControlType = car.CarParams.SteerControlType # These steering fault definitions seem to be common across LKA (torque) and LTA (angle): @@ -24,6 +26,8 @@ TEMP_STEER_FAULTS = (0, 9, 11, 21, 25) # - prolonged high driver torque: 17 (permanent) PERM_STEER_FAULTS = (3, 17) +ZSS_THRESHOLD = 4.0 +ZSS_THRESHOLD_COUNT = 10 class CarState(CarStateBase): def __init__(self, CP): @@ -44,6 +48,28 @@ class CarState(CarStateBase): self.acc_type = 1 self.lkas_hud = {} + # zss + params = Params() + self._dp_alka = params.get_bool('dp_alka') + self._dp_toyota_zss = params.get_bool('dp_toyota_zss') + self._dp_zss_compute = False + self._dp_zss_cruise_active_last = False + self._dp_zss_angle_offset = 0. + self._dp_zss_threshold_count = 0 + + # bsm + self.dp_toyota_enhanced_bsm = params.get_bool('dp_toyota_enhanced_bsm') + self._left_blindspot = False + self._left_blindspot_d1 = 0 + self._left_blindspot_d2 = 0 + self._left_blindspot_counter = 0 + + self._right_blindspot = False + self._right_blindspot_d1 = 0 + self._right_blindspot_d2 = 0 + self._right_blindspot_counter = 0 + + def update(self, cp, cp_cam): ret = car.CarState.new_message() @@ -58,9 +84,7 @@ class CarState(CarStateBase): ret.gas = (cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) // 2 ret.gasPressed = ret.gas > 805 else: - # TODO: find a new, common signal - msg = "GAS_PEDAL_HYBRID" if (self.CP.flags & ToyotaFlags.HYBRID) else "GAS_PEDAL" - ret.gas = cp.vl[msg]["GAS_PEDAL"] + # TODO: find a common gas pedal percentage signal ret.gasPressed = cp.vl["PCM_CRUISE"]["GAS_RELEASED"] == 0 ret.wheelSpeeds = self.get_wheel_speeds( @@ -91,6 +115,35 @@ class CarState(CarStateBase): ret.steeringAngleOffsetDeg = self.angle_offset.x ret.steeringAngleDeg = torque_sensor_angle_deg - self.angle_offset.x + # dp - toyota zss + # if diff between steeringAngleDeg and ZSS is too large, disable ZSS + if self._dp_zss_threshold_count > ZSS_THRESHOLD_COUNT: + self._dp_toyota_zss = False + + if self._dp_toyota_zss: + zorro_steer = cp.vl["SECONDARY_STEER_ANGLE"]["ZORRO_STEER"] + # rick - when alka is on, we check main_on state + acc_active = (self._dp_alka and cp.vl["PCM_CRUISE_2"]["MAIN_ON"] != 0) or bool(cp.vl["PCM_CRUISE"]["CRUISE_ACTIVE"]) + # only compute zss offset when acc is active + if acc_active and not self._dp_zss_cruise_active_last: + self._dp_zss_threshold_count = 0 + self._dp_zss_compute = True # cruise was just activated, so allow offset to be recomputed + self._dp_zss_cruise_active_last = acc_active + + # compute zss offset + if self._dp_zss_compute: + if abs(ret.steeringAngleDeg) > 1e-3 and abs(zorro_steer) > 1e-3: + self._dp_zss_compute = False + self._dp_zss_angle_offset = zorro_steer - ret.steeringAngleDeg + + # error check + new_steering_angle_deg = zorro_steer - self._dp_zss_angle_offset + if abs(ret.steeringAngleDeg - new_steering_angle_deg) > ZSS_THRESHOLD: + self._dp_zss_threshold_count += 1 + else: + ret.steeringAngleDeg = new_steering_angle_deg + + ret.steeringRateDeg = cp.vl["STEER_ANGLE_SENSOR"]["STEER_RATE"] can_gear = int(cp.vl["GEAR_PACKET"]["GEAR"]) @@ -163,6 +216,50 @@ class CarState(CarStateBase): if self.CP.carFingerprint != CAR.PRIUS_V: self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"]) + # Enable blindspot debug mode once (@arne182) + # let's keep all the commented out code for easy debug purpose for future. + if self.dp_toyota_enhanced_bsm and self.frame > 199: #self.CP.carFingerprint == CAR.PRIUS_TSS2: #not (self.CP.carFingerprint in TSS2_CAR or self.CP.carFingerprint == CAR.CAMRY or self.CP.carFingerprint == CAR.CAMRYH): + distance_1 = cp.vl["DEBUG"].get('BLINDSPOTD1') + distance_2 = cp.vl["DEBUG"].get('BLINDSPOTD2') + side = cp.vl["DEBUG"].get('BLINDSPOTSIDE') + + if distance_1 is not None and distance_2 is not None and side is not None: + if side == 65: # Left blind spot + if distance_1 != self._left_blindspot_d1: + self._left_blindspot_d1 = distance_1 + self._left_blindspot_counter = 100 + if distance_2 != self._left_blindspot_d2: + self._left_blindspot_d2 = distance_2 + self._left_blindspot_counter = 100 + if self._left_blindspot_d1 > 10 or self._left_blindspot_d2 > 10: + self._left_blindspot = True + elif side == 66: # Right blind spot + if distance_1 != self._right_blindspot_d1: + self._right_blindspot_d1 = distance_1 + self._right_blindspot_counter = 100 + if distance_2 != self._right_blindspot_d2: + self._right_blindspot_d2 = distance_2 + self._right_blindspot_counter = 100 + if self._right_blindspot_d1 > 10 or self._right_blindspot_d2 > 10: + self._right_blindspot = True + + if self._left_blindspot_counter > 0: + self._left_blindspot_counter -= 1 + else: + self._left_blindspot = False + self._left_blindspot_d1 = 0 + self._left_blindspot_d2 = 0 + + if self._right_blindspot_counter > 0: + self._right_blindspot_counter -= 1 + else: + self._right_blindspot = False + self._right_blindspot_d1 = 0 + self._right_blindspot_d2 = 0 + + ret.leftBlindspot = self._left_blindspot + ret.rightBlindspot = self._right_blindspot + return ret @staticmethod @@ -183,11 +280,6 @@ class CarState(CarStateBase): ("STEER_TORQUE_SENSOR", 50), ] - if CP.flags & ToyotaFlags.HYBRID: - messages.append(("GAS_PEDAL_HYBRID", 33)) - else: - messages.append(("GAS_PEDAL", 33)) - if CP.carFingerprint in UNSUPPORTED_DSU_CAR: messages.append(("DSU_CRUISE", 5)) messages.append(("PCM_CRUISE_ALT", 1)) @@ -210,11 +302,18 @@ class CarState(CarStateBase): ("PCS_HUD", 1), ] - if CP.carFingerprint not in (TSS2_CAR - RADAR_ACC_CAR) and not CP.enableDsu: + if CP.carFingerprint not in (TSS2_CAR - RADAR_ACC_CAR) and not CP.enableDsu and not CP.flags & ToyotaFlags.DISABLE_RADAR.value: messages += [ ("PRE_COLLISION", 33), ] + params = Params() + if params.get_bool('dp_toyota_zss'): + messages.append(("SECONDARY_STEER_ANGLE", 0)) + + if params.get_bool('dp_toyota_enhanced_bsm'): + messages.append(("DEBUG", 65)) + return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0) @staticmethod diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index b4312bc59..e103caab0 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -1,10 +1,9 @@ -#!/usr/bin/env python3 from cereal import car from openpilot.common.conversions import Conversions as CV from panda import Panda from panda.python import uds from openpilot.selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \ - MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR + MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR from openpilot.selfdrive.car import get_safety_config from openpilot.selfdrive.car.disable_ecu import disable_ecu from openpilot.selfdrive.car.interfaces import CarInterfaceBase @@ -82,7 +81,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFactor = 0.444 # not optimized yet ret.mass = 2860. * CV.LB_TO_KG # mean between normal and hybrid - elif candidate in (CAR.LEXUS_RX, CAR.LEXUS_RXH, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2): + elif candidate in (CAR.LEXUS_RX, CAR.LEXUS_RXH, CAR.LEXUS_RX_TSS2): stop_and_go = True ret.wheelbase = 2.79 ret.steerRatio = 16. # 14.8 is spec end-to-end @@ -90,7 +89,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFactor = 0.5533 ret.mass = 4481. * CV.LB_TO_KG # mean between min and max - elif candidate in (CAR.CHR, CAR.CHRH, CAR.CHR_TSS2, CAR.CHRH_TSS2): + elif candidate in (CAR.CHR, CAR.CHR_TSS2, CAR.CHRH_TSS2): stop_and_go = True ret.wheelbase = 2.63906 ret.steerRatio = 13.6 @@ -120,7 +119,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFactor = 0.7983 ret.mass = 3505. * CV.LB_TO_KG # mean between normal and hybrid - elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, + elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.RAV4H_TSS2_2023): ret.wheelbase = 2.68986 ret.steerRatio = 14.3 @@ -142,13 +141,13 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kf = 0.00004 break - elif candidate in (CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2): + elif candidate == CAR.COROLLA_TSS2: ret.wheelbase = 2.67 # Average between 2.70 for sedan and 2.64 for hatchback ret.steerRatio = 13.9 ret.tireStiffnessFactor = 0.444 # not optimized yet ret.mass = 3060. * CV.LB_TO_KG - elif candidate in (CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2): + elif candidate in (CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_ES_TSS2): if candidate not in (CAR.LEXUS_ES,): # TODO: LEXUS_ES may have sng stop_and_go = True ret.wheelbase = 2.8702 @@ -176,7 +175,7 @@ class CarInterface(CarInterfaceBase): ret.tireStiffnessFactor = 0.517 ret.mass = 3108 * CV.LB_TO_KG # mean between min and max - elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NXH, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2): + elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2): stop_and_go = True ret.wheelbase = 2.66 ret.steerRatio = 14.7 @@ -203,10 +202,14 @@ class CarInterface(CarInterfaceBase): ret.mass = 4305. * CV.LB_TO_KG ret.centerToFront = ret.wheelbase * 0.44 + + # TODO: Some TSS-P platforms have BSM, but are flipped based on region or driving direction. + # Detect flipped signals and enable for C-HR and others ret.enableBsm = 0x3F6 in fingerprint[0] and candidate in TSS2_CAR # Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it - if 0x2FF in fingerprint[0]: + # 0x2AA is sent by a similar device which intercepts the radar instead of DSU on NO_DSU_CARs + if 0x2FF in fingerprint[0] or (0x2AA in fingerprint[0] and candidate in NO_DSU_CAR): ret.flags |= ToyotaFlags.SMART_DSU.value # No radar dbc for cars without DSU which are not TSS 2.0 @@ -220,13 +223,14 @@ class CarInterface(CarInterfaceBase): ret.enableGasInterceptor = 0x201 in fingerprint[0] # if the smartDSU is detected, openpilot can send ACC_CONTROL and the smartDSU will block it from the DSU or radar. - # since we don't yet parse radar on TSS2 radar-based ACC cars, gate longitudinal behind experimental toggle + # since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle use_sdsu = bool(ret.flags & ToyotaFlags.SMART_DSU) - if candidate in RADAR_ACC_CAR: + if candidate in (RADAR_ACC_CAR | NO_DSU_CAR): ret.experimentalLongitudinalAvailable = use_sdsu if not use_sdsu: - if experimental_long and False: # TODO: disabling radar isn't supported yet + # Disabling radar is only supported on TSS2 radar-ACC cars + if experimental_long and candidate in RADAR_ACC_CAR and False: # TODO: disabling radar isn't supported yet ret.flags |= ToyotaFlags.DISABLE_RADAR.value else: use_sdsu = use_sdsu and experimental_long @@ -238,17 +242,13 @@ class CarInterface(CarInterfaceBase): # openpilot longitudinal behind experimental long toggle: # - TSS2 radar ACC cars w/ smartDSU installed # - TSS2 radar ACC cars w/o smartDSU installed (disables radar) + # - TSS-P DSU-less cars w/ CAN filter installed (no radar parser yet) ret.openpilotLongitudinalControl = use_sdsu or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value) ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR if not ret.openpilotLongitudinalControl: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL - # we can't use the fingerprint to detect this reliably, since - # the EV gas pedal signal can take a couple seconds to appear - if candidate in EV_HYBRID_CAR: - ret.flags |= ToyotaFlags.HYBRID.value - # min speed to enable ACC. if car can do stop and go, then set enabling speed # to a negative value, so it won't matter. ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else MIN_ACC_SPEED diff --git a/selfdrive/car/toyota/toyotacan.py b/selfdrive/car/toyota/toyotacan.py index 0792ac869..ed0237c1b 100644 --- a/selfdrive/car/toyota/toyotacan.py +++ b/selfdrive/car/toyota/toyotacan.py @@ -27,7 +27,7 @@ def create_lta_steer_command(packer, steer_angle, steer_req, frame, setme_x64): return packer.make_can_msg("STEERING_LTA", 0, values) -def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type): +def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert): # TODO: find the exact canceling bit that does not create a chime values = { "ACCEL_CMD": accel, @@ -38,6 +38,7 @@ def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_ty "RELEASE_STANDSTILL": not standstill_req, "CANCEL_REQ": pcm_cancel, "ALLOW_LONG_PRESS": 1, + "ACC_CUT_IN": fcw_alert, # only shown when ACC enabled } return packer.make_can_msg("ACC_CONTROL", 0, values) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index b0f7a7098..a2eba9da2 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -1,7 +1,9 @@ +import re from collections import defaultdict from dataclasses import dataclass, field from enum import Enum, IntFlag -from typing import Dict, List, Union +from strenum import StrEnum +from typing import Dict, List, Set, Union from cereal import car from openpilot.common.conversions import Conversions as CV @@ -45,7 +47,7 @@ class ToyotaFlags(IntFlag): DISABLE_RADAR = 4 -class CAR: +class CAR(StrEnum): # Toyota ALPHARD_TSS2 = "TOYOTA ALPHARD 2020" ALPHARDH_TSS2 = "TOYOTA ALPHARD HYBRID 2021" @@ -60,12 +62,10 @@ class CAR: CAMRYH_TSS2 = "TOYOTA CAMRY HYBRID 2021" CHR = "TOYOTA C-HR 2018" CHR_TSS2 = "TOYOTA C-HR 2021" - CHRH = "TOYOTA C-HR HYBRID 2018" CHRH_TSS2 = "TOYOTA C-HR HYBRID 2022" COROLLA = "TOYOTA COROLLA 2017" - COROLLA_TSS2 = "TOYOTA COROLLA TSS2 2019" # LSS2 Lexus UX Hybrid is same as a TSS2 Corolla Hybrid - COROLLAH_TSS2 = "TOYOTA COROLLA HYBRID TSS2 2019" + COROLLA_TSS2 = "TOYOTA COROLLA TSS2 2019" HIGHLANDER = "TOYOTA HIGHLANDER 2017" HIGHLANDER_TSS2 = "TOYOTA HIGHLANDER 2020" HIGHLANDERH = "TOYOTA HIGHLANDER HYBRID 2018" @@ -78,7 +78,6 @@ class CAR: RAV4_TSS2 = "TOYOTA RAV4 2019" RAV4_TSS2_2022 = "TOYOTA RAV4 2022" RAV4_TSS2_2023 = "TOYOTA RAV4 2023" - RAV4H_TSS2 = "TOYOTA RAV4 HYBRID 2019" RAV4H_TSS2_2022 = "TOYOTA RAV4 HYBRID 2022" RAV4H_TSS2_2023 = "TOYOTA RAV4 HYBRID 2023" MIRAI = "TOYOTA MIRAI 2021" # TSS 2.5 @@ -89,18 +88,14 @@ class CAR: LEXUS_ES = "LEXUS ES 2018" LEXUS_ESH = "LEXUS ES HYBRID 2018" LEXUS_ES_TSS2 = "LEXUS ES 2019" - LEXUS_ESH_TSS2 = "LEXUS ES HYBRID 2019" LEXUS_IS = "LEXUS IS 2018" LEXUS_IS_TSS2 = "LEXUS IS 2023" LEXUS_NX = "LEXUS NX 2018" - LEXUS_NXH = "LEXUS NX HYBRID 2018" LEXUS_NX_TSS2 = "LEXUS NX 2020" - LEXUS_NXH_TSS2 = "LEXUS NX HYBRID 2020" LEXUS_RC = "LEXUS RC 2020" LEXUS_RX = "LEXUS RX 2016" LEXUS_RXH = "LEXUS RX HYBRID 2017" LEXUS_RX_TSS2 = "LEXUS RX 2020" - LEXUS_RXH_TSS2 = "LEXUS RX HYBRID 2020" class Footnote(Enum): @@ -130,18 +125,19 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.CAMRY: ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]), CAR.CAMRYH: ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"), CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-23", footnotes=[Footnote.CAMRY]), - CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-23"), - CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"), + CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-24"), + CAR.CHR: [ + ToyotaCarInfo("Toyota C-HR 2017-20"), + ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"), + ], CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"), - CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"), CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"), CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"), CAR.COROLLA_TSS2: [ ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), ToyotaCarInfo("Toyota Corolla Cross (Non-US only) 2020-23", min_enable_speed=7.5), ToyotaCarInfo("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), - ], - CAR.COROLLAH_TSS2: [ + # Hybrid platforms ToyotaCarInfo("Toyota Corolla Hybrid 2020-22"), ToyotaCarInfo("Toyota Corolla Hybrid (Non-US only) 2020-23", min_enable_speed=7.5), ToyotaCarInfo("Toyota Corolla Cross Hybrid (Non-US only) 2020-22", min_enable_speed=7.5), @@ -169,10 +165,12 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { ToyotaCarInfo("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26"), ToyotaCarInfo("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26") ], - CAR.RAV4_TSS2: ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), + CAR.RAV4_TSS2: [ + ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), + ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), + ], CAR.RAV4_TSS2_2022: ToyotaCarInfo("Toyota RAV4 2022"), CAR.RAV4_TSS2_2023: ToyotaCarInfo("Toyota RAV4 2023"), - CAR.RAV4H_TSS2: ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), CAR.RAV4H_TSS2_2022: ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"), CAR.RAV4H_TSS2_2023: ToyotaCarInfo("Toyota RAV4 Hybrid 2023"), CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"), @@ -182,14 +180,20 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+"), CAR.LEXUS_ES: ToyotaCarInfo("Lexus ES 2017-18"), CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18"), - CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-22"), - CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-23", video_link="https://youtu.be/BZ29osRVJeg?t=12"), + CAR.LEXUS_ES_TSS2: [ + ToyotaCarInfo("Lexus ES 2019-24"), + ToyotaCarInfo("Lexus ES Hybrid 2019-23", video_link="https://youtu.be/BZ29osRVJeg?t=12"), + ], CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"), - CAR.LEXUS_IS_TSS2: ToyotaCarInfo("Lexus IS 2023"), - CAR.LEXUS_NX: ToyotaCarInfo("Lexus NX 2018-19"), - CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19"), - CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"), - CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020-21"), + CAR.LEXUS_IS_TSS2: ToyotaCarInfo("Lexus IS 2022-23"), + CAR.LEXUS_NX: [ + ToyotaCarInfo("Lexus NX 2018-19"), + ToyotaCarInfo("Lexus NX Hybrid 2018-19"), + ], + CAR.LEXUS_NX_TSS2: [ + ToyotaCarInfo("Lexus NX 2020-21"), + ToyotaCarInfo("Lexus NX Hybrid 2020-21"), + ], CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2018-20"), CAR.LEXUS_RX: [ ToyotaCarInfo("Lexus RX 2016", "Lexus Safety System+"), @@ -199,41 +203,152 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = { ToyotaCarInfo("Lexus RX Hybrid 2016", "Lexus Safety System+"), ToyotaCarInfo("Lexus RX Hybrid 2017-19"), ], - CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-22"), - CAR.LEXUS_RXH_TSS2: ToyotaCarInfo("Lexus RX Hybrid 2020-22"), + CAR.LEXUS_RX_TSS2: [ + ToyotaCarInfo("Lexus RX 2020-22"), + ToyotaCarInfo("Lexus RX Hybrid 2020-22"), + ], } # (addr, cars, bus, 1/freq*100, vl) STATIC_DSU_MSGS = [ - (0x128, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 3, b'\xf4\x01\x90\x83\x00\x37'), + (0x128, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 3, b'\xf4\x01\x90\x83\x00\x37'), (0x128, (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH), 1, 3, b'\x03\x00\x20\x00\x00\x52'), - (0x141, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, + (0x141, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 1, 2, b'\x00\x00\x00\x46'), - (0x160, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, + (0x160, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 1, 7, b'\x00\x00\x08\x12\x01\x31\x9c\x51'), - (0x161, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON, CAR.LEXUS_RX, CAR.PRIUS_V, CAR.LEXUS_ES), + (0x161, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON, CAR.LEXUS_RX, CAR.PRIUS_V, CAR.LEXUS_ES), 1, 7, b'\x00\x1e\x00\x00\x00\x80\x07'), (0X161, (CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ESH), 1, 7, b'\x00\x1e\x00\xd4\x00\x00\x5b'), - (0x283, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, + (0x283, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 0, 3, b'\x00\x00\x00\x00\x00\x00\x8c'), (0x2E6, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, b'\xff\xf8\x00\x08\x7f\xe0\x00\x4e'), (0x2E7, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 3, b'\xa8\x9c\x31\x9c\x00\x00\x00\x02'), (0x33E, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH), 0, 20, b'\x0f\xff\x26\x40\x00\x1f\x00'), - (0x344, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, + (0x344, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 0, 5, b'\x00\x00\x01\x00\x00\x00\x00\x50'), - (0x365, (CAR.PRIUS, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x00\x80\x03\x00\x08'), + (0x365, (CAR.PRIUS, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x00\x80\x03\x00\x08'), (0x365, (CAR.RAV4, CAR.RAV4H, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 0, 20, b'\x00\x00\x00\x80\xfc\x00\x08'), - (0x366, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x4d\x82\x40\x02\x00'), + (0x366, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.HIGHLANDERH), 0, 20, b'\x00\x00\x4d\x82\x40\x02\x00'), (0x366, (CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 0, 20, b'\x00\x72\x07\xff\x09\xfe\x00'), (0x366, (CAR.LEXUS_ES,), 0, 20, b'\x00\x95\x07\xfe\x08\x05\x00'), (0x470, (CAR.PRIUS, CAR.LEXUS_RXH), 1, 100, b'\x00\x00\x02\x7a'), (0x470, (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.RAV4H, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.PRIUS_V), 1, 100, b'\x00\x00\x01\x79'), - (0x4CB, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.AVALON, + (0x4CB, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RXH, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_RX, CAR.PRIUS_V), 0, 100, b'\x0c\x00\x00\x00\x00\x00\x00\x00'), ] + +def get_platform_codes(fw_versions: List[bytes]) -> Dict[bytes, Set[bytes]]: + # Returns sub versions in a dict so comparisons can be made within part-platform-major_version combos + codes = defaultdict(set) # Optional[part]-platform-major_version: set of sub_version + for fw in fw_versions: + # FW versions returned from UDS queries can return multiple fields/chunks of data (different ECU calibrations, different data?) + # and are prefixed with a byte that describes how many chunks of data there are. + # But FW returned from KWP requires querying of each sub-data id and does not have a length prefix. + + length_code = 1 + length_code_match = FW_LEN_CODE.search(fw) + if length_code_match is not None: + length_code = length_code_match.group()[0] + fw = fw[1:] + + # fw length should be multiple of 16 bytes (per chunk, even if no length code), skip parsing if unexpected length + if length_code * FW_CHUNK_LEN != len(fw): + continue + + chunks = [fw[FW_CHUNK_LEN * i:FW_CHUNK_LEN * i + FW_CHUNK_LEN].strip(b'\x00 ') for i in range(length_code)] + + # only first is considered for now since second is commonly shared (TODO: understand that) + first_chunk = chunks[0] + if len(first_chunk) == 8: + # TODO: no part number, but some short chunks have it in subsequent chunks + fw_match = SHORT_FW_PATTERN.search(first_chunk) + if fw_match is not None: + platform, major_version, sub_version = fw_match.groups() + codes[b'-'.join((platform, major_version))].add(sub_version) + + elif len(first_chunk) == 10: + fw_match = MEDIUM_FW_PATTERN.search(first_chunk) + if fw_match is not None: + part, platform, major_version, sub_version = fw_match.groups() + codes[b'-'.join((part, platform, major_version))].add(sub_version) + + elif len(first_chunk) == 12: + fw_match = LONG_FW_PATTERN.search(first_chunk) + if fw_match is not None: + part, platform, major_version, sub_version = fw_match.groups() + codes[b'-'.join((part, platform, major_version))].add(sub_version) + + return dict(codes) + + +def match_fw_to_car_fuzzy(live_fw_versions) -> Set[str]: + candidates = set() + + for candidate, fws in FW_VERSIONS.items(): + # Keep track of ECUs which pass all checks (platform codes, within sub-version range) + valid_found_ecus = set() + valid_expected_ecus = {ecu[1:] for ecu in fws if ecu[0] in PLATFORM_CODE_ECUS} + for ecu, expected_versions in fws.items(): + addr = ecu[1:] + # Only check ECUs expected to have platform codes + if ecu[0] not in PLATFORM_CODE_ECUS: + continue + + # Expected platform codes & versions + expected_platform_codes = get_platform_codes(expected_versions) + + # Found platform codes & versions + found_platform_codes = get_platform_codes(live_fw_versions.get(addr, set())) + + # Check part number + platform code + major version matches for any found versions + # Platform codes and major versions change for different physical parts, generation, API, etc. + # Sub-versions are incremented for minor recalls, do not need to be checked. + if not any(found_platform_code in expected_platform_codes for found_platform_code in found_platform_codes): + break + + valid_found_ecus.add(addr) + + # If all live ECUs pass all checks for candidate, add it as a match + if valid_expected_ecus.issubset(valid_found_ecus): + candidates.add(candidate) + + return {str(c) for c in (candidates - FUZZY_EXCLUDED_PLATFORMS)} + + +# Regex patterns for parsing more general platform-specific identifiers from FW versions. +# - Part number: Toyota part number (usually last character needs to be ignored to find a match). +# Each ECU address has just one part number. +# - Platform: usually multiple codes per an openpilot platform, however this is the least variable and +# is usually shared across ECUs and model years signifying this describes something about the specific platform. +# This describes more generational changes (TSS-P vs TSS2), or manufacture region. +# - Major version: second least variable part of the FW version. Seen splitting cars by model year/API such as +# RAV4 2022/2023 and Avalon. Used to differentiate cars where API has changed slightly, but is not a generational change. +# It is important to note that these aren't always consecutive, for example: +# Avalon 2016-18's fwdCamera has these major versions: 01, 03 while 2019 has: 02 +# - Sub version: exclusive to major version, but shared with other cars. Should only be used for further filtering. +# Seen bumped in TSB FW updates, and describes other minor differences. +SHORT_FW_PATTERN = re.compile(b'[A-Z0-9](?P[A-Z0-9]{2})(?P[A-Z0-9]{2})(?P[A-Z0-9]{3})') +MEDIUM_FW_PATTERN = re.compile(b'(?P[A-Z0-9]{5})(?P[A-Z0-9]{2})(?P[A-Z0-9]{1})(?P[A-Z0-9]{2})') +LONG_FW_PATTERN = re.compile(b'(?P[A-Z0-9]{5})(?P[A-Z0-9]{2})(?P[A-Z0-9]{2})(?P[A-Z0-9]{3})') +FW_LEN_CODE = re.compile(b'^[\x01-\x03]') # highest seen is 3 chunks, 16 bytes each +FW_CHUNK_LEN = 16 + +# List of ECUs that are most unique across openpilot platforms +# TODO: use hybrid ECU, splits similar ICE and hybrid variants +# - fwdCamera: describes actual features related to ADAS. For example, on the Avalon it describes +# when TSS-P became standard, whether the car supports stop and go, and whether it's TSS2. +# On the RAV4, it describes the move to the radar doing ACC, and the use of LTA for lane keeping. +# - abs: differentiates hybrid/ICE on most cars (Corolla TSS2 is an exception) +# - eps: describes lateral API changes for the EPS, such as using LTA for lane keeping and rejecting LKA messages +PLATFORM_CODE_ECUS = [Ecu.fwdCamera, Ecu.abs, Ecu.eps] + +# These platforms have at least one platform code for all ECUs shared with another platform. +FUZZY_EXCLUDED_PLATFORMS = {CAR.LEXUS_ES_TSS2, CAR.LEXUS_RX_TSS2} + # Some ECUs that use KWP2000 have their FW versions on non-standard data identifiers. # Toyota diagnostic software first gets the supported data ids, then queries them one by one. # For example, sends: 0x1a8800, receives: 0x1a8800010203, queries: 0x1a8801, 0x1a8802, 0x1a8803 @@ -247,7 +362,7 @@ FW_QUERY_CONFIG = FwQueryConfig( [StdQueries.SHORT_TESTER_PRESENT_REQUEST, TOYOTA_VERSION_REQUEST_KWP], [StdQueries.SHORT_TESTER_PRESENT_RESPONSE, TOYOTA_VERSION_RESPONSE_KWP], whitelist_ecus=[Ecu.fwdCamera, Ecu.fwdRadar, Ecu.dsu, Ecu.abs, Ecu.eps, Ecu.epb, Ecu.telematics, - Ecu.hybrid, Ecu.srs, Ecu.combinationMeter, Ecu.transmission, Ecu.gateway, Ecu.hvac], + Ecu.srs, Ecu.combinationMeter, Ecu.transmission, Ecu.gateway, Ecu.hvac], bus=0, ), Request( @@ -269,7 +384,8 @@ FW_QUERY_CONFIG = FwQueryConfig( # FIXME: On some models, abs can sometimes be missing Ecu.abs: [CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_IS], # On some models, the engine can show on two different addresses - Ecu.engine: [CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.CHR_TSS2, CAR.LEXUS_IS, CAR.LEXUS_RC], + Ecu.engine: [CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.CHR_TSS2, CAR.LEXUS_IS, CAR.LEXUS_RC, + CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2, CAR.LEXUS_RX_TSS2], }, extra_ecus=[ # All known ECUs on a late-model Toyota vehicle not queried here: @@ -303,6 +419,7 @@ FW_QUERY_CONFIG = FwQueryConfig( (Ecu.combinationMeter, 0x7c0, None), (Ecu.hvac, 0x7c4, None), ], + match_fw_to_car_fuzzy=match_fw_to_car_fuzzy, ) FW_VERSIONS = { @@ -516,6 +633,7 @@ FW_VERSIONS = { b'\x018966333X0000\x00\x00\x00\x00', b'\x018966333X4000\x00\x00\x00\x00', b'\x01896633T16000\x00\x00\x00\x00', + b'\x018966306L9000\x00\x00\x00\x00', b'\x028966306B2100\x00\x00\x00\x00897CF3302002\x00\x00\x00\x00', b'\x028966306B2300\x00\x00\x00\x00897CF3302002\x00\x00\x00\x00', b'\x028966306B2500\x00\x00\x00\x00897CF3302002\x00\x00\x00\x00', @@ -664,6 +782,13 @@ FW_VERSIONS = { b'\x01896631017200\x00\x00\x00\x00', b'\x0189663F413100\x00\x00\x00\x00', b'\x0189663F414100\x00\x00\x00\x00', + b'\x0289663F405100\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896631013200\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x0289663F405000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x0289663F418000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x0289663F423000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x0289663F431000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x0189663F438000\x00\x00\x00\x00', ], (Ecu.dsu, 0x791, None): [ b'8821F0W01000 ', @@ -674,6 +799,9 @@ FW_VERSIONS = { b'8821FF405100 ', b'8821FF406000 ', b'8821FF407100 ', + b'8821FF402300 ', + b'8821FF402400 ', + b'8821FF405000 ', ], (Ecu.abs, 0x7b0, None): [ b'F152610020\x00\x00\x00\x00\x00\x00', @@ -684,11 +812,21 @@ FW_VERSIONS = { b'F1526F4073\x00\x00\x00\x00\x00\x00', b'F1526F4121\x00\x00\x00\x00\x00\x00', b'F1526F4122\x00\x00\x00\x00\x00\x00', + b'F152610012\x00\x00\x00\x00\x00\x00', + b'F152610013\x00\x00\x00\x00\x00\x00', + b'F152610014\x00\x00\x00\x00\x00\x00', + b'F152610040\x00\x00\x00\x00\x00\x00', + b'F152610190\x00\x00\x00\x00\x00\x00', + b'F152610200\x00\x00\x00\x00\x00\x00', + b'F152610220\x00\x00\x00\x00\x00\x00', + b'F152610230\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B10011\x00\x00\x00\x00\x00\x00', b'8965B10040\x00\x00\x00\x00\x00\x00', b'8965B10070\x00\x00\x00\x00\x00\x00', + b'8965B10020\x00\x00\x00\x00\x00\x00', + b'8965B10050\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'\x0331024000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00895231203202\x00\x00\x00\x00', @@ -708,6 +846,9 @@ FW_VERSIONS = { b'8821FF406000 ', b'8821FF407100 ', b'8821F0W01100 ', + b'8821FF402300 ', + b'8821FF402400 ', + b'8821FF405000 ', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'8646FF401700 ', @@ -715,6 +856,8 @@ FW_VERSIONS = { b'8646FF404000 ', b'8646FF406000 ', b'8646FF407000 ', + b'8646FF402100 ', + b'8646FF407100 ', ], }, CAR.CHR_TSS2: { @@ -741,61 +884,6 @@ FW_VERSIONS = { b'\x028646FF411100\x00\x00\x00\x008646GF409000\x00\x00\x00\x00', ], }, - CAR.CHRH: { - (Ecu.engine, 0x700, None): [ - b'\x0289663F405100\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896631013200\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x0289663F405000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x0289663F418000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x0289663F423000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x0289663F431000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x0189663F438000\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152610012\x00\x00\x00\x00\x00\x00', - b'F152610013\x00\x00\x00\x00\x00\x00', - b'F152610014\x00\x00\x00\x00\x00\x00', - b'F152610040\x00\x00\x00\x00\x00\x00', - b'F152610190\x00\x00\x00\x00\x00\x00', - b'F152610200\x00\x00\x00\x00\x00\x00', - b'F152610220\x00\x00\x00\x00\x00\x00', - b'F152610230\x00\x00\x00\x00\x00\x00', - ], - (Ecu.dsu, 0x791, None): [ - b'8821F0W01000 ', - b'8821FF402300 ', - b'8821FF402400 ', - b'8821FF404000 ', - b'8821FF404100 ', - b'8821FF405000 ', - b'8821FF406000 ', - b'8821FF407100 ', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B10011\x00\x00\x00\x00\x00\x00', - b'8965B10020\x00\x00\x00\x00\x00\x00', - b'8965B10040\x00\x00\x00\x00\x00\x00', - b'8965B10050\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'8821F0W01000 ', - b'8821FF402300 ', - b'8821FF402400 ', - b'8821FF404000 ', - b'8821FF404100 ', - b'8821FF405000 ', - b'8821FF406000 ', - b'8821FF407100 ', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'8646FF401700 ', - b'8646FF402100 ', - b'8646FF404000 ', - b'8646FF406000 ', - b'8646FF407000 ', - b'8646FF407100 ', - ], - }, CAR.CHRH_TSS2: { (Ecu.eps, 0x7a1, None): [ b'8965B10092\x00\x00\x00\x00\x00\x00', @@ -886,6 +974,33 @@ FW_VERSIONS = { b'\x018966312W3000\x00\x00\x00\x00', b'\x018966312W9000\x00\x00\x00\x00', b'\x01896637644000\x00\x00\x00\x00', + b'\x01896630ZJ1000\x00\x00\x00\x00', + b'\x01896630ZU8000\x00\x00\x00\x00', + b'\x01896637621000\x00\x00\x00\x00', + b'\x01896637623000\x00\x00\x00\x00', + b'\x01896637624000\x00\x00\x00\x00', + b'\x01896637626000\x00\x00\x00\x00', + b'\x01896637639000\x00\x00\x00\x00', + b'\x01896637648000\x00\x00\x00\x00', + b'\x01896637643000\x00\x00\x00\x00', + b'\x02896630A07000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630A21000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZJ5000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZK8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZN8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZQ3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZR2000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZT8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZT9000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x02896630ZZ0000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966312K6000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966312L0000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966312Q3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966312Q3100\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x028966312Q4000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', + b'\x038966312L7000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1205001\x00\x00\x00\x00', + b'\x038966312N1000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', + b'\x038966312T3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1205001\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'\x0230A10000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00', @@ -917,13 +1032,18 @@ FW_VERSIONS = { b'8965B76012\x00\x00\x00\x00\x00\x00', b'\x018965B12510\x00\x00\x00\x00\x00\x00', b'\x018965B1256000\x00\x00\x00\x00', + b'8965B12451\x00\x00\x00\x00\x00\x00', + b'8965B16101\x00\x00\x00\x00\x00\x00', + b'8965B16170\x00\x00\x00\x00\x00\x00', + b'8965B76050\x00\x00\x00\x00\x00\x00', + b'8965B76091\x00\x00\x00\x00\x00\x00', ], (Ecu.abs, 0x7b0, None): [ b'\x01F152602280\x00\x00\x00\x00\x00\x00', b'\x01F152602560\x00\x00\x00\x00\x00\x00', b'\x01F152602590\x00\x00\x00\x00\x00\x00', b'\x01F152602650\x00\x00\x00\x00\x00\x00', - b"\x01F15260A010\x00\x00\x00\x00\x00\x00", + b'\x01F15260A010\x00\x00\x00\x00\x00\x00', b'\x01F15260A050\x00\x00\x00\x00\x00\x00', b'\x01F152612641\x00\x00\x00\x00\x00\x00', b'\x01F152612651\x00\x00\x00\x00\x00\x00', @@ -941,74 +1061,6 @@ FW_VERSIONS = { b'\x01F152612B91\x00\x00\x00\x00\x00\x00', b'\x01F15260A070\x00\x00\x00\x00\x00\x00', b'\x01F152676250\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'\x018821F3301100\x00\x00\x00\x00', - b'\x018821F3301200\x00\x00\x00\x00', - b'\x018821F3301300\x00\x00\x00\x00', - b'\x018821F3301400\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'\x028646F12010D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F1201100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F1201200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F1201300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F1201400\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', - b'\x028646F1202000\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', - b'\x028646F1202100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F1202200\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', - b'\x028646F1601100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F1601300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - ], - }, - CAR.COROLLAH_TSS2: { - (Ecu.engine, 0x700, None): [ - b'\x01896630ZJ1000\x00\x00\x00\x00', - b'\x01896630ZU8000\x00\x00\x00\x00', - b'\x01896637621000\x00\x00\x00\x00', - b'\x01896637623000\x00\x00\x00\x00', - b'\x01896637624000\x00\x00\x00\x00', - b'\x01896637626000\x00\x00\x00\x00', - b'\x01896637639000\x00\x00\x00\x00', - b'\x01896637648000\x00\x00\x00\x00', - b'\x01896637643000\x00\x00\x00\x00', - b'\x02896630A07000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630A21000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZJ5000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZK8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZN8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZQ3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZR2000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZT8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZT9000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x02896630ZZ0000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x028966312K6000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x028966312L0000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x028966312Q3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x028966312Q3100\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x028966312Q4000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', - b'\x038966312L7000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1205001\x00\x00\x00\x00', - b'\x038966312N1000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', - b'\x038966312T3000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00897CF1205001\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B12361\x00\x00\x00\x00\x00\x00', - b'8965B12451\x00\x00\x00\x00\x00\x00', - b'8965B16011\x00\x00\x00\x00\x00\x00', - b'8965B16101\x00\x00\x00\x00\x00\x00', - b'8965B16170\x00\x00\x00\x00\x00\x00', - b'8965B76012\x00\x00\x00\x00\x00\x00', - b'8965B76050\x00\x00\x00\x00\x00\x00', - b'8965B76091\x00\x00\x00\x00\x00\x00', - b'\x018965B12350\x00\x00\x00\x00\x00\x00', - b'\x018965B12470\x00\x00\x00\x00\x00\x00', - b'\x018965B12490\x00\x00\x00\x00\x00\x00', - b'\x018965B12500\x00\x00\x00\x00\x00\x00', - b'\x018965B12510\x00\x00\x00\x00\x00\x00', - b'\x018965B12520\x00\x00\x00\x00\x00\x00', - b'\x018965B12530\x00\x00\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ b'F152612590\x00\x00\x00\x00\x00\x00', b'F152612691\x00\x00\x00\x00\x00\x00', b'F152612692\x00\x00\x00\x00\x00\x00', @@ -1042,14 +1094,15 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F12010D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F1201100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', + b'\x028646F1201200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F1201300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F1201400\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', b'\x028646F1202000\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F1202100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F1202200\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', b'\x028646F1601100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', + b'\x028646F1601300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F1601200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b"\x028646F1601300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00", b'\x028646F4203400\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F76020C0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F7603100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', @@ -1260,17 +1313,21 @@ FW_VERSIONS = { CAR.LEXUS_IS_TSS2: { (Ecu.engine, 0x700, None): [ b'\x018966353S1000\x00\x00\x00\x00', + b'\x018966353S2000\x00\x00\x00\x00', ], (Ecu.abs, 0x7b0, None): [ + b'\x01F15265337200\x00\x00\x00\x00', b'\x01F15265342000\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B53450\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ + b'\x018821F6201200\x00\x00\x00\x00', b'\x018821F6201300\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ + b'\x028646F5303300\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', b'\x028646F5303400\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, @@ -1500,6 +1557,24 @@ FW_VERSIONS = { b'\x02896634A43000\x00\x00\x00\x00897CF4201001\x00\x00\x00\x00', b'\x02896634A47000\x00\x00\x00\x00897CF4201001\x00\x00\x00\x00', b'\x028966342Z8000\x00\x00\x00\x00897CF1201001\x00\x00\x00\x00', + b'\x01896634A15000\x00\x00\x00\x00', + b'\x018966342M5000\x00\x00\x00\x00', + b'\x018966342W8000\x00\x00\x00\x00', + b'\x018966342X5000\x00\x00\x00\x00', + b'\x018966342X6000\x00\x00\x00\x00', + b'\x01896634A25000\x00\x00\x00\x00', + b'\x018966342W5000\x00\x00\x00\x00', + b'\x018966342W7000\x00\x00\x00\x00', + b'\x028966342W4001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', + b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', + b'\x02896634A13101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', + b'\x02896634A14001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', + b'\x02896634A23000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02896634A23001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', + b'\x02896634A23101\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', + b'\x02896634A14001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', + b'\x02896634A14101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', ], (Ecu.abs, 0x7b0, None): [ b'\x01F15260R210\x00\x00\x00\x00\x00\x00', @@ -1517,6 +1592,18 @@ FW_VERSIONS = { b'\x01F152642750\x00\x00\x00\x00\x00\x00', b'\x01F152642751\x00\x00\x00\x00\x00\x00', b'\x01F15260R292\x00\x00\x00\x00\x00\x00', + b'F152642291\x00\x00\x00\x00\x00\x00', + b'F152642290\x00\x00\x00\x00\x00\x00', + b'F152642322\x00\x00\x00\x00\x00\x00', + b'F152642330\x00\x00\x00\x00\x00\x00', + b'F152642331\x00\x00\x00\x00\x00\x00', + b'F152642531\x00\x00\x00\x00\x00\x00', + b'F152642532\x00\x00\x00\x00\x00\x00', + b'F152642520\x00\x00\x00\x00\x00\x00', + b'F152642521\x00\x00\x00\x00\x00\x00', + b'F152642540\x00\x00\x00\x00\x00\x00', + b'F152642541\x00\x00\x00\x00\x00\x00', + b'F152642542\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B42170\x00\x00\x00\x00\x00\x00', @@ -1575,6 +1662,7 @@ FW_VERSIONS = { (Ecu.engine, 0x700, None): [ b'\x01896634A88100\x00\x00\x00\x00', b'\x01896634AJ2000\x00\x00\x00\x00', + b'\x01896634A89100\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R03100\x00\x00\x00\x00', @@ -1583,65 +1671,6 @@ FW_VERSIONS = { b'\x028646F0R05100\x00\x00\x00\x008646G0R02100\x00\x00\x00\x00', ], }, - CAR.RAV4H_TSS2: { - (Ecu.engine, 0x700, None): [ - b'\x01896634A15000\x00\x00\x00\x00', - b'\x018966342M5000\x00\x00\x00\x00', - b'\x018966342W8000\x00\x00\x00\x00', - b'\x018966342X5000\x00\x00\x00\x00', - b'\x018966342X6000\x00\x00\x00\x00', - b'\x01896634A25000\x00\x00\x00\x00', - b'\x018966342W5000\x00\x00\x00\x00', - b'\x018966342W7000\x00\x00\x00\x00', - b'\x028966342W4001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', - b'\x02896634A13000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02896634A13001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', - b'\x02896634A13101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', - b'\x02896634A14001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', - b'\x02896634A23000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02896634A23001\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', - b'\x02896634A23101\x00\x00\x00\x00897CF1203001\x00\x00\x00\x00', - b'\x02896634A14001\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', - b'\x02896634A14101\x00\x00\x00\x00897CF4801001\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152642291\x00\x00\x00\x00\x00\x00', - b'F152642290\x00\x00\x00\x00\x00\x00', - b'F152642322\x00\x00\x00\x00\x00\x00', - b'F152642330\x00\x00\x00\x00\x00\x00', - b'F152642331\x00\x00\x00\x00\x00\x00', - b'F152642531\x00\x00\x00\x00\x00\x00', - b'F152642532\x00\x00\x00\x00\x00\x00', - b'F152642520\x00\x00\x00\x00\x00\x00', - b'F152642521\x00\x00\x00\x00\x00\x00', - b'F152642540\x00\x00\x00\x00\x00\x00', - b'F152642541\x00\x00\x00\x00\x00\x00', - b'F152642542\x00\x00\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B42170\x00\x00\x00\x00\x00\x00', - b'8965B42171\x00\x00\x00\x00\x00\x00', - b'8965B42180\x00\x00\x00\x00\x00\x00', - b'8965B42181\x00\x00\x00\x00\x00\x00', - b'\x028965B0R01200\x00\x00\x00\x008965B0R02200\x00\x00\x00\x00', - b'\x028965B0R01300\x00\x00\x00\x008965B0R02300\x00\x00\x00\x00', - b'\x028965B0R01400\x00\x00\x00\x008965B0R02400\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'\x018821F3301100\x00\x00\x00\x00', - b'\x018821F3301200\x00\x00\x00\x00', - b'\x018821F3301300\x00\x00\x00\x00', - b'\x018821F3301400\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'\x028646F4203200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F4203300\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F4203400\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', - b'\x028646F4203500\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', - b'\x028646F4203700\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F4203800\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', - ], - }, CAR.RAV4H_TSS2_2022: { (Ecu.abs, 0x7b0, None): [ b'\x01F15264283100\x00\x00\x00\x00', @@ -1674,6 +1703,7 @@ FW_VERSIONS = { (Ecu.abs, 0x7b0, None): [ b'\x01F15264283200\x00\x00\x00\x00', b'\x01F15264283300\x00\x00\x00\x00', + b'\x01F152642F1000\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'\x028965B0R11000\x00\x00\x00\x008965B0R12000\x00\x00\x00\x00', @@ -1684,15 +1714,17 @@ FW_VERSIONS = { b'\x01896634AF0000\x00\x00\x00\x00', ], (Ecu.hybrid, 0x7d2, None): [ + b'\x02899830R39000\x00\x00\x00\x00899850R20000\x00\x00\x00\x00', b'\x02899830R41000\x00\x00\x00\x00899850R20000\x00\x00\x00\x00', b'\x028998342C0000\x00\x00\x00\x00899854224000\x00\x00\x00\x00', - b'\x02899830R39000\x00\x00\x00\x00899850R20000\x00\x00\x00\x00', + b'\x028998342C6000\x00\x00\x00\x00899854224000\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R03100\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F0R05100\x00\x00\x00\x008646G0R02100\x00\x00\x00\x00', + b'\x028646F0R05200\x00\x00\x00\x008646G0R02200\x00\x00\x00\x00', ], }, CAR.SIENNA: { @@ -1756,12 +1788,26 @@ FW_VERSIONS = { b'\x018966333T5100\x00\x00\x00\x00', b'\x018966333X6000\x00\x00\x00\x00', b'\x01896633T07000\x00\x00\x00\x00', + b'\x028966333S8000\x00\x00\x00\x00897CF3302002\x00\x00\x00\x00', + b'\x028966333S8000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', + b'\x028966333T0100\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', + b'\x028966333V4000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', + b'\x028966333W1000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', + b'\x02896633T09000\x00\x00\x00\x00897CF3307001\x00\x00\x00\x00', + b'\x01896633T38000\x00\x00\x00\x00', + b'\x01896633T58000\x00\x00\x00\x00', ], (Ecu.abs, 0x7b0, None): [ b'\x01F152606281\x00\x00\x00\x00\x00\x00', b'\x01F152606340\x00\x00\x00\x00\x00\x00', b'\x01F152606461\x00\x00\x00\x00\x00\x00', b'\x01F15260E031\x00\x00\x00\x00\x00\x00', + b'\x01F15260646200\x00\x00\x00\x00', + b'F152633423\x00\x00\x00\x00\x00\x00', + b'F152633680\x00\x00\x00\x00\x00\x00', + b'F152633681\x00\x00\x00\x00\x00\x00', + b'F152633F50\x00\x00\x00\x00\x00\x00', + b'F152633F51\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B33252\x00\x00\x00\x00\x00\x00', @@ -1775,6 +1821,8 @@ FW_VERSIONS = { b'\x018821F3301200\x00\x00\x00\x00', b'\x018821F3301400\x00\x00\x00\x00', b'\x018821F6201300\x00\x00\x00\x00', + b'\x018821F3301300\x00\x00\x00\x00', + b'\x018821F6201400\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F33030D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', @@ -1783,48 +1831,9 @@ FW_VERSIONS = { b'\x028646F3304300\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', b'\x028646F3309100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', b'\x028646F4810200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - ], - }, - CAR.LEXUS_ESH_TSS2: { - (Ecu.engine, 0x700, None): [ - b'\x028966333S8000\x00\x00\x00\x00897CF3302002\x00\x00\x00\x00', - b'\x028966333S8000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', - b'\x028966333T0100\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', - b'\x028966333V4000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', - b'\x028966333W1000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00', - b'\x02896633T09000\x00\x00\x00\x00897CF3307001\x00\x00\x00\x00', - b'\x01896633T38000\x00\x00\x00\x00', - b'\x01896633T58000\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152633423\x00\x00\x00\x00\x00\x00', - b'F152633680\x00\x00\x00\x00\x00\x00', - b'F152633681\x00\x00\x00\x00\x00\x00', - b'F152633F50\x00\x00\x00\x00\x00\x00', - b'F152633F51\x00\x00\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B33252\x00\x00\x00\x00\x00\x00', - b'8965B33590\x00\x00\x00\x00\x00\x00', - b'8965B33690\x00\x00\x00\x00\x00\x00', - b'8965B33721\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'\x018821F3301100\x00\x00\x00\x00', - b'\x018821F3301200\x00\x00\x00\x00', - b'\x018821F3301300\x00\x00\x00\x00', - b'\x018821F3301400\x00\x00\x00\x00', - b'\x018821F6201300\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ b'\x028646F0610000\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', - b'\x028646F33030D0\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', b'\x028646F3303100\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F3303200\x00\x00\x00\x008646G26011A0\x00\x00\x00\x00', - b'\x028646F3304100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F3304200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F3304300\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', - b'\x028646F3309100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, CAR.LEXUS_ES: { @@ -1877,17 +1886,30 @@ FW_VERSIONS = { b'\x01896637854000\x00\x00\x00\x00', b'\x01896637878000\x00\x00\x00\x00', ], + (Ecu.engine, 0x7e0, None): [ + b'\x0237841000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0237842000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0237880000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0237882000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0237886000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + ], (Ecu.abs, 0x7b0, None): [ b'F152678130\x00\x00\x00\x00\x00\x00', b'F152678140\x00\x00\x00\x00\x00\x00', + b'F152678160\x00\x00\x00\x00\x00\x00', + b'F152678170\x00\x00\x00\x00\x00\x00', + b'F152678171\x00\x00\x00\x00\x00\x00', ], (Ecu.dsu, 0x791, None): [ b'881517803100\x00\x00\x00\x00', b'881517803300\x00\x00\x00\x00', + b'881517804300\x00\x00\x00\x00', + b'881517804100\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B78060\x00\x00\x00\x00\x00\x00', b'8965B78080\x00\x00\x00\x00\x00\x00', + b'8965B78100\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'8821F4702100\x00\x00\x00\x00', @@ -1906,9 +1928,17 @@ FW_VERSIONS = { b'\x018966378G2000\x00\x00\x00\x00', b'\x018966378G3000\x00\x00\x00\x00', b'\x018966378B2000\x00\x00\x00\x00', + b'\x018966378B3100\x00\x00\x00\x00', + ], + (Ecu.engine, 0x7e0, None): [ + b'\x0237887000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02378A0000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02378F4000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.abs, 0x7b0, None): [ b'\x01F152678221\x00\x00\x00\x00\x00\x00', + b'F152678210\x00\x00\x00\x00\x00\x00', + b'F152678211\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B78120\x00\x00\x00\x00\x00\x00', @@ -1923,59 +1953,6 @@ FW_VERSIONS = { b'\x028646F7803100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', ], }, - CAR.LEXUS_NXH_TSS2: { - (Ecu.engine, 0x7e0, None): [ - b'\x0237887000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02378A0000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02378F4000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152678210\x00\x00\x00\x00\x00\x00', - b'F152678211\x00\x00\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B78120\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'\x018821F3301400\x00\x00\x00\x00', - b'\x018821F3301300\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'\x028646F78030A0\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', - b'\x028646F7803100\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - ], - }, - CAR.LEXUS_NXH: { - (Ecu.engine, 0x7e0, None): [ - b'\x0237841000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0237842000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0237880000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0237882000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0237886000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152678160\x00\x00\x00\x00\x00\x00', - b'F152678170\x00\x00\x00\x00\x00\x00', - b'F152678171\x00\x00\x00\x00\x00\x00', - ], - (Ecu.dsu, 0x791, None): [ - b'881517804300\x00\x00\x00\x00', - b'881517804100\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B78060\x00\x00\x00\x00\x00\x00', - b'8965B78080\x00\x00\x00\x00\x00\x00', - b'8965B78100\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'8821F4702300\x00\x00\x00\x00', - b'8821F4702100\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'8646F7801300\x00\x00\x00\x00', - b'8646F7801100\x00\x00\x00\x00', - ], - }, CAR.LEXUS_RC: { (Ecu.engine, 0x700, None): [ b'\x01896632478200\x00\x00\x00\x00', @@ -2121,11 +2098,26 @@ FW_VERSIONS = { b'\x018966348X0000\x00\x00\x00\x00', b'\x01896630ED5000\x00\x00\x00\x00', ], + (Ecu.engine, 0x7e0, None): [ + b'\x02348X4000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348X5000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348X8000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + b'\x02348U2000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', + ], (Ecu.abs, 0x7b0, None): [ b'\x01F15260E031\x00\x00\x00\x00\x00\x00', b'\x01F15260E041\x00\x00\x00\x00\x00\x00', b'\x01F152648781\x00\x00\x00\x00\x00\x00', b'\x01F152648801\x00\x00\x00\x00\x00\x00', + b'F152648831\x00\x00\x00\x00\x00\x00', + b'F152648891\x00\x00\x00\x00\x00\x00', + b'F152648D00\x00\x00\x00\x00\x00\x00', + b'F152648D60\x00\x00\x00\x00\x00\x00', + b'F152648811\x00\x00\x00\x00\x00\x00', + b'F152648C80\x00\x00\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'8965B48261\x00\x00\x00\x00\x00\x00', @@ -2143,35 +2135,6 @@ FW_VERSIONS = { b'\x028646F4810400\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', ], }, - CAR.LEXUS_RXH_TSS2: { - (Ecu.engine, 0x7e0, None): [ - b'\x02348X4000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02348X5000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02348X8000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', - ], - (Ecu.abs, 0x7b0, None): [ - b'F152648831\x00\x00\x00\x00\x00\x00', - b'F152648891\x00\x00\x00\x00\x00\x00', - b'F152648D00\x00\x00\x00\x00\x00\x00', - b'F152648D60\x00\x00\x00\x00\x00\x00', - b'F152648811\x00\x00\x00\x00\x00\x00', - ], - (Ecu.eps, 0x7a1, None): [ - b'8965B48261\x00\x00\x00\x00\x00\x00', - b'8965B48271\x00\x00\x00\x00\x00\x00', - ], - (Ecu.fwdRadar, 0x750, 0xf): [ - b'\x018821F3301400\x00\x00\x00\x00', - ], - (Ecu.fwdCamera, 0x750, 0x6d): [ - b'\x028646F4810100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', - b'\x028646F4810200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - b'\x028646F4810300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', - ], - }, CAR.PRIUS_TSS2: { (Ecu.engine, 0x700, None): [ b'\x028966347B1000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', @@ -2262,10 +2225,8 @@ DBC = { CAR.LEXUS_RX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_RXH: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_RX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), - CAR.LEXUS_RXH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.CHR: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), CAR.CHR_TSS2: dbc_dict('toyota_nodsu_pt_generated', None), - CAR.CHRH: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), CAR.CHRH_TSS2: dbc_dict('toyota_nodsu_pt_generated', None), CAR.CAMRY: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), CAR.CAMRYH: dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), @@ -2284,22 +2245,17 @@ DBC = { CAR.RAV4_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None), CAR.RAV4_TSS2_2023: dbc_dict('toyota_nodsu_pt_generated', None), CAR.COROLLA_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), - CAR.COROLLAH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.LEXUS_ES: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), CAR.LEXUS_ES_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), - CAR.LEXUS_ESH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.LEXUS_ESH: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), CAR.SIENNA: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_IS: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_IS_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.LEXUS_CTH: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), - CAR.RAV4H_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.RAV4H_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None), CAR.RAV4H_TSS2_2023: dbc_dict('toyota_nodsu_pt_generated', None), - CAR.LEXUS_NXH: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_NX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), CAR.LEXUS_NX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), - CAR.LEXUS_NXH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.PRIUS_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.MIRAI: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), CAR.ALPHARD_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'), @@ -2310,12 +2266,12 @@ DBC = { EPS_SCALE = defaultdict(lambda: 73, {CAR.PRIUS: 66, CAR.COROLLA: 88, CAR.LEXUS_IS: 77, CAR.LEXUS_RC: 77, CAR.LEXUS_CTH: 100, CAR.PRIUS_V: 100}) # Toyota/Lexus Safety Sense 2.0 and 2.5 -TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, - CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.RAV4H_TSS2_2023, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, +TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.COROLLA_TSS2, CAR.LEXUS_ES_TSS2, + CAR.RAV4H_TSS2_2022, CAR.RAV4H_TSS2_2023, CAR.LEXUS_RX_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2, CAR.LEXUS_IS_TSS2, CAR.MIRAI, CAR.LEXUS_NX_TSS2, - CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2, CAR.CHR_TSS2, CAR.CHRH_TSS2} + CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2, CAR.CHR_TSS2, CAR.CHRH_TSS2} -NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH} +NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CAMRY, CAR.CAMRYH} # the DSU uses the AEB message for longitudinal on these cars UNSUPPORTED_DSU_CAR = {CAR.LEXUS_IS, CAR.LEXUS_RC} @@ -2326,10 +2282,5 @@ RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2_2023, C # these cars use the Lane Tracing Assist (LTA) message for lateral control ANGLE_CONTROL_CAR = {CAR.RAV4H_TSS2_2023, CAR.RAV4_TSS2_2023} -EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.CHRH_TSS2, CAR.COROLLAH_TSS2, - CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS, CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, - CAR.RAV4H_TSS2_2023, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH, - CAR.LEXUS_RXH_TSS2, CAR.LEXUS_NXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2} - # no resume button press required NO_STOP_TIMER_CAR = TSS2_CAR | {CAR.PRIUS_V, CAR.RAV4H, CAR.HIGHLANDERH, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_ESH} diff --git a/selfdrive/car/volkswagen/radar_interface.py b/selfdrive/car/volkswagen/radar_interface.py index b461fcd5f..e654bd61f 100644 --- a/selfdrive/car/volkswagen/radar_interface.py +++ b/selfdrive/car/volkswagen/radar_interface.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 3ffc09a43..7aa62d4e1 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1,6 +1,7 @@ from collections import defaultdict, namedtuple from dataclasses import dataclass, field from enum import Enum +from strenum import StrEnum from typing import Dict, List, Union from cereal import car @@ -114,7 +115,7 @@ class CANBUS: # FW_VERSIONS for that existing CAR. # Exception: SEAT Leon and SEAT Ateca share a chassis code -class CAR: +class CAR(StrEnum): ARTEON_MK1 = "VOLKSWAGEN ARTEON 1ST GEN" # Chassis AN, Mk1 VW Arteon and variants ATLAS_MK1 = "VOLKSWAGEN ATLAS 1ST GEN" # Chassis CA, Mk1 VW Atlas and Atlas Cross Sport CRAFTER_MK2 = "VOLKSWAGEN CRAFTER 2ND GEN" # Chassis SY/SZ, Mk2 VW Crafter, VW Grand California, MAN TGE @@ -161,7 +162,7 @@ class Footnote(Enum): Column.MODEL) SKODA_HEATED_WINDSHIELD = CarFootnote( "Some Škoda vehicles are equipped with heated windshields, which are known " + - "to block GPS signal needed for some comma three functionality.", + "to block GPS signal needed for some comma 3X functionality.", Column.MODEL) VW_EXP_LONG = CarFootnote( "Only available for vehicles using a gateway (J533) harness. At this time, vehicles using a camera harness " + @@ -184,7 +185,7 @@ class VWCarInfo(CarInfo): self.footnotes.append(Footnote.SKODA_HEATED_WINDSHIELD) if CP.carFingerprint in (CAR.CRAFTER_MK2, CAR.TRANSPORTER_T61): - self.car_parts = CarParts([Device.three_angled_mount, CarHarness.j533]) + self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.j533]) CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { @@ -245,7 +246,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2016-23"), CAR.TRANSPORTER_T61: [ VWCarInfo("Volkswagen Caravelle 2020"), - VWCarInfo("Volkswagen California 2021"), + VWCarInfo("Volkswagen California 2021-23"), ], CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_MQB_A0]), CAR.AUDI_A3_MK3: [ @@ -265,7 +266,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020-23", footnotes=[Footnote.VW_MQB_A0]), CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-22"), CAR.SKODA_OCTAVIA_MK3: [ - VWCarInfo("Škoda Octavia 2015, 2018-19"), + VWCarInfo("Škoda Octavia 2015-19"), VWCarInfo("Škoda Octavia RS 2016"), ], } @@ -396,6 +397,7 @@ FW_VERSIONS = { }, CAR.CRAFTER_MK2: { (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8704L906056BP\xf1\x894729', b'\xf1\x8704L906056EK\xf1\x896391', b'\xf1\x8705L906023BC\xf1\x892688', ], @@ -403,15 +405,18 @@ FW_VERSIONS = { #(Ecu.transmission, 0x7e1, None): [ #], (Ecu.srs, 0x715, None): [ + b'\xf1\x873Q0959655AL\xf1\x890505\xf1\x82\x0e1411001413001203151311031100', b'\xf1\x873Q0959655BG\xf1\x890703\xf1\x82\x0e16120016130012051G1313052900', b'\xf1\x875QF959655AS\xf1\x890755\xf1\x82\x1315140015150011111100050200--1311120749', ], (Ecu.eps, 0x712, None): [ + b'\xf1\x872N0909143D\x00\xf1\x897010\xf1\x82\x05183AZ306A2', b'\xf1\x872N0909143E \xf1\x897021\xf1\x82\x05163AZ306A2', b'\xf1\x872N0909144K \xf1\x897045\xf1\x82\x05233AZ810A2', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', + b'\xf1\x872Q0907572J \xf1\x890156', b'\xf1\x872Q0907572M \xf1\x890233', ], }, @@ -461,6 +466,7 @@ FW_VERSIONS = { b'\xf1\x878V0906259K \xf1\x890003', b'\xf1\x878V0906259P \xf1\x890001', b'\xf1\x878V0906259Q \xf1\x890002', + b'\xf1\x878V0906259R \xf1\x890002', b'\xf1\x878V0906264F \xf1\x890003', b'\xf1\x878V0906264L \xf1\x890002', b'\xf1\x878V0906264M \xf1\x890001', @@ -502,6 +508,7 @@ FW_VERSIONS = { b'\xf1\x870GC300012A \xf1\x891401', b'\xf1\x870GC300012A \xf1\x891403', b'\xf1\x870GC300014B \xf1\x892401', + b'\xf1\x870GC300014B \xf1\x892403', b'\xf1\x870GC300014B \xf1\x892405', b'\xf1\x870GC300020G \xf1\x892401', b'\xf1\x870GC300020G \xf1\x892403', @@ -521,6 +528,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1314160011123300314240012250229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2251229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2252229333463100', + b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142405A2251229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142405A2252229333463100', b'\xf1\x875Q0959655C \xf1\x890361\xf1\x82\x111413001112120004110415121610169112', b'\xf1\x875Q0959655D \xf1\x890388\xf1\x82\x111413001113120006110417121A101A9113', @@ -547,6 +555,7 @@ FW_VERSIONS = { b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571A0J714A1', b'\xf1\x873Q0909144L \xf1\x895081\xf1\x82\x0571A0JA15A1', b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A01A18A1', + b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A02A16A1', b'\xf1\x873Q0909144M \xf1\x895082\xf1\x82\x0571A0JA16A1', b'\xf1\x873QM909144 \xf1\x895072\xf1\x82\x0571A01714A1', b'\xf1\x875Q0909143K \xf1\x892033\xf1\x820519A9040203', @@ -766,15 +775,18 @@ FW_VERSIONS = { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906027NJ\xf1\x891445', b'\xf1\x8704E906027NP\xf1\x891286', + b'\xf1\x8705E906013BD\xf1\x892496', b'\xf1\x8705E906013E \xf1\x891624', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8709G927158EM\xf1\x893812', b'\xf1\x8709S927158BL\xf1\x893791', + b'\xf1\x8709S927158DN\xf1\x893946', b'\xf1\x8709S927158FF\xf1\x893876', ], (Ecu.srs, 0x715, None): [ b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1311111111333500314646021450149333613100', + b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1312111111333500314646021550159333613100', b'\xf1\x875Q0959655CE\xf1\x890421\xf1\x82\x1311110011333300314240021350139333613100', ], (Ecu.eps, 0x712, None): [ @@ -814,11 +826,13 @@ FW_VERSIONS = { b'\xf1\x875NA906259H \xf1\x890002', b'\xf1\x875NA907115E \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890005', + b'\xf1\x875NA907115J \xf1\x890002', b'\xf1\x8783A907115B \xf1\x890005', b'\xf1\x8783A907115F \xf1\x890002', b'\xf1\x8783A907115G \xf1\x890001', b'\xf1\x8783A907115K \xf1\x890001', b'\xf1\x8704E906024AP\xf1\x891461', + b'\xf1\x8783A907115 \xf1\x890007', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8709G927158DT\xf1\x893698', @@ -836,12 +850,14 @@ FW_VERSIONS = { b'\xf1\x870DL300013G \xf1\x892120', b'\xf1\x870DL300014C \xf1\x893703', b'\xf1\x870DD300046K \xf1\x892302', + b'\xf1\x870GC300013P \xf1\x892401', ], (Ecu.srs, 0x715, None): [ b'\xf1\x875Q0959655AR\xf1\x890317\xf1\x82\02331310031333334313132573732379333313100', b'\xf1\x875Q0959655BJ\xf1\x890336\xf1\x82\x1312110031333300314232583732379333423100', b'\xf1\x875Q0959655BJ\xf1\x890339\xf1\x82\x1331310031333334313132013730379333423100', b'\xf1\x875Q0959655BM\xf1\x890403\xf1\x82\02316143231313500314641011750179333423100', + b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1312110031333300314240013750379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02312110031333300314240583752379333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\02331310031333336313140013950399333423100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x1331310031333334313140013750379333423100', @@ -849,6 +865,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655CB\xf1\x890421\xf1\x82\x1316143231313500314647021750179333613100', b'\xf1\x875Q0959655CG\xf1\x890421\xf1\x82\x1331310031333300314240024050409333613100', b'\xf1\x875Q0959655CD\xf1\x890421\xf1\x82\x13123112313333003145406F6154619333613100', + b'\xf1\x875Q0959655AG\xf1\x890338\xf1\x82\x1316143231313500314617011730179333423100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820529A6060603', @@ -863,6 +880,7 @@ FW_VERSIONS = { b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\00521A60804A1', b'\xf1\x875QM907144D \xf1\x891063\xf1\x82\x002SA6092SOM', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567A6017A00', + b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60804A1', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', @@ -902,12 +920,14 @@ FW_VERSIONS = { b'\xf1\x8704L906057AP\xf1\x891186', b'\xf1\x8704L906057N \xf1\x890413', b'\xf1\x8705L906023E \xf1\x891352', + b'\xf1\x8705L906023MR\xf1\x892582', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x870BT300012G \xf1\x893102', b'\xf1\x870BT300012E \xf1\x893105', b'\xf1\x870BT300046R \xf1\x893102', b'\xf1\x870DV300012B \xf1\x893701', + b'\xf1\x870DV300012B \xf1\x893702', ], (Ecu.srs, 0x715, None): [ b'\xf1\x872Q0959655AE\xf1\x890506\xf1\x82\x1316170411110411--04041704161611152S1411', @@ -1049,10 +1069,12 @@ FW_VERSIONS = { b'\xf1\x8705L906022M \xf1\x890901', b'\xf1\x8783A906259 \xf1\x890001', b'\xf1\x8783A906259 \xf1\x890005', + b'\xf1\x8783A906259C \xf1\x890002', b'\xf1\x8783A906259F \xf1\x890001', ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x8709G927158CN\xf1\x893608', + b'\xf1\x8709G927158FL\xf1\x893758', b'\xf1\x8709G927158GP\xf1\x893937', b'\xf1\x870GC300045D \xf1\x892802', b'\xf1\x870GC300046F \xf1\x892701', @@ -1067,6 +1089,7 @@ FW_VERSIONS = { b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567G6000300', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567G6000800', b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\x0571G60533A1', + b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\x0571G60733A1', b'\xf1\x875TA907145D \xf1\x891051\xf1\x82\x001PG60A1P7N', ], (Ecu.fwdRadar, 0x757, None): [ @@ -1254,6 +1277,7 @@ FW_VERSIONS = { b'\xf1\x8704E906027HD\xf1\x893742', b'\xf1\x8704E906027MH\xf1\x894786', b'\xf1\x8704L906021DT\xf1\x898127', + b'\xf1\x8704L906026BP\xf1\x897608', b'\xf1\x8704L906026BS\xf1\x891541', b'\xf1\x875G0906259C \xf1\x890002', ], @@ -1263,11 +1287,13 @@ FW_VERSIONS = { b'\xf1\x870CW300043B \xf1\x891601', b'\xf1\x870CW300043P \xf1\x891605', b'\xf1\x870D9300041C \xf1\x894936', + b'\xf1\x870D9300041H \xf1\x895220', b'\xf1\x870D9300041J \xf1\x894902', b'\xf1\x870D9300041P \xf1\x894507', ], (Ecu.srs, 0x715, None): [ b'\xf1\x873Q0959655AC\xf1\x890200\xf1\x82\r11120011100010022212110200', + b'\xf1\x873Q0959655AP\xf1\x890305\xf1\x82\r11110011110011213331312131', b'\xf1\x873Q0959655AQ\xf1\x890200\xf1\x82\r11120011100010312212113100', b'\xf1\x873Q0959655AS\xf1\x890200\xf1\x82\r11120011100010022212110200', b'\xf1\x873Q0959655BH\xf1\x890703\xf1\x82\0163221003221002105755331052100', @@ -1279,13 +1305,15 @@ FW_VERSIONS = { b'\xf1\x873Q0909144J \xf1\x895063\xf1\x82\00566A01513A1', b'\xf1\x875Q0909144AA\xf1\x891081\xf1\x82\00521T00403A1', b'\xf1\x875Q0909144AB\xf1\x891082\xf1\x82\x0521T00403A1', - b'\xf1\x875QD909144E \xf1\x891081\xf1\x82\x0521T00503A1', b'\xf1\x875Q0909144R \xf1\x891061\xf1\x82\x0516A00604A1', + b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\x0521T00601A1', + b'\xf1\x875QD909144E \xf1\x891081\xf1\x82\x0521T00503A1', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x875Q0907572D \xf1\x890304\xf1\x82\x0101', b'\xf1\x875Q0907572F \xf1\x890400\xf1\x82\00101', b'\xf1\x875Q0907572J \xf1\x890654', + b'\xf1\x875Q0907572K \xf1\x890402\xf1\x82\x0101', b'\xf1\x875Q0907572P \xf1\x890682', b'\xf1\x875Q0907572R \xf1\x890771', ], @@ -1315,8 +1343,12 @@ FW_VERSIONS = { }, CAR.SKODA_SUPERB_MK3: { (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8704E906027BS\xf1\x892887', + b'\xf1\x8704E906027BT\xf1\x899042', b'\xf1\x8704L906026ET\xf1\x891343', + b'\xf1\x8704L906026ET\xf1\x891990', b'\xf1\x8704L906026FP\xf1\x891196', + b'\xf1\x8704L906026KA\xf1\x896014', b'\xf1\x8704L906026KB\xf1\x894071', b'\xf1\x8704L906026KD\xf1\x894798', b'\xf1\x8704L906026MT\xf1\x893076', @@ -1327,12 +1359,16 @@ FW_VERSIONS = { ], (Ecu.transmission, 0x7e1, None): [ b'\xf1\x870CW300042H \xf1\x891601', + b'\xf1\x870CW300043B \xf1\x891603', + b'\xf1\x870CW300049Q \xf1\x890906', b'\xf1\x870D9300011T \xf1\x894801', b'\xf1\x870D9300012 \xf1\x894940', b'\xf1\x870D9300013A \xf1\x894905', b'\xf1\x870D9300014K \xf1\x895006', b'\xf1\x870D9300041H \xf1\x894905', + b'\xf1\x870D9300042M \xf1\x895013', b'\xf1\x870D9300043F \xf1\x895202', + b'\xf1\x870GC300013K \xf1\x892403', b'\xf1\x870GC300014M \xf1\x892801', b'\xf1\x870GC300019G \xf1\x892803', b'\xf1\x870GC300043 \xf1\x892301', @@ -1342,18 +1378,23 @@ FW_VERSIONS = { b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\022111200111121001121118112231292221111', b'\xf1\x875Q0959655AK\xf1\x890130\xf1\x82\022111200111121001121110012211292221111', b'\xf1\x875Q0959655AS\xf1\x890317\xf1\x82\x1331310031313100313131823133319331313100', + b'\xf1\x875Q0959655AT\xf1\x890317\xf1\x82\x1331310031313100313131013131319331313100', b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\02331310031313100313131013141319331413100', b'\xf1\x875Q0959655BK\xf1\x890336\xf1\x82\x1331310031313100313131013141319331413100', b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151013141319331423100', + b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151823143319331423100', b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1333310031313100313152025350539331463100', b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1333310031313100313152855372539331463100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143K \xf1\x892033\xf1\x820514UZ070203', + b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820522UZ050303', b'\xf1\x875Q0909143M \xf1\x892041\xf1\x820522UZ070303', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820526UZ070505', + b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820526UZ060505', b'\xf1\x875Q0910143B \xf1\x892201\xf1\x82\00563UZ060700', b'\xf1\x875Q0910143B \xf1\x892201\xf1\x82\x0563UZ060600', + b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567UZ070500', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567UZ070600', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567UZ070700', ], diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 9cfe0c798..0d97032a0 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -59,6 +59,9 @@ ACTUATOR_FIELDS = tuple(car.CarControl.Actuators.schema.fields.keys()) ACTIVE_STATES = (State.enabled, State.softDisabling, State.overriding) ENABLED_STATES = (State.preEnabled, *ACTIVE_STATES) +DP_VAG_TIMEBOMB_BYPASS_WARNING = 34000 +DP_VAG_TIMEBOMB_BYPASS_START = 345000 +DP_VAG_TIMEBOMB_BYPASS_END = 348000 class Controls: def __init__(self, sm=None, pm=None, can_sock=None, CI=None): @@ -80,23 +83,22 @@ class Controls: else: self.camera_packets = ["roadCameraState", "driverCameraState"] - self.can_sock = can_sock - if can_sock is None: - can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 20 - self.can_sock = messaging.sub_sock('can', timeout=can_timeout) + can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 20 + self.can_sock = messaging.sub_sock('can', timeout=can_timeout) self.log_sock = messaging.sub_sock('androidLog') self.params = Params() self.dp_no_gps_ctrl = self.params.get_bool("dp_no_gps_ctrl") self.dp_no_fan_ctrl = self.params.get_bool("dp_no_fan_ctrl") - self.params = Params() + self.dp_0813 = self.params.get_bool("dp_0813") self._dp_alka = self.params.get_bool("dp_alka") self._dp_alka_active = True self._dp_alka_trigger_count = 0 self._dp_alka_btn_block_frame = 0 - self.dp_0813 = self.params.get_bool("dp_0813") self.dp_device_disable_temp_check = self.params.get_bool("dp_device_disable_temp_check") + self._dp_vag_timebomb_bypass_counter = 0 + self._dp_vag_timebomb_bypass = self.params.get_bool("dp_vag_timebomb_bypass") self.sm = sm if self.sm is None: ignore = ['testJoystick'] @@ -644,6 +646,26 @@ class Controls: else: CC.latActive = True + # rick - vag timebomb bypass + if self._dp_vag_timebomb_bypass: + if not CC.latActive: + self._dp_vag_timebomb_bypass_counter = 0 + else: + self._dp_vag_timebomb_bypass_counter += 1 + + # start warning + if DP_VAG_TIMEBOMB_BYPASS_WARNING <= self._dp_vag_timebomb_bypass_counter < DP_VAG_TIMEBOMB_BYPASS_START: + self.events.add(EventName.steerTimeLimit) + + # disable steering + if self._dp_vag_timebomb_bypass_counter >= DP_VAG_TIMEBOMB_BYPASS_START: + self.events.add(EventName.ldw) + CC.latActive = False + + # reset counter + if self._dp_vag_timebomb_bypass_counter >= DP_VAG_TIMEBOMB_BYPASS_END: + self._dp_vag_timebomb_bypass_counter = 0 + actuators = CC.actuators actuators.longControlState = self.LoC.long_control_state @@ -685,8 +707,8 @@ class Controls: if CC.latActive: steer = clip(self.sm['testJoystick'].axes[1], -1, 1) - # max angle is 45 for angle-based cars - actuators.steer, actuators.steeringAngleDeg = steer, steer * 45. + # max angle is 45 for angle-based cars, max curvature is 0.02 + actuators.steer, actuators.steeringAngleDeg, actuators.curvature = steer, steer * 45., steer * -0.02 lac_log.active = self.active lac_log.steeringAngleDeg = CS.steeringAngleDeg @@ -911,6 +933,7 @@ class Controls: self.is_metric = self.params.get_bool("IsMetric") self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl + # rick - we should disable experimental mode on radarless car w/ 0.8.13 model if self.CP.radarUnavailable and self.dp_0813: self.experimental_mode = False diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index 65e233040..b988fd7e1 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -44,7 +44,6 @@ class MPC_COST_LAT: HEADING = 1.0 STEER_RATE = 1.0 - class VCruiseHelper: def __init__(self, CP): self.CP = CP diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 8b3d2c01a..33ed3fccb 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -666,6 +666,11 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { }, EventName.steerTimeLimit: { + ET.PERMANENT: Alert( + _("Vehicle Steering Time Limit"), + "", + AlertStatus.userPrompt, AlertSize.small, + Priority.LOW, VisualAlert.ldw, AudibleAlert.prompt, 3.), ET.SOFT_DISABLE: soft_disable_alert(_("Vehicle Steering Time Limit")), ET.NO_ENTRY: NoEntryAlert(_("Vehicle Steering Time Limit")), }, diff --git a/selfdrive/controls/lib/lateral_mpc_lib/acados_ocp_lat.json b/selfdrive/controls/lib/lateral_mpc_lib/acados_ocp_lat.json index a7c0271de..0403c52f0 100644 --- a/selfdrive/controls/lib/lateral_mpc_lib/acados_ocp_lat.json +++ b/selfdrive/controls/lib/lateral_mpc_lib/acados_ocp_lat.json @@ -91,124 +91,11 @@ "usphi_e": [] }, "cost": { - "Vu": [ - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ] - ], - "Vu_0": [ - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ], - [ - 0.0 - ] - ], - "Vx": [ - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ] - ], - "Vx_0": [ - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ] - ], - "Vx_e": [ - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ], - [ - 0.0, - 0.0, - 0.0, - 0.0 - ] - ], + "Vu": [], + "Vu_0": [], + "Vx": [], + "Vx_0": [], + "Vx_e": [], "Vz": [], "Vz_0": [], "W": [ @@ -336,7 +223,10 @@ "zu": [], "zu_e": [] }, - "cython_include_dirs": "/data/data/com.termux/files/usr/lib/python3.8/site-packages/numpy/core/include", + "cython_include_dirs": [ + "/data/data/com.termux/files/usr/lib/python3.8/site-packages/numpy/core/include", + "/data/data/com.termux/files/usr/include/python3.8" + ], "dims": { "N": 16, "nbu": 0, @@ -371,73 +261,74 @@ "ny_e": 3, "nz": 0 }, + "json_file": "/data/openpilot/selfdrive/controls/lib/lateral_mpc_lib/acados_ocp_lat.json", "model": { + "con_h_expr": null, + "con_h_expr_e": null, + "con_phi_expr": null, + "con_phi_expr_e": null, + "con_r_expr": null, + "con_r_expr_e": null, + "con_r_in_phi": null, + "con_r_in_phi_e": null, + "cost_conl_custom_outer_hess": null, + "cost_conl_custom_outer_hess_0": null, + "cost_conl_custom_outer_hess_e": null, + "cost_expr_ext_cost": null, + "cost_expr_ext_cost_0": null, + "cost_expr_ext_cost_custom_hess": null, + "cost_expr_ext_cost_custom_hess_0": null, + "cost_expr_ext_cost_custom_hess_e": null, + "cost_expr_ext_cost_e": null, + "cost_psi_expr": null, + "cost_psi_expr_0": null, + "cost_psi_expr_e": null, + "cost_r_in_psi_expr": null, + "cost_r_in_psi_expr_0": null, + "cost_r_in_psi_expr_e": null, + "cost_y_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaajhpffghgpgegdaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgkaaaaaaaegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegdaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpgegdaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaaahdhjgpfbgdgdgfgmgpffghgpgegeaaaaaaaaaaaaaaachjaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachkjjjjjjjjjjjjlpd", + "cost_y_expr_0": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegjaaaaaaaaaaaaaaafaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaajhpffghgpgegdaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgkaaaaaaaegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegdaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpgegdaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaaahdhjgpfbgdgdgfgmgpffghgpgegeaaaaaaaaaaaaaaachjaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaaegmcaaaaaaaaaaaaaachkjjjjjjjjjjjjlpd", + "cost_y_expr_e": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaeghaaaaaaaaaaaaaaadaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaajhpffghgpgegdaaaaaaaaaaaaaaaegbaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegmcaaaaaaaaaaaaaajgkaaaaaaaegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegdaaaaaaaaaaaaaaacheaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpg", + "disc_dyn_expr": null, "dyn_disc_fun": null, "dyn_disc_fun_jac": null, "dyn_disc_fun_jac_hess": null, "dyn_ext_fun_type": "casadi", - "dyn_source_discrete": null, + "dyn_generic_source": null, + "f_expl_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegoaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegdaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaapaaaaaaachpgehbgehjgpgogpfchbgegjgfhdhegnaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpgegbaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaachbaaaaaaaaaaaaaaaegnaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaachfaaaaaaaaaaaaaaaegoaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaachiaaaaaaaaaaaaaaachiaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaaahdhjgpfbgdgdgfgmgpffghgpg", + "f_impl_expr": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaajaaaaaaaihpffghgpgpfegpgehegcaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegoaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegdaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaapaaaaaaachpgehbgehjgpgogpfchbgegjgfhdhegnaaaaaaaaaaaaaaachdaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpgegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaajaaaaaaajhpffghgpgpfegpgehegbaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaachcaaaaaaaaaaaaaaaegnaaaaaaaaaaaaaaachdaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaachgaaaaaaaaaaaaaaaegoaaaaaaaaaaaaaaachdaaaaaaaaaaaaaaachjaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaalaaaaaaaahdhjgpffghgpgpfegpgehchjaaaaaaaaaaaaaaaegcaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaaabaaaaaaahdhjgpfchbgehfgpffghgpgpfegpgehegpcaaaaaaaaaaaaaanaaaaaaaahdhjgpfbgdgdgfgmgpffghgpg", "gnsf": { "nontrivial_f_LO": 1, "purely_linear": 0 }, - "name": "lat" + "name": "lat", + "p": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaeggaaaaaaaaaaaaaaacaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaghpffghgpgegpcaaaaaaaaaaaaaapaaaaaaachpgehbgehjgpgogpfchbgegjgfhdh", + "u": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegfaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaanaaaaaaaahdhjgpfbgdgdgfgmgpffghgpg", + "x": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaafaaaaaaaihpffghgpgegpcaaaaaaaaaaaaaafaaaaaaajhpffghgpgegpcaaaaaaaaaaaaaahaaaaaaaahdhjgpffghgpgegpcaaaaaaaaaaaaaamaaaaaaaahdhjgpfchbgehfgpffghgpg", + "xdot": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegiaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaacaaaaaaaaaaaaaaadaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaegpcaaaaaaaaaaaaaajaaaaaaaihpffghgpgpfegpgehegpcaaaaaaaaaaaaaajaaaaaaajhpffghgpgpfegpgehegpcaaaaaaaaaaaaaalaaaaaaaahdhjgpffghgpgpfegpgehegpcaaaaaaaaaaaaaaabaaaaaaahdhjgpfchbgehfgpffghgpgpfegpgeh", + "z": "jhpnnagiieahaaaadaaaaaaaaaaaaaaaaaegdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, "parameter_values": [ 0.0, 0.0 ], "problem_class": "OCP", - "simulink_opts": { - "inputs": { - "cost_W": 0, - "cost_W_0": 0, - "cost_W_e": 0, - "lbu": 1, - "lbx": 1, - "lbx_0": 1, - "lbx_e": 1, - "lg": 1, - "lh": 1, - "parameter_traj": 1, - "reset_solver": 0, - "u_init": 0, - "ubu": 1, - "ubx": 1, - "ubx_0": 1, - "ubx_e": 1, - "ug": 1, - "uh": 1, - "x_init": 0, - "y_ref": 1, - "y_ref_0": 1, - "y_ref_e": 1 - }, - "outputs": { - "CPU_time": 1, - "CPU_time_lin": 0, - "CPU_time_qp": 0, - "CPU_time_sim": 0, - "KKT_residual": 1, - "solver_status": 1, - "sqp_iter": 1, - "u0": 1, - "utraj": 0, - "x1": 1, - "xtraj": 0 - }, - "samplingtime": "t0" - }, + "shared_lib_ext": ".so", "solver_options": { "Tsim": 0.009765625, "alpha_min": 0.05, "alpha_reduction": 0.7, "collocation_type": "GAUSS_LEGENDRE", + "custom_templates": [], + "custom_update_copy": true, + "custom_update_filename": "", + "custom_update_header_filename": "", "eps_sufficient_descent": 0.0001, "exact_hess_constr": 1, "exact_hess_cost": 1, "exact_hess_dyn": 1, "ext_cost_num_hess": 0, + "ext_fun_compile_flags": "-O2", "full_step_dual": 0, "globalization": "FIXED_STEP", "globalization_use_SOC": 0, @@ -449,6 +340,7 @@ "line_search_use_sufficient_descent": 0, "model_external_shared_lib_dir": null, "model_external_shared_lib_name": null, + "nlp_solver_ext_qp_res": 0, "nlp_solver_max_iter": 100, "nlp_solver_step_length": 1.0, "nlp_solver_tol_comp": 1e-06, @@ -459,13 +351,34 @@ "print_level": 0, "qp_solver": "PARTIAL_CONDENSING_HPIPM", "qp_solver_cond_N": 1, + "qp_solver_cond_ric_alg": 1, "qp_solver_iter_max": 1, + "qp_solver_ric_alg": 1, "qp_solver_tol_comp": null, "qp_solver_tol_eq": null, "qp_solver_tol_ineq": null, "qp_solver_tol_stat": null, "qp_solver_warm_start": 0, "regularize_method": null, + "shooting_nodes": [ + 0.0, + 0.009765625, + 0.0390625, + 0.087890625, + 0.15625, + 0.244140625, + 0.3515625, + 0.478515625, + 0.625, + 0.791015625, + 0.9765625, + 1.181640625, + 1.40625, + 1.650390625, + 1.9140625, + 2.197265625, + 2.5 + ], "sim_method_jac_reuse": [ 0, 0, @@ -485,6 +398,7 @@ 0 ], "sim_method_newton_iter": 3, + "sim_method_newton_tol": 0.0, "sim_method_num_stages": [ 4, 4, diff --git a/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_sim_solver_lat.h b/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_sim_solver_lat.h index 86b9c84c9..e7e8a9d39 100644 --- a/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_sim_solver_lat.h +++ b/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_sim_solver_lat.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -61,6 +58,7 @@ typedef struct sim_solver_capsule /* external functions */ // ERK external_function_param_casadi * sim_forw_vde_casadi; + external_function_param_casadi * sim_vde_adj_casadi; external_function_param_casadi * sim_expl_ode_fun_casadi; external_function_param_casadi * sim_expl_ode_hess; diff --git a/selfdrive/controls/lib/legacy_lateral_planner.py b/selfdrive/controls/lib/legacy_lateral_planner.py index e6696a6be..0e6d5981c 100644 --- a/selfdrive/controls/lib/legacy_lateral_planner.py +++ b/selfdrive/controls/lib/legacy_lateral_planner.py @@ -78,8 +78,8 @@ class LateralPlanner: self.LP.lll_prob *= self.DH.lane_change_ll_prob self.LP.rll_prob *= self.DH.lane_change_ll_prob - # dp - check laneline prob when priority is on use_laneline = False + # dp - check laneline prob when priority is on if self._dp_lat_lane_priority_mode: self._update_laneless_laneline_mode() use_laneline = self._dp_lat_lane_priority_mode_active diff --git a/selfdrive/controls/lib/legacy_longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/legacy_longitudinal_mpc_lib/long_mpc.py index dab06383f..653f0d010 100644 --- a/selfdrive/controls/lib/legacy_longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/legacy_longitudinal_mpc_lib/long_mpc.py @@ -98,6 +98,16 @@ def get_safe_obstacle_distance(v_ego, t_follow): def desired_follow_distance(v_ego, v_lead, t_follow=get_T_FOLLOW()): return get_safe_obstacle_distance(v_ego, t_follow) - get_stopped_equivalence_factor(v_lead) +def get_stopped_equivalence_factor_krkeegen(v_lead, v_ego): + # KRKeegan this offset rapidly decreases the following distance when the lead pulls + # away, resulting in an early demand for acceleration. + v_diff_offset = 0 + if np.all(v_lead - v_ego > 0): + v_diff_offset = ((v_lead - v_ego) * 1.) + v_diff_offset = np.clip(v_diff_offset, 0, STOP_DISTANCE / 2) + v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego)/10), 0) + distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset + return distance def gen_long_model(): model = AcadosModel() @@ -345,7 +355,7 @@ class LongitudinalMpc: self.cruise_min_a = min_a self.cruise_max_a = max_a - def update(self, carstate, radarstate, v_cruise, personality=log.LongitudinalPersonality.standard, use_df_tune=False): + def update(self, carstate, radarstate, v_cruise, personality=log.LongitudinalPersonality.standard, use_df_tune=False, use_krkeegen_tune=False): # t_follow = get_T_FOLLOW(personality) v_ego = self.x0[1] t_follow = get_T_FOLLOW(personality) if not use_df_tune else get_dynamic_follow(v_ego, personality) @@ -361,8 +371,12 @@ class LongitudinalMpc: # To estimate a safe distance from a moving lead, we calculate how much stopping # distance that lead needs as a minimum. We can add that to the current distance # and then treat that as a stopped car/obstacle at this new distance. - lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor(lead_xv_0[:,1]) - lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1]) + if use_krkeegen_tune: + lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor(lead_xv_0[:,1], v_ego) + lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1], v_ego) + else: + lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor(lead_xv_0[:,1]) + lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1]) # Fake an obstacle for cruise, this ensures smooth acceleration to set speed # when the leads are no factor. diff --git a/selfdrive/controls/lib/legacy_longitudinal_planner.py b/selfdrive/controls/lib/legacy_longitudinal_planner.py index 21da804b1..1b1d64c74 100644 --- a/selfdrive/controls/lib/legacy_longitudinal_planner.py +++ b/selfdrive/controls/lib/legacy_longitudinal_planner.py @@ -11,10 +11,11 @@ from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.legacy_modeld.constants import T_IDXS from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState -from openpilot.selfdrive.controls.lib.legacy_longitudinal_mpc_lib.long_mpc import LongitudinalMpc, STOP_DISTANCE +from openpilot.selfdrive.controls.lib.legacy_longitudinal_mpc_lib.long_mpc import LongitudinalMpc from openpilot.selfdrive.controls.lib.legacy_longitudinal_mpc_lib.long_mpc import T_IDXS as T_IDXS_MPC from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, CONTROL_N from openpilot.system.swaglog import cloudlog +from openpilot.selfdrive.controls.lib.legacy_longitudinal_mpc_lib.long_mpc import STOP_DISTANCE from openpilot.selfdrive.controls.lib.vision_turn_controller import VisionTurnController from openpilot.selfdrive.controls.lib.accel_controller import AccelController @@ -70,22 +71,20 @@ class LongitudinalPlanner: self.read_param() self.personality = log.LongitudinalPersonality.standard self.dp_long_use_df_tune = False + self.dp_long_use_krkeegen_tune = False def read_param(self): - try: - self.personality = int(self.params.get('LongitudinalPersonality')) - self.dp_long_use_df_tune = self.params.get_bool('dp_long_use_df_tune') - except (ValueError, TypeError): - self.personality = log.LongitudinalPersonality.standard - self.dp_long_use_df_tune = False + self.personality = int(self.params.get('LongitudinalPersonality')) + self.dp_long_use_df_tune = self.params.get_bool('dp_long_use_df_tune') + self.dp_long_use_krkeegen_tune = self.params.get_bool('dp_long_use_krkeegen_tune') def update(self, sm): if self.param_read_counter % 50 == 0: self.read_param() - if self.param_read_counter % 300 == 0: - self.accel_controller.set_profile(self.params.get("dp_long_accel_profile", encoding='utf-8')) - self.vision_turn_controller.set_enabled(self.params.get_bool("dp_mapd_vision_turn_control")) + if self.param_read_counter % 300 == 0: + self.accel_controller.set_profile(self.params.get("dp_long_accel_profile", encoding='utf-8')) + self.vision_turn_controller.set_enabled(self.params.get_bool("dp_mapd_vision_turn_control")) self.param_read_counter += 1 v_ego = sm['carState'].vEgo @@ -133,7 +132,7 @@ class LongitudinalPlanner: self.mpc.set_weights(prev_accel_constraint, personality=self.personality) self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1]) self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired) - self.mpc.update(sm['carState'], sm['radarState'], v_cruise_sol, personality=self.personality, use_df_tune=self.dp_long_use_df_tune) + self.mpc.update(sm['carState'], sm['radarState'], v_cruise_sol, personality=self.personality, use_df_tune=self.dp_long_use_df_tune, use_krkeegen_tune=self.dp_long_use_krkeegen_tune) self.v_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC, self.mpc.v_solution) self.a_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC, self.mpc.a_solution) diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index 4c4f54b66..9b621cb62 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -102,6 +102,16 @@ def desired_follow_distance(v_ego, v_lead, t_follow=None): t_follow = get_T_FOLLOW() return get_safe_obstacle_distance(v_ego, t_follow) - get_stopped_equivalence_factor(v_lead) +def get_stopped_equivalence_factor_krkeegen(v_lead, v_ego): + # KRKeegan this offset rapidly decreases the following distance when the lead pulls + # away, resulting in an early demand for acceleration. + v_diff_offset = 0 + if np.all(v_lead - v_ego > 0): + v_diff_offset = ((v_lead - v_ego) * 1.) + v_diff_offset = np.clip(v_diff_offset, 0, STOP_DISTANCE / 2) + v_diff_offset = np.maximum(v_diff_offset * ((10 - v_ego)/10), 0) + distance = (v_lead**2) / (2 * COMFORT_BRAKE) + v_diff_offset + return distance def gen_long_model(): model = AcadosModel() @@ -345,7 +355,7 @@ class LongitudinalMpc: self.max_a = max_a # def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard): - def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard, use_df_tune=False): + def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard, use_df_tune=False, use_krkeegen_tune=False): # t_follow = get_T_FOLLOW(personality) v_ego = self.x0[1] t_follow = get_T_FOLLOW(personality) if not use_df_tune else get_dynamic_follow(v_ego, personality) @@ -357,8 +367,12 @@ class LongitudinalMpc: # To estimate a safe distance from a moving lead, we calculate how much stopping # distance that lead needs as a minimum. We can add that to the current distance # and then treat that as a stopped car/obstacle at this new distance. - lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor(lead_xv_0[:,1]) - lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1]) + if use_krkeegen_tune: + lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor_krkeegen(lead_xv_0[:,1], v_ego) + lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor_krkeegen(lead_xv_1[:,1], v_ego) + else: + lead_0_obstacle = lead_xv_0[:,0] + get_stopped_equivalence_factor(lead_xv_0[:,1]) + lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1]) self.params[:,0] = ACCEL_MIN self.params[:,1] = self.max_a diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 1013ea78b..f8201d81e 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -75,10 +75,16 @@ class LongitudinalPlanner: self.read_param() self.personality = log.LongitudinalPersonality.standard self.dp_long_use_df_tune = False + self.dp_long_use_krkeegen_tune = False def read_param(self): - self.personality = int(self.params.get('LongitudinalPersonality')) + try: + self.personality = int(self.params.get('LongitudinalPersonality')) + except (ValueError, TypeError): + self.personality = log.LongitudinalPersonality.standard + self.dp_long_use_df_tune = self.params.get_bool('dp_long_use_df_tune') + self.dp_long_use_krkeegen_tune = self.params.get_bool('dp_long_use_krkeegen_tune') @staticmethod def parse_model(model_msg, model_error, v_ego, taco=False): @@ -164,7 +170,7 @@ class LongitudinalPlanner: self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1]) self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired) x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error, v_ego, taco=True) - self.mpc.update(sm['radarState'], v_cruise_sol, x, v, a, j, personality=self.personality, use_df_tune=self.dp_long_use_df_tune) + self.mpc.update(sm['radarState'], v_cruise_sol, x, v, a, j, personality=self.personality, use_df_tune=self.dp_long_use_df_tune, use_krkeegen_tune=self.dp_long_use_krkeegen_tune) self.v_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.v_solution) self.a_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.a_solution) diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 88218375e..9842d66e6 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -6,8 +6,6 @@ from openpilot.common.params import Params from openpilot.common.realtime import Priority, config_realtime_process from openpilot.system.swaglog import cloudlog from openpilot.selfdrive.hybrid_modeld.constants import T_IDXS -# from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner -# from openpilot.selfdrive.controls.lib.lateral_planner import LateralPlanner import cereal.messaging as messaging from openpilot.system.hardware import TICI @@ -49,6 +47,7 @@ def plannerd_thread(sm=None, pm=None): longitudinal_planner = LongitudinalPlanner(CP) lateral_planner = LateralPlanner(CP, debug=debug_mode) + is_old_model = Params().get_bool("dp_0813") if sm is None: sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2'], @@ -65,7 +64,8 @@ def plannerd_thread(sm=None, pm=None): lateral_planner.publish(sm, pm) longitudinal_planner.update(sm) longitudinal_planner.publish(sm, pm) - # publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner) + # if not is_old_model: + # publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner) def main(sm=None, pm=None): plannerd_thread(sm, pm) diff --git a/selfdrive/hybrid_modeld/_dmonitoringmodeld b/selfdrive/hybrid_modeld/_dmonitoringmodeld index ea49d3311..3cb711e6a 100755 Binary files a/selfdrive/hybrid_modeld/_dmonitoringmodeld and b/selfdrive/hybrid_modeld/_dmonitoringmodeld differ diff --git a/selfdrive/hybrid_modeld/_modeld b/selfdrive/hybrid_modeld/_modeld index 0d201c41d..c1a8dc5c6 100755 Binary files a/selfdrive/hybrid_modeld/_modeld and b/selfdrive/hybrid_modeld/_modeld differ diff --git a/selfdrive/hybrid_modeld/models/supercombo.thneed b/selfdrive/hybrid_modeld/models/supercombo.thneed index f557a6e10..4f07ce7c8 100644 Binary files a/selfdrive/hybrid_modeld/models/supercombo.thneed and b/selfdrive/hybrid_modeld/models/supercombo.thneed differ diff --git a/selfdrive/legacy_modeld/_modeld b/selfdrive/legacy_modeld/_modeld index 46e2a1be0..7d72c3fad 100755 Binary files a/selfdrive/legacy_modeld/_modeld and b/selfdrive/legacy_modeld/_modeld differ diff --git a/selfdrive/legacy_modeld/models/supercombo.thneed b/selfdrive/legacy_modeld/models/supercombo.thneed index ab2e730dc..7b538fe9f 100644 Binary files a/selfdrive/legacy_modeld/models/supercombo.thneed and b/selfdrive/legacy_modeld/models/supercombo.thneed differ diff --git a/selfdrive/locationd/locationd b/selfdrive/locationd/locationd index 3cc1544d4..1fe0a2b83 100755 Binary files a/selfdrive/locationd/locationd and b/selfdrive/locationd/locationd differ diff --git a/selfdrive/locationd/models/generated/car.h b/selfdrive/locationd/models/generated/car.h index 02feaa51e..d7f3502a9 100644 --- a/selfdrive/locationd/models/generated/car.h +++ b/selfdrive/locationd/models/generated/car.h @@ -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_671583855790742447); -void car_inv_err_fun(double *nom_x, double *true_x, double *out_5648898715511339411); -void car_H_mod_fun(double *state, double *out_1463661415422686295); -void car_f_fun(double *state, double dt, double *out_4065214630836186202); -void car_F_fun(double *state, double dt, double *out_8116097140535481129); -void car_h_25(double *state, double *unused, double *out_4769400438462954391); -void car_H_25(double *state, double *unused, double *out_4920414855801952303); -void car_h_24(double *state, double *unused, double *out_5467276253789859636); -void car_H_24(double *state, double *unused, double *out_1655156950789565798); -void car_h_30(double *state, double *unused, double *out_8362735586557612018); -void car_H_30(double *state, double *unused, double *out_2402081897294703676); -void car_h_26(double *state, double *unused, double *out_4441278616070982763); -void car_H_26(double *state, double *unused, double *out_8661918174676008527); -void car_h_27(double *state, double *unused, double *out_4099496445352121952); -void car_H_27(double *state, double *unused, double *out_178487826110760459); -void car_h_29(double *state, double *unused, double *out_3361062318896766373); -void car_H_29(double *state, double *unused, double *out_1891850552980311492); -void car_h_28(double *state, double *unused, double *out_2514929989030348327); -void car_H_28(double *state, double *unused, double *out_6974249570049842066); -void car_h_31(double *state, double *unused, double *out_141268967578377915); -void car_H_31(double *state, double *unused, double *out_4889768893924991875); +void car_err_fun(double *nom_x, double *delta_x, double *out_4194531078134201846); +void car_inv_err_fun(double *nom_x, double *true_x, double *out_5396071230919349347); +void car_H_mod_fun(double *state, double *out_2499327206041353790); +void car_f_fun(double *state, double dt, double *out_4500860229340437360); +void car_F_fun(double *state, double dt, double *out_9000440748762279641); +void car_h_25(double *state, double *unused, double *out_2791333436777253726); +void car_H_25(double *state, double *unused, double *out_7985710765029417005); +void car_h_24(double *state, double *unused, double *out_5318903299789527977); +void car_H_24(double *state, double *unused, double *out_5760002981050548443); +void car_h_30(double *state, double *unused, double *out_2634146768426124581); +void car_H_30(double *state, double *unused, double *out_1069020423537800250); +void car_h_26(double *state, double *unused, double *out_7596526766107417813); +void car_H_26(double *state, double *unused, double *out_6719529989806078387); +void car_h_27(double *state, double *unused, double *out_4419576049476967785); +void car_H_27(double *state, double *unused, double *out_3243783735338225161); +void car_h_29(double *state, double *unused, double *out_4144381987192461896); +void car_H_29(double *state, double *unused, double *out_558789079223408066); +void car_h_28(double *state, double *unused, double *out_582097218183877860); +void car_H_28(double *state, double *unused, double *out_5641188096292938640); +void car_h_31(double *state, double *unused, double *out_5163811280143236534); +void car_H_31(double *state, double *unused, double *out_7955064803152456577); 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); diff --git a/selfdrive/locationd/models/generated/gnss.h b/selfdrive/locationd/models/generated/gnss.h index 7584af259..658d1a532 100644 --- a/selfdrive/locationd/models/generated/gnss.h +++ b/selfdrive/locationd/models/generated/gnss.h @@ -5,18 +5,18 @@ void gnss_update_6(double *in_x, double *in_P, double *in_z, double *in_R, doubl void gnss_update_20(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void gnss_update_7(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void gnss_update_21(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); -void gnss_err_fun(double *nom_x, double *delta_x, double *out_3729148486180488546); -void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_5677138656413877520); -void gnss_H_mod_fun(double *state, double *out_237374271348491673); -void gnss_f_fun(double *state, double dt, double *out_5929499374247199262); -void gnss_F_fun(double *state, double dt, double *out_847881920946397673); -void gnss_h_6(double *state, double *sat_pos, double *out_4769849476023598544); -void gnss_H_6(double *state, double *sat_pos, double *out_747127776806928814); -void gnss_h_20(double *state, double *sat_pos, double *out_5861460590680520073); -void gnss_H_20(double *state, double *sat_pos, double *out_8385843719838436302); -void gnss_h_7(double *state, double *sat_pos_vel, double *out_5467876944101765304); -void gnss_H_7(double *state, double *sat_pos_vel, double *out_4135749185661226665); -void gnss_h_21(double *state, double *sat_pos_vel, double *out_5467876944101765304); -void gnss_H_21(double *state, double *sat_pos_vel, double *out_4135749185661226665); +void gnss_err_fun(double *nom_x, double *delta_x, double *out_5365537455458469032); +void gnss_inv_err_fun(double *nom_x, double *true_x, double *out_3513839179035210816); +void gnss_H_mod_fun(double *state, double *out_2405840849544132315); +void gnss_f_fun(double *state, double dt, double *out_5902818684448534426); +void gnss_F_fun(double *state, double dt, double *out_1914444734837403549); +void gnss_h_6(double *state, double *sat_pos, double *out_2903029344596054497); +void gnss_H_6(double *state, double *sat_pos, double *out_3798983711418579832); +void gnss_h_20(double *state, double *sat_pos, double *out_5130050872567602623); +void gnss_H_20(double *state, double *sat_pos, double *out_8832869769537760488); +void gnss_h_7(double *state, double *sat_pos_vel, double *out_2068205041655051004); +void gnss_H_7(double *state, double *sat_pos_vel, double *out_121303140786155029); +void gnss_h_21(double *state, double *sat_pos_vel, double *out_2068205041655051004); +void gnss_H_21(double *state, double *sat_pos_vel, double *out_121303140786155029); void gnss_predict(double *in_x, double *in_P, double *in_Q, double dt); } \ No newline at end of file diff --git a/selfdrive/locationd/models/generated/libkf.so b/selfdrive/locationd/models/generated/libkf.so index b1a8e2896..19b710ed8 100755 Binary files a/selfdrive/locationd/models/generated/libkf.so and b/selfdrive/locationd/models/generated/libkf.so differ diff --git a/selfdrive/locationd/models/generated/live.h b/selfdrive/locationd/models/generated/live.h index 42248bf79..99806d559 100644 --- a/selfdrive/locationd/models/generated/live.h +++ b/selfdrive/locationd/models/generated/live.h @@ -10,29 +10,29 @@ void live_update_32(double *in_x, double *in_P, double *in_z, double *in_R, doub void live_update_13(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void live_update_14(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); void live_update_33(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea); -void live_H(double *in_vec, double *out_5647844793781907598); -void live_err_fun(double *nom_x, double *delta_x, double *out_7240336443609568449); -void live_inv_err_fun(double *nom_x, double *true_x, double *out_5067105285576238600); -void live_H_mod_fun(double *state, double *out_1707446900005187655); -void live_f_fun(double *state, double dt, double *out_8886202847586122156); -void live_F_fun(double *state, double dt, double *out_8123954071177754895); -void live_h_4(double *state, double *unused, double *out_5003732951226513629); -void live_H_4(double *state, double *unused, double *out_7002519190470052957); -void live_h_9(double *state, double *unused, double *out_2706973776430170011); -void live_H_9(double *state, double *unused, double *out_7243708837099643602); -void live_h_10(double *state, double *unused, double *out_5958541671058094074); -void live_H_10(double *state, double *unused, double *out_6806706378750062726); -void live_h_12(double *state, double *unused, double *out_3703959340398270602); -void live_H_12(double *state, double *unused, double *out_6424768475207536864); -void live_h_35(double *state, double *unused, double *out_1455318101445775547); -void live_H_35(double *state, double *unused, double *out_8077562825866891283); -void live_h_32(double *state, double *unused, double *out_6206442455067868074); -void live_H_32(double *state, double *unused, double *out_6136724488533882482); -void live_h_13(double *state, double *unused, double *out_5313389083226060905); -void live_H_13(double *state, double *unused, double *out_8424484780051135399); -void live_h_14(double *state, double *unused, double *out_2706973776430170011); -void live_H_14(double *state, double *unused, double *out_7243708837099643602); -void live_h_33(double *state, double *unused, double *out_2007778731318175820); -void live_H_33(double *state, double *unused, double *out_4927005821228033679); +void live_H(double *in_vec, double *out_8878279768875785666); +void live_err_fun(double *nom_x, double *delta_x, double *out_4998791096521120383); +void live_inv_err_fun(double *nom_x, double *true_x, double *out_1441787487494056884); +void live_H_mod_fun(double *state, double *out_2717665409679363478); +void live_f_fun(double *state, double dt, double *out_403942427496437977); +void live_F_fun(double *state, double dt, double *out_2458917812698566361); +void live_h_4(double *state, double *unused, double *out_8582149101819624565); +void live_H_4(double *state, double *unused, double *out_5558417177173870845); +void live_h_9(double *state, double *unused, double *out_1154860171408856960); +void live_H_9(double *state, double *unused, double *out_5601107961271233301); +void live_h_10(double *state, double *unused, double *out_969643799357744360); +void live_H_10(double *state, double *unused, double *out_3456013052689401283); +void live_h_12(double *state, double *unused, double *out_5206625952372223305); +void live_H_12(double *state, double *unused, double *out_7868870488503718976); +void live_h_35(double *state, double *unused, double *out_9180592447251693531); +void live_H_35(double *state, double *unused, double *out_8925079234546478221); +void live_h_32(double *state, double *unused, double *out_1313397742306899264); +void live_H_32(double *state, double *unused, double *out_3325668821679395988); +void live_h_13(double *state, double *unused, double *out_2452376588077375079); +void live_H_13(double *state, double *unused, double *out_617763348992320591); +void live_h_14(double *state, double *unused, double *out_1154860171408856960); +void live_H_14(double *state, double *unused, double *out_5601107961271233301); +void live_h_33(double *state, double *unused, double *out_6863252709328783372); +void live_H_33(double *state, double *unused, double *out_6371107834524215791); void live_predict(double *in_x, double *in_P, double *in_Q, double dt); } \ No newline at end of file diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py index b0886eec9..936a8ec1e 100755 --- a/selfdrive/locationd/torqued.py +++ b/selfdrive/locationd/torqued.py @@ -63,8 +63,6 @@ class PointBuckets: def __init__(self, x_bounds, min_points, min_points_total): self.x_bounds = x_bounds self.buckets = {bounds: NPQueue(maxlen=POINTS_PER_BUCKET, rowsize=3) for bounds in x_bounds} - # self.buckets_min_points = dict(zip(x_bounds, min_points, strict=True)) - # rick - TypeError: zip() takes no keyword arguments self.buckets_min_points = dict(zip(x_bounds, min_points)) self.min_points_total = min_points_total @@ -75,12 +73,8 @@ class PointBuckets: return sum(self.bucket_lengths()) def is_valid(self): - # return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values(), strict=True)) \ - # and (self.__len__() >= self.min_points_total) - # rick - TypeError: zip() takes no keyword arguments return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values())) and (self.__len__() >= self.min_points_total) - def add_point(self, x, y): for bound_min, bound_max in self.x_bounds: if (x >= bound_min) and (x < bound_max): @@ -308,6 +302,5 @@ def main(sm=None, pm=None): msg = estimator.get_msg(with_points=True) put_nonblocking("LiveTorqueParameters", msg.to_bytes()) - if __name__ == "__main__": main() diff --git a/selfdrive/loggerd/bootlog b/selfdrive/loggerd/bootlog index c46111b46..21a7f1f09 100755 Binary files a/selfdrive/loggerd/bootlog and b/selfdrive/loggerd/bootlog differ diff --git a/selfdrive/loggerd/loggerd b/selfdrive/loggerd/loggerd index da14c231f..5b882639d 100755 Binary files a/selfdrive/loggerd/loggerd and b/selfdrive/loggerd/loggerd differ diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index c2d252aaa..bfc161461 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -50,13 +50,16 @@ def manager_init() -> None: ("dp_no_gps_ctrl", "0"), ("dp_no_fan_ctrl", "0"), ("dp_logging", "0"), + ("dp_0813", "1"), + + # dp addition ("dp_alka", "0"), ("dp_mapd", "0"), ("dp_lat_lane_priority_mode", "0"), - ("dp_0813", "0"), ("dp_device_auto_shutdown", "0"), ("dp_device_auto_shutdown_in", "30"), ("dp_toyota_sng", "0"), + ("dp_toyota_enhanced_bsm", "0"), ("dp_toyota_auto_lock", "0"), ("dp_toyota_auto_unlock", "0"), ("dp_device_display_off_mode", "0"), @@ -72,6 +75,10 @@ def manager_init() -> None: ("dp_mapd_vision_turn_control", "0"), ("dp_hkg_min_steer_speed_bypass", "0"), ("dp_lat_lane_priority_mode_speed_based", "0"), + ("dp_long_use_krkeegen_tune", "0"), + ("dp_toyota_zss", "0"), + ("dp_long_accel_btn", "0"), + ("dp_long_personality_btn", "0"), ] if not PC: default_params.append(("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8'))) diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index 8328f1cee..a160104bd 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -20,6 +20,29 @@ from openpilot.system.swaglog import cloudlog WATCHDOG_FN = "/dev/shm/wd_" ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None +def mapd_is_enabled(): + try: + return Params().get_bool("dp_mapd") + except Exception: + return False + +def scipy_is_valid(): + try: + import scipy + return True + except (ImportError, AttributeError) as e: + return False + + +def overpy_is_valid(): + try: + import overpy + return True + except (ImportError, AttributeError) as e: + return False + +MAPD_ACTIVATED = mapd_is_enabled() and scipy_is_valid() and overpy_is_valid() + def launcher(proc: str, name: str) -> None: try: @@ -217,6 +240,8 @@ class PythonProcess(ManagerProcess): def prepare(self) -> None: if self.enabled: + if self.module == "selfdrive.mapd.mapd" and not MAPD_ACTIVATED: + return cloudlog.info(f"preimporting {self.module}") importlib.import_module(self.module) diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 67281dcfe..2a5e3b40c 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -36,9 +36,6 @@ def ublox(started, params, CP: car.CarParams) -> bool: def qcomgps(started, params, CP: car.CarParams) -> bool: return started and not ublox_available() - -use_old_model = Params().get_bool("dp_0813") - procs = [ NativeProcess("camerad", "selfdrive/camerad", ["./camerad"], callback=driverview), NativeProcess("clocksd", "system/clocksd", ["./clocksd"]), @@ -53,7 +50,7 @@ procs = [ # NativeProcess("encoderd", "system/loggerd", ["./encoderd"]), # NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], onroad=False, callback=notcar), NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging), - NativeProcess("modeld", "selfdrive/hybrid_modeld", ["./modeld"]), + NativeProcess("modeld", "selfdrive/hybrid_modeld" if not Params().get_bool("dp_0813") else "selfdrive/legacy_modeld", ["./modeld"]), # NativeProcess("mapsd", "selfdrive/navd", ["./mapsd"]), # NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"]), NativeProcess("sensord", "system/sensord", ["./sensord"], enabled=not PC, offroad=EON), diff --git a/selfdrive/sentry.py b/selfdrive/sentry.py index ef339f207..0dbaa08f7 100644 --- a/selfdrive/sentry.py +++ b/selfdrive/sentry.py @@ -4,7 +4,7 @@ from enum import Enum from sentry_sdk.integrations.threading import ThreadingIntegration from openpilot.common.params import Params -# from openpilot.selfdrive.athena.registration import is_registered_device +from openpilot.selfdrive.athena.registration import is_registered_device from openpilot.system.hardware import HARDWARE, PC from openpilot.system.swaglog import cloudlog from openpilot.system.version import get_branch, get_commit, get_origin, get_version, \ diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index 0939c8f34..a6194c870 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -40,7 +40,7 @@ class PowerMonitoring: self.integration_lock = threading.Lock() self.is_oneplus = os.path.isfile('/ONEPLUS') self.dp_device_auto_shutdown = self.params.get_bool("dp_device_auto_shutdown") - self.dp_device_auto_shutdown_in = int(self.params.get("dp_device_auto_shutdown_in")) + self.dp_device_auto_shutdown_in = int(self.params.get("dp_device_auto_shutdown_in")) * 60 self.dp_device_auto_shutdown_voltage_prev = 0 car_battery_capacity_uWh = self.params.get("CarBatteryCapacity") diff --git a/selfdrive/ui/_ui b/selfdrive/ui/_ui index 5edbea43e..5a75b6966 100755 Binary files a/selfdrive/ui/_ui and b/selfdrive/ui/_ui differ diff --git a/selfdrive/ui/qt/spinner b/selfdrive/ui/qt/spinner index 792920493..7adb47f9a 100755 Binary files a/selfdrive/ui/qt/spinner and b/selfdrive/ui/qt/spinner differ diff --git a/selfdrive/ui/qt/text b/selfdrive/ui/qt/text index c233aa272..bb2f2ca83 100755 Binary files a/selfdrive/ui/qt/text and b/selfdrive/ui/qt/text differ diff --git a/selfdrive/ui/soundd/_soundd b/selfdrive/ui/soundd/_soundd index 98f5f948e..dd71e262f 100755 Binary files a/selfdrive/ui/soundd/_soundd and b/selfdrive/ui/soundd/_soundd differ diff --git a/selfdrive/ui/update_translations.py b/selfdrive/ui/update_translations.py index 2fae1abdf..e97ef2e07 100755 --- a/selfdrive/ui/update_translations.py +++ b/selfdrive/ui/update_translations.py @@ -38,7 +38,7 @@ def update_translations(vanish=False, plural_only=None, translations_dir=TRANSLA for file in translation_files.values(): tr_file = os.path.join(translations_dir, f"{file}.ts") - args = f"lupdate -locations none -recursive {UI_DIR} -ts {tr_file}" + (f"-I {BASEDIR}" if BASEDIR != "" else "") + args = f"lupdate -locations none -recursive {UI_DIR} -ts {tr_file} -I {BASEDIR}" if vanish: args += " -no-obsolete" if file in plural_only: diff --git a/system/hardware/eon/libs/strenum.tar.gz b/system/hardware/eon/libs/strenum.tar.gz new file mode 100644 index 000000000..b845ee5cf Binary files /dev/null and b/system/hardware/eon/libs/strenum.tar.gz differ diff --git a/system/hardware/pc/hardware.py b/system/hardware/pc/hardware.py index 27c05f590..0e6a2893d 100644 --- a/system/hardware/pc/hardware.py +++ b/system/hardware/pc/hardware.py @@ -85,3 +85,6 @@ class Pc(HardwareBase): def get_networks(self): return None + + def get_usb_present(self): + return False diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 7e8cd480b..9f21fce78 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -1,19 +1,19 @@ [ { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279.img.xz", - "hash": "8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279", - "hash_raw": "8d8d8620de8b2687f3a8fffdb81b2abd1fe2ead5bc831361a1a212e5589ac279", - "size": 15636480, + "url": "https://commadist.azureedge.net/agnosupdate/boot-7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c.img.xz", + "hash": "7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c", + "hash_raw": "7d953f5e1bc606984e4d49c6f957421a4172f72b4ebd359baa689ef43b7e911c", + "size": 15153152, "sparse": false, "full_check": true, "has_ab": true }, { "name": "abl", - "url": "https://commadist.azureedge.net/agnosupdate/abl-0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d.img.xz", - "hash": "0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d", - "hash_raw": "0084fcf79fea067632a1c2d9519b6445ad484aa8b09f49f22e6b45b4dccacd2d", + "url": "https://commadist.azureedge.net/agnosupdate/abl-50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602.img.xz", + "hash": "50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602", + "hash_raw": "50329ac734ff7a6c20c3f552dce9b13f84b3eb2e73faa64b9810049d9b406602", "size": 274432, "sparse": false, "full_check": true, @@ -21,9 +21,9 @@ }, { "name": "xbl", - "url": "https://commadist.azureedge.net/agnosupdate/xbl-942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa.img.xz", - "hash": "942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa", - "hash_raw": "942b9b2914d89c2a70fdf27380b59e04b549ac2fd53ecb29d6549d1a9c8daeaa", + "url": "https://commadist.azureedge.net/agnosupdate/xbl-dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15.img.xz", + "hash": "dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15", + "hash_raw": "dc297986b38f50c47584bd8549b188b37b1d6a0c77b3255859dd675c177b5c15", "size": 3282672, "sparse": false, "full_check": true, @@ -31,9 +31,9 @@ }, { "name": "xbl_config", - "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf.img.xz", - "hash": "6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf", - "hash_raw": "6881d94599f65d94c13bcc0bd860184dfba2dfe96ec776d08fb35ac5b5f85bbf", + "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40.img.xz", + "hash": "b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40", + "hash_raw": "b73fbbb42934aabc6d4f16ce84ac6c8c0205bc70e0a85412a771f3cc1d62cc40", "size": 98124, "sparse": false, "full_check": true, @@ -41,9 +41,9 @@ }, { "name": "devcfg", - "url": "https://commadist.azureedge.net/agnosupdate/devcfg-9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262.img.xz", - "hash": "9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262", - "hash_raw": "9bbf168baff6101f4890c5c95c118e30813c2610cfb35b8e19e363f04a32a262", + "url": "https://commadist.azureedge.net/agnosupdate/devcfg-2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca.img.xz", + "hash": "2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca", + "hash_raw": "2d3063d106813006ac9ceeaf8818a31d4b33996873e81178ac5129f5e1b82bca", "size": 40336, "sparse": false, "full_check": true, @@ -51,9 +51,9 @@ }, { "name": "aop", - "url": "https://commadist.azureedge.net/agnosupdate/aop-c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222.img.xz", - "hash": "c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222", - "hash_raw": "c1d9d712980f6b2a4b12196597f4d1bf3fe4fec6c59edf29ae63ef21f11b8222", + "url": "https://commadist.azureedge.net/agnosupdate/aop-d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e.img.xz", + "hash": "d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e", + "hash_raw": "d69450d5438b3e5e2ba5b77db1ae49e1cf9cab17836f563aa57192b5b3a4ac3e", "size": 184364, "sparse": false, "full_check": true, @@ -61,9 +61,9 @@ }, { "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-e1fa3018bce9bad01c6967e5e21f1141cf5c8f02d2edfaed51c738f74a32a432.img.xz", - "hash": "611011f3e3f147bc24f371105a9dd3760ec11ba424c56d4a442a66b098c784c0", - "hash_raw": "e1fa3018bce9bad01c6967e5e21f1141cf5c8f02d2edfaed51c738f74a32a432", + "url": "https://commadist.azureedge.net/agnosupdate/system-4a8311dd591006e0c2a6f60060d6ef579ceec9b3d688e8438a9aef4e230ae028.img.xz", + "hash": "23c9f111f81fc3ee83f85016cb320e03a46aad6721a85e1b4a3f04b6a764e934", + "hash_raw": "4a8311dd591006e0c2a6f60060d6ef579ceec9b3d688e8438a9aef4e230ae028", "size": 10737418240, "sparse": true, "full_check": false, diff --git a/system/proclogd/proclogd b/system/proclogd/proclogd index 701dee6d8..e745e014d 100755 Binary files a/system/proclogd/proclogd and b/system/proclogd/proclogd differ diff --git a/system/sensord/_sensord b/system/sensord/_sensord index 957a9df8d..ab374bc13 100755 Binary files a/system/sensord/_sensord and b/system/sensord/_sensord differ diff --git a/system/ubloxd/ubloxd b/system/ubloxd/ubloxd index b271f8edc..3bc4025ca 100755 Binary files a/system/ubloxd/ubloxd and b/system/ubloxd/ubloxd differ diff --git a/third_party/acados/acados_template/__pycache__/__init__.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/__init__.cpython-38.pyc index 6d5cb8b25..ff3e0f1ae 100644 Binary files a/third_party/acados/acados_template/__pycache__/__init__.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/__init__.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/acados_model.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/acados_model.cpython-38.pyc index 8f1c86185..7cccec119 100644 Binary files a/third_party/acados/acados_template/__pycache__/acados_model.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/acados_model.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/acados_ocp.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/acados_ocp.cpython-38.pyc index 6ce2aae79..008e77e73 100644 Binary files a/third_party/acados/acados_template/__pycache__/acados_ocp.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/acados_ocp.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/acados_ocp_solver.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/acados_ocp_solver.cpython-38.pyc index cbd39ad6a..28e8fea72 100644 Binary files a/third_party/acados/acados_template/__pycache__/acados_ocp_solver.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/acados_ocp_solver.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/acados_sim.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/acados_sim.cpython-38.pyc index 62e8ea7d4..72229e6de 100644 Binary files a/third_party/acados/acados_template/__pycache__/acados_sim.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/acados_sim.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/acados_sim_solver.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/acados_sim_solver.cpython-38.pyc index 32e50e4b5..49d3db4cb 100644 Binary files a/third_party/acados/acados_template/__pycache__/acados_sim_solver.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/acados_sim_solver.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/builders.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/builders.cpython-38.pyc index 3d508a7ba..1cac1094f 100644 Binary files a/third_party/acados/acados_template/__pycache__/builders.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/builders.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/casadi_function_generation.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/casadi_function_generation.cpython-38.pyc new file mode 100644 index 000000000..588c0d29a Binary files /dev/null and b/third_party/acados/acados_template/__pycache__/casadi_function_generation.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/utils.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/utils.cpython-38.pyc index fca9127de..55baaaa40 100644 Binary files a/third_party/acados/acados_template/__pycache__/utils.cpython-38.pyc and b/third_party/acados/acados_template/__pycache__/utils.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/__pycache__/zoro_description.cpython-38.pyc b/third_party/acados/acados_template/__pycache__/zoro_description.cpython-38.pyc new file mode 100644 index 000000000..df6fb92f6 Binary files /dev/null and b/third_party/acados/acados_template/__pycache__/zoro_description.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/__init__.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 000000000..591bd42a4 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/__init__.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/check_reformulation.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/check_reformulation.cpython-38.pyc new file mode 100644 index 000000000..1e3bcf58d Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/check_reformulation.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/detect_affine_terms_reduce_nonlinearity.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/detect_affine_terms_reduce_nonlinearity.cpython-38.pyc new file mode 100644 index 000000000..f7a149275 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/detect_affine_terms_reduce_nonlinearity.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/detect_gnsf_structure.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/detect_gnsf_structure.cpython-38.pyc new file mode 100644 index 000000000..b9f4c6b21 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/detect_gnsf_structure.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/determine_input_nonlinearity_function.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/determine_input_nonlinearity_function.cpython-38.pyc new file mode 100644 index 000000000..5256b670a Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/determine_input_nonlinearity_function.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/determine_trivial_gnsf_transcription.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/determine_trivial_gnsf_transcription.cpython-38.pyc new file mode 100644 index 000000000..709bcc39d Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/determine_trivial_gnsf_transcription.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_LOS.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_LOS.cpython-38.pyc new file mode 100644 index 000000000..6f0241b36 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_LOS.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_invertible_E_mat.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_invertible_E_mat.cpython-38.pyc new file mode 100644 index 000000000..2bc653434 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/reformulate_with_invertible_E_mat.cpython-38.pyc differ diff --git a/third_party/acados/acados_template/gnsf/__pycache__/structure_detection_print_summary.cpython-38.pyc b/third_party/acados/acados_template/gnsf/__pycache__/structure_detection_print_summary.cpython-38.pyc new file mode 100644 index 000000000..007237c32 Binary files /dev/null and b/third_party/acados/acados_template/gnsf/__pycache__/structure_detection_print_summary.cpython-38.pyc differ