From d8569b07ebeed5fcb2b466fcd3824b968b4a8271 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Wed, 1 Apr 2026 16:14:15 -0700 Subject: [PATCH] DM: Lancia Delta HF Integrale model (#37696) * 00c00ac7-7b6e-4546-b86f-7ddd5f0596b4 * mici cleanup * update msg * rename --- cereal/log.capnp | 12 +++++----- .../assets/icons_mici/onroad/glasses.png | 3 --- selfdrive/modeld/dmonitoringmodeld.py | 9 +++----- .../modeld/models/dmonitoring_model.onnx | 4 ++-- selfdrive/monitoring/helpers.py | 19 +++++----------- selfdrive/monitoring/test_monitoring.py | 6 ++--- selfdrive/test/process_replay/model_replay.py | 2 +- .../ui/mici/onroad/driver_camera_dialog.py | 22 ++++--------------- 8 files changed, 24 insertions(+), 53 deletions(-) delete mode 100644 selfdrive/assets/icons_mici/onroad/glasses.png diff --git a/cereal/log.capnp b/cereal/log.capnp index d8e9f56316..56af5ae5f6 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -2176,12 +2176,14 @@ struct DriverStateV2 { facePosition @2 :List(Float32); facePositionStd @3 :List(Float32); faceProb @4 :Float32; - leftEyeProb @5 :Float32; - rightEyeProb @6 :Float32; - leftBlinkProb @7 :Float32; - rightBlinkProb @8 :Float32; - sunglassesProb @9 :Float32; + eyesVisibleProb @14 :Float32; + eyesClosedProb @15 :Float32; phoneProb @13 :Float32; + leftEyeProbDEPRECATED @5 :Float32; + rightEyeProbDEPRECATED @6 :Float32; + leftBlinkProbDEPRECATED @7 :Float32; + rightBlinkProbDEPRECATED @8 :Float32; + sunglassesProbDEPRECATED @9 :Float32; notReadyProbDEPRECATED @12 :List(Float32); occludedProbDEPRECATED @10 :Float32; readyProbDEPRECATED @11 :List(Float32); diff --git a/selfdrive/assets/icons_mici/onroad/glasses.png b/selfdrive/assets/icons_mici/onroad/glasses.png deleted file mode 100644 index 006972fd39..0000000000 --- a/selfdrive/assets/icons_mici/onroad/glasses.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56de402482b5987ed9a0ff3f793a1c89f857304b34fbb8a3deb5b5d4a332be1c -size 3688 diff --git a/selfdrive/modeld/dmonitoringmodeld.py b/selfdrive/modeld/dmonitoringmodeld.py index 28190db3e6..efd8214b9f 100755 --- a/selfdrive/modeld/dmonitoringmodeld.py +++ b/selfdrive/modeld/dmonitoringmodeld.py @@ -80,7 +80,7 @@ def parse_model_output(model_output): face_descs = model_output[f'face_descs_{ds_suffix}'] parsed[f'face_descs_{ds_suffix}'] = face_descs[:, :-6] parsed[f'face_descs_{ds_suffix}_std'] = safe_exp(face_descs[:, -6:]) - for key in ['face_prob', 'left_eye_prob', 'right_eye_prob','left_blink_prob', 'right_blink_prob', 'sunglasses_prob', 'using_phone_prob']: + for key in ['face_prob', 'eyes_visible_prob', 'eyes_closed_prob', 'using_phone_prob']: parsed[f'{key}_{ds_suffix}'] = sigmoid(model_output[f'{key}_{ds_suffix}']) return parsed @@ -90,11 +90,8 @@ def fill_driver_data(msg, model_output, ds_suffix): msg.facePosition = model_output[f'face_descs_{ds_suffix}'][0, 3:5].tolist() msg.facePositionStd = model_output[f'face_descs_{ds_suffix}_std'][0, 3:5].tolist() msg.faceProb = model_output[f'face_prob_{ds_suffix}'][0, 0].item() - msg.leftEyeProb = model_output[f'left_eye_prob_{ds_suffix}'][0, 0].item() - msg.rightEyeProb = model_output[f'right_eye_prob_{ds_suffix}'][0, 0].item() - msg.leftBlinkProb = model_output[f'left_blink_prob_{ds_suffix}'][0, 0].item() - msg.rightBlinkProb = model_output[f'right_blink_prob_{ds_suffix}'][0, 0].item() - msg.sunglassesProb = model_output[f'sunglasses_prob_{ds_suffix}'][0, 0].item() + msg.eyesVisibleProb = model_output[f'eyes_visible_prob_{ds_suffix}'][0, 0].item() + msg.eyesClosedProb = model_output[f'eyes_closed_prob_{ds_suffix}'][0, 0].item() msg.phoneProb = model_output[f'using_phone_prob_{ds_suffix}'][0, 0].item() def get_driverstate_packet(model_output, frame_id: int, location_ts: int, exec_time: float, gpu_exec_time: float): diff --git a/selfdrive/modeld/models/dmonitoring_model.onnx b/selfdrive/modeld/models/dmonitoring_model.onnx index dc621bed03..628f385796 100644 --- a/selfdrive/modeld/models/dmonitoring_model.onnx +++ b/selfdrive/modeld/models/dmonitoring_model.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7aff7ff1dc08bbaf562a8f77380ab5e5914f8557dba2f760d87e4d953f5604b0 -size 7307246 +oid sha256:2fd471febb6e973313ac0d0c6755f6410c1937ba92230b58a433761e8c883072 +size 7364290 diff --git a/selfdrive/monitoring/helpers.py b/selfdrive/monitoring/helpers.py index 19d169da42..90cc565802 100644 --- a/selfdrive/monitoring/helpers.py +++ b/selfdrive/monitoring/helpers.py @@ -32,9 +32,8 @@ class DRIVER_MONITOR_SETTINGS: self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6. self._FACE_THRESHOLD = 0.7 - self._EYE_THRESHOLD = 0.65 - self._SG_THRESHOLD = 0.9 - self._BLINK_THRESHOLD = 0.865 + self._EYE_THRESHOLD = 0.5 + self._BLINK_THRESHOLD = 0.5 self._PHONE_THRESH = 0.5 self._POSE_PITCH_THRESHOLD = 0.3133 @@ -111,11 +110,6 @@ class DriverProb: self.prob_offseter = RunningStatFilter(raw_priors=raw_priors, max_trackable=max_trackable) self.prob_calibrated = False -class DriverBlink: - def __init__(self): - self.left = 0. - self.right = 0. - # model output refers to center of undistorted+leveled image EFL = 598.0 # focal length in K @@ -150,7 +144,7 @@ class DriverMonitoring: wheelpos_filter_raw_priors = (self.settings._WHEELPOS_DATA_AVG, self.settings._WHEELPOS_DATA_VAR, 2) self.wheelpos = DriverProb(raw_priors=wheelpos_filter_raw_priors, max_trackable=self.settings._WHEELPOS_MAX_COUNT) self.pose = DriverPose(settings=self.settings) - self.blink = DriverBlink() + self.blink_prob = 0. self.phone_prob = 0. self.always_on = always_on @@ -253,7 +247,7 @@ class DriverMonitoring: if pitch_error > pitch_threshold or yaw_error > yaw_threshold: distracted_types.append(DistractedType.DISTRACTED_POSE) - if (self.blink.left + self.blink.right)*0.5 > self.settings._BLINK_THRESHOLD: + if self.blink_prob > self.settings._BLINK_THRESHOLD: distracted_types.append(DistractedType.DISTRACTED_BLINK) if self.phone_prob > self.settings._PHONE_THRESH: @@ -294,10 +288,7 @@ class DriverMonitoring: self.pose.yaw_std = driver_data.faceOrientationStd[1] model_std_max = max(self.pose.pitch_std, self.pose.yaw_std) self.pose.low_std = model_std_max < self.settings._POSESTD_THRESHOLD - self.blink.left = driver_data.leftBlinkProb * (driver_data.leftEyeProb > self.settings._EYE_THRESHOLD) \ - * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) - self.blink.right = driver_data.rightBlinkProb * (driver_data.rightEyeProb > self.settings._EYE_THRESHOLD) \ - * (driver_data.sunglassesProb < self.settings._SG_THRESHOLD) + self.blink_prob = driver_data.eyesClosedProb * (driver_data.eyesVisibleProb > self.settings._EYE_THRESHOLD) self.phone_prob = driver_data.phoneProb self.distracted_types = self._get_distracted_types() diff --git a/selfdrive/monitoring/test_monitoring.py b/selfdrive/monitoring/test_monitoring.py index 15eb2c8605..733ea85bc0 100644 --- a/selfdrive/monitoring/test_monitoring.py +++ b/selfdrive/monitoring/test_monitoring.py @@ -19,10 +19,8 @@ def make_msg(face_detected, distracted=False, model_uncertain=False): ds.leftDriverData.faceOrientation = [0., 0., 0.] ds.leftDriverData.facePosition = [0., 0.] ds.leftDriverData.faceProb = 1. * face_detected - ds.leftDriverData.leftEyeProb = 1. - ds.leftDriverData.rightEyeProb = 1. - ds.leftDriverData.leftBlinkProb = 1. * distracted - ds.leftDriverData.rightBlinkProb = 1. * distracted + ds.leftDriverData.eyesVisibleProb = 1. + ds.leftDriverData.eyesClosedProb = 1. * distracted ds.leftDriverData.faceOrientationStd = [1.*model_uncertain, 1.*model_uncertain, 1.*model_uncertain] ds.leftDriverData.facePositionStd = [1.*model_uncertain, 1.*model_uncertain] # TODO: test both separately when e2e is used diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index a6ccaa1047..eb7cdbe34a 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -76,7 +76,7 @@ def generate_report(proposed, master, tmp, commit): (lambda x: get_idx_if_non_empty(x.wheelOnRightProb), "wheelOnRightProb"), (lambda x: get_idx_if_non_empty(x.leftDriverData.faceProb), "leftDriverData.faceProb"), (lambda x: get_idx_if_non_empty(x.leftDriverData.faceOrientation, 0), "leftDriverData.faceOrientation0"), - (lambda x: get_idx_if_non_empty(x.leftDriverData.leftBlinkProb), "leftDriverData.leftBlinkProb"), + (lambda x: get_idx_if_non_empty(x.leftDriverData.eyesClosedProb), "leftDriverData.eyesClosedProb"), (lambda x: get_idx_if_non_empty(x.leftDriverData.phoneProb), "leftDriverData.phoneProb"), (lambda x: get_idx_if_non_empty(x.rightDriverData.faceProb), "rightDriverData.faceProb"), ], "driverStateV2") diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/selfdrive/ui/mici/onroad/driver_camera_dialog.py index e8321b099c..e8b8abb7f5 100644 --- a/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -39,8 +39,6 @@ class BaseDriverCameraDialog(Widget): self._eye_fill_texture = None self._eye_orange_texture = None self._eye_size = 74 - self._glasses_texture = None - self._glasses_size = 171 self._load_eye_textures() @@ -154,8 +152,6 @@ class BaseDriverCameraDialog(Widget): self._eye_fill_texture = gui_app.texture("icons_mici/onroad/eye_fill.png", self._eye_size, self._eye_size) if self._eye_orange_texture is None: self._eye_orange_texture = gui_app.texture("icons_mici/onroad/eye_orange.png", self._eye_size, self._eye_size) - if self._glasses_texture is None: - self._glasses_texture = gui_app.texture("icons_mici/onroad/glasses.png", self._glasses_size, self._glasses_size) def _draw_face_detection(self, rect: rl.Rectangle): dm_state = ui_state.sm["driverMonitoringState"] @@ -202,31 +198,21 @@ class BaseDriverCameraDialog(Widget): eye_offset_x = 10 eye_offset_y = 10 eye_spacing = self._eye_size + 15 + eyes_prob = driver_data.eyesVisibleProb left_eye_x = rect.x + eye_offset_x left_eye_y = rect.y + eye_offset_y - left_eye_prob = driver_data.leftEyeProb right_eye_x = rect.x + eye_offset_x + eye_spacing right_eye_y = rect.y + eye_offset_y - right_eye_prob = driver_data.rightEyeProb # Draw eyes with opacity based on probability - for eye_x, eye_y, eye_prob in [(left_eye_x, left_eye_y, left_eye_prob), (right_eye_x, right_eye_y, right_eye_prob)]: - fill_opacity = eye_prob - orange_opacity = 1.0 - eye_prob - + fill_opacity = eyes_prob + orange_opacity = 1.0 - eyes_prob + for eye_x, eye_y in [(left_eye_x, left_eye_y), (right_eye_x, right_eye_y)]: rl.draw_texture_v(self._eye_orange_texture, (eye_x, eye_y), rl.Color(255, 255, 255, int(255 * orange_opacity))) rl.draw_texture_v(self._eye_fill_texture, (eye_x, eye_y), rl.Color(255, 255, 255, int(255 * fill_opacity))) - # Draw sunglasses indicator based on sunglasses probability - # Position glasses centered between the two eyes at top left - glasses_x = rect.x + eye_offset_x - 4 - glasses_y = rect.y - glasses_pos = rl.Vector2(glasses_x, glasses_y) - glasses_prob = driver_data.sunglassesProb - rl.draw_texture_v(self._glasses_texture, glasses_pos, rl.Color(70, 80, 161, int(255 * glasses_prob))) - class DriverCameraDialog(NavWidget, BaseDriverCameraDialog): def __init__(self):