""" Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ import cereal.messaging as messaging from cereal import log, custom from opendbc.car import structs from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.sunnypilot.selfdrive.controls.lib.param_store import ParamStore from openpilot.sunnypilot.selfdrive.controls.lib.blinker_pause_lateral import BlinkerPauseLateral class ControlsExt: def __init__(self, CP: structs.CarParams, params: Params): self.CP = CP self.params = params self.blinker_pause_lateral = BlinkerPauseLateral() self.param_store = ParamStore(self.CP) self.get_params_sp() cloudlog.info("controlsd_ext is waiting for CarParamsSP") self.CP_SP = messaging.log_from_bytes(params.get("CarParamsSP", block=True), custom.CarParamsSP) cloudlog.info("controlsd_ext got CarParamsSP") self.sm_services_ext = ['radarState', 'selfdriveStateSP'] self.pm_services_ext = ['carControlSP'] def get_params_sp(self) -> None: self.param_store.update(self.params) self.blinker_pause_lateral.get_params() def get_lat_active(self, sm: messaging.SubMaster) -> bool: if self.blinker_pause_lateral.update(sm['carState']): return False ss_sp = sm['selfdriveStateSP'] if ss_sp.mads.available: return bool(ss_sp.mads.active) # MADS not available, use stock state to engage return bool(sm['selfdriveState'].active) @staticmethod def get_lead_data(ld: log.RadarState.LeadData) -> dict: return { "dRel": ld.dRel, "yRel": ld.yRel, "vRel": ld.vRel, "aRel": ld.aRel, "vLead": ld.vLead, "dPath": ld.dPath, "vLat": ld.vLat, "vLeadK": ld.vLeadK, "aLeadK": ld.aLeadK, "fcw": ld.fcw, "status": ld.status, "aLeadTau": ld.aLeadTau, "modelProb": ld.modelProb, "radar": ld.radar, "radarTrackId": ld.radarTrackId, } def state_control_ext(self, sm: messaging.SubMaster) -> custom.CarControlSP: CC_SP = custom.CarControlSP.new_message() CC_SP.leadOne = self.get_lead_data(sm['radarState'].leadOne) CC_SP.leadTwo = self.get_lead_data(sm['radarState'].leadTwo) # MADS state CC_SP.mads = sm['selfdriveStateSP'].mads CC_SP.params = self.param_store.param_list CC_SP.intelligentCruiseButtonManagement = sm['selfdriveStateSP'].intelligentCruiseButtonManagement return CC_SP @staticmethod def publish_ext(CC_SP: custom.CarControlSP, sm: messaging.SubMaster, pm: messaging.PubMaster) -> None: cc_sp_send = messaging.new_message('carControlSP') cc_sp_send.valid = sm['carState'].canValid cc_sp_send.carControlSP = CC_SP pm.send('carControlSP', cc_sp_send) def run_ext(self, sm: messaging.SubMaster, pm: messaging.PubMaster) -> None: CC_SP = self.state_control_ext(sm) self.publish_ext(CC_SP, sm, pm)