diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 9db1e2081..150173b7b 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import os import math +import random import time import threading from typing import SupportsFloat @@ -21,7 +22,7 @@ from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.car.car_helpers import get_car_interface, get_startup_event from openpilot.selfdrive.controls.lib.alertmanager import AlertManager, set_offroad_alert -from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, clip_curvature +from openpilot.selfdrive.controls.lib.drive_helpers import IMPERIAL_INCREMENT, VCruiseHelper, clip_curvature from openpilot.selfdrive.controls.lib.events import Events, ET from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID @@ -194,10 +195,14 @@ class Controls: self.always_on_lateral_active = False self.drive_added = False + self.fcw_random_event_triggered = False self.holiday_theme_alerted = False + self.no_entry_alert_played = False + self.no_entry_alert_triggered = False self.onroad_distance_pressed = False self.openpilot_crashed_triggered = False self.previous_traffic_mode = False + self.random_event_triggered = False self.resume_pressed = False self.resume_previously_pressed = False self.speed_check = False @@ -208,7 +213,10 @@ class Controls: self.display_timer = 0 self.drive_distance = 0 self.drive_time = 0 + self.max_acceleration = 0 self.previous_speed_limit = 0 + self.previous_v_cruise = 0 + self.random_event_timer = 0 self.speed_limit_timer = 0 def set_initial_state(self): @@ -411,6 +419,11 @@ class Controls: planner_fcw = self.sm['longitudinalPlan'].fcw and self.enabled if (planner_fcw or model_fcw) and not (self.CP.notCar and self.joystick_mode): self.events.add(EventName.fcw) + self.fcw_random_event_triggered = not self.random_event_triggered + elif self.fcw_random_event_triggered and self.frogpilot_toggles.random_events: + self.events.add(EventName.yourFrogTriedToKillMe) + self.fcw_random_event_triggered = False + self.random_event_triggered = True for m in messaging.drain_sock(self.log_sock, wait_for_one=False): try: @@ -553,6 +566,7 @@ class Controls: if self.events.contains(ET.ENABLE): if self.events.contains(ET.NO_ENTRY): self.current_alert_types.append(ET.NO_ENTRY) + self.no_entry_alert_triggered = True else: if self.events.contains(ET.PRE_ENABLE): @@ -665,8 +679,18 @@ class Controls: turning = abs(lac_log.desiredLateralAccel) > 1.0 good_speed = CS.vEgo > 5 max_torque = abs(self.sm['carOutput'].actuatorsOutput.steer) > 0.99 - if undershooting and turning and good_speed and max_torque: - lac_log.active and self.events.add(EventName.goatSteerSaturated if self.frogpilot_toggles.goat_scream else EventName.steerSaturated) + if undershooting and turning and good_speed and max_torque and not self.random_event_triggered: + event_choices = [1, 2] + if self.sm.frame % (10000 // len(event_choices)) == 0 and self.frogpilot_toggles.random_events: + event_choice = random.choice(event_choices) + if event_choice == 1: + lac_log.active and self.events.add(EventName.firefoxSteerSaturated) + self.params_memory.put_int("CurrentRandomEvent", 1) + elif event_choice == 2: + lac_log.active and self.events.add(EventName.goatSteerSaturated) + self.random_event_triggered = True + else: + lac_log.active and self.events.add(EventName.goatSteerSaturated if self.frogpilot_toggles.goat_scream else EventName.steerSaturated) elif lac_log.saturated: # TODO probably should not use dpath_points but curvature dpath_points = model_v2.position.y @@ -933,9 +957,56 @@ class Controls: self.events.add(EventName.leadDeparting) if not self.openpilot_crashed_triggered and os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')): - self.events.add(EventName.openpilotCrashed) + if self.frogpilot_toggles.random_events: + self.events.add(EventName.openpilotCrashedRandomEvent) + else: + self.events.add(EventName.openpilotCrashed) self.openpilot_crashed_triggered = True + if self.frogpilot_toggles.random_events and not self.random_event_triggered: + acceleration = CS.aEgo + + if not CS.gasPressed: + self.max_acceleration = max(acceleration, self.max_acceleration) + else: + self.max_acceleration = 0 + + if 3.5 > self.max_acceleration >= 3.0 and acceleration < 1.5: + self.events.add(EventName.accel30) + self.params_memory.put_int("CurrentRandomEvent", 2) + self.random_event_triggered = True + self.max_acceleration = 0 + + elif 4.0 > self.max_acceleration >= 3.5 and acceleration < 1.5: + self.events.add(EventName.accel35) + self.params_memory.put_int("CurrentRandomEvent", 3) + self.random_event_triggered = True + self.max_acceleration = 0 + + elif self.max_acceleration >= 4.0 and acceleration < 1.5: + self.events.add(EventName.accel40) + self.params_memory.put_int("CurrentRandomEvent", 4) + self.random_event_triggered = True + self.max_acceleration = 0 + + if frogpilotPlan.takingCurveQuickly: + self.events.add(EventName.dejaVuCurve) + self.params_memory.put_int("CurrentRandomEvent", 5) + self.random_event_triggered = True + + if self.no_entry_alert_triggered and not self.no_entry_alert_played: + self.events.add(EventName.hal9000) + self.no_entry_alert_played = True + self.random_event_triggered = True + + conversion = 1 if self.is_metric else IMPERIAL_INCREMENT + v_cruise = max(self.v_cruise_helper.v_cruise_kph, self.v_cruise_helper.v_cruise_cluster_kph) * conversion + + if 70 > v_cruise >= 69 and v_cruise != self.previous_v_cruise: + self.events.add(EventName.vCruise69) + self.random_event_triggered = True + self.previous_v_cruise = v_cruise + if self.frogpilot_toggles.speed_limit_alert and self.speed_limit_changed: self.events.add(EventName.speedLimitChanged) @@ -994,6 +1065,13 @@ class Controls: self.experimental_mode = not self.experimental_mode self.params.put_bool_nonblocking("ExperimentalMode", self.experimental_mode) + if self.random_event_triggered: + self.random_event_timer += DT_CTRL + if self.random_event_timer >= 4: + self.random_event_triggered = False + self.random_event_timer = 0 + self.params_memory.remove("CurrentRandomEvent") + if self.sm.frame % 10 == 0 or self.resume_pressed: self.resume_previously_pressed = self.resume_pressed diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index 4eef1c2d7..9c3ac1e6c 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -14,7 +14,7 @@ V_CRUISE_MAX = 145 V_CRUISE_UNSET = 255 V_CRUISE_INITIAL = 40 V_CRUISE_INITIAL_EXPERIMENTAL_MODE = 105 -IMPERIAL_INCREMENT = 1.6 # should be CV.MPH_TO_KPH, but this causes rounding errors +IMPERIAL_INCREMENT = round(CV.MPH_TO_KPH, 1) # round here to avoid rounding errors incrementing set speed MIN_SPEED = 1.0 CONTROL_N = 17 diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 09af3a436..6780ba3d8 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -1117,6 +1117,79 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { AlertStatus.normal, AlertSize.small, Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .1, alert_rate=0.75), }, + + # Random Events + EventName.accel30: { + ET.WARNING: Alert( + "UwU u went a bit fast there!", + "(⁄ ⁄•⁄ω⁄•⁄ ⁄)", + AlertStatus.frogpilot, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.uwu, 4.), + }, + + EventName.accel35: { + ET.WARNING: Alert( + "I ain't giving you no tree-fiddy", + "You damn Loch Ness Monsta!", + AlertStatus.frogpilot, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.nessie, 4.), + }, + + EventName.accel40: { + ET.WARNING: Alert( + "Great Scott!", + "🚗💨", + AlertStatus.frogpilot, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.doc, 4.), + }, + + EventName.dejaVuCurve: { + ET.WARNING: Alert( + "♬♪ Deja vu! ᕕ(⌐■_■)ᕗ ♪♬", + "🏎️", + AlertStatus.frogpilot, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.dejaVu, 4.), + }, + + EventName.firefoxSteerSaturated: { + ET.WARNING: Alert( + "Turn Exceeds Steering Limit", + "IE Has Stopped Responding...", + AlertStatus.userPrompt, AlertSize.mid, + Priority.LOW, VisualAlert.steerRequired, AudibleAlert.firefox, 4.), + }, + + EventName.hal9000: { + ET.WARNING: Alert( + "I'm sorry Dave", + "I'm afraid I can't do that...", + AlertStatus.normal, AlertSize.mid, + Priority.HIGH, VisualAlert.none, AudibleAlert.hal9000, 4.), + }, + + EventName.openpilotCrashedRandomEvent: { + ET.PERMANENT: Alert( + "openpilot crashed 💩", + "Please post the 'Error Log' in the FrogPilot Discord!", + AlertStatus.normal, AlertSize.mid, + Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 10.), + }, + + EventName.vCruise69: { + ET.PERMANENT: Alert( + "Lol 69", + "", + AlertStatus.frogpilot, AlertSize.small, + Priority.LOW, VisualAlert.none, AudibleAlert.noice, 2.), + }, + + EventName.yourFrogTriedToKillMe: { + ET.PERMANENT: Alert( + "Your Frog tried to kill me...", + "👺", + AlertStatus.frogpilot, AlertSize.mid, + Priority.MID, VisualAlert.none, AudibleAlert.angry, 5.), + }, } diff --git a/selfdrive/frogpilot/assets/random_events/images/firefox.gif b/selfdrive/frogpilot/assets/random_events/images/firefox.gif new file mode 100644 index 000000000..ff29df21b Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/images/firefox.gif differ diff --git a/selfdrive/frogpilot/assets/random_events/images/great_scott.gif b/selfdrive/frogpilot/assets/random_events/images/great_scott.gif new file mode 100644 index 000000000..d976d2087 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/images/great_scott.gif differ diff --git a/selfdrive/frogpilot/assets/random_events/images/tree_fiddy.gif b/selfdrive/frogpilot/assets/random_events/images/tree_fiddy.gif new file mode 100644 index 000000000..3fee08abd Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/images/tree_fiddy.gif differ diff --git a/selfdrive/frogpilot/assets/random_events/images/weeb_wheel.gif b/selfdrive/frogpilot/assets/random_events/images/weeb_wheel.gif new file mode 100644 index 000000000..0d231c146 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/images/weeb_wheel.gif differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/angry.wav b/selfdrive/frogpilot/assets/random_events/sounds/angry.wav new file mode 100644 index 000000000..6bc69913b Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/angry.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/dejaVu.wav b/selfdrive/frogpilot/assets/random_events/sounds/dejaVu.wav new file mode 100644 index 000000000..a3538434f Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/dejaVu.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/doc.wav b/selfdrive/frogpilot/assets/random_events/sounds/doc.wav new file mode 100644 index 000000000..9fd679e3f Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/doc.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/fart.wav b/selfdrive/frogpilot/assets/random_events/sounds/fart.wav new file mode 100644 index 000000000..d825cbaee Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/fart.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/firefox.wav b/selfdrive/frogpilot/assets/random_events/sounds/firefox.wav new file mode 100644 index 000000000..9b0668f83 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/firefox.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/goat.wav b/selfdrive/frogpilot/assets/random_events/sounds/goat.wav new file mode 100644 index 000000000..e6f3c2c13 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/goat.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/hal9000.wav b/selfdrive/frogpilot/assets/random_events/sounds/hal9000.wav new file mode 100644 index 000000000..7285aff88 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/hal9000.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/nessie.wav b/selfdrive/frogpilot/assets/random_events/sounds/nessie.wav new file mode 100644 index 000000000..899dc7296 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/nessie.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/noice.wav b/selfdrive/frogpilot/assets/random_events/sounds/noice.wav new file mode 100644 index 000000000..bf7cedc70 Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/noice.wav differ diff --git a/selfdrive/frogpilot/assets/random_events/sounds/uwu.wav b/selfdrive/frogpilot/assets/random_events/sounds/uwu.wav new file mode 100644 index 000000000..830360ccd Binary files /dev/null and b/selfdrive/frogpilot/assets/random_events/sounds/uwu.wav differ diff --git a/selfdrive/frogpilot/controls/frogpilot_planner.py b/selfdrive/frogpilot/controls/frogpilot_planner.py index 20450ce9e..6c33abb86 100644 --- a/selfdrive/frogpilot/controls/frogpilot_planner.py +++ b/selfdrive/frogpilot/controls/frogpilot_planner.py @@ -56,6 +56,7 @@ class FrogPilotPlanner: self.override_force_stop = False self.override_slc = False self.slower_lead = False + self.taking_curve_quickly = False self.tracking_lead = False self.acceleration_jerk = 0 @@ -124,6 +125,9 @@ class FrogPilotPlanner: self.override_force_stop |= frogpilotCarControl.resumePressed self.road_curvature = calculate_road_curvature(modelData, v_ego) if not carState.standstill and driving_gear else 1 + if frogpilot_toggles.random_events and v_ego > CRUISING_SPEED and driving_gear: + self.taking_curve_quickly = v_ego > (1 / self.road_curvature)**0.5 * 2 > CRUISING_SPEED * 2 and abs(carState.steeringAngleDeg) > 30 + self.set_acceleration(controlsState, frogpilotCarState, v_cruise, v_ego, frogpilot_toggles) self.set_follow_values(controlsState, frogpilotCarState, lead_distance, stopping_distance, v_ego, v_lead, frogpilot_toggles) self.set_lead_status(lead_distance, stopping_distance, v_ego) @@ -347,6 +351,8 @@ class FrogPilotPlanner: frogpilotPlan.slcSpeedLimitOffset = SpeedLimitController.offset frogpilotPlan.unconfirmedSlcSpeedLimit = SpeedLimitController.desired_speed_limit + frogpilotPlan.takingCurveQuickly = self.taking_curve_quickly + frogpilotPlan.vCruise = self.v_cruise pm.send('frogpilotPlan', frogpilot_plan_send) diff --git a/selfdrive/ui/qt/onroad/buttons.cc b/selfdrive/ui/qt/onroad/buttons.cc index e2cce4815..418f53f69 100644 --- a/selfdrive/ui/qt/onroad/buttons.cc +++ b/selfdrive/ui/qt/onroad/buttons.cc @@ -19,6 +19,18 @@ void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrus p.restore(); } +void drawIconGif(QPainter &p, const QPoint ¢er, const QMovie &img, const QBrush &bg, float opacity) { + p.setRenderHint(QPainter::Antialiasing); + p.setOpacity(1.0); // bg dictates opacity of ellipse + p.setPen(Qt::NoPen); + p.setBrush(bg); + p.drawEllipse(center.x() - btn_size / 2, center.y() - btn_size / 2, btn_size, btn_size); + p.setOpacity(opacity); + QPixmap currentFrame = img.currentPixmap(); + p.drawPixmap(center - QPoint(currentFrame.width() / 2, currentFrame.height() / 2), currentFrame); + p.setOpacity(1.0); +} + // ExperimentalButton ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent) { setFixedSize(btn_size, btn_size); @@ -36,6 +48,13 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals {5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})}, {6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})}, }; + + wheelImagesGif = { + {0, new QMovie("../frogpilot/assets/random_events/images/firefox.gif", QByteArray(), this)}, + {1, new QMovie("../frogpilot/assets/random_events/images/weeb_wheel.gif", QByteArray(), this)}, + {2, new QMovie("../frogpilot/assets/random_events/images/tree_fiddy.gif", QByteArray(), this)}, + {3, new QMovie("../frogpilot/assets/random_events/images/great_scott.gif", QByteArray(), this)}, + }; } void ExperimentalButton::changeMode() { @@ -67,13 +86,31 @@ void ExperimentalButton::updateState(const UIState &s) { conditionalExperimental = scene.conditional_experimental; conditionalStatus = scene.conditional_status; navigateOnOpenpilot = scene.navigate_on_openpilot; + randomEvent = scene.current_random_event; rotatingWheel = scene.rotating_wheel; trafficModeActive = scene.traffic_mode_active; wheelIcon = scene.wheel_icon; + wheelIconGif = 0; - if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) { + if (randomEvent == 0 && gifLabel) { + delete gifLabel; + gifLabel = nullptr; + } else if (randomEvent == 1 || randomEvent == 2 || randomEvent == 3 || randomEvent == 4) { + gifLabel = new QLabel(this); + + QMovie *movie = wheelImagesGif[randomEvent - 1]; + if (movie) { + movie->setScaledSize(QSize(img_size, img_size)); + gifLabel->setMovie(movie); + gifLabel->move((width() - gifLabel->width()) / 2, (height() - gifLabel->height()) / 2); + gifLabel->movie()->start(); + } + + wheelIconGif = randomEvent - 1; update(); + } else if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) { steeringAngleDeg = scene.steering_angle_deg; + update(); } else if (!rotatingWheel) { steeringAngleDeg = 0; } @@ -87,6 +124,7 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) { QPainter p(this); engage_img = wheelImages[wheelIcon]; QPixmap img = wheelIcon != 0 ? engage_img : (experimental_mode ? experimental_img : engage_img); + QMovie *gif = wheelImagesGif[wheelIconGif]; QColor background_color = wheelIcon != 0 && !isDown() && engageable ? (alwaysOnLateralActive ? bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE] : @@ -96,7 +134,11 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) { (navigateOnOpenpilot ? bg_colors[STATUS_NAVIGATION_ACTIVE] : QColor(0, 0, 0, 166)))))) : QColor(0, 0, 0, 166); - drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, QColor(0, 0, 0, 166), (isDown() || !engageable) ? 0.6 : 1.0, steeringAngleDeg); + if (wheelIconGif != 0) { + drawIconGif(p, QPoint(btn_size / 2, btn_size / 2), *gif, background_color, 1.0); + } else { + drawIcon(p, QPoint(btn_size / 2, btn_size / 2), img, background_color, (isDown() || !engageable) ? 0.6 : 1.0, steeringAngleDeg); + } } // MapSettingsButton diff --git a/selfdrive/ui/qt/onroad/buttons.h b/selfdrive/ui/qt/onroad/buttons.h index 2785ae99f..6cf03c371 100644 --- a/selfdrive/ui/qt/onroad/buttons.h +++ b/selfdrive/ui/qt/onroad/buttons.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include "selfdrive/ui/ui.h" @@ -32,10 +34,15 @@ private: bool trafficModeActive; int conditionalStatus; + int randomEvent; int steeringAngleDeg; int wheelIcon; + int wheelIconGif; + + QLabel *gifLabel; QMap wheelImages; + QMap wheelImagesGif; Params paramsMemory{"/dev/shm/params"}; }; diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index b5c8d9bd6..f9924d0e6 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -41,6 +41,17 @@ sound_list: dict[int, tuple[str, int | None, float]] = { AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME), AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME), + # Random Events + AudibleAlert.angry: ("angry.wav", 1, MAX_VOLUME), + AudibleAlert.dejaVu: ("dejaVu.wav", 1, MAX_VOLUME), + AudibleAlert.doc: ("doc.wav", 1, MAX_VOLUME), + AudibleAlert.fart: ("fart.wav", 1, MAX_VOLUME), + AudibleAlert.firefox: ("firefox.wav", 1, MAX_VOLUME), + AudibleAlert.hal9000: ("hal9000.wav", 1, MAX_VOLUME), + AudibleAlert.nessie: ("nessie.wav", 1, MAX_VOLUME), + AudibleAlert.noice: ("noice.wav", 1, MAX_VOLUME), + AudibleAlert.uwu: ("uwu.wav", 1, MAX_VOLUME), + # Other AudibleAlert.goat: ("goat.wav", None, MAX_VOLUME), } @@ -69,6 +80,20 @@ class Soundd: self.frogpilot_toggles = FrogPilotVariables.toggles self.previous_sound_directory = None + self.random_events_directory = BASEDIR + "/selfdrive/frogpilot/assets/random_events/sounds/" + + self.random_events_map = { + AudibleAlert.angry: MAX_VOLUME, + AudibleAlert.dejaVu: MAX_VOLUME, + AudibleAlert.doc: MAX_VOLUME, + AudibleAlert.fart: MAX_VOLUME, + AudibleAlert.firefox: MAX_VOLUME, + AudibleAlert.goat: MAX_VOLUME, + AudibleAlert.hal9000: MAX_VOLUME, + AudibleAlert.nessie: MAX_VOLUME, + AudibleAlert.noice: MAX_VOLUME, + AudibleAlert.uwu: MAX_VOLUME, + } self.update_toggles = False @@ -81,12 +106,15 @@ class Soundd: for sound in sound_list: filename, play_count, volume = sound_list[sound] - try: + if sound in self.random_events_map: + wavefile = wave.open(self.random_events_directory + filename, 'r') + else: if sound == AudibleAlert.goat and not self.frogpilot_toggles.goat_scream: continue - wavefile = wave.open(self.sound_directory + filename, 'r') - except FileNotFoundError: - wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') + try: + wavefile = wave.open(self.sound_directory + filename, 'r') + except FileNotFoundError: + wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') assert wavefile.getnchannels() == 1 assert wavefile.getsampwidth() == 2 @@ -172,6 +200,9 @@ class Soundd: elif self.frogpilot_toggles.alert_volume_control and self.current_alert in self.volume_map: self.current_volume = self.volume_map[self.current_alert] / 100.0 + elif self.current_alert in self.random_events_map: + self.current_volume = self.random_events_map[self.current_alert] + self.get_audible_alert(sm) rk.keep_time() diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index fae751388..5a0c8ceb4 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -336,6 +336,7 @@ void ui_update_frogpilot_params(UIState *s, Params ¶ms) { scene.custom_icons = custom_theme ? params.getInt("CustomIcons") : 0; scene.custom_signals = custom_theme ? params.getInt("CustomSignals") : 0; scene.holiday_themes = custom_theme && params.getBool("HolidayThemes"); + scene.random_events = custom_theme && params.getBool("RandomEvents"); scene.disable_smoothing_mtsc = params.getBool("MTSCEnabled") && params.getBool("DisableMTSCSmoothing"); scene.disable_smoothing_vtsc = params.getBool("VisionTurnControl") && params.getBool("DisableVTSCSmoothing"); @@ -461,6 +462,7 @@ void UIState::update() { // FrogPilot variables that need to be constantly updated scene.conditional_status = scene.conditional_experimental && scene.enabled ? paramsMemory.getInt("CEStatus") : 0; scene.current_holiday_theme = scene.holiday_themes ? paramsMemory.getInt("CurrentHolidayTheme") : 0; + scene.current_random_event = scene.random_events ? paramsMemory.getInt("CurrentRandomEvent") : 0; scene.started_timer = scene.started || started_prev ? scene.started_timer + 1 : 0; } diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 6af5affa6..97d9325b8 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -146,6 +146,7 @@ typedef struct UIScene { bool onroad_distance_button; bool parked; bool pedals_on_ui; + bool random_events; bool red_light; bool reverse; bool reverse_cruise; @@ -189,6 +190,7 @@ typedef struct UIScene { int conditional_speed_lead; int conditional_status; int current_holiday_theme; + int current_random_event; int custom_colors; int custom_icons; int custom_signals;