from opendbc.can.packer import CANPacker from common.realtime import DT_CTRL from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons from selfdrive.car.chrysler.values import CAR, RAM_CARS, CarControllerParams class CarController: def __init__(self, dbc_name, CP, VM): self.CP = CP self.apply_steer_last = 0 self.frame = 0 self.hud_count = 0 self.last_lkas_falling_edge = 0 self.lkas_control_bit_prev = False self.last_button_frame = 0 self.packer = CANPacker(dbc_name) self.params = CarControllerParams(CP) def update(self, CC, CS): can_sends = [] lkas_active = CC.latActive and self.lkas_control_bit_prev # cruise buttons if (self.frame - self.last_button_frame)*DT_CTRL > 0.05: das_bus = 2 if self.CP.carFingerprint in RAM_CARS else 0 # ACC cancellation if CC.cruiseControl.cancel: self.last_button_frame = self.frame can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, cancel=True)) # ACC resume from standstill elif CC.cruiseControl.resume: self.last_button_frame = self.frame can_sends.append(create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, resume=True)) # HUD alerts if self.frame % 25 == 0: if CS.lkas_car_model != -1: can_sends.append(create_lkas_hud(self.packer, self.CP, lkas_active, CC.hudControl.visualAlert, self.hud_count, CS.lkas_car_model, CS.auto_high_beam)) self.hud_count += 1 # steering if self.frame % 2 == 0: # TODO: can we make this more sane? why is it different for all the cars? lkas_control_bit = self.lkas_control_bit_prev if CS.out.vEgo > self.CP.minSteerSpeed: lkas_control_bit = True elif self.CP.carFingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): if CS.out.vEgo < (self.CP.minSteerSpeed - 3.0): lkas_control_bit = False elif self.CP.carFingerprint in RAM_CARS: if CS.out.vEgo < (self.CP.minSteerSpeed - 0.5): lkas_control_bit = False # EPS faults if LKAS re-enables too quickly lkas_control_bit = lkas_control_bit and (self.frame - self.last_lkas_falling_edge > 200) if not lkas_control_bit and self.lkas_control_bit_prev: self.last_lkas_falling_edge = self.frame self.lkas_control_bit_prev = lkas_control_bit # steer torque new_steer = int(round(CC.actuators.steer * self.params.STEER_MAX)) apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params) if not lkas_active or not lkas_control_bit: apply_steer = 0 self.apply_steer_last = apply_steer can_sends.append(create_lkas_command(self.packer, self.CP, int(apply_steer), lkas_control_bit)) self.frame += 1 new_actuators = CC.actuators.copy() new_actuators.steer = self.apply_steer_last / self.params.STEER_MAX return new_actuators, can_sends