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 "