From bb1a17d2a087558e80bc0783224dc6093b3ff8ef Mon Sep 17 00:00:00 2001 From: Isaac Barham Date: Fri, 28 Aug 2026 07:27:01 -0400 Subject: [PATCH] Prototype assisted driving milestones --- .gitattributes | 1 + .../selfdrive/assets/sounds/milestone.wav | Bin 0 -> 78764 bytes openpilot/selfdrive/ui/mici/layouts/main.py | 6 +- .../ui/mici/onroad/augmented_road_view.py | 11 ++ openpilot/selfdrive/ui/soundd.py | 25 ++- .../onroad/milestone_celebration_prototype.py | 181 ++++++++++++++++++ .../onroad/milestone_tracker_prototype.py | 70 +++++++ .../ui/tests/generate_milestone_sound.py | 45 +++++ .../run_milestone_celebration_prototype.sh | 22 +++ .../tests/test_milestone_tracker_prototype.py | 55 ++++++ openpilot/selfdrive/ui/tests/test_soundd.py | 29 ++- 11 files changed, 442 insertions(+), 3 deletions(-) create mode 100644 openpilot/selfdrive/assets/sounds/milestone.wav create mode 100644 openpilot/selfdrive/ui/sunnypilot/onroad/milestone_celebration_prototype.py create mode 100644 openpilot/selfdrive/ui/sunnypilot/onroad/milestone_tracker_prototype.py create mode 100644 openpilot/selfdrive/ui/tests/generate_milestone_sound.py create mode 100644 openpilot/selfdrive/ui/tests/run_milestone_celebration_prototype.sh create mode 100644 openpilot/selfdrive/ui/tests/test_milestone_tracker_prototype.py diff --git a/.gitattributes b/.gitattributes index 5cb404146d..62e66beb12 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ *.ttf filter=lfs diff=lfs merge=lfs -text *.otf filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text +openpilot/selfdrive/assets/sounds/milestone.wav -filter -diff -merge -text openpilot/selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text openpilot/common/hardware/comma/updater filter=lfs diff=lfs merge=lfs -text diff --git a/openpilot/selfdrive/assets/sounds/milestone.wav b/openpilot/selfdrive/assets/sounds/milestone.wav new file mode 100644 index 0000000000000000000000000000000000000000..91ec34c91d9f05a25cc9ab5e4e63c68d959e4b72 GIT binary patch literal 78764 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�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 list[ConfettiParticle]: + rng = random.Random(20260828) + return [ + ConfettiParticle( + x=rng.random(), + y=rng.uniform(-0.25, 0.95), + width=rng.uniform(10, 24), + height=rng.uniform(24, 58), + speed=rng.uniform(0.12, 0.34), + drift=rng.uniform(-0.035, 0.035), + angle=rng.uniform(0, 360), + spin=rng.uniform(-150, 150), + phase=rng.uniform(0, math.tau), + color=CONFETTI_COLORS[rng.randrange(len(CONFETTI_COLORS))], + ) + for _ in range(PARTICLE_COUNT) + ] + + def _render(self, rect: rl.Rectangle, /) -> None: + now = time.monotonic() + if ui_state.started_time != self._drive_started_time: + # Reset on every off-road -> on-road transition so the spike can be tested on every drive. + self._drive_started_time = ui_state.started_time + self._celebration_started_time = None + self._current_milestone = None + self._pending_milestones.clear() + self._tracker.reset() + self._screenshot_taken = False + self._screenshot_ready = False + + car_control = ui_state.sm["carControl"] + category = assist_category(car_control.latActive, car_control.longActive) + + self._pending_milestones.extend(self._tracker.update( + ui_state.sm.logMonoTime["carState"], + ui_state.sm["carState"].vEgo, + category, + )) + + if self._current_milestone is None and self._pending_milestones: + self._current_milestone = self._pending_milestones.popleft() + self._celebration_started_time = now + + if self._celebration_started_time is None or self._current_milestone is None: + return + + elapsed = now - self._celebration_started_time + if elapsed >= CELEBRATION_DURATION: + self._celebration_started_time = None + self._current_milestone = None + return + + alpha = min(1.0, elapsed / 0.2, (CELEBRATION_DURATION - elapsed) / 0.8) + self._draw_confetti(rect, elapsed, alpha) + self._draw_milestone_card(rect, elapsed, alpha, self._current_milestone) + self._screenshot_ready = elapsed >= 1.0 + + def capture_screenshot(self) -> None: + screenshot_path = os.getenv("SP_MILESTONE_SCREENSHOT") + if screenshot_path and self._screenshot_ready and not self._screenshot_taken: + rl.rl_draw_render_batch_active() + rl.take_screenshot(screenshot_path) + self._screenshot_taken = True + + def _draw_confetti(self, rect: rl.Rectangle, elapsed: float, alpha: float) -> None: + travel_height = rect.height * 1.45 + compact = rect.height <= 300 + particle_scale = rect.height / 1080.0 + particles = self._particles[:100] if compact else self._particles + for particle in particles: + x = rect.x + rect.width * (particle.x + particle.drift * elapsed + 0.012 * math.sin(elapsed * 3 + particle.phase)) + y = rect.y - rect.height * 0.2 + (particle.y * travel_height + particle.speed * rect.height * elapsed) % travel_height + flip = 0.2 + 0.8 * abs(math.sin(elapsed * 5 + particle.phase)) + particle_rect = rl.Rectangle(x, y, particle.width * particle_scale * flip, particle.height * particle_scale) + origin = rl.Vector2(particle_rect.width / 2, particle_rect.height / 2) + color = rl.Color(particle.color.r, particle.color.g, particle.color.b, int(245 * alpha)) + rl.draw_rectangle_pro(particle_rect, origin, particle.angle + particle.spin * elapsed, color) + + @staticmethod + def _draw_milestone_card(rect: rl.Rectangle, elapsed: float, alpha: float, milestone: DistanceMilestone) -> None: + compact = rect.height <= 300 + scale = rect.height / (240.0 if compact else 1080.0) + card_width = (210 if compact else 590) * scale + card_height = (82 if compact else 230) * scale + pulse = 1.0 + 0.025 * math.sin(min(elapsed, 0.6) / 0.6 * math.pi) + card_width *= pulse + card_height *= pulse + card = rl.Rectangle( + rect.x + (rect.width - card_width) / 2, + rect.y + (rect.height - card_height) / 2, + card_width, + card_height, + ) + + rl.draw_rectangle_rounded(card, 0.20, 16, rl.Color(25, 31, 42, int(225 * alpha))) + rl.draw_rectangle_rounded_lines_ex(card, 0.20, 16, max(1, int(2 * scale)), rl.Color(255, 255, 255, int(90 * alpha))) + + number_font = gui_app.font(FontWeight.BOLD) + label_font = gui_app.font(FontWeight.MEDIUM) + number_size = int((35 if compact else 98) * scale) + label_size = int((14 if compact else 42) * scale) + number = f"{milestone.distance_miles:.1f} mi" + label = "FULL ASSIST MILESTONE" if milestone.category == AssistCategory.FULL_ASSIST else "MADS MILESTONE" + + number_bounds = measure_text_cached(number_font, number, number_size) + label_bounds = measure_text_cached(label_font, label, label_size) + number_y = 9 if compact else 35 + label_y = 55 if compact else 145 + number_pos = rl.Vector2(card.x + (card.width - number_bounds.x) / 2, card.y + number_y * scale) + label_pos = rl.Vector2(card.x + (card.width - label_bounds.x) / 2, card.y + label_y * scale) + rl.draw_text_ex(number_font, number, number_pos, number_size, 0, rl.Color(255, 255, 255, int(255 * alpha))) + rl.draw_text_ex(label_font, label, label_pos, label_size, 2 * scale, rl.Color(220, 226, 235, int(230 * alpha))) diff --git a/openpilot/selfdrive/ui/sunnypilot/onroad/milestone_tracker_prototype.py b/openpilot/selfdrive/ui/sunnypilot/onroad/milestone_tracker_prototype.py new file mode 100644 index 0000000000..4eecef836a --- /dev/null +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/milestone_tracker_prototype.py @@ -0,0 +1,70 @@ +"""PROTOTYPE: per-drive assisted-distance milestone tracking.""" + +from dataclasses import dataclass +from enum import StrEnum + + +METERS_PER_MILE = 1609.344 +TEST_MILESTONE_MILES = 0.5 +MAX_SAMPLE_INTERVAL_SECONDS = 0.5 + + +class AssistCategory(StrEnum): + MADS = "mads" + FULL_ASSIST = "full_assist" + + +def assist_category(lat_active: bool, long_active: bool) -> AssistCategory | None: + if not lat_active: + return None + return AssistCategory.FULL_ASSIST if long_active else AssistCategory.MADS + + +@dataclass(frozen=True) +class DistanceMilestone: + category: AssistCategory + distance_meters: float + + @property + def distance_miles(self) -> float: + return self.distance_meters / METERS_PER_MILE + + +class PerDriveMilestoneTracker: + def __init__(self, milestone_meters: float = TEST_MILESTONE_MILES * METERS_PER_MILE): + if milestone_meters <= 0: + raise ValueError("milestone distance must be positive") + self.milestone_meters = milestone_meters + self.reset() + + def reset(self) -> None: + self._distance_meters = dict.fromkeys(AssistCategory, 0.0) + self._next_milestone_meters = dict.fromkeys(AssistCategory, self.milestone_meters) + self._last_timestamp_ns: int | None = None + self._last_speed_mps = 0.0 + self._last_category: AssistCategory | None = None + + def distance_meters(self, category: AssistCategory) -> float: + return self._distance_meters[category] + + def update(self, timestamp_ns: int, speed_mps: float, category: AssistCategory | None) -> list[DistanceMilestone]: + milestones: list[DistanceMilestone] = [] + speed_mps = max(0.0, speed_mps) + + if self._last_timestamp_ns is not None and timestamp_ns != self._last_timestamp_ns: + dt = (timestamp_ns - self._last_timestamp_ns) / 1e9 + if 0 < dt <= MAX_SAMPLE_INTERVAL_SECONDS and self._last_category is not None: + delta_meters = (self._last_speed_mps + speed_mps) / 2.0 * dt + active_category = self._last_category + self._distance_meters[active_category] += delta_meters + + next_milestone = self._next_milestone_meters[active_category] + while self._distance_meters[active_category] >= next_milestone: + milestones.append(DistanceMilestone(active_category, next_milestone)) + next_milestone += self.milestone_meters + self._next_milestone_meters[active_category] = next_milestone + + self._last_timestamp_ns = timestamp_ns + self._last_speed_mps = speed_mps + self._last_category = category + return milestones diff --git a/openpilot/selfdrive/ui/tests/generate_milestone_sound.py b/openpilot/selfdrive/ui/tests/generate_milestone_sound.py new file mode 100644 index 0000000000..5d7fc7b86c --- /dev/null +++ b/openpilot/selfdrive/ui/tests/generate_milestone_sound.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Generate the temporary milestone celebration chime.""" + +import math +import wave +from array import array +from pathlib import Path + + +SAMPLE_RATE = 48_000 +DURATION_SECONDS = 0.82 +NOTES = ( + (0.00, 523.25), + (0.11, 659.25), + (0.22, 783.99), +) + + +def note_sample(age: float, frequency: float) -> float: + if not 0 <= age <= 0.58: + return 0.0 + attack = min(age / 0.008, 1.0) + release = min((0.58 - age) / 0.15, 1.0) + envelope = attack * release * math.exp(-3.8 * age) + tone = math.sin(math.tau * frequency * age) + 0.16 * math.sin(math.tau * frequency * 2 * age) + return envelope * tone + + +def main() -> None: + output = Path(__file__).parents[4] / "openpilot/selfdrive/assets/sounds/milestone.wav" + samples = array('h') + for frame in range(round(SAMPLE_RATE * DURATION_SECONDS)): + t = frame / SAMPLE_RATE + value = 0.38 * sum(note_sample(t - start, frequency) for start, frequency in NOTES) + samples.append(round(max(-1.0, min(1.0, value)) * 32767)) + + with wave.open(str(output), "wb") as wav: + wav.setnchannels(1) + wav.setsampwidth(2) + wav.setframerate(SAMPLE_RATE) + wav.writeframes(samples.tobytes()) + + +if __name__ == "__main__": + main() diff --git a/openpilot/selfdrive/ui/tests/run_milestone_celebration_prototype.sh b/openpilot/selfdrive/ui/tests/run_milestone_celebration_prototype.sh new file mode 100644 index 0000000000..b0868400db --- /dev/null +++ b/openpilot/selfdrive/ui/tests/run_milestone_celebration_prototype.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# PROTOTYPE: launch the demo replay and comma four milestone celebration together. +set -e + +prototype_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +prototype_replay_pid="" + +cleanup_prototype() { + if [[ -n "$prototype_replay_pid" ]]; then + kill "$prototype_replay_pid" 2>/dev/null || true + wait "$prototype_replay_pid" 2>/dev/null || true + fi +} +trap cleanup_prototype EXIT INT TERM + +export PATH="$prototype_root/.venv/bin:$PATH" +export SP_MILESTONE_PROTOTYPE=1 + +"$prototype_root/openpilot/tools/replay/replay" --demo & +prototype_replay_pid=$! + +"$prototype_root/.venv/bin/python" "$prototype_root/openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py" diff --git a/openpilot/selfdrive/ui/tests/test_milestone_tracker_prototype.py b/openpilot/selfdrive/ui/tests/test_milestone_tracker_prototype.py new file mode 100644 index 0000000000..9cd18c019c --- /dev/null +++ b/openpilot/selfdrive/ui/tests/test_milestone_tracker_prototype.py @@ -0,0 +1,55 @@ +import unittest + +from openpilot.selfdrive.ui.sunnypilot.onroad.milestone_tracker_prototype import ( + AssistCategory, + PerDriveMilestoneTracker, + assist_category, +) + + +class TestPerDriveMilestoneTracker(unittest.TestCase): + def test_classifies_actual_actuation(self): + self.assertIsNone(assist_category(False, False)) + self.assertIsNone(assist_category(False, True)) + self.assertEqual(assist_category(True, False), AssistCategory.MADS) + self.assertEqual(assist_category(True, True), AssistCategory.FULL_ASSIST) + + def test_tracks_categories_and_emits_repeated_milestones(self): + tracker = PerDriveMilestoneTracker(milestone_meters=10.0) + + self.assertEqual(tracker.update(0, 10.0, AssistCategory.MADS), []) + self.assertEqual(tracker.update(500_000_000, 10.0, AssistCategory.MADS), []) + milestones = tracker.update(1_000_000_000, 10.0, AssistCategory.FULL_ASSIST) + self.assertEqual([(m.category, m.distance_meters) for m in milestones], [(AssistCategory.MADS, 10.0)]) + + self.assertEqual(tracker.update(1_500_000_000, 10.0, AssistCategory.FULL_ASSIST), []) + milestones = tracker.update(2_000_000_000, 10.0, AssistCategory.FULL_ASSIST) + self.assertEqual([(m.category, m.distance_meters) for m in milestones], [(AssistCategory.FULL_ASSIST, 10.0)]) + + self.assertEqual(tracker.update(2_500_000_000, 10.0, AssistCategory.FULL_ASSIST), []) + milestones = tracker.update(3_000_000_000, 10.0, AssistCategory.FULL_ASSIST) + self.assertEqual([(m.category, m.distance_meters) for m in milestones], [(AssistCategory.FULL_ASSIST, 20.0)]) + + def test_does_not_count_unassisted_time_or_timestamp_gaps(self): + tracker = PerDriveMilestoneTracker(milestone_meters=10.0) + + tracker.update(0, 20.0, None) + tracker.update(500_000_000, 20.0, AssistCategory.MADS) + self.assertEqual(tracker.distance_meters(AssistCategory.MADS), 0.0) + + tracker.update(2_000_000_000, 20.0, AssistCategory.MADS) + self.assertEqual(tracker.distance_meters(AssistCategory.MADS), 0.0) + + def test_reset_clears_per_drive_distance_and_sampling_state(self): + tracker = PerDriveMilestoneTracker(milestone_meters=10.0) + tracker.update(0, 10.0, AssistCategory.MADS) + tracker.update(500_000_000, 10.0, AssistCategory.MADS) + + tracker.reset() + + self.assertEqual(tracker.distance_meters(AssistCategory.MADS), 0.0) + self.assertEqual(tracker.update(1_000_000_000, 10.0, AssistCategory.MADS), []) + + +if __name__ == "__main__": + unittest.main() diff --git a/openpilot/selfdrive/ui/tests/test_soundd.py b/openpilot/selfdrive/ui/tests/test_soundd.py index 3416a22c98..38e7721202 100644 --- a/openpilot/selfdrive/ui/tests/test_soundd.py +++ b/openpilot/selfdrive/ui/tests/test_soundd.py @@ -1,15 +1,42 @@ import threading import time +from types import SimpleNamespace from openpilot.common.test import OpenpilotTestCase from openpilot.cereal import log, messaging from openpilot.cereal.messaging import SubMaster, PubMaster -from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert +from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, Soundd, check_selfdrive_timeout_alert +from openpilot.selfdrive.ui.sunnypilot.onroad.milestone_tracker_prototype import PerDriveMilestoneTracker AudibleAlert = log.SelfdriveState.AudibleAlert class TestSoundd(OpenpilotTestCase): + def test_milestone_chime_uses_real_assisted_distance(self): + soundd = Soundd() + soundd.milestone_tracker = PerDriveMilestoneTracker(milestone_meters=10.0) + + class SubMasterStub: + def __init__(self): + self.logMonoTime = {'carState': 0} + self.data = { + 'deviceState': SimpleNamespace(started=True), + 'carState': SimpleNamespace(vEgo=10.0), + 'carControl': SimpleNamespace(latActive=True, longActive=True), + } + + def __getitem__(self, service): + return self.data[service] + + sm = SubMasterStub() + soundd.update_milestone_alert(sm) + sm.logMonoTime['carState'] = 500_000_000 + soundd.update_milestone_alert(sm) + sm.logMonoTime['carState'] = 1_000_000_000 + soundd.update_milestone_alert(sm) + + assert soundd.current_alert == AudibleAlert.complete + def test_check_selfdrive_timeout_alert(self, mocker): sm = SubMaster(['selfdriveState', 'selfdriveStateSP']) pm = PubMaster(['selfdriveState', 'selfdriveStateSP'])