Random Events
|
After Width: | Height: | Size: 266 KiB |
|
After Width: | Height: | Size: 549 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 445 KiB |
|
After Width: | Height: | Size: 515 KiB |
|
After Width: | Height: | Size: 940 KiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 658 KiB |
@@ -10,7 +10,7 @@ from urllib.parse import quote_plus
|
||||
|
||||
from openpilot.frogpilot.common.frogpilot_download_utilities import GITLAB_URL, download_file, get_repository_url, handle_error, verify_download
|
||||
from openpilot.frogpilot.common.frogpilot_utilities import delete_file, extract_zip, load_json_file, update_json_file
|
||||
from openpilot.frogpilot.common.frogpilot_variables import ACTIVE_THEME_PATH, RESOURCES_REPO, THEME_SAVE_PATH
|
||||
from openpilot.frogpilot.common.frogpilot_variables import ACTIVE_THEME_PATH, RANDOM_EVENTS_PATH, RESOURCES_REPO, THEME_SAVE_PATH
|
||||
|
||||
CANCEL_DOWNLOAD_PARAM = "CancelThemeDownload"
|
||||
DOWNLOAD_PROGRESS_PARAM = "ThemeDownloadProgress"
|
||||
@@ -542,11 +542,13 @@ class ThemeManager:
|
||||
|
||||
self.update_theme_params(downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels)
|
||||
|
||||
def update_wheel_image(self, image, boot_run=False):
|
||||
def update_wheel_image(self, image, boot_run=False, random_event=False):
|
||||
wheel_save_location = ACTIVE_THEME_PATH / "steering_wheel"
|
||||
|
||||
if self.holiday_theme != "stock":
|
||||
wheel_location = HOLIDAY_THEME_PATH / self.holiday_theme / "steering_wheel"
|
||||
elif random_event:
|
||||
wheel_location = RANDOM_EVENTS_PATH / "steering_wheels"
|
||||
elif image == "stock":
|
||||
wheel_location = STOCKOP_THEME_PATH / "steering_wheel"
|
||||
elif image in HOLIDAY_SLUGS:
|
||||
|
||||
@@ -20,13 +20,13 @@ from openpilot.frogpilot.controls.lib.frogpilot_following import FrogPilotFollow
|
||||
from openpilot.frogpilot.controls.lib.frogpilot_vcruise import FrogPilotVCruise
|
||||
|
||||
class FrogPilotPlanner:
|
||||
def __init__(self, error_log):
|
||||
def __init__(self, error_log, ThemeManager):
|
||||
self.params = Params(return_defaults=True)
|
||||
self.params_memory = Params(memory=True)
|
||||
|
||||
self.frogpilot_acceleration = FrogPilotAcceleration(self)
|
||||
self.frogpilot_cem = ConditionalExperimentalMode(self)
|
||||
self.frogpilot_events = FrogPilotEvents(self, error_log)
|
||||
self.frogpilot_events = FrogPilotEvents(self, error_log, ThemeManager)
|
||||
self.frogpilot_following = FrogPilotFollowing(self)
|
||||
self.frogpilot_vcruise = FrogPilotVCruise(self)
|
||||
|
||||
|
||||
@@ -1,18 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
import random
|
||||
|
||||
from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY, CV
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.selfdrive.selfdrived.events import ET, EVENT_NAME, FROGPILOT_EVENT_NAME, EventName, FrogPilotEventName, Events
|
||||
|
||||
from openpilot.frogpilot.common.frogpilot_variables import NON_DRIVING_GEARS
|
||||
from openpilot.frogpilot.common.frogpilot_variables import CRUISING_SPEED, NON_DRIVING_GEARS
|
||||
|
||||
DEJA_VU_G_FORCE = 0.75
|
||||
RANDOM_EVENTS_CHANCE = 0.01 * DT_MDL
|
||||
RANDOM_EVENTS_LENGTH = 5
|
||||
|
||||
RANDOM_EVENT_START = FrogPilotEventName.accel30
|
||||
RANDOM_EVENT_END = FrogPilotEventName.youveGotMail
|
||||
|
||||
class FrogPilotEvents:
|
||||
def __init__(self, FrogPilotPlanner, error_log):
|
||||
def __init__(self, FrogPilotPlanner, error_log, ThemeManager):
|
||||
self.frogpilot_planner = FrogPilotPlanner
|
||||
self.theme_manager = ThemeManager
|
||||
|
||||
self.events = Events(frogpilot=True)
|
||||
|
||||
self.always_on_lateral_enabled_previously = False
|
||||
self.random_event_playing = False
|
||||
self.startup_seen = False
|
||||
self.stopped_for_light = False
|
||||
|
||||
self.max_acceleration = 0
|
||||
self.random_event_timer = 0
|
||||
self.tracked_lead_distance = 0
|
||||
|
||||
self.played_events = set()
|
||||
@@ -63,8 +78,105 @@ class FrogPilotEvents:
|
||||
if "nnffLoaded" not in self.played_events and self.startup_seen and alerts_empty and len(self.events) == 0 and self.frogpilot_planner.params.get("NNFFModelName") is not None and frogpilot_toggles.nnff:
|
||||
self.events.add(FrogPilotEventName.nnffLoaded)
|
||||
|
||||
if self.random_event_playing:
|
||||
self.random_event_timer += DT_MDL
|
||||
|
||||
if self.random_event_timer >= RANDOM_EVENTS_LENGTH:
|
||||
self.theme_manager.update_wheel_image(frogpilot_toggles.wheel_image)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
|
||||
self.random_event_playing = False
|
||||
self.random_event_timer = 0
|
||||
|
||||
if not self.random_event_playing and frogpilot_toggles.random_events:
|
||||
if "accel30" not in self.played_events and 3.5 > self.max_acceleration >= 3.0 and acceleration < 1.5:
|
||||
self.events.add(FrogPilotEventName.accel30)
|
||||
|
||||
self.theme_manager.update_wheel_image("accel30", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
|
||||
self.max_acceleration = 0
|
||||
|
||||
elif "accel35" not in self.played_events and 4.0 > self.max_acceleration >= 3.5 and acceleration < 1.5:
|
||||
self.events.add(FrogPilotEventName.accel35)
|
||||
|
||||
self.theme_manager.update_wheel_image("accel35", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
|
||||
self.max_acceleration = 0
|
||||
|
||||
elif "accel40" not in self.played_events and self.max_acceleration >= 4.0 and acceleration < 1.5:
|
||||
self.events.add(FrogPilotEventName.accel40)
|
||||
|
||||
self.theme_manager.update_wheel_image("accel40", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
|
||||
self.max_acceleration = 0
|
||||
|
||||
if "dejaVuCurve" not in self.played_events and sm["carState"].vEgo > CRUISING_SPEED:
|
||||
if self.frogpilot_planner.lateral_acceleration >= DEJA_VU_G_FORCE * ACCELERATION_DUE_TO_GRAVITY:
|
||||
self.events.add(FrogPilotEventName.dejaVuCurve)
|
||||
|
||||
if "hal9000" not in self.played_events and (ET.NO_ENTRY in current_alert or ET.NO_ENTRY in current_frogpilot_alert):
|
||||
self.events.add(FrogPilotEventName.hal9000)
|
||||
|
||||
if f"{EVENT_NAME[EventName.steerSaturated]}/" in current_alert or f"{FROGPILOT_EVENT_NAME[FrogPilotEventName.goatSteerSaturated]}/" in current_frogpilot_alert:
|
||||
event_choices = []
|
||||
if "firefoxSteerSaturated" not in self.played_events:
|
||||
event_choices.append("firefoxSteerSaturated")
|
||||
if "goatSteerSaturated" not in self.played_events:
|
||||
event_choices.append("goatSteerSaturated")
|
||||
if "thisIsFineSteerSaturated" not in self.played_events:
|
||||
event_choices.append("thisIsFineSteerSaturated")
|
||||
|
||||
if event_choices and random.random() < RANDOM_EVENTS_CHANCE:
|
||||
event_choice = random.choice(event_choices)
|
||||
|
||||
if event_choice == "firefoxSteerSaturated":
|
||||
self.events.add(FrogPilotEventName.firefoxSteerSaturated)
|
||||
|
||||
self.theme_manager.update_wheel_image("firefoxSteerSaturated", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
elif event_choice == "goatSteerSaturated":
|
||||
self.events.add(FrogPilotEventName.goatSteerSaturated)
|
||||
|
||||
self.theme_manager.update_wheel_image("goatSteerSaturated", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
elif event_choice == "thisIsFineSteerSaturated":
|
||||
self.events.add(FrogPilotEventName.thisIsFineSteerSaturated)
|
||||
|
||||
self.theme_manager.update_wheel_image("thisIsFineSteerSaturated", random_event=True)
|
||||
self.frogpilot_planner.params_memory.put_bool("UpdateWheelImage", True)
|
||||
|
||||
if "vCruise69" not in self.played_events and 70 > max(sm["carState"].vCruise, sm["carState"].vCruiseCluster) * (1 if frogpilot_toggles.is_metric else CV.KPH_TO_MPH) >= 69:
|
||||
self.events.add(FrogPilotEventName.vCruise69)
|
||||
|
||||
if f"{EVENT_NAME[EventName.fcw]}/" in current_alert or f"{EVENT_NAME[EventName.stockAeb]}/" in current_alert:
|
||||
event_choices = []
|
||||
if "toBeContinued" not in self.played_events:
|
||||
event_choices.append("toBeContinued")
|
||||
if "yourFrogTriedToKillMe" not in self.played_events:
|
||||
event_choices.append("yourFrogTriedToKillMe")
|
||||
|
||||
if event_choices:
|
||||
event_choice = random.choice(event_choices)
|
||||
if event_choice == "toBeContinued":
|
||||
self.events.add(FrogPilotEventName.toBeContinued)
|
||||
elif event_choice == "yourFrogTriedToKillMe":
|
||||
self.events.add(FrogPilotEventName.yourFrogTriedToKillMe)
|
||||
|
||||
if "youveGotMail" not in self.played_events and sm["frogpilotCarState"].alwaysOnLateralEnabled and not self.always_on_lateral_enabled_previously:
|
||||
if random.random() < RANDOM_EVENTS_CHANCE / DT_MDL:
|
||||
self.events.add(FrogPilotEventName.youveGotMail)
|
||||
|
||||
self.always_on_lateral_enabled_previously = sm["frogpilotCarState"].alwaysOnLateralEnabled
|
||||
self.random_event_playing |= bool({event for event in self.events.names if RANDOM_EVENT_START <= event <= RANDOM_EVENT_END})
|
||||
|
||||
if self.error_log.is_file():
|
||||
self.events.add(FrogPilotEventName.openpilotCrashed)
|
||||
if frogpilot_toggles.random_events:
|
||||
self.events.add(FrogPilotEventName.openpilotCrashedRandomEvent)
|
||||
else:
|
||||
self.events.add(FrogPilotEventName.openpilotCrashed)
|
||||
|
||||
self.startup_seen |= sm["frogpilotSelfdriveState"].alertText1 == frogpilot_toggles.startup_alert_top and sm["frogpilotSelfdriveState"].alertText2 == frogpilot_toggles.startup_alert_bottom
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ def frogpilot_thread():
|
||||
|
||||
run_update_checks = True
|
||||
elif started and not started_previously:
|
||||
frogpilot_planner = FrogPilotPlanner(error_log)
|
||||
frogpilot_planner = FrogPilotPlanner(error_log, theme_manager)
|
||||
frogpilot_tracking = FrogPilotTracking(frogpilot_planner, frogpilot_toggles)
|
||||
|
||||
transition_onroad(error_log)
|
||||
|
||||
@@ -1179,6 +1179,109 @@ FROGPILOT_EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
AlertStatus.critical, AlertSize.mid,
|
||||
Priority.HIGHEST, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
},
|
||||
|
||||
# Random Events
|
||||
FrogPilotEventName.accel30: {
|
||||
ET.WARNING: Alert(
|
||||
"UwU u went a bit fast there!",
|
||||
"(⁄ ⁄•⁄ω⁄•⁄ ⁄)",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.uwu, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.accel35: {
|
||||
ET.WARNING: Alert(
|
||||
"I ain't giving you no tree-fiddy",
|
||||
"You damn Loch Ness Monsta!",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.nessie, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.accel40: {
|
||||
ET.WARNING: Alert(
|
||||
"Great Scott!",
|
||||
"🚗💨",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.doc, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.dejaVuCurve: {
|
||||
ET.PERMANENT: Alert(
|
||||
"♬♪ Deja vu! ᕕ(⌐■_■)ᕗ ♪♬",
|
||||
"🏎️",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.dejaVu, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.firefoxSteerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"IE Has Stopped Responding...",
|
||||
"Turn Exceeds Steering Limit",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, FrogPilotAudibleAlert.firefox, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.hal9000: {
|
||||
ET.WARNING: Alert(
|
||||
"I'm sorry Dave",
|
||||
"I'm afraid I can't do that...",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.none, FrogPilotAudibleAlert.hal9000, 4.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.openpilotCrashedRandomEvent: {
|
||||
ET.IMMEDIATE_DISABLE: Alert(
|
||||
"openpilot crashed 💩",
|
||||
"Please post the 'Error Log' in the FrogPilot Discord!",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGHEST, VisualAlert.none, FrogPilotAudibleAlert.fart, 10.),
|
||||
|
||||
ET.NO_ENTRY: Alert(
|
||||
"openpilot crashed 💩",
|
||||
"Please post the 'Error Log' in the FrogPilot Discord!",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGHEST, VisualAlert.none, FrogPilotAudibleAlert.fart, 10.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.thisIsFineSteerSaturated: {
|
||||
ET.WARNING: Alert(
|
||||
"This is fine ☕",
|
||||
"Turn Exceeds Steering Limit",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, FrogPilotAudibleAlert.thisIsFine, 2.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.toBeContinued: {
|
||||
ET.PERMANENT: Alert(
|
||||
"To be continued...",
|
||||
"⬅️",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.none, FrogPilotAudibleAlert.continued, 7.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.vCruise69: {
|
||||
ET.WARNING: Alert(
|
||||
"Lol 69",
|
||||
"",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.noice, 2.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.yourFrogTriedToKillMe: {
|
||||
ET.PERMANENT: Alert(
|
||||
"Your Frog tried to kill me...",
|
||||
"👺",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.none, FrogPilotAudibleAlert.angry, 5.),
|
||||
},
|
||||
|
||||
FrogPilotEventName.youveGotMail: {
|
||||
ET.WARNING: Alert(
|
||||
"You've got mail! 📧",
|
||||
"",
|
||||
FrogPilotAlertStatus.frogpilot, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, FrogPilotAudibleAlert.mail, 3.),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,11 +38,19 @@ OnroadAlerts::Alert OnroadAlerts::getAlert(const SubMaster &sm, const SubMaster
|
||||
Alert a = {};
|
||||
static QString crash_log_path = "/data/error_logs/error.txt";
|
||||
if (QFile::exists(crash_log_path)) {
|
||||
a = {tr("openpilot crashed"),
|
||||
tr("Please post the \"Error Log\" in the FrogPilot Discord!"),
|
||||
"openpilotCrashed",
|
||||
cereal::SelfdriveState::AlertSize::MID,
|
||||
cereal::SelfdriveState::AlertStatus::CRITICAL};
|
||||
if (frogpilot_toggles.value("random_events").toBool()) {
|
||||
a = {tr("openpilot crashed 💩"),
|
||||
tr("Please post the \"Error Log\" in the FrogPilot Discord!"),
|
||||
"openpilotCrashedRandomEvent",
|
||||
cereal::SelfdriveState::AlertSize::MID,
|
||||
cereal::SelfdriveState::AlertStatus::CRITICAL};
|
||||
} else {
|
||||
a = {tr("openpilot crashed"),
|
||||
tr("Please post the \"Error Log\" in the FrogPilot Discord!"),
|
||||
"openpilotCrashed",
|
||||
cereal::SelfdriveState::AlertSize::MID,
|
||||
cereal::SelfdriveState::AlertStatus::CRITICAL};
|
||||
}
|
||||
return a;
|
||||
} else if (selfdrive_frame >= started_frame) { // Don't get old alert.
|
||||
a = {ss.getAlertText1().cStr(), ss.getAlertText2().cStr(),
|
||||
|
||||
@@ -54,6 +54,11 @@ void ExperimentalButton::updateState(const UIState &s, const FrogPilotUIState &f
|
||||
const cereal::CarState::Reader &carState = (*s.sm)["carState"].getCarState();
|
||||
|
||||
updateBackgroundColor();
|
||||
|
||||
if (params_memory.getBool("UpdateWheelImage")) {
|
||||
updateTheme();
|
||||
params_memory.remove("UpdateWheelImage");
|
||||
}
|
||||
}
|
||||
|
||||
void ExperimentalButton::paintEvent(QPaintEvent *event) {
|
||||
|
||||
@@ -16,7 +16,7 @@ from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system import micd
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
|
||||
from openpilot.frogpilot.common.frogpilot_variables import ACTIVE_THEME_PATH, ERROR_LOGS_PATH, get_frogpilot_toggles
|
||||
from openpilot.frogpilot.common.frogpilot_variables import ACTIVE_THEME_PATH, ERROR_LOGS_PATH, RANDOM_EVENTS_PATH, get_frogpilot_toggles
|
||||
|
||||
SAMPLE_RATE = 48000
|
||||
SAMPLE_BUFFER = 4096 # (approx 100ms)
|
||||
@@ -52,7 +52,20 @@ sound_list: dict[int, tuple[str, int | None, float]] = {
|
||||
AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME),
|
||||
|
||||
# FrogPilot variables
|
||||
FrogPilotAudibleAlert.angry: ("angry.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.continued: ("continued.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.dejaVu: ("dejaVu.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.doc: ("doc.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.fart: ("fart.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.firefox: ("firefox.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.goat: ("goat.wav", None, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.hal9000: ("hal9000.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.mail: ("mail.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.nessie: ("nessie.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.noice: ("noice.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.startup: ("startup.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.thisIsFine: ("this_is_fine.wav", 1, MAX_VOLUME),
|
||||
FrogPilotAudibleAlert.uwu: ("uwu.wav", 1, MAX_VOLUME),
|
||||
}
|
||||
if HARDWARE.get_device_type() in ("tici", "tizi"):
|
||||
sound_list.update({
|
||||
@@ -92,6 +105,7 @@ class Soundd:
|
||||
self.previous_sound_pack = None
|
||||
|
||||
self.error_log = ERROR_LOGS_PATH / "error.txt"
|
||||
self.random_events_directory = RANDOM_EVENTS_PATH / "sounds"
|
||||
|
||||
self.update_frogpilot_sounds()
|
||||
|
||||
@@ -102,6 +116,7 @@ class Soundd:
|
||||
for sound in sound_list:
|
||||
filename, play_count, volume = sound_list[sound]
|
||||
|
||||
random_events_path = self.random_events_directory / filename
|
||||
sounds_path = self.sound_directory / filename
|
||||
|
||||
if not sounds_path.exists() and "_tizi" in filename:
|
||||
@@ -109,7 +124,9 @@ class Soundd:
|
||||
if standard_path.exists():
|
||||
sounds_path = standard_path
|
||||
|
||||
if sounds_path.exists():
|
||||
if random_events_path.exists():
|
||||
wavefile = wave.open(str(random_events_path), 'r')
|
||||
elif sounds_path.exists():
|
||||
wavefile = wave.open(str(sounds_path), 'r')
|
||||
else:
|
||||
if filename == "startup.wav":
|
||||
|
||||