diff --git a/cereal b/cereal index 32024acdc0..1e7810dbbf 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 32024acdc0fe2147f6aa62a61a5609dad56bc4f6 +Subproject commit 1e7810dbbfe31003b85f11f948ac6e03b1134570 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 959d75fce1..8dd19a54d9 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -52,7 +52,7 @@ class Controls: self.sm = sm if self.sm is None: - self.sm = messaging.SubMaster(['thermal', 'health', 'frame', 'model', 'liveCalibration', + self.sm = messaging.SubMaster(['thermal', 'health', 'model', 'liveCalibration', 'dMonitoringState', 'plan', 'pathPlan', 'liveLocationKalman']) self.can_sock = can_sock @@ -227,9 +227,6 @@ class Controls: self.events.add(EventName.posenetInvalid) if not self.sm['liveLocationKalman'].deviceStable: self.events.add(EventName.deviceFalling) - if not self.sm['frame'].recoverState < 2: - # counter>=2 is active - self.events.add(EventName.focusRecoverActive) if not self.sm['plan'].radarValid: self.events.add(EventName.radarFault) if self.sm['plan'].radarCanError: @@ -447,7 +444,7 @@ class Controls: if CC.hudControl.rightLaneDepart or CC.hudControl.leftLaneDepart: self.events.add(EventName.ldw) - clear_event = ET.WARNING if ET.WARNING 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.AM.add_many(self.sm.frame, alerts, self.enabled) self.AM.process_alerts(self.sm.frame, clear_event) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 61413248fb..b1a4c27396 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -167,6 +167,11 @@ class EngagementAlert(Alert): Priority.MID, VisualAlert.none, audible_alert, .2, 0., 0.), +class NormalPermanentAlert(Alert): + def __init__(self, alert_text_1, alert_text_2): + super().__init__(alert_text_1, alert_text_2, + AlertStatus.normal, AlertSize.mid, + Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), # ********** alert callback functions ********** @@ -257,11 +262,11 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.whitePandaUnsupported: { ET.PERMANENT: Alert( - "White Panda Is No Longer Supported", + "White Panda No Longer Supported", "Upgrade to comma two or black panda", AlertStatus.normal, AlertSize.mid, Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - ET.NO_ENTRY: NoEntryAlert("White panda is no longer supported"), + ET.NO_ENTRY: NoEntryAlert("Unsupported Hardware"), }, EventName.invalidLkasSetting: { @@ -352,13 +357,13 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo "KEEP EYES ON ROAD: Driver Distracted", "", AlertStatus.normal, AlertSize.small, - Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), + Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1), }, EventName.promptDriverDistracted: { ET.WARNING: Alert( "KEEP EYES ON ROAD", - "Driver Appears Distracted", + "Driver Distracted", AlertStatus.userPrompt, AlertSize.mid, Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), }, @@ -366,7 +371,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.driverDistracted: { ET.WARNING: Alert( "DISENGAGE IMMEDIATELY", - "Driver Was Distracted", + "Driver Distracted", AlertStatus.critical, AlertSize.full, Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), }, @@ -382,7 +387,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.promptDriverUnresponsive: { ET.WARNING: Alert( "TOUCH STEERING WHEEL", - "Driver Is Unresponsive", + "Driver Unresponsive", AlertStatus.userPrompt, AlertSize.mid, Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), }, @@ -390,7 +395,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.driverUnresponsive: { ET.WARNING: Alert( "DISENGAGE IMMEDIATELY", - "Driver Was Unresponsive", + "Driver Unresponsive", AlertStatus.critical, AlertSize.full, Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), }, @@ -398,7 +403,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.driverMonitorLowAcc: { ET.WARNING: Alert( "CHECK DRIVER FACE VISIBILITY", - "Driver Monitor Model Output Uncertain", + "Driver Monitoring Uncertain", AlertStatus.normal, AlertSize.mid, Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .4, 0., 1.5), }, @@ -460,15 +465,11 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo "TAKE CONTROL", "Turn Exceeds Steering Limit", AlertStatus.userPrompt, AlertSize.mid, - Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 2., 3.), + Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 1., 1.), }, EventName.fanMalfunction: { - ET.PERMANENT: Alert( - "Fan Malfunction", - "Contact Support", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2) + ET.PERMANENT: NormalPermanentAlert("Fan Malfunction", "Contact Support"), }, # ********** events that affect controls state transitions ********** @@ -525,15 +526,12 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo duration_hud_alert=0.), }, - EventName.focusRecoverActive: { - ET.WARNING: Alert( - "TAKE CONTROL", - "Attempting Refocus: Camera Focus Invalid", - AlertStatus.userPrompt, AlertSize.mid, - Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, .4, 2., 3., creation_delay=3.1), - }, - EventName.outOfSpace: { + ET.PERMANENT: Alert( + "Out of Storage", + "", + AlertStatus.normal, AlertSize.small, + Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), ET.NO_ENTRY: NoEntryAlert("Out of Storage Space", duration_hud_alert=0.), }, @@ -542,15 +540,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo ET.NO_ENTRY: NoEntryAlert("Speed Too Low"), }, - EventName.neosUpdateRequired: { - ET.PERMANENT: Alert( - "NEOS Update Required", - "Please Wait for Update", - AlertStatus.normal, AlertSize.mid, - Priority.HIGHEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - ET.NO_ENTRY: NoEntryAlert("NEOS Update Required"), - }, - EventName.sensorDataInvalid: { ET.PERMANENT: Alert( "No Data from Device Sensors", @@ -565,11 +554,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo }, EventName.soundsUnavailable: { - ET.PERMANENT: Alert( - "Speaker not found", - "Reboot your Device", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + ET.PERMANENT: NormalPermanentAlert("Speaker not found", "Reboot your Device"), ET.NO_ENTRY: NoEntryAlert("Speaker not found"), }, @@ -578,8 +563,13 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo }, EventName.overheat: { + ET.PERMANENT: Alert( + "System Overheated", + "", + AlertStatus.normal, AlertSize.small, + Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), ET.SOFT_DISABLE: SoftDisableAlert("System Overheated"), - ET.NO_ENTRY: NoEntryAlert("System overheated"), + ET.NO_ENTRY: NoEntryAlert("System Overheated"), }, EventName.wrongGear: { @@ -588,29 +578,25 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo }, EventName.calibrationInvalid: { - ET.PERMANENT: Alert( - "Calibration Invalid", - "Reposition Device and Recalibrate", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - ET.SOFT_DISABLE: SoftDisableAlert("Calibration Invalid: Reposition Device & Recalibrate"), - ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Reposition Device & Recalibrate"), + ET.PERMANENT: NormalPermanentAlert("Calibration Invalid", "Remount Device and Recalibrate"), + ET.SOFT_DISABLE: SoftDisableAlert("Calibration Invalid: Remount Device & Recalibrate"), + ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Remount Device & Recalibrate"), }, EventName.calibrationIncomplete: { - ET.SOFT_DISABLE: SoftDisableAlert("Calibration in Progress"), ET.PERMANENT: calibration_incomplete_alert, + ET.SOFT_DISABLE: SoftDisableAlert("Calibration in Progress"), ET.NO_ENTRY: NoEntryAlert("Calibration in Progress"), }, EventName.doorOpen: { ET.SOFT_DISABLE: SoftDisableAlert("Door Open"), - ET.NO_ENTRY: NoEntryAlert("Door open"), + ET.NO_ENTRY: NoEntryAlert("Door Open"), }, EventName.seatbeltNotLatched: { ET.SOFT_DISABLE: SoftDisableAlert("Seatbelt Unlatched"), - ET.NO_ENTRY: NoEntryAlert("Seatbelt unlatched"), + ET.NO_ENTRY: NoEntryAlert("Seatbelt Unlatched"), }, EventName.espDisabled: { @@ -651,8 +637,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo }, EventName.posenetInvalid: { - ET.SOFT_DISABLE: SoftDisableAlert("Vision Model Output Uncertain"), - ET.NO_ENTRY: NoEntryAlert("Vision Model Output Uncertain"), + ET.SOFT_DISABLE: SoftDisableAlert("Model Output Uncertain"), + ET.NO_ENTRY: NoEntryAlert("Model Output Uncertain"), }, EventName.deviceFalling: { @@ -662,11 +648,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.lowMemory: { ET.SOFT_DISABLE: SoftDisableAlert("Low Memory: Reboot Your Device"), - ET.PERMANENT: Alert( - "RAM Critically Low", - "Reboot your Device", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + ET.PERMANENT: NormalPermanentAlert("Low Memory", "Reboot your Device"), ET.NO_ENTRY : NoEntryAlert("Low Memory: Reboot Your Device", audible_alert=AudibleAlert.chimeDisengage), }, @@ -710,11 +692,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo ET.NO_ENTRY: NoEntryAlert("Cruise Fault: Restart the Car"), }, - EventName.gasUnavailable: { - ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Gas Fault: Restart the Car"), - ET.NO_ENTRY: NoEntryAlert("Gas Error: Restart the Car"), - }, - EventName.reverseGear: { ET.PERMANENT: Alert( "Reverse\nGear", @@ -736,11 +713,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo EventName.relayMalfunction: { ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Malfunction"), - ET.PERMANENT: Alert( - "Harness Malfunction", - "Please Check Hardware", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + ET.PERMANENT: NormalPermanentAlert("Harness Malfunction", "Check Hardware"), ET.NO_ENTRY: NoEntryAlert("Harness Malfunction"), }, @@ -774,13 +747,10 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), }, + # TODO: this is unclear, update check only happens offroad EventName.internetConnectivityNeeded: { - ET.PERMANENT: Alert( - "Please connect to Internet", - "An Update Check Is Required to Engage", - AlertStatus.normal, AlertSize.mid, - Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), - ET.NO_ENTRY: NoEntryAlert("Please Connect to Internet", + ET.PERMANENT: NormalPermanentAlert("Connect to Internet", "An Update Check Is Required to Engage"), + ET.NO_ENTRY: NoEntryAlert("Connect to Internet", audible_alert=AudibleAlert.chimeDisengage), }, diff --git a/selfdrive/controls/tests/test_alerts.py b/selfdrive/controls/tests/test_alerts.py index 5f3a962cfa..a0f3689a92 100755 --- a/selfdrive/controls/tests/test_alerts.py +++ b/selfdrive/controls/tests/test_alerts.py @@ -15,6 +15,14 @@ AlertSize = log.ControlsState.AlertSize OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "selfdrive/controls/lib/alerts_offroad.json") +# TODO: add callback alerts +ALERTS = [] +for event_types in EVENTS.values(): + for alert in event_types.values(): + if isinstance(alert, Alert): + ALERTS.append(alert) + + class TestAlerts(unittest.TestCase): @classmethod @@ -50,13 +58,7 @@ class TestAlerts(unittest.TestCase): ImageFont.truetype(regular_font_path, int(36 * font_scale_factor))], } - alerts = [] - for event_types in EVENTS.values(): - for alert in event_types.values(): - if isinstance(alert, Alert): - alerts.append(alert) - - for alert in alerts: + for alert in ALERTS: # for full size alerts, both text fields wrap the text, # so it's unlikely that they would go past the max width if alert.alert_size in [AlertSize.none, AlertSize.full]: @@ -71,6 +73,17 @@ class TestAlerts(unittest.TestCase): msg = "type: %s msg: %s" % (alert.alert_type, txt) self.assertLessEqual(w, max_text_width, msg=msg) + def test_alert_sanity_check(self): + for a in ALERTS: + if a.alert_size == AlertSize.none: + self.assertEqual(0, len(a.alert_text_1)) + self.assertEqual(0, len(a.alert_text_2)) + else: + if a.alert_size == AlertSize.small: + self.assertEqual(0, len(a.alert_text_2)) + + self.assertTrue(all([n >= 0. for n in [a.duration_sound, a.duration_hud_alert, a.duration_text]])) + def test_offroad_alerts(self): params = Params() for a in self.offroad_alerts: diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index b3d7fa9f3b..af13a26f53 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -6f90ffa4970c48edc018ee733bf81b3231b4c463 \ No newline at end of file +fe7f0cbcead73a8ee5f91507238b933505bb53de \ No newline at end of file