add check driver camera alert (#36577)

* add event

* missing arg

* creation_delay is wrong

* add logging

* set offroad alert

* Update selfdrive/selfdrived/alerts_offroad.json

Co-authored-by: Shane Smiskol <shane@smiskol.com>

* rm onard

* add details

* rename to DM

* log rename

* no poss

---------

Co-authored-by: Shane Smiskol <shane@smiskol.com>
pull/36592/merge
ZwX1616 5 days ago committed by GitHub
parent 890b1cf512
commit 1262fca36b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      cereal/log.capnp
  2. 1
      common/params_keys.h
  3. 27
      selfdrive/monitoring/helpers.py
  4. 2
      selfdrive/monitoring/test_monitoring.py
  5. 4
      selfdrive/selfdrived/alerts_offroad.json

@ -2224,6 +2224,7 @@ struct DriverMonitoringState @0xb83cda094a1da284 {
hiStdCount @14 :UInt32; hiStdCount @14 :UInt32;
isActiveMode @16 :Bool; isActiveMode @16 :Bool;
isRHD @4 :Bool; isRHD @4 :Bool;
uncertainCount @19 :UInt32;
isPreviewDEPRECATED @15 :Bool; isPreviewDEPRECATED @15 :Bool;
rhdCheckedDEPRECATED @5 :Bool; rhdCheckedDEPRECATED @5 :Bool;

@ -97,6 +97,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"Offroad_TemperatureTooHigh", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_TemperatureTooHigh", {CLEAR_ON_MANAGER_START, JSON}},
{"Offroad_UnregisteredHardware", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_UnregisteredHardware", {CLEAR_ON_MANAGER_START, JSON}},
{"Offroad_UpdateFailed", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_UpdateFailed", {CLEAR_ON_MANAGER_START, JSON}},
{"Offroad_DriverMonitoringUncertain", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}},
{"OnroadCycleRequested", {CLEAR_ON_MANAGER_START, BOOL}}, {"OnroadCycleRequested", {CLEAR_ON_MANAGER_START, BOOL}},
{"OpenpilotEnabledToggle", {PERSISTENT, BOOL, "1"}}, {"OpenpilotEnabledToggle", {PERSISTENT, BOOL, "1"}},
{"PandaHeartbeatLost", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}}, {"PandaHeartbeatLost", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},

@ -4,6 +4,7 @@ import numpy as np
from cereal import car, log from cereal import car, log
import cereal.messaging as messaging import cereal.messaging as messaging
from openpilot.selfdrive.selfdrived.events import Events from openpilot.selfdrive.selfdrived.events import Events
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
from openpilot.common.realtime import DT_DMON from openpilot.common.realtime import DT_DMON
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.common.params import Params from openpilot.common.params import Params
@ -57,6 +58,9 @@ class DRIVER_MONITOR_SETTINGS:
self._YAW_MAX_OFFSET = 0.289 self._YAW_MAX_OFFSET = 0.289
self._YAW_MIN_OFFSET = -0.0246 self._YAW_MIN_OFFSET = -0.0246
self._DCAM_UNCERTAIN_ALERT_THRESHOLD = 0.1
self._DCAM_UNCERTAIN_ALERT_COUNT = int(60 / self._DT_DMON)
self._DCAM_UNCERTAIN_RESET_COUNT = int(20 / self._DT_DMON)
self._POSESTD_THRESHOLD = 0.3 self._POSESTD_THRESHOLD = 0.3
self._HI_STD_FALLBACK_TIME = int(10 / self._DT_DMON) # fall back to wheel touch if model is uncertain for 10s self._HI_STD_FALLBACK_TIME = int(10 / self._DT_DMON) # fall back to wheel touch if model is uncertain for 10s
self._DISTRACTED_FILTER_TS = 0.25 # 0.6Hz self._DISTRACTED_FILTER_TS = 0.25 # 0.6Hz
@ -158,6 +162,9 @@ class DriverMonitoring:
self.hi_stds = 0 self.hi_stds = 0
self.threshold_pre = self.settings._DISTRACTED_PRE_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME self.threshold_pre = self.settings._DISTRACTED_PRE_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME
self.threshold_prompt = self.settings._DISTRACTED_PROMPT_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME self.threshold_prompt = self.settings._DISTRACTED_PROMPT_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME
self.dcam_uncertain_cnt = 0
self.dcam_uncertain_alerted = False # once per drive
self.dcam_reset_cnt = 0
self.params = Params() self.params = Params()
self.too_distracted = self.params.get_bool("DriverTooDistracted") self.too_distracted = self.params.get_bool("DriverTooDistracted")
@ -245,7 +252,7 @@ class DriverMonitoring:
return distracted_types return distracted_types
def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged): def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, standstill):
rhd_pred = driver_state.wheelOnRightProb rhd_pred = driver_state.wheelOnRightProb
# calibrates only when there's movement and either face detected # calibrates only when there's movement and either face detected
if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or
@ -296,6 +303,16 @@ class DriverMonitoring:
self.pose.yaw_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT self.pose.yaw_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT
self.ee1_calibrated = self.ee1_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT self.ee1_calibrated = self.ee1_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT
if self.face_detected and not self.driver_distracted:
if model_std_max > self.settings._DCAM_UNCERTAIN_ALERT_THRESHOLD:
if not standstill:
self.dcam_uncertain_cnt += 1
self.dcam_reset_cnt = 0
else:
self.dcam_reset_cnt += 1
if self.dcam_reset_cnt > self.settings._DCAM_UNCERTAIN_RESET_COUNT:
self.dcam_uncertain_cnt = 0
self.is_model_uncertain = self.hi_stds > self.settings._HI_STD_FALLBACK_TIME self.is_model_uncertain = self.hi_stds > self.settings._HI_STD_FALLBACK_TIME
self._set_timers(self.face_detected and not self.is_model_uncertain) self._set_timers(self.face_detected and not self.is_model_uncertain)
if self.face_detected and not self.pose.low_std and not self.driver_distracted: if self.face_detected and not self.pose.low_std and not self.driver_distracted:
@ -372,6 +389,10 @@ class DriverMonitoring:
if alert is not None: if alert is not None:
self.current_events.add(alert) self.current_events.add(alert)
if self.dcam_uncertain_cnt > self.settings._DCAM_UNCERTAIN_ALERT_COUNT and not self.dcam_uncertain_alerted:
set_offroad_alert("Offroad_DriverMonitoringUncertain", True)
self.dcam_uncertain_alerted = True
def get_state_packet(self, valid=True): def get_state_packet(self, valid=True):
# build driverMonitoringState packet # build driverMonitoringState packet
@ -393,6 +414,7 @@ class DriverMonitoring:
"hiStdCount": self.hi_stds, "hiStdCount": self.hi_stds,
"isActiveMode": self.active_monitoring_mode, "isActiveMode": self.active_monitoring_mode,
"isRHD": self.wheel_on_right, "isRHD": self.wheel_on_right,
"uncertainCount": self.dcam_uncertain_cnt,
} }
return dat return dat
@ -408,7 +430,8 @@ class DriverMonitoring:
driver_state=sm['driverStateV2'], driver_state=sm['driverStateV2'],
cal_rpy=sm['liveCalibration'].rpyCalib, cal_rpy=sm['liveCalibration'].rpyCalib,
car_speed=sm['carState'].vEgo, car_speed=sm['carState'].vEgo,
op_engaged=sm['selfdriveState'].enabled op_engaged=sm['selfdriveState'].enabled,
standstill=sm['carState'].standstill,
) )
# Update distraction events # Update distraction events

