|
|
|
from cereal import car
|
|
|
|
from selfdrive.config import Conversions as CV
|
|
|
|
from opendbc.can.can_define import CANDefine
|
|
|
|
from opendbc.can.parser import CANParser
|
|
|
|
from selfdrive.car.interfaces import CarStateBase
|
|
|
|
from selfdrive.car.mazda.values import DBC, LKAS_LIMITS, GEN1
|
|
|
|
|
|
|
|
class CarState(CarStateBase):
|
|
|
|
def __init__(self, CP):
|
|
|
|
super().__init__(CP)
|
|
|
|
|
|
|
|
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
|
|
|
|
self.shifter_values = can_define.dv["GEAR"]["GEAR"]
|
|
|
|
|
|
|
|
self.cruise_speed = 0
|
|
|
|
self.acc_active_last = False
|
|
|
|
self.low_speed_lockout = True
|
|
|
|
self.low_speed_alert = False
|
|
|
|
self.lkas_allowed = False
|
|
|
|
|
|
|
|
def update(self, cp, cp_cam):
|
|
|
|
|
|
|
|
ret = car.CarState.new_message()
|
|
|
|
ret.wheelSpeeds.fl = cp.vl["WHEEL_SPEEDS"]["FL"] * CV.KPH_TO_MS
|
|
|
|
ret.wheelSpeeds.fr = cp.vl["WHEEL_SPEEDS"]["FR"] * CV.KPH_TO_MS
|
|
|
|
ret.wheelSpeeds.rl = cp.vl["WHEEL_SPEEDS"]["RL"] * CV.KPH_TO_MS
|
|
|
|
ret.wheelSpeeds.rr = cp.vl["WHEEL_SPEEDS"]["RR"] * CV.KPH_TO_MS
|
|
|
|
ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4.
|
|
|
|
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
|
|
|
|
|
|
|
|
# Match panda speed reading
|
|
|
|
speed_kph = cp.vl["ENGINE_DATA"]["SPEED"]
|
|
|
|
ret.standstill = speed_kph < .1
|
|
|
|
|
|
|
|
can_gear = int(cp.vl["GEAR"]["GEAR"])
|
|
|
|
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None))
|
|
|
|
|
|
|
|
ret.leftBlinker = cp.vl["BLINK_INFO"]["LEFT_BLINK"] == 1
|
|
|
|
ret.rightBlinker = cp.vl["BLINK_INFO"]["RIGHT_BLINK"] == 1
|
|
|
|
|
|
|
|
ret.steeringAngleDeg = cp.vl["STEER"]["STEER_ANGLE"]
|
|
|
|
ret.steeringTorque = cp.vl["STEER_TORQUE"]["STEER_TORQUE_SENSOR"]
|
|
|
|
ret.steeringPressed = abs(ret.steeringTorque) > LKAS_LIMITS.STEER_THRESHOLD
|
|
|
|
|
|
|
|
ret.steeringTorqueEps = cp.vl["STEER_TORQUE"]["STEER_TORQUE_MOTOR"]
|
|
|
|
ret.steeringRateDeg = cp.vl["STEER_RATE"]["STEER_ANGLE_RATE"]
|
|
|
|
|
|
|
|
ret.brakePressed = cp.vl["PEDALS"]["BRAKE_ON"] == 1
|
|
|
|
ret.brake = cp.vl["BRAKE"]["BRAKE_PRESSURE"]
|
|
|
|
|
|
|
|
ret.seatbeltUnlatched = cp.vl["SEATBELT"]["DRIVER_SEATBELT"] == 0
|
|
|
|
ret.doorOpen = any([cp.vl["DOORS"]["FL"], cp.vl["DOORS"]["FR"],
|
|
|
|
cp.vl["DOORS"]["BL"], cp.vl["DOORS"]["BR"]])
|
|
|
|
|
|
|
|
ret.gas = cp.vl["ENGINE_DATA"]["PEDAL_GAS"]
|
|
|
|
ret.gasPressed = ret.gas > 0
|
|
|
|
|
|
|
|
ret.leftBlindspot = cp.vl["BSM"]["LEFT_BS1"] == 1
|
|
|
|
ret.rightBlindspot = cp.vl["BSM"]["RIGHT_BS1"] == 1
|
|
|
|
|
|
|
|
# LKAS is enabled at 52kph going up and disabled at 45kph going down
|
|
|
|
if speed_kph > LKAS_LIMITS.ENABLE_SPEED:
|
|
|
|
self.lkas_allowed = True
|
|
|
|
elif speed_kph < LKAS_LIMITS.DISABLE_SPEED:
|
|
|
|
self.lkas_allowed = False
|
|
|
|
|
|
|
|
ret.cruiseState.available = cp.vl["CRZ_CTRL"]["CRZ_AVAILABLE"] == 1
|
|
|
|
ret.cruiseState.enabled = cp.vl["CRZ_CTRL"]["CRZ_ACTIVE"] == 1
|
|
|
|
ret.cruiseState.speed = cp.vl["CRZ_EVENTS"]["CRZ_SPEED"] * CV.KPH_TO_MS
|
|
|
|
|
|
|
|
if ret.cruiseState.enabled:
|
|
|
|
if not self.lkas_allowed:
|
|
|
|
if not self.acc_active_last:
|
|
|
|
self.low_speed_lockout = True
|
|
|
|
else:
|
|
|
|
self.low_speed_alert = True
|
|
|
|
else:
|
|
|
|
self.low_speed_lockout = False
|
|
|
|
self.low_speed_alert = False
|
|
|
|
|
|
|
|
# Check if LKAS is disabled due to lack of driver torque
|
|
|
|
ret.steerWarning = (cp.vl["STEER_RATE"]["HANDS_OFF_5_SECONDS"] == 1) and (cp.vl["STEER_RATE"]["LKAS_BLOCK"] == 1)
|
|
|
|
|
|
|
|
self.acc_active_last = ret.cruiseState.enabled
|
|
|
|
|
|
|
|
self.cam_lkas = cp_cam.vl["CAM_LKAS"]
|
|
|
|
ret.steerError = cp_cam.vl["CAM_LKAS"]["ERR_BIT_1"] == 1
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_can_parser(CP):
|
|
|
|
# this function generates lists for signal, messages and initial values
|
|
|
|
signals = [
|
|
|
|
# sig_name, sig_address, default
|
|
|
|
("LEFT_BLINK", "BLINK_INFO", 0),
|
|
|
|
("RIGHT_BLINK", "BLINK_INFO", 0),
|
|
|
|
("STEER_ANGLE", "STEER", 0),
|
|
|
|
("STEER_ANGLE_RATE", "STEER_RATE", 0),
|
|
|
|
("STEER_TORQUE_SENSOR", "STEER_TORQUE", 0),
|
|
|
|
("STEER_TORQUE_MOTOR", "STEER_TORQUE", 0),
|
|
|
|
("FL", "WHEEL_SPEEDS", 0),
|
|
|
|
("FR", "WHEEL_SPEEDS", 0),
|
|
|
|
("RL", "WHEEL_SPEEDS", 0),
|
|
|
|
("RR", "WHEEL_SPEEDS", 0),
|
|
|
|
]
|
|
|
|
|
|
|
|
checks = [
|
|
|
|
# sig_address, frequency
|
|
|
|
("BLINK_INFO", 10),
|
|
|
|
("STEER", 67),
|
|
|
|
("STEER_RATE", 83),
|
|
|
|
("STEER_TORQUE", 83),
|
|
|
|
("WHEEL_SPEEDS", 100),
|
|
|
|
]
|
|
|
|
|
|
|
|
if CP.carFingerprint in GEN1:
|
|
|
|
signals += [
|
|
|
|
("LKAS_BLOCK", "STEER_RATE", 0),
|
|
|
|
("LKAS_TRACK_STATE", "STEER_RATE", 0),
|
|
|
|
("HANDS_OFF_5_SECONDS", "STEER_RATE", 0),
|
|
|
|
("CRZ_ACTIVE", "CRZ_CTRL", 0),
|
|
|
|
("CRZ_AVAILABLE", "CRZ_CTRL", 0),
|
|
|
|
("CRZ_SPEED", "CRZ_EVENTS", 0),
|
|
|
|
("STANDSTILL", "PEDALS", 0),
|
|
|
|
("BRAKE_ON", "PEDALS", 0),
|
|
|
|
("BRAKE_PRESSURE", "BRAKE", 0),
|
|
|
|
("GEAR", "GEAR", 0),
|
|
|
|
("DRIVER_SEATBELT", "SEATBELT", 0),
|
|
|
|
("FL", "DOORS", 0),
|
|
|
|
("FR", "DOORS", 0),
|
|
|
|
("BL", "DOORS", 0),
|
|
|
|
("BR", "DOORS", 0),
|
|
|
|
("PEDAL_GAS", "ENGINE_DATA", 0),
|
|
|
|
("SPEED", "ENGINE_DATA", 0),
|
|
|
|
("RES", "CRZ_BTNS", 0),
|
|
|
|
("SET_P", "CRZ_BTNS", 0),
|
|
|
|
("SET_M", "CRZ_BTNS", 0),
|
|
|
|
("CTR", "CRZ_BTNS", 0),
|
|
|
|
("LEFT_BS1", "BSM", 0),
|
|
|
|
("RIGHT_BS1", "BSM", 0),
|
|
|
|
]
|
|
|
|
|
|
|
|
checks += [
|
|
|
|
("ENGINE_DATA", 100),
|
|
|
|
("CRZ_CTRL", 50),
|
|
|
|
("CRZ_EVENTS", 50),
|
|
|
|
("CRZ_BTNS", 10),
|
|
|
|
("PEDALS", 50),
|
|
|
|
("BRAKE", 50),
|
|
|
|
("SEATBELT", 10),
|
|
|
|
("DOORS", 10),
|
|
|
|
("GEAR", 20),
|
|
|
|
("BSM", 10),
|
|
|
|
]
|
|
|
|
|
|
|
|
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 0)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_cam_can_parser(CP):
|
|
|
|
signals = []
|
|
|
|
checks = []
|
|
|
|
|
|
|
|
if CP.carFingerprint in GEN1:
|
|
|
|
signals += [
|
|
|
|
# sig_name, sig_address, default
|
|
|
|
("LKAS_REQUEST", "CAM_LKAS", 0),
|
|
|
|
("CTR", "CAM_LKAS", 0),
|
|
|
|
("ERR_BIT_1", "CAM_LKAS", 0),
|
|
|
|
("LINE_NOT_VISIBLE", "CAM_LKAS", 0),
|
|
|
|
("LDW", "CAM_LKAS", 0),
|
|
|
|
("BIT_1", "CAM_LKAS", 1),
|
|
|
|
("ERR_BIT_2", "CAM_LKAS", 0),
|
|
|
|
("STEERING_ANGLE", "CAM_LKAS", 0),
|
|
|
|
("ANGLE_ENABLED", "CAM_LKAS", 0),
|
|
|
|
("CHKSUM", "CAM_LKAS", 0),
|
|
|
|
]
|
|
|
|
|
|
|
|
checks += [
|
|
|
|
# sig_address, frequency
|
|
|
|
("CAM_LKAS", 16),
|
|
|
|
]
|
|
|
|
|
|
|
|
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2)
|