def status_monitor(): # use driverState socker to drive timing. driverState = messaging.sub_sock('driverState', addr=args.addr, conflate=True) sm = messaging.SubMaster(['carState', 'dMonitoringState'], addr=args.addr) steering_status = SteeringStatus() while messaging.recv_one(driverState): try: sm.update() # Get status and steering pressed value from our own instance of SteeringStatus steering_status.update(Events(), sm['carState'].steeringPressed, sm['carState'].cruiseState.enabled, sm['carState'].standstill) steering_value = int(math.floor(steering_status.current_steering_pressed() * 9.99)) plot_list = ['-' for i in range(10)] plot_list[steering_value] = '+' # Get events from `dMonitoringState` events = sm['dMonitoringState'].events event_name = events[0].name if len(events) else "None" # Print output sys.stdout.write(f'\rsteering Pressed -> {"".join(plot_list)} | state: {steering_status.steering_state.name} | event: {event_name}') sys.stdout.flush() except Exception as e: print(e)
def cruise_solutions(self, enabled, v_ego, a_ego, v_cruise, sm): # Update controllers self.vision_turn_controller.update(enabled, v_ego, a_ego, v_cruise, sm) self.events = Events() self.speed_limit_controller.update(enabled, v_ego, a_ego, sm, v_cruise, self.events) self.turn_speed_controller.update(enabled, v_ego, a_ego, sm) # Pick solution with lowest acceleration target. a_solutions = {'cruise': float("inf")} v_solutions = {'cruise': v_cruise} if self.vision_turn_controller.is_active: a_solutions['turn'] = self.vision_turn_controller.a_target v_solutions['turn'] = self.vision_turn_controller.v_turn if self.speed_limit_controller.is_active: a_solutions['limit'] = self.speed_limit_controller.a_target v_solutions[ 'limit'] = self.speed_limit_controller.speed_limit_offseted if self.turn_speed_controller.is_active: a_solutions['turnlimit'] = self.turn_speed_controller.a_target v_solutions['turnlimit'] = self.turn_speed_controller.speed_limit source = min(v_solutions, key=v_solutions.get) return source, a_solutions[source], v_solutions[source]
def __init__(self, CP, init_v=0.0, init_a=0.0): self.CP = CP self.mpc = LongitudinalMpc() self.fcw = False self.v_desired = init_v self.a_desired = init_a self.alpha = np.exp(-DT_MDL / 2.0) self.v_desired_trajectory = np.zeros(CONTROL_N) self.a_desired_trajectory = np.zeros(CONTROL_N) self.j_desired_trajectory = np.zeros(CONTROL_N) # dp self.dp_accel_profile_ctrl = False self.dp_accel_profile = DP_ACCEL_ECO self.dp_following_profile_ctrl = False self.dp_following_profile = 2 self.dp_following_dist = 1.8 # default val self.cruise_source = 'cruise' self.vision_turn_controller = VisionTurnController(CP) self.speed_limit_controller = SpeedLimitController() self.events = Events() self.turn_speed_controller = TurnSpeedController()
def update_curv(self, CS, sm, model_speed): wait_time_cmd = 0 set_speed = self.cruise_set_speed_kph # 2. 커브 감속. #if self.cruise_set_speed_kph >= 100: if CS.out.cruiseState.modeSel == 1 and Events().names not in [EventName.laneChangeManual, EventName.laneChange] and not self.map_decel_only: if model_speed < 60 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.275) self.seq_step_debug = "커브감속-4" wait_time_cmd = 30 elif model_speed < 70 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.225) self.seq_step_debug = "커브감속-3" wait_time_cmd = 50 elif model_speed < 80 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.175) self.seq_step_debug = "커브감속-2" wait_time_cmd = 70 elif model_speed < 90 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.125) self.seq_step_debug = "커브감속-1" wait_time_cmd = 90 return wait_time_cmd, set_speed
def update_curv(self, CS, sm, model_speed): wait_time_cmd = 0 set_speed = self.cruise_set_speed_kph # 2. 커브 감속. #if self.cruise_set_speed_kph >= 100: if int(Params().get('LimitSetSpeedCurv')) == 1 and Events().names not in [EventName.laneChangeManual, EventName.laneChange]: if model_speed < 60 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.2) self.seq_step_debug = "커브감속-4" wait_time_cmd = 70 elif model_speed < 70 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.15) self.seq_step_debug = "커브감속-3" wait_time_cmd = 80 elif model_speed < 80 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.1) self.seq_step_debug = "커브감속-2" wait_time_cmd = 90 elif model_speed < 90 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.05) self.seq_step_debug = "커브감속-1" wait_time_cmd = 100 return wait_time_cmd, set_speed
def update_curv(self, CS, sm, curve_speed): wait_time_cmd = 0 set_speed = self.cruise_set_speed_kph # 2. 커브 감속. #if self.cruise_set_speed_kph >= 100: if CS.out.cruiseState.modeSel == 1 and Events().names not in [EventName.laneChangeManual, EventName.laneChange] and not (CS.left_blinker_flash or CS.right_blinker_flash)and not self.map_decel_only: if curve_speed < 25 and int(CS.clu_Vanz) >= 40 and CS.lead_distance >= 15: set_speed = min(45, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.3)) self.seq_step_debug = "커브감속-5" wait_time_cmd = 8 elif curve_speed < 40 and int(CS.clu_Vanz) >= 40 and CS.lead_distance >= 15: set_speed = min(55, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.25)) self.seq_step_debug = "커브감속-4" wait_time_cmd = 8 elif curve_speed < 60 and int(CS.clu_Vanz) >= 40 and CS.lead_distance >= 15: set_speed = min(65, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.2)) self.seq_step_debug = "커브감속-3" wait_time_cmd = 8 elif curve_speed < 75 and int(CS.clu_Vanz) >= 40 and CS.lead_distance >= 15: set_speed = min(75, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.15)) self.seq_step_debug = "커브감속-2" wait_time_cmd = 8 elif curve_speed < 90 and int(CS.clu_Vanz) >= 40 and CS.lead_distance >= 15: set_speed = min(85, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.1)) self.seq_step_debug = "커브감속-1" wait_time_cmd = 8 return wait_time_cmd, set_speed
def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True): # pylint: disable=dangerous-default-value events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) #if cs_out.seatbeltUnlatched: #events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and cs_out.gearShifter not in extra_gears and cs_out.cruiseState.enabled: events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse and cs_out.cruiseState.enabled: events.add(EventName.reverseGear) if not cs_out.cruiseState.available and cs_out.cruiseState.enabled: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.gasPressed and self.CP.openpilotLongitudinalControl: events.add(EventName.gasPressed) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) if cs_out.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) if cs_out.steerError: events.add(EventName.steerUnavailable) #elif cs_out.steerWarning: #events.add(EventName.steerTempUnavailable) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # Optionally allow to press gas at zero speed to resume. # e.g. Chrysler does not spam the resume button yet, so resuming with gas is handy. FIXME! if self.CP.openpilotLongitudinalControl: if (cs_out.gasPressed and (not self.CS.out.gasPressed) and cs_out.vEgo > gas_resume_speed) or \ (cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)): events.add(EventName.pedalPressed) # we engage when pcm is active (rising edge) #if pcm_enable: # if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: # events.add(EventName.pcmEnable) # elif not cs_out.cruiseState.enabled: # events.add(EventName.pcmDisable) if not pcm_enable: pass elif cs_out.cruiseState.enabled != self.cruise_enabled_prev: if cs_out.cruiseState.enabled: events.add(EventName.pcmEnable) else: events.add(EventName.pcmDisable) self.cruise_enabled_prev = cs_out.cruiseState.enabled return events
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True): events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and ( extra_gears is None or cs_out.gearShifter not in extra_gears): events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) if cs_out.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) if cs_out.brakeHoldActive and self.CP.openpilotLongitudinalControl: events.add(EventName.brakeHold) if cs_out.parkingBrake: events.add(EventName.parkBrake) if cs_out.accFaulted: events.add(EventName.accFaulted) # Handle permanent and temporary steering faults self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 if cs_out.steerFaultTemporary: # if the user overrode recently, show a less harsh alert if self.silent_steer_warning or cs_out.standstill or self.steering_unpressed < int( 1.5 / DT_CTRL): self.silent_steer_warning = True events.add(EventName.steerTempUnavailableSilent) else: events.add(EventName.steerTempUnavailable) else: self.silent_steer_warning = False if cs_out.steerFaultPermanent: events.add(EventName.steerUnavailable) # we engage when pcm is active (rising edge) # enabling can optionally be blocked by the car interface if pcm_enable: if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled and allow_enable: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True): events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and ( extra_gears is None or cs_out.gearShifter not in extra_gears): events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.gasPressed: events.add(EventName.gasPressed) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) if cs_out.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) if cs_out.brakeHoldActive and self.CP.openpilotLongitudinalControl: events.add(EventName.brakeHold) # Handle permanent and temporary steering faults self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 if cs_out.steerWarning: # if the user overrode recently, show a less harsh alert if self.silent_steer_warning or cs_out.standstill or self.steering_unpressed < int( 1.5 / DT_CTRL): self.silent_steer_warning = True events.add(EventName.steerTempUnavailableSilent) else: events.add(EventName.steerTempUnavailable) else: self.silent_steer_warning = False if cs_out.steerError: events.add(EventName.steerUnavailable) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # TODO: JJS : Fix gas press correctly (with an option) #if (cs_out.gasPressed and not self.CS.out.gasPressed) or \ if (cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)): events.add(EventName.pedalPressed) # we engage when pcm is active (rising edge) if pcm_enable: if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def cycle_alerts(duration=200, is_metric=False): alerts = list(EVENTS.keys()) print(alerts) alerts = [ EventName.preDriverDistracted, EventName.promptDriverDistracted, EventName.driverDistracted ] CP = CarInterface.get_params("HONDA CIVIC 2016 TOURING") sm = messaging.SubMaster([ 'deviceState', 'pandaState', 'roadCameraState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman' ]) controls_state = messaging.pub_sock('controlsState') deviceState = messaging.pub_sock('deviceState') idx, last_alert_millis = 0, 0 events = Events() AM = AlertManager() frame = 0 while 1: if frame % duration == 0: idx = (idx + 1) % len(alerts) events.clear() events.add(alerts[idx]) current_alert_types = [ ET.PERMANENT, ET.USER_DISABLE, ET.IMMEDIATE_DISABLE, ET.SOFT_DISABLE, ET.PRE_ENABLE, ET.NO_ENTRY, ET.ENABLE, ET.WARNING ] a = events.create_alerts(current_alert_types, [CP, sm, is_metric]) AM.add_many(frame, a) AM.process_alerts(frame) dat = messaging.new_message() dat.init('controlsState') dat.controlsState.alertText1 = AM.alert_text_1 dat.controlsState.alertText2 = AM.alert_text_2 dat.controlsState.alertSize = AM.alert_size dat.controlsState.alertStatus = AM.alert_status dat.controlsState.alertBlinkingRate = AM.alert_rate dat.controlsState.alertType = AM.alert_type dat.controlsState.alertSound = AM.audible_alert controls_state.send(dat.to_bytes()) dat = messaging.new_message() dat.init('deviceState') dat.deviceState.started = True deviceState.send(dat.to_bytes()) frame += 1 time.sleep(0.01)
def setUp(self): CarInterface, CarController, CarState = interfaces["mock"] CP = CarInterface.get_params("mock") CI = CarInterface(CP, CarController, CarState) self.controlsd = Controls(CI=CI) self.controlsd.events = Events() self.controlsd.soft_disable_timer = int(SOFT_DISABLE_TIME / DT_CTRL) self.CS = car.CarState()
def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True): # pylint: disable=dangerous-default-value events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if self.dragonconf.dpGearCheck: if cs_out.gearShifter != GearShifter.drive and cs_out.gearShifter not in extra_gears: events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available and not self.dragonconf.dpAtl: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.gasPressed and not self.dragonconf.dpAllowGas and not self.dragonconf.dpAtl: events.add(EventName.gasPressed) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > self.dragonconf.dpMaxCtrlSpeed: events.add(EventName.speedTooHigh) if cs_out.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) if not self.dragonconf.dpLatCtrl: events.add(EventName.manualSteeringRequired) elif self.dragonconf.dpSteeringOnSignal and (cs_out.leftBlinker or cs_out.rightBlinker): events.add(EventName.manualSteeringRequiredBlinkersOn) elif cs_out.steerError: events.add(EventName.steerUnavailable) elif cs_out.steerWarning: events.add(EventName.steerTempUnavailable) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # Optionally allow to press gas at zero speed to resume. # e.g. Chrysler does not spam the resume button yet, so resuming with gas is handy. FIXME! if self.dragonconf.dpAtl: pass elif self.dragonconf.dpAllowGas: if cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill): events.add(EventName.pedalPressed) else: if (cs_out.gasPressed and (not self.CS.out.gasPressed) and cs_out.vEgo > gas_resume_speed) or \ (cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)): events.add(EventName.pedalPressed) # we engage when pcm is active (rising edge) if pcm_enable: if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def create_common_events(self, cs_out, extra_gears=None, gas_resume_speed=-1, pcm_enable=True): events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and (extra_gears is None or cs_out.gearShifter not in extra_gears): events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.gasPressed: events.add(EventName.gasPressed) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) if cs_out.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) self.steer_warning = self.steer_warning + 1 if cs_out.steerWarning else 0 self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 # Handle permanent and temporary steering faults if cs_out.steerError: events.add(EventName.steerUnavailable) elif cs_out.steerWarning: # only escalate to the harsher alert after the condition has # persisted for 0.5s and we're certain that the user isn't overriding if self.steering_unpressed > int(0.5/DT_CTRL) and self.steer_warning > int(0.5/DT_CTRL): events.add(EventName.steerTempUnavailable) else: events.add(EventName.steerTempUnavailableSilent) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # Optionally allow to press gas at zero speed to resume. # e.g. Chrysler does not spam the resume button yet, so resuming with gas is handy. FIXME! if (cs_out.gasPressed and (not self.CS.out.gasPressed) and cs_out.vEgo > gas_resume_speed) or \ (cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)): events.add(EventName.pedalPressed) # we engage when pcm is active (rising edge) if pcm_enable: if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def create_common_events(self, cs_out, extra_gears=None, gas_resume_speed=-1, pcm_enable=True): events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and ( extra_gears is None or cs_out.gearShifter not in extra_gears): events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) self.steer_warning = self.steer_warning + 1 if cs_out.steerWarning else 0 self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1 # Handle permanent and temporary steering faults if cs_out.steerError: events.add(EventName.steerUnavailable) elif cs_out.steerWarning: # only escalate to the harsher alert after the condition has # persisted for 0.5s and we're certain that the user isn't overriding if self.steering_unpressed > int( 0.5 / DT_CTRL) and self.steer_warning > int(0.5 / DT_CTRL): events.add(EventName.steerTempUnavailable) else: events.add(EventName.steerTempUnavailableSilent) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. if cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill): pass #events.add(EventName.pedalPressed) if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def _run_seq(self, msgs, interaction, engaged, standstill): DS = DriverStatus() events = [] for idx in range(len(msgs)): e = Events() DS.update_states(msgs[idx], [0, 0, 0], 0, engaged[idx]) # cal_rpy and car_speed don't matter here # evaluate events at 10Hz for tests DS.update_events(e, interaction[idx], engaged[idx], standstill[idx]) events.append(e) assert len(events) == len(msgs), f"got {len(events)} for {len(msgs)} driverState input msgs" return events, DS
def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True): events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) elif cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) elif cs_out.gearShifter != GearShifter.drive and cs_out.gearShifter not in extra_gears: events.add(EventName.wrongGear) elif cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) elif not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) elif cs_out.espDisabled: events.add(EventName.espDisabled) elif cs_out.gasPressed and self.CP.longcontrolEnabled: events.add(EventName.gasPressed) elif cs_out.stockFcw: events.add(EventName.stockFcw) elif cs_out.stockAeb: events.add(EventName.stockAeb) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # Optionally allow to press gas at zero speed to resume. # e.g. Chrysler does not spam the resume button yet, so resuming with gas is handy. FIXME! if self.CP.longcontrolEnabled: if (cs_out.gasPressed and (not self.CS.out.gasPressed) and cs_out.vEgo > gas_resume_speed) or \ (cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill)): events.add(EventName.pedalPressed) # we engage when pcm is active (rising edge) #if pcm_enable: # if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: # events.add( EventName.pcmEnable ) # elif not cs_out.cruiseState.enabled: # events.add( EventName.pcmDisable ) if not pcm_enable: pass elif cs_out.cruiseState.enabled != self.cruise_enabled_prev: if cs_out.cruiseState.enabled: events.add(EventName.pcmEnable) else: events.add(EventName.pcmDisable) self.cruise_enabled_prev = cs_out.cruiseState.enabled return events
def run_DState_seq(driver_state_msgs, driver_car_interaction, openpilot_status, car_standstill_status): # inputs are all 10Hz DS = DriverStatus() events_from_DM = [] for idx in range(len(driver_state_msgs)): e = Events() DS.get_pose(driver_state_msgs[idx], [0, 0, 0], 0, openpilot_status[idx]) # cal_rpy and car_speed don't matter here # evaluate events at 10Hz for tests DS.update(e, driver_car_interaction[idx], openpilot_status[idx], car_standstill_status[idx]) events_from_DM.append(e) assert len(events_from_DM) == len(driver_state_msgs), 'somethings wrong' return events_from_DM, DS
def update(self, enabled, v_ego, a_ego, sm, v_cruise_setpoint, events=Events()): self._op_enabled = enabled self._v_ego = v_ego self._a_ego = a_ego self._v_cruise_setpoint = v_cruise_setpoint self._gas_pressed = sm['carState'].gasPressed self._speed_limit, self._distance, self._source = self._resolver.resolve(v_ego, self.speed_limit, sm) self._update_params() self._update_calculations() self._state_transition() self._update_solution() self._update_events(events)
def __init__(self, CP): self.CP = CP self.mpcs = {} self.mpcs['lead0'] = LeadMpc(0) self.mpcs['lead1'] = LeadMpc(1) self.mpcs['cruise'] = LongitudinalMpc() self.mpcs['custom'] = LimitsLongitudinalMpc() self.fcw = False self.fcw_checker = FCWChecker() self.v_desired = 0.0 self.a_desired = 0.0 self.longitudinalPlanSource = 'cruise' self.alpha = np.exp(-CP.radarTimeStep/2.0) self.lead_0 = log.ModelDataV2.LeadDataV3.new_message() self.lead_1 = log.ModelDataV2.LeadDataV3.new_message() self.v_desired_trajectory = np.zeros(CONTROL_N) self.a_desired_trajectory = np.zeros(CONTROL_N) self.vision_turn_controller = VisionTurnController(CP) self.speed_limit_controller = SpeedLimitController() self.events = Events() self.turn_speed_controller = TurnSpeedController() self._params = Params() self.params_check_last_t = 0. self.params_check_freq = 0.1 # check params at 10Hz self.accel_mode = int(self._params.get("AccelMode", encoding="utf8")) # 0 = normal, 1 = sport; 2 = eco; 3 = creep self.coasting_lead_d = -1. # [m] lead distance. -1. if no lead self.coasting_lead_v = -10. # lead "absolute"" velocity self.tr = 1.8 self.sessionInitTime = sec_since_boot() self.debug_logging = False self.debug_log_time_step = 0.333 self.last_debug_log_t = 0. self.debug_log_path = "/data/openpilot/long_debug.csv" if self.debug_logging: with open(self.debug_log_path,"w") as f: f.write(",".join([ "t", "vEgo", "vEgo (mph)", "a lim low", "a lim high", "out a", "out long plan"]) + "\n")
def status_monitor(): # use driverState socker to drive timing. driverState = messaging.sub_sock('driverState', addr=args.addr, conflate=True) sm = messaging.SubMaster(['carState', 'dMonitoringState'], addr=args.addr) steering_status = HandsOnWheelStatus() v_cruise_last = 0 while messaging.recv_one(driverState): try: sm.update() v_cruise = sm['carState'].cruiseState.speed steering_wheel_engaged = len(sm['carState'].buttonEvents) > 0 or \ v_cruise != v_cruise_last or sm['carState'].steeringPressed v_cruise_last = v_cruise # Get status from our own instance of SteeringStatus steering_status.update(Events(), steering_wheel_engaged, sm['carState'].cruiseState.enabled, sm['carState'].vEgo) steering_state = steering_status.hands_on_wheel_state state_name = "Unknown " if steering_state == HandsOnWheelState.none: state_name = "Not Active " elif steering_state == HandsOnWheelState.ok: state_name = "Hands On Wheel " elif steering_state == HandsOnWheelState.minor: state_name = "Hands Off Wheel - Minor " elif steering_state == HandsOnWheelState.warning: state_name = "Hands Off Wheel - Warning " elif steering_state == HandsOnWheelState.critical: state_name = "Hands Off Wheel - Critical" elif steering_state == HandsOnWheelState.terminal: state_name = "Hands Off Wheel - Terminal" # Get events from `dMonitoringState` events = sm['dMonitoringState'].events event_name = events[0].name if len(events) else "None" event_name = "{:<30}".format(event_name[:30]) # Print output sys.stdout.write( f'\rSteering State: {state_name} | event: {event_name}') sys.stdout.flush() except Exception as e: print(e)
def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1): # pylint: disable=dangerous-default-value events = Events() if cs_out.doorOpen: events.add(EventName.doorOpen) if cs_out.seatbeltUnlatched: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and cs_out.gearShifter not in extra_gears: events.add(EventName.wrongGear) if cs_out.gearShifter == GearShifter.reverse: events.add(EventName.reverseGear) if not cs_out.cruiseState.available: events.add(EventName.wrongCarMode) if cs_out.espDisabled: events.add(EventName.espDisabled) if cs_out.stockFcw: events.add(EventName.stockFcw) if cs_out.stockAeb: events.add(EventName.stockAeb) if cs_out.vEgo > MAX_CTRL_SPEED: events.add(EventName.speedTooHigh) if cs_out.steerError: events.add(EventName.steerUnavailable) elif cs_out.steerWarning: events.add(EventName.steerTempUnavailable) # Disable on rising edge of gas or brake. Also disable on brake when speed > 0. # Optionally allow to press gas at zero speed to resume. # e.g. Chrysler does not spam the resume button yet, so resuming with gas is handy. FIXME! if cs_out.brakePressed and (not self.CS.out.brakePressed or not cs_out.standstill): None # events.add(EventName.pedalPressed) if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: events.add(EventName.pcmEnable) elif not cs_out.cruiseState.enabled: events.add(EventName.pcmDisable) return events
def run_HOWState_seq(steering_wheel_interaction, openpilot_status, speed_status): # inputs are all 10Hz HOWS = HandsOnWheelStatus() events_from_HOWM = [] hands_on_wheel_state_from_HOWM = [] for idx in range(len(steering_wheel_interaction)): e = Events() # evaluate events at 10Hz for tests HOWS.update(e, steering_wheel_interaction[idx], openpilot_status[idx], speed_status[idx]) events_from_HOWM.append(e) hands_on_wheel_state_from_HOWM.append(HOWS.hands_on_wheel_state) assert len(events_from_HOWM) == len( steering_wheel_interaction), 'somethings wrong' assert len(hands_on_wheel_state_from_HOWM) == len( steering_wheel_interaction), 'somethings wrong' return events_from_HOWM, hands_on_wheel_state_from_HOWM
def mpc_solutions(self, enabled, v_ego, a_ego, v_cruise, sm): # Update controllers self.vision_turn_controller.update(enabled, v_ego, a_ego, v_cruise, sm) self.events = Events() self.speed_limit_controller.update(enabled, v_ego, a_ego, sm, v_cruise, self.events) self.turn_speed_controller.update(enabled, v_ego, a_ego, sm) # Pick solution with lowest acceleration target. a_solutions = {None: float("inf")} if self.vision_turn_controller.is_active: a_solutions['turn'] = self.vision_turn_controller.a_target if self.speed_limit_controller.is_active: a_solutions['limit'] = self.speed_limit_controller.a_target if self.turn_speed_controller.is_active: a_solutions['turnlimit'] = self.turn_speed_controller.a_target source = min(a_solutions, key=a_solutions.get) a_sol = { 'cruise': a_ego, # Irrelevant 'lead0': a_ego, # Irrelevant 'lead1': a_ego, # Irrelevant 'custom': 0. if source is None else a_solutions[source], } active_sol = { 'cruise': True, # Irrelevant 'lead0': True, # Irrelevant 'lead1': True, # Irrelevant 'custom': source is not None, } return a_sol, active_sol, source
def update_curv(self, CS, sm, curve_speed): wait_time_cmd = 0 set_speed = self.cruise_set_speed_kph # 2. 커브 감속. #if self.cruise_set_speed_kph >= 100: if CS.out.cruiseState.modeSel == 1 and Events().names not in [ EventName.laneChangeManual, EventName.laneChange ] and not self.map_decel_only: if curve_speed < 40 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = min( 48, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.25)) self.seq_step_debug = "커브감속-5" wait_time_cmd = 15 elif curve_speed < 60 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = min( 55, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.2)) self.seq_step_debug = "커브감속-4" wait_time_cmd = 20 elif curve_speed < 70 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = min( 65, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.15)) self.seq_step_debug = "커브감속-3" wait_time_cmd = 25 elif curve_speed < 80 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = min( 75, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.1)) self.seq_step_debug = "커브감속-2" wait_time_cmd = 30 elif curve_speed < 90 and CS.clu_Vanz > 40 and CS.lead_distance >= 15: set_speed = min( 85, self.cruise_set_speed_kph - int(CS.clu_Vanz * 0.05)) self.seq_step_debug = "커브감속-1" wait_time_cmd = 35 return wait_time_cmd, set_speed
def __init__(self, sm=None, pm=None, can_sock=None): config_realtime_process(3, Priority.CTRL_HIGH) # Setup sockets self.pm = pm if self.pm is None: self.pm = messaging.PubMaster(['sendcan', 'controlsState', 'carState', 'carControl', 'carEvents', 'carParams']) self.sm = sm if self.sm is None: self.sm = messaging.SubMaster(['thermal', 'health', 'model', 'liveCalibration', 'dMonitoringState', 'plan', 'pathPlan', 'liveLocationKalman']) self.can_sock = can_sock if can_sock is None: can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 100 self.can_sock = messaging.sub_sock('can', timeout=can_timeout) # wait for one health and one CAN packet hw_type = messaging.recv_one(self.sm.sock['health']).health.hwType has_relay = hw_type in [HwType.blackPanda, HwType.uno, HwType.dos] print("Waiting for CAN messages...") get_one_can(self.can_sock) self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], has_relay) # read params params = Params() self.is_metric = params.get("IsMetric", encoding='utf8') == "1" self.is_ldw_enabled = params.get("IsLdwEnabled", encoding='utf8') == "1" internet_needed = (params.get("Offroad_ConnectivityNeeded", encoding='utf8') is not None) and (params.get("DisableUpdates") != b"1") community_feature_toggle = params.get("CommunityFeaturesToggle", encoding='utf8') == "1" openpilot_enabled_toggle = params.get("OpenpilotEnabledToggle", encoding='utf8') == "1" passive = params.get("Passive", encoding='utf8') == "1" or \ internet_needed or not openpilot_enabled_toggle # detect sound card presence and ensure successful init sounds_available = HARDWARE.get_sound_card_online() car_recognized = self.CP.carName != 'mock' # If stock camera is disconnected, we loaded car controls and it's not dashcam mode controller_available = self.CP.enableCamera and self.CI.CC is not None and not passive and not self.CP.dashcamOnly community_feature_disallowed = self.CP.communityFeature and not community_feature_toggle self.read_only = not car_recognized or not controller_available or \ self.CP.dashcamOnly or community_feature_disallowed if self.read_only: self.CP.safetyModel = car.CarParams.SafetyModel.noOutput # Write CarParams for radard and boardd safety mode cp_bytes = self.CP.to_bytes() params.put("CarParams", cp_bytes) put_nonblocking("CarParamsCache", cp_bytes) self.CC = car.CarControl.new_message() self.AM = AlertManager() self.events = Events() self.LoC = LongControl(self.CP, self.CI.compute_gb) self.VM = VehicleModel(self.CP) if self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP) elif self.CP.lateralTuning.which() == 'indi': self.LaC = LatControlINDI(self.CP) elif self.CP.lateralTuning.which() == 'lqr': self.LaC = LatControlLQR(self.CP) self.state = State.disabled self.enabled = False self.active = False self.can_rcv_error = False self.soft_disable_timer = 0 self.v_cruise_kph = 255 self.v_cruise_kph_last = 0 self.mismatch_counter = 0 self.can_error_counter = 0 self.last_blinker_frame = 0 self.saturated_count = 0 self.distance_traveled = 0 self.last_functional_fan_frame = 0 self.events_prev = [] self.current_alert_types = [ET.PERMANENT] self.sm['liveCalibration'].calStatus = Calibration.CALIBRATED self.sm['thermal'].freeSpace = 1. self.sm['dMonitoringState'].events = [] self.sm['dMonitoringState'].awarenessStatus = 1. self.sm['dMonitoringState'].faceDetected = False self.startup_event = get_startup_event(car_recognized, controller_available, hw_type) if not sounds_available: self.events.add(EventName.soundsUnavailable, static=True) if internet_needed: self.events.add(EventName.internetConnectivityNeeded, static=True) if community_feature_disallowed: self.events.add(EventName.communityFeatureDisallowed, static=True) if not car_recognized: self.events.add(EventName.carUnrecognized, static=True) if hw_type == HwType.whitePanda: self.events.add(EventName.whitePandaUnsupported, static=True) # controlsd is driven by can recv, expected at 100Hz self.rk = Ratekeeper(100, print_delay_threshold=None) self.prof = Profiler(False) # off by default
def __init__(self, sm=None, pm=None, can_sock=None): gc.disable() set_realtime_priority(3) self.trace_log = trace1.Loger("controlsd") # Setup sockets self.pm = pm if self.pm is None: self.pm = messaging.PubMaster(['sendcan', 'controlsState', 'carState', \ 'carControl', 'carEvents', 'carParams']) self.sm = sm if self.sm is None: socks = [ 'thermal', 'health', 'model', 'liveCalibration', 'dMonitoringState', 'plan', 'pathPlan', 'liveLocationKalman' ] self.sm = messaging.SubMaster(socks, ignore_alive=['dMonitoringState']) #self.sm = messaging.SubMaster(['thermal', 'health', 'model', 'liveCalibration', \ # 'dMonitoringState', 'plan', 'pathPlan', 'liveLocationKalman']) print(" start_Controls messages...1") self.can_sock = can_sock if can_sock is None: can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 100 self.can_sock = messaging.sub_sock('can', timeout=can_timeout) print(" start_Controls messages...2") # wait for one health and one CAN packet hw_type = messaging.recv_one(self.sm.sock['health']).health.hwType has_relay = hw_type in [HwType.blackPanda, HwType.uno] print("Waiting for CAN messages...") messaging.get_one_can(self.can_sock) self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], has_relay) # read params params = Params() self.is_metric = params.get("IsMetric", encoding='utf8') == "1" self.is_ldw_enabled = params.get("IsLdwEnabled", encoding='utf8') == "1" internet_needed = params.get("Offroad_ConnectivityNeeded", encoding='utf8') is not None community_feature_toggle = params.get("CommunityFeaturesToggle", encoding='utf8') == "1" openpilot_enabled_toggle = params.get("OpenpilotEnabledToggle", encoding='utf8') == "1" passive = params.get("Passive", encoding='utf8') == "1" or \ internet_needed or not openpilot_enabled_toggle # detect sound card presence and ensure successful init sounds_available = not os.path.isfile('/EON') or (os.path.isfile('/proc/asound/card0/state') \ and open('/proc/asound/card0/state').read().strip() == 'ONLINE') car_recognized = self.CP.carName != 'mock' # If stock camera is disconnected, we loaded car controls and it's not dashcam mode controller_available = self.CP.enableCamera and self.CI.CC is not None and not passive community_feature_disallowed = self.CP.communityFeature and not community_feature_toggle self.read_only = not car_recognized or not controller_available or \ self.CP.dashcamOnly or community_feature_disallowed if self.read_only: self.CP.safetyModel = car.CarParams.SafetyModel.noOutput # Write CarParams for radard and boardd safety mode cp_bytes = self.CP.to_bytes() params.put("CarParams", cp_bytes) put_nonblocking("CarParamsCache", cp_bytes) put_nonblocking("LongitudinalControl", "1" if self.CP.openpilotLongitudinalControl else "0") self.CC = car.CarControl.new_message() self.AM = AlertManager() self.events = Events() self.LoC = LongControl(self.CP, self.CI.compute_gb) self.VM = VehicleModel(self.CP) print('self.CP.lateralTuning.which()={}'.format( self.CP.lateralTuning.which())) if self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP) elif self.CP.lateralTuning.which() == 'indi': self.LaC = LatControlINDI(self.CP) elif self.CP.lateralTuning.which() == 'lqr': self.LaC = LatControlLQR(self.CP) self.state = State.disabled self.enabled = False self.active = False self.can_rcv_error = False self.soft_disable_timer = 0 self.v_cruise_kph = 255 self.v_cruise_kph_last = 0 self.mismatch_counter = 0 self.can_error_counter = 0 self.consecutive_can_error_count = 0 self.last_blinker_frame = 0 self.saturated_count = 0 self.events_prev = [] self.current_alert_types = [] self.sm['liveCalibration'].calStatus = Calibration.INVALID self.sm['thermal'].freeSpace = 1. self.sm['dMonitoringState'].events = [] self.sm['dMonitoringState'].awarenessStatus = 1. self.sm['dMonitoringState'].faceDetected = False self.startup_event = get_startup_event(car_recognized, controller_available, hw_type) if not sounds_available: self.events.add(EventName.soundsUnavailable, static=True) if internet_needed: self.events.add(EventName.internetConnectivityNeeded, static=True) if community_feature_disallowed: self.events.add(EventName.communityFeatureDisallowed, static=True) if self.read_only and not passive: self.events.add(EventName.carUnrecognized, static=True) # if hw_type == HwType.whitePanda: # self.events.add(EventName.whitePandaUnsupported, static=True) uname = subprocess.check_output(["uname", "-v"], encoding='utf8').strip() if uname == "#1 SMP PREEMPT Wed Jun 10 12:40:53 PDT 2020": self.events.add(EventName.neosUpdateRequired, static=True) # controlsd is driven by can recv, expected at 100Hz self.rk = Ratekeeper(100, print_delay_threshold=None) self.prof = Profiler(False) # off by default self.hyundai_lkas = self.read_only #read_only self.init_flag = True
def cycle_alerts(duration=200, is_metric=False): # all alerts #alerts = list(EVENTS.keys()) # this plays each type of audible alert alerts = [ (EventName.buttonEnable, ET.ENABLE), (EventName.buttonCancel, ET.USER_DISABLE), (EventName.wrongGear, ET.NO_ENTRY), (EventName.vehicleModelInvalid, ET.SOFT_DISABLE), (EventName.accFaulted, ET.IMMEDIATE_DISABLE), # DM sequence (EventName.preDriverDistracted, ET.WARNING), (EventName.promptDriverDistracted, ET.WARNING), (EventName.driverDistracted, ET.WARNING), ] # debug alerts alerts = [ #(EventName.highCpuUsage, ET.NO_ENTRY), #(EventName.lowMemory, ET.PERMANENT), #(EventName.overheat, ET.PERMANENT), #(EventName.outOfSpace, ET.PERMANENT), #(EventName.modeldLagging, ET.PERMANENT), #(EventName.processNotRunning, ET.NO_ENTRY), #(EventName.commIssue, ET.NO_ENTRY), #(EventName.calibrationInvalid, ET.PERMANENT), (EventName.cameraMalfunction, ET.PERMANENT), (EventName.cameraFrameRate, ET.PERMANENT), ] cameras = ['roadCameraState', 'wideRoadCameraState', 'driverCameraState'] CS = car.CarState.new_message() CP = CarInterface.get_params("HONDA CIVIC 2016") sm = messaging.SubMaster([ 'deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', 'managerState' ] + cameras) pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState']) events = Events() AM = AlertManager() frame = 0 while True: for alert, et in alerts: events.clear() events.add(alert) sm['deviceState'].freeSpacePercent = randperc() sm['deviceState'].memoryUsagePercent = int(randperc()) sm['deviceState'].cpuTempC = [randperc() for _ in range(3)] sm['deviceState'].gpuTempC = [randperc() for _ in range(3)] sm['deviceState'].cpuUsagePercent = [ int(randperc()) for _ in range(8) ] sm['modelV2'].frameDropPerc = randperc() if random.random() > 0.25: sm['modelV2'].velocity.x = [ random.random(), ] if random.random() > 0.25: CS.vEgo = random.random() procs = [ p.get_process_state_msg() for p in managed_processes.values() ] random.shuffle(procs) for i in range(random.randint(0, 10)): procs[i].shouldBeRunning = True sm['managerState'].processes = procs sm['liveCalibration'].rpyCalib = [ -1 * random.random() for _ in range(random.randint(0, 3)) ] for s in sm.data.keys(): prob = 0.3 if s in cameras else 0.08 sm.alive[s] = random.random() > prob sm.valid[s] = random.random() > prob sm.freq_ok[s] = random.random() > prob a = events.create_alerts([ et, ], [CP, CS, sm, is_metric, 0]) AM.add_many(frame, a) alert = AM.process_alerts(frame, []) print(alert) for _ in range(duration): dat = messaging.new_message() dat.init('controlsState') dat.controlsState.enabled = False if alert: dat.controlsState.alertText1 = alert.alert_text_1 dat.controlsState.alertText2 = alert.alert_text_2 dat.controlsState.alertSize = alert.alert_size dat.controlsState.alertStatus = alert.alert_status dat.controlsState.alertBlinkingRate = alert.alert_rate dat.controlsState.alertType = alert.alert_type dat.controlsState.alertSound = alert.audible_alert pm.send('controlsState', dat) dat = messaging.new_message() dat.init('deviceState') dat.deviceState.started = True pm.send('deviceState', dat) dat = messaging.new_message('pandaStates', 1) dat.pandaStates[0].ignitionLine = True dat.pandaStates[0].pandaType = log.PandaState.PandaType.uno pm.send('pandaStates', dat) frame += 1 time.sleep(DT_CTRL)
def __init__(self, sm=None, pm=None, can_sock=None): config_realtime_process(4 if TICI else 3, Priority.CTRL_HIGH) # Setup sockets self.pm = pm if self.pm is None: self.pm = messaging.PubMaster([ 'sendcan', 'controlsState', 'carState', 'carControl', 'carEvents', 'carParams' ]) self.sm = sm if self.sm is None: ignore = ['driverCameraState', 'managerState' ] if SIMULATION else None self.sm = messaging.SubMaster([ 'deviceState', 'pandaState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', 'roadCameraState', 'driverCameraState', 'managerState', 'liveParameters', 'radarState' ], ignore_alive=ignore) self.can_sock = can_sock if can_sock is None: can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 100 self.can_sock = messaging.sub_sock('can', timeout=can_timeout) # wait for one pandaState and one CAN packet print("Waiting for CAN messages...") get_one_can(self.can_sock) self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan']) # read params params = Params() self.is_metric = params.get_bool("IsMetric") self.is_ldw_enabled = params.get_bool("IsLdwEnabled") community_feature_toggle = params.get_bool("CommunityFeaturesToggle") openpilot_enabled_toggle = params.get_bool("OpenpilotEnabledToggle") passive = params.get_bool("Passive") or not openpilot_enabled_toggle # detect sound card presence and ensure successful init sounds_available = HARDWARE.get_sound_card_online() car_recognized = self.CP.carName != 'mock' # If stock camera is disconnected, we loaded car controls and it's not dashcam mode controller_available = self.CP.enableCamera and self.CI.CC is not None and not passive and not self.CP.dashcamOnly community_feature_disallowed = self.CP.communityFeature and not community_feature_toggle self.read_only = not car_recognized or not controller_available or \ self.CP.dashcamOnly or community_feature_disallowed if self.read_only: self.CP.safetyModel = car.CarParams.SafetyModel.noOutput # Write CarParams for radard and boardd safety mode cp_bytes = self.CP.to_bytes() params.put("CarParams", cp_bytes) put_nonblocking("CarParamsCache", cp_bytes) self.CC = car.CarControl.new_message() self.AM = AlertManager() self.events = Events() self.LoC = LongControl(self.CP, self.CI.compute_gb) self.VM = VehicleModel(self.CP) if self.CP.steerControlType == car.CarParams.SteerControlType.angle: self.LaC = LatControlAngle(self.CP) elif self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP) elif self.CP.lateralTuning.which() == 'indi': self.LaC = LatControlINDI(self.CP) elif self.CP.lateralTuning.which() == 'lqr': self.LaC = LatControlLQR(self.CP) self.state = State.disabled self.enabled = False self.active = False self.can_rcv_error = False self.soft_disable_timer = 0 self.v_cruise_kph = 255 self.v_cruise_kph_last = 0 self.mismatch_counter = 0 self.can_error_counter = 0 self.last_blinker_frame = 0 self.saturated_count = 0 self.distance_traveled = 0 self.last_functional_fan_frame = 0 self.events_prev = [] self.current_alert_types = [ET.PERMANENT] self.logged_comm_issue = False self.sm['liveCalibration'].calStatus = Calibration.CALIBRATED self.sm['deviceState'].freeSpacePercent = 100 self.sm['driverMonitoringState'].events = [] self.sm['driverMonitoringState'].awarenessStatus = 1. self.sm['driverMonitoringState'].faceDetected = False self.sm['liveParameters'].valid = True self.startup_event = get_startup_event(car_recognized, controller_available) if not sounds_available: self.events.add(EventName.soundsUnavailable, static=True) if community_feature_disallowed: self.events.add(EventName.communityFeatureDisallowed, static=True) if not car_recognized: self.events.add(EventName.carUnrecognized, static=True) elif self.read_only: self.events.add(EventName.dashcamMode, static=True) # controlsd is driven by can recv, expected at 100Hz self.rk = Ratekeeper(100, print_delay_threshold=None) self.prof = Profiler(False) # off by default
def __init__(self, sm=None, pm=None, can_sock=None): config_realtime_process(4 if TICI else 3, Priority.CTRL_HIGH) # Setup sockets self.pm = pm if self.pm is None: self.pm = messaging.PubMaster([ 'sendcan', 'controlsState', 'carState', 'carControl', 'carEvents', 'carParams' ]) self.camera_packets = ["roadCameraState", "driverCameraState"] if TICI: self.camera_packets.append("wideRoadCameraState") params = Params() self.joystick_mode = params.get_bool("JoystickDebugMode") joystick_packet = ['testJoystick'] if self.joystick_mode else [] self.sm = sm if self.sm is None: ignore = ['driverCameraState', 'managerState' ] if SIMULATION else None self.sm = messaging.SubMaster( [ 'deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', 'managerState', 'liveParameters', 'radarState' ] + self.camera_packets + joystick_packet, ignore_alive=ignore, ignore_avg_freq=['radarState', 'longitudinalPlan']) self.can_sock = can_sock if can_sock is None: can_timeout = None if os.environ.get('NO_CAN_TIMEOUT', False) else 100 self.can_sock = messaging.sub_sock('can', timeout=can_timeout) if TICI: self.log_sock = messaging.sub_sock('androidLog') # wait for one pandaState and one CAN packet print("Waiting for CAN messages...") get_one_can(self.can_sock) self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan']) # read params self.is_metric = params.get_bool("IsMetric") self.is_ldw_enabled = params.get_bool("IsLdwEnabled") community_feature_toggle = params.get_bool("CommunityFeaturesToggle") openpilot_enabled_toggle = params.get_bool("OpenpilotEnabledToggle") passive = params.get_bool("Passive") or not openpilot_enabled_toggle # detect sound card presence and ensure successful init sounds_available = HARDWARE.get_sound_card_online() car_recognized = self.CP.carName != 'mock' controller_available = self.CI.CC is not None and not passive and not self.CP.dashcamOnly community_feature = self.CP.communityFeature or \ self.CP.fingerprintSource == car.CarParams.FingerprintSource.can community_feature_disallowed = community_feature and ( not community_feature_toggle) self.read_only = not car_recognized or not controller_available or \ self.CP.dashcamOnly or community_feature_disallowed if self.read_only: safety_config = car.CarParams.SafetyConfig.new_message() safety_config.safetyModel = car.CarParams.SafetyModel.noOutput self.CP.safetyConfigs = [safety_config] # Write CarParams for radard cp_bytes = self.CP.to_bytes() params.put("CarParams", cp_bytes) put_nonblocking("CarParamsCache", cp_bytes) self.CC = car.CarControl.new_message() self.AM = AlertManager() self.events = Events() self.LoC = LongControl(self.CP) self.VM = VehicleModel(self.CP) if self.CP.steerControlType == car.CarParams.SteerControlType.angle: self.LaC = LatControlAngle(self.CP) elif self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP, self.CI) elif self.CP.lateralTuning.which() == 'indi': self.LaC = LatControlINDI(self.CP) elif self.CP.lateralTuning.which() == 'lqr': self.LaC = LatControlLQR(self.CP) self.initialized = False self.state = State.disabled self.enabled = False self.active = False self.can_rcv_error = False self.soft_disable_timer = 0 self.v_cruise_kph = 255 self.v_cruise_kph_last = 0 self.mismatch_counter = 0 self.can_error_counter = 0 self.last_blinker_frame = 0 self.saturated_count = 0 self.distance_traveled = 0 self.last_functional_fan_frame = 0 self.events_prev = [] self.current_alert_types = [ET.PERMANENT] self.logged_comm_issue = False self.button_timers = { ButtonEvent.Type.decelCruise: 0, ButtonEvent.Type.accelCruise: 0 } # TODO: no longer necessary, aside from process replay self.sm['liveParameters'].valid = True self.startup_event = get_startup_event(car_recognized, controller_available, len(self.CP.carFw) > 0) if not sounds_available: self.events.add(EventName.soundsUnavailable, static=True) if community_feature_disallowed and car_recognized and not self.CP.dashcamOnly: self.events.add(EventName.communityFeatureDisallowed, static=True) if not car_recognized: self.events.add(EventName.carUnrecognized, static=True) elif self.read_only: self.events.add(EventName.dashcamMode, static=True) elif self.joystick_mode: self.events.add(EventName.joystickDebug, static=True) self.startup_event = None # controlsd is driven by can recv, expected at 100Hz self.rk = Ratekeeper(100, print_delay_threshold=None) self.prof = Profiler(False) # off by default
def dmonitoringd_thread(sm=None, pm=None): if pm is None: pm = messaging.PubMaster(['driverMonitoringState']) if sm is None: sm = messaging.SubMaster([ 'driverState', 'liveCalibration', 'carState', 'controlsState', 'modelV2' ], poll=['driverState']) driver_status = DriverStatus(rhd=Params().get_bool("IsRHD")) sm['liveCalibration'].calStatus = Calibration.INVALID sm['liveCalibration'].rpyCalib = [0, 0, 0] sm['carState'].vEgo = 0. sm['carState'].buttonEvents = [] sm['carState'].standstill = True v_cruise_last = 0 driver_engaged = False # 10Hz <- dmonitoringmodeld while True: sm.update() if not sm.updated['driverState']: continue # Get interaction if sm.updated['carState']: v_cruise = sm['carState'].cruiseState.speed driver_engaged = len(sm['carState'].buttonEvents) > 0 or \ v_cruise != v_cruise_last or \ sm['carState'].steeringPressed or \ sm['carState'].gasPressed if driver_engaged: driver_status.update(Events(), True, sm['controlsState'].enabled, sm['carState'].standstill, sm['carState'].vEgo) v_cruise_last = v_cruise if sm.updated['modelV2']: driver_status.set_policy(sm['modelV2']) # Get data from dmonitoringmodeld events = Events() driver_status.get_pose(sm['driverState'], sm['liveCalibration'].rpyCalib, sm['carState'].vEgo, sm['controlsState'].enabled) # Block engaging after max number of distrations if driver_status.terminal_alert_cnt >= MAX_TERMINAL_ALERTS or driver_status.terminal_time >= MAX_TERMINAL_DURATION: events.add(car.CarEvent.EventName.tooDistracted) # Update events from driver state driver_status.update(events, driver_engaged, sm['controlsState'].enabled, sm['carState'].standstill, sm['carState'].vEgo) # build driverMonitoringState packet dat = messaging.new_message('driverMonitoringState') dat.driverMonitoringState = { "events": events.to_msg(), "faceDetected": driver_status.face_detected, "isDistracted": driver_status.driver_distracted, "awarenessStatus": driver_status.awareness, "posePitchOffset": driver_status.pose.pitch_offseter.filtered_stat.mean(), "posePitchValidCount": driver_status.pose.pitch_offseter.filtered_stat.n, "poseYawOffset": driver_status.pose.yaw_offseter.filtered_stat.mean(), "poseYawValidCount": driver_status.pose.yaw_offseter.filtered_stat.n, "stepChange": driver_status.step_change, "awarenessActive": driver_status.awareness_active, "awarenessPassive": driver_status.awareness_passive, "isLowStd": driver_status.pose.low_std, "hiStdCount": driver_status.hi_stds, "isActiveMode": driver_status.active_monitoring_mode, } pm.send('driverMonitoringState', dat)