#!/usr/bin/env python3 from cereal import car from opendbc.can.parser import CANParser from openpilot.selfdrive.car.tesla.values import CAR, DBC, CANBUS from openpilot.selfdrive.car.interfaces import RadarInterfaceBase class RadarInterface(RadarInterfaceBase): def __init__(self, CP): super().__init__(CP) self.CP = CP if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: messages = [('RadarStatus', 16)] self.num_points = 40 self.trigger_msg = 1119 else: messages = [('TeslaRadarSguInfo', 10)] self.num_points = 32 self.trigger_msg = 878 for i in range(self.num_points): messages.extend([ (f'RadarPoint{i}_A', 16), (f'RadarPoint{i}_B', 16), ]) self.rcp = CANParser(DBC[CP.carFingerprint]['radar'], messages, CANBUS.radar) self.updated_messages = set() self.track_id = 0 def update(self, can_strings): if self.rcp is None: return super().update(None) values = self.rcp.update_strings(can_strings) self.updated_messages.update(values) if self.trigger_msg not in self.updated_messages: return None ret = car.RadarData.new_message() # Errors errors = [] if not self.rcp.can_valid: errors.append('canError') if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: radar_status = self.rcp.vl['RadarStatus'] if radar_status['sensorBlocked'] or radar_status['shortTermUnavailable'] or radar_status['vehDynamicsError']: errors.append('fault') else: radar_status = self.rcp.vl['TeslaRadarSguInfo'] if radar_status['RADC_HWFail'] or radar_status['RADC_SGUFail'] or radar_status['RADC_SensorDirty']: errors.append('fault') ret.errors = errors # Radar tracks for i in range(self.num_points): msg_a = self.rcp.vl[f'RadarPoint{i}_A'] msg_b = self.rcp.vl[f'RadarPoint{i}_B'] # Make sure msg A and B are together if msg_a['Index'] != msg_b['Index2']: continue # Check if it's a valid track if not msg_a['Tracked']: if i in self.pts: del self.pts[i] continue # New track! if i not in self.pts: self.pts[i] = car.RadarData.RadarPoint.new_message() self.pts[i].trackId = self.track_id self.track_id += 1 # Parse track data self.pts[i].dRel = msg_a['LongDist'] self.pts[i].yRel = msg_a['LatDist'] self.pts[i].vRel = msg_a['LongSpeed'] self.pts[i].aRel = msg_a['LongAccel'] self.pts[i].yvRel = msg_b['LatSpeed'] self.pts[i].measured = bool(msg_a['Meas']) ret.points = list(self.pts.values()) self.updated_messages.clear() return ret