parent
05a09435b0
commit
48340cc8cb
24 changed files with 987 additions and 1171 deletions
@ -1 +1 @@ |
|||||||
Subproject commit 4f68db8f6aa31e87d968da882460e196c6b101a3 |
Subproject commit 856c9812d552fe0ac640b75074b080f76c9a3cba |
@ -1,825 +0,0 @@ |
|||||||
from cereal import car, log |
|
||||||
|
|
||||||
# Priority |
|
||||||
class Priority: |
|
||||||
LOWEST = 0 |
|
||||||
LOWER = 1 |
|
||||||
LOW = 2 |
|
||||||
MID = 3 |
|
||||||
HIGH = 4 |
|
||||||
HIGHEST = 5 |
|
||||||
|
|
||||||
AlertSize = log.ControlsState.AlertSize |
|
||||||
AlertStatus = log.ControlsState.AlertStatus |
|
||||||
AudibleAlert = car.CarControl.HUDControl.AudibleAlert |
|
||||||
VisualAlert = car.CarControl.HUDControl.VisualAlert |
|
||||||
|
|
||||||
class Alert(): |
|
||||||
def __init__(self, |
|
||||||
alert_type, |
|
||||||
alert_text_1, |
|
||||||
alert_text_2, |
|
||||||
alert_status, |
|
||||||
alert_size, |
|
||||||
alert_priority, |
|
||||||
visual_alert, |
|
||||||
audible_alert, |
|
||||||
duration_sound, |
|
||||||
duration_hud_alert, |
|
||||||
duration_text, |
|
||||||
alert_rate=0.): |
|
||||||
|
|
||||||
self.alert_type = alert_type |
|
||||||
self.alert_text_1 = alert_text_1 |
|
||||||
self.alert_text_2 = alert_text_2 |
|
||||||
self.alert_status = alert_status |
|
||||||
self.alert_size = alert_size |
|
||||||
self.alert_priority = alert_priority |
|
||||||
self.visual_alert = visual_alert |
|
||||||
self.audible_alert = audible_alert |
|
||||||
|
|
||||||
self.duration_sound = duration_sound |
|
||||||
self.duration_hud_alert = duration_hud_alert |
|
||||||
self.duration_text = duration_text |
|
||||||
|
|
||||||
self.start_time = 0. |
|
||||||
self.alert_rate = alert_rate |
|
||||||
|
|
||||||
# typecheck that enums are valid on startup |
|
||||||
tst = car.CarControl.new_message() |
|
||||||
tst.hudControl.visualAlert = self.visual_alert |
|
||||||
|
|
||||||
def __str__(self): |
|
||||||
return self.alert_text_1 + "/" + self.alert_text_2 + " " + str(self.alert_priority) + " " + str( |
|
||||||
self.visual_alert) + " " + str(self.audible_alert) |
|
||||||
|
|
||||||
def __gt__(self, alert2): |
|
||||||
return self.alert_priority > alert2.alert_priority |
|
||||||
|
|
||||||
|
|
||||||
ALERTS = [ |
|
||||||
# Miscellaneous alerts |
|
||||||
Alert( |
|
||||||
"enable", |
|
||||||
"", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.none, |
|
||||||
Priority.MID, VisualAlert.none, AudibleAlert.chimeEngage, .2, 0., 0.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"disable", |
|
||||||
"", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.none, |
|
||||||
Priority.MID, VisualAlert.none, AudibleAlert.chimeDisengage, .2, 0., 0.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"fcw", |
|
||||||
"BRAKE!", |
|
||||||
"Risk of Collision", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.chimeWarningRepeat, 1., 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"fcwStock", |
|
||||||
"BRAKE!", |
|
||||||
"Risk of Collision", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 1., 2., 2.), # no EON chime for stock FCW |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerSaturated", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Turn Exceeds Steering Limit", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerTempUnavailable", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Steering Temporarily Unavailable", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerTempUnavailableMute", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Steering Temporarily Unavailable", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2, .2, .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"preDriverDistracted", |
|
||||||
"KEEP EYES ON ROAD: Driver Distracted", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"promptDriverDistracted", |
|
||||||
"KEEP EYES ON ROAD", |
|
||||||
"Driver Appears Distracted", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"driverDistracted", |
|
||||||
"DISENGAGE IMMEDIATELY", |
|
||||||
"Driver Was Distracted", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"preDriverUnresponsive", |
|
||||||
"TOUCH STEERING WHEEL: No Face Detected", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"promptDriverUnresponsive", |
|
||||||
"TOUCH STEERING WHEEL", |
|
||||||
"Driver Is Unresponsive", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"driverUnresponsive", |
|
||||||
"DISENGAGE IMMEDIATELY", |
|
||||||
"Driver Was Unresponsive", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"driverMonitorLowAcc", |
|
||||||
"CHECK DRIVER FACE VISIBILITY", |
|
||||||
"Driver Monitor Model Output Uncertain", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .4, 0., 1.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"geofence", |
|
||||||
"DISENGAGEMENT REQUIRED", |
|
||||||
"Not in Geofenced Area", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"startup", |
|
||||||
"Be ready to take over at any time", |
|
||||||
"Always keep hands on wheel and eyes on road", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"startupMaster", |
|
||||||
"WARNING: This branch is not tested", |
|
||||||
"Always keep hands on wheel and eyes on road", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"startupNoControl", |
|
||||||
"Dashcam mode", |
|
||||||
"Always keep hands on wheel and eyes on road", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"startupNoCar", |
|
||||||
"Dashcam mode for unsupported car", |
|
||||||
"Always keep hands on wheel and eyes on road", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"ethicalDilemma", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Ethical Dilemma Detected", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 1., 3., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerTempUnavailableNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Steering Temporarily Unavailable", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 0., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"manualRestart", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Resume Driving Manually", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"resumeRequired", |
|
||||||
"STOPPED", |
|
||||||
"Press Resume to Move", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"belowSteerSpeed", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Steer Unavailable Below ", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.none, 0., 0.4, .3), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"debugAlert", |
|
||||||
"DEBUG ALERT", |
|
||||||
"", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1, .1, .1), |
|
||||||
Alert( |
|
||||||
"preLaneChangeLeft", |
|
||||||
"Steer Left to Start Lane Change", |
|
||||||
"Monitor Other Vehicles", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"preLaneChangeRight", |
|
||||||
"Steer Right to Start Lane Change", |
|
||||||
"Monitor Other Vehicles", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"laneChange", |
|
||||||
"Changing Lane", |
|
||||||
"Monitor Other Vehicles", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"posenetInvalid", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Vision Model Output Uncertain", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, .4, 2., 3.), |
|
||||||
|
|
||||||
# Non-entry only alerts |
|
||||||
Alert( |
|
||||||
"wrongCarModeNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Main Switch Off", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 0., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"dataNeededNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Calibration Needs Data. Upload Drive, Try Again", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 0., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"outOfSpaceNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Out of Storage Space", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 0., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"pedalPressedNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Pedal Pressed During Attempt", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, "brakePressed", AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"speedTooLowNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Speed Too Low", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"brakeHoldNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Brake Hold Active", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"parkBrakeNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Park Brake Engaged", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowSpeedLockoutNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Cruise Fault: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowBatteryNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Low Battery", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"sensorDataInvalidNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"No Data from Device Sensors", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"soundsUnavailableNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Speaker not found", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"tooDistractedNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Distraction Level Too High", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
# Cancellation alerts causing soft disabling |
|
||||||
Alert( |
|
||||||
"overheat", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"System Overheated", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"wrongGear", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Gear not D", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"calibrationInvalid", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Calibration Invalid: Reposition Device and Recalibrate", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"calibrationIncomplete", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Calibration in Progress", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"doorOpen", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Door Open", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"seatbeltNotLatched", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Seatbelt Unlatched", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"espDisabled", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"ESP Off", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowBattery", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Low Battery", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"commIssue", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Communication Issue between Processes", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarCommIssue", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Radar Communication Issue", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarCanError", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Radar Error: Restart the Car", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarFault", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Radar Error: Restart the Car", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowMemory", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Low Memory: Reboot Your Device", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
|
||||||
|
|
||||||
# Cancellation alerts causing immediate disabling |
|
||||||
Alert( |
|
||||||
"controlsFailed", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Controls Failed", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"controlsMismatch", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Controls Mismatch", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"canError", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"CAN Error: Check Connections", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerUnavailable", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"LKAS Fault: Restart the Car", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"brakeUnavailable", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Cruise Fault: Restart the Car", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"gasUnavailable", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Gas Fault: Restart the Car", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"reverseGear", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Reverse Gear", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"cruiseDisabled", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Cruise Is Off", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"plannerError", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Planner Solution Error", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"relayMalfunction", |
|
||||||
"TAKE CONTROL IMMEDIATELY", |
|
||||||
"Harness Malfunction", |
|
||||||
AlertStatus.critical, AlertSize.full, |
|
||||||
Priority.HIGHEST, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"speedTooHigh", |
|
||||||
"Speed Too High", |
|
||||||
"Slow down to resume operation", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, 2.2, 3., 4.), |
|
||||||
|
|
||||||
|
|
||||||
# not loud cancellations (user is in control) |
|
||||||
Alert( |
|
||||||
"noTarget", |
|
||||||
"openpilot Canceled", |
|
||||||
"No close lead car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"speedTooLow", |
|
||||||
"openpilot Canceled", |
|
||||||
"Speed too low", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
|
|
||||||
# Cancellation alerts causing non-entry |
|
||||||
Alert( |
|
||||||
"overheatNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"System overheated", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"wrongGearNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Gear not D", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"calibrationInvalidNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Calibration Invalid: Reposition Device & Recalibrate", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"calibrationIncompleteNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Calibration in Progress", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"doorOpenNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Door open", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"seatbeltNotLatchedNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Seatbelt unlatched", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"espDisabledNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"ESP Off", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"geofenceNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Not in Geofenced Area", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.MID, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarCanErrorNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Radar Error: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarFaultNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Radar Error: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"posenetInvalidNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Vision Model Output Uncertain", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"controlsFailedNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Controls Failed", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"canErrorNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"CAN Error: Check Connections", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"steerUnavailableNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"LKAS Fault: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"brakeUnavailableNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Cruise Fault: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"gasUnavailableNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Gas Error: Restart the Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"reverseGearNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Reverse Gear", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"cruiseDisabledNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Cruise is Off", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"noTargetNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"No Close Lead Car", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"plannerErrorNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Planner Solution Error", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"commIssueNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Communication Issue between Processes", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"radarCommIssueNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Radar Communication Issue", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"internetConnectivityNeededNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Please Connect to Internet", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowMemoryNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Low Memory: Reboot Your Device", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"speedTooHighNoEntry", |
|
||||||
"Speed Too High", |
|
||||||
"Slow down to engage", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"relayMalfunctionNoEntry", |
|
||||||
"openpilot Unavailable", |
|
||||||
"Harness Malfunction", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
|
||||||
|
|
||||||
# permanent alerts |
|
||||||
Alert( |
|
||||||
"steerUnavailablePermanent", |
|
||||||
"LKAS Fault: Restart the car to engage", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"brakeUnavailablePermanent", |
|
||||||
"Cruise Fault: Restart the car to engage", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowSpeedLockoutPermanent", |
|
||||||
"Cruise Fault: Restart the car to engage", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"calibrationIncompletePermanent", |
|
||||||
"Calibration in Progress: ", |
|
||||||
"Drive Above ", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"invalidGiraffeToyotaPermanent", |
|
||||||
"Unsupported Giraffe Configuration", |
|
||||||
"Visit comma.ai/tg", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"invalidLkasSettingPermanent", |
|
||||||
"Stock LKAS is turned on", |
|
||||||
"Turn off stock LKAS to engage", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"internetConnectivityNeededPermanent", |
|
||||||
"Please connect to Internet", |
|
||||||
"An Update Check Is Required to Engage", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"communityFeatureDisallowedPermanent", |
|
||||||
"Community Feature Detected", |
|
||||||
"Enable Community Features in Developer Settings", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), # LOW priority to overcome Cruise Error |
|
||||||
|
|
||||||
Alert( |
|
||||||
"sensorDataInvalidPermanent", |
|
||||||
"No Data from Device Sensors", |
|
||||||
"Reboot your Device", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"soundsUnavailablePermanent", |
|
||||||
"Speaker not found", |
|
||||||
"Reboot your Device", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"lowMemoryPermanent", |
|
||||||
"RAM Critically Low", |
|
||||||
"Reboot your Device", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"carUnrecognizedPermanent", |
|
||||||
"Dashcam Mode", |
|
||||||
"Car Unrecognized", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"relayMalfunctionPermanent", |
|
||||||
"Harness Malfunction", |
|
||||||
"Please Check Hardware", |
|
||||||
AlertStatus.normal, AlertSize.mid, |
|
||||||
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"vehicleModelInvalid", |
|
||||||
"Vehicle Parameter Identification Failed", |
|
||||||
"", |
|
||||||
AlertStatus.normal, AlertSize.small, |
|
||||||
Priority.LOWEST, VisualAlert.steerRequired, AudibleAlert.none, .0, .0, .1), |
|
||||||
|
|
||||||
Alert( |
|
||||||
"ldwPermanent", |
|
||||||
"TAKE CONTROL", |
|
||||||
"Lane Departure Detected", |
|
||||||
AlertStatus.userPrompt, AlertSize.mid, |
|
||||||
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 2., 3.), |
|
||||||
] |
|
@ -0,0 +1,694 @@ |
|||||||
|
from cereal import log, car |
||||||
|
|
||||||
|
from selfdrive.config import Conversions as CV |
||||||
|
|
||||||
|
from selfdrive.locationd.calibration_helpers import Filter |
||||||
|
|
||||||
|
AlertSize = log.ControlsState.AlertSize |
||||||
|
AlertStatus = log.ControlsState.AlertStatus |
||||||
|
VisualAlert = car.CarControl.HUDControl.VisualAlert |
||||||
|
AudibleAlert = car.CarControl.HUDControl.AudibleAlert |
||||||
|
EventName = car.CarEvent.EventName |
||||||
|
|
||||||
|
# Alert priorities |
||||||
|
class Priority: |
||||||
|
LOWEST = 0 |
||||||
|
LOWER = 1 |
||||||
|
LOW = 2 |
||||||
|
MID = 3 |
||||||
|
HIGH = 4 |
||||||
|
HIGHEST = 5 |
||||||
|
|
||||||
|
# Event types |
||||||
|
class ET: |
||||||
|
ENABLE = 'enable' |
||||||
|
PRE_ENABLE = 'preEnable' |
||||||
|
NO_ENTRY = 'noEntry' |
||||||
|
WARNING = 'warning' |
||||||
|
USER_DISABLE = 'userDisable' |
||||||
|
SOFT_DISABLE = 'softDisable' |
||||||
|
IMMEDIATE_DISABLE = 'immediateDisable' |
||||||
|
PERMANENT = 'permanent' |
||||||
|
|
||||||
|
# get event name from enum |
||||||
|
EVENT_NAME = {v: k for k, v in EventName.schema.enumerants.items()} |
||||||
|
|
||||||
|
class Events: |
||||||
|
def __init__(self): |
||||||
|
self.events = [] |
||||||
|
self.static_events = [] |
||||||
|
|
||||||
|
@property |
||||||
|
def names(self): |
||||||
|
return self.events |
||||||
|
|
||||||
|
def __len__(self): |
||||||
|
return len(self.events) |
||||||
|
|
||||||
|
def add(self, event_name, static=False): |
||||||
|
if static: |
||||||
|
self.static_events.append(event_name) |
||||||
|
self.events.append(event_name) |
||||||
|
|
||||||
|
def clear(self): |
||||||
|
self.events = self.static_events.copy() |
||||||
|
|
||||||
|
def any(self, event_type): |
||||||
|
for e in self.events: |
||||||
|
if event_type in EVENTS.get(e, {}).keys(): |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
def create_alerts(self, event_types, callback_args=[]): |
||||||
|
ret = [] |
||||||
|
for e in self.events: |
||||||
|
types = EVENTS[e].keys() |
||||||
|
for et in event_types: |
||||||
|
if et in types: |
||||||
|
alert = EVENTS[e][et] |
||||||
|
if not isinstance(alert, Alert): |
||||||
|
alert = alert(*callback_args) |
||||||
|
alert.alert_type = EVENT_NAME[e] |
||||||
|
ret.append(alert) |
||||||
|
return ret |
||||||
|
|
||||||
|
def add_from_msg(self, events): |
||||||
|
for e in events: |
||||||
|
self.events.append(e.name.raw) |
||||||
|
|
||||||
|
def to_msg(self): |
||||||
|
ret = [] |
||||||
|
for event_name in self.events: |
||||||
|
event = car.CarEvent.new_message() |
||||||
|
event.name = event_name |
||||||
|
for event_type in EVENTS.get(event_name, {}).keys(): |
||||||
|
setattr(event, event_type , True) |
||||||
|
ret.append(event) |
||||||
|
return ret |
||||||
|
|
||||||
|
class Alert: |
||||||
|
def __init__(self, |
||||||
|
alert_text_1, |
||||||
|
alert_text_2, |
||||||
|
alert_status, |
||||||
|
alert_size, |
||||||
|
alert_priority, |
||||||
|
visual_alert, |
||||||
|
audible_alert, |
||||||
|
duration_sound, |
||||||
|
duration_hud_alert, |
||||||
|
duration_text, |
||||||
|
alert_rate=0.): |
||||||
|
|
||||||
|
self.alert_type = "" |
||||||
|
self.alert_text_1 = alert_text_1 |
||||||
|
self.alert_text_2 = alert_text_2 |
||||||
|
self.alert_status = alert_status |
||||||
|
self.alert_size = alert_size |
||||||
|
self.alert_priority = alert_priority |
||||||
|
self.visual_alert = visual_alert |
||||||
|
self.audible_alert = audible_alert |
||||||
|
|
||||||
|
self.duration_sound = duration_sound |
||||||
|
self.duration_hud_alert = duration_hud_alert |
||||||
|
self.duration_text = duration_text |
||||||
|
|
||||||
|
self.start_time = 0. |
||||||
|
self.alert_rate = alert_rate |
||||||
|
|
||||||
|
# typecheck that enums are valid on startup |
||||||
|
tst = car.CarControl.new_message() |
||||||
|
tst.hudControl.visualAlert = self.visual_alert |
||||||
|
|
||||||
|
def __str__(self): |
||||||
|
return self.alert_text_1 + "/" + self.alert_text_2 + " " + str(self.alert_priority) + " " + str( |
||||||
|
self.visual_alert) + " " + str(self.audible_alert) |
||||||
|
|
||||||
|
def __gt__(self, alert2): |
||||||
|
return self.alert_priority > alert2.alert_priority |
||||||
|
|
||||||
|
class NoEntryAlert(Alert): |
||||||
|
def __init__(self, alert_text_2, audible_alert=AudibleAlert.chimeError, |
||||||
|
visual_alert=VisualAlert.none, duration_hud_alert=2.): |
||||||
|
super().__init__("openpilot Unavailable", alert_text_2, AlertStatus.normal, |
||||||
|
AlertSize.mid, Priority.LOW, visual_alert, |
||||||
|
audible_alert, .4, duration_hud_alert, 3.) |
||||||
|
|
||||||
|
|
||||||
|
class SoftDisableAlert(Alert): |
||||||
|
def __init__(self, alert_text_2): |
||||||
|
super().__init__("TAKE CONTROL IMMEDIATELY", alert_text_2, |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.MID, VisualAlert.steerRequired, |
||||||
|
AudibleAlert.chimeWarningRepeat, .1, 2., 2.), |
||||||
|
|
||||||
|
|
||||||
|
class ImmediateDisableAlert(Alert): |
||||||
|
def __init__(self, alert_text_2, alert_text_1="TAKE CONTROL IMMEDIATELY"): |
||||||
|
super().__init__(alert_text_1, alert_text_2, |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGHEST, VisualAlert.steerRequired, |
||||||
|
AudibleAlert.chimeWarningRepeat, 2.2, 3., 4.), |
||||||
|
|
||||||
|
class EngagementAlert(Alert): |
||||||
|
def __init__(self, audible_alert=True): |
||||||
|
super().__init__("", "", |
||||||
|
AlertStatus.normal, AlertSize.none, |
||||||
|
Priority.MID, VisualAlert.none, |
||||||
|
audible_alert, .2, 0., 0.), |
||||||
|
|
||||||
|
def below_steer_speed_alert(CP, sm, metric): |
||||||
|
speed = CP.minSteerSpeed * (CV.MS_TO_KPH if metric else CV.MS_TO_MPH) |
||||||
|
unit = "kph" if metric else "mph" |
||||||
|
return Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Steer Unavailable Below %d %s" % (speed, unit), |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.MID, VisualAlert.steerRequired, AudibleAlert.none, 0., 0.4, .3), |
||||||
|
|
||||||
|
def calibration_incomplete_alert(CP, sm, metric): |
||||||
|
speed = int(Filter.MIN_SPEED * (CV.MS_TO_KPH if metric else CV.MS_TO_MPH)) |
||||||
|
unit = "kph" if metric else "mph" |
||||||
|
return Alert( |
||||||
|
"Calibration in Progress: %d" % sm['liveCalibration'].calPerc, |
||||||
|
"Drive Above %d %s" % (speed, unit), |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
|
||||||
|
EVENTS = { |
||||||
|
# ********** events with no alerts ********** |
||||||
|
|
||||||
|
EventName.gasPressed: {ET.PRE_ENABLE: None}, |
||||||
|
|
||||||
|
# ********** events only containing alerts displayed in all states ********** |
||||||
|
|
||||||
|
EventName.debugAlert: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"DEBUG ALERT", |
||||||
|
"", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.startup: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Be ready to take over at any time", |
||||||
|
"Always keep hands on wheel and eyes on road", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.startupMaster: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"WARNING: This branch is not tested", |
||||||
|
"Always keep hands on wheel and eyes on road", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.startupNoControl: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Dashcam mode", |
||||||
|
"Always keep hands on wheel and eyes on road", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.startupNoCar: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Dashcam mode for unsupported car", |
||||||
|
"Always keep hands on wheel and eyes on road", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.invalidGiraffeToyota: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Unsupported Giraffe Configuration", |
||||||
|
"Visit comma.ai/tg", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.invalidLkasSetting: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Stock LKAS is turned on", |
||||||
|
"Turn off stock LKAS to engage", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.communityFeatureDisallowed: { |
||||||
|
# LOW priority to overcome Cruise Error |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"", |
||||||
|
"Community Feature Detected", |
||||||
|
"Enable Community Features in Developer Settings", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.carUnrecognized: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Dashcam Mode", |
||||||
|
"Car Unrecognized", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.stockAeb: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"BRAKE!", |
||||||
|
"Stock AEB: Risk of Collision", |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 1., 2., 2.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.stockFcw: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"BRAKE!", |
||||||
|
"Stock FCW: Risk of Collision", |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.none, 1., 2., 2.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.fcw: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"BRAKE!", |
||||||
|
"Risk of Collision", |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGHEST, VisualAlert.fcw, AudibleAlert.chimeWarningRepeat, 1., 2., 2.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.ldw: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Lane Departure Detected", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 2., 3.), |
||||||
|
}, |
||||||
|
|
||||||
|
# ********** events only containing alerts that display while engaged ********** |
||||||
|
|
||||||
|
EventName.vehicleModelInvalid: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"Vehicle Parameter Identification Failed", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOWEST, VisualAlert.steerRequired, AudibleAlert.none, .0, .0, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.steerTempUnavailableMute: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Steering Temporarily Unavailable", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.none, .2, .2, .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.preDriverDistracted: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"KEEP EYES ON ROAD: Driver Distracted", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.promptDriverDistracted: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"KEEP EYES ON ROAD", |
||||||
|
"Driver Appears Distracted", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.driverDistracted: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"DISEventName.AGE IMMEDIATELY", |
||||||
|
"Driver Was Distracted", |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.preDriverUnresponsive: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TOUCH STEERING WHEEL: No Face Detected", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.promptDriverUnresponsive: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TOUCH STEERING WHEEL", |
||||||
|
"Driver Is Unresponsive", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.MID, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, .1, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.driverUnresponsive: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"DISEventName.AGE IMMEDIATELY", |
||||||
|
"Driver Was Unresponsive", |
||||||
|
AlertStatus.critical, AlertSize.full, |
||||||
|
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarningRepeat, .1, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.driverMonitorLowAcc: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"CHECK DRIVER FACE VISIBILITY", |
||||||
|
"Driver Monitor Model Output Uncertain", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .4, 0., 1.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.manualRestart: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Resume Driving Manually", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.resumeRequired: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"STOPPED", |
||||||
|
"Press Resume to Move", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.belowSteerSpeed: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Steer Unavailable Below ", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.MID, VisualAlert.steerRequired, AudibleAlert.none, 0., 0.4, .3), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.preLaneChangeLeft: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"Steer Left to Start Lane Change", |
||||||
|
"Monitor Other Vehicles", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.preLaneChangeRight: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"Steer Right to Start Lane Change", |
||||||
|
"Monitor Other Vehicles", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1, alert_rate=0.75), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.laneChange: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"Changing Lane", |
||||||
|
"Monitor Other Vehicles", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.none, .0, .1, .1), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.steerSaturated: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Turn Exceeds Steering Limit", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimePrompt, 1., 2., 3.), |
||||||
|
}, |
||||||
|
|
||||||
|
# ********** events that affect controls state transitions ********** |
||||||
|
|
||||||
|
EventName.pcmEnable: { |
||||||
|
ET.ENABLE: EngagementAlert(AudibleAlert.chimeEngage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.buttonEnable: { |
||||||
|
ET.ENABLE: EngagementAlert(AudibleAlert.chimeEngage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.pcmDisable: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.buttonCancel: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.brakeHold: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Brake Hold Active"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.parkBrake: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Park Brake Engaged"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.pedalPressed: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Pedal Pressed During Attempt", |
||||||
|
visual_alert=VisualAlert.brakePressed), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.wrongCarMode: { |
||||||
|
ET.USER_DISABLE: EngagementAlert(AudibleAlert.chimeDisengage), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Main Switch Off", |
||||||
|
duration_hud_alert=0.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.steerTempUnavailable: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Steering Temporarily Unavailable", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, .4, 2., 3.), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Steering Temporarily Unavailable", |
||||||
|
duration_hud_alert=0.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.posenetInvalid: { |
||||||
|
ET.WARNING: Alert( |
||||||
|
"TAKE CONTROL", |
||||||
|
"Vision Model Output Uncertain", |
||||||
|
AlertStatus.userPrompt, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.chimeWarning1, .4, 2., 3.), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Vision Model Output Uncertain"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.outOfSpace: { |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Out of Storage Space", |
||||||
|
duration_hud_alert=0.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.sensorDataInvalid: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"No Data from Device Sensors", |
||||||
|
"Reboot your Device", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("No Data from Device Sensors"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.soundsUnavailable: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Speaker not found", |
||||||
|
"Reboot your Device", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Speaker not found"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.tooDistracted: { |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Distraction Level Too High"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.overheat: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("System Overheated"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("System overheated"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.wrongGear: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Gear not D"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Gear not D"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.calibrationInvalid: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Calibration Invalid: Reposition Device and Recalibrate"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Calibration Invalid: Reposition Device & Recalibrate"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.calibrationIncomplete: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Calibration in Progress"), |
||||||
|
ET.PERMANENT: calibration_incomplete_alert, |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Calibration in Progress"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.doorOpen: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Door Open"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Door open"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.seatbeltNotLatched: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Seatbelt Unlatched"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Seatbelt unlatched"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.espDisabled: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("ESP Off"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("ESP Off"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.lowBattery: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Low Battery"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Low Battery"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.commIssue: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Communication Issue between Processes"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Communication Issue between Processes", |
||||||
|
audible_alert=AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.radarCommIssue: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Radar Communication Issue"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Radar Communication Issue", |
||||||
|
audible_alert=AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.radarCanError: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Radar Error: Restart the Car"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Radar Error: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.radarFault: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Radar Error: Restart the Car"), |
||||||
|
ET.NO_ENTRY : NoEntryAlert("Radar Error: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.lowMemory: { |
||||||
|
ET.SOFT_DISABLE: SoftDisableAlert("Low Memory: Reboot Your Device"), |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"RAM Critically Low", |
||||||
|
"Reboot your Device", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY : NoEntryAlert("Low Memory: Reboot Your Device", |
||||||
|
audible_alert=AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.controlsFailed: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Controls Failed"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Controls Failed"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.controlsMismatch: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Controls Mismatch"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.canError: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("CAN Error: Check Connections"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("CAN Error: Check Connections"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.steerUnavailable: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("LKAS Fault: Restart the Car"), |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"LKAS Fault: Restart the car to engage", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("LKAS Fault: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.brakeUnavailable: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Fault: Restart the Car"), |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Cruise Fault: Restart the car to engage", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Cruise Fault: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.gasUnavailable: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Gas Fault: Restart the Car"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Gas Error: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.reverseGear: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Reverse Gear"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.cruiseDisabled: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Cruise Is Off"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.plannerError: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Planner Solution Error"), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Planner Solution Error"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.relayMalfunction: { |
||||||
|
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Harness Malfunction"), |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Harness Malfunction", |
||||||
|
"Please Check Hardware", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Harness Malfunction"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.noTarget: { |
||||||
|
ET.IMMEDIATE_DISABLE: Alert( |
||||||
|
"openpilot Canceled", |
||||||
|
"No close lead car", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
||||||
|
ET.NO_ENTRY : NoEntryAlert("No Close Lead Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.speedTooLow: { |
||||||
|
ET.IMMEDIATE_DISABLE: Alert( |
||||||
|
"openpilot Canceled", |
||||||
|
"Speed too low", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.HIGH, VisualAlert.none, AudibleAlert.chimeDisengage, .4, 2., 3.), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Speed Too Low"), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.speedTooHigh: { |
||||||
|
ET.IMMEDIATE_DISABLE: Alert( |
||||||
|
"Speed Too High", |
||||||
|
"Slow down to resume operation", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.chimeWarning2Repeat, 2.2, 3., 4.), |
||||||
|
ET.NO_ENTRY: Alert( |
||||||
|
"Speed Too High", |
||||||
|
"Slow down to engage", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.internetConnectivityNeeded: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Please connect to Internet", |
||||||
|
"An Update Check Is Required to Engage", |
||||||
|
AlertStatus.normal, AlertSize.mid, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Please Connect to Internet", |
||||||
|
audible_alert=AudibleAlert.chimeDisengage), |
||||||
|
}, |
||||||
|
|
||||||
|
EventName.lowSpeedLockout: { |
||||||
|
ET.PERMANENT: Alert( |
||||||
|
"Cruise Fault: Restart the car to engage", |
||||||
|
"", |
||||||
|
AlertStatus.normal, AlertSize.small, |
||||||
|
Priority.LOWER, VisualAlert.none, AudibleAlert.none, 0., 0., .2), |
||||||
|
ET.NO_ENTRY: NoEntryAlert("Cruise Fault: Restart the Car"), |
||||||
|
}, |
||||||
|
|
||||||
|
} |
@ -1,48 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import os |
|
||||||
import unittest |
|
||||||
from PIL import Image, ImageDraw, ImageFont |
|
||||||
|
|
||||||
from cereal import log |
|
||||||
from common.basedir import BASEDIR |
|
||||||
from selfdrive.controls.lib.alerts import ALERTS |
|
||||||
|
|
||||||
AlertSize = log.ControlsState.AlertSize |
|
||||||
|
|
||||||
FONT_PATH = os.path.join(BASEDIR, "selfdrive/assets/fonts") |
|
||||||
REGULAR_FONT_PATH = os.path.join(FONT_PATH, "opensans_semibold.ttf") |
|
||||||
BOLD_FONT_PATH = os.path.join(FONT_PATH, "opensans_semibold.ttf") |
|
||||||
SEMIBOLD_FONT_PATH = os.path.join(FONT_PATH, "opensans_semibold.ttf") |
|
||||||
|
|
||||||
MAX_TEXT_WIDTH = 1920 - 300 # full screen width is useable, minus sidebar |
|
||||||
# TODO: get exact scale factor. found this empirically, works well enough |
|
||||||
FONT_SIZE_SCALE = 1.85 # factor to scale from nanovg units to PIL |
|
||||||
|
|
||||||
class TestAlerts(unittest.TestCase): |
|
||||||
|
|
||||||
# ensure alert text doesn't exceed allowed width |
|
||||||
def test_alert_text_length(self): |
|
||||||
draw = ImageDraw.Draw(Image.new('RGB', (0, 0))) |
|
||||||
|
|
||||||
fonts = { |
|
||||||
AlertSize.small: [ImageFont.truetype(SEMIBOLD_FONT_PATH, int(40*FONT_SIZE_SCALE))], |
|
||||||
AlertSize.mid: [ImageFont.truetype(BOLD_FONT_PATH, int(48*FONT_SIZE_SCALE)), |
|
||||||
ImageFont.truetype(REGULAR_FONT_PATH, int(36*FONT_SIZE_SCALE))], |
|
||||||
} |
|
||||||
|
|
||||||
for alert in ALERTS: |
|
||||||
# for full size alerts, both text fields wrap the text, |
|
||||||
# so it's unlikely that they would go past the max width |
|
||||||
if alert.alert_size in [AlertSize.none, AlertSize.full]: |
|
||||||
continue |
|
||||||
|
|
||||||
for i, txt in enumerate([alert.alert_text_1, alert.alert_text_2]): |
|
||||||
if i >= len(fonts[alert.alert_size]): break |
|
||||||
|
|
||||||
font = fonts[alert.alert_size][i] |
|
||||||
w, h = draw.textsize(txt, font) |
|
||||||
msg = "type: %s msg: %s" % (alert.alert_type, txt) |
|
||||||
self.assertLessEqual(w, MAX_TEXT_WIDTH, msg=msg) |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
unittest.main() |
|
@ -0,0 +1,63 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import os |
||||||
|
import unittest |
||||||
|
from PIL import Image, ImageDraw, ImageFont |
||||||
|
|
||||||
|
from cereal import log, car |
||||||
|
from common.basedir import BASEDIR |
||||||
|
from selfdrive.controls.lib.events import Alert, EVENTS |
||||||
|
|
||||||
|
AlertSize = log.ControlsState.AlertSize |
||||||
|
|
||||||
|
class TestAlerts(unittest.TestCase): |
||||||
|
|
||||||
|
def test_events_defined(self): |
||||||
|
# Ensure all events in capnp schema are defined in events.py |
||||||
|
events = car.CarEvent.EventName.schema.enumerants |
||||||
|
|
||||||
|
for name, e in events.items(): |
||||||
|
if not name.endswith("DEPRECATED"): |
||||||
|
fail_msg = "%s @%d not in EVENTS" % (name, e) |
||||||
|
self.assertTrue(e in EVENTS.keys(), msg=fail_msg) |
||||||
|
|
||||||
|
# ensure alert text doesn't exceed allowed width |
||||||
|
def test_alert_text_length(self): |
||||||
|
font_path = os.path.join(BASEDIR, "selfdrive/assets/fonts") |
||||||
|
regular_font_path = os.path.join(font_path, "opensans_semibold.ttf") |
||||||
|
bold_font_path = os.path.join(font_path, "opensans_semibold.ttf") |
||||||
|
semibold_font_path = os.path.join(font_path, "opensans_semibold.ttf") |
||||||
|
|
||||||
|
max_text_width = 1920 - 300 # full screen width is useable, minus sidebar |
||||||
|
# TODO: get exact scale factor. found this empirically, works well enough |
||||||
|
font_scale_factor = 1.85 # factor to scale from nanovg units to PIL |
||||||
|
|
||||||
|
draw = ImageDraw.Draw(Image.new('RGB', (0, 0))) |
||||||
|
|
||||||
|
fonts = { |
||||||
|
AlertSize.small: [ImageFont.truetype(semibold_font_path, int(40*font_scale_factor))], |
||||||
|
AlertSize.mid: [ImageFont.truetype(bold_font_path, int(48*font_scale_factor)), |
||||||
|
ImageFont.truetype(regular_font_path, int(36*font_scale_factor))], |
||||||
|
} |
||||||
|
|
||||||
|
alerts = [] |
||||||
|
for event_types in EVENTS.values(): |
||||||
|
for alert in event_types.values(): |
||||||
|
if isinstance(alert, Alert): |
||||||
|
alerts.append(alert) |
||||||
|
|
||||||
|
for alert in alerts: |
||||||
|
# for full size alerts, both text fields wrap the text, |
||||||
|
# so it's unlikely that they would go past the max width |
||||||
|
if alert.alert_size in [AlertSize.none, AlertSize.full]: |
||||||
|
continue |
||||||
|
|
||||||
|
for i, txt in enumerate([alert.alert_text_1, alert.alert_text_2]): |
||||||
|
if i >= len(fonts[alert.alert_size]): break |
||||||
|
|
||||||
|
font = fonts[alert.alert_size][i] |
||||||
|
w, h = draw.textsize(txt, font) |
||||||
|
msg = "type: %s msg: %s" % (alert.alert_type, txt) |
||||||
|
self.assertLessEqual(w, max_text_width, msg=msg) |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
unittest.main() |
@ -1 +1 @@ |
|||||||
1050a84363baf1e7910d3f8f9a01e201e6041e70 |
76e577b86d113139167275b4a7379f3591abfa02 |
Loading…
Reference in new issue