Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 49 additions & 5 deletions opendbc/car/psa/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.psa.values import LKAS_LIMITS
from opendbc.car.psa.values import CAR, DBC, CarControllerParams
from opendbc.car.interfaces import CarStateBase

Expand All @@ -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
Expand All @@ -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']))
Expand Down
38 changes: 38 additions & 0 deletions opendbc/car/psa/fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
#
],
},
}
14 changes: 14 additions & 0 deletions opendbc/car/psa/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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(
Expand Down
Loading