@ -53,7 +53,7 @@ class TestMonitoring:
DM = DriverMonitoring() DM = DriverMonitoring()
events = [] events = []
for idx in range(len(msgs)): for idx in range(len(msgs)):
DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx]) DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], standstill[idx])
# cal_rpy and car_speed don't matter here # cal_rpy and car_speed don't matter here
# evaluate events at 10Hz for tests # evaluate events at 10Hz for tests

@ -37,6 +37,10 @@
"text": "openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.", "text": "openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.",
"severity": 0 "severity": 0
}, },
"Offroad_DriverMonitoringUncertain": {
"text": "openpilot detected poor visibility for driver monitoring. Ensure the device has a clear view of the driver. This can be checked using Settings -> Device -> Driver Camera Preview. Extreme lighting conditions and/or unconventional mounting positions may also trigger this alert.",
"severity": 0
},
"Offroad_ExcessiveActuation": { "Offroad_ExcessiveActuation": {
"text": "openpilot detected excessive %1 actuation on your last drive. Please contact support at https://comma.ai/support and share your device's Dongle ID for troubleshooting.", "text": "openpilot detected excessive %1 actuation on your last drive. Please contact support at https://comma.ai/support and share your device's Dongle ID for troubleshooting.",
"severity": 1, "severity": 1,

Loading…
Cancel
Save