byd: add BYD car port (HAN EV 23 / Seal Performance 2025) with MADS support
Car port adapted from HotIce0/openpilot develop_byd_comma4 to sunnypilot's opendbc API (CP_SP signatures, (ret, ret_sp) carstate returns): - opendbc/car/byd/: interface, carstate, carcontroller, bydcan, values, fingerprints (BYD_SEAL_PERFORMANCE_25 with full 91-msg fingerprint) - opendbc/dbc/byd_common.dbc - Brand registration: car/values.py, car/fingerprints.py (+MIGRATION), car.capnp SafetyModel byd @35, torque_data/params.toml - safety/modes/byd.h: SAFETY_BYD 35U with real TX checks (steer torque cmd checks, longitudinal accel checks), MADS LKAS button from PCM_BUTTONS (944), pcm_cruise_check, ESC vehicle_moving. MISRA clean. - safety/tests/test_byd.py: 120 tests (stock + longitudinal variants) - opendbc/sunnypilot/car/byd/mads.py: MadsCarState tracking the dedicated LKAS steering wheel button - sunnypilot/mads/mads.py: allow_always for byd (dedicated LKAS button) - panda: restore SConstruct/SConscript build system, rebuild panda_h7.bin.signed (TIZI) with SAFETY_BYD + MADS lateral gating Known limitation: BYD_HAN_EV_23 fingerprint is a subset of the Seal's, so HAN requires FINGERPRINT=BYD_HAN_EV_23 env var (live fingerprint cannot distinguish it; Seal fingerprints natively).
This commit is contained in:
1 parent
de77c89cf6
commit
c8903e592c
44 files changed
+1479
-4
No files matched your search
@@ -57,6 +57,13 @@ opendbc/car/body/carstate.py
|
|||||||
opendbc/car/body/fingerprints.py
|
opendbc/car/body/fingerprints.py
|
||||||
opendbc/car/body/interface.py
|
opendbc/car/body/interface.py
|
||||||
opendbc/car/body/values.py
|
opendbc/car/body/values.py
|
||||||
|
opendbc/car/byd/__init__.py
|
||||||
|
opendbc/car/byd/bydcan.py
|
||||||
|
opendbc/car/byd/carcontroller.py
|
||||||
|
opendbc/car/byd/carstate.py
|
||||||
|
opendbc/car/byd/fingerprints.py
|
||||||
|
opendbc/car/byd/interface.py
|
||||||
|
opendbc/car/byd/values.py
|
||||||
opendbc/car/chrysler/__init__.py
|
opendbc/car/chrysler/__init__.py
|
||||||
opendbc/car/chrysler/carcontroller.py
|
opendbc/car/chrysler/carcontroller.py
|
||||||
opendbc/car/chrysler/carstate.py
|
opendbc/car/chrysler/carstate.py
|
||||||
@@ -214,6 +221,7 @@ opendbc/dbc/FORD_CADS_64.dbc
|
|||||||
opendbc/dbc/__init__.py
|
opendbc/dbc/__init__.py
|
||||||
opendbc/dbc/acura_ilx_2016_nidec.dbc
|
opendbc/dbc/acura_ilx_2016_nidec.dbc
|
||||||
opendbc/dbc/bmw_e9x_e8x.dbc
|
opendbc/dbc/bmw_e9x_e8x.dbc
|
||||||
|
opendbc/dbc/byd_common.dbc
|
||||||
opendbc/dbc/cadillac_ct6_chassis.dbc
|
opendbc/dbc/cadillac_ct6_chassis.dbc
|
||||||
opendbc/dbc/cadillac_ct6_object.dbc
|
opendbc/dbc/cadillac_ct6_object.dbc
|
||||||
opendbc/dbc/cadillac_ct6_powertrain.dbc
|
opendbc/dbc/cadillac_ct6_powertrain.dbc
|
||||||
@@ -345,6 +353,7 @@ opendbc/safety/lateral.h
|
|||||||
opendbc/safety/longitudinal.h
|
opendbc/safety/longitudinal.h
|
||||||
opendbc/safety/safety.h
|
opendbc/safety/safety.h
|
||||||
opendbc/safety/modes/body.h
|
opendbc/safety/modes/body.h
|
||||||
|
opendbc/safety/modes/byd.h
|
||||||
opendbc/safety/modes/chrysler.h
|
opendbc/safety/modes/chrysler.h
|
||||||
opendbc/safety/modes/chrysler_common.h
|
opendbc/safety/modes/chrysler_common.h
|
||||||
opendbc/safety/modes/chrysler_cusw.h
|
opendbc/safety/modes/chrysler_cusw.h
|
||||||
@@ -416,6 +425,8 @@ opendbc/sunnypilot/car/intelligent_cruise_button_management_interface_base.py
|
|||||||
opendbc/sunnypilot/car/interfaces.py
|
opendbc/sunnypilot/car/interfaces.py
|
||||||
opendbc/sunnypilot/car/lateral_ext.py
|
opendbc/sunnypilot/car/lateral_ext.py
|
||||||
opendbc/sunnypilot/car/platform_list.py
|
opendbc/sunnypilot/car/platform_list.py
|
||||||
|
opendbc/sunnypilot/car/byd/__init__.py
|
||||||
|
opendbc/sunnypilot/car/byd/mads.py
|
||||||
opendbc/sunnypilot/car/chrysler/__init__.py
|
opendbc/sunnypilot/car/chrysler/__init__.py
|
||||||
opendbc/sunnypilot/car/chrysler/carcontroller_ext.py
|
opendbc/sunnypilot/car/chrysler/carcontroller_ext.py
|
||||||
opendbc/sunnypilot/car/chrysler/carstate_ext.py
|
opendbc/sunnypilot/car/chrysler/carstate_ext.py
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# byd
|
||||||
Whitespace-only changes.
@@ -0,0 +1,161 @@
|
|||||||
|
from opendbc.car.byd.values import CANBUS
|
||||||
|
|
||||||
|
|
||||||
|
def byd_checksum(data: bytearray) -> int:
|
||||||
|
byte_key = 0xAF
|
||||||
|
sum_first = sum(byte >> 4 for byte in data) # Extract upper nibble.
|
||||||
|
sum_second = sum(byte & 0xF for byte in data) # Extract lower nibble.
|
||||||
|
|
||||||
|
remainder = sum_second >> 4
|
||||||
|
|
||||||
|
sum_first += (byte_key & 0xF) # Low nibble of byte_key.
|
||||||
|
sum_second += (byte_key >> 4) # High nibble of byte_key.
|
||||||
|
|
||||||
|
# Inline inverse computation for each sum:
|
||||||
|
# inv = (-sum + 0x9) & 0xF
|
||||||
|
inv_first = ((-sum_first + 0x9) & 0xF)
|
||||||
|
inv_second = ((-sum_second + 0x9) & 0xF)
|
||||||
|
|
||||||
|
return (((inv_first + (5 - remainder)) << 4) + inv_second) & 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
def byd_checksum_short(data: bytearray) -> int:
|
||||||
|
# checksum for CHECKSUM_S 4byte
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BydCAN:
|
||||||
|
LKAS_MODE_ACTIVE2 = 3
|
||||||
|
LKAS_MODE_PASSIVE = 1
|
||||||
|
|
||||||
|
def __init__(self, packer):
|
||||||
|
self.packer = packer
|
||||||
|
self.mpc_lkas_counter = 0
|
||||||
|
self.eps_steering_torque_counter = 0
|
||||||
|
self.mpc_acc_cmd_counter = 0
|
||||||
|
|
||||||
|
def update_mpc_lkas_counter(self, val):
|
||||||
|
self.mpc_lkas_counter = val
|
||||||
|
|
||||||
|
def _generate_mpc_lkas_new_counter(self):
|
||||||
|
counter = self.mpc_lkas_counter
|
||||||
|
self.mpc_lkas_counter = int(self.mpc_lkas_counter + 1) & 0xF
|
||||||
|
return counter
|
||||||
|
|
||||||
|
def update_eps_steering_torque_counter(self, val):
|
||||||
|
self.eps_steering_torque_counter = val
|
||||||
|
|
||||||
|
def _generate_eps_steering_torque_new_counter(self):
|
||||||
|
counter = self.eps_steering_torque_counter
|
||||||
|
self.eps_steering_torque_counter = int(
|
||||||
|
self.eps_steering_torque_counter + 1) & 0xF
|
||||||
|
return counter
|
||||||
|
|
||||||
|
def update_acc_cmd_counter(self, val):
|
||||||
|
self.mpc_acc_cmd_counter = val
|
||||||
|
|
||||||
|
def _generate_acc_cmd_new_counter(self):
|
||||||
|
counter = self.mpc_acc_cmd_counter
|
||||||
|
self.mpc_acc_cmd_counter = int(self.mpc_acc_cmd_counter + 1) & 0xF
|
||||||
|
return counter
|
||||||
|
|
||||||
|
# MPC -> Panda -> EPS
|
||||||
|
def create_steering_control_torque(self, mpc_lkas_cmd_msg, torque,
|
||||||
|
request_prepare, active, mode,
|
||||||
|
eps_active):
|
||||||
|
lkas_output = torque if active and eps_active else 0
|
||||||
|
lkas_prepare = request_prepare
|
||||||
|
lkas_active = active
|
||||||
|
lkas_mode = mode
|
||||||
|
left_lane = mpc_lkas_cmd_msg["LeftLane"]
|
||||||
|
right_lane = mpc_lkas_cmd_msg["RightLane"]
|
||||||
|
if active or request_prepare:
|
||||||
|
left_lane = 1
|
||||||
|
right_lane = 1
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"SETME_0x1": mpc_lkas_cmd_msg["SETME_0x1"],
|
||||||
|
"LeftLane": left_lane,
|
||||||
|
"Config": mpc_lkas_cmd_msg["Config"],
|
||||||
|
"SETME2_0x1": mpc_lkas_cmd_msg["SETME2_0x1"],
|
||||||
|
"Keep_Hands_On_Wheel": 0,
|
||||||
|
"MPCErr": mpc_lkas_cmd_msg["MPCErr"],
|
||||||
|
"SETME3_0x1": mpc_lkas_cmd_msg["SETME3_0x1"],
|
||||||
|
"LKAS_Output": lkas_output,
|
||||||
|
"LKASPrepare": lkas_prepare,
|
||||||
|
"LKAS_ACTIVE": lkas_active,
|
||||||
|
"TSRStatus": mpc_lkas_cmd_msg["TSRStatus"],
|
||||||
|
"SETME4_0x1": mpc_lkas_cmd_msg["SETME4_0x1"],
|
||||||
|
"RightLane": right_lane,
|
||||||
|
"LKAS_Mode": lkas_mode,
|
||||||
|
"SETME_0x0": mpc_lkas_cmd_msg["SETME_0x0"],
|
||||||
|
"TSRResult": mpc_lkas_cmd_msg["TSRResult"],
|
||||||
|
"Unknow1": mpc_lkas_cmd_msg["Unknow1"],
|
||||||
|
"COUNTER": self._generate_mpc_lkas_new_counter(),
|
||||||
|
}
|
||||||
|
data = self.packer.make_can_msg("MPC_LKAS_CMD", CANBUS.main_bus, values)[1]
|
||||||
|
values["CHECKSUM"] = byd_checksum(data)
|
||||||
|
return self.packer.make_can_msg("MPC_LKAS_CMD", CANBUS.main_bus, values)
|
||||||
|
|
||||||
|
def create_steering_torque(self, eps_steering_torque_msg, mpc_lkas_output,
|
||||||
|
mpc_lkas_request_prepare, mpc_lkas_active):
|
||||||
|
lks_prepared = eps_steering_torque_msg["LKSPrepare"]
|
||||||
|
cruise_activated = eps_steering_torque_msg["Cruise_Activated"]
|
||||||
|
main_torque = eps_steering_torque_msg["MAIN_TORQUE"]
|
||||||
|
|
||||||
|
if mpc_lkas_active:
|
||||||
|
lks_prepared = 0
|
||||||
|
cruise_activated = 1
|
||||||
|
main_torque = mpc_lkas_output
|
||||||
|
elif mpc_lkas_request_prepare:
|
||||||
|
lks_prepared = 1
|
||||||
|
cruise_activated = 0
|
||||||
|
main_torque = 0
|
||||||
|
else:
|
||||||
|
lks_prepared = 0
|
||||||
|
cruise_activated = 0
|
||||||
|
main_torque = 0
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"LKSPrepare": lks_prepared,
|
||||||
|
"Cruise_Activated": cruise_activated,
|
||||||
|
"TORQUE_FAILED": eps_steering_torque_msg["TORQUE_FAILED"],
|
||||||
|
"SET_ME_1_1": eps_steering_torque_msg["SET_ME_1_1"],
|
||||||
|
"Steer_Warning": eps_steering_torque_msg["Steer_Warning"],
|
||||||
|
"Steer_Error_1": eps_steering_torque_msg["Steer_Error_1"],
|
||||||
|
"Steer_Error_2": eps_steering_torque_msg["Steer_Error_2"],
|
||||||
|
"SET_ME_1": eps_steering_torque_msg["SET_ME_1"],
|
||||||
|
"MAIN_TORQUE": main_torque,
|
||||||
|
"SET_ME_1_2": eps_steering_torque_msg["SET_ME_1_2"],
|
||||||
|
"Keep_Hands_On_Wheel": 0,
|
||||||
|
"SET_ME_3": eps_steering_torque_msg["SET_ME_3"],
|
||||||
|
"Steer_Torque_Sensor": eps_steering_torque_msg["Steer_Torque_Sensor"],
|
||||||
|
"SET_ME_XF_1": eps_steering_torque_msg["SET_ME_XF_1"],
|
||||||
|
"SET_ME_XFFF": eps_steering_torque_msg["SET_ME_XFFF"],
|
||||||
|
"COUNTER": self._generate_eps_steering_torque_new_counter(),
|
||||||
|
}
|
||||||
|
data = self.packer.make_can_msg("STEERING_TORQUE", CANBUS.cam_bus, values)[1]
|
||||||
|
values["CHECKSUM"] = byd_checksum(data)
|
||||||
|
return self.packer.make_can_msg("STEERING_TORQUE", CANBUS.cam_bus, values)
|
||||||
|
|
||||||
|
def create_acc_cmd(self, acc_cmd_msg, accel):
|
||||||
|
values = {
|
||||||
|
"ACCEL_CMD": accel,
|
||||||
|
"ComfortBandUpper": acc_cmd_msg["ComfortBandUpper"],
|
||||||
|
"ComfortBandLower": acc_cmd_msg["ComfortBandLower"],
|
||||||
|
"JerkUpperLimit": 1,
|
||||||
|
"SET_ME_1": acc_cmd_msg["SET_ME_1"],
|
||||||
|
"JerkLowerLimit": -1,
|
||||||
|
"STANDSTILL_RESUME": 0,
|
||||||
|
"STANDSTILL_STATE": 0,
|
||||||
|
"BRAKE_BEHAVIOR": acc_cmd_msg["BRAKE_BEHAVIOR"],
|
||||||
|
"ACC_REQ_NOT_STANDSTILL": acc_cmd_msg["ACC_REQ_NOT_STANDSTILL"],
|
||||||
|
"ACC_CONTROLLABLE_AND_ON": acc_cmd_msg["ACC_CONTROLLABLE_AND_ON"],
|
||||||
|
"ACC_OVERRIDE_OR_STANDSTILL": acc_cmd_msg["ACC_OVERRIDE_OR_STANDSTILL"],
|
||||||
|
"ESP_BEHAVIOR": acc_cmd_msg["ESP_BEHAVIOR"],
|
||||||
|
"COUNTER": self._generate_acc_cmd_new_counter(),
|
||||||
|
"SET_ME_XF": acc_cmd_msg["SET_ME_XF"],
|
||||||
|
}
|
||||||
|
data = self.packer.make_can_msg("ACC_CMD", CANBUS.main_bus, values)[1]
|
||||||
|
values["CHECKSUM"] = byd_checksum(data)
|
||||||
|
return self.packer.make_can_msg("ACC_CMD", CANBUS.main_bus, values)
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import numpy as np
|
||||||
|
from opendbc.can.packer import CANPacker
|
||||||
|
from opendbc.car import Bus, structs
|
||||||
|
from opendbc.car.lateral import apply_meas_steer_torque_limits
|
||||||
|
from opendbc.car.interfaces import CarControllerBase
|
||||||
|
from opendbc.car.byd.bydcan import BydCAN
|
||||||
|
from opendbc.car.byd.values import CarControllerParams
|
||||||
|
|
||||||
|
VisualAlert = structs.CarControl.HUDControl.VisualAlert
|
||||||
|
ButtonType = structs.CarState.ButtonEvent.Type
|
||||||
|
LongCtrlState = structs.CarControl.Actuators.LongControlState
|
||||||
|
|
||||||
|
|
||||||
|
class LKASState:
|
||||||
|
INACTIVE = 0
|
||||||
|
PREPARING = 1
|
||||||
|
ACTIVE = 2
|
||||||
|
|
||||||
|
|
||||||
|
class CarController(CarControllerBase):
|
||||||
|
def __init__(self, dbc_names, CP, CP_SP):
|
||||||
|
super().__init__(dbc_names, CP, CP_SP)
|
||||||
|
self.params = CarControllerParams(CP)
|
||||||
|
self.packer = CANPacker(dbc_names[Bus.pt])
|
||||||
|
self.can = BydCAN(self.packer)
|
||||||
|
self.apply_torque_last = 0
|
||||||
|
|
||||||
|
self.lkas_state = LKASState.INACTIVE
|
||||||
|
self.lkas_counter_updated = False
|
||||||
|
|
||||||
|
self.apply_accel_last = 0
|
||||||
|
|
||||||
|
def update(self, CC, CC_SP, CS, now_nanos):
|
||||||
|
# car control running in 100Hz
|
||||||
|
actuators = CC.actuators
|
||||||
|
can_sends = []
|
||||||
|
|
||||||
|
if (self.frame % self.params.STEER_STEP) == 0:
|
||||||
|
# steering control running in 50Hz
|
||||||
|
if not self.lkas_counter_updated:
|
||||||
|
self.lkas_counter_updated = True
|
||||||
|
self.can.update_mpc_lkas_counter(
|
||||||
|
int(CS.mpc_lkas_cmd_msg["COUNTER"] + 1) & 0xF)
|
||||||
|
self.can.update_eps_steering_torque_counter(
|
||||||
|
int(CS.eps_steering_torque_msg["COUNTER"] + 1) & 0xF)
|
||||||
|
self.can.update_acc_cmd_counter(
|
||||||
|
int(CS.acc_cmd_msg["COUNTER"] + 1) & 0xF)
|
||||||
|
|
||||||
|
# update lkas state
|
||||||
|
if self.lkas_state == LKASState.INACTIVE:
|
||||||
|
if CC.latActive:
|
||||||
|
self.lkas_state = LKASState.PREPARING
|
||||||
|
elif self.lkas_state == LKASState.PREPARING:
|
||||||
|
if CS.eps_prepared:
|
||||||
|
self.lkas_state = LKASState.ACTIVE
|
||||||
|
elif self.lkas_state == LKASState.ACTIVE:
|
||||||
|
if not CC.latActive:
|
||||||
|
self.lkas_state = LKASState.INACTIVE
|
||||||
|
|
||||||
|
lkas_request_prepare = int(self.lkas_state == LKASState.PREPARING)
|
||||||
|
lkas_active = int(self.lkas_state == LKASState.ACTIVE)
|
||||||
|
if self.lkas_state in (LKASState.PREPARING, LKASState.ACTIVE):
|
||||||
|
lkas_mode = BydCAN.LKAS_MODE_ACTIVE2
|
||||||
|
else:
|
||||||
|
lkas_mode = BydCAN.LKAS_MODE_PASSIVE
|
||||||
|
|
||||||
|
# calc apply torque
|
||||||
|
apply_torque = 0
|
||||||
|
if self.lkas_state == LKASState.ACTIVE:
|
||||||
|
apply_torque = int(round(actuators.torque * self.params.STEER_MAX))
|
||||||
|
apply_torque = apply_meas_steer_torque_limits(apply_torque, self.apply_torque_last,
|
||||||
|
CS.out.steeringTorqueEps, self.params)
|
||||||
|
|
||||||
|
pack = self.can.create_steering_control_torque(CS.mpc_lkas_cmd_msg, apply_torque,
|
||||||
|
lkas_request_prepare, lkas_active,
|
||||||
|
lkas_mode, CS.eps_activated)
|
||||||
|
can_sends.append(pack)
|
||||||
|
pack = self.can.create_steering_torque(CS.eps_steering_torque_msg,
|
||||||
|
CS.mpc_lkas_output,
|
||||||
|
CS.mpc_lkas_request_prepare,
|
||||||
|
CS.mpc_lkas_active)
|
||||||
|
can_sends.append(pack)
|
||||||
|
|
||||||
|
self.apply_torque_last = apply_torque
|
||||||
|
|
||||||
|
# Longitudinal control
|
||||||
|
if self.CP.openpilotLongitudinalControl:
|
||||||
|
if (self.frame % self.params.ACC_SETP) == 0:
|
||||||
|
accel = 0
|
||||||
|
|
||||||
|
if CC.longActive:
|
||||||
|
accel = float(np.clip(actuators.accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX))
|
||||||
|
|
||||||
|
pack = self.can.create_acc_cmd(CS.acc_cmd_msg, accel)
|
||||||
|
can_sends.append(pack)
|
||||||
|
self.apply_accel_last = accel
|
||||||
|
|
||||||
|
new_actuators = actuators.as_builder()
|
||||||
|
new_actuators.torque = self.apply_torque_last / self.params.STEER_MAX
|
||||||
|
new_actuators.torqueOutputCan = self.apply_torque_last
|
||||||
|
new_actuators.accel = self.apply_accel_last
|
||||||
|
|
||||||
|
self.frame += 1
|
||||||
|
return new_actuators, can_sends
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
import copy
|
||||||
|
from opendbc.car import Bus, create_button_events, structs
|
||||||
|
from opendbc.can.parser import CANParser
|
||||||
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
|
from opendbc.car.interfaces import CarStateBase
|
||||||
|
from opendbc.car.byd.values import DBC, CANBUS, STEER_THRESHOLD, GEAR_MAP
|
||||||
|
from opendbc.sunnypilot.car.byd.mads import MadsCarState
|
||||||
|
|
||||||
|
GearShifter = structs.CarState.GearShifter
|
||||||
|
ButtonType = structs.CarState.ButtonEvent.Type
|
||||||
|
|
||||||
|
|
||||||
|
class CarState(CarStateBase, MadsCarState):
|
||||||
|
def __init__(self, CP, CP_SP):
|
||||||
|
CarStateBase.__init__(self, CP, CP_SP)
|
||||||
|
MadsCarState.__init__(self, CP, CP_SP)
|
||||||
|
|
||||||
|
self.mpc_lkas_cmd_msg = None
|
||||||
|
self.eps_steering_torque_msg = None
|
||||||
|
self.eps_prepared = False
|
||||||
|
self.eps_activated = False
|
||||||
|
self.acc_cmd_msg = None
|
||||||
|
|
||||||
|
self.mpc_lkas_output = 0
|
||||||
|
self.mpc_lkas_active = False
|
||||||
|
self.mpc_lkas_request_prepare = False
|
||||||
|
|
||||||
|
def update(self, can_parsers) -> tuple[structs.CarState, structs.CarStateSP]:
|
||||||
|
cp = can_parsers[Bus.pt]
|
||||||
|
cp_cam = can_parsers[Bus.cam]
|
||||||
|
ret = structs.CarState()
|
||||||
|
ret_sp = structs.CarStateSP()
|
||||||
|
|
||||||
|
# car Speed
|
||||||
|
ret.vEgoRaw = cp.vl["ESC"]["VEHICLE_SPEED"] * CV.KPH_TO_MS
|
||||||
|
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
|
||||||
|
ret.standstill = cp.vl["BRAKE_APPLIED"]["STANDSTILL"] == 1
|
||||||
|
|
||||||
|
# Gas pedal
|
||||||
|
ret.gasPressed = cp.vl["PEDAL"]["GAS_PEDAL"] > 0
|
||||||
|
|
||||||
|
# Brake pedal
|
||||||
|
ret.brakePressed = cp.vl["PEDAL"]["BRAKE_PEDAL"] > 0
|
||||||
|
|
||||||
|
# Steering wheel
|
||||||
|
ret.steeringAngleDeg = cp.vl["STEER_MODULE"]["STEER_ANGLE"]
|
||||||
|
ret.steeringRateDeg = cp.vl["STEER_MODULE"]["STEERING_RATE"]
|
||||||
|
ret.steeringTorque = cp.vl["STEERING_TORQUE"]["Steer_Torque_Sensor"]
|
||||||
|
ret.steeringTorqueEps = cp.vl["STEERING_TORQUE"]["MAIN_TORQUE"]
|
||||||
|
# TODO: looks like STEER_THRESHOLD is too small
|
||||||
|
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > STEER_THRESHOLD, 5)
|
||||||
|
ret.steerFaultPermanent = cp.vl["STEERING_TORQUE"]["TORQUE_FAILED"] != 0
|
||||||
|
ret.steerFaultTemporary = cp.vl["STEERING_TORQUE"]["TORQUE_FAILED"] != 0
|
||||||
|
|
||||||
|
ret.stockAeb = cp_cam.vl["ACC_HUD_ADAS"]["AEB"] == 1
|
||||||
|
ret.stockFcw = cp_cam.vl["ACC_HUD_ADAS"]["FCW"] == 1 # Forward Collision Warning
|
||||||
|
|
||||||
|
# Cruise state
|
||||||
|
ret.cruiseState.enabled = cp_cam.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] in (3, 5) # (Active, Override)
|
||||||
|
ret.cruiseState.speed = cp_cam.vl["ACC_HUD_ADAS"]["SET_SPEED"] * 10 * CV.KPH_TO_MS
|
||||||
|
ret.cruiseState.available = cp_cam.vl["ACC_HUD_ADAS"]["CRUISE_STATE"] not in (8, 9) # (Failure, PermanentFailure)
|
||||||
|
ret.cruiseState.standstill = False # This needs to be false, since we can resume from stop without sending anything special
|
||||||
|
|
||||||
|
# Gear
|
||||||
|
ret.gearShifter = GEAR_MAP.get(int(cp.vl["DRIVE_STATE"]["GEAR"]), GearShifter.unknown)
|
||||||
|
|
||||||
|
# MADS: track the dedicated LKAS steering wheel button
|
||||||
|
MadsCarState.update_mads(self, ret, can_parsers)
|
||||||
|
|
||||||
|
# button presses
|
||||||
|
ret.leftBlinker = cp.vl["STALKS"]["TURN_SIGNAL_SWITCH"] == 3 # LeftSteeringLongLift
|
||||||
|
ret.rightBlinker = cp.vl["STALKS"]["TURN_SIGNAL_SWITCH"] == 5 # RightSteeringLongLift
|
||||||
|
|
||||||
|
ret.buttonEvents = [*create_button_events(self.lkas_button, self.prev_lkas_button, {1: ButtonType.lkas})]
|
||||||
|
|
||||||
|
# lock info
|
||||||
|
ret.doorOpen = any([cp.vl["METER_CLUSTER"]["FRONT_LEFT_DOOR"],
|
||||||
|
cp.vl["METER_CLUSTER"]["FRONT_RIGHT_DOOR"],
|
||||||
|
cp.vl["METER_CLUSTER"]["BACK_LEFT_DOOR"],
|
||||||
|
cp.vl["METER_CLUSTER"]["BACK_RIGHT_DOOR"]])
|
||||||
|
ret.seatbeltUnlatched = cp.vl["METER_CLUSTER"]["SEATBELT_DRIVER"] != 1
|
||||||
|
|
||||||
|
# blindspot sensors
|
||||||
|
# ret.leftBlindspot = False
|
||||||
|
# ret.rightBlindspot = False
|
||||||
|
|
||||||
|
# Messages needed by carcontroller
|
||||||
|
# for generate MPC_LKAS_CMD
|
||||||
|
self.mpc_lkas_cmd_msg = copy.copy(cp_cam.vl["MPC_LKAS_CMD"])
|
||||||
|
self.eps_prepared = cp.vl["STEERING_TORQUE"]["LKSPrepare"] != 0
|
||||||
|
self.eps_activated = cp.vl["STEERING_TORQUE"]["Cruise_Activated"] != 0
|
||||||
|
# for generate STEERING_TORQUE
|
||||||
|
self.eps_steering_torque_msg = copy.copy(cp.vl["STEERING_TORQUE"])
|
||||||
|
self.mpc_lkas_output = cp_cam.vl["MPC_LKAS_CMD"]["LKAS_Output"]
|
||||||
|
self.mpc_lkas_active = cp_cam.vl["MPC_LKAS_CMD"]["LKAS_ACTIVE"] != 0
|
||||||
|
self.mpc_lkas_request_prepare = cp_cam.vl["MPC_LKAS_CMD"]["LKASPrepare"] != 0
|
||||||
|
# for generate ACC_CMD
|
||||||
|
self.acc_cmd_msg = copy.copy(cp_cam.vl["ACC_CMD"])
|
||||||
|
return ret, ret_sp
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_can_parsers(CP, CP_SP):
|
||||||
|
pt_messages = [
|
||||||
|
# sig_address, frequency
|
||||||
|
("ESC", 50),
|
||||||
|
("BRAKE_APPLIED", 50),
|
||||||
|
("PEDAL", 50),
|
||||||
|
("STEER_MODULE", 100),
|
||||||
|
("STEERING_TORQUE", 50),
|
||||||
|
("DRIVE_STATE", 50),
|
||||||
|
("STALKS", 20),
|
||||||
|
("METER_CLUSTER", 20),
|
||||||
|
("PCM_BUTTONS", 20),
|
||||||
|
]
|
||||||
|
|
||||||
|
cam_messages = [
|
||||||
|
("ACC_HUD_ADAS", 50),
|
||||||
|
("MPC_LKAS_CMD", 50),
|
||||||
|
("ACC_CMD", 25),
|
||||||
|
]
|
||||||
|
|
||||||
|
return {
|
||||||
|
Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], pt_messages, CANBUS.main_bus),
|
||||||
|
Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], cam_messages, CANBUS.cam_bus),
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
from opendbc.car.structs import CarParams
|
||||||
|
from opendbc.car.byd.values import CAR
|
||||||
|
|
||||||
|
Ecu = CarParams.Ecu
|
||||||
|
|
||||||
|
FINGERPRINTS = {
|
||||||
|
# NOTE: the HAN EV 23 fingerprint is a minimal subset of the SEAL fingerprint,
|
||||||
|
# so a HAN cannot be uniquely identified by live CAN fingerprinting.
|
||||||
|
# Set FINGERPRINT=BYD_HAN_EV_23 (and SKIP_FW_QUERY) to force it.
|
||||||
|
CAR.BYD_HAN_EV_23: [{
|
||||||
|
140: 8, 213: 8, 287: 5, 289: 8, 291: 8, 301: 8, 307: 8, 337: 8, 496: 8, 536: 8, 544: 8, 546: 8, 547: 8, 575: 8, 576: 8
|
||||||
|
}],
|
||||||
|
CAR.BYD_SEAL_PERFORMANCE_25: [{
|
||||||
|
140: 8, 213: 8, 287: 5, 289: 8, 291: 8, 301: 8, 307: 8, 311: 8, 312: 8, 337: 8, 359: 8, 482: 8, 493: 8, 496: 8, 508: 8,
|
||||||
|
511: 8, 536: 8, 544: 8, 546: 8, 547: 8, 567: 8, 575: 8, 576: 8, 578: 8, 588: 8, 604: 8, 612: 8, 626: 8, 657: 8, 660: 8,
|
||||||
|
661: 8, 663: 8, 668: 8, 692: 8, 694: 8, 714: 8, 724: 8, 748: 8, 758: 8, 790: 8, 797: 8, 798: 8, 801: 8, 802: 8, 803: 8,
|
||||||
|
813: 8, 814: 8, 815: 8, 833: 8, 834: 8, 836: 8, 837: 8, 854: 8, 860: 8, 868: 8, 877: 8, 904: 8, 906: 8, 944: 8, 948: 8,
|
||||||
|
951: 8, 965: 8, 973: 8, 985: 8, 1023: 8, 1028: 8, 1031: 8, 1033: 8, 1040: 8, 1048: 8, 1058: 8, 1074: 8, 1092: 8, 1093: 8,
|
||||||
|
1107: 8, 1108: 8, 1141: 8, 1166: 8, 1168: 8, 1178: 8, 1189: 8, 1193: 8, 1203: 64, 1204: 64, 1226: 16, 1246: 8, 1297: 8,
|
||||||
|
1319: 8, 1322: 8, 1365: 8, 1366: 8
|
||||||
|
}],
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
from opendbc.car import get_safety_config, structs
|
||||||
|
from opendbc.car.common.conversions import Conversions as CV
|
||||||
|
from opendbc.car.interfaces import CarInterfaceBase
|
||||||
|
from opendbc.car.byd.carcontroller import CarController
|
||||||
|
from opendbc.car.byd.carstate import CarState
|
||||||
|
from opendbc.car.byd.values import CAR, BydFlags, BydSafetyFlags
|
||||||
|
|
||||||
|
|
||||||
|
class CarInterface(CarInterfaceBase):
|
||||||
|
CarState = CarState
|
||||||
|
CarController = CarController
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, alpha_long, is_release, docs) -> structs.CarParams:
|
||||||
|
ret.brand = "byd"
|
||||||
|
ret.dashcamOnly = False
|
||||||
|
|
||||||
|
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.byd)]
|
||||||
|
|
||||||
|
# lateral control parameters
|
||||||
|
ret.steerActuatorDelay = 0.3
|
||||||
|
ret.steerLimitTimer = 0.5
|
||||||
|
|
||||||
|
if candidate in (CAR.BYD_HAN_EV_23, CAR.BYD_SEAL_PERFORMANCE_25):
|
||||||
|
ret.steerControlType = structs.CarParams.SteerControlType.torque
|
||||||
|
|
||||||
|
ret.minEnableSpeed = -1.
|
||||||
|
ret.minSteerSpeed = 0.1 * CV.KPH_TO_MS
|
||||||
|
ret.steerLimitTimer = 0.5
|
||||||
|
|
||||||
|
if ret.steerControlType == structs.CarParams.SteerControlType.torque:
|
||||||
|
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||||
|
|
||||||
|
# longitudinal control parameters
|
||||||
|
ret.alphaLongitudinalAvailable = True
|
||||||
|
if alpha_long:
|
||||||
|
ret.openpilotLongitudinalControl = True
|
||||||
|
ret.startingState = True
|
||||||
|
ret.startAccel = 0.1
|
||||||
|
ret.flags |= BydFlags.LONG_CONTROL.value
|
||||||
|
ret.safetyConfigs[0].safetyParam |= BydSafetyFlags.LONG_CONTROL.value
|
||||||
|
ret.vEgoStopping = 0.1
|
||||||
|
ret.vEgoStarting = 0.1
|
||||||
|
ret.stoppingDecelRate = 0.3
|
||||||
|
|
||||||
|
# TODO: add radar support
|
||||||
|
ret.radarUnavailable = True
|
||||||
|
|
||||||
|
return ret
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
from dataclasses import dataclass, field
|
||||||
|
from enum import IntFlag
|
||||||
|
from opendbc.car import Bus, DbcDict, PlatformConfig, Platforms, CarSpecs, STD_CARGO_KG
|
||||||
|
from opendbc.car.structs import CarParams, CarState
|
||||||
|
from opendbc.car.docs_definitions import CarHarness, CarDocs, CarParts
|
||||||
|
|
||||||
|
Ecu = CarParams.Ecu
|
||||||
|
|
||||||
|
|
||||||
|
class CANBUS:
|
||||||
|
main_bus = 0
|
||||||
|
radar_bus = 1
|
||||||
|
cam_bus = 2
|
||||||
|
|
||||||
|
|
||||||
|
class BydSafetyFlags(IntFlag):
|
||||||
|
LONG_CONTROL = 1
|
||||||
|
|
||||||
|
|
||||||
|
class BydFlags(IntFlag):
|
||||||
|
LONG_CONTROL = 1
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class BydCarDocs(CarDocs):
|
||||||
|
package: str = "All"
|
||||||
|
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.custom]))
|
||||||
|
#todo add docs and harness info
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class BydPlatformConfig(PlatformConfig):
|
||||||
|
dbc_dict: DbcDict = field(default_factory=lambda: {Bus.pt: "byd_common"})
|
||||||
|
|
||||||
|
|
||||||
|
class CAR(Platforms):
|
||||||
|
BYD_HAN_EV_23 = BydPlatformConfig(
|
||||||
|
[BydCarDocs("BYD HAN EV 2023")],
|
||||||
|
CarSpecs(mass=1940 + STD_CARGO_KG, wheelbase=2.92, steerRatio=16.5,
|
||||||
|
centerToFrontRatio=0.44, tireStiffnessFactor=1.0)
|
||||||
|
)
|
||||||
|
BYD_SEAL_PERFORMANCE_25 = BydPlatformConfig(
|
||||||
|
[BydCarDocs("BYD SEAL PERFORMANCE 2025")],
|
||||||
|
# TODO: verify steerRatio and centerToFrontRatio on a real car
|
||||||
|
CarSpecs(mass=2100 + STD_CARGO_KG, wheelbase=2.92, steerRatio=16.0,
|
||||||
|
centerToFrontRatio=0.44, tireStiffnessFactor=1.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CarControllerParams:
|
||||||
|
def __init__(self, CP):
|
||||||
|
self.STEER_STEP = 2 # 50Hz
|
||||||
|
self.ACC_SETP = 4 # 25Hz
|
||||||
|
|
||||||
|
self.STEER_ERROR_MAX = 46
|
||||||
|
if CP.carFingerprint in (CAR.BYD_HAN_EV_23, CAR.BYD_SEAL_PERFORMANCE_25):
|
||||||
|
self.STEER_MAX = 300
|
||||||
|
self.STEER_DELTA_UP = 6
|
||||||
|
self.STEER_DELTA_DOWN = 6
|
||||||
|
|
||||||
|
self.ACCEL_MAX = 2.0 # m/s^2
|
||||||
|
self.ACCEL_MIN = -4.0 # m/s^2
|
||||||
|
self.JERK_LIMIT_MAX = 4.0 # m/s^3
|
||||||
|
self.JERK_LIMIT_MIN = -4.0 # m/s^3
|
||||||
|
|
||||||
|
|
||||||
|
STEER_THRESHOLD = 1
|
||||||
|
|
||||||
|
GEAR_MAP = {
|
||||||
|
4: CarState.GearShifter.drive,
|
||||||
|
2: CarState.GearShifter.reverse,
|
||||||
|
3: CarState.GearShifter.neutral,
|
||||||
|
1: CarState.GearShifter.park,
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: Get a BYD VDS to see how firmware could be queried. Until then BYD is
|
||||||
|
# identified by legacy CAN fingerprinting only.
|
||||||
|
DBC = CAR.create_dbc_map()
|
||||||
@@ -634,6 +634,7 @@ struct CarParams {
|
|||||||
fcaGiorgio @32;
|
fcaGiorgio @32;
|
||||||
rivian @33;
|
rivian @33;
|
||||||
volkswagenMeb @34;
|
volkswagenMeb @34;
|
||||||
|
byd @35;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SteerControlType {
|
enum SteerControlType {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from opendbc.car.interfaces import get_interface_attr
|
from opendbc.car.interfaces import get_interface_attr
|
||||||
from opendbc.car.body.values import CAR as BODY
|
from opendbc.car.body.values import CAR as BODY
|
||||||
|
from opendbc.car.byd.values import CAR as BYD
|
||||||
from opendbc.car.chrysler.values import CAR as CHRYSLER
|
from opendbc.car.chrysler.values import CAR as CHRYSLER
|
||||||
from opendbc.car.ford.values import CAR as FORD
|
from opendbc.car.ford.values import CAR as FORD
|
||||||
from opendbc.car.gm.values import CAR as GM
|
from opendbc.car.gm.values import CAR as GM
|
||||||
@@ -56,6 +57,8 @@ def all_legacy_fingerprint_cars():
|
|||||||
|
|
||||||
# A dict that maps old platform strings to their latest representations
|
# A dict that maps old platform strings to their latest representations
|
||||||
MIGRATION = {
|
MIGRATION = {
|
||||||
|
"BYD HAN EV 23": BYD.BYD_HAN_EV_23,
|
||||||
|
"BYD SEAL PERFORMANCE 2025": BYD.BYD_SEAL_PERFORMANCE_25,
|
||||||
"ACURA ILX 2016 ACURAWATCH PLUS": HONDA.ACURA_ILX,
|
"ACURA ILX 2016 ACURAWATCH PLUS": HONDA.ACURA_ILX,
|
||||||
"ACURA RDX 2018 ACURAWATCH PLUS": HONDA.ACURA_RDX,
|
"ACURA RDX 2018 ACURAWATCH PLUS": HONDA.ACURA_RDX,
|
||||||
"ACURA RDX 2020 TECH": HONDA.ACURA_RDX_3G,
|
"ACURA RDX 2020 TECH": HONDA.ACURA_RDX_3G,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
|
legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
|
||||||
|
"BYD_HAN_EV_23" = [1.807, 1.674, 0.04]
|
||||||
|
"BYD_SEAL_PERFORMANCE_25" = [1.807, 1.674, 0.04]
|
||||||
"ACURA_ILX" = [1.524988973896102, 0.519011053086259, 0.34236219253028]
|
"ACURA_ILX" = [1.524988973896102, 0.519011053086259, 0.34236219253028]
|
||||||
"ACURA_RDX" = [0.9987728568686902, 0.5323765166196301, 0.303218805715844]
|
"ACURA_RDX" = [0.9987728568686902, 0.5323765166196301, 0.303218805715844]
|
||||||
"ACURA_RDX_3G" = [1.4314459806646749, 0.33874701282109954, 0.18048847083897598]
|
"ACURA_RDX_3G" = [1.4314459806646749, 0.33874701282109954, 0.18048847083897598]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from typing import get_args
|
from typing import get_args
|
||||||
from opendbc.car.body.values import CAR as BODY
|
from opendbc.car.body.values import CAR as BODY
|
||||||
|
from opendbc.car.byd.values import CAR as BYD
|
||||||
from opendbc.car.chrysler.values import CAR as CHRYSLER
|
from opendbc.car.chrysler.values import CAR as CHRYSLER
|
||||||
from opendbc.car.ford.values import CAR as FORD
|
from opendbc.car.ford.values import CAR as FORD
|
||||||
from opendbc.car.gm.values import CAR as GM
|
from opendbc.car.gm.values import CAR as GM
|
||||||
@@ -15,7 +16,7 @@ from opendbc.car.tesla.values import CAR as TESLA
|
|||||||
from opendbc.car.toyota.values import CAR as TOYOTA
|
from opendbc.car.toyota.values import CAR as TOYOTA
|
||||||
from opendbc.car.volkswagen.values import CAR as VOLKSWAGEN
|
from opendbc.car.volkswagen.values import CAR as VOLKSWAGEN
|
||||||
|
|
||||||
Platform = BODY | CHRYSLER | FORD | GM | HONDA | HYUNDAI | MAZDA | MOCK | NISSAN | PSA | RIVIAN | SUBARU | TESLA | TOYOTA | VOLKSWAGEN
|
Platform = BODY | BYD | CHRYSLER | FORD | GM | HONDA | HYUNDAI | MAZDA | MOCK | NISSAN | PSA | RIVIAN | SUBARU | TESLA | TOYOTA | VOLKSWAGEN
|
||||||
BRANDS = get_args(Platform)
|
BRANDS = get_args(Platform)
|
||||||
|
|
||||||
PLATFORMS: dict[str, Platform] = {str(platform): platform for brand in BRANDS for platform in brand}
|
PLATFORMS: dict[str, Platform] = {str(platform): platform for brand in BRANDS for platform in brand}
|
||||||
@@ -0,0 +1,375 @@
|
|||||||
|
VERSION ""
|
||||||
|
|
||||||
|
|
||||||
|
NS_ :
|
||||||
|
NS_DESC_
|
||||||
|
CM_
|
||||||
|
BA_DEF_
|
||||||
|
BA_
|
||||||
|
VAL_
|
||||||
|
CAT_DEF_
|
||||||
|
CAT_
|
||||||
|
FILTER
|
||||||
|
BA_DEF_DEF_
|
||||||
|
EV_DATA_
|
||||||
|
ENVVAR_DATA_
|
||||||
|
SGTYPE_
|
||||||
|
SGTYPE_VAL_
|
||||||
|
BA_DEF_SGTYPE_
|
||||||
|
BA_SGTYPE_
|
||||||
|
SIG_TYPE_REF_
|
||||||
|
VAL_TABLE_
|
||||||
|
SIG_GROUP_
|
||||||
|
SIG_VALTYPE_
|
||||||
|
SIGTYPE_VALTYPE_
|
||||||
|
BO_TX_BU_
|
||||||
|
BA_DEF_REL_
|
||||||
|
BA_REL_
|
||||||
|
BA_DEF_DEF_REL_
|
||||||
|
BU_SG_REL_
|
||||||
|
BU_EV_REL_
|
||||||
|
BU_BO_REL_
|
||||||
|
SG_MUL_VAL_
|
||||||
|
|
||||||
|
BS_:
|
||||||
|
|
||||||
|
BU_: XXX
|
||||||
|
|
||||||
|
BO_ 85 EPB: 8 XXX
|
||||||
|
SG_ EPB_ACTIVE : 40|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 234 STEERING_TORQUE_ALT: 8 XXX
|
||||||
|
SG_ LKSPrepare : 0|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Cruise_Activated : 1|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ TORQUE_FAILED : 4|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Steer_Torque_Sensor : 8|12@1- (1,0) [0|4095] "" XXX
|
||||||
|
SG_ MAIN_TORQUE : 24|12@1+ (0.15,-316) [0|4095] "" XXX
|
||||||
|
SG_ WAIT_INIT : 36|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 235 MPC_LKAS_CMD_ALT: 8 XXX
|
||||||
|
SG_ TORQUE_FACTOR : 0|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ LKAS_Output : 8|12@1- (0.15,0) [0|4095] "" XXX
|
||||||
|
SG_ LKASPrepare : 20|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LKAS_ACTIVE : 21|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_2 : 22|2@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_FF_1 : 24|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ SET_ME_FF_2 : 32|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ SET_ME_FF_3 : 40|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ SET_ME_F : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 269 ECM: 8 XXX
|
||||||
|
SG_ ENG_RPM : 0|16@1+ (0.25,0) [0|255] "" XXX
|
||||||
|
SG_ GAS_PEDAL : 40|8@1+ (0.00392,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 287 STEER_MODULE: 5 XXX
|
||||||
|
SG_ STEER_ANGLE : 0|16@1- (0.1,0) [-450|450] "" XXX
|
||||||
|
SG_ STEERING_RATE : 16|8@1+ (4,0) [0|1020] "" XXX
|
||||||
|
SG_ PAYLOAD : 24|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ COUNTER : 32|4@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ CHECKSUM_S : 36|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
|
||||||
|
BO_ 289 ESC: 8 XXX
|
||||||
|
SG_ VEHICLE_SPEED : 0|12@1+ (0.0725,0) [0|4095] "" XXX
|
||||||
|
|
||||||
|
BO_ 291 IPB: 8 XXX
|
||||||
|
SG_ BRAKE_PRESSED : 43|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 301 BRAKE_PRESSED: 8 XXX
|
||||||
|
SG_ BRAKE_PRESSED : 8|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 307 STALKS: 8 XXX
|
||||||
|
SG_ EPB_ACTIVE : 1|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ HEADLIGHT : 2|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ HIGH_BEAM : 3|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LEFT_BLINKER : 4|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ RIGHT_BLINKER : 5|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ TURN_SIGNAL_SWITCH : 36|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ AUTO_HEADLIGHT : 40|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 455 STEER_ANGLE_ALT: 8 XXX
|
||||||
|
SG_ STEER_ANGLE : 0|16@1- (0.1,0) [0|4095] "" XXX
|
||||||
|
SG_ STEER_RATE : 16|8@1+ (4,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 482 MPC_LKAS_CMD_ANGLE: 8 XXX
|
||||||
|
SG_ JerkUpperLimit : 0|10@1- (1,0) [0|65535] "" XXX
|
||||||
|
SG_ JerkLowerLimit : 10|10@1- (1,0) [0|15] "" XXX
|
||||||
|
SG_ LKASPrepare : 20|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LKAS_ACTIVE : 21|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_3 : 22|2@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LKAS_Output : 24|16@1- (0.1,0) [0|255] "" XXX
|
||||||
|
SG_ SET_ME_FF : 47|8@0+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ SET_ME_F : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 496 WHEEL_SPEED: 8 XXX
|
||||||
|
SG_ WHEELSPEED_FL : 0|12@1+ (0.0725,0) [0|281.4625] "km/h" XXX
|
||||||
|
SG_ FAULT_FR : 12|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ FAULT_FL : 13|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ FAULT_BR : 14|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ FAULT_BL : 15|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ WHEELSPEED_FR : 16|12@1+ (0.0725,0) [0|281.4625] "km/h" XXX
|
||||||
|
SG_ WHEELSPEED_BL : 28|12@1+ (0.0725,0) [0|281.4625] "km/h" XXX
|
||||||
|
SG_ WHEELSPEED_BR : 40|12@1+ (0.0725,0) [0|281.4625] "km/h" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 508 STEERING_TORQUE_ANGLE: 8 XXX
|
||||||
|
SG_ LKSPrepare : 0|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Cruise_Activated : 1|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ TORQUE_FAILED : 2|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Steer_Torque_Sensor : 4|12@1- (0.1,0) [0|65535] "" XXX
|
||||||
|
SG_ TARGET_ANGLE : 16|16@1- (0.1,0) [0|255] "" XXX
|
||||||
|
SG_ MAIN_TORQUE : 32|12@1- (1,0) [0|63] "" XXX
|
||||||
|
SG_ Keep_Hands_On_Wheel : 45|1@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ TORQUE_TEMP_FAILED : 46|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 522 ENGINE_RPM: 8 XXX
|
||||||
|
SG_ ENG_RPM : 31|8@0+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 523 ENGINE_GAUGE: 8 XXX
|
||||||
|
SG_ ENG_RPM : 15|8@0+ (12,0) [0|0] "" XXX
|
||||||
|
|
||||||
|
BO_ 530 TCU: 8 XXX
|
||||||
|
SG_ GEAR : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
|
||||||
|
BO_ 536 EPB_NG: 8 XXX
|
||||||
|
SG_ EPB_ACTIVE : 0|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ EPB_STATUS : 9|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ COUNTER : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 544 BRAKE_APPLIED: 8 XXX
|
||||||
|
SG_ BRAKE_HOLD_ACTIVE : 8|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BRAKE_APPLIED_ACTIVE_LOW : 12|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ STANDSTILL : 19|2@0+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ VLC_SENSOR : 24|8@1+ (0.05,-7) [0|255] "" XXX
|
||||||
|
SG_ NEW_SIGNAL_2 : 32|13@1+ (1,0) [0|8191] "" XXX
|
||||||
|
|
||||||
|
BO_ 546 YAW_SENSOR: 8 XXX
|
||||||
|
SG_ YAW_RATE : 0|12@1+ (0.002132603,-2.094216146) [0|4095] "" XXX
|
||||||
|
SG_ YAW_OFFSET : 12|12@1+ (0.002132603,-0.130088783) [0|4095] "" XXX
|
||||||
|
|
||||||
|
BO_ 547 ACCEL_SENSOR: 8 XXX
|
||||||
|
SG_ LONGITUDE : 0|12@1- (0.027126736,-21.592881856) [-2848|1247] "" XXX
|
||||||
|
SG_ LONGITUDE_OFFSET : 12|12@1+ (0.027126736,-21.592881856) [0|4095] "" XXX
|
||||||
|
SG_ LATERAL : 24|12@1- (0.027126736,-21.592881856) [-2848|1247] "" XXX
|
||||||
|
SG_ LATERAL_OFFSET : 36|12@1+ (0.027126736,-21.592881856) [0|4095] "" XXX
|
||||||
|
|
||||||
|
BO_ 578 DRIVE_STATE: 8 XXX
|
||||||
|
SG_ WHEELSPEED_HR : 0|16@1+ (0.01706666666,-512) [0|65535] "" XXX
|
||||||
|
SG_ RAW_THROTTLE : 30|7@0+ (1,0) [0|127] "" XXX
|
||||||
|
SG_ BRAKE_PRESSED : 37|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ GEAR : 40|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
|
||||||
|
BO_ 660 METER_CLUSTER: 8 XXX
|
||||||
|
SG_ FRONT_RIGHT_DOOR : 1|1@1+ (1,0) [0|511] "" XXX
|
||||||
|
SG_ FRONT_LEFT_DOOR : 3|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BACK_LEFT_DOOR : 5|1@1+ (1,0) [0|511] "" XXX
|
||||||
|
SG_ BACK_RIGHT_DOOR : 7|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SEATBELT_DRIVER : 17|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BRAKE_PRESSED_ALT : 26|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ COUNTER : 48|4@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 665 IKEY: 3 XXX
|
||||||
|
SG_ IKEY_REVERT : 20|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ IKEY_MOVE_OR_STEERING : 21|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ IKEY_ENABLE : 22|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 790 MPC_LKAS_CMD: 8 XXX
|
||||||
|
SG_ SETME_0x1 : 0|4@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ LeftLane : 4|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ Config : 6|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ SETME2_0x1 : 8|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ Keep_Hands_On_Wheel : 10|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ MPCErr : 11|4@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME3_0x1 : 15|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LKAS_Output : 16|11@1- (1,0) [-1024|1023] "" XXX
|
||||||
|
SG_ LKASPrepare : 27|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ LKAS_ACTIVE : 28|1@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ TSRStatus : 29|3@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME4_0x1 : 32|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ RightLane : 34|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ LKAS_Mode : 36|3@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ SETME_0x0 : 39|1@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ TSRResult : 40|8@1+ (5,-5) [-5|1270] "" XXX
|
||||||
|
SG_ Unknow1 : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 792 STEERING_TORQUE: 8 XXX
|
||||||
|
SG_ LKSPrepare : 0|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Cruise_Activated : 1|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ TORQUE_FAILED : 2|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_1_1 : 3|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Steer_Warning : 4|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Steer_Error_1 : 5|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Steer_Error_2 : 6|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_1 : 7|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ MAIN_TORQUE : 8|12@1- (1,0) [-2048|2047] "" XXX
|
||||||
|
SG_ SET_ME_1_2 : 20|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ Keep_Hands_On_Wheel : 21|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_3 : 22|2@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ Steer_Torque_Sensor : 24|12@1- (1,0) [-2048|2047] "" XXX
|
||||||
|
SG_ SET_ME_XF_1 : 36|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ SET_ME_XFFF : 40|12@1+ (1,0) [0|4095] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 801 BRAKE_PEDAL_LEG: 8 XXX
|
||||||
|
SG_ BRAKE_PEDAL : 0|12@1+ (0.001,-0.278) [0|255] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 813 ACC_HUD_ADAS: 8 XXX
|
||||||
|
SG_ SET_SPEED : 0|9@1+ (0.5,0) [0|255.5] "" XXX
|
||||||
|
SG_ HAS_LEAD : 9|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_DISTANCE : 10|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ LEAD_DISTANCE : 13|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ AEB : 16|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ FCW : 17|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_1 : 18|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_ON2 : 19|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_CONTROLLABLE_AND_ON : 20|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ OVERRIDE : 21|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_ON1 : 22|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ TOO_CLOSE : 23|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_1_1 : 24|3@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ NOTIFY : 27|5@1+ (1,0) [0|127] "" XXX
|
||||||
|
SG_ ERROR : 32|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ SET_ME_XFF : 36|8@1+ (1,0) [0|4095] "" XXX
|
||||||
|
SG_ CRUISE_STATE : 44|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ COUNTER : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ SET_ME_XF : 55|4@0+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 814 ACC_CMD: 8 XXX
|
||||||
|
SG_ ACCEL_CMD : 0|8@1+ (0.05,-5) [-100|155] "m/s^2" XXX
|
||||||
|
SG_ ComfortBandUpper : 8|8@1+ (0.05,-5) [0|1.26] "m/s^2" XXX
|
||||||
|
SG_ ComfortBandLower : 16|8@1+ (0.05,-5) [0|1.26] "m/s^2" XXX
|
||||||
|
SG_ JerkUpperLimit : 24|7@1+ (0.2,0) [0|12.7] "m/s^3" XXX
|
||||||
|
SG_ SET_ME_1 : 31|1@0+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ JerkLowerLimit : 32|7@1+ (0.2,-16) [0|12.7] "m/s^3" XXX
|
||||||
|
SG_ STANDSTILL_RESUME : 39|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ STANDSTILL_STATE : 40|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BRAKE_BEHAVIOR : 41|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ ACC_REQ_NOT_STANDSTILL : 43|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_CONTROLLABLE_AND_ON : 44|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_OVERRIDE_OR_STANDSTILL : 45|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ESP_BEHAVIOR : 46|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ COUNTER : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ SET_ME_XF : 55|4@0+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 815 ACC_AEB: 8 XXX
|
||||||
|
SG_ PAYLOAD : 0|48@1+ (1,0) [0|4.5035996273705e+15] "" XXX
|
||||||
|
SG_ COUNTER : 48|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ SETME_0xF : 55|4@0+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 834 PEDAL: 8 XXX
|
||||||
|
SG_ GAS_PEDAL : 0|8@1+ (0.01,0) [0|2.55] "" XXX
|
||||||
|
SG_ BRAKE_PEDAL : 8|8@1+ (0.01,0) [0|2.55] "" XXX
|
||||||
|
SG_ STILL_GENERATOR : 19|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ DRIVE_MODE : 20|2@1+ (1,0) [0|255] "" XXX
|
||||||
|
SG_ POWER_MODE : 28|2@1+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 848 RADAR_UNUSED_0: 8 XXX
|
||||||
|
|
||||||
|
BO_ 849 RADAR_TRACK_1: 8 XXX
|
||||||
|
SG_ LONG_DIST : 16|12@1- (0.06,-4) [-61.44|61.41] "m" XXX
|
||||||
|
SG_ LAT_DIST : 28|10@1+ (0.05,-25.6) [-15.36|15.33] "m" XXX
|
||||||
|
SG_ TRACK_ID : 38|6@1+ (1,0) [0|63] "" XXX
|
||||||
|
SG_ REL_SPEED : 44|10@1+ (1,-512) [-512|511] "km/s" XXX
|
||||||
|
SG_ SETME_0x3 : 54|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ VALID : 56|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME_0x0 : 57|7@1+ (1,0) [0|127] "" XXX
|
||||||
|
|
||||||
|
BO_ 850 RADAR_TRACK_2: 8 XXX
|
||||||
|
SG_ LONG_DIST : 16|12@1- (0.06,-4) [-61.44|61.41] "m" XXX
|
||||||
|
SG_ LAT_DIST : 28|10@1+ (-0.05,-25.6) [-15.36|15.33] "m" XXX
|
||||||
|
SG_ TRACK_ID : 38|6@1+ (1,0) [0|63] "" XXX
|
||||||
|
SG_ REL_SPEED : 44|10@1+ (1,-512) [-512|511] "km/s" XXX
|
||||||
|
SG_ SETME_0x3 : 54|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ VALID : 56|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME_0x0 : 57|7@1+ (1,0) [0|127] "" XXX
|
||||||
|
|
||||||
|
BO_ 851 RADAR_TRACK_3: 8 XXX
|
||||||
|
SG_ LONG_DIST : 16|12@1- (0.06,-4) [-61.44|61.41] "m" XXX
|
||||||
|
SG_ LAT_DIST : 28|10@1+ (0.05,-25.6) [-15.36|15.33] "m" XXX
|
||||||
|
SG_ TRACK_ID : 38|6@1+ (1,0) [0|63] "" XXX
|
||||||
|
SG_ REL_SPEED : 44|10@1+ (1,-512) [-512|511] "km/s" XXX
|
||||||
|
SG_ SETME_0x3 : 54|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ VALID : 56|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME_0x0 : 57|7@1+ (1,0) [0|127] "" XXX
|
||||||
|
|
||||||
|
BO_ 852 RADAR_TRACK_4: 8 XXX
|
||||||
|
SG_ LONG_DIST : 16|12@1- (0.06,-4) [-61.44|61.41] "m" XXX
|
||||||
|
SG_ LAT_DIST : 28|10@1+ (0.05,-25.6) [-15.36|15.33] "m" XXX
|
||||||
|
SG_ TRACK_ID : 38|6@1+ (1,0) [0|63] "" XXX
|
||||||
|
SG_ REL_SPEED : 44|10@1+ (1,-512) [-512|511] "km/s" XXX
|
||||||
|
SG_ SETME_0x3 : 54|2@1+ (1,0) [0|3] "" XXX
|
||||||
|
SG_ VALID : 56|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SETME_0x0 : 57|7@1+ (1,0) [0|127] "" XXX
|
||||||
|
|
||||||
|
BO_ 884 RADAR_TRACK_COMBINE: 8 XXX
|
||||||
|
SG_ TRACK_ID : 0|3@1+ (1,0) [0|7] "bit" XXX
|
||||||
|
SG_ TargetType : 4|4@1+ (1,0) [0|8] "bit" XXX
|
||||||
|
SG_ LAT_DIST : 8|8@1+ (0.1,-12) [-100|100] "bit" XXX
|
||||||
|
SG_ LONG_DIST : 16|8@1+ (1,-100) [-100|100] "bit" XXX
|
||||||
|
SG_ REL_SPEED : 24|8@1+ (1,0) [0|254] "km/h" XXX
|
||||||
|
SG_ REL_SPEED_H : 32|8@1+ (1,0) [0|254] "km/h" XXX
|
||||||
|
SG_ VALID : 40|2@1+ (1,0) [0|3] "bit" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "bit" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "bit" XXX
|
||||||
|
|
||||||
|
BO_ 926 GAUGE_SPEED: 8 XXX
|
||||||
|
SG_ GAUGE_SPEED : 8|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 944 PCM_BUTTONS: 8 XXX
|
||||||
|
SG_ DISTANCE_BTN : 0|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ BTN_ACC_DEC : 3|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ SET_BTN : 6|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_0_1 : 7|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_ON_BTN : 8|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_0 : 9|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ RES_BTN : 10|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_2 : 11|3@1+ (1,0) [0|7] "" XXX
|
||||||
|
SG_ LKAS_ON_BTN : 14|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BTN_DIST_DOWN : 15|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ BTN_DIST_UP : 16|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_0_2 : 17|2@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ ACC_SWITCH : 19|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ SET_ME_XFFFFF : 20|32@1+ (1,0) [0|68719476735] "" XXX
|
||||||
|
SG_ COUNTER : 52|4@1+ (1,0) [0|15] "" XXX
|
||||||
|
SG_ CHECKSUM : 56|8@1+ (1,0) [0|255] "" XXX
|
||||||
|
|
||||||
|
BO_ 1048 BSM: 8 XXX
|
||||||
|
SG_ LEFT_APPROACH : 9|2@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ RIGHT_APPROACH : 11|2@0+ (1,0) [0|1] "" XXX
|
||||||
|
SG_ APPROACH : 17|1@0+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
BO_ 1172 BRAKE_APPLIED_2: 8 XXX
|
||||||
|
SG_ BRAKE_APPLIED_ACTIVE_LOW : 47|1@1+ (1,0) [0|1] "" XXX
|
||||||
|
|
||||||
|
VAL_ 307 TURN_SIGNAL_SWITCH 0 "Invalid" 1 "OFFGear" 2 "LeftSteeringShortLift" 3 "LeftSteeringLongLift" 4 "RightSteeringShortLift" 5 "RightSteeringLongLift" 7 "Unavaliable";
|
||||||
|
VAL_ 508 TORQUE_TEMP_FAILED 2 "TooFast" 1 "TooLarge" 3 "Both";
|
||||||
|
VAL_ 530 GEAR 4 "D" 2 "R" 3 "N" 1 "P";
|
||||||
|
VAL_ 536 EPB_ACTIVE 0 "NotActive" 1 "Release" 2 "Apply" 3 "Reserved";
|
||||||
|
VAL_ 536 EPB_STATUS 0 "Releasing" 1 "Released" 2 "Applying" 3 "Applied" 4 "FaultProhibitionOfRemoteDriving";
|
||||||
|
VAL_ 578 GEAR 4 "D" 2 "R" 3 "N" 1 "P";
|
||||||
|
VAL_ 790 Config 3 "FULL_TERRAIN" 2 "LKAS" 1 "ALERT" 0 "DISABLE";
|
||||||
|
VAL_ 790 LKAS_Mode 0 "OFF" 1 "Passive" 2 "Active1" 3 "Active2" 4 "Fault" 5 "StandBy";
|
||||||
|
VAL_ 813 SET_DISTANCE 4 "4bar" 3 "3bar" 2 "2bar" 1 "1bar";
|
||||||
|
VAL_ 813 NOTIFY 4 "OVERRIDE" 3 "ENGAGE" 2 "DISENGAGE" 7 "ACC_ON" 8 "ACC_OFF" 0 "NONE";
|
||||||
|
VAL_ 813 CRUISE_STATE 0 "OFF" 1 "Passive" 2 "StandBy" 3 "Active" 4 "BrakeOnly" 5 "Override" 6 "StandStillActive" 7 "StandStillWait" 8 "Failure" 9 "PermanentFailure";
|
||||||
|
VAL_ 834 DRIVE_MODE 3 "NORMAL" 2 "SPORT" 1 "ECO";
|
||||||
|
VAL_ 834 POWER_MODE 3 "HEV" 2 "FORCE_EV" 1 "EV";
|
||||||
|
VAL_ 944 BTN_ACC_DEC 4 "ACC 10" 3 "ACC 1" 2
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#define SAFETY_PSA 31U
|
#define SAFETY_PSA 31U
|
||||||
#define SAFETY_RIVIAN 33U
|
#define SAFETY_RIVIAN 33U
|
||||||
#define SAFETY_VOLKSWAGEN_MEB 34U
|
#define SAFETY_VOLKSWAGEN_MEB 34U
|
||||||
|
#define SAFETY_BYD 35U
|
||||||
|
|
||||||
#define GET_BIT(msg, b) ((bool)!!(((msg)->data[((b) / 8U)] >> ((b) % 8U)) & 0x1U))
|
#define GET_BIT(msg, b) ((bool)!!(((msg)->data[((b) / 8U)] >> ((b) % 8U)) & 0x1U))
|
||||||
#define GET_FLAG(value, mask) (((value) & (mask)) == (mask))
|
#define GET_FLAG(value, mask) (((value) & (mask)) == (mask))
|
||||||
@@ -368,3 +369,4 @@ extern const safety_hooks volkswagen_meb_hooks;
|
|||||||
extern const safety_hooks volkswagen_pq_hooks;
|
extern const safety_hooks volkswagen_pq_hooks;
|
||||||
extern const safety_hooks rivian_hooks;
|
extern const safety_hooks rivian_hooks;
|
||||||
extern const safety_hooks psa_hooks;
|
extern const safety_hooks psa_hooks;
|
||||||
|
extern const safety_hooks byd_hooks;
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
#include "opendbc/safety/declarations.h"
|
||||||
|
|
||||||
|
// MPC_LKAS_CMD (790), little endian
|
||||||
|
#define BYD_GET_LKAS_OUTPUT(msg) (to_signed((((msg)->data[3] & 0x7U) << 8U) | (msg)->data[2], 11))
|
||||||
|
#define BYD_LKAS_ACTIVE_BIT 28U
|
||||||
|
// STEERING_TORQUE (792), little endian
|
||||||
|
#define BYD_GET_MAIN_TORQUE(msg) (to_signed((((msg)->data[2] & 0xFU) << 8U) | (msg)->data[1], 12))
|
||||||
|
#define BYD_GET_DRIVER_TORQUE(msg) (to_signed((((msg)->data[4] & 0xFU) << 8U) | (msg)->data[3], 12))
|
||||||
|
// PCM_BUTTONS (944)
|
||||||
|
#define BYD_LKAS_ON_BTN_BIT 14U
|
||||||
|
|
||||||
|
static bool byd_tx_hook(const CANPacket_t *msg) {
|
||||||
|
const TorqueSteeringLimits BYD_STEERING_LIMITS = {
|
||||||
|
.max_torque = 300,
|
||||||
|
.max_rate_up = 6,
|
||||||
|
.max_rate_down = 6,
|
||||||
|
.max_rt_delta = 112, // 75 per 250ms at 50Hz steer rate, plus 50% buffer
|
||||||
|
.type = TorqueMotorLimited,
|
||||||
|
.driver_torque_allowance = 46,
|
||||||
|
.driver_torque_multiplier = 1,
|
||||||
|
.max_torque_error = 46,
|
||||||
|
};
|
||||||
|
|
||||||
|
const LongitudinalLimits BYD_LONG_LIMITS = {
|
||||||
|
.max_accel = 140, // 2.0 m/s^2 (raw = (m/s^2 + 5) / 0.05)
|
||||||
|
.min_accel = 20, // -4.0 m/s^2
|
||||||
|
.inactive_accel = 100, // 0 m/s^2, sent when longitudinal control is inactive
|
||||||
|
};
|
||||||
|
|
||||||
|
bool tx = true;
|
||||||
|
|
||||||
|
// MPC_LKAS_CMD: steering actuation towards the EPS
|
||||||
|
if (msg->addr == 790U) {
|
||||||
|
int desired_torque = BYD_GET_LKAS_OUTPUT(msg);
|
||||||
|
bool steer_req = GET_BIT(msg, BYD_LKAS_ACTIVE_BIT);
|
||||||
|
|
||||||
|
if (steer_torque_cmd_checks(desired_torque, steer_req, BYD_STEERING_LIMITS)) {
|
||||||
|
tx = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEERING_TORQUE: feedback message towards the camera, torque echoes the
|
||||||
|
// camera's own request. Only sanity-check the absolute limit so stock LKAS
|
||||||
|
// requests don't fault when openpilot is inactive.
|
||||||
|
if (msg->addr == 792U) {
|
||||||
|
int main_torque = BYD_GET_MAIN_TORQUE(msg);
|
||||||
|
if (safety_max_limit_check(main_torque, BYD_STEERING_LIMITS.max_torque, -BYD_STEERING_LIMITS.max_torque)) {
|
||||||
|
tx = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACC_CMD: longitudinal actuation
|
||||||
|
if (msg->addr == 814U) {
|
||||||
|
int desired_accel = msg->data[0];
|
||||||
|
|
||||||
|
if (longitudinal_accel_checks(desired_accel, BYD_LONG_LIMITS)) {
|
||||||
|
tx = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void byd_rx_hook(const CANPacket_t *msg) {
|
||||||
|
// Main Bus
|
||||||
|
if (msg->bus == 0U) {
|
||||||
|
// PEDAL
|
||||||
|
if (msg->addr == 834U) {
|
||||||
|
gas_pressed = msg->data[0] != 0U;
|
||||||
|
brake_pressed = msg->data[1] != 0U;
|
||||||
|
}
|
||||||
|
// ESC
|
||||||
|
if (msg->addr == 289U) {
|
||||||
|
vehicle_moving = (((msg->data[1] & 0x0FU) << 8U) | msg->data[0]) != 0U;
|
||||||
|
}
|
||||||
|
// STEERING_TORQUE: sample EPS output torque and driver torque
|
||||||
|
if (msg->addr == 792U) {
|
||||||
|
int torque_meas_new = BYD_GET_MAIN_TORQUE(msg);
|
||||||
|
update_sample(&torque_meas, torque_meas_new);
|
||||||
|
torque_meas.min--;
|
||||||
|
torque_meas.max++;
|
||||||
|
|
||||||
|
int torque_driver_new = BYD_GET_DRIVER_TORQUE(msg);
|
||||||
|
update_sample(&torque_driver, torque_driver_new);
|
||||||
|
}
|
||||||
|
// PCM_BUTTONS: dedicated LKAS steering wheel button for MADS
|
||||||
|
if (msg->addr == 944U) {
|
||||||
|
mads_button_press = GET_BIT(msg, BYD_LKAS_ON_BTN_BIT) ? MADS_BUTTON_PRESSED : MADS_BUTTON_NOT_PRESSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cam Bus
|
||||||
|
else if (msg->bus == 2U) {
|
||||||
|
// ACC_HUD_ADAS
|
||||||
|
if (msg->addr == 813U) {
|
||||||
|
// CRUISE_STATE in (3, 5) == (Active, Override)
|
||||||
|
uint8_t cruise_state = (msg->data[5] >> 4U) & 0x0FU;
|
||||||
|
pcm_cruise_check((cruise_state == 3U) || (cruise_state == 5U));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static safety_config byd_init(uint16_t param) {
|
||||||
|
static const CanMsg BYD_TX_MSGS[] = {
|
||||||
|
{790, 0, 8, .check_relay = true}, // MPC_LKAS_CMD
|
||||||
|
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CanMsg BYD_TX_LONG_MSGS[] = {
|
||||||
|
{790, 0, 8, .check_relay = true}, // MPC_LKAS_CMD
|
||||||
|
{792, 2, 8, .check_relay = true}, // STEERING_TORQUE
|
||||||
|
{814, 0, 8, .check_relay = true}, // ACC_CMD
|
||||||
|
};
|
||||||
|
|
||||||
|
static RxCheck byd_rx_checks[] = {
|
||||||
|
{.msg = {{578, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // DRIVE_STATE
|
||||||
|
{.msg = {{544, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // BRAKE_APPLIED
|
||||||
|
{.msg = {{834, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // PEDAL
|
||||||
|
{.msg = {{289, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // ESC
|
||||||
|
{.msg = {{287, 0, 5, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // STEER_MODULE
|
||||||
|
{.msg = {{792, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // STEERING_TORQUE
|
||||||
|
{.msg = {{944, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // PCM_BUTTONS
|
||||||
|
{.msg = {{813, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // ACC_HUD_ADAS
|
||||||
|
{.msg = {{307, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // STALKS
|
||||||
|
{.msg = {{660, 0, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // METER_CLUSTER
|
||||||
|
{.msg = {{790, 2, 8, .ignore_checksum = true, .ignore_counter = true, .ignore_quality_flag = true}, { 0 }, { 0 }}}, // MPC_LKAS_CMD
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t BYD_FLAG_LONG_CONTROL = 1;
|
||||||
|
const bool byd_longitudinal = GET_FLAG(param, BYD_FLAG_LONG_CONTROL);
|
||||||
|
|
||||||
|
safety_config ret;
|
||||||
|
if (byd_longitudinal) {
|
||||||
|
ret = BUILD_SAFETY_CFG(byd_rx_checks, BYD_TX_LONG_MSGS);
|
||||||
|
} else {
|
||||||
|
ret = BUILD_SAFETY_CFG(byd_rx_checks, BYD_TX_MSGS);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const safety_hooks byd_hooks = {
|
||||||
|
.init = byd_init,
|
||||||
|
.rx = byd_rx_hook,
|
||||||
|
.tx = byd_tx_hook,
|
||||||
|
};
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "opendbc/safety/modes/body.h"
|
#include "opendbc/safety/modes/body.h"
|
||||||
#include "opendbc/safety/modes/psa.h"
|
#include "opendbc/safety/modes/psa.h"
|
||||||
#include "opendbc/safety/modes/hyundai_canfd.h"
|
#include "opendbc/safety/modes/hyundai_canfd.h"
|
||||||
|
#include "opendbc/safety/modes/byd.h"
|
||||||
|
|
||||||
uint32_t GET_BYTES(const CANPacket_t *msg, int start, int len) {
|
uint32_t GET_BYTES(const CANPacket_t *msg, int start, int len) {
|
||||||
uint32_t ret = 0U;
|
uint32_t ret = 0U;
|
||||||
@@ -419,6 +420,7 @@ int set_safety_hooks(uint16_t mode, uint16_t param) {
|
|||||||
{SAFETY_RIVIAN, &rivian_hooks},
|
{SAFETY_RIVIAN, &rivian_hooks},
|
||||||
{SAFETY_TESLA, &tesla_hooks},
|
{SAFETY_TESLA, &tesla_hooks},
|
||||||
{SAFETY_HYUNDAI_CANFD, &hyundai_canfd_hooks},
|
{SAFETY_HYUNDAI_CANFD, &hyundai_canfd_hooks},
|
||||||
|
{SAFETY_BYD, &byd_hooks},
|
||||||
#ifdef ALLOW_DEBUG
|
#ifdef ALLOW_DEBUG
|
||||||
{SAFETY_CHRYSLER_CUSW, &chrysler_cusw_hooks},
|
{SAFETY_CHRYSLER_CUSW, &chrysler_cusw_hooks},
|
||||||
{SAFETY_PSA, &psa_hooks},
|
{SAFETY_PSA, &psa_hooks},
|
||||||
|
|||||||
@@ -1017,6 +1017,8 @@ class SafetyTest(SafetyTestBase):
|
|||||||
continue
|
continue
|
||||||
if attr.startswith('TestFord') and current_test.startswith('TestFord'):
|
if attr.startswith('TestFord') and current_test.startswith('TestFord'):
|
||||||
continue
|
continue
|
||||||
|
if attr.startswith('TestByd') and current_test.startswith('TestByd'):
|
||||||
|
continue
|
||||||
if attr.startswith('TestHyundaiCanfd') and current_test.startswith('TestHyundaiCanfd'):
|
if attr.startswith('TestHyundaiCanfd') and current_test.startswith('TestHyundaiCanfd'):
|
||||||
continue
|
continue
|
||||||
if {attr, current_test}.issubset({'TestHyundaiLongitudinalSafety', 'TestHyundaiLongitudinalSafetyCameraSCC', 'TestHyundaiSafetyFCEVLong'}):
|
if {attr, current_test}.issubset({'TestHyundaiLongitudinalSafety', 'TestHyundaiLongitudinalSafetyCameraSCC', 'TestHyundaiSafetyFCEVLong'}):
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from opendbc.car.structs import CarParams
|
||||||
|
from opendbc.safety.tests.libsafety import libsafety_py
|
||||||
|
import opendbc.safety.tests.common as common
|
||||||
|
from opendbc.safety.tests.common import CANPackerSafety
|
||||||
|
|
||||||
|
MSG_MPC_LKAS_CMD = 790 # TX by OP, lateral actuation towards EPS
|
||||||
|
MSG_STEERING_TORQUE = 792 # RX from EPS / TX by OP, torque feedback towards camera
|
||||||
|
MSG_ACC_HUD_ADAS = 813 # RX from camera, ACC state
|
||||||
|
MSG_ACC_CMD = 814 # TX by OP, longitudinal actuation
|
||||||
|
MSG_PCM_BUTTONS = 944 # RX from PCM, steering wheel buttons
|
||||||
|
|
||||||
|
|
||||||
|
def byd_checksum(msg):
|
||||||
|
addr, dat, bus = msg
|
||||||
|
ret = bytearray(dat)
|
||||||
|
|
||||||
|
if addr in (MSG_MPC_LKAS_CMD, MSG_STEERING_TORQUE, MSG_ACC_CMD):
|
||||||
|
byte_key = 0xAF
|
||||||
|
sum_first = sum(byte >> 4 for byte in ret) # upper nibbles
|
||||||
|
sum_second = sum(byte & 0xF for byte in ret) # lower nibbles
|
||||||
|
|
||||||
|
remainder = sum_second >> 4
|
||||||
|
|
||||||
|
sum_first += (byte_key & 0xF)
|
||||||
|
sum_second += (byte_key >> 4)
|
||||||
|
|
||||||
|
inv_first = ((-sum_first + 0x9) & 0xF)
|
||||||
|
inv_second = ((-sum_second + 0x9) & 0xF)
|
||||||
|
|
||||||
|
ret[7] = (((inv_first + (5 - remainder)) << 4) + inv_second) & 0xFF
|
||||||
|
|
||||||
|
return addr, ret, bus
|
||||||
|
|
||||||
|
|
||||||
|
class TestBydSafetyBase(common.CarSafetyTest, common.MotorTorqueSteeringSafetyTest):
|
||||||
|
TX_MSGS = [[MSG_MPC_LKAS_CMD, 0], [MSG_STEERING_TORQUE, 2]]
|
||||||
|
STANDSTILL_THRESHOLD = 0
|
||||||
|
RELAY_MALFUNCTION_ADDRS = {0: (MSG_MPC_LKAS_CMD,), 2: (MSG_STEERING_TORQUE,)}
|
||||||
|
FWD_BLACKLISTED_ADDRS = {0: [MSG_STEERING_TORQUE], 2: [MSG_MPC_LKAS_CMD]}
|
||||||
|
|
||||||
|
MAX_TORQUE_LOOKUP = ([0], [300])
|
||||||
|
MAX_RATE_UP = 6
|
||||||
|
MAX_RATE_DOWN = 6
|
||||||
|
MAX_RT_DELTA = 112
|
||||||
|
MAX_TORQUE_ERROR = 46
|
||||||
|
TORQUE_MEAS_TOLERANCE = 1
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.packer = CANPackerSafety("byd_common")
|
||||||
|
self.safety = libsafety_py.libsafety
|
||||||
|
self.safety.set_safety_hooks(CarParams.SafetyModel.byd, 0)
|
||||||
|
self.safety.init_tests()
|
||||||
|
|
||||||
|
def _torque_cmd_msg(self, torque, steer_req=1):
|
||||||
|
values = {"LKAS_Output": torque, "LKAS_ACTIVE": steer_req}
|
||||||
|
return self.packer.make_can_msg_safety("MPC_LKAS_CMD", 0, values, byd_checksum)
|
||||||
|
|
||||||
|
def _torque_meas_msg(self, torque):
|
||||||
|
values = {"MAIN_TORQUE": torque}
|
||||||
|
return self.packer.make_can_msg_safety("STEERING_TORQUE", 0, values)
|
||||||
|
|
||||||
|
def _torque_driver_msg(self, torque):
|
||||||
|
values = {"Steer_Torque_Sensor": torque}
|
||||||
|
return self.packer.make_can_msg_safety("STEERING_TORQUE", 0, values)
|
||||||
|
|
||||||
|
def _speed_msg(self, speed):
|
||||||
|
values = {"VEHICLE_SPEED": speed}
|
||||||
|
return self.packer.make_can_msg_safety("ESC", 0, values)
|
||||||
|
|
||||||
|
def _user_brake_msg(self, brake):
|
||||||
|
values = {"BRAKE_PEDAL": brake}
|
||||||
|
return self.packer.make_can_msg_safety("PEDAL", 0, values)
|
||||||
|
|
||||||
|
def _user_gas_msg(self, gas):
|
||||||
|
values = {"GAS_PEDAL": gas}
|
||||||
|
return self.packer.make_can_msg_safety("PEDAL", 0, values)
|
||||||
|
|
||||||
|
def _pcm_status_msg(self, enable):
|
||||||
|
# CRUISE_STATE: 3 == Active, 0 == Off
|
||||||
|
values = {"CRUISE_STATE": 3 if enable else 0}
|
||||||
|
return self.packer.make_can_msg_safety("ACC_HUD_ADAS", 2, values)
|
||||||
|
|
||||||
|
def _lkas_button_msg(self, enabled):
|
||||||
|
values = {"LKAS_ON_BTN": enabled}
|
||||||
|
return self.packer.make_can_msg_safety("PCM_BUTTONS", 0, values)
|
||||||
|
|
||||||
|
def _acc_state_msg(self, enable):
|
||||||
|
# BYD has no separate ACC main switch state in panda; MADS is toggled
|
||||||
|
# with the dedicated LKAS steering wheel button instead
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class TestBydStockSafety(TestBydSafetyBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestBydLongitudinalSafety(TestBydSafetyBase):
|
||||||
|
TX_MSGS = [[MSG_MPC_LKAS_CMD, 0], [MSG_STEERING_TORQUE, 2], [MSG_ACC_CMD, 0]]
|
||||||
|
RELAY_MALFUNCTION_ADDRS = {0: (MSG_MPC_LKAS_CMD, MSG_ACC_CMD), 2: (MSG_STEERING_TORQUE,)}
|
||||||
|
FWD_BLACKLISTED_ADDRS = {0: [MSG_STEERING_TORQUE], 2: [MSG_MPC_LKAS_CMD, MSG_ACC_CMD]}
|
||||||
|
|
||||||
|
MIN_ACCEL = 20 # -4.0 m/s^2, raw = (m/s^2 + 5) / 0.05
|
||||||
|
MAX_ACCEL = 140 # 2.0 m/s^2
|
||||||
|
INACTIVE_ACCEL = 100 # 0 m/s^2
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.packer = CANPackerSafety("byd_common")
|
||||||
|
self.safety = libsafety_py.libsafety
|
||||||
|
self.safety.set_safety_hooks(CarParams.SafetyModel.byd, 1) # BydSafetyFlags.LONG_CONTROL
|
||||||
|
self.safety.init_tests()
|
||||||
|
|
||||||
|
def _accel_msg(self, accel: float):
|
||||||
|
# accel in m/s^2, ACCEL_CMD raw = (m/s^2 + 5) / 0.05
|
||||||
|
values = {"ACCEL_CMD": accel}
|
||||||
|
return self.packer.make_can_msg_safety("ACC_CMD", 0, values, byd_checksum)
|
||||||
|
|
||||||
|
def test_accel_actuation_limits(self):
|
||||||
|
self.safety.set_controls_allowed(True)
|
||||||
|
for accel in [self.MIN_ACCEL - 1, self.MIN_ACCEL, 100, self.MAX_ACCEL, self.MAX_ACCEL + 1]:
|
||||||
|
send = self.MIN_ACCEL <= accel <= self.MAX_ACCEL
|
||||||
|
self.assertEqual(send, self._tx(self._accel_raw_msg(accel)), f"{accel=}")
|
||||||
|
|
||||||
|
def _accel_raw_msg(self, raw: int):
|
||||||
|
msg = self._accel_msg(0)
|
||||||
|
msg[0].data[0] = raw & 0xFF
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def test_accel_when_not_allowed(self):
|
||||||
|
# when controls are not allowed, only 0 m/s^2 (inactive) may be sent
|
||||||
|
self.safety.set_controls_allowed(False)
|
||||||
|
self.assertTrue(self._tx(self._accel_raw_msg(self.INACTIVE_ACCEL)))
|
||||||
|
self.assertFalse(self._tx(self._accel_raw_msg(self.INACTIVE_ACCEL + 5)))
|
||||||
|
self.assertFalse(self._tx(self._accel_raw_msg(self.INACTIVE_ACCEL - 5)))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Whitespace-only changes.
@@ -0,0 +1,24 @@
|
|||||||
|
"""
|
||||||
|
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||||
|
|
||||||
|
This file is part of sunnypilot and is licensed under the MIT License.
|
||||||
|
See the LICENSE.md file in the root directory for more details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from enum import StrEnum
|
||||||
|
|
||||||
|
from opendbc.car import Bus, structs
|
||||||
|
|
||||||
|
from opendbc.sunnypilot.mads_base import MadsCarStateBase
|
||||||
|
from opendbc.can.parser import CANParser
|
||||||
|
|
||||||
|
|
||||||
|
class MadsCarState(MadsCarStateBase):
|
||||||
|
def __init__(self, CP: structs.CarParams, CP_SP: structs.CarParamsSP):
|
||||||
|
super().__init__(CP, CP_SP)
|
||||||
|
|
||||||
|
def update_mads(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None:
|
||||||
|
cp = can_parsers[Bus.pt]
|
||||||
|
|
||||||
|
self.prev_lkas_button = self.lkas_button
|
||||||
|
self.lkas_button = cp.vl["PCM_BUTTONS"]["LKAS_ON_BTN"]
|
||||||
@@ -47,6 +47,9 @@ class ModularAssistiveDrivingSystem:
|
|||||||
self.allow_always = True
|
self.allow_always = True
|
||||||
if self.CP.brand == "tesla":
|
if self.CP.brand == "tesla":
|
||||||
self.allow_always = True
|
self.allow_always = True
|
||||||
|
if self.CP.brand == "byd":
|
||||||
|
# BYD has a dedicated LKAS steering wheel button
|
||||||
|
self.allow_always = True
|
||||||
|
|
||||||
if self.CP.brand in MADS_NO_ACC_MAIN_BUTTON:
|
if self.CP.brand in MADS_NO_ACC_MAIN_BUTTON:
|
||||||
self.no_main_cruise = True
|
self.no_main_cruise = True
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
import os
|
||||||
|
import hashlib
|
||||||
|
import opendbc
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
PREFIX = "arm-none-eabi-"
|
||||||
|
BUILDER = "DEV"
|
||||||
|
|
||||||
|
common_flags = []
|
||||||
|
|
||||||
|
if os.getenv("RELEASE"):
|
||||||
|
BUILD_TYPE = "RELEASE"
|
||||||
|
cert_fn = os.getenv("CERT")
|
||||||
|
assert cert_fn is not None, 'No certificate file specified. Please set CERT env variable'
|
||||||
|
assert os.path.exists(cert_fn), 'Certificate file not found. Please specify absolute path'
|
||||||
|
else:
|
||||||
|
BUILD_TYPE = "DEBUG"
|
||||||
|
cert_fn = File("./board/certs/debug").srcnode().relpath
|
||||||
|
common_flags += ["-DALLOW_DEBUG"]
|
||||||
|
|
||||||
|
if os.getenv("DEBUG"):
|
||||||
|
common_flags += ["-DDEBUG"]
|
||||||
|
|
||||||
|
def objcopy(source, target, env, for_signature):
|
||||||
|
return '$OBJCOPY -O binary %s %s' % (source[0], target[0])
|
||||||
|
|
||||||
|
def get_version(builder, build_type):
|
||||||
|
try:
|
||||||
|
git = subprocess.check_output(["git", "rev-parse", "--short=8", "HEAD"], encoding='utf8').strip()
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
git = "unknown"
|
||||||
|
return f"{builder}-{git}-{build_type}"
|
||||||
|
|
||||||
|
def get_key_header(name):
|
||||||
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
|
public_fn = File(f'./board/certs/{name}.pub').srcnode().get_path()
|
||||||
|
with open(public_fn) as f:
|
||||||
|
rsa = RSA.importKey(f.read())
|
||||||
|
assert(rsa.size_in_bits() == 1024)
|
||||||
|
|
||||||
|
rr = pow(2**1024, 2, rsa.n)
|
||||||
|
n0inv = 2**32 - pow(rsa.n, -1, 2**32)
|
||||||
|
|
||||||
|
r = [
|
||||||
|
f"RSAPublicKey {name}_rsa_key = {{",
|
||||||
|
f" .len = 0x20,",
|
||||||
|
f" .n0inv = {n0inv}U,",
|
||||||
|
f" .n = {to_c_uint32(rsa.n)},",
|
||||||
|
f" .rr = {to_c_uint32(rr)},",
|
||||||
|
f" .exponent = {rsa.e},",
|
||||||
|
f"}};",
|
||||||
|
]
|
||||||
|
return r
|
||||||
|
|
||||||
|
def to_c_uint32(x):
|
||||||
|
nums = []
|
||||||
|
for _ in range(0x20):
|
||||||
|
nums.append(x % (2**32))
|
||||||
|
x //= (2**32)
|
||||||
|
return "{" + 'U,'.join(map(str, nums)) + "U}"
|
||||||
|
|
||||||
|
|
||||||
|
def build_project(project_name, project, main, extra_flags):
|
||||||
|
project_dir = Dir(f'./board/obj/{project_name}/')
|
||||||
|
|
||||||
|
flags = project["FLAGS"] + extra_flags + common_flags + [
|
||||||
|
"-Wall",
|
||||||
|
"-Wextra",
|
||||||
|
"-Wstrict-prototypes",
|
||||||
|
"-Werror",
|
||||||
|
"-mlittle-endian",
|
||||||
|
"-mthumb",
|
||||||
|
"-nostdlib",
|
||||||
|
"-fno-builtin",
|
||||||
|
"-std=gnu11",
|
||||||
|
"-fmax-errors=1",
|
||||||
|
f"-T{File(project['LINKER_SCRIPT']).srcnode().relpath}",
|
||||||
|
"-fsingle-precision-constant",
|
||||||
|
"-Os",
|
||||||
|
"-g",
|
||||||
|
]
|
||||||
|
|
||||||
|
env = Environment(
|
||||||
|
ENV=os.environ,
|
||||||
|
CC=PREFIX + 'gcc',
|
||||||
|
AS=PREFIX + 'gcc',
|
||||||
|
OBJCOPY=PREFIX + 'objcopy',
|
||||||
|
OBJDUMP=PREFIX + 'objdump',
|
||||||
|
OBJPREFIX=project_dir,
|
||||||
|
CFLAGS=flags,
|
||||||
|
ASFLAGS=flags,
|
||||||
|
LINKFLAGS=flags,
|
||||||
|
CPPPATH=[Dir("./"), "./board/stm32h7/inc", opendbc.INCLUDE_PATH],
|
||||||
|
ASCOM="$AS $ASFLAGS -o $TARGET -c $SOURCES",
|
||||||
|
BUILDERS={
|
||||||
|
'Objcopy': Builder(generator=objcopy, suffix='.bin', src_suffix='.elf')
|
||||||
|
},
|
||||||
|
tools=["default", "compilation_db"],
|
||||||
|
)
|
||||||
|
|
||||||
|
startup = env.Object(project["STARTUP_FILE"])
|
||||||
|
|
||||||
|
# Build bootstub
|
||||||
|
bs_env = env.Clone()
|
||||||
|
bs_env.Append(CFLAGS="-DBOOTSTUB", ASFLAGS="-DBOOTSTUB", LINKFLAGS="-DBOOTSTUB")
|
||||||
|
bs_elf = bs_env.Program(f"{project_dir}/bootstub.elf", [
|
||||||
|
startup,
|
||||||
|
"./board/crypto/rsa.c",
|
||||||
|
"./board/crypto/sha.c",
|
||||||
|
"./board/bootstub.c",
|
||||||
|
])
|
||||||
|
bs_env.Objcopy(f"./board/obj/bootstub.{project_name}.bin", bs_elf)
|
||||||
|
|
||||||
|
# Build + sign main (aka app)
|
||||||
|
main_elf = env.Program(f"{project_dir}/main.elf", [
|
||||||
|
startup,
|
||||||
|
main
|
||||||
|
], LINKFLAGS=[f"-Wl,--section-start,.isr_vector={project['APP_START_ADDRESS']}"] + flags)
|
||||||
|
main_bin = env.Objcopy(f"{project_dir}/main.bin", main_elf)
|
||||||
|
sign_py = File(f"./board/crypto/sign.py").srcnode().relpath
|
||||||
|
env.Command(f"./board/obj/{project_name}.bin.signed", main_bin, f"SETLEN=1 {sign_py} $SOURCE $TARGET {cert_fn}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
base_project_h7 = {
|
||||||
|
"STARTUP_FILE": "./board/stm32h7/startup_stm32h7x5xx.s",
|
||||||
|
"LINKER_SCRIPT": "./board/stm32h7/stm32h7x5_flash.ld",
|
||||||
|
"APP_START_ADDRESS": "0x8020000",
|
||||||
|
"FLAGS": [
|
||||||
|
"-mcpu=cortex-m7",
|
||||||
|
"-mhard-float",
|
||||||
|
"-DSTM32H7",
|
||||||
|
"-DSTM32H725xx",
|
||||||
|
"-Iboard/stm32h7/inc",
|
||||||
|
"-mfpu=fpv5-d16",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Common autogenerated includes
|
||||||
|
with open("board/obj/gitversion.h", "w") as f:
|
||||||
|
version = get_version(BUILDER, BUILD_TYPE)
|
||||||
|
f.write(f'extern const uint8_t gitversion[{len(version)+1}];\n')
|
||||||
|
f.write(f'const uint8_t gitversion[{len(version)+1}] = "{version}";\n')
|
||||||
|
|
||||||
|
with open("board/obj/version", "w") as f:
|
||||||
|
f.write(f'{get_version(BUILDER, BUILD_TYPE)}')
|
||||||
|
|
||||||
|
certs = [get_key_header(n) for n in ["debug", "release"]]
|
||||||
|
with open("board/obj/cert.h", "w") as f:
|
||||||
|
for cert in certs:
|
||||||
|
f.write("\n".join(cert) + "\n")
|
||||||
|
|
||||||
|
# Packet version defines: SHA hash of the struct header files
|
||||||
|
def version_hash(path):
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
# Normalize line endings on Windows
|
||||||
|
return int.from_bytes(hashlib.sha256(f.read().replace(b'\r', b'')).digest()[:4], 'little')
|
||||||
|
hh, ch, jh = version_hash("board/health.h"), version_hash(os.path.join(opendbc.INCLUDE_PATH, "opendbc/safety/can.h")), version_hash("board/jungle/jungle_health.h")
|
||||||
|
common_flags += [f"-DHEALTH_PACKET_VERSION=0x{hh:08X}U", f"-DCAN_PACKET_VERSION_HASH=0x{ch:08X}U",
|
||||||
|
f"-DJUNGLE_HEALTH_PACKET_VERSION=0x{jh:08X}U"]
|
||||||
|
|
||||||
|
# panda fw
|
||||||
|
build_project("panda_h7", base_project_h7, "./board/main.c", [])
|
||||||
|
|
||||||
|
# panda jungle fw
|
||||||
|
flags = [
|
||||||
|
"-DPANDA_JUNGLE",
|
||||||
|
]
|
||||||
|
build_project("panda_jungle_h7", base_project_h7, "./board/jungle/main.c", flags)
|
||||||
|
|
||||||
|
# body fw
|
||||||
|
build_project("body_h7", base_project_h7, "./board/body/main.c", ["-DPANDA_BODY"])
|
||||||
|
|
||||||
|
# test files
|
||||||
|
SConscript('tests/libpanda/SConscript')
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
env = Environment(
|
||||||
|
COMPILATIONDB_USE_ABSPATH=True,
|
||||||
|
tools=["default", "compilation_db"],
|
||||||
|
)
|
||||||
|
|
||||||
|
SetOption('num_jobs', max(1, int((os.cpu_count() or 1)-1)))
|
||||||
|
|
||||||
|
env.CompilationDatabase("compile_commands.json")
|
||||||
|
|
||||||
|
# panda fw & test files
|
||||||
|
SConscript('SConscript')
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
|||||||
extern const uint8_t gitversion[18];
|
extern const uint8_t gitversion[19];
|
||||||
const uint8_t gitversion[18] = "DEV-unknown-DEBUG";
|
const uint8_t gitversion[19] = "DEV-de77c89c-DEBUG";
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
DEV-unknown-DEBUG
|
DEV-de77c89c-DEBUG
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
LICENSE
|
LICENSE
|
||||||
LICENSE.md
|
LICENSE.md
|
||||||
README.md
|
README.md
|
||||||
|
__init__.py
|
||||||
pyproject.toml
|
pyproject.toml
|
||||||
./__init__.py
|
./__init__.py
|
||||||
./board/__init__.py
|
./board/__init__.py
|
||||||
@@ -22,8 +23,27 @@ pyproject.toml
|
|||||||
./python/spi.py
|
./python/spi.py
|
||||||
./python/usb.py
|
./python/usb.py
|
||||||
./python/utils.py
|
./python/utils.py
|
||||||
|
board/__init__.py
|
||||||
|
board/flash.py
|
||||||
|
board/health.h
|
||||||
|
board/recover.py
|
||||||
|
board/body/__init__.py
|
||||||
|
board/body/flash.py
|
||||||
|
board/jungle/__init__.py
|
||||||
|
board/jungle/flash.py
|
||||||
|
board/jungle/jungle_health.h
|
||||||
|
board/jungle/recover.py
|
||||||
pandacan.egg-info/PKG-INFO
|
pandacan.egg-info/PKG-INFO
|
||||||
pandacan.egg-info/SOURCES.txt
|
pandacan.egg-info/SOURCES.txt
|
||||||
pandacan.egg-info/dependency_links.txt
|
pandacan.egg-info/dependency_links.txt
|
||||||
pandacan.egg-info/requires.txt
|
pandacan.egg-info/requires.txt
|
||||||
pandacan.egg-info/top_level.txt
|
pandacan.egg-info/top_level.txt
|
||||||
|
python/__init__.py
|
||||||
|
python/base.py
|
||||||
|
python/constants.py
|
||||||
|
python/dfu.py
|
||||||
|
python/serial.py
|
||||||
|
python/socketpanda.py
|
||||||
|
python/spi.py
|
||||||
|
python/usb.py
|
||||||
|
python/utils.py
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import opendbc
|
||||||
|
|
||||||
|
env = Environment(
|
||||||
|
CFLAGS=[
|
||||||
|
'-nostdlib',
|
||||||
|
'-fno-builtin',
|
||||||
|
'-std=gnu11',
|
||||||
|
'-Wfatal-errors',
|
||||||
|
'-Wno-pointer-to-int-cast',
|
||||||
|
],
|
||||||
|
CPPPATH=[".", "../../", "../../board/", opendbc.INCLUDE_PATH],
|
||||||
|
)
|
||||||
|
|
||||||
|
panda = env.SharedObject("panda.os", "panda.c")
|
||||||
|
libpanda = env.SharedLibrary("libpanda.so", [panda])
|
||||||
Binary file not shown.
Reference in new issue
Block a user