New sounds (#22652)
* new engage/disengage + amp config * first family * cleanup audible alerts * tici isn't special * fix up debug cycle alerts * these were better * extend range * use distracted sound * log scaling * getting closer * slightly louder * prompt * update tests * update refs * fix c2 test * resolve todo * adjust tolerance * revert for now * should work Co-authored-by: Comma Device <device@comma.ai>pull/23092/head
parent
b3b5beb627
commit
e679d05d9e
2
cereal
2
cereal
|
@ -1 +1 @@
|
|||
Subproject commit d6f233bf7bd6d1ee3508b17667e44420ce38de0d
|
||||
Subproject commit 9ce45916c6c27e8cfbbe2aa6b796fac41eeeba00
|
|
@ -4,7 +4,6 @@ selfdrive/timezoned.py
|
|||
|
||||
selfdrive/assets/navigation/*
|
||||
selfdrive/assets/training_wide/*
|
||||
selfdrive/assets/sounds_tici/*
|
||||
|
||||
selfdrive/camerad/cameras/camera_qcom2.cc
|
||||
selfdrive/camerad/cameras/camera_qcom2.h
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -41,6 +41,7 @@ class AlertManager:
|
|||
self.activealerts: Dict[str, AlertEntry] = defaultdict(AlertEntry)
|
||||
|
||||
def reset(self) -> None:
|
||||
self.alert: Optional[Alert] = None
|
||||
self.alert_type: str = ""
|
||||
self.alert_text_1: str = ""
|
||||
self.alert_text_2: str = ""
|
||||
|
@ -74,13 +75,13 @@ class AlertManager:
|
|||
# clear current alert
|
||||
self.reset()
|
||||
|
||||
a = current_alert.alert
|
||||
if a is not None:
|
||||
self.alert_type = a.alert_type
|
||||
self.audible_alert = a.audible_alert
|
||||
self.visual_alert = a.visual_alert
|
||||
self.alert_text_1 = a.alert_text_1
|
||||
self.alert_text_2 = a.alert_text_2
|
||||
self.alert_status = a.alert_status
|
||||
self.alert_size = a.alert_size
|
||||
self.alert_rate = a.alert_rate
|
||||
self.alert = current_alert.alert
|
||||
if self.alert is not None:
|
||||
self.alert_type = self.alert.alert_type
|
||||
self.audible_alert = self.alert.audible_alert
|
||||
self.visual_alert = self.alert.visual_alert
|
||||
self.alert_text_1 = self.alert.alert_text_1
|
||||
self.alert_text_2 = self.alert.alert_text_2
|
||||
self.alert_status = self.alert.alert_status
|
||||
self.alert_size = self.alert.alert_size
|
||||
self.alert_rate = self.alert.alert_rate
|
||||
|
|
|
@ -139,11 +139,10 @@ class Alert:
|
|||
|
||||
|
||||
class NoEntryAlert(Alert):
|
||||
def __init__(self, alert_text_2, audible_alert=AudibleAlert.chimeError,
|
||||
visual_alert=VisualAlert.none):
|
||||
def __init__(self, alert_text_2, visual_alert=VisualAlert.none):
|
||||
super().__init__("openpilot Unavailable", alert_text_2, AlertStatus.normal,
|
||||
AlertSize.mid, Priority.LOW, visual_alert,
|
||||
audible_alert, 3.)
|
||||
AudibleAlert.refuse, 3.)
|
||||
|
||||
|
||||
class SoftDisableAlert(Alert):
|
||||
|
@ -151,7 +150,7 @@ class SoftDisableAlert(Alert):
|
|||
super().__init__("TAKE CONTROL IMMEDIATELY", alert_text_2,
|
||||
AlertStatus.userPrompt, AlertSize.full,
|
||||
Priority.MID, VisualAlert.steerRequired,
|
||||
AudibleAlert.chimeWarningRepeatInfinite, 2.),
|
||||
AudibleAlert.warningSoft, 2.),
|
||||
|
||||
|
||||
class ImmediateDisableAlert(Alert):
|
||||
|
@ -159,7 +158,7 @@ class ImmediateDisableAlert(Alert):
|
|||
super().__init__("TAKE CONTROL IMMEDIATELY", alert_text_2,
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.steerRequired,
|
||||
AudibleAlert.chimeWarningRepeatInfinite, 4.),
|
||||
AudibleAlert.warningImmediate, 4.),
|
||||
|
||||
|
||||
class EngagementAlert(Alert):
|
||||
|
@ -201,7 +200,7 @@ def below_steer_speed_alert(CP: car.CarParams, sm: messaging.SubMaster, metric:
|
|||
f"Steer Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 0.4)
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.prompt, 0.4)
|
||||
|
||||
|
||||
def calibration_incomplete_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool) -> Alert:
|
||||
|
@ -321,7 +320,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"BRAKE!",
|
||||
"Risk of Collision",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.chimeWarningRepeatInfinite, 2.),
|
||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.warningSoft, 2.),
|
||||
},
|
||||
|
||||
EventName.ldw: {
|
||||
|
@ -329,7 +328,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"TAKE CONTROL",
|
||||
"Lane Departure Detected",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.ldw, AudibleAlert.chimePrompt, 3.),
|
||||
Priority.LOW, VisualAlert.ldw, AudibleAlert.prompt, 3.),
|
||||
},
|
||||
|
||||
# ********** events only containing alerts that display while engaged **********
|
||||
|
@ -360,7 +359,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"Steering Temporarily Unavailable",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1.),
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.prompt, 1.),
|
||||
},
|
||||
|
||||
EventName.preDriverDistracted: {
|
||||
|
@ -376,7 +375,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"KEEP EYES ON ROAD",
|
||||
"Driver Distracted",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2RepeatInfinite, .1),
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.prompt, .1),
|
||||
},
|
||||
|
||||
EventName.driverDistracted: {
|
||||
|
@ -384,7 +383,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Distracted",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeatInfinite, .1),
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.preDriverUnresponsive: {
|
||||
|
@ -400,7 +399,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"TOUCH STEERING WHEEL",
|
||||
"Driver Unresponsive",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2RepeatInfinite, .1),
|
||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.prompt, .1),
|
||||
},
|
||||
|
||||
EventName.driverUnresponsive: {
|
||||
|
@ -408,7 +407,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"DISENGAGE IMMEDIATELY",
|
||||
"Driver Unresponsive",
|
||||
AlertStatus.critical, AlertSize.full,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeatInfinite, .1),
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
|
||||
},
|
||||
|
||||
EventName.manualRestart: {
|
||||
|
@ -452,7 +451,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"Car Detected in Blindspot",
|
||||
"",
|
||||
AlertStatus.userPrompt, AlertSize.small,
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimePrompt, .1),
|
||||
Priority.LOW, VisualAlert.none, AudibleAlert.prompt, .1),
|
||||
},
|
||||
|
||||
EventName.laneChange: {
|
||||
|
@ -468,7 +467,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"TAKE CONTROL",
|
||||
"Turn Exceeds Steering Limit",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning2RepeatInfinite, 1.),
|
||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 1.),
|
||||
},
|
||||
|
||||
# Thrown when the fan is driven at >50% but is not rotating
|
||||
|
@ -496,44 +495,44 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
# ********** events that affect controls state transitions **********
|
||||
|
||||
EventName.pcmEnable: {
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.chimeEngage),
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.engage),
|
||||
},
|
||||
|
||||
EventName.buttonEnable: {
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.chimeEngage),
|
||||
ET.ENABLE: EngagementAlert(AudibleAlert.engage),
|
||||
},
|
||||
|
||||
EventName.pcmDisable: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
},
|
||||
|
||||
EventName.buttonCancel: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
},
|
||||
|
||||
EventName.brakeHold: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Brake Hold Active"),
|
||||
},
|
||||
|
||||
EventName.parkBrake: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Park Brake Engaged"),
|
||||
},
|
||||
|
||||
EventName.pedalPressed: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Pedal Pressed During Attempt",
|
||||
visual_alert=VisualAlert.brakePressed),
|
||||
},
|
||||
|
||||
EventName.wrongCarMode: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: wrong_car_mode_alert,
|
||||
},
|
||||
|
||||
EventName.wrongCruiseMode: {
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage),
|
||||
ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Enable Adaptive Cruise"),
|
||||
},
|
||||
|
||||
|
@ -627,14 +626,12 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
# ten times the regular interval, or the average interval is more than 10% too high.
|
||||
EventName.commIssue: {
|
||||
ET.SOFT_DISABLE: SoftDisableAlert("Communication Issue between Processes"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Communication Issue between Processes",
|
||||
audible_alert=AudibleAlert.chimeDisengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Communication Issue between Processes"),
|
||||
},
|
||||
|
||||
# Thrown when manager detects a service exited unexpectedly while driving
|
||||
EventName.processNotRunning: {
|
||||
ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device",
|
||||
audible_alert=AudibleAlert.chimeDisengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device"),
|
||||
},
|
||||
|
||||
EventName.radarFault: {
|
||||
|
@ -670,15 +667,13 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
EventName.lowMemory: {
|
||||
ET.SOFT_DISABLE: SoftDisableAlert("Low Memory: Reboot Your Device"),
|
||||
ET.PERMANENT: NormalPermanentAlert("Low Memory", "Reboot your Device"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device",
|
||||
audible_alert=AudibleAlert.chimeDisengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device"),
|
||||
},
|
||||
|
||||
EventName.highCpuUsage: {
|
||||
#ET.SOFT_DISABLE: SoftDisableAlert("System Malfunction: Reboot Your Device"),
|
||||
#ET.PERMANENT: NormalPermanentAlert("System Malfunction", "Reboot your Device"),
|
||||
ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device",
|
||||
audible_alert=AudibleAlert.chimeDisengage),
|
||||
ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device"),
|
||||
},
|
||||
|
||||
EventName.accFaulted: {
|
||||
|
@ -782,7 +777,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"openpilot Canceled",
|
||||
"No close lead car",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, 3.),
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.disengage, 3.),
|
||||
ET.NO_ENTRY: NoEntryAlert("No Close Lead Car"),
|
||||
},
|
||||
|
||||
|
@ -791,7 +786,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"openpilot Canceled",
|
||||
"Speed too low",
|
||||
AlertStatus.normal, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, 3.),
|
||||
Priority.HIGH, VisualAlert.none, AudibleAlert.disengage, 3.),
|
||||
},
|
||||
|
||||
# When the car is driving faster than most cars in the training data the model outputs can be unpredictable
|
||||
|
@ -800,7 +795,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, Callable[[Any, messaging.SubMaster, boo
|
|||
"Speed Too High",
|
||||
"Model uncertain at this speed",
|
||||
AlertStatus.userPrompt, AlertSize.mid,
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarning2RepeatInfinite, 4.),
|
||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.promptRepeat, 4.),
|
||||
ET.NO_ENTRY: NoEntryAlert("Slow down to engage"),
|
||||
},
|
||||
|
||||
|
|
|
@ -7,18 +7,31 @@ import time
|
|||
|
||||
from cereal import car, log
|
||||
import cereal.messaging as messaging
|
||||
from common.realtime import DT_CTRL
|
||||
from selfdrive.car.honda.interface import CarInterface
|
||||
from selfdrive.controls.lib.events import ET, EVENTS, Events
|
||||
from selfdrive.controls.lib.alertmanager import AlertManager
|
||||
|
||||
EventName = car.CarEvent.EventName
|
||||
|
||||
def cycle_alerts(duration=2000, is_metric=False):
|
||||
alerts = list(EVENTS.keys())
|
||||
print(alerts)
|
||||
def cycle_alerts(duration=200, is_metric=False):
|
||||
# all alerts
|
||||
#alerts = list(EVENTS.keys())
|
||||
|
||||
alerts = [EventName.preDriverDistracted, EventName.promptDriverDistracted, EventName.driverDistracted]
|
||||
#alerts = [EventName.preLaneChangeLeft, EventName.preLaneChangeRight]
|
||||
# this plays each type of audible alert
|
||||
alerts = [
|
||||
(EventName.buttonEnable, ET.ENABLE),
|
||||
(EventName.buttonCancel, ET.USER_DISABLE),
|
||||
(EventName.wrongGear, ET.NO_ENTRY),
|
||||
|
||||
(EventName.vehicleModelInvalid, ET.SOFT_DISABLE),
|
||||
(EventName.accFaulted, ET.IMMEDIATE_DISABLE),
|
||||
|
||||
# DM sequence
|
||||
(EventName.preDriverDistracted, ET.WARNING),
|
||||
(EventName.promptDriverDistracted, ET.WARNING),
|
||||
(EventName.driverDistracted, ET.WARNING),
|
||||
]
|
||||
|
||||
CP = CarInterface.get_params("HONDA CIVIC 2016")
|
||||
sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration',
|
||||
|
@ -30,23 +43,24 @@ def cycle_alerts(duration=2000, is_metric=False):
|
|||
AM = AlertManager()
|
||||
|
||||
frame = 0
|
||||
idx, last_alert_millis = 0, 0
|
||||
while 1:
|
||||
if frame % duration == 0:
|
||||
idx = (idx + 1) % len(alerts)
|
||||
events.clear()
|
||||
events.add(alerts[idx])
|
||||
|
||||
|
||||
while True:
|
||||
current_alert_types = [ET.PERMANENT, ET.USER_DISABLE, ET.IMMEDIATE_DISABLE,
|
||||
ET.SOFT_DISABLE, ET.PRE_ENABLE, ET.NO_ENTRY,
|
||||
ET.ENABLE, ET.WARNING]
|
||||
a = events.create_alerts(current_alert_types, [CP, sm, is_metric])
|
||||
|
||||
for alert, et in alerts:
|
||||
events.clear()
|
||||
events.add(alert)
|
||||
|
||||
a = events.create_alerts([et, ], [CP, sm, is_metric])
|
||||
AM.add_many(frame, a)
|
||||
AM.process_alerts(frame)
|
||||
|
||||
print(AM.alert)
|
||||
for _ in range(duration):
|
||||
dat = messaging.new_message()
|
||||
dat.init('controlsState')
|
||||
dat.controlsState.enabled = True
|
||||
|
||||
dat.controlsState.alertText1 = AM.alert_text_1
|
||||
dat.controlsState.alertText2 = AM.alert_text_2
|
||||
dat.controlsState.alertSize = AM.alert_size
|
||||
|
@ -66,7 +80,8 @@ def cycle_alerts(duration=2000, is_metric=False):
|
|||
dat.pandaStates[0].pandaType = log.PandaState.PandaType.uno
|
||||
pm.send('pandaStates', dat)
|
||||
|
||||
time.sleep(0.01)
|
||||
frame += 1
|
||||
time.sleep(DT_CTRL)
|
||||
|
||||
if __name__ == '__main__':
|
||||
cycle_alerts()
|
||||
|
|
|
@ -31,17 +31,18 @@ BASE_CONFIG = [
|
|||
AmpConfig("Enable PLL2", 0b1, 0x1A, 7, 0b10000000),
|
||||
AmpConfig("DAI1: I2S mode", 0b00100, 0x14, 2, 0b01111100),
|
||||
AmpConfig("DAI2: I2S mode", 0b00100, 0x1C, 2, 0b01111100),
|
||||
AmpConfig("Right speaker output volume", 0x1a, 0x3E, 0, 0b00011111),
|
||||
AmpConfig("Right speaker output volume", 0x1c, 0x3E, 0, 0b00011111),
|
||||
AmpConfig("DAI1 Passband filtering: music mode", 0b1, 0x18, 7, 0b10000000),
|
||||
AmpConfig("DAI1 voice mode gain (DV1G)", 0b00, 0x2F, 4, 0b00110000),
|
||||
AmpConfig("DAI1 attenuation (DV1)", 0x0, 0x2F, 0, 0b00001111),
|
||||
AmpConfig("DAI2 attenuation (DV2)", 0x0, 0x31, 0, 0b00001111),
|
||||
AmpConfig("DAI2: DC blocking", 0b1, 0x20, 0, 0b00000001),
|
||||
AmpConfig("DAI2: High sample rate", 0b0, 0x20, 3, 0b00001000),
|
||||
AmpConfig("ALC enable", 0b0, 0x43, 7, 0b10000000),
|
||||
AmpConfig("ALC enable", 0b1, 0x43, 7, 0b10000000),
|
||||
AmpConfig("ALC/excursion limiter release time", 0b101, 0x43, 4, 0b01110000),
|
||||
AmpConfig("ALC multiband enable", 0b1, 0x43, 3, 0b00001000),
|
||||
AmpConfig("DAI1 EQ enable", 0b0, 0x49, 0, 0b00000001),
|
||||
AmpConfig("DAI2 EQ enable", 0b0, 0x49, 1, 0b00000010),
|
||||
AmpConfig("DAI2 EQ enable", 0b1, 0x49, 1, 0b00000010),
|
||||
AmpConfig("DAI2 EQ clip detection disabled", 0b1, 0x32, 4, 0b00010000),
|
||||
AmpConfig("DAI2 EQ attenuation", 0x5, 0x32, 0, 0b00001111),
|
||||
AmpConfig("Excursion limiter upper corner freq", 0b100, 0x41, 4, 0b01110000),
|
||||
|
@ -62,11 +63,11 @@ BASE_CONFIG = [
|
|||
AmpConfig("Zero-crossing detection disabled", 0b0, 0x49, 5, 0b00100000),
|
||||
]
|
||||
|
||||
BASE_CONFIG += configs_from_eq_params(0x84, EQParams(0x65C4, 0xC07C, 0x3D66, 0x07D9, 0x120F))
|
||||
BASE_CONFIG += configs_from_eq_params(0x84, EQParams(0x274F, 0xC0FF, 0x3BF9, 0x0B3C, 0x1656))
|
||||
BASE_CONFIG += configs_from_eq_params(0x8E, EQParams(0x1009, 0xC6BF, 0x2952, 0x1C97, 0x30DF))
|
||||
BASE_CONFIG += configs_from_eq_params(0x98, EQParams(0x2822, 0xC1C7, 0x3B50, 0x0EF8, 0x180A))
|
||||
BASE_CONFIG += configs_from_eq_params(0xA2, EQParams(0x1009, 0xC5C2, 0x271F, 0x1A87, 0x32A6))
|
||||
BASE_CONFIG += configs_from_eq_params(0xAC, EQParams(0x2000, 0xCA1E, 0x4000, 0x2287, 0x0000))
|
||||
BASE_CONFIG += configs_from_eq_params(0x98, EQParams(0x0F75, 0xCBE5, 0x0ED2, 0x2528, 0x3E42))
|
||||
BASE_CONFIG += configs_from_eq_params(0xA2, EQParams(0x091F, 0x3D4C, 0xCE11, 0x1266, 0x2807))
|
||||
BASE_CONFIG += configs_from_eq_params(0xAC, EQParams(0x0A9E, 0x3F20, 0xE573, 0x0A8B, 0x3A3B))
|
||||
|
||||
class Amplifier:
|
||||
AMP_I2C_BUS = 0
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
class HardwareTici : public HardwareNone {
|
||||
public:
|
||||
static constexpr float MAX_VOLUME = 1.0;
|
||||
static constexpr float MIN_VOLUME = 0.4;
|
||||
static constexpr float MAX_VOLUME = 0.9;
|
||||
static constexpr float MIN_VOLUME = 0.3;
|
||||
static bool TICI() { return true; }
|
||||
static std::string get_os_version() {
|
||||
return "AGNOS " + util::read_file("/VERSION");
|
||||
|
|
|
@ -1 +1 @@
|
|||
e0926a8b9f7cffc35808109a710648a7f57c0b71
|
||||
9cbef406393a83b35a8f25aa75099da8f8d68276
|
|
@ -1,5 +1,9 @@
|
|||
#include "selfdrive/ui/soundd/sound.h"
|
||||
|
||||
#include <QAudio>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QDebug>
|
||||
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "selfdrive/common/util.h"
|
||||
|
||||
|
@ -7,14 +11,15 @@
|
|||
// TODO: detect when we can't display the UI
|
||||
|
||||
Sound::Sound(QObject *parent) : sm({"carState", "controlsState", "deviceState"}) {
|
||||
const QString sound_asset_path = Hardware::TICI() ? "../../assets/sounds_tici/" : "../../assets/sounds/";
|
||||
qInfo() << "default audio device: " << QAudioDeviceInfo::defaultOutputDevice().deviceName();
|
||||
|
||||
for (auto &[alert, fn, loops] : sound_list) {
|
||||
QSoundEffect *s = new QSoundEffect(this);
|
||||
QObject::connect(s, &QSoundEffect::statusChanged, [=]() {
|
||||
assert(s->status() != QSoundEffect::Error);
|
||||
});
|
||||
s->setVolume(Hardware::MIN_VOLUME);
|
||||
s->setSource(QUrl::fromLocalFile(sound_asset_path + fn));
|
||||
s->setSource(QUrl::fromLocalFile("../../assets/sounds/" + fn));
|
||||
sounds[alert] = {s, loops};
|
||||
}
|
||||
|
||||
|
@ -42,8 +47,9 @@ void Sound::update() {
|
|||
|
||||
// scale volume with speed
|
||||
if (sm.updated("carState")) {
|
||||
float volume = util::map_val(sm["carState"].getCarState().getVEgo(), 0.f, 20.f,
|
||||
Hardware::MIN_VOLUME, Hardware::MAX_VOLUME);
|
||||
float volume = std::clamp(sm["carState"].getCarState().getVEgo() / 29.f, 0.1f, 1.0f);
|
||||
volume = QAudio::convertVolume(volume, QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale);
|
||||
volume = util::map_val(volume, 0.f, 1.f, Hardware::MIN_VOLUME, Hardware::MAX_VOLUME);
|
||||
for (auto &[s, loops] : sounds) {
|
||||
s->setVolume(std::round(100 * volume) / 100);
|
||||
}
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
|
||||
const std::tuple<AudibleAlert, QString, int> sound_list[] = {
|
||||
// AudibleAlert, file name, loop count
|
||||
{AudibleAlert::CHIME_DISENGAGE, "disengaged.wav", 0},
|
||||
{AudibleAlert::CHIME_ENGAGE, "engaged.wav", 0},
|
||||
{AudibleAlert::CHIME_WARNING1, "warning_1.wav", 0},
|
||||
{AudibleAlert::CHIME_WARNING_REPEAT, "warning_repeat.wav", 10},
|
||||
{AudibleAlert::CHIME_WARNING_REPEAT_INFINITE, "warning_repeat.wav", QSoundEffect::Infinite},
|
||||
{AudibleAlert::CHIME_WARNING2_REPEAT_INFINITE, "warning_2.wav", QSoundEffect::Infinite},
|
||||
{AudibleAlert::CHIME_ERROR, "error.wav", 0},
|
||||
{AudibleAlert::CHIME_PROMPT, "error.wav", 0},
|
||||
{AudibleAlert::ENGAGE, "engage.wav", 0},
|
||||
{AudibleAlert::DISENGAGE, "disengage.wav", 0},
|
||||
{AudibleAlert::REFUSE, "refuse.wav", 0},
|
||||
|
||||
{AudibleAlert::PROMPT, "prompt.wav", 0},
|
||||
{AudibleAlert::PROMPT_REPEAT, "prompt.wav", QSoundEffect::Infinite},
|
||||
|
||||
{AudibleAlert::WARNING_SOFT, "warning_soft.wav", QSoundEffect::Infinite},
|
||||
{AudibleAlert::WARNING_IMMEDIATE, "warning_immediate.wav", 10},
|
||||
};
|
||||
|
||||
class Sound : public QObject {
|
||||
|
|
|
@ -15,14 +15,13 @@ AudibleAlert = car.CarControl.HUDControl.AudibleAlert
|
|||
SOUNDS = {
|
||||
# sound: total writes
|
||||
AudibleAlert.none: 0,
|
||||
AudibleAlert.chimeEngage: 173,
|
||||
AudibleAlert.chimeDisengage: 173,
|
||||
AudibleAlert.chimeError: 173,
|
||||
AudibleAlert.chimePrompt: 173,
|
||||
AudibleAlert.chimeWarning1: 163,
|
||||
AudibleAlert.chimeWarningRepeat: 468,
|
||||
AudibleAlert.chimeWarningRepeatInfinite: 468,
|
||||
AudibleAlert.chimeWarning2RepeatInfinite: 470,
|
||||
AudibleAlert.engage: 197,
|
||||
AudibleAlert.disengage: 230,
|
||||
AudibleAlert.refuse: 223,
|
||||
AudibleAlert.prompt: 217,
|
||||
AudibleAlert.promptRepeat: 475,
|
||||
AudibleAlert.warningSoft: 477,
|
||||
AudibleAlert.warningImmediate: 468,
|
||||
}
|
||||
|
||||
def get_total_writes():
|
||||
|
@ -40,7 +39,7 @@ class TestSoundd(unittest.TestCase):
|
|||
pm = messaging.PubMaster(['deviceState', 'controlsState'])
|
||||
|
||||
# make sure they're all defined
|
||||
alert_sounds = {v: k for k, v in car.CarControl.HUDControl.AudibleAlert.schema.enumerants.items()}
|
||||
alert_sounds = {v: k for k, v in car.CarControl.HUDControl.AudibleAlert.schema.enumerants.items() if not k.endswith('DEPRECATED')}
|
||||
diff = set(SOUNDS.keys()).symmetric_difference(alert_sounds.keys())
|
||||
assert len(diff) == 0, f"not all sounds defined in test: {diff}"
|
||||
|
||||
|
@ -65,7 +64,7 @@ class TestSoundd(unittest.TestCase):
|
|||
pm.send('controlsState', msg)
|
||||
time.sleep(DT_CTRL)
|
||||
|
||||
tolerance = (expected_writes % 100) * 2
|
||||
tolerance = expected_writes / 10
|
||||
actual_writes = get_total_writes() - start_writes
|
||||
assert abs(expected_writes - actual_writes) <= tolerance, f"{alert_sounds[sound]}: expected {expected_writes} writes, got {actual_writes}"
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ struct Alert {
|
|||
// car is started, but controls is lagging or died
|
||||
return {"TAKE CONTROL IMMEDIATELY", "Controls Unresponsive",
|
||||
"controlsUnresponsive", cereal::ControlsState::AlertSize::FULL,
|
||||
AudibleAlert::CHIME_WARNING_REPEAT};
|
||||
AudibleAlert::WARNING_IMMEDIATE};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
|
|
Loading…
Reference in New Issue