diff --git a/cereal/custom.capnp b/cereal/custom.capnp index ce63df7..578fc8b 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -18,6 +18,7 @@ struct FrogPilotDeviceState @0xaedffd8f31e7b55d { } enum FrogPilotEvents @0xf35cc4560bbf6ec2 { + frogSteerSaturated @0; } struct FrogPilotLateralPlan @0xda96579883444c35 { diff --git a/common/params.cc b/common/params.cc index 2ffe36c..287b5ff 100644 --- a/common/params.cc +++ b/common/params.cc @@ -236,10 +236,16 @@ std::unordered_map keys = { {"CEStopLights", PERSISTENT}, {"CEStopLightsLead", PERSISTENT}, {"ConditionalExperimental", PERSISTENT}, + {"CustomColors", PERSISTENT}, + {"CustomIcons", PERSISTENT}, {"CustomPersonalities", PERSISTENT}, {"CustomUI", PERSISTENT}, + {"CustomSignals", PERSISTENT}, + {"CustomSounds", PERSISTENT}, + {"CustomTheme", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT}, {"GasRegenCmd", PERSISTENT}, + {"GoatScream", PERSISTENT}, {"LaneLinesWidth", PERSISTENT}, {"LateralTune", PERSISTENT}, {"LeadInfo", PERSISTENT}, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 17d659b..6e25c4b 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -698,7 +698,7 @@ class Controls: good_speed = CS.vEgo > 5 max_torque = abs(self.last_actuators.steer) > 0.99 if undershooting and turning and good_speed and max_torque: - lac_log.active and self.events.add(EventName.steerSaturated) + lac_log.active and self.events.add(FrogPilotEventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated) elif lac_log.saturated: dpath_points = lat_plan.dPathPoints if len(dpath_points): @@ -953,6 +953,11 @@ class Controls: self.average_desired_curvature = self.params.get_bool("AverageCurvature") self.conditional_experimental_mode = self.params.get_bool("ConditionalExperimental") + custom_theme = self.params.get_bool("CustomTheme") + custom_sounds = self.params.get_int("CustomSounds") if custom_theme else 0 + frog_sounds = custom_sounds == 1 + self.goat_scream = self.params.get_bool("GoatScream") and frog_sounds + longitudinal_tune = self.params.get_bool("LongitudinalTune") self.sport_plus = self.params.get_int("AccelerationProfile") == 3 and longitudinal_tune diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 9292067..5cf1458 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -967,6 +967,13 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { }, # FrogPilot Events + FrogPilotEventName.frogSteerSaturated: { + ET.WARNING: Alert( + "Turn Exceeds Steering Limit", + "JESUS TAKE THE WHEEL!!", + AlertStatus.userPrompt, AlertSize.mid, + Priority.LOW, VisualAlert.steerRequired, AudibleAlert.warningSoft, 2.), + }, } diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_flag.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_flag.png new file mode 100644 index 0000000..627af8a Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_flag.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_home.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_home.png new file mode 100644 index 0000000..627af8a Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_home.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_settings.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_settings.png new file mode 100644 index 0000000..5592759 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/button_settings.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1.png new file mode 100644 index 0000000..43e0b44 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1_red.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1_red.png new file mode 100644 index 0000000..7c10245 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_1_red.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_2.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_2.png new file mode 100644 index 0000000..e8e1479 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_2.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_3.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_3.png new file mode 100644 index 0000000..b59b003 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_3.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_4.png b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_4.png new file mode 100644 index 0000000..c3c1d20 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/images/turn_signal_4.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/disengage.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/disengage.wav new file mode 100644 index 0000000..7794b90 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/disengage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/engage.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/engage.wav new file mode 100644 index 0000000..4bfb44f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/engage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt.wav new file mode 100644 index 0000000..420e9fa Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt_distracted.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt_distracted.wav new file mode 100644 index 0000000..c3d4475 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/prompt_distracted.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/refuse.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/refuse.wav new file mode 100644 index 0000000..0e80f7d Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/refuse.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_immediate.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_immediate.wav new file mode 100644 index 0000000..a8c778f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_immediate.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_soft.wav b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_soft.wav new file mode 100644 index 0000000..0acb3cd Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/frog_theme/sounds/warning_soft.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_flag.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_flag.png new file mode 100644 index 0000000..1dca7ef Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_flag.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_home.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_home.png new file mode 100644 index 0000000..1dca7ef Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_home.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_settings.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_settings.png new file mode 100644 index 0000000..b58a726 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/button_settings.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1.png new file mode 100644 index 0000000..e676572 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1_red.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1_red.png new file mode 100644 index 0000000..3c26791 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_1_red.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_2.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_2.png new file mode 100644 index 0000000..e8b60bf Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_2.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_3.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_3.png new file mode 100644 index 0000000..0f4b10e Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_3.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_4.png b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_4.png new file mode 100644 index 0000000..6e66c3c Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/images/turn_signal_4.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/disengage.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/disengage.wav new file mode 100644 index 0000000..2e7e764 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/disengage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/engage.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/engage.wav new file mode 100644 index 0000000..f83bfaa Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/engage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt.wav new file mode 100644 index 0000000..420e9fa Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt_distracted.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt_distracted.wav new file mode 100644 index 0000000..c3d4475 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/prompt_distracted.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/refuse.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/refuse.wav new file mode 100644 index 0000000..aa4b42f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/refuse.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_immediate.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_immediate.wav new file mode 100644 index 0000000..a8c778f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_immediate.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_soft.wav b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_soft.wav new file mode 100644 index 0000000..f3982ea Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stalin_theme/sounds/warning_soft.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_flag.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_flag.png new file mode 100644 index 0000000..cac4db6 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_flag.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_home.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_home.png new file mode 100644 index 0000000..9f52faf Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_home.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_settings.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_settings.png new file mode 100644 index 0000000..e04262b Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/button_settings.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1.png new file mode 100644 index 0000000..27320df Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1_red.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1_red.png new file mode 100644 index 0000000..27320df Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_1_red.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_2.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_2.png new file mode 100644 index 0000000..27320df Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_2.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_3.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_3.png new file mode 100644 index 0000000..27320df Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_3.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_4.png b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_4.png new file mode 100644 index 0000000..27320df Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/images/turn_signal_4.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/disengage.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/disengage.wav new file mode 100644 index 0000000..7794b90 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/disengage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/engage.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/engage.wav new file mode 100644 index 0000000..4bfb44f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/engage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt.wav new file mode 100644 index 0000000..420e9fa Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt_distracted.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt_distracted.wav new file mode 100644 index 0000000..c3d4475 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/prompt_distracted.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/refuse.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/refuse.wav new file mode 100644 index 0000000..0e80f7d Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/refuse.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_immediate.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_immediate.wav new file mode 100644 index 0000000..a8c778f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_immediate.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_soft.wav b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_soft.wav new file mode 100644 index 0000000..0acb3cd Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/stock_theme/sounds/warning_soft.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_flag.png b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_flag.png new file mode 100644 index 0000000..2a140b9 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_flag.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_home.png b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_home.png new file mode 100644 index 0000000..2a140b9 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_home.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_settings.png b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_settings.png new file mode 100644 index 0000000..549e2be Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/images/button_settings.png differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/disengage.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/disengage.wav new file mode 100644 index 0000000..34187bc Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/disengage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/engage.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/engage.wav new file mode 100644 index 0000000..5203a04 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/engage.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt.wav new file mode 100644 index 0000000..420e9fa Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt_distracted.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt_distracted.wav new file mode 100644 index 0000000..c3d4475 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/prompt_distracted.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/refuse.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/refuse.wav new file mode 100644 index 0000000..0e80f7d Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/refuse.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_immediate.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_immediate.wav new file mode 100644 index 0000000..a8c778f Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_immediate.wav differ diff --git a/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_soft.wav b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_soft.wav new file mode 100644 index 0000000..334bf97 Binary files /dev/null and b/selfdrive/frogpilot/assets/custom_themes/tesla_theme/sounds/warning_soft.wav differ diff --git a/selfdrive/frogpilot/ui/visual_settings.cc b/selfdrive/frogpilot/ui/visual_settings.cc index 0d12932..c530c53 100644 --- a/selfdrive/frogpilot/ui/visual_settings.cc +++ b/selfdrive/frogpilot/ui/visual_settings.cc @@ -3,6 +3,12 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { const std::vector> visualToggles { + {"CustomTheme", "Custom Themes", "Enable the ability to use custom themes.", "../frogpilot/assets/wheel_images/frog.png"}, + {"CustomColors", "Color Theme", "Switch out the standard openpilot color scheme with a custom color scheme.\n\nWant to submit your own color scheme? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""}, + {"CustomIcons", "Icon Pack", "Switch out the standard openpilot icons with a set of custom icons.\n\nWant to submit your own icon pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""}, + {"CustomSignals", "Turn Signals", "Add custom animations for your turn signals for a personal touch!\n\nWant to submit your own turn signal animation? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""}, + {"CustomSounds", "Sound Pack", "Switch out the standard openpilot sounds with a set of custom sounds.\n\nWant to submit your own sound pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""}, + {"CameraView", "Camera View", "Choose your preferred camera view for the onroad UI. This is a visual change only and doesn't impact openpilot.", "../frogpilot/assets/toggle_icons/icon_camera.png"}, {"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"}, @@ -31,6 +37,32 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot FrogPilotButtonParamControl *preferredCamera = new FrogPilotButtonParamControl(param, title, desc, icon, cameraOptions); toggle = preferredCamera; + } else if (param == "CustomTheme") { + FrogPilotParamManageControl *customThemeToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customThemeToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(customThemeKeys.find(key.c_str()) != customThemeKeys.end()); + } + }); + toggle = customThemeToggle; + } else if (param == "CustomColors" || param == "CustomIcons" || param == "CustomSignals" || param == "CustomSounds") { + std::vector themeOptions{tr("Stock"), tr("Frog"), tr("Tesla"), tr("Stalin")}; + FrogPilotButtonParamControl *themeSelection = new FrogPilotButtonParamControl(param, title, desc, icon, themeOptions); + toggle = themeSelection; + + if (param == "CustomSounds") { + QObject::connect(static_cast(toggle), &FrogPilotButtonParamControl::buttonClicked, [this](int id) { + if (id == 1) { + if (FrogPilotConfirmationDialog::yesorno("Do you want to enable the bonus 'Goat' sound effect?", this)) { + params.putBool("GoatScream", true); + } else { + params.putBool("GoatScream", false); + } + } + }); + } + } else if (param == "CustomUI") { FrogPilotParamManageControl *customUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); QObject::connect(customUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { @@ -99,7 +131,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot } customOnroadUIKeys = {"AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo"}; - customThemeKeys = {}; + customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"}; modelUIKeys = {"AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"}; QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotVisualsPanel::hideSubToggles); diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 005abdb..018dd9d 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -409,7 +409,7 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { has_eu_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::VIENNA); is_metric = s.scene.is_metric; speedUnit = s.scene.is_metric ? tr("km/h") : tr("mph"); - hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE); + hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE || customSignals && (turnSignalLeft || turnSignalRight)); status = s.status; // update engageability/experimental mode button @@ -571,13 +571,21 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { // lanelines for (int i = 0; i < std::size(scene.lane_line_vertices); ++i) { - painter.setBrush(QColor::fromRgbF(1.0, 1.0, 1.0, std::clamp(scene.lane_line_probs[i], 0.0, 0.7))); + if (customColors != 0) { + painter.setBrush(themeConfiguration[customColors].second.first); + } else { + painter.setBrush(QColor::fromRgbF(1.0, 1.0, 1.0, std::clamp(scene.lane_line_probs[i], 0.0, 0.7))); + } painter.drawPolygon(scene.lane_line_vertices[i]); } // road edges for (int i = 0; i < std::size(scene.road_edge_vertices); ++i) { - painter.setBrush(QColor::fromRgbF(1.0, 0, 0, std::clamp(1.0 - scene.road_edge_stds[i], 0.0, 1.0))); + if (customColors != 0) { + painter.setBrush(themeConfiguration[customColors].second.first); + } else { + painter.setBrush(QColor::fromRgbF(1.0, 0, 0, std::clamp(1.0 - scene.road_edge_stds[i], 0.0, 1.0))); + } painter.drawPolygon(scene.road_edge_vertices[i]); } @@ -586,8 +594,14 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { if (sm["controlsState"].getControlsState().getExperimentalMode() || accelerationPath) { // The first half of track_vertices are the points for the right side of the path // and the indices match the positions of accel from uiPlan - const auto &acceleration = sm["uiPlan"].getUiPlan().getAccel(); - const int max_len = std::min(scene.track_vertices.length() / 2, acceleration.size()); + const auto &acceleration_const = sm["uiPlan"].getUiPlan().getAccel(); + const int max_len = std::min(scene.track_vertices.length() / 2, acceleration_const.size()); + + // Copy of the acceleration vector + std::vector acceleration; + for (int i = 0; i < acceleration_const.size(); i++) { + acceleration.push_back(acceleration_const[i]); + } for (int i = 0; i < max_len; ++i) { // Some points are out of frame @@ -596,20 +610,33 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { // Flip so 0 is bottom of frame float lin_grad_point = (height() - scene.track_vertices[i].y()) / height(); - // speed up: 120, slow down: 0 - float path_hue = fmax(fmin(60 + acceleration[i] * 35, 120), 0); - // FIXME: painter.drawPolygon can be slow if hue is not rounded - path_hue = int(path_hue * 100 + 0.5) / 100; + // If acceleration is between -0.2 and 0.2, resort to the theme color + if (std::abs(acceleration[i]) < 0.2 && (customColors != 0)) { + const auto &colorMap = themeConfiguration[customColors].second.second; + for (const auto &[position, brush] : colorMap) { + bg.setColorAt(position, brush.color()); + } + } else { + // speed up: 120, slow down: 0 + float path_hue = fmax(fmin(60 + acceleration[i] * 35, 120), 0); + // FIXME: painter.drawPolygon can be slow if hue is not rounded + path_hue = int(path_hue * 100 + 0.5) / 100; - float saturation = fmin(fabs(acceleration[i] * 1.5), 1); - float lightness = util::map_val(saturation, 0.0f, 1.0f, 0.95f, 0.62f); // lighter when grey - float alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, 0.4f, 0.0f); // matches previous alpha fade - bg.setColorAt(lin_grad_point, QColor::fromHslF(path_hue / 360., saturation, lightness, alpha)); + float saturation = fmin(fabs(acceleration[i] * 1.5), 1); + float lightness = util::map_val(saturation, 0.0f, 1.0f, 0.95f, 0.62f); // lighter when grey + float alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, 0.4f, 0.0f); // matches previous alpha fade + bg.setColorAt(lin_grad_point, QColor::fromHslF(path_hue / 360., saturation, lightness, alpha)); - // Skip a point, unless next is last - i += (i + 2) < max_len ? 1 : 0; + // Skip a point, unless next is last + i += (i + 2) < max_len ? 1 : 0; + } } + } else if (customColors != 0) { + const auto &colorMap = themeConfiguration[customColors].second.second; + for (const auto &[position, brush] : colorMap) { + bg.setColorAt(position, brush.color()); + } } else { bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4)); bg.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.35)); @@ -642,6 +669,12 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { pe.setColorAt(0.0, QColor::fromHslF(205 / 360., 0.85, 0.56, 1.0)); pe.setColorAt(0.5, QColor::fromHslF(205 / 360., 0.85, 0.56, 0.5)); pe.setColorAt(1.0, QColor::fromHslF(205 / 360., 0.85, 0.56, 0.1)); + } else if (customColors != 0) { + const auto &colorMap = themeConfiguration[customColors].second.second; + for (const auto &[position, brush] : colorMap) { + QColor darkerColor = brush.color().darker(120); + pe.setColorAt(position, darkerColor); + } } else { pe.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 1.0)); pe.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.00, 0.68, 0.5)); @@ -756,8 +789,8 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s) void AnnotatedCameraWidget::drawLead(QPainter &painter, const cereal::RadarState::LeadData::Reader &lead_data, const QPointF &vd) { painter.save(); - const float speedBuff = 10.; - const float leadBuff = 40.; + const float speedBuff = customColors ? 25. : 10.; // Make the center of the chevron appear sooner if a custom theme is active + const float leadBuff = customColors ? 100. : 40.; // Make the center of the chevron appear sooner if a custom theme is active const float d_rel = lead_data.getDRel(); const float v_rel = lead_data.getVRel(); @@ -783,7 +816,11 @@ void AnnotatedCameraWidget::drawLead(QPainter &painter, const cereal::RadarState // chevron QPointF chevron[] = {{x + (sz * 1.25), y + sz}, {x, y}, {x - (sz * 1.25), y + sz}}; - painter.setBrush(redColor(fillAlpha)); + if (customColors != 0) { + painter.setBrush(themeConfiguration[customColors].second.first); + } else { + painter.setBrush(redColor(fillAlpha)); + } painter.drawPolygon(chevron, std::size(chevron)); // Add lead info @@ -949,6 +986,25 @@ void AnnotatedCameraWidget::initializeFrogPilotWidgets() { bottom_layout->addWidget(map_settings_btn_bottom); main_layout->addLayout(bottom_layout); + + // Custom themes configuration + themeConfiguration = { + {1, {QString("frog_theme"), {QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))}, + {0.5, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.5))}, + {1.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.1))}}}}}, + {2, {QString("tesla_theme"), {QColor(0, 72, 255, 255), {{0.0, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.9))}, + {0.5, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.5))}, + {1.0, QBrush(QColor::fromHslF(223 / 360., 1.0, 0.5, 0.1))}}}}}, + {3, {QString("stalin_theme"), {QColor(255, 0, 0, 255), {{0.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.9))}, + {0.5, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.5))}, + {1.0, QBrush(QColor::fromHslF(0 / 360., 1.0, 0.5, 0.1))}}}}} + }; + + // Initialize the timer for the turn signal animation + animationTimer = new QTimer(this); + connect(animationTimer, &QTimer::timeout, this, [this] { + animationFrameIndex = (animationFrameIndex + 1) % totalFrames; + }); } void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { @@ -962,6 +1018,7 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { conditionalSpeed = scene.conditional_speed; conditionalSpeedLead = scene.conditional_speed_lead; conditionalStatus = scene.conditional_status; + customColors = scene.custom_colors; desiredFollow = scene.desired_follow; experimentalMode = scene.experimental_mode; laneWidthLeft = scene.lane_width_left; @@ -970,6 +1027,8 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { obstacleDistance = scene.obstacle_distance; obstacleDistanceStock = scene.obstacle_distance_stock; stoppedEquivalence = scene.stopped_equivalence; + turnSignalLeft = scene.turn_signal_left; + turnSignalRight = scene.turn_signal_right; useSI = scene.use_si; if (leadInfo) { @@ -980,11 +1039,46 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { drawStatusBar(p); } + if (customSignals && (turnSignalLeft || turnSignalRight)) { + if (!animationTimer->isActive()) { + animationTimer->start(totalFrames * 11); // 440 milliseconds per loop; syncs up perfectly with my 2019 Lexus ES 350 turn signal clicks + } + drawTurnSignals(p); + } else if (animationTimer->isActive()) { + animationTimer->stop(); + } + map_settings_btn_bottom->setEnabled(map_settings_btn->isEnabled()); if (map_settings_btn_bottom->isEnabled()) { map_settings_btn_bottom->setVisible(!hideBottomIcons); bottom_layout->setAlignment(map_settings_btn_bottom, rightHandDM ? Qt::AlignLeft : Qt::AlignRight); } + + // Update the turn signal animation images upon toggle change + if (customSignals != scene.custom_signals) { + customSignals = scene.custom_signals; + + const QString theme_path = QString("../frogpilot/assets/custom_themes/%1/images").arg(themeConfiguration.find(customSignals) != themeConfiguration.end() ? + themeConfiguration[customSignals].first : "stock_theme"); + const QStringList imagePaths = { + theme_path + "/turn_signal_1.png", + theme_path + "/turn_signal_2.png", + theme_path + "/turn_signal_3.png", + theme_path + "/turn_signal_4.png" + }; + + signalImgVector.clear(); + signalImgVector.reserve(4 * imagePaths.size() + 2); // Reserve space for both regular and flipped images + for (int i = 0; i < 2; ++i) { + for (const QString &imagePath : imagePaths) { + QPixmap pixmap(imagePath); + signalImgVector.push_back(pixmap); // Regular image + signalImgVector.push_back(pixmap.transformed(QTransform().scale(-1, 1))); // Flipped image + } + } + signalImgVector.push_back(QPixmap(theme_path + "/turn_signal_1_red.png")); // Regular blindspot image + signalImgVector.push_back(QPixmap(theme_path + "/turn_signal_1_red.png").transformed(QTransform().scale(-1, 1))); // Flipped blindspot image + } } void AnnotatedCameraWidget::drawLeadInfo(QPainter &p) { @@ -1162,3 +1256,35 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) { p.restore(); } + +void AnnotatedCameraWidget::drawTurnSignals(QPainter &p) { + // Declare the turn signal size + constexpr int signalHeight = 480; + constexpr int signalWidth = 360; + + // Calculate the vertical position for the turn signals + int baseYPosition = (height() - signalHeight) / 2 + (alwaysOnLateral || conditionalExperimental || roadNameUI ? 225 : 300); + // Calculate the x-coordinates for the turn signals + int leftSignalXPosition = 75 + width() - signalWidth - 300 * (blindSpotLeft ? 0 : animationFrameIndex); + int rightSignalXPosition = -75 + 300 * (blindSpotRight ? 0 : animationFrameIndex); + + // Enable Antialiasing + p.setRenderHint(QPainter::Antialiasing); + + // Draw the turn signals + if (animationFrameIndex < signalImgVector.size()) { + auto drawSignal = [&](bool signalActivated, int xPosition, bool flip, bool blindspot) { + if (signalActivated) { + // Get the appropriate image from the signalImgVector + int uniqueImages = signalImgVector.size() / 4; // Each image has a regular, flipped, and two blindspot versions + int index = (blindspot ? 2 * uniqueImages : 2 * animationFrameIndex % totalFrames) + (flip ? 1 : 0); + QPixmap &signal = signalImgVector[index]; + p.drawPixmap(xPosition, baseYPosition, signalWidth, signalHeight, signal); + } + }; + + // Display the animation based on which signal is activated + drawSignal(turnSignalLeft, leftSignalXPosition, false, blindSpotLeft); + drawSignal(turnSignalRight, rightSignalXPosition, true, blindSpotRight); + } +} diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index 4d53691..0397ccb 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -115,6 +115,7 @@ private: // FrogPilot widgets void drawLeadInfo(QPainter &p); void drawStatusBar(QPainter &p); + void drawTurnSignals(QPainter &p); void initializeFrogPilotWidgets(); void updateFrogPilotWidgets(QPainter &p); @@ -133,6 +134,8 @@ private: bool conditionalExperimental; bool experimentalMode; bool leadInfo; + bool turnSignalLeft; + bool turnSignalRight; bool useSI; double maxAcceleration; float laneWidthLeft; @@ -141,10 +144,18 @@ private: int conditionalSpeed; int conditionalSpeedLead; int conditionalStatus; + int customColors; + int customSignals; int desiredFollow; int obstacleDistance; int obstacleDistanceStock; int stoppedEquivalence; + int totalFrames = 8; + QTimer *animationTimer; + size_t animationFrameIndex; + + std::unordered_map>>> themeConfiguration; + std::vector signalImgVector; protected: void paintGL() override; diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index 90d3f73..81d8944 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -48,6 +48,23 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed( isStorageLeft = params.getBool("ShowStorageLeft"); isStorageUsed = params.getBool("ShowStorageUsed"); + themeConfiguration = { + {0, {"stock", {QColor(255, 255, 255)}}}, + {1, {"frog_theme", {QColor(23, 134, 68)}}}, + {2, {"tesla_theme", {QColor(0, 72, 255)}}}, + {3, {"stalin_theme", {QColor(255, 0, 0)}}} + }; + + for (auto &[key, themeData] : themeConfiguration) { + QString &themeName = themeData.first; + QString base = themeName == "stock" ? "../assets/images" : QString("../frogpilot/assets/custom_themes/%1/images").arg(themeName); + std::vector paths = {base + "/button_home.png", base + "/button_flag.png", base + "/button_settings.png"}; + + home_imgs[key] = loadPixmap(paths[0], home_btn.size()); + flag_imgs[key] = loadPixmap(paths[1], home_btn.size()); + settings_imgs[key] = loadPixmap(paths[2], settings_btn.size(), Qt::IgnoreAspectRatio); + } + updateFrogPilotParams(); } @@ -117,6 +134,8 @@ void Sidebar::updateState(const UIState &s) { // FrogPilot properties auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState(); + QColor theme_color = currentColors[0]; + // FrogPilot metrics if (isCPU || isGPU) { auto cpu_loads = deviceState.getCpuUsagePercent(); @@ -129,7 +148,7 @@ void Sidebar::updateState(const UIState &s) { QString metric = isGPU ? gpu : cpu; int usage = isGPU ? gpu_usage : cpu_usage; - ItemStatus cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, good_color}; + ItemStatus cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, theme_color}; if (usage >= 85) { cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, danger_color}; } else if (usage >= 70) { @@ -147,7 +166,7 @@ void Sidebar::updateState(const UIState &s) { QString storage = QString::number(isStorageLeft ? storage_left : storage_used) + " GB"; if (isMemoryUsage) { - ItemStatus memoryStatus = {{tr("MEMORY"), memory}, good_color}; + ItemStatus memoryStatus = {{tr("MEMORY"), memory}, theme_color}; if (memory_usage >= 85) { memoryStatus = {{tr("MEMORY"), memory}, danger_color}; } else if (memory_usage >= 70) { @@ -155,7 +174,7 @@ void Sidebar::updateState(const UIState &s) { } setProperty("memoryStatus", QVariant::fromValue(memoryStatus)); } else { - ItemStatus storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, good_color}; + ItemStatus storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, theme_color}; if (10 <= storage_left && storage_left < 25) { storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, warning_color}; } else if (storage_left < 10) { @@ -171,7 +190,7 @@ void Sidebar::updateState(const UIState &s) { connectStatus = ItemStatus{{tr("CONNECT"), tr("OFFLINE")}, warning_color}; } else { connectStatus = nanos_since_boot() - last_ping < 80e9 - ? ItemStatus{{tr("CONNECT"), tr("ONLINE")}, good_color} + ? ItemStatus{{tr("CONNECT"), tr("ONLINE")}, theme_color} : ItemStatus{{tr("CONNECT"), tr("ERROR")}, danger_color}; } setProperty("connectStatus", QVariant::fromValue(connectStatus)); @@ -179,13 +198,13 @@ void Sidebar::updateState(const UIState &s) { ItemStatus tempStatus = {{tr("TEMP"), tr("HIGH")}, danger_color}; auto ts = deviceState.getThermalStatus(); if (ts == cereal::DeviceState::ThermalStatus::GREEN) { - tempStatus = {{tr("TEMP"), tr("GOOD")}, good_color}; + tempStatus = {{tr("TEMP"), tr("GOOD")}, theme_color}; } else if (ts == cereal::DeviceState::ThermalStatus::YELLOW) { tempStatus = {{tr("TEMP"), tr("OK")}, warning_color}; } setProperty("tempStatus", QVariant::fromValue(tempStatus)); - ItemStatus pandaStatus = {{tr("VEHICLE"), tr("ONLINE")}, good_color}; + ItemStatus pandaStatus = {{tr("VEHICLE"), tr("ONLINE")}, theme_color}; if (s.scene.pandaType == cereal::PandaState::PandaType::UNKNOWN) { pandaStatus = {{tr("NO"), tr("PANDA")}, danger_color}; } else if (s.scene.started && !sm["liveLocationKalman"].getLiveLocationKalman().getGpsOK()) { @@ -196,6 +215,15 @@ void Sidebar::updateState(const UIState &s) { void Sidebar::updateFrogPilotParams() { // Update FrogPilot parameters upon toggle change + isCustomTheme = params.getBool("CustomTheme"); + customColors = isCustomTheme ? params.getInt("CustomColors") : 0; + customIcons = isCustomTheme ? params.getInt("CustomIcons") : 0; + + home_img = home_imgs[customIcons]; + flag_img = flag_imgs[customIcons]; + settings_img = settings_imgs[customIcons]; + + currentColors = themeConfiguration[customColors].second; } void Sidebar::paintEvent(QPaintEvent *event) { diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index b9936ab..63f2312 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -73,9 +73,18 @@ private: ItemStatus cpu_status, memory_status, storage_status; + std::unordered_map>> themeConfiguration; + std::unordered_map flag_imgs; + std::unordered_map home_imgs; + std::unordered_map settings_imgs; + std::vector currentColors; + bool isCPU; + bool isCustomTheme; bool isGPU; bool isMemoryUsage; bool isStorageLeft; bool isStorageUsed; + int customColors; + int customIcons; }; diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 0962c1e..b5f73f5 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -77,7 +77,7 @@ class Soundd: for sound in sound_list: filename, play_count, volume = sound_list[sound] - wavefile = wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') + wavefile = wave.open(self.sound_directory + filename, 'r') assert wavefile.getnchannels() == 1 assert wavefile.getsampwidth() == 2 @@ -169,6 +169,21 @@ class Soundd: def update_frogpilot_params(self): + custom_theme = self.params.get_bool("CustomTheme") + custom_sounds = self.params.get_int("CustomSounds") if custom_theme else 0 + + theme_configuration = { + 0: "stock", + 1: "frog_theme", + 2: "tesla_theme", + 3: "stalin_theme" + } + + theme_name = theme_configuration.get(custom_sounds, "stock") + self.sound_directory = (f"{BASEDIR}/selfdrive/frogpilot/assets/custom_themes/{theme_name}/sounds/" if custom_sounds else f"{BASEDIR}/selfdrive/assets/sounds/") + + self.load_sounds() + def main(): s = Soundd() s.soundd_thread() diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index b79201e..92b8687 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -214,10 +214,14 @@ static void update_state(UIState *s) { } if (sm.updated("carState")) { auto carState = sm["carState"].getCarState(); - if (scene.blind_spot_path) { + if (scene.blind_spot_path || scene.custom_signals) { scene.blind_spot_left = carState.getLeftBlindspot(); scene.blind_spot_right = carState.getRightBlindspot(); } + if (scene.custom_signals) { + scene.turn_signal_left = carState.getLeftBlinker(); + scene.turn_signal_right = carState.getRightBlinker(); + } } if (sm.updated("controlsState")) { auto controlsState = sm["controlsState"].getControlsState(); @@ -285,6 +289,10 @@ void ui_update_params(UIState *s) { scene.show_fps = scene.custom_onroad_ui && params.getBool("ShowFPS"); scene.use_si = scene.custom_onroad_ui && params.getBool("UseSI"); + scene.custom_theme = params.getBool("CustomTheme"); + scene.custom_colors = scene.custom_theme ? params.getInt("CustomColors") : 0; + scene.custom_signals = scene.custom_theme ? params.getInt("CustomSignals") : 0; + scene.model_ui = params.getBool("ModelUI"); scene.acceleration_path = scene.model_ui && params.getBool("AccelerationPath"); scene.lane_line_width = params.getInt("LaneLinesWidth") * (scene.is_metric ? 1 : INCH_TO_CM) / 200; diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index f3de37d..f5c0200 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -178,11 +178,14 @@ typedef struct UIScene { bool blind_spot_right; bool conditional_experimental; bool custom_onroad_ui; + bool custom_theme; bool enabled; bool experimental_mode; bool lead_info; bool model_ui; bool show_fps; + bool turn_signal_left; + bool turn_signal_right; bool unlimited_road_ui_length; bool use_si; float lane_line_width; @@ -195,6 +198,8 @@ typedef struct UIScene { int conditional_speed; int conditional_speed_lead; int conditional_status; + int custom_colors; + int custom_signals; int desired_follow; int obstacle_distance; int obstacle_distance_stock;