FrogPilot 0.9.7

This commit is contained in:
FrogAi
2024-06-27 10:22:08 -07:00
parent da00915ac8
commit b705b02e70
682 changed files with 181798 additions and 1348 deletions
+104 -7
View File
@@ -3,6 +3,7 @@ import numpy as np
import time
import wave
from pathlib import Path
from cereal import car, messaging
from openpilot.common.basedir import BASEDIR
@@ -13,6 +14,8 @@ from openpilot.common.swaglog import cloudlog
from openpilot.system import micd
from openpilot.selfdrive.frogpilot.frogpilot_variables import ACTIVE_THEME_PATH, RANDOM_EVENTS_PATH, get_frogpilot_toggles, params_memory
SAMPLE_RATE = 48000
SAMPLE_BUFFER = 4096 # (approx 100ms)
MAX_VOLUME = 1.0
@@ -38,6 +41,23 @@ 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),
# FrogPilot sounds
AudibleAlert.angry: ("angry.wav", 1, MAX_VOLUME),
AudibleAlert.continued: ("continued.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.goat: ("goat.wav", None, MAX_VOLUME),
AudibleAlert.hal9000: ("hal9000.wav", 1, MAX_VOLUME),
AudibleAlert.mail: ("mail.wav", 1, MAX_VOLUME),
AudibleAlert.nessie: ("nessie.wav", 1, MAX_VOLUME),
AudibleAlert.noice: ("noice.wav", 1, MAX_VOLUME),
AudibleAlert.promptRepeat: ("prompt_repeat.wav", None, MAX_VOLUME),
AudibleAlert.startup: ("startup.wav", 1, MAX_VOLUME),
AudibleAlert.thisIsFine: ("this_is_fine.wav", 1, MAX_VOLUME),
AudibleAlert.uwu: ("uwu.wav", 1, MAX_VOLUME),
}
def check_controls_timeout_alert(sm):
@@ -52,8 +72,6 @@ def check_controls_timeout_alert(sm):
class Soundd:
def __init__(self):
self.load_sounds()
self.current_alert = AudibleAlert.none
self.current_volume = MIN_VOLUME
self.current_sound_frame = 0
@@ -62,6 +80,33 @@ class Soundd:
self.spl_filter_weighted = FirstOrderFilter(0, 2.5, FILTER_DT, initialized=False)
# FrogPilot variables
self.frogpilot_toggles = get_frogpilot_toggles()
self.auto_volume = 0
self.previous_sound_pack = None
self.random_events_directory = Path(RANDOM_EVENTS_PATH) / "sounds"
self.random_events_map = {
AudibleAlert.angry: MAX_VOLUME,
AudibleAlert.continued: 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.mail: MAX_VOLUME,
AudibleAlert.nessie: MAX_VOLUME,
AudibleAlert.noice: MAX_VOLUME,
AudibleAlert.thisIsFine: MAX_VOLUME,
AudibleAlert.uwu: MAX_VOLUME,
}
self.update_frogpilot_sounds()
def load_sounds(self):
self.loaded_sounds: dict[int, np.ndarray] = {}
@@ -69,7 +114,17 @@ class Soundd:
for sound in sound_list:
filename, play_count, volume = sound_list[sound]
wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r')
if sound in self.random_events_map:
wavefile = wave.open(str(self.random_events_directory / filename), 'r')
else:
try:
wavefile = wave.open(str(self.sound_directory / filename), 'r')
except FileNotFoundError:
if filename == "prompt_repeat.wav":
filename = "prompt.wav"
if filename == "startup.wav":
filename = "engage.wav"
wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r')
assert wavefile.getnchannels() == 1
assert wavefile.getsampwidth() == 2
@@ -136,18 +191,31 @@ class Soundd:
# sounddevice must be imported after forking processes
import sounddevice as sd
sm = messaging.SubMaster(['controlsState', 'microphone'])
sm = messaging.SubMaster(['controlsState', 'microphone', 'frogpilotPlan'])
with self.get_stream(sd) as stream:
rk = Ratekeeper(20)
cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}")
while True:
while not params_memory.get_bool("TestingSound"):
sm.update(0)
if sm.updated['microphone'] and self.current_alert == AudibleAlert.none: # only update volume filter when not playing alert
self.spl_filter_weighted.update(sm["microphone"].soundPressureWeightedDb)
self.current_volume = self.calculate_volume(float(self.spl_filter_weighted.x))
if self.frogpilot_toggles.alert_volume_control:
self.spl_filter_weighted.update(sm["microphone"].soundPressureWeightedDb)
self.auto_volume = self.calculate_volume(float(self.spl_filter_weighted.x))
self.current_volume = 0.0
else:
self.spl_filter_weighted.update(sm["microphone"].soundPressureWeightedDb)
self.current_volume = self.calculate_volume(float(self.spl_filter_weighted.x))
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
if self.current_volume == 1.01:
self.current_volume = self.auto_volume
elif self.current_alert in self.random_events_map:
self.current_volume = self.random_events_map[self.current_alert]
self.get_audible_alert(sm)
@@ -155,6 +223,35 @@ class Soundd:
assert stream.active
# Update FrogPilot parameters
if sm['frogpilotPlan'].togglesUpdated:
self.frogpilot_toggles = get_frogpilot_toggles()
self.update_frogpilot_sounds()
def update_frogpilot_sounds(self):
self.volume_map = {
AudibleAlert.engage: self.frogpilot_toggles.engage_volume,
AudibleAlert.disengage: self.frogpilot_toggles.disengage_volume,
AudibleAlert.refuse: self.frogpilot_toggles.refuse_volume,
AudibleAlert.prompt: self.frogpilot_toggles.prompt_volume,
AudibleAlert.promptRepeat: self.frogpilot_toggles.prompt_volume,
AudibleAlert.promptDistracted: self.frogpilot_toggles.promptDistracted_volume,
AudibleAlert.warningSoft: self.frogpilot_toggles.warningSoft_volume,
AudibleAlert.warningImmediate: self.frogpilot_toggles.warningImmediate_volume,
AudibleAlert.goat: self.frogpilot_toggles.prompt_volume,
}
if self.frogpilot_toggles.sound_pack != "stock":
self.sound_directory = Path(ACTIVE_THEME_PATH) / "sounds"
else:
self.sound_directory = Path(BASEDIR) / "selfdrive" / "assets" / "sounds"
if self.frogpilot_toggles.sound_pack != self.previous_sound_pack:
self.load_sounds()
self.previous_sound_pack = self.frogpilot_toggles.sound_pack
def main():
s = Soundd()