diff --git a/cereal b/cereal index 96109a71b3..1f5c4aa350 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 96109a71b37d04b6848b46c660c1f13b542d5de8 +Subproject commit 1f5c4aa350c3783f249724e7a4ea0049e4c46a7a diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 3878b99f26..ac194693b8 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -466,14 +466,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), }, - EventName.driverMonitorLowAcc: { - ET.WARNING: Alert( - "CHECK DRIVER FACE VISIBILITY", - "Driver Monitoring Uncertain", - AlertStatus.normal, AlertSize.mid, - Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .4, 0., 1.5), - }, - EventName.manualRestart: { ET.WARNING: Alert( "TAKE CONTROL", diff --git a/selfdrive/monitoring/driver_monitor.py b/selfdrive/monitoring/driver_monitor.py index ff7bdefb96..accaf62ae2 100644 --- a/selfdrive/monitoring/driver_monitor.py +++ b/selfdrive/monitoring/driver_monitor.py @@ -39,7 +39,6 @@ _PITCH_POS_ALLOWANCE = 0.12 # rad, to not be too sensitive on positive pitch _PITCH_NATURAL_OFFSET = 0.02 # people don't seem to look straight when they drive relaxed, rather a bit up _YAW_NATURAL_OFFSET = 0.08 # people don't seem to look straight when they drive relaxed, rather a bit to the right (center of car) -_HI_STD_TIMEOUT = 5 _HI_STD_FALLBACK_TIME = 10 # fall back to wheel touch if model is uncertain for a long time _DISTRACTED_FILTER_TS = 0.25 # 0.6Hz @@ -119,7 +118,6 @@ class DriverStatus(): self.active_monitoring_mode = True self.is_model_uncertain = False self.hi_stds = 0 - self.hi_std_alert_enabled = True self.threshold_prompt = _DISTRACTED_PROMPT_TIME_TILL_TERMINAL / _DISTRACTED_TIME self._set_timers(active_monitoring=True) @@ -196,10 +194,11 @@ class DriverStatus(): self.blink.left_blink = driver_state.leftBlinkProb * (driver_state.leftEyeProb > _EYE_THRESHOLD) * (driver_state.sunglassesProb < _SG_THRESHOLD) self.blink.right_blink = driver_state.rightBlinkProb * (driver_state.rightEyeProb > _EYE_THRESHOLD) * (driver_state.sunglassesProb < _SG_THRESHOLD) - self.driver_distracted = (self._is_driver_distracted(self.pose, self.blink) > 0 and - driver_state.faceProb > _FACE_THRESHOLD and self.pose.low_std) or \ - ((driver_state.distractedPose > _E2E_POSE_THRESHOLD or driver_state.distractedEyes > _E2E_EYES_THRESHOLD) and - (self.face_detected and not self.face_partial)) + distracted_normal = (self._is_driver_distracted(self.pose, self.blink) > 0 and + driver_state.faceProb > _FACE_THRESHOLD and self.pose.low_std) + distracted_E2E = ((driver_state.distractedPose > _E2E_POSE_THRESHOLD or driver_state.distractedEyes > _E2E_EYES_THRESHOLD) and + (self.face_detected and not self.face_partial)) + self.driver_distracted = distracted_normal or distracted_E2E self.driver_distraction_filter.update(self.driver_distracted) # update offseter @@ -229,10 +228,6 @@ class DriverStatus(): driver_attentive = self.driver_distraction_filter.x < 0.37 awareness_prev = self.awareness - if self.face_detected and self.hi_stds * DT_DMON > _HI_STD_TIMEOUT and self.hi_std_alert_enabled: - events.add(EventName.driverMonitorLowAcc) - self.hi_std_alert_enabled = False # only showed once until orange prompt resets it - if (driver_attentive and self.face_detected and self.pose.low_std and self.awareness > 0): # only restore awareness when paying attention and alert is not red self.awareness = min(self.awareness + ((_RECOVERY_FACTOR_MAX-_RECOVERY_FACTOR_MIN)*(1.-self.awareness)+_RECOVERY_FACTOR_MIN)*self.step_change, 1.) @@ -242,16 +237,18 @@ class DriverStatus(): if self.awareness > self.threshold_prompt: return - # should always be counting if distracted unless at standstill and reaching orange - if (not (self.face_detected and self.hi_stds * DT_DMON <= _HI_STD_FALLBACK_TIME) or (self.driver_distraction_filter.x > 0.63 and self.driver_distracted and self.face_detected)) and \ - not (standstill and self.awareness - self.step_change <= self.threshold_prompt): - self.awareness = max(self.awareness - self.step_change, -0.1) + standstill_exemption = standstill and self.awareness - self.step_change <= self.threshold_prompt + certainly_distracted = self.driver_distraction_filter.x > 0.63 and self.driver_distracted and self.face_detected + maybe_distracted = self.hi_stds * DT_DMON > _HI_STD_FALLBACK_TIME or not self.face_detected + if certainly_distracted or maybe_distracted: + # should always be counting if distracted unless at standstill and reaching orange + if not standstill_exemption: + self.awareness = max(self.awareness - self.step_change, -0.1) alert = None if self.awareness <= 0.: # terminal red alert: disengagement required alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive - self.hi_std_alert_enabled = True self.terminal_time += 1 if awareness_prev > 0.: self.terminal_alert_cnt += 1 diff --git a/selfdrive/monitoring/test_monitoring.py b/selfdrive/monitoring/test_monitoring.py index 5872655fee..9d660496af 100755 --- a/selfdrive/monitoring/test_monitoring.py +++ b/selfdrive/monitoring/test_monitoring.py @@ -9,7 +9,7 @@ from selfdrive.monitoring.driver_monitor import DriverStatus, \ _AWARENESS_TIME, _AWARENESS_PRE_TIME_TILL_TERMINAL, \ _AWARENESS_PROMPT_TIME_TILL_TERMINAL, _DISTRACTED_TIME, \ _DISTRACTED_PRE_TIME_TILL_TERMINAL, _DISTRACTED_PROMPT_TIME_TILL_TERMINAL, \ - _POSESTD_THRESHOLD, _HI_STD_TIMEOUT, _HI_STD_FALLBACK_TIME + _POSESTD_THRESHOLD, _HI_STD_FALLBACK_TIME EventName = car.CarEvent.EventName @@ -18,7 +18,6 @@ _DISTRACTED_SECONDS_TO_ORANGE = _DISTRACTED_TIME - _DISTRACTED_PROMPT_TIME_TILL_ _DISTRACTED_SECONDS_TO_RED = _DISTRACTED_TIME + 1 _INVISIBLE_SECONDS_TO_ORANGE = _AWARENESS_TIME - _AWARENESS_PROMPT_TIME_TILL_TERMINAL + 1 _INVISIBLE_SECONDS_TO_RED = _AWARENESS_TIME + 1 -_UNCERTAIN_SECONDS_TO_GREEN = _HI_STD_TIMEOUT + 0.5 def make_msg(face_detected, distracted=False, model_uncertain=False): ds = log.DriverState.new_message() @@ -33,6 +32,7 @@ def make_msg(face_detected, distracted=False, model_uncertain=False): ds.facePositionStd = [1.*model_uncertain, 1.*model_uncertain] return ds + # driver state from neural net, 10Hz msg_NO_FACE_DETECTED = make_msg(False) msg_ATTENTIVE = make_msg(True) @@ -192,11 +192,10 @@ class TestMonitoring(unittest.TestCase): ds_vector = [msg_DISTRACTED_BUT_SOMEHOW_UNCERTAIN] * int(_TEST_TIMESPAN/DT_DMON) interaction_vector = always_false[:] events = self._run_seq(ds_vector, interaction_vector, always_true, always_false)[0] - self.assertEqual(len(events[int(_UNCERTAIN_SECONDS_TO_GREEN*0.5/DT_DMON)]), 0) - self.assertEqual(events[int((_HI_STD_TIMEOUT)/DT_DMON)].names[0], EventName.driverMonitorLowAcc) self.assertTrue(EventName.preDriverUnresponsive in events[int((_INVISIBLE_SECONDS_TO_ORANGE-1+_HI_STD_FALLBACK_TIME-0.1)/DT_DMON)].names) self.assertTrue(EventName.promptDriverUnresponsive in events[int((_INVISIBLE_SECONDS_TO_ORANGE-1+_HI_STD_FALLBACK_TIME+0.1)/DT_DMON)].names) self.assertTrue(EventName.driverUnresponsive in events[int((_INVISIBLE_SECONDS_TO_RED-1+_HI_STD_FALLBACK_TIME+0.1)/DT_DMON)].names) + if __name__ == "__main__": unittest.main()