You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.7 KiB
129 lines
4.7 KiB
2 months ago
|
import copy
|
||
|
from opendbc.can.parser import CANParser
|
||
|
from opendbc.car import Bus, structs
|
||
|
from opendbc.car.interfaces import CarStateBase
|
||
|
from opendbc.car.rivian.values import DBC, GEAR_MAP
|
||
|
from opendbc.car.common.conversions import Conversions as CV
|
||
|
|
||
|
GearShifter = structs.CarState.GearShifter
|
||
|
|
||
|
|
||
|
class CarState(CarStateBase):
|
||
|
def __init__(self, CP):
|
||
|
super().__init__(CP)
|
||
|
self.last_speed = 30
|
||
|
|
||
|
self.acm_lka_hba_cmd = None
|
||
|
self.sccm_wheel_touch = None
|
||
|
self.vdm_adas_status = None
|
||
|
|
||
|
def update(self, can_parsers) -> structs.CarState:
|
||
|
cp = can_parsers[Bus.pt]
|
||
|
cp_cam = can_parsers[Bus.cam]
|
||
|
cp_adas = can_parsers[Bus.adas]
|
||
|
ret = structs.CarState()
|
||
|
|
||
|
# Vehicle speed
|
||
|
ret.vEgoRaw = cp.vl["ESP_Status"]["ESP_Vehicle_Speed"] * CV.KPH_TO_MS
|
||
|
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
|
||
|
ret.standstill = abs(ret.vEgoRaw) < 0.01
|
||
|
|
||
|
# Gas pedal
|
||
|
pedal_status = cp.vl["VDM_PropStatus"]["VDM_AcceleratorPedalPosition"]
|
||
|
ret.gas = pedal_status / 100.0
|
||
|
ret.gasPressed = pedal_status > 0
|
||
|
|
||
|
# Brake pedal
|
||
|
ret.brake = cp.vl["ESPiB3"]["ESPiB3_pMC1"] / 250.0 # pressure in Bar
|
||
|
ret.brakePressed = cp.vl["iBESP2"]["iBESP2_BrakePedalApplied"] == 1
|
||
|
|
||
|
# Steering wheel
|
||
|
ret.steeringAngleDeg = cp.vl["EPAS_AdasStatus"]["EPAS_InternalSas"]
|
||
|
ret.steeringRateDeg = cp.vl["EPAS_AdasStatus"]["EPAS_SteeringAngleSpeed"]
|
||
|
ret.steeringTorque = cp.vl["EPAS_SystemStatus"]["EPAS_TorsionBarTorque"]
|
||
|
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > 1.0, 5)
|
||
|
|
||
|
ret.steerFaultTemporary = cp.vl["EPAS_AdasStatus"]["EPAS_EacErrorCode"] != 0
|
||
|
|
||
|
# Cruise state
|
||
|
speed = min(int(cp_adas.vl["ACM_tsrCmd"]["ACM_tsrSpdDisClsMain"]), 85)
|
||
|
self.last_speed = speed if speed != 0 else self.last_speed
|
||
|
ret.cruiseState.enabled = cp_cam.vl["ACM_Status"]["ACM_FeatureStatus"] == 1
|
||
|
# TODO: find cruise set speed on CAN
|
||
|
ret.cruiseState.speed = self.last_speed * CV.MPH_TO_MS # detected speed limit
|
||
|
if not self.CP.openpilotLongitudinalControl:
|
||
|
ret.cruiseState.speed = -1
|
||
|
ret.cruiseState.available = True # cp.vl["VDM_AdasSts"]["VDM_AdasInterfaceStatus"] == 1
|
||
|
ret.cruiseState.standstill = cp.vl["VDM_AdasSts"]["VDM_AdasAccelRequestAcknowledged"] == 1
|
||
|
|
||
|
# TODO: log ACM_Unkown2=3 as a fault. need to filter it at the start and end of routes though
|
||
|
# ACM_FaultStatus hasn't been seen yet
|
||
|
ret.accFaulted = (cp_cam.vl["ACM_Status"]["ACM_FaultStatus"] == 1 or
|
||
|
# VDM_AdasFaultStatus=Brk_Intv is the default for some reason
|
||
|
# VDM_AdasFaultStatus=Imps_Cmd was seen when sending it rapidly changing ACC enable commands
|
||
|
# VDM_AdasFaultStatus=Cntr_Fault isn't fully understood, but we've seen it in the wild
|
||
|
cp.vl["VDM_AdasSts"]["VDM_AdasFaultStatus"] in (3,)) # 3=Imps_Cmd
|
||
|
|
||
|
# Gear
|
||
|
ret.gearShifter = GEAR_MAP.get(int(cp.vl["VDM_PropStatus"]["VDM_Prndl_Status"]), GearShifter.unknown)
|
||
|
|
||
|
# Doors
|
||
|
ret.doorOpen = (cp_adas.vl["IndicatorLights"]["RearDriverDoor"] != 2 or
|
||
|
cp_adas.vl["IndicatorLights"]["FrontPassengerDoor"] != 2 or
|
||
|
cp_adas.vl["IndicatorLights"]["DriverDoor"] != 2 or
|
||
|
cp_adas.vl["IndicatorLights"]["RearPassengerDoor"] != 2)
|
||
|
|
||
|
# Blinkers
|
||
|
ret.leftBlinker = cp_adas.vl["IndicatorLights"]["TurnLightLeft"] in (1, 2)
|
||
|
ret.rightBlinker = cp_adas.vl["IndicatorLights"]["TurnLightRight"] in (1, 2)
|
||
|
|
||
|
# Seatbelt
|
||
|
ret.seatbeltUnlatched = cp.vl["RCM_Status"]["RCM_Status_IND_WARN_BELT_DRIVER"] != 0
|
||
|
|
||
|
# Blindspot
|
||
|
# ret.leftBlindspot = False
|
||
|
# ret.rightBlindspot = False
|
||
|
|
||
|
# AEB
|
||
|
ret.stockAeb = cp_cam.vl["ACM_AebRequest"]["ACM_EnableRequest"] != 0
|
||
|
|
||
|
# Messages needed by carcontroller
|
||
|
self.acm_lka_hba_cmd = copy.copy(cp_cam.vl["ACM_lkaHbaCmd"])
|
||
|
self.sccm_wheel_touch = copy.copy(cp.vl["SCCM_WheelTouch"])
|
||
|
self.vdm_adas_status = copy.copy(cp.vl["VDM_AdasSts"])
|
||
|
|
||
|
return ret
|
||
|
|
||
|
@staticmethod
|
||
|
def get_can_parsers(CP):
|
||
|
pt_messages = [
|
||
|
# sig_address, frequency
|
||
|
("ESP_Status", 50),
|
||
|
("VDM_PropStatus", 50),
|
||
|
("iBESP2", 50),
|
||
|
("ESPiB3", 50),
|
||
|
("EPAS_AdasStatus", 100),
|
||
|
("EPAS_SystemStatus", 100),
|
||
|
("RCM_Status", 8),
|
||
|
("VDM_AdasSts", 100),
|
||
|
("SCCM_WheelTouch", 20),
|
||
|
]
|
||
|
|
||
|
cam_messages = [
|
||
|
("ACM_longitudinalRequest", 100),
|
||
|
("ACM_AebRequest", 100),
|
||
|
("ACM_Status", 100),
|
||
|
("ACM_lkaHbaCmd", 100)
|
||
|
]
|
||
|
|
||
|
adas_messages = [
|
||
|
("IndicatorLights", 10),
|
||
|
("ACM_tsrCmd", 10),
|
||
|
]
|
||
|
|
||
|
return {
|
||
|
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, 0),
|
||
|
Bus.adas: CANParser(DBC[CP.carFingerprint][Bus.pt], adas_messages, 1),
|
||
|
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, 2),
|
||
|
}
|