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.
104 lines
4.4 KiB
104 lines
4.4 KiB
from opendbc.car.ford.values import FordSafetyFlags
|
|
from opendbc.car.hyundai.values import HyundaiSafetyFlags
|
|
from opendbc.car.toyota.values import ToyotaSafetyFlags
|
|
from opendbc.car.structs import CarParams
|
|
from opendbc.safety.tests.libsafety import libsafety_py
|
|
|
|
def to_signed(d, bits):
|
|
ret = d
|
|
if d >= (1 << (bits - 1)):
|
|
ret = d - (1 << bits)
|
|
return ret
|
|
|
|
def is_steering_msg(mode, param, addr):
|
|
ret = False
|
|
if mode in (CarParams.SafetyModel.hondaNidec, CarParams.SafetyModel.hondaBosch):
|
|
ret = (addr == 0xE4) or (addr == 0x194) or (addr == 0x33D) or (addr == 0x33DA) or (addr == 0x33DB)
|
|
elif mode == CarParams.SafetyModel.toyota:
|
|
ret = addr == (0x191 if param & ToyotaSafetyFlags.LTA else 0x2E4)
|
|
elif mode == CarParams.SafetyModel.gm:
|
|
ret = addr == 384
|
|
elif mode in (CarParams.SafetyModel.hyundai, CarParams.SafetyModel.hyundaiLegacy):
|
|
ret = addr == 832
|
|
elif mode == CarParams.SafetyModel.hyundaiCanfd:
|
|
ret = addr == (0x110 if param & HyundaiSafetyFlags.CANFD_LKA_STEERING_ALT else
|
|
0x50 if param & HyundaiSafetyFlags.CANFD_LKA_STEERING else
|
|
0x12A)
|
|
elif mode == CarParams.SafetyModel.chrysler:
|
|
ret = addr == 0x292
|
|
elif mode == CarParams.SafetyModel.subaru:
|
|
ret = addr == 0x122
|
|
elif mode == CarParams.SafetyModel.ford:
|
|
ret = addr == 0x3d6 if param & FordSafetyFlags.CANFD else addr == 0x3d3
|
|
elif mode == CarParams.SafetyModel.nissan:
|
|
ret = addr == 0x169
|
|
elif mode == CarParams.SafetyModel.rivian:
|
|
ret = addr == 0x120
|
|
elif mode == CarParams.SafetyModel.tesla:
|
|
ret = addr == 0x488
|
|
return ret
|
|
|
|
def get_steer_value(mode, param, to_send):
|
|
# TODO: use CANParser
|
|
torque, angle = 0, 0
|
|
if mode in (CarParams.SafetyModel.hondaNidec, CarParams.SafetyModel.hondaBosch):
|
|
torque = (to_send.data[0] << 8) | to_send.data[1]
|
|
torque = to_signed(torque, 16)
|
|
elif mode == CarParams.SafetyModel.toyota:
|
|
if param & ToyotaSafetyFlags.LTA:
|
|
angle = (to_send.data[1] << 8) | to_send.data[2]
|
|
angle = to_signed(angle, 16)
|
|
else:
|
|
torque = (to_send.data[1] << 8) | (to_send.data[2])
|
|
torque = to_signed(torque, 16)
|
|
elif mode == CarParams.SafetyModel.gm:
|
|
torque = ((to_send.data[0] & 0x7) << 8) | to_send.data[1]
|
|
torque = to_signed(torque, 11)
|
|
elif mode in (CarParams.SafetyModel.hyundai, CarParams.SafetyModel.hyundaiLegacy):
|
|
torque = (((to_send.data[3] & 0x7) << 8) | to_send.data[2]) - 1024
|
|
elif mode == CarParams.SafetyModel.hyundaiCanfd:
|
|
torque = ((to_send.data[5] >> 1) | (to_send.data[6] & 0xF) << 7) - 1024
|
|
elif mode == CarParams.SafetyModel.chrysler:
|
|
torque = (((to_send.data[0] & 0x7) << 8) | to_send.data[1]) - 1024
|
|
elif mode == CarParams.SafetyModel.subaru:
|
|
torque = ((to_send.data[3] & 0x1F) << 8) | to_send.data[2]
|
|
torque = -to_signed(torque, 13)
|
|
elif mode == CarParams.SafetyModel.ford:
|
|
if param & FordSafetyFlags.CANFD:
|
|
angle = ((to_send.data[2] << 3) | (to_send.data[3] >> 5)) - 1000
|
|
else:
|
|
angle = ((to_send.data[0] << 3) | (to_send.data[1] >> 5)) - 1000
|
|
elif mode == CarParams.SafetyModel.nissan:
|
|
angle = (to_send.data[0] << 10) | (to_send.data[1] << 2) | (to_send.data[2] >> 6)
|
|
angle = -angle + (1310 * 100)
|
|
elif mode == CarParams.SafetyModel.rivian:
|
|
torque = ((to_send.data[2] << 3) | (to_send.data[3] >> 5)) - 1024
|
|
elif mode == CarParams.SafetyModel.tesla:
|
|
angle = (((to_send.data[0] & 0x7F) << 8) | (to_send.data[1])) - 16384 # ceil(1638.35/0.1)
|
|
return torque, angle
|
|
|
|
def package_can_msg(msg):
|
|
return libsafety_py.make_CANPacket(msg.address, msg.src % 4, msg.dat)
|
|
|
|
def init_segment(safety, msgs, mode, param):
|
|
sendcan = (msg for msg in msgs if msg.which() == 'sendcan')
|
|
steering_msgs = (can for msg in sendcan for can in msg.sendcan if is_steering_msg(mode, param, can.address))
|
|
|
|
msg = next(steering_msgs, None)
|
|
if msg is None:
|
|
print("no steering msgs found!")
|
|
return
|
|
|
|
to_send = package_can_msg(msg)
|
|
torque, angle = get_steer_value(mode, param, to_send)
|
|
if torque != 0:
|
|
safety.set_controls_allowed(1)
|
|
safety.set_desired_torque_last(torque)
|
|
safety.set_rt_torque_last(torque)
|
|
safety.set_torque_meas(torque, torque)
|
|
safety.set_torque_driver(torque, torque)
|
|
elif angle != 0:
|
|
safety.set_controls_allowed(1)
|
|
safety.set_desired_angle_last(angle)
|
|
safety.set_angle_meas(angle, angle)
|
|
assert safety.safety_tx_hook(to_send), "failed to initialize panda safety for segment"
|
|
|