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