openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
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

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"