From e3a6b92ae6fa54152318c8a45617b0d91784e7ce Mon Sep 17 00:00:00 2001 From: cristian zantedeschi Date: Sat, 20 Jun 2026 10:41:10 +0200 Subject: [PATCH 1/2] peugeot 3008 --- opendbc/car/psa/carstate.py | 54 ++++++++++++++++++++++++++++++--- opendbc/car/psa/fingerprints.py | 38 +++++++++++++++++++++++ opendbc/car/psa/values.py | 14 +++++++++ 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/opendbc/car/psa/carstate.py b/opendbc/car/psa/carstate.py index c13bff5bdaf..80c91f88f3d 100644 --- a/opendbc/car/psa/carstate.py +++ b/opendbc/car/psa/carstate.py @@ -2,6 +2,7 @@ from opendbc.car import structs, Bus from opendbc.can.parser import CANParser from opendbc.car.common.conversions import Conversions as CV +from opendbc.car.mazda.values import LKAS_LIMITS from opendbc.car.psa.values import CAR, DBC, CarControllerParams from opendbc.car.interfaces import CarStateBase @@ -27,23 +28,52 @@ def update(self, can_parsers) -> structs.CarState: ret.standstill = bool(cp_adas.vl['HS2_DYN_UCF_MDD_32D']['VEHICLE_STANDSTILL']) # gas - ret.gasPressed = cp_cam.vl['DRIVER']['GAS_PEDAL'] > 0 + # gas + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + ret.gasPressed = cp.vl['Dyn5_CMM']['P334_ACCPed_Position'] > 0 + else: + ret.gasPressed = cp_cam.vl['DRIVER']['GAS_PEDAL'] > 0 # brake ret.brakePressed = bool(cp_cam.vl['Dat_BSI']['P013_MainBrake']) ret.parkingBrake = cp.vl['Dyn_EasyMove']['P337_Com_stPrkBrk'] == 1 # 0: disengaged, 1: engaged, 3: brake actuator moving + # brake pressure + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + raw = cp.vl["Dyn2_FRE"]["BRAKE_PRESSURE"] + ret.brake = max(0.0, float(raw) - 550.0) # clamp a 0 + # steering wheel STEERING_ALT_BUS = { CAR.PSA_PEUGEOT_208: cp.vl, CAR.PSA_PEUGEOT_508: cp_cam.vl, + CAR.PSA_PEUGEOT_3008: cp.vl, + } bus = STEERING_ALT_BUS[self.CP.carFingerprint] ret.steeringAngleDeg = bus['STEERING_ALT']['ANGLE'] # EPS - ret.steeringRateDeg = bus['STEERING_ALT']['RATE'] * (1 - 2 * bus['STEERING_ALT']['RATE_SIGN']) # convert [0,1] to [1,-1] EPS: rot. speed * rot. sign + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + # PSA EPS encodes the steering rotation direction bit inverted from the driver's perspective: + # RATE_SIGN = 0 → clockwise (right turn) + # RATE_SIGN = 1 → anticlockwise (left turn) + # Invert the sign to match OpenPilot's convention: right = positive, left = negative. + ret.steeringRateDeg = bus['STEERING_ALT']['RATE'] * (1 - 2 * bus['STEERING_ALT']['RATE_SIGN']) + else: + # Convert EPS direction bit [0,1] to signed multiplier [-1,+1] + # Standard convention: 0 → left (negative), 1 → right (positive) + ret.steeringRateDeg = bus['STEERING_ALT']['RATE'] * (1 - 2 * bus['STEERING_ALT']['RATE_SIGN']) # convert [0,1] to [1,-1] EPS: rot. speed * rot. sign + ret.steeringTorque = cp.vl['STEERING']['DRIVER_TORQUE'] ret.steeringTorqueEps = cp.vl['IS_DAT_DIRA']['EPS_TORQUE'] - ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5) + + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + # Peugeot 3008: EPS_TORQUE represents only driver-applied torque (no motor assist). + # The signal is already smoothed by the EPS ECU, so update_steering_pressed is unnecessary. + ret.steeringPressed = abs(ret.steeringTorque) > LKAS_LIMITS.STEER_THRESHOLD + else: + ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5) + + # ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5) self.eps_active = cp.vl['IS_DAT_DIRA']['EPS_STATE_LKA'] == 3 # 0: Unauthorized, 1: Authorized, 2: Available, 3: Active, 4: Defect # cruise @@ -64,8 +94,22 @@ def update(self, can_parsers) -> structs.CarState: # blinkers blinker = cp_cam.vl['HS2_DAT7_BSI_612']['CDE_CLG_ET_HDC'] - ret.leftBlinker = blinker == 1 - ret.rightBlinker = blinker == 2 + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + ret.leftBlinker = blinker == 2 + ret.rightBlinker = blinker == 1 + else: + ret.leftBlinker = blinker == 1 + ret.rightBlinker = blinker == 2 + + # Blind sensor ( there is not left and right ) + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + ret.leftBlindspot = cp_adas.vl["HS2_DYN_MDD_ETAT_2F6"]["BLIND_SENSOR"] != 0 + ret.rightBlindspot = cp_adas.vl["HS2_DYN_MDD_ETAT_2F6"]["BLIND_SENSOR"] != 0 + + # Auto Braking in progress + if self.CP.carFingerprint == CAR.PSA_PEUGEOT_3008: + ret.stockAeb = cp_adas.vl["HS2_DYN1_MDD_ETAT_2B6"]["AUTO_BRAKING_STATUS"] == 1 + # lock info ret.doorOpen = any((cp_cam.vl['Dat_BSI']['DRIVER_DOOR'], cp_cam.vl['Dat_BSI']['PASSENGER_DOOR'])) diff --git a/opendbc/car/psa/fingerprints.py b/opendbc/car/psa/fingerprints.py index 207d7d8bb32..4cd2f6b4382 100644 --- a/opendbc/car/psa/fingerprints.py +++ b/opendbc/car/psa/fingerprints.py @@ -28,4 +28,42 @@ b'369042321125160806', ], }, + + CAR.PSA_PEUGEOT_3008: { + # ARTIV - Front Radar ADAS + (Ecu.fwdRadar, 0x6B6, None): [ ], + + # DIRECTN - Electronic power steering + (Ecu.eps, 0x6B5, None): [ ], + + # HCU2 - Hybrid Control Unit + (Ecu.hybrid, 0x6A6, None): [ ], + + # BOITEVIT - Automatic transmission (EAT6/8) + (Ecu.transmission, 0x6A9, None): [ + ## Peugeot 3008 II (Phase I, 2016) 1.6 PureTech (180 Hp) Automatic S&S /2018, 2019, 2020 + b'1614191B101502000000', + b'\xff\xff\x00\x000`\x08\x01\x13\x01%\x06\x08\xff\xff\xff\x00\x02\x00\x00\x01\x934t', + # + ], + + # FREINEBB - Electronic Brake Booster + (Ecu.electricBrakeBooster, 0x5D0, None): [], + + # INJ - Engine (VCU) + (Ecu.engine, 0x6A8, None): [ + ## Peugeot 3008 II (Phase I, 2016) 1.6 PureTech (180 Hp) Automatic S&S /2018, 2019, 2020 + b'000D170047100', + b'\xff\xff\x00\x00\x03&\t\x02\x13\x01C1\x04\xff\xff\xff\x00\x02\x00\x00\x01\x93YW', + # + ], + + # ABRASR - ABS/ESP + (Ecu.abs, 0x6AD, None): [ + ## Peugeot 3008 II (Phase I, 2016) 1.6 PureTech (180 Hp) Automatic S&S /2018, 2019, 2020 + b'085065201906190129', + b'\x00\x00\x00\x00\x03\x92\x01\x06\x11\x01\x06\x18\x02\xff\xff\xff\x00\x02\x00\x00\x01\x92\x83\x12', + # + ], + }, } diff --git a/opendbc/car/psa/values.py b/opendbc/car/psa/values.py index e2ee255f8ba..7bee5dbe468 100644 --- a/opendbc/car/psa/values.py +++ b/opendbc/car/psa/values.py @@ -42,6 +42,11 @@ class CAR(Platforms): [PSACarDocs("Peugeot 508 2019-23")], CarSpecs(mass=1720, wheelbase=2.79, steerRatio=17.6), ) + PSA_PEUGEOT_3008 = PSAPlatformConfig( + [PSACarDocs("PEUGEOT 3008 2016-29")], + # https://www.auto-data.net/en/peugeot-3008-ii-phase-i-2016-1.6-puretech-180hp-automatic-s-s-34446#google_vignette + CarSpecs(mass=1577, wheelbase=2.675, steerRatio=17.69, tireStiffnessFactor=0.996044 ), + ) PSA_DIAG_REQ = bytes([uds.SERVICE_TYPE.DIAGNOSTIC_SESSION_CONTROL, 0x01]) @@ -52,6 +57,15 @@ class CAR(Platforms): PSA_RX_OFFSET = -0x20 +class LKAS_LIMITS: + # Peugeot 3008 + # STEER_THRESHOLD: torque (deci-Nm) to detect driver input (steeringPressed) + # DISABLE/ENABLE_SPEED: LKA hysteresis in km/h + STEER_THRESHOLD = 5 + DISABLE_SPEED = 50 # kph + ENABLE_SPEED = 50 # kph + + FW_QUERY_CONFIG = FwQueryConfig( requests=[ Request( From d2a70ea2934ab2cbcaec539050e75e674c7ab9e0 Mon Sep 17 00:00:00 2001 From: cristian zantedeschi Date: Sat, 20 Jun 2026 12:31:54 +0200 Subject: [PATCH 2/2] peugeot 3008 --- opendbc/car/psa/carstate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc/car/psa/carstate.py b/opendbc/car/psa/carstate.py index 80c91f88f3d..bc84ce322a4 100644 --- a/opendbc/car/psa/carstate.py +++ b/opendbc/car/psa/carstate.py @@ -2,7 +2,7 @@ from opendbc.car import structs, Bus from opendbc.can.parser import CANParser from opendbc.car.common.conversions import Conversions as CV -from opendbc.car.mazda.values import LKAS_LIMITS +from opendbc.car.psa.values import LKAS_LIMITS from opendbc.car.psa.values import CAR, DBC, CarControllerParams from opendbc.car.interfaces import CarStateBase