Skip to content

Commit 1262fca

Browse files
ZwX1616sshane
andauthored
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 <[email protected]> * rm onard * add details * rename to DM * log rename * no poss --------- Co-authored-by: Shane Smiskol <[email protected]>
1 parent 890b1cf commit 1262fca

File tree

5 files changed

+32
-3
lines changed

5 files changed

+32
-3
lines changed

cereal/log.capnp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,7 @@ struct DriverMonitoringState @0xb83cda094a1da284 {
22242224
hiStdCount @14 :UInt32;
22252225
isActiveMode @16 :Bool;
22262226
isRHD @4 :Bool;
2227+
uncertainCount @19 :UInt32;
22272228

22282229
isPreviewDEPRECATED @15 :Bool;
22292230
rhdCheckedDEPRECATED @5 :Bool;

common/params_keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
9797
{"Offroad_TemperatureTooHigh", {CLEAR_ON_MANAGER_START, JSON}},
9898
{"Offroad_UnregisteredHardware", {CLEAR_ON_MANAGER_START, JSON}},
9999
{"Offroad_UpdateFailed", {CLEAR_ON_MANAGER_START, JSON}},
100+
{"Offroad_DriverMonitoringUncertain", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}},
100101
{"OnroadCycleRequested", {CLEAR_ON_MANAGER_START, BOOL}},
101102
{"OpenpilotEnabledToggle", {PERSISTENT, BOOL, "1"}},
102103
{"PandaHeartbeatLost", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},

selfdrive/monitoring/helpers.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from cereal import car, log
55
import cereal.messaging as messaging
66
from openpilot.selfdrive.selfdrived.events import Events
7+
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
78
from openpilot.common.realtime import DT_DMON
89
from openpilot.common.filter_simple import FirstOrderFilter
910
from openpilot.common.params import Params
@@ -57,6 +58,9 @@ def __init__(self):
5758
self._YAW_MAX_OFFSET = 0.289
5859
self._YAW_MIN_OFFSET = -0.0246
5960

61+
self._DCAM_UNCERTAIN_ALERT_THRESHOLD = 0.1
62+
self._DCAM_UNCERTAIN_ALERT_COUNT = int(60 / self._DT_DMON)
63+
self._DCAM_UNCERTAIN_RESET_COUNT = int(20 / self._DT_DMON)
6064
self._POSESTD_THRESHOLD = 0.3
6165
self._HI_STD_FALLBACK_TIME = int(10 / self._DT_DMON) # fall back to wheel touch if model is uncertain for 10s
6266
self._DISTRACTED_FILTER_TS = 0.25 # 0.6Hz
@@ -158,6 +162,9 @@ def __init__(self, rhd_saved=False, settings=None, always_on=False):
158162
self.hi_stds = 0
159163
self.threshold_pre = self.settings._DISTRACTED_PRE_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME
160164
self.threshold_prompt = self.settings._DISTRACTED_PROMPT_TIME_TILL_TERMINAL / self.settings._DISTRACTED_TIME
165+
self.dcam_uncertain_cnt = 0
166+
self.dcam_uncertain_alerted = False # once per drive
167+
self.dcam_reset_cnt = 0
161168

162169
self.params = Params()
163170
self.too_distracted = self.params.get_bool("DriverTooDistracted")
@@ -245,7 +252,7 @@ def _get_distracted_types(self):
245252

246253
return distracted_types
247254

248-
def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged):
255+
def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, standstill):
249256
rhd_pred = driver_state.wheelOnRightProb
250257
# calibrates only when there's movement and either face detected
251258
if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or
@@ -296,6 +303,16 @@ def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged):
296303
self.pose.yaw_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT
297304
self.ee1_calibrated = self.ee1_offseter.filtered_stat.n > self.settings._POSE_OFFSET_MIN_COUNT
298305

306+
if self.face_detected and not self.driver_distracted:
307+
if model_std_max > self.settings._DCAM_UNCERTAIN_ALERT_THRESHOLD:
308+
if not standstill:
309+
self.dcam_uncertain_cnt += 1
310+
self.dcam_reset_cnt = 0
311+
else:
312+
self.dcam_reset_cnt += 1
313+
if self.dcam_reset_cnt > self.settings._DCAM_UNCERTAIN_RESET_COUNT:
314+
self.dcam_uncertain_cnt = 0
315+
299316
self.is_model_uncertain = self.hi_stds > self.settings._HI_STD_FALLBACK_TIME
300317
self._set_timers(self.face_detected and not self.is_model_uncertain)
301318
if self.face_detected and not self.pose.low_std and not self.driver_distracted:
@@ -372,6 +389,10 @@ def _update_events(self, driver_engaged, op_engaged, standstill, wrong_gear, car
372389
if alert is not None:
373390
self.current_events.add(alert)
374391

392+
if self.dcam_uncertain_cnt > self.settings._DCAM_UNCERTAIN_ALERT_COUNT and not self.dcam_uncertain_alerted:
393+
set_offroad_alert("Offroad_DriverMonitoringUncertain", True)
394+
self.dcam_uncertain_alerted = True
395+
375396

376397
def get_state_packet(self, valid=True):
377398
# build driverMonitoringState packet
@@ -393,6 +414,7 @@ def get_state_packet(self, valid=True):
393414
"hiStdCount": self.hi_stds,
394415
"isActiveMode": self.active_monitoring_mode,
395416
"isRHD": self.wheel_on_right,
417+
"uncertainCount": self.dcam_uncertain_cnt,
396418
}
397419
return dat
398420

@@ -408,7 +430,8 @@ def run_step(self, sm):
408430
driver_state=sm['driverStateV2'],
409431
cal_rpy=sm['liveCalibration'].rpyCalib,
410432
car_speed=sm['carState'].vEgo,
411-
op_engaged=sm['selfdriveState'].enabled
433+
op_engaged=sm['selfdriveState'].enabled,
434+
standstill=sm['carState'].standstill,
412435
)
413436

414437
# Update distraction events

selfdrive/monitoring/test_monitoring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _run_seq(self, msgs, interaction, engaged, standstill):
5353
DM = DriverMonitoring()
5454
events = []
5555
for idx in range(len(msgs)):
56-
DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx])
56+
DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], standstill[idx])
5757
# cal_rpy and car_speed don't matter here
5858

5959
# evaluate events at 10Hz for tests

selfdrive/selfdrived/alerts_offroad.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
"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.",
3838
"severity": 0
3939
},
40+
"Offroad_DriverMonitoringUncertain": {
41+
"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.",
42+
"severity": 0
43+
},
4044
"Offroad_ExcessiveActuation": {
4145
"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.",
4246
"severity": 1,

0 commit comments

Comments
 (0)