optimize alertmanager (#23433)

old-commit-hash: 09a835916b
commatwo_master
Dean Lee 3 years ago committed by GitHub
parent 557882ddf3
commit 296925cd6a
  1. 21
      selfdrive/controls/controlsd.py
  2. 38
      selfdrive/controls/lib/alertmanager.py
  3. 4
      selfdrive/controls/lib/tests/test_alertmanager.py

@ -619,8 +619,9 @@ class Controls:
clear_event = ET.WARNING if ET.WARNING not in self.current_alert_types else None clear_event = ET.WARNING if ET.WARNING not in self.current_alert_types else None
alerts = self.events.create_alerts(self.current_alert_types, [self.CP, self.sm, self.is_metric, self.soft_disable_timer]) alerts = self.events.create_alerts(self.current_alert_types, [self.CP, self.sm, self.is_metric, self.soft_disable_timer])
self.AM.add_many(self.sm.frame, alerts) self.AM.add_many(self.sm.frame, alerts)
self.AM.process_alerts(self.sm.frame, clear_event) current_alert = self.AM.process_alerts(self.sm.frame, clear_event)
hudControl.visualAlert = self.AM.visual_alert if current_alert:
hudControl.visualAlert = current_alert.visual_alert
if not self.read_only and self.initialized: if not self.read_only and self.initialized:
# send car controls over can # send car controls over can
@ -641,13 +642,15 @@ class Controls:
dat = messaging.new_message('controlsState') dat = messaging.new_message('controlsState')
dat.valid = CS.canValid dat.valid = CS.canValid
controlsState = dat.controlsState controlsState = dat.controlsState
controlsState.alertText1 = self.AM.alert_text_1 if current_alert:
controlsState.alertText2 = self.AM.alert_text_2 controlsState.alertText1 = current_alert.alert_text_1
controlsState.alertSize = self.AM.alert_size controlsState.alertText2 = current_alert.alert_text_2
controlsState.alertStatus = self.AM.alert_status controlsState.alertSize = current_alert.alert_size
controlsState.alertBlinkingRate = self.AM.alert_rate controlsState.alertStatus = current_alert.alert_status
controlsState.alertType = self.AM.alert_type controlsState.alertBlinkingRate = current_alert.alert_rate
controlsState.alertSound = self.AM.audible_alert controlsState.alertType = current_alert.alert_type
controlsState.alertSound = current_alert.audible_alert
controlsState.canMonoTimes = list(CS.canMonoTimes) controlsState.canMonoTimes = list(CS.canMonoTimes)
controlsState.longitudinalPlanMonoTime = self.sm.logMonoTime['longitudinalPlan'] controlsState.longitudinalPlanMonoTime = self.sm.logMonoTime['longitudinalPlan']
controlsState.lateralPlanMonoTime = self.sm.logMonoTime['lateralPlan'] controlsState.lateralPlanMonoTime = self.sm.logMonoTime['lateralPlan']

@ -5,7 +5,6 @@ from collections import defaultdict
from dataclasses import dataclass from dataclasses import dataclass
from typing import List, Dict, Optional from typing import List, Dict, Optional
from cereal import car, log
from common.basedir import BASEDIR from common.basedir import BASEDIR
from common.params import Params from common.params import Params
from selfdrive.controls.lib.events import Alert from selfdrive.controls.lib.events import Alert
@ -36,22 +35,9 @@ class AlertEntry:
return frame <= self.end_frame return frame <= self.end_frame
class AlertManager: class AlertManager:
def __init__(self): def __init__(self):
self.reset()
self.alerts: Dict[str, AlertEntry] = defaultdict(AlertEntry) self.alerts: Dict[str, AlertEntry] = defaultdict(AlertEntry)
def reset(self) -> None:
self.alert: Optional[Alert] = None
self.alert_type: str = ""
self.alert_text_1: str = ""
self.alert_text_2: str = ""
self.alert_status = log.ControlsState.AlertStatus.normal
self.alert_size = log.ControlsState.AlertSize.none
self.visual_alert = car.CarControl.HUDControl.VisualAlert.none
self.audible_alert = car.CarControl.HUDControl.AudibleAlert.none
self.alert_rate: float = 0.
def add_many(self, frame: int, alerts: List[Alert]) -> None: def add_many(self, frame: int, alerts: List[Alert]) -> None:
for alert in alerts: for alert in alerts:
key = alert.alert_type key = alert.alert_type
@ -61,30 +47,18 @@ class AlertManager:
min_end_frame = self.alerts[key].start_frame + alert.duration min_end_frame = self.alerts[key].start_frame + alert.duration
self.alerts[key].end_frame = max(frame + 1, min_end_frame) self.alerts[key].end_frame = max(frame + 1, min_end_frame)
def process_alerts(self, frame: int, clear_event_type=None) -> None: def process_alerts(self, frame: int, clear_event_type=None) -> Optional[Alert]:
current_alert = AlertEntry() current_alert = AlertEntry()
for k, v in self.alerts.items(): for v in self.alerts.values():
if v.alert is None: if not v.alert:
continue continue
if clear_event_type is not None and v.alert.event_type == clear_event_type: if clear_event_type and v.alert.event_type == clear_event_type:
self.alerts[k].end_frame = -1 v.end_frame = -1
# sort by priority first and then by start_frame # sort by priority first and then by start_frame
greater = current_alert.alert is None or (v.alert.priority, v.start_frame) > (current_alert.alert.priority, current_alert.start_frame) greater = current_alert.alert is None or (v.alert.priority, v.start_frame) > (current_alert.alert.priority, current_alert.start_frame)
if v.active(frame) and greater: if v.active(frame) and greater:
current_alert = v current_alert = v
# clear current alert return current_alert.alert
self.reset()
self.alert = current_alert.alert
if self.alert is not None:
self.alert_type = self.alert.alert_type
self.audible_alert = self.alert.audible_alert
self.visual_alert = self.alert.visual_alert
self.alert_text_1 = self.alert.alert_text_1
self.alert_text_2 = self.alert.alert_text_2
self.alert_status = self.alert.alert_status
self.alert_size = self.alert.alert_size
self.alert_rate = self.alert.alert_rate

@ -34,9 +34,9 @@ class TestAlertManager(unittest.TestCase):
for frame in range(duration+10): for frame in range(duration+10):
if frame < add_duration: if frame < add_duration:
AM.add_many(frame, [alert, ]) AM.add_many(frame, [alert, ])
AM.process_alerts(frame) current_alert = AM.process_alerts(frame)
shown = AM.alert is not None shown = current_alert is not None
should_show = frame <= show_duration should_show = frame <= show_duration
self.assertEqual(shown, should_show, msg=f"{frame=} {add_duration=} {duration=}") self.assertEqual(shown, should_show, msg=f"{frame=} {add_duration=} {duration=}")

Loading…
Cancel
Save