From dd3337279d66605a48c0b9ee3474875046077c3e Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Thu, 9 May 2024 19:49:07 -0700 Subject: [PATCH] FrogPilot setup - Toggle panels --- .../toggle_icons/icon_always_on_lateral.png | Bin 0 -> 9723 bytes .../assets/toggle_icons/icon_conditional.png | Bin 0 -> 13317 bytes .../assets/toggle_icons/icon_device.png | Bin 0 -> 25414 bytes .../assets/toggle_icons/icon_green_light.png | Bin 0 -> 28527 bytes .../assets/toggle_icons/icon_lane.png | Bin 0 -> 18310 bytes .../assets/toggle_icons/icon_lateral_tune.png | Bin 0 -> 30135 bytes .../assets/toggle_icons/icon_light.png | Bin 0 -> 9097 bytes .../toggle_icons/icon_longitudinal_tune.png | Bin 0 -> 37131 bytes .../assets/toggle_icons/icon_mute.png | Bin 0 -> 12576 bytes .../assets/toggle_icons/icon_personality.png | Bin 0 -> 14244 bytes .../assets/toggle_icons/icon_rotate.png | Bin 0 -> 41150 bytes .../assets/toggle_icons/icon_speed_map.png | Bin 0 -> 64396 bytes .../assets/toggle_icons/icon_vtc.png | Bin 0 -> 36850 bytes .../assets/toggle_icons/quality_of_life.png | Bin 0 -> 42955 bytes .../ui/qt/offroad/control_settings.cc | 1216 +++++++++++++++++ .../ui/qt/offroad/control_settings.h | 83 ++ .../ui/qt/offroad/vehicle_settings.cc | 284 ++++ .../ui/qt/offroad/vehicle_settings.h | 46 + .../ui/qt/offroad/visual_settings.cc | 428 ++++++ .../frogpilot/ui/qt/offroad/visual_settings.h | 43 + .../ui/qt/widgets/frogpilot_controls.cc | 40 + .../ui/qt/widgets/frogpilot_controls.h | 705 ++++++++++ selfdrive/ui/SConscript | 5 +- selfdrive/ui/qt/offroad/settings.cc | 64 +- selfdrive/ui/qt/offroad/settings.h | 20 + selfdrive/ui/qt/widgets/controls.h | 4 + selfdrive/ui/qt/widgets/scrollview.cc | 4 + selfdrive/ui/qt/widgets/scrollview.h | 4 + selfdrive/ui/ui.cc | 1 + 29 files changed, 2945 insertions(+), 2 deletions(-) create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_always_on_lateral.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_conditional.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_device.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_green_light.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_lane.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_lateral_tune.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_light.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_mute.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_personality.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_rotate.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_speed_map.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_vtc.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png create mode 100644 selfdrive/frogpilot/ui/qt/offroad/control_settings.cc create mode 100644 selfdrive/frogpilot/ui/qt/offroad/control_settings.h create mode 100644 selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc create mode 100644 selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h create mode 100644 selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc create mode 100644 selfdrive/frogpilot/ui/qt/offroad/visual_settings.h diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_always_on_lateral.png b/selfdrive/frogpilot/assets/toggle_icons/icon_always_on_lateral.png new file mode 100644 index 0000000000000000000000000000000000000000..1e55e3feb958850c75f576a8854224c2becc4cee GIT binary patch literal 9723 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≻}>t1hIjeO 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 oAs%=a#p$JVd^57p57?EnA( literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_device.png b/selfdrive/frogpilot/assets/toggle_icons/icon_device.png new file mode 100644 index 0000000000000000000000000000000000000000..e4f44076fbe825f8abeae8d0c925b9ac7f3436bf GIT binary patch literal 25414 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 ZhjqXCClQxU?gN286-7;jGI`5a{}1A#SkwRj literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_lane.png b/selfdrive/frogpilot/assets/toggle_icons/icon_lane.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8e40aab515d565a21760149f0b5d71df13f53d GIT binary patch literal 18310 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_light.png b/selfdrive/frogpilot/assets/toggle_icons/icon_light.png new file mode 100644 index 0000000000000000000000000000000000000000..2a3369c4e8fec9e7d4ef17ea84083133287eff96 GIT binary patch literal 9097 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png b/selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png new file mode 100644 index 0000000000000000000000000000000000000000..4af03cd3c704e0bfe8ca17c2dddbb2b2120c91f3 GIT binary patch literal 37131 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
|j*3xT+Wh@Cpo$hgswLaksf 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_mute.png b/selfdrive/frogpilot/assets/toggle_icons/icon_mute.png new file mode 100644 index 0000000000000000000000000000000000000000..3e31a137877bd88839f0c9e13019eaf2c659cd9e GIT binary patch literal 12576 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%0Abh^luo_o00~AA)E^GchZE+t-*^JtOYwC{oit?w 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 ATmS$7 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_personality.png b/selfdrive/frogpilot/assets/toggle_icons/icon_personality.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1d7fe5f5229427edf573a9b7edd4069518c53 GIT binary patch literal 14244 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_speed_map.png b/selfdrive/frogpilot/assets/toggle_icons/icon_speed_map.png new file mode 100644 index 0000000000000000000000000000000000000000..60b87eb97e8a696f3d526009f8772c4859a37d6d GIT binary patch literal 64396 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

R$ugIB-{tuHC!kgwdJOcJ0ko&ZcuoUx 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⋙UY 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 D-Z>As literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_vtc.png b/selfdrive/frogpilot/assets/toggle_icons/icon_vtc.png new file mode 100644 index 0000000000000000000000000000000000000000..8218b456ccd690092126e628e7485e21ab40c2e1 GIT binary patch literal 36850 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png b/selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png new file mode 100644 index 0000000000000000000000000000000000000000..1719a605f293614de0a1b59246c283bf43e5e2a1 GIT binary patch literal 42955 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 LR^Qax=Kntc+i=!{ literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc b/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc new file mode 100644 index 0000000..faf63a1 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc @@ -0,0 +1,1216 @@ +#include +#include + +#include "selfdrive/frogpilot/ui/qt/offroad/control_settings.h" + +namespace fs = std::filesystem; + +bool checkCommaNNFFSupport(const std::string &carFingerprint) { + const std::string filePath = "../car/torque_data/neural_ff_weights.json"; + + if (!std::filesystem::exists(filePath)) { + return false; + } + + std::ifstream file(filePath); + std::string line; + while (std::getline(file, line)) { + if (line.find(carFingerprint) != std::string::npos) { + std::cout << "comma's NNFF supports fingerprint: " << carFingerprint << std::endl; + return true; + } + } + + return false; +} + +bool checkNNFFLogFileExists(const std::string &carFingerprint) { + const fs::path dirPath("../car/torque_data/lat_models"); + + if (!fs::exists(dirPath)) { + std::cerr << "Directory does not exist: " << fs::absolute(dirPath) << std::endl; + return false; + } + + for (const auto &entry : fs::directory_iterator(dirPath)) { + if (entry.path().filename().string().find(carFingerprint) == 0) { + std::cout << "NNFF supports fingerprint: " << entry.path().filename() << std::endl; + return true; + } + } + + return false; +} + +FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + std::string branch = params.get("GitBranch"); + isRelease = branch == "FrogPilot"; + + const std::vector> controlToggles { + {"AlwaysOnLateral", tr("Always on Lateral"), tr("Maintain openpilot lateral control when the brake or gas pedals are used.\n\nDeactivation occurs only through the 'Cruise Control' button."), "../frogpilot/assets/toggle_icons/icon_always_on_lateral.png"}, + {"AlwaysOnLateralMain", tr("Enable On Cruise Main"), tr("Enable 'Always On Lateral' by clicking your 'Cruise Control' button without requring openpilot to be enabled first."), ""}, + {"PauseAOLOnBrake", tr("Pause On Brake Below"), tr("Pause 'Always On Lateral' when the brake pedal is being pressed below the set speed."), ""}, + {"HideAOLStatusBar", tr("Hide the Status Bar"), tr("Don't use the status bar for 'Always On Lateral'."), ""}, + + {"ConditionalExperimental", tr("Conditional Experimental Mode"), tr("Automatically switches to 'Experimental Mode' under predefined conditions."), "../frogpilot/assets/toggle_icons/icon_conditional.png"}, + {"CECurves", tr("Curve Detected Ahead"), tr("Switch to 'Experimental Mode' when a curve is detected."), ""}, + {"CENavigation", tr("Navigation Based"), tr("Switch to 'Experimental Mode' based on navigation data. (i.e. Intersections, stop signs, upcoming turns, etc.)"), ""}, + {"CESlowerLead", tr("Slower/Stopped Lead Detected Ahead"), tr("Switch to 'Experimental Mode' when a slower or stopped lead vehicle is detected ahead."), ""}, + {"CEStopLights", tr("Stop Lights and Stop Signs"), tr("Switch to 'Experimental Mode' when a stop light or stop sign is detected."), ""}, + {"CESignal", tr("Turn Signal When Below Highway Speeds"), tr("Switch to 'Experimental Mode' when using turn signals below highway speeds to help assist with turns."), ""}, + {"HideCEMStatusBar", tr("Hide the Status Bar"), tr("Don't use the status bar for 'Conditional Experimental Mode'."), ""}, + + {"DeviceManagement", tr("Device Management"), tr("Tweak your device's behaviors to your personal preferences."), "../frogpilot/assets/toggle_icons/icon_device.png"}, + {"DeviceShutdown", tr("Device Shutdown Timer"), tr("Configure how quickly the device shuts down after going offroad."), ""}, + {"NoLogging", tr("Disable Logging"), tr("Turn off all data tracking to enhance privacy or reduce thermal load."), ""}, + {"NoUploads", tr("Disable Uploads"), tr("Turn off all data uploads to comma's servers."), ""}, + {"IncreaseThermalLimits", tr("Increase Thermal Safety Limit"), tr("Allow the device to run at a temperature above comma's recommended thermal limits."), ""}, + {"LowVoltageShutdown", tr("Low Voltage Shutdown Threshold"), tr("Automatically shut the device down when your battery reaches a specific voltage level to prevent killing your battery."), ""}, + {"OfflineMode", tr("Offline Mode"), tr("Allow the device to be offline indefinitely."), ""}, + + {"DrivingPersonalities", tr("Driving Personalities"), tr("Manage the driving behaviors of comma's 'Personality Profiles'."), "../frogpilot/assets/toggle_icons/icon_personality.png"}, + {"CustomPersonalities", tr("Customize Personalities"), tr("Customize the driving personality profiles to your driving style."), ""}, + {"TrafficPersonalityProfile", tr("Traffic Personality"), tr("Customize the 'Traffic' personality profile."), "../frogpilot/assets/other_images/traffic.png"}, + {"TrafficFollow", tr("Following Distance"), tr("Set the minimum following distance when using 'Traffic Mode'. Your following distance will dynamically adjust between this distance and the following distance from the 'Aggressive' profile when driving between 0 and %1.\n\nFor example:\n\nTraffic Mode: 0.5s\nAggressive: 1.0s\n\n0%2 = 0.5s\n%3 = 0.75s\n%1 = 1.0s"), ""}, + {"TrafficJerkAcceleration", tr("Acceleration/Deceleration Response Offset"), tr("Customize the response rate for acceleration when using 'Traffic Mode'."), ""}, + {"TrafficJerkSpeed", tr("Speed Control Response Offset"), tr("Customize the response rate for keeping your speed (including braking) when using 'Traffic Mode'."), ""}, + {"ResetTrafficPersonality", tr("Reset Settings"), tr("Reset the values for the 'Traffic Mode' personality back to stock."), ""}, + {"AggressivePersonalityProfile", tr("Aggressive Personality"), tr("Customize the 'Aggressive' personality profile."), "../frogpilot/assets/other_images/aggressive.png"}, + {"AggressiveFollow", tr("Following Distance"), tr("Set the 'Aggressive' personality following distance. Represents seconds to follow behind the lead vehicle.\n\nStock: 1.25 seconds."), ""}, + {"AggressiveJerkAcceleration", tr("Acceleration/Deceleration Response Offset"), tr("Customize the response rate for acceleration when using the 'Aggressive' personality."), ""}, + {"AggressiveJerkSpeed", tr("Speed Control Response Offset"), tr("Customize the response rate for keeping your speed (including braking) when using the 'Aggressive' personality."), ""}, + {"ResetAggressivePersonality", tr("Reset Settings"), tr("Reset the values for the 'Aggressive' personality back to stock."), ""}, + {"StandardPersonalityProfile", tr("Standard Personality"), tr("Customize the 'Standard' personality profile."), "../frogpilot/assets/other_images/standard.png"}, + {"StandardFollow", tr("Following Distance"), tr("Set the 'Standard' personality following distance. Represents seconds to follow behind the lead vehicle.\n\nStock: 1.45 seconds."), ""}, + {"StandardJerkAcceleration", tr("Acceleration/Deceleration Response Offset"), tr("Customize the response rate for acceleration when using the 'Standard' personality."), ""}, + {"StandardJerkSpeed", tr("Speed Control Response Offset"), tr("Customize the response rate for keeping your speed (including braking) when using the 'Standard' personality."), ""}, + {"ResetStandardPersonality", tr("Reset Settings"), tr("Reset the values for the 'Standard' personality back to stock."), ""}, + {"RelaxedPersonalityProfile", tr("Relaxed Personality"), tr("Customize the 'Relaxed' personality profile."), "../frogpilot/assets/other_images/relaxed.png"}, + {"RelaxedFollow", tr("Following Distance"), tr("Set the 'Relaxed' personality following distance. Represents seconds to follow behind the lead vehicle.\n\nStock: 1.75 seconds."), ""}, + {"RelaxedJerkAcceleration", tr("Acceleration/Deceleration Response Offset"), tr("Customize the response rate for acceleration when using the 'Relaxed' personality."), ""}, + {"RelaxedJerkSpeed", tr("Speed Control Response Offset"), tr("Customize the response rate for keeping your speed (including braking) when using the 'Relaxed' personality."), ""}, + {"ResetRelaxedPersonality", tr("Reset Settings"), tr("Reset the values for the 'Relaxed' personality back to stock."), ""}, + {"OnroadDistanceButton", tr("Onroad Distance Button"), tr("Simulate a distance button via the onroad UI to control personalities, 'Experimental Mode', and 'Traffic Mode'."), ""}, + + {"ExperimentalModeActivation", tr("Experimental Mode Activation"), tr("Toggle Experimental Mode with either buttons on the steering wheel or the screen. \n\nOverrides 'Conditional Experimental Mode'."), "../assets/img_experimental_white.svg"}, + {"ExperimentalModeViaLKAS", tr("Double Click LKAS"), tr("Enable/disable 'Experimental Mode' by double clicking the 'LKAS' button on your steering wheel."), ""}, + {"ExperimentalModeViaTap", tr("Double Tap the UI"), tr("Enable/disable 'Experimental Mode' by double tapping the onroad UI within a 0.5 second time frame."), ""}, + {"ExperimentalModeViaDistance", tr("Long Press Distance"), tr("Enable/disable 'Experimental Mode' by holding down the 'distance' button on your steering wheel for 0.5 seconds."), ""}, + + {"LaneChangeCustomizations", tr("Lane Change Customizations"), tr("Customize the lane change behaviors in openpilot."), "../frogpilot/assets/toggle_icons/icon_lane.png"}, + {"MinimumLaneChangeSpeed", tr("Minimum Lane Change Speed"), tr("Customize the minimum driving speed to allow openpilot to change lanes."), ""}, + {"NudgelessLaneChange", tr("Nudgeless Lane Change"), tr("Enable lane changes without requiring manual steering input."), ""}, + {"LaneChangeTime", tr("Lane Change Timer"), tr("Set a delay before executing a lane change."), ""}, + {"LaneDetectionWidth", tr("Lane Detection Threshold"), tr("Set the required lane width to be qualified as a lane."), ""}, + {"OneLaneChange", tr("One Lane Change Per Signal"), tr("Only allow one lane change per turn signal activation."), ""}, + + {"LateralTune", tr("Lateral Tuning"), tr("Modify openpilot's steering behavior."), "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"}, + {"ForceAutoTune", tr("Force Auto Tune"), tr("Forces comma's auto lateral tuning for unsupported vehicles."), ""}, + {"NNFF", tr("NNFF"), tr("Use Twilsonco's Neural Network Feedforward for enhanced precision in lateral control."), ""}, + {"NNFFLite", tr("NNFF-Lite"), tr("Use Twilsonco's Neural Network Feedforward for enhanced precision in lateral control for cars without available NNFF logs."), ""}, + {"SteerRatio", steerRatioStock != 0 ? QString(tr("Steer Ratio (Default: %1)")).arg(QString::number(steerRatioStock, 'f', 2)) : tr("Steer Ratio"), tr("Use a custom steer ratio as opposed to comma's auto tune value."), ""}, + {"TacoTune", tr("Taco Tune"), tr("Use comma's 'Taco Tune' designed for handling left and right turns."), ""}, + {"TurnDesires", tr("Use Turn Desires"), tr("Use turn desires for greater precision in turns below the minimum lane change speed."), ""}, + + {"LongitudinalTune", tr("Longitudinal Tuning"), tr("Modify openpilot's acceleration and braking behavior."), "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, + {"AccelerationProfile", tr("Acceleration Profile"), tr("Change the acceleration rate to be either sporty or eco-friendly."), ""}, + {"DecelerationProfile", tr("Deceleration Profile"), tr("Change the deceleration rate to be either sporty or eco-friendly."), ""}, + {"AggressiveAcceleration", tr("Increase Acceleration Behind Lead"), tr("Increase aggressiveness when following a faster lead."), ""}, + {"StoppingDistance", tr("Increase Stop Distance Behind Lead"), tr("Increase the stopping distance for a more comfortable stop from lead vehicles."), ""}, + {"LeadDetectionThreshold", tr("Lead Detection Threshold"), tr("Increase or decrease the lead detection threshold to either detect leads sooner, or increase model confidence."), ""}, + {"SmoothBraking", tr("Smoother Braking"), tr("Smoothen out the braking behavior when approaching slower vehicles."), ""}, + {"TrafficMode", tr("Traffic Mode"), tr("Enable the ability to activate 'Traffic Mode' by holding down the 'distance' button for 2.5 seconds. When 'Traffic Mode' is active the onroad UI will turn red and openpilot will drive catered towards stop and go traffic."), ""}, + + {"MTSCEnabled", tr("Map Turn Speed Control"), tr("Slow down for anticipated curves detected by the downloaded maps."), "../frogpilot/assets/toggle_icons/icon_speed_map.png"}, + {"DisableMTSCSmoothing", tr("Disable MTSC UI Smoothing"), tr("Disables the smoothing for the requested speed in the onroad UI to show exactly what speed MTSC is currently requesting."), ""}, + {"MTSCCurvatureCheck", tr("Model Curvature Detection Failsafe"), tr("Only trigger MTSC when the model detects a curve in the road. Purely used as a failsafe to prevent false positives. Leave this off if you never experience false positives."), ""}, + {"MTSCAggressiveness", tr("Turn Speed Aggressiveness"), tr("Set turn speed aggressiveness. Higher values result in faster turns, lower values yield gentler turns. \n\nA change of +- 1% results in the speed being raised or lowered by about 1 mph."), ""}, + + {"ModelSelector", tr("Model Selector"), tr("Manage openpilot's driving models."), "../assets/offroad/icon_calibration.png"}, + + {"QOLControls", tr("Quality of Life"), tr("Miscellaneous quality of life changes to improve your overall openpilot experience."), "../frogpilot/assets/toggle_icons/quality_of_life.png"}, + {"CustomCruise", tr("Cruise Increase Interval"), tr("Set a custom interval to increase the max set speed by."), ""}, + {"CustomCruiseLong", tr("Cruise Increase Interval (Long Press)"), tr("Set a custom interval to increase the max set speed by when holding down the cruise increase button."), ""}, + {"MapGears", tr("Map Accel/Decel To Gears"), tr("Map your acceleration/deceleration profile to your 'Eco' and/or 'Sport' gears."), ""}, + {"PauseLateralSpeed", tr("Pause Lateral Below"), tr("Pause lateral control on all speeds below the set speed."), ""}, + {"ReverseCruise", tr("Reverse Cruise Increase"), tr("Reverses the 'long press' functionality logic to increase the max set speed by 5 instead of 1. Useful to increase the max speed quickly."), ""}, + {"SetSpeedOffset", tr("Set Speed Offset"), tr("Set an offset for your desired set speed."), ""}, + + {"SpeedLimitController", tr("Speed Limit Controller"), tr("Automatically adjust the max speed to match the current speed limit using 'Open Street Maps', 'Navigate On openpilot', or your car's dashboard (Toyotas/Lexus/HKG only)."), "../assets/offroad/icon_speed_limit.png"}, + {"SLCControls", tr("Controls Settings"), tr("Manage toggles related to 'Speed Limit Controller's controls."), ""}, + {"Offset1", tr("Speed Limit Offset (0-34 mph)"), tr("Speed limit offset for speed limits between 0-34 mph."), ""}, + {"Offset2", tr("Speed Limit Offset (35-54 mph)"), tr("Speed limit offset for speed limits between 35-54 mph."), ""}, + {"Offset3", tr("Speed Limit Offset (55-64 mph)"), tr("Speed limit offset for speed limits between 55-64 mph."), ""}, + {"Offset4", tr("Speed Limit Offset (65-99 mph)"), tr("Speed limit offset for speed limits between 65-99 mph."), ""}, + {"SLCFallback", tr("Fallback Method"), tr("Choose your fallback method when there is no speed limit available."), ""}, + {"SLCOverride", tr("Override Method"), tr("Choose your preferred method to override the current speed limit."), ""}, + {"SLCPriority", tr("Priority Order"), tr("Configure the speed limit priority order."), ""}, + {"SLCQOL", tr("Quality of Life Settings"), tr("Manage toggles related to 'Speed Limit Controller's quality of life features."), ""}, + {"SLCConfirmation", tr("Confirm New Speed Limits"), tr("Don't automatically start using the new speed limit until it's been manually confirmed."), ""}, + {"ForceMPHDashboard", tr("Force MPH From Dashboard Readings"), tr("Force MPH readings from the dashboard. Only use this if you live in an area where the speed limits from your dashboard are in KPH, but you use MPH."), ""}, + {"SLCLookaheadHigher", tr("Prepare For Higher Speed Limits"), tr("Set a 'lookahead' value to prepare for upcoming speed limits higher than your current speed limit using the data stored in 'Open Street Maps'."), ""}, + {"SLCLookaheadLower", tr("Prepare For Lower Speed Limits"), tr("Set a 'lookahead' value to prepare for upcoming speed limits lower than your current speed limit using the data stored in 'Open Street Maps'."), ""}, + {"SetSpeedLimit", tr("Use Current Speed Limit As Set Speed"), tr("Sets your max speed to the current speed limit if one is populated when you initially enable openpilot."), ""}, + {"SLCVisuals", tr("Visuals Settings"), tr("Manage toggles related to 'Speed Limit Controller's visuals."), ""}, + {"ShowSLCOffset", tr("Show Speed Limit Offset"), tr("Show the speed limit offset separated from the speed limit in the onroad UI when using 'Speed Limit Controller'."), ""}, + {"SpeedLimitChangedAlert", tr("Speed Limit Changed Alert"), tr("Trigger an alert whenever the speed limit changes."), ""}, + {"UseVienna", tr("Use Vienna Speed Limit Signs"), tr("Use the Vienna (EU) speed limit style signs as opposed to MUTCD (US)."), ""}, + + {"VisionTurnControl", tr("Vision Turn Speed Controller"), tr("Slow down for detected curves in the road."), "../frogpilot/assets/toggle_icons/icon_vtc.png"}, + {"DisableVTSCSmoothing", tr("Disable VTSC UI Smoothing"), tr("Disables the smoothing for the requested speed in the onroad UI."), ""}, + {"CurveSensitivity", tr("Curve Detection Sensitivity"), tr("Set curve detection sensitivity. Higher values prompt earlier responses, lower values lead to smoother but later reactions."), ""}, + {"TurnAggressiveness", tr("Turn Speed Aggressiveness"), tr("Set turn speed aggressiveness. Higher values result in faster turns, lower values yield gentler turns."), ""}, + }; + + for (const auto &[param, title, desc, icon] : controlToggles) { + AbstractControl *toggle; + + if (param == "AlwaysOnLateral") { + FrogPilotParamManageControl *aolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(aolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(aolKeys.find(key.c_str()) != aolKeys.end()); + } + }); + toggle = aolToggle; + } else if (param == "PauseAOLOnBrake") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map(), this, false, tr(" mph")); + + } else if (param == "ConditionalExperimental") { + FrogPilotParamManageControl *conditionalExperimentalToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(conditionalExperimentalToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + conditionalSpeedsImperial->setVisible(!isMetric); + conditionalSpeedsMetric->setVisible(isMetric); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end()); + } + }); + toggle = conditionalExperimentalToggle; + } else if (param == "CECurves") { + FrogPilotParamValueControl *CESpeedImperial = new FrogPilotParamValueControl("CESpeed", tr("Below"), tr("Switch to 'Experimental Mode' below this speed when not following a lead vehicle."), "", 0, 99, + std::map(), this, false, tr(" mph")); + FrogPilotParamValueControl *CESpeedLeadImperial = new FrogPilotParamValueControl("CESpeedLead", tr(" w/Lead"), tr("Switch to 'Experimental Mode' below this speed when following a lead vehicle."), "", 0, 99, + std::map(), this, false, tr(" mph")); + conditionalSpeedsImperial = new FrogPilotDualParamControl(CESpeedImperial, CESpeedLeadImperial, this); + addItem(conditionalSpeedsImperial); + + FrogPilotParamValueControl *CESpeedMetric = new FrogPilotParamValueControl("CESpeed", tr("Below"), tr("Switch to 'Experimental Mode' below this speed in absence of a lead vehicle."), "", 0, 150, + std::map(), this, false, tr(" kph")); + FrogPilotParamValueControl *CESpeedLeadMetric = new FrogPilotParamValueControl("CESpeedLead", tr(" w/Lead"), tr("Switch to 'Experimental Mode' below this speed when following a lead vehicle."), "", 0, 150, + std::map(), this, false, tr(" kph")); + conditionalSpeedsMetric = new FrogPilotDualParamControl(CESpeedMetric, CESpeedLeadMetric, this); + addItem(conditionalSpeedsMetric); + + std::vector curveToggles{"CECurvesLead"}; + std::vector curveToggleNames{tr("With Lead")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, curveToggles, curveToggleNames); + } else if (param == "CENavigation") { + std::vector navigationToggles{"CENavigationIntersections", "CENavigationTurns", "CENavigationLead"}; + std::vector navigationToggleNames{tr("Intersections"), tr("Turns"), tr("With Lead")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, navigationToggles, navigationToggleNames); + } else if (param == "CEStopLights") { + std::vector stopLightToggles{"CEStopLightsLead"}; + std::vector stopLightToggleNames{tr("With Lead")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, stopLightToggles, stopLightToggleNames); + + } else if (param == "DeviceManagement") { + FrogPilotParamManageControl *deviceManagementToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(deviceManagementToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(deviceManagementKeys.find(key.c_str()) != deviceManagementKeys.end()); + } + }); + toggle = deviceManagementToggle; + } else if (param == "DeviceShutdown") { + std::map shutdownLabels; + for (int i = 0; i <= 33; ++i) { + shutdownLabels[i] = i == 0 ? tr("5 mins") : i <= 3 ? QString::number(i * 15) + tr(" mins") : QString::number(i - 3) + (i == 4 ? tr(" hour") : tr(" hours")); + } + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false); + } else if (param == "NoUploads") { + std::vector uploadsToggles{"DisableOnroadUploads"}; + std::vector uploadsToggleNames{tr("Only Onroad")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, uploadsToggles, uploadsToggleNames); + } else if (param == "LowVoltageShutdown") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 11.8, 12.5, std::map(), this, false, tr(" volts"), 1, 0.01); + + } else if (param == "DrivingPersonalities") { + FrogPilotParamManageControl *drivingPersonalitiesToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(drivingPersonalitiesToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(drivingPersonalityKeys.find(key.c_str()) != drivingPersonalityKeys.end()); + } + }); + toggle = drivingPersonalitiesToggle; + } else if (param == "CustomPersonalities") { + FrogPilotParamManageControl *customPersonalitiesToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customPersonalitiesToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + customPersonalitiesOpen = true; + for (auto &[key, toggle] : toggles) { + toggle->setVisible(customdrivingPersonalityKeys.find(key.c_str()) != customdrivingPersonalityKeys.end()); + openSubParentToggle(); + } + }); + + personalitiesInfoBtn = new ButtonControl(tr("What Do All These Do?"), tr("VIEW"), tr("Learn what all the values in 'Custom Personality Profiles' do on openpilot's driving behaviors.")); + connect(personalitiesInfoBtn, &ButtonControl::clicked, [=]() { + const std::string txt = util::read_file("../frogpilot/ui/qt/offroad/personalities_info.txt"); + ConfirmationDialog::rich(QString::fromStdString(txt), this); + }); + addItem(personalitiesInfoBtn); + + toggle = customPersonalitiesToggle; + } else if (param == "ResetTrafficPersonality" || param == "ResetAggressivePersonality" || param == "ResetStandardPersonality" || param == "ResetRelaxedPersonality") { + std::vector personalityOptions{tr("Reset")}; + FrogPilotButtonsControl *profileBtn = new FrogPilotButtonsControl(title, desc, icon, personalityOptions); + toggle = profileBtn; + } else if (param == "TrafficPersonalityProfile") { + FrogPilotParamManageControl *trafficPersonalityToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(trafficPersonalityToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(trafficPersonalityKeys.find(key.c_str()) != trafficPersonalityKeys.end()); + } + openSubSubParentToggle(); + personalitiesInfoBtn->setVisible(true); + }); + toggle = trafficPersonalityToggle; + } else if (param == "AggressivePersonalityProfile") { + FrogPilotParamManageControl *aggressivePersonalityToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(aggressivePersonalityToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(aggressivePersonalityKeys.find(key.c_str()) != aggressivePersonalityKeys.end()); + } + openSubSubParentToggle(); + personalitiesInfoBtn->setVisible(true); + }); + toggle = aggressivePersonalityToggle; + } else if (param == "StandardPersonalityProfile") { + FrogPilotParamManageControl *standardPersonalityToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(standardPersonalityToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(standardPersonalityKeys.find(key.c_str()) != standardPersonalityKeys.end()); + } + openSubSubParentToggle(); + personalitiesInfoBtn->setVisible(true); + }); + toggle = standardPersonalityToggle; + } else if (param == "RelaxedPersonalityProfile") { + FrogPilotParamManageControl *relaxedPersonalityToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(relaxedPersonalityToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(relaxedPersonalityKeys.find(key.c_str()) != relaxedPersonalityKeys.end()); + } + openSubSubParentToggle(); + personalitiesInfoBtn->setVisible(true); + }); + toggle = relaxedPersonalityToggle; + } else if (trafficPersonalityKeys.find(param) != trafficPersonalityKeys.end() || + aggressivePersonalityKeys.find(param) != aggressivePersonalityKeys.end() || + standardPersonalityKeys.find(param) != standardPersonalityKeys.end() || + relaxedPersonalityKeys.find(param) != relaxedPersonalityKeys.end()) { + if (param == "TrafficFollow" || param == "AggressiveFollow" || param == "StandardFollow" || param == "RelaxedFollow") { + if (param == "TrafficFollow") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.5, 5, std::map(), this, false, tr(" seconds"), 1, 0.01); + } else { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 5, std::map(), this, false, tr(" seconds"), 1, 0.01); + } + } else { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 500, std::map(), this, false, "%"); + } + } else if (param == "OnroadDistanceButton") { + std::vector onroadDistanceToggles{"KaofuiIcons"}; + std::vector onroadDistanceToggleNames{tr("Kaofui's Icons")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, onroadDistanceToggles, onroadDistanceToggleNames); + + } else if (param == "ExperimentalModeActivation") { + FrogPilotParamManageControl *experimentalModeActivationToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(experimentalModeActivationToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end()); + } + }); + toggle = experimentalModeActivationToggle; + + } else if (param == "LateralTune") { + FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedLateralTuneKeys = lateralTuneKeys; + + if (hasAutoTune || params.getBool("LateralTune") && params.getBool("NNFF")) { + modifiedLateralTuneKeys.erase("ForceAutoTune"); + } + + if (hasCommaNNFFSupport) { + modifiedLateralTuneKeys.erase("NNFF"); + modifiedLateralTuneKeys.erase("NNFFLite"); + } else if (hasNNFFLog) { + modifiedLateralTuneKeys.erase("NNFFLite"); + } else { + modifiedLateralTuneKeys.erase("NNFF"); + } + + toggle->setVisible(modifiedLateralTuneKeys.find(key.c_str()) != modifiedLateralTuneKeys.end()); + } + }); + toggle = lateralTuneToggle; + } else if (param == "SteerRatio") { + std::vector steerRatioToggles{"ResetSteerRatio"}; + std::vector steerRatioToggleNames{"Reset"}; + toggle = new FrogPilotParamValueToggleControl(param, title, desc, icon, steerRatioStock * 0.75, steerRatioStock * 1.25, std::map(), this, false, "", 1, 0.01, steerRatioToggles, steerRatioToggleNames); + + } else if (param == "LongitudinalTune") { + FrogPilotParamManageControl *longitudinalTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(longitudinalTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedLongitudinalTuneKeys = longitudinalTuneKeys; + + if (params.get("Model") == "radical-turtle") { + modifiedLongitudinalTuneKeys.erase("LeadDetectionThreshold"); + } + + toggle->setVisible(modifiedLongitudinalTuneKeys.find(key.c_str()) != modifiedLongitudinalTuneKeys.end()); + } + }); + toggle = longitudinalTuneToggle; + } else if (param == "AccelerationProfile") { + std::vector profileOptions{tr("Standard"), tr("Eco"), tr("Sport"), tr("Sport+")}; + FrogPilotButtonParamControl *profileSelection = new FrogPilotButtonParamControl(param, title, desc, icon, profileOptions); + toggle = profileSelection; + + QObject::connect(static_cast(toggle), &FrogPilotButtonParamControl::buttonClicked, [this](int id) { + if (id == 3) { + FrogPilotConfirmationDialog::toggleAlert(tr("WARNING: This maxes out openpilot's acceleration from 2.0 m/s to 4.0 m/s and may cause oscillations when accelerating!"), + tr("I understand the risks."), this); + } + }); + } else if (param == "AggressiveAcceleration") { + std::vector accelerationToggles{"AggressiveAccelerationExperimental"}; + std::vector accelerationToggleNames{tr("Experimental")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, accelerationToggles, accelerationToggleNames); + QObject::connect(static_cast(toggle), &FrogPilotParamToggleControl::buttonClicked, [this](bool checked) { + if (checked) { + FrogPilotConfirmationDialog::toggleAlert( + tr("WARNING: This is very experimental and may cause the car to not brake or stop safely! Please report any issues in the FrogPilot Discord!"), + tr("I understand the risks."), this); + } + }); + } else if (param == "DecelerationProfile") { + std::vector profileOptions{tr("Standard"), tr("Eco"), tr("Sport")}; + FrogPilotButtonParamControl *profileSelection = new FrogPilotButtonParamControl(param, title, desc, icon, profileOptions); + toggle = profileSelection; + } else if (param == "StoppingDistance") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, std::map(), this, false, tr(" feet")); + } else if (param == "LeadDetectionThreshold") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, std::map(), this, false, "%"); + } else if (param == "SmoothBraking") { + std::vector brakingToggles{"SmoothBrakingJerk", "SmoothBrakingFarLead"}; + std::vector brakingToggleNames{tr("Apply to Jerk"), tr("Far Lead Offset")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, brakingToggles, brakingToggleNames); + QObject::connect(static_cast(toggle), &FrogPilotParamToggleControl::buttonClicked, [this](bool checked) { + if (checked) { + FrogPilotConfirmationDialog::toggleAlert( + tr("WARNING: This is very experimental and may cause the car to not brake or stop safely! Please report any issues in the FrogPilot Discord!"), + tr("I understand the risks."), this); + } + }); + + } else if (param == "MTSCEnabled") { + FrogPilotParamManageControl *mtscToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(mtscToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(mtscKeys.find(key.c_str()) != mtscKeys.end()); + } + }); + toggle = mtscToggle; + } else if (param == "MTSCAggressiveness") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 200, std::map(), this, false, "%"); + + } else if (param == "ModelSelector") { + FrogPilotParamManageControl *modelsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(modelsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(false); + } + + deleteModelBtn->setVisible(true); + downloadModelBtn->setVisible(true); + selectModelBtn->setVisible(true); + }); + toggle = modelsToggle; + + QDir modelDir("/data/models/"); + + deleteModelBtn = new ButtonControl(tr("Delete Model"), tr("DELETE"), ""); + QObject::connect(deleteModelBtn, &ButtonControl::clicked, [=]() { + std::string currentModel = params.get("Model") + ".thneed"; + + QStringList availableModels = QString::fromStdString(params.get("AvailableModels")).split(","); + QStringList modelLabels = QString::fromStdString(params.get("AvailableModelsNames")).split(","); + + QStringList existingModelFiles = modelDir.entryList({"*.thneed"}, QDir::Files); + QMap labelToFileMap; + QStringList deletableModelLabels; + for (int i = 0; i < availableModels.size(); ++i) { + QString modelFileName = availableModels[i] + ".thneed"; + if (existingModelFiles.contains(modelFileName) && modelFileName != QString::fromStdString(currentModel)) { + QString readableName = modelLabels[i]; + deletableModelLabels.append(readableName); + labelToFileMap[readableName] = modelFileName; + } + } + + QString selectedModel = MultiOptionDialog::getSelection(tr("Select a model to delete"), deletableModelLabels, "", this); + if (!selectedModel.isEmpty() && ConfirmationDialog::confirm(tr("Are you sure you want to delete this model?"), tr("Delete"), this)) { + std::thread([=]() { + deleteModelBtn->setValue(tr("Deleting...")); + + deleteModelBtn->setEnabled(false); + downloadModelBtn->setEnabled(false); + selectModelBtn->setEnabled(false); + + QString modelToDelete = labelToFileMap[selectedModel]; + + QFile::remove(modelDir.absoluteFilePath(modelToDelete)); + + deleteModelBtn->setEnabled(true); + downloadModelBtn->setEnabled(true); + selectModelBtn->setEnabled(true); + + deleteModelBtn->setValue(tr("Deleted!")); + std::this_thread::sleep_for(std::chrono::seconds(3)); + deleteModelBtn->setValue(""); + }).detach(); + } + }); + addItem(deleteModelBtn); + + downloadModelBtn = new ButtonControl(tr("Download Model"), tr("DOWNLOAD"), ""); + QObject::connect(downloadModelBtn, &ButtonControl::clicked, [=]() { + QStringList availableModels = QString::fromStdString(params.get("AvailableModels")).split(","); + QStringList modelLabels = QString::fromStdString(params.get("AvailableModelsNames")).split(","); + + QMap labelToModelMap; + QStringList downloadableModelLabels; + QStringList existingModelFiles = modelDir.entryList({"*.thneed"}, QDir::Files); + for (int i = 0; i < availableModels.size(); ++i) { + QString modelFileName = availableModels.at(i) + ".thneed"; + if (!existingModelFiles.contains(modelFileName)) { + QString readableName = modelLabels.at(i); + if (!readableName.contains("(Default)")) { + downloadableModelLabels.append(readableName); + labelToModelMap.insert(readableName, availableModels.at(i)); + } + } + } + + QString modelToDownload = MultiOptionDialog::getSelection(tr("Select a driving model to download"), downloadableModelLabels, "", this); + if (!modelToDownload.isEmpty()) { + QString selectedModelValue = labelToModelMap.value(modelToDownload); + paramsMemory.put("ModelToDownload", selectedModelValue.toStdString()); + + deleteModelBtn->setEnabled(false); + downloadModelBtn->setEnabled(false); + selectModelBtn->setEnabled(false); + + QTimer *failureTimer = new QTimer(this); + failureTimer->setSingleShot(true); + + QTimer *progressTimer = new QTimer(this); + progressTimer->setInterval(100); + + connect(failureTimer, &QTimer::timeout, this, [=]() { + deleteModelBtn->setEnabled(true); + downloadModelBtn->setEnabled(true); + selectModelBtn->setEnabled(true); + + downloadModelBtn->setValue(tr("Download failed...")); + paramsMemory.remove("ModelDownloadProgress"); + paramsMemory.remove("ModelToDownload"); + + progressTimer->stop(); + progressTimer->deleteLater(); + + QTimer::singleShot(3000, this, [this]() { + downloadModelBtn->setValue(""); + }); + }); + + connect(progressTimer, &QTimer::timeout, this, [=]() mutable { + static int lastProgress = -1; + int progress = paramsMemory.getInt("ModelDownloadProgress"); + + if (progress == lastProgress) { + if (!failureTimer->isActive()) { + failureTimer->start(30000); + } + } else { + lastProgress = progress; + downloadModelBtn->setValue(QString::number(progress) + "%"); + failureTimer->stop(); + + if (progress == 100) { + deleteModelBtn->setEnabled(true); + downloadModelBtn->setEnabled(true); + selectModelBtn->setEnabled(true); + + downloadModelBtn->setValue(tr("Downloaded!")); + paramsMemory.remove("ModelDownloadProgress"); + paramsMemory.remove("ModelToDownload"); + + progressTimer->stop(); + progressTimer->deleteLater(); + + QTimer::singleShot(3000, this, [this]() { + if (paramsMemory.get("ModelDownloadProgress").empty()) { + downloadModelBtn->setValue(""); + } + }); + } + } + }); + progressTimer->start(); + } + }); + addItem(downloadModelBtn); + + selectModelBtn = new ButtonControl(tr("Select Model"), tr("SELECT"), ""); + QObject::connect(selectModelBtn, &ButtonControl::clicked, [=]() { + QStringList availableModels = QString::fromStdString(params.get("AvailableModels")).split(","); + QStringList modelLabels = QString::fromStdString(params.get("AvailableModelsNames")).split(","); + + QStringList modelFiles = modelDir.entryList({"*.thneed"}, QDir::Files); + QSet modelFilesBaseNames; + for (const QString &modelFile : modelFiles) { + modelFilesBaseNames.insert(modelFile.section('.', 0, 0)); + } + + QStringList selectableModelLabels; + for (int i = 0; i < availableModels.size(); ++i) { + if (modelFilesBaseNames.contains(availableModels[i]) || modelLabels[i].contains("(Default)")) { + selectableModelLabels.append(modelLabels[i]); + } + } + + QString modelToSelect = MultiOptionDialog::getSelection(tr("Select a model - 🗺️ = Navigation | 📡 = Radar | 👀 = VOACC"), selectableModelLabels, "", this); + if (!modelToSelect.isEmpty()) { + selectModelBtn->setValue(modelToSelect); + + int modelIndex = modelLabels.indexOf(modelToSelect); + if (modelIndex != -1) { + QString selectedModel = availableModels.at(modelIndex); + params.putNonBlocking("Model", selectedModel.toStdString()); + params.putNonBlocking("ModelName", modelToSelect.toStdString()); + } + + if (FrogPilotConfirmationDialog::yesorno(tr("Do you want to start with a fresh calibration for the newly selected model?"), this)) { + params.remove("CalibrationParams"); + params.remove("LiveTorqueParameters"); + } + + if (started) { + if (FrogPilotConfirmationDialog::toggle(tr("Reboot required to take effect."), tr("Reboot Now"), this)) { + Hardware::reboot(); + } + } + } + }); + addItem(selectModelBtn); + selectModelBtn->setValue(QString::fromStdString(params.get("ModelName"))); + + } else if (param == "QOLControls") { + FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedQolKeys = qolKeys; + + if (!hasPCMCruise) { + modifiedQolKeys.erase("ReverseCruise"); + } else { + modifiedQolKeys.erase("CustomCruise"); + modifiedQolKeys.erase("CustomCruiseLong"); + modifiedQolKeys.erase("SetSpeedOffset"); + } + + if (!isToyota && !isGM && !isHKGCanFd) { + modifiedQolKeys.erase("MapGears"); + } + + toggle->setVisible(modifiedQolKeys.find(key.c_str()) != modifiedQolKeys.end()); + } + }); + toggle = qolToggle; + } else if (param == "CustomCruise") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, std::map(), this, false, tr(" mph")); + } else if (param == "CustomCruiseLong") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, std::map(), this, false, tr(" mph")); + } else if (param == "MapGears") { + std::vector mapGearsToggles{"MapAcceleration", "MapDeceleration"}; + std::vector mapGearsToggleNames{tr("Acceleration"), tr("Deceleration")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, mapGearsToggles, mapGearsToggleNames); + } else if (param == "PauseLateralSpeed") { + std::vector pauseLateralToggles{"PauseLateralOnSignal"}; + std::vector pauseLateralToggleNames{"Turn Signal Only"}; + toggle = new FrogPilotParamValueToggleControl(param, title, desc, icon, 0, 99, std::map(), this, false, tr(" mph"), 1, 1, pauseLateralToggles, pauseLateralToggleNames); + } else if (param == "PauseLateralOnSignal") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map(), this, false, tr(" mph")); + } else if (param == "ReverseCruise") { + std::vector reverseCruiseToggles{"ReverseCruiseUI"}; + std::vector reverseCruiseNames{tr("Control Via UI")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, reverseCruiseToggles, reverseCruiseNames); + } else if (param == "SetSpeedOffset") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map(), this, false, tr(" mph")); + + } else if (param == "LaneChangeCustomizations") { + FrogPilotParamManageControl *laneChangeToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(laneChangeToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(laneChangeKeys.find(key.c_str()) != laneChangeKeys.end()); + } + }); + toggle = laneChangeToggle; + } else if (param == "MinimumLaneChangeSpeed") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map(), this, false, tr(" mph")); + } else if (param == "LaneChangeTime") { + std::map laneChangeTimeLabels; + for (int i = 0; i <= 10; ++i) { + laneChangeTimeLabels[i] = i == 0 ? "Instant" : QString::number(i / 2.0) + " seconds"; + } + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, laneChangeTimeLabels, this, false); + } else if (param == "LaneDetectionWidth") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map(), this, false, " feet", 10); + + } else if (param == "SpeedLimitController") { + FrogPilotParamManageControl *speedLimitControllerToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(speedLimitControllerToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + slcOpen = true; + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end()); + } + }); + toggle = speedLimitControllerToggle; + } else if (param == "SLCControls") { + FrogPilotParamManageControl *manageSLCControlsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true); + QObject::connect(manageSLCControlsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(speedLimitControllerControlsKeys.find(key.c_str()) != speedLimitControllerControlsKeys.end()); + openSubParentToggle(); + } + }); + toggle = manageSLCControlsToggle; + } else if (param == "SLCQOL") { + FrogPilotParamManageControl *manageSLCQOLToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true); + QObject::connect(manageSLCQOLToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + std::set modifiedSpeedLimitControllerQOLKeys = speedLimitControllerQOLKeys; + + if (hasPCMCruise) { + modifiedSpeedLimitControllerQOLKeys.erase("SetSpeedLimit"); + } + + if (!isToyota) { + modifiedSpeedLimitControllerQOLKeys.erase("ForceMPHDashboard"); + } + + toggle->setVisible(modifiedSpeedLimitControllerQOLKeys.find(key.c_str()) != modifiedSpeedLimitControllerQOLKeys.end()); + openSubParentToggle(); + } + }); + toggle = manageSLCQOLToggle; + } else if (param == "SLCConfirmation") { + std::vector slcConfirmationToggles{"SLCConfirmationLower", "SLCConfirmationHigher"}; + std::vector slcConfirmationNames{tr("Lower Limits"), tr("Higher Limits")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, slcConfirmationToggles, slcConfirmationNames); + } else if (param == "SLCLookaheadHigher" || param == "SLCLookaheadLower") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 60, std::map(), this, false, " seconds"); + } else if (param == "SLCVisuals") { + FrogPilotParamManageControl *manageSLCVisualsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this, true); + QObject::connect(manageSLCVisualsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + for (auto &[key, toggle] : toggles) { + toggle->setVisible(speedLimitControllerVisualsKeys.find(key.c_str()) != speedLimitControllerVisualsKeys.end()); + openSubParentToggle(); + } + }); + toggle = manageSLCVisualsToggle; + } else if (param == "Offset1" || param == "Offset2" || param == "Offset3" || param == "Offset4") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, -99, 99, std::map(), this, false, tr(" mph")); + } else if (param == "ShowSLCOffset") { + std::vector slcOffsetToggles{"ShowSLCOffsetUI"}; + std::vector slcOffsetToggleNames{tr("Control Via UI")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, slcOffsetToggles, slcOffsetToggleNames); + } else if (param == "SLCFallback") { + std::vector fallbackOptions{tr("Set Speed"), tr("Experimental Mode"), tr("Previous Limit")}; + FrogPilotButtonParamControl *fallbackSelection = new FrogPilotButtonParamControl(param, title, desc, icon, fallbackOptions); + toggle = fallbackSelection; + } else if (param == "SLCOverride") { + std::vector overrideOptions{tr("None"), tr("Manual Set Speed"), tr("Set Speed")}; + FrogPilotButtonParamControl *overrideSelection = new FrogPilotButtonParamControl(param, title, desc, icon, overrideOptions); + toggle = overrideSelection; + } else if (param == "SLCPriority") { + ButtonControl *slcPriorityButton = new ButtonControl(title, tr("SELECT"), desc); + QStringList primaryPriorities = {tr("None"), tr("Dashboard"), tr("Navigation"), tr("Offline Maps"), tr("Highest"), tr("Lowest")}; + QStringList secondaryTertiaryPriorities = {tr("None"), tr("Dashboard"), tr("Navigation"), tr("Offline Maps")}; + QStringList priorityPrompts = {tr("Select your primary priority"), tr("Select your secondary priority"), tr("Select your tertiary priority")}; + + QObject::connect(slcPriorityButton, &ButtonControl::clicked, [=]() { + QStringList selectedPriorities; + + for (int i = 1; i <= 3; ++i) { + QStringList currentPriorities = (i == 1) ? primaryPriorities : secondaryTertiaryPriorities; + QStringList prioritiesToDisplay = currentPriorities; + for (const auto &selectedPriority : qAsConst(selectedPriorities)) { + prioritiesToDisplay.removeAll(selectedPriority); + } + + if (!hasDashSpeedLimits) { + prioritiesToDisplay.removeAll(tr("Dashboard")); + } + + if (prioritiesToDisplay.size() == 1 && prioritiesToDisplay.contains(tr("None"))) { + break; + } + + QString priorityKey = QString("SLCPriority%1").arg(i); + QString selection = MultiOptionDialog::getSelection(priorityPrompts[i - 1], prioritiesToDisplay, "", this); + + if (selection.isEmpty()) break; + + params.putNonBlocking(priorityKey.toStdString(), selection.toStdString()); + selectedPriorities.append(selection); + + if (selection == tr("Lowest") || selection == tr("Highest") || selection == tr("None")) break; + + updateFrogPilotToggles(); + } + + selectedPriorities.removeAll(tr("None")); + slcPriorityButton->setValue(selectedPriorities.join(", ")); + }); + + QStringList initialPriorities; + for (int i = 1; i <= 3; ++i) { + QString priorityKey = QString("SLCPriority%1").arg(i); + QString priority = QString::fromStdString(params.get(priorityKey.toStdString())); + + if (!priority.isEmpty() && primaryPriorities.contains(priority) && priority != tr("None")) { + initialPriorities.append(priority); + } + } + slcPriorityButton->setValue(initialPriorities.join(", ")); + toggle = slcPriorityButton; + + } else if (param == "VisionTurnControl") { + FrogPilotParamManageControl *visionTurnControlToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(visionTurnControlToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end()); + } + }); + toggle = visionTurnControlToggle; + } else if (param == "CurveSensitivity" || param == "TurnAggressiveness") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 200, std::map(), this, false, "%"); + + } else { + toggle = new ParamControl(param, title, desc, icon, this); + } + + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(static_cast(toggle), &ToggleControl::toggleFlipped, &updateFrogPilotToggles); + QObject::connect(static_cast(toggle), &FrogPilotParamValueControl::valueChanged, &updateFrogPilotToggles); + + ParamWatcher *param_watcher = new ParamWatcher(this); + param_watcher->addParam("CESpeed"); + param_watcher->addParam("CESpeedLead"); + + QObject::connect(param_watcher, &ParamWatcher::paramChanged, [=](const QString ¶m_name, const QString ¶m_value) { + updateFrogPilotToggles(); + }); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + update(); + }); + } + + QObject::connect(static_cast(toggles["IncreaseThermalLimits"]), &ToggleControl::toggleFlipped, [this]() { + if (params.getBool("IncreaseThermalLimits")) { + FrogPilotConfirmationDialog::toggleAlert( + tr("WARNING: This can cause premature wear or damage by running the device over comma's recommended temperature limits!"), + tr("I understand the risks."), this); + } + }); + + QObject::connect(static_cast(toggles["NoLogging"]), &ToggleControl::toggleFlipped, [this]() { + if (params.getBool("NoLogging")) { + FrogPilotConfirmationDialog::toggleAlert( + tr("WARNING: This will prevent your drives from being recorded and the data will be unobtainable!"), + tr("I understand the risks."), this); + } + }); + + QObject::connect(static_cast(toggles["NoUploads"]), &ToggleControl::toggleFlipped, [this]() { + if (params.getBool("NoUploads")) { + FrogPilotConfirmationDialog::toggleAlert( + tr("WARNING: This will prevent your drives from appearing on comma connect which may impact debugging and support!"), + tr("I understand the risks."), this); + } + }); + + QObject::connect(static_cast(toggles["TrafficMode"]), &ToggleControl::toggleFlipped, [this]() { + if (params.getBool("TrafficMode")) { + FrogPilotConfirmationDialog::toggleAlert( + tr("To activate 'Traffic Mode' you hold down the 'distance' button on your steering wheel for 2.5 seconds."), + tr("Sounds good!"), this); + } + }); + + std::set rebootKeys = {"AlwaysOnLateral", "NNFF", "NNFFLite"}; + for (const QString &key : rebootKeys) { + QObject::connect(static_cast(toggles[key.toStdString().c_str()]), &ToggleControl::toggleFlipped, [this]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle(tr("Reboot required to take effect."), tr("Reboot Now"), this)) { + Hardware::reboot(); + } + } + }); + } + + FrogPilotParamValueControl *trafficFollowToggle = static_cast(toggles["TrafficFollow"]); + FrogPilotParamValueControl *trafficAccelerationoggle = static_cast(toggles["TrafficJerkAcceleration"]); + FrogPilotParamValueControl *trafficSpeedToggle = static_cast(toggles["TrafficJerkSpeed"]); + FrogPilotButtonsControl *trafficResetButton = static_cast(toggles["ResetTrafficPersonality"]); + + QObject::connect(trafficResetButton, &FrogPilotButtonsControl::buttonClicked, this, [=]() { + if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the 'Traffic Mode' personality?"), this)) { + params.putFloat("TrafficFollow", 0.5); + params.putFloat("TrafficJerkAcceleration", 50); + params.putFloat("TrafficJerkSpeed", 75); + trafficFollowToggle->refresh(); + trafficAccelerationoggle->refresh(); + trafficSpeedToggle->refresh(); + updateFrogPilotToggles(); + } + }); + + FrogPilotParamValueControl *aggressiveFollowToggle = static_cast(toggles["AggressiveFollow"]); + FrogPilotParamValueControl *aggressiveAccelerationoggle = static_cast(toggles["AggressiveJerkAcceleration"]); + FrogPilotParamValueControl *aggressiveSpeedToggle = static_cast(toggles["AggressiveJerkSpeed"]); + FrogPilotButtonsControl *aggressiveResetButton = static_cast(toggles["ResetAggressivePersonality"]); + + QObject::connect(aggressiveResetButton, &FrogPilotButtonsControl::buttonClicked, this, [=]() { + if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the 'Aggressive' personality?"), this)) { + params.putFloat("AggressiveFollow", 1.25); + params.putFloat("AggressiveJerkAcceleration", 50); + params.putFloat("AggressiveJerkSpeed", 50); + aggressiveFollowToggle->refresh(); + aggressiveAccelerationoggle->refresh(); + aggressiveSpeedToggle->refresh(); + updateFrogPilotToggles(); + } + }); + + FrogPilotParamValueControl *standardFollowToggle = static_cast(toggles["StandardFollow"]); + FrogPilotParamValueControl *standardAccelerationoggle = static_cast(toggles["StandardJerkAcceleration"]); + FrogPilotParamValueControl *standardSpeedToggle = static_cast(toggles["StandardJerkSpeed"]); + FrogPilotButtonsControl *standardResetButton = static_cast(toggles["ResetStandardPersonality"]); + + QObject::connect(standardResetButton, &FrogPilotButtonsControl::buttonClicked, this, [=]() { + if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the 'Standard' personality?"), this)) { + params.putFloat("StandardFollow", 1.45); + params.putFloat("StandardJerkAcceleration", 100); + params.putFloat("StandardJerkSpeed", 100); + standardFollowToggle->refresh(); + standardAccelerationoggle->refresh(); + standardSpeedToggle->refresh(); + updateFrogPilotToggles(); + } + }); + + FrogPilotParamValueControl *relaxedFollowToggle = static_cast(toggles["RelaxedFollow"]); + FrogPilotParamValueControl *relaxedAccelerationoggle = static_cast(toggles["RelaxedJerkAcceleration"]); + FrogPilotParamValueControl *relaxedSpeedToggle = static_cast(toggles["RelaxedJerkSpeed"]); + FrogPilotButtonsControl *relaxedResetButton = static_cast(toggles["ResetRelaxedPersonality"]); + + QObject::connect(relaxedResetButton, &FrogPilotButtonsControl::buttonClicked, this, [=]() { + if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the 'Relaxed' personality?"), this)) { + params.putFloat("RelaxedFollow", 1.75); + params.putFloat("RelaxedJerkAcceleration", 100); + params.putFloat("RelaxedJerkSpeed", 100); + relaxedFollowToggle->refresh(); + relaxedAccelerationoggle->refresh(); + relaxedSpeedToggle->refresh(); + updateFrogPilotToggles(); + } + }); + + modelManagerToggle = static_cast(toggles["ModelSelector"]); + steerRatioToggle = static_cast(toggles["SteerRatio"]); + + QObject::connect(steerRatioToggle, &FrogPilotParamValueToggleControl::buttonClicked, this, [this]() { + params.putFloat("SteerRatio", steerRatioStock); + params.putBool("ResetSteerRatio", false); + steerRatioToggle->refresh(); + updateFrogPilotToggles(); + }); + + QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotControlsPanel::hideToggles); + QObject::connect(parent, &SettingsWindow::closeSubParentToggle, this, &FrogPilotControlsPanel::hideSubToggles); + QObject::connect(parent, &SettingsWindow::closeSubSubParentToggle, this, &FrogPilotControlsPanel::hideSubSubToggles); + QObject::connect(parent, &SettingsWindow::updateMetric, this, &FrogPilotControlsPanel::updateMetric); + QObject::connect(uiState(), &UIState::offroadTransition, this, &FrogPilotControlsPanel::updateCarToggles); + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotControlsPanel::updateState); + + updateMetric(); +} + +void FrogPilotControlsPanel::showEvent(QShowEvent *event, const UIState &s) { + hasOpenpilotLongitudinal = hasOpenpilotLongitudinal && !params.getBool("DisableOpenpilotLongitudinal"); + + downloadModelBtn->setEnabled(s.scene.online); +} + +void FrogPilotControlsPanel::updateState(const UIState &s) { + if (!isVisible()) return; + + started = s.scene.started; + + modelManagerToggle->setEnabled(!s.scene.started || s.scene.parked); +} + +void FrogPilotControlsPanel::updateCarToggles() { + auto carParams = params.get("CarParamsPersistent"); + if (!carParams.empty()) { + AlignedBuffer aligned_buf; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(carParams.data(), carParams.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + auto carFingerprint = CP.getCarFingerprint(); + auto carName = CP.getCarName(); + auto safetyConfigs = CP.getSafetyConfigs(); + auto safetyModel = safetyConfigs[0].getSafetyModel(); + + hasAutoTune = (carName == "hyundai" || carName == "toyota") && CP.getLateralTuning().which() == cereal::CarParams::LateralTuning::TORQUE; + uiState()->scene.has_auto_tune = hasAutoTune; + hasCommaNNFFSupport = checkCommaNNFFSupport(carFingerprint); + hasDashSpeedLimits = carName == "hyundai" || carName == "toyota"; + hasNNFFLog = checkNNFFLogFileExists(carFingerprint); + hasOpenpilotLongitudinal = CP.getOpenpilotLongitudinalControl() && !params.getBool("DisableOpenpilotLongitudinal"); + hasPCMCruise = CP.getPcmCruise(); + isGM = carName == "gm"; + isHKGCanFd = (carName == "hyundai") && (safetyModel == cereal::CarParams::SafetyModel::HYUNDAI_CANFD); + isToyota = carName == "toyota"; + steerRatioStock = CP.getSteerRatio(); + + steerRatioToggle->setTitle(QString(tr("Steer Ratio (Default: %1)")).arg(QString::number(steerRatioStock, 'f', 2))); + steerRatioToggle->updateControl(steerRatioStock * 0.75, steerRatioStock * 1.25, "", 0.01); + steerRatioToggle->refresh(); + } else { + hasAutoTune = false; + hasCommaNNFFSupport = false; + hasDashSpeedLimits = true; + hasNNFFLog = true; + hasOpenpilotLongitudinal = true; + hasPCMCruise = true; + isGM = true; + isHKGCanFd = true; + isToyota = true; + } + + hideToggles(); +} + +void FrogPilotControlsPanel::updateMetric() { + bool previousIsMetric = isMetric; + isMetric = params.getBool("IsMetric"); + + if (isMetric != previousIsMetric) { + double distanceConversion = isMetric ? FOOT_TO_METER : METER_TO_FOOT; + double speedConversion = isMetric ? MILE_TO_KM : KM_TO_MILE; + + params.putIntNonBlocking("CESpeed", std::nearbyint(params.getInt("CESpeed") * speedConversion)); + params.putIntNonBlocking("CESpeedLead", std::nearbyint(params.getInt("CESpeedLead") * speedConversion)); + params.putIntNonBlocking("CustomCruise", std::nearbyint(params.getInt("CustomCruise") * speedConversion)); + params.putIntNonBlocking("CustomCruiseLong", std::nearbyint(params.getInt("CustomCruiseLong") * speedConversion)); + params.putIntNonBlocking("LaneDetectionWidth", std::nearbyint(params.getInt("LaneDetectionWidth") * distanceConversion)); + params.putIntNonBlocking("MinimumLaneChangeSpeed", std::nearbyint(params.getInt("MinimumLaneChangeSpeed") * speedConversion)); + params.putIntNonBlocking("Offset1", std::nearbyint(params.getInt("Offset1") * speedConversion)); + params.putIntNonBlocking("Offset2", std::nearbyint(params.getInt("Offset2") * speedConversion)); + params.putIntNonBlocking("Offset3", std::nearbyint(params.getInt("Offset3") * speedConversion)); + params.putIntNonBlocking("Offset4", std::nearbyint(params.getInt("Offset4") * speedConversion)); + params.putIntNonBlocking("PauseAOLOnBrake", std::nearbyint(params.getInt("PauseAOLOnBrake") * speedConversion)); + params.putIntNonBlocking("PauseLateralOnSignal", std::nearbyint(params.getInt("PauseLateralOnSignal") * speedConversion)); + params.putIntNonBlocking("PauseLateralSpeed", std::nearbyint(params.getInt("PauseLateralSpeed") * speedConversion)); + params.putIntNonBlocking("SetSpeedOffset", std::nearbyint(params.getInt("SetSpeedOffset") * speedConversion)); + params.putIntNonBlocking("StoppingDistance", std::nearbyint(params.getInt("StoppingDistance") * distanceConversion)); + } + + FrogPilotParamValueControl *customCruiseToggle = static_cast(toggles["CustomCruise"]); + FrogPilotParamValueControl *customCruiseLongToggle = static_cast(toggles["CustomCruiseLong"]); + FrogPilotParamValueControl *laneWidthToggle = static_cast(toggles["LaneDetectionWidth"]); + FrogPilotParamValueControl *minimumLaneChangeSpeedToggle = static_cast(toggles["MinimumLaneChangeSpeed"]); + FrogPilotParamValueControl *offset1Toggle = static_cast(toggles["Offset1"]); + FrogPilotParamValueControl *offset2Toggle = static_cast(toggles["Offset2"]); + FrogPilotParamValueControl *offset3Toggle = static_cast(toggles["Offset3"]); + FrogPilotParamValueControl *offset4Toggle = static_cast(toggles["Offset4"]); + FrogPilotParamValueControl *pauseAOLOnBrakeToggle = static_cast(toggles["PauseAOLOnBrake"]); + FrogPilotParamValueControl *pauseLateralToggle = static_cast(toggles["PauseLateralSpeed"]); + FrogPilotParamValueControl *setSpeedOffsetToggle = static_cast(toggles["SetSpeedOffset"]); + FrogPilotParamValueControl *stoppingDistanceToggle = static_cast(toggles["StoppingDistance"]); + + if (isMetric) { + offset1Toggle->setTitle(tr("Speed Limit Offset (0-34 kph)")); + offset2Toggle->setTitle(tr("Speed Limit Offset (35-54 kph)")); + offset3Toggle->setTitle(tr("Speed Limit Offset (55-64 kph)")); + offset4Toggle->setTitle(tr("Speed Limit Offset (65-99 kph)")); + + offset1Toggle->setDescription(tr("Set speed limit offset for limits between 0-34 kph.")); + offset2Toggle->setDescription(tr("Set speed limit offset for limits between 35-54 kph.")); + offset3Toggle->setDescription(tr("Set speed limit offset for limits between 55-64 kph.")); + offset4Toggle->setDescription(tr("Set speed limit offset for limits between 65-99 kph.")); + + customCruiseToggle->updateControl(1, 150, tr(" kph")); + customCruiseLongToggle->updateControl(1, 150, tr(" kph")); + minimumLaneChangeSpeedToggle->updateControl(0, 150, tr(" kph")); + offset1Toggle->updateControl(-99, 99, tr(" kph")); + offset2Toggle->updateControl(-99, 99, tr(" kph")); + offset3Toggle->updateControl(-99, 99, tr(" kph")); + offset4Toggle->updateControl(-99, 99, tr(" kph")); + pauseAOLOnBrakeToggle->updateControl(0, 99, tr(" kph")); + pauseLateralToggle->updateControl(0, 99, tr(" kph")); + setSpeedOffsetToggle->updateControl(0, 150, tr(" kph")); + + laneWidthToggle->updateControl(0, 30, tr(" meters"), 10); + stoppingDistanceToggle->updateControl(0, 5, tr(" meters")); + } else { + offset1Toggle->setTitle(tr("Speed Limit Offset (0-34 mph)")); + offset2Toggle->setTitle(tr("Speed Limit Offset (35-54 mph)")); + offset3Toggle->setTitle(tr("Speed Limit Offset (55-64 mph)")); + offset4Toggle->setTitle(tr("Speed Limit Offset (65-99 mph)")); + + offset1Toggle->setDescription(tr("Set speed limit offset for limits between 0-34 mph.")); + offset2Toggle->setDescription(tr("Set speed limit offset for limits between 35-54 mph.")); + offset3Toggle->setDescription(tr("Set speed limit offset for limits between 55-64 mph.")); + offset4Toggle->setDescription(tr("Set speed limit offset for limits between 65-99 mph.")); + + customCruiseToggle->updateControl(1, 99, tr(" mph")); + customCruiseLongToggle->updateControl(1, 99, tr(" mph")); + minimumLaneChangeSpeedToggle->updateControl(0, 99, tr(" mph")); + offset1Toggle->updateControl(-99, 99, tr(" mph")); + offset2Toggle->updateControl(-99, 99, tr(" mph")); + offset3Toggle->updateControl(-99, 99, tr(" mph")); + offset4Toggle->updateControl(-99, 99, tr(" mph")); + pauseAOLOnBrakeToggle->updateControl(0, 99, tr(" mph")); + pauseLateralToggle->updateControl(0, 99, tr(" mph")); + setSpeedOffsetToggle->updateControl(0, 99, tr(" mph")); + + laneWidthToggle->updateControl(0, 100, tr(" feet"), 10); + stoppingDistanceToggle->updateControl(0, 10, tr(" feet")); + } + + customCruiseToggle->refresh(); + customCruiseLongToggle->refresh(); + laneWidthToggle->refresh(); + minimumLaneChangeSpeedToggle->refresh(); + offset1Toggle->refresh(); + offset2Toggle->refresh(); + offset3Toggle->refresh(); + offset4Toggle->refresh(); + pauseAOLOnBrakeToggle->refresh(); + pauseLateralToggle->refresh(); + setSpeedOffsetToggle->refresh(); + stoppingDistanceToggle->refresh(); +} + +void FrogPilotControlsPanel::hideToggles() { + customPersonalitiesOpen = false; + slcOpen = false; + + conditionalSpeedsImperial->setVisible(false); + conditionalSpeedsMetric->setVisible(false); + deleteModelBtn->setVisible(false); + downloadModelBtn->setVisible(false); + personalitiesInfoBtn->setVisible(false); + selectModelBtn->setVisible(false); + + std::set longitudinalKeys = {"ConditionalExperimental", "DrivingPersonalities", "ExperimentalModeActivation", + "LongitudinalTune", "MTSCEnabled", "SpeedLimitController", "VisionTurnControl"}; + + for (auto &[key, toggle] : toggles) { + toggle->setVisible(false); + + if (!hasOpenpilotLongitudinal && longitudinalKeys.find(key.c_str()) != longitudinalKeys.end()) { + continue; + } + + bool subToggles = aggressivePersonalityKeys.find(key.c_str()) != aggressivePersonalityKeys.end() || + aolKeys.find(key.c_str()) != aolKeys.end() || + conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() || + customdrivingPersonalityKeys.find(key.c_str()) != customdrivingPersonalityKeys.end() || + relaxedPersonalityKeys.find(key.c_str()) != relaxedPersonalityKeys.end() || + deviceManagementKeys.find(key.c_str()) != deviceManagementKeys.end() || + drivingPersonalityKeys.find(key.c_str()) != drivingPersonalityKeys.end() || + experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end() || + laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() || + lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() || + longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end() || + mtscKeys.find(key.c_str()) != mtscKeys.end() || + qolKeys.find(key.c_str()) != qolKeys.end() || + relaxedPersonalityKeys.find(key.c_str()) != relaxedPersonalityKeys.end() || + speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end() || + speedLimitControllerControlsKeys.find(key.c_str()) != speedLimitControllerControlsKeys.end() || + speedLimitControllerQOLKeys.find(key.c_str()) != speedLimitControllerQOLKeys.end() || + speedLimitControllerVisualsKeys.find(key.c_str()) != speedLimitControllerVisualsKeys.end() || + standardPersonalityKeys.find(key.c_str()) != standardPersonalityKeys.end() || + relaxedPersonalityKeys.find(key.c_str()) != relaxedPersonalityKeys.end() || + trafficPersonalityKeys.find(key.c_str()) != trafficPersonalityKeys.end() || + tuningKeys.find(key.c_str()) != tuningKeys.end() || + visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end(); + toggle->setVisible(!subToggles); + } + + update(); +} + +void FrogPilotControlsPanel::hideSubToggles() { + if (customPersonalitiesOpen) { + for (auto &[key, toggle] : toggles) { + bool isVisible = drivingPersonalityKeys.find(key.c_str()) != drivingPersonalityKeys.end(); + toggle->setVisible(isVisible); + } + } else if (slcOpen) { + for (auto &[key, toggle] : toggles) { + bool isVisible = speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end(); + toggle->setVisible(isVisible); + } + } + + update(); +} + +void FrogPilotControlsPanel::hideSubSubToggles() { + personalitiesInfoBtn->setVisible(false); + + for (auto &[key, toggle] : toggles) { + bool isVisible = customdrivingPersonalityKeys.find(key.c_str()) != customdrivingPersonalityKeys.end(); + toggle->setVisible(isVisible); + } + + update(); +} diff --git a/selfdrive/frogpilot/ui/qt/offroad/control_settings.h b/selfdrive/frogpilot/ui/qt/offroad/control_settings.h new file mode 100644 index 0000000..2e6e862 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/control_settings.h @@ -0,0 +1,83 @@ +#pragma once + +#include + +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotControlsPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotControlsPanel(SettingsWindow *parent); + +signals: + void openParentToggle(); + void openSubParentToggle(); + void openSubSubParentToggle(); + +private: + void hideSubToggles(); + void hideSubSubToggles(); + void hideToggles(); + void showEvent(QShowEvent *event, const UIState &s); + void updateCarToggles(); + void updateMetric(); + void updateState(const UIState &s); + + ButtonControl *deleteModelBtn; + ButtonControl *downloadModelBtn; + ButtonControl *personalitiesInfoBtn; + ButtonControl *selectModelBtn; + + FrogPilotDualParamControl *conditionalSpeedsImperial; + FrogPilotDualParamControl *conditionalSpeedsMetric; + + FrogPilotParamManageControl *modelManagerToggle; + + FrogPilotParamValueToggleControl *steerRatioToggle; + + std::set aggressivePersonalityKeys = {"AggressiveFollow", "AggressiveJerkAcceleration", "AggressiveJerkSpeed", "ResetAggressivePersonality"}; + std::set aolKeys = {"AlwaysOnLateralMain", "HideAOLStatusBar", "PauseAOLOnBrake"}; + std::set conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CENavigation", "CESignal", "CESlowerLead", "CEStopLights", "HideCEMStatusBar"}; + std::set deviceManagementKeys = {"DeviceShutdown", "IncreaseThermalLimits", "LowVoltageShutdown", "NoLogging", "NoUploads", "OfflineMode"}; + std::set customdrivingPersonalityKeys = {"TrafficPersonalityProfile", "AggressivePersonalityProfile", "StandardPersonalityProfile", "RelaxedPersonalityProfile"}; + std::set drivingPersonalityKeys = {"CustomPersonalities", "OnroadDistanceButton"}; + std::set experimentalModeActivationKeys = {"ExperimentalModeViaDistance", "ExperimentalModeViaLKAS", "ExperimentalModeViaTap"}; + std::set laneChangeKeys = {"LaneChangeTime", "LaneDetectionWidth", "MinimumLaneChangeSpeed", "NudgelessLaneChange", "OneLaneChange"}; + std::set lateralTuneKeys = {"ForceAutoTune", "NNFF", "NNFFLite", "SteerRatio", "TacoTune", "TurnDesires"}; + std::set longitudinalTuneKeys = {"AccelerationProfile", "AggressiveAcceleration", "DecelerationProfile", "LeadDetectionThreshold", "SmoothBraking", "StoppingDistance", "TrafficMode"}; + std::set mtscKeys = {"DisableMTSCSmoothing", "MTSCAggressiveness", "MTSCCurvatureCheck"}; + std::set qolKeys = {"CustomCruise", "CustomCruiseLong", "MapGears", "PauseLateralSpeed", "ReverseCruise", "SetSpeedOffset"}; + std::set relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedJerkAcceleration", "RelaxedJerkSpeed", "ResetRelaxedPersonality"}; + std::set speedLimitControllerKeys = {"SLCControls", "SLCQOL", "SLCVisuals"}; + std::set speedLimitControllerControlsKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "SLCFallback", "SLCOverride", "SLCPriority"}; + std::set speedLimitControllerQOLKeys = {"ForceMPHDashboard", "SetSpeedLimit", "SLCConfirmation", "SLCLookaheadHigher", "SLCLookaheadLower"}; + std::set speedLimitControllerVisualsKeys = {"ShowSLCOffset", "SpeedLimitChangedAlert", "UseVienna"}; + std::set standardPersonalityKeys = {"StandardFollow", "StandardJerkAcceleration", "StandardJerkSpeed", "ResetStandardPersonality"}; + std::set trafficPersonalityKeys = {"TrafficFollow", "TrafficJerkAcceleration", "TrafficJerkSpeed", "ResetTrafficPersonality"}; + std::set tuningKeys = {"kiV1", "kiV2", "kiV3", "kiV4", "kpV1", "kpV2", "kpV3", "kpV4"}; + std::set visionTurnControlKeys = {"CurveSensitivity", "DisableVTSCSmoothing", "TurnAggressiveness"}; + + std::map toggles; + + Params params; + Params paramsMemory{"/dev/shm/params"}; + + bool customPersonalitiesOpen; + bool hasAutoTune; + bool hasCommaNNFFSupport; + bool hasNNFFLog; + bool hasOpenpilotLongitudinal; + bool hasPCMCruise; + bool hasDashSpeedLimits; + bool isGM; + bool isHKGCanFd; + bool isMetric = params.getBool("IsMetric"); + bool isRelease; + bool isToyota; + bool slcOpen; + bool started; + + float steerRatioStock; +}; diff --git a/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc b/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc new file mode 100644 index 0000000..aa9b108 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc @@ -0,0 +1,284 @@ +#include +#include +#include + +#include "selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h" + +QStringList getCarNames(const QString &carMake) { + QMap makeMap; + makeMap["acura"] = "honda"; + makeMap["audi"] = "volkswagen"; + makeMap["buick"] = "gm"; + makeMap["cadillac"] = "gm"; + makeMap["chevrolet"] = "gm"; + makeMap["chrysler"] = "chrysler"; + makeMap["dodge"] = "chrysler"; + makeMap["ford"] = "ford"; + makeMap["gm"] = "gm"; + makeMap["gmc"] = "gm"; + makeMap["genesis"] = "hyundai"; + makeMap["honda"] = "honda"; + makeMap["hyundai"] = "hyundai"; + makeMap["infiniti"] = "nissan"; + makeMap["jeep"] = "chrysler"; + makeMap["kia"] = "hyundai"; + makeMap["lexus"] = "toyota"; + makeMap["lincoln"] = "ford"; + makeMap["man"] = "volkswagen"; + makeMap["mazda"] = "mazda"; + makeMap["nissan"] = "nissan"; + makeMap["ram"] = "chrysler"; + makeMap["seat"] = "volkswagen"; + makeMap["škoda"] = "volkswagen"; + makeMap["subaru"] = "subaru"; + makeMap["tesla"] = "tesla"; + makeMap["toyota"] = "toyota"; + makeMap["volkswagen"] = "volkswagen"; + + QString dirPath = "../car"; + QDir dir(dirPath); + QString targetFolder = makeMap.value(carMake, carMake); + QStringList names; + + QString filePath = dir.absoluteFilePath(targetFolder + "/values.py"); + QFile file(filePath); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + QRegularExpression regex(R"delimiter(\w+\s*=\s*\w+PlatformConfig\(\s*"([^"]+)",)delimiter"); + QRegularExpressionMatchIterator it = regex.globalMatch(in.readAll()); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + names << match.captured(1); + } + file.close(); + } + + std::sort(names.begin(), names.end()); + return names; +} + +FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + selectMakeButton = new ButtonControl(tr("Select Make"), tr("SELECT")); + QObject::connect(selectMakeButton, &ButtonControl::clicked, [this]() { + QStringList makes = { + "Acura", "Audi", "BMW", "Buick", "Cadillac", "Chevrolet", "Chrysler", "Dodge", "Ford", "GM", "GMC", + "Genesis", "Honda", "Hyundai", "Infiniti", "Jeep", "Kia", "Lexus", "Lincoln", "MAN", "Mazda", + "Mercedes", "Nissan", "Ram", "SEAT", "Škoda", "Subaru", "Tesla", "Toyota", "Volkswagen", "Volvo", + }; + + QString newMakeSelection = MultiOptionDialog::getSelection(tr("Select a Make"), makes, "", this); + if (!newMakeSelection.isEmpty()) { + carMake = newMakeSelection; + params.putNonBlocking("CarMake", carMake.toStdString()); + selectMakeButton->setValue(newMakeSelection); + setModels(); + } + }); + addItem(selectMakeButton); + + selectModelButton = new ButtonControl(tr("Select Model"), tr("SELECT")); + QObject::connect(selectModelButton, &ButtonControl::clicked, [this]() { + QString newModelSelection = MultiOptionDialog::getSelection(tr("Select a Model"), models, "", this); + if (!newModelSelection.isEmpty()) { + carModel = newModelSelection; + params.putNonBlocking("CarModel", newModelSelection.toStdString()); + selectModelButton->setValue(newModelSelection); + } + }); + addItem(selectModelButton); + selectModelButton->setVisible(false); + + ParamControl *forceFingerprint = new ParamControl("ForceFingerprint", tr("Disable Automatic Fingerprint Detection"), tr("Forces the selected fingerprint and prevents it from ever changing."), "", this); + addItem(forceFingerprint); + + bool disableOpenpilotLongState = params.getBool("DisableOpenpilotLongitudinal"); + disableOpenpilotLong = new ToggleControl(tr("Disable openpilot Longitudinal Control"), tr("Disable openpilot longitudinal control and use stock ACC instead."), "", disableOpenpilotLongState); + QObject::connect(disableOpenpilotLong, &ToggleControl::toggleFlipped, [=](bool state) { + if (state) { + if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely disable openpilot longitudinal control?"), this)) { + params.putBoolNonBlocking("DisableOpenpilotLongitudinal", state); + if (started) { + if (FrogPilotConfirmationDialog::toggle(tr("Reboot required to take effect."), tr("Reboot Now"), this)) { + Hardware::reboot(); + } + } + } + } else { + params.putBoolNonBlocking("DisableOpenpilotLongitudinal", state); + } + updateCarToggles(); + }); + addItem(disableOpenpilotLong); + + std::vector> vehicleToggles { + {"LongPitch", tr("Long Pitch Compensation"), tr("Smoothen out the gas and pedal controls."), ""}, + {"GasRegenCmd", tr("Truck Tune"), tr("Increase the acceleration and smoothen out the brake control when coming to a stop. For use on Silverado/Sierra only."), ""}, + + {"CrosstrekTorque", tr("Subaru Crosstrek Torque Increase"), tr("Increases the maximum allowed torque for the Subaru Crosstrek."), ""}, + + {"ToyotaDoors", tr("Automatically Lock/Unlock Doors"), tr("Automatically lock the doors when in drive and unlock when in park."), ""}, + {"ClusterOffset", tr("Cluster Offset"), tr("Set the cluster offset openpilot uses to try and match the speed displayed on the dash."), ""}, + {"SNGHack", tr("Stop and Go Hack"), tr("Enable the 'Stop and Go' hack for vehicles without stock stop and go functionality."), ""}, + {"ToyotaTune", tr("Toyota Tune"), tr("Use a custom Toyota longitudinal tune.\n\nCydia = More focused on TSS-P vehicles but works for all Toyotas\n\nDragonPilot = Focused on TSS2 vehicles\n\nFrogPilot = Takes the best of both worlds with some personal tweaks focused around FrogsGoMoo's 2019 Lexus ES 350"), ""}, + }; + + for (const auto &[param, title, desc, icon] : vehicleToggles) { + AbstractControl *toggle; + + if (param == "ToyotaDoors") { + std::vector lockToggles{"LockDoors", "UnlockDoors"}; + std::vector lockToggleNames{tr("Lock"), tr("Unlock")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, lockToggles, lockToggleNames); + + } else if (param == "ClusterOffset") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1.000, 1.050, std::map(), this, false, "x", 1, 0.001); + + } else if (param == "ToyotaTune") { + std::vector> tuneOptions{ + {"StockTune", tr("Stock")}, + {"CydiaTune", tr("Cydia")}, + {"DragonPilotTune", tr("DragonPilot")}, + {"FrogsGoMooTune", tr("FrogPilot")}, + }; + toggle = new FrogPilotButtonsParamControl(param, title, desc, icon, tuneOptions); + + QObject::connect(static_cast(toggle), &FrogPilotButtonsParamControl::buttonClicked, [this]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle(tr("Reboot required to take effect."), tr("Reboot Now"), this)) { + Hardware::reboot(); + } + } + }); + + } else { + toggle = new ParamControl(param, title, desc, icon, this); + } + + toggle->setVisible(false); + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(static_cast(toggle), &ToggleControl::toggleFlipped, &updateFrogPilotToggles); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + } + + std::set rebootKeys = {"CrosstrekTorque", "GasRegenCmd"}; + for (const QString &key : rebootKeys) { + QObject::connect(static_cast(toggles[key.toStdString().c_str()]), &ToggleControl::toggleFlipped, [this]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle(tr("Reboot required to take effect."), tr("Reboot Now"), this)) { + Hardware::reboot(); + } + } + }); + } + + QObject::connect(uiState(), &UIState::offroadTransition, [this](bool offroad) { + std::thread([this]() { + while (carMake.isEmpty()) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + carMake = QString::fromStdString(params.get("CarMake")); + carModel = QString::fromStdString(params.get("CarModel")); + } + setModels(); + updateCarToggles(); + }).detach(); + }); + + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVehiclesPanel::updateState); + + carMake = QString::fromStdString(params.get("CarMake")); + carModel = QString::fromStdString(params.get("CarModel")); + + if (!carMake.isEmpty()) { + setModels(); + } +} + +void FrogPilotVehiclesPanel::updateState(const UIState &s) { + if (!isVisible()) return; + + started = s.scene.started; +} + +void FrogPilotVehiclesPanel::updateCarToggles() { + auto carParams = params.get("CarParamsPersistent"); + if (!carParams.empty()) { + AlignedBuffer aligned_buf; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(carParams.data(), carParams.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + + auto carFingerprint = CP.getCarFingerprint(); + + hasExperimentalOpenpilotLongitudinal = CP.getExperimentalLongitudinalAvailable(); + hasOpenpilotLongitudinal = CP.getOpenpilotLongitudinalControl(); + hasSNG = CP.getMinEnableSpeed() <= 0; + isGMTruck = carFingerprint == "CHEVROLET SILVERADO 1500 2020"; + isImpreza = carFingerprint == "SUBARU IMPREZA LIMITED 2019"; + } else { + hasExperimentalOpenpilotLongitudinal = false; + hasOpenpilotLongitudinal = true; + hasSNG = false; + isGMTruck = true; + isImpreza = true; + } + + hideToggles(); +} + +void FrogPilotVehiclesPanel::setModels() { + models = getCarNames(carMake.toLower()); + hideToggles(); +} + +void FrogPilotVehiclesPanel::hideToggles() { + disableOpenpilotLong->setVisible(hasOpenpilotLongitudinal && !hasExperimentalOpenpilotLongitudinal && !params.getBool("HideDisableOpenpilotLongitudinal")); + + selectMakeButton->setValue(carMake); + selectModelButton->setValue(carModel); + selectModelButton->setVisible(!carMake.isEmpty()); + + bool gm = carMake == "Buick" || carMake == "Cadillac" || carMake == "Chevrolet" || carMake == "GM" || carMake == "GMC"; + bool subaru = carMake == "Subaru"; + bool toyota = carMake == "Lexus" || carMake == "Toyota"; + + std::set gmTruckKeys = {"GasRegenCmd"}; + std::set imprezaKeys = {"CrosstrekTorque"}; + std::set longitudinalKeys = {"GasRegenCmd", "ToyotaTune", "LongPitch", "SNGHack"}; + std::set sngKeys = {"SNGHack"}; + + for (auto &[key, toggle] : toggles) { + if (toggle) { + toggle->setVisible(false); + + if ((!hasOpenpilotLongitudinal || params.getBool("DisableOpenpilotLongitudinal")) && longitudinalKeys.find(key.c_str()) != longitudinalKeys.end()) { + continue; + } + + if (hasSNG && sngKeys.find(key.c_str()) != sngKeys.end()) { + continue; + } + + if (!isGMTruck && gmTruckKeys.find(key.c_str()) != gmTruckKeys.end()) { + continue; + } + + if (!isImpreza && imprezaKeys.find(key.c_str()) != imprezaKeys.end()) { + continue; + } + + if (gm) { + toggle->setVisible(gmKeys.find(key.c_str()) != gmKeys.end()); + } else if (subaru) { + toggle->setVisible(subaruKeys.find(key.c_str()) != subaruKeys.end()); + } else if (toyota) { + toggle->setVisible(toyotaKeys.find(key.c_str()) != toyotaKeys.end()); + } + } + } + + update(); +} diff --git a/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h b/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h new file mode 100644 index 0000000..d640536 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotVehiclesPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotVehiclesPanel(SettingsWindow *parent); + +private: + void hideToggles(); + void setModels(); + void updateCarToggles(); + void updateState(const UIState &s); + + ButtonControl *selectMakeButton; + ButtonControl *selectModelButton; + + ToggleControl *disableOpenpilotLong; + + QString carMake; + QString carModel; + + QStringList models; + + std::set gmKeys = {"GasRegenCmd", "LongPitch"}; + std::set subaruKeys = {"CrosstrekTorque"}; + std::set toyotaKeys = {"ClusterOffset", "ToyotaTune", "SNGHack", "ToyotaDoors"}; + + std::map toggles; + + Params params; + + bool hasExperimentalOpenpilotLongitudinal; + bool hasOpenpilotLongitudinal; + bool hasSNG; + bool isGMTruck; + bool isImpreza; + bool started; +}; diff --git a/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc new file mode 100644 index 0000000..ef5ffd5 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc @@ -0,0 +1,428 @@ +#include "selfdrive/frogpilot/ui/qt/offroad/visual_settings.h" + +FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + std::string branch = params.get("GitBranch"); + isRelease = branch == "FrogPilot"; + + const std::vector> visualToggles { + {"AlertVolumeControl", tr("Alert Volume Controller"), tr("Control the volume level for each individual sound in openpilot."), "../frogpilot/assets/toggle_icons/icon_mute.png"}, + {"DisengageVolume", tr("Disengage Volume"), tr("Related alerts:\n\nAdaptive Cruise Disabled\nParking Brake Engaged\nBrake Pedal Pressed\nSpeed too Low"), ""}, + {"EngageVolume", tr("Engage Volume"), tr("Related alerts:\n\nNNFF Torque Controller loaded\nopenpilot engaged"), ""}, + {"PromptVolume", tr("Prompt Volume"), tr("Related alerts:\n\nCar Detected in Blindspot\nSpeed too Low\nSteer Unavailable Below 'X'\nTake Control, Turn Exceeds Steering Limit"), ""}, + {"PromptDistractedVolume", tr("Prompt Distracted Volume"), tr("Related alerts:\n\nPay Attention, Driver Distracted\nTouch Steering Wheel, Driver Unresponsive"), ""}, + {"RefuseVolume", tr("Refuse Volume"), tr("Related alerts:\n\nopenpilot Unavailable"), ""}, + {"WarningSoftVolume", tr("Warning Soft Volume"), tr("Related alerts:\n\nBRAKE!, Risk of Collision\nTAKE CONTROL IMMEDIATELY"), ""}, + {"WarningImmediateVolume", tr("Warning Immediate Volume"), tr("Related alerts:\n\nDISENGAGE IMMEDIATELY, Driver Distracted\nDISENGAGE IMMEDIATELY, Driver Unresponsive"), ""}, + + {"CustomAlerts", tr("Custom Alerts"), tr("Enable custom alerts for openpilot events."), "../frogpilot/assets/toggle_icons/icon_green_light.png"}, + {"GreenLightAlert", tr("Green Light Alert"), tr("Get an alert when a traffic light changes from red to green."), ""}, + {"LeadDepartingAlert", tr("Lead Departing Alert"), tr("Get an alert when the lead vehicle starts departing when at a standstill."), ""}, + {"LoudBlindspotAlert", tr("Loud Blindspot Alert"), tr("Enable a louder alert for when a vehicle is detected in the blindspot when attempting to change lanes."), ""}, + + {"CustomUI", tr("Custom Onroad UI"), tr("Customize the Onroad UI."), "../assets/offroad/icon_road.png"}, + {"Compass", tr("Compass"), tr("Add a compass to the onroad UI."), ""}, + {"CustomPaths", tr("Paths"), tr("Show your projected acceleration on the driving path, detected adjacent lanes, or when a vehicle is detected in your blindspot."), ""}, + {"PedalsOnUI", tr("Pedals Being Pressed"), tr("Display the brake and gas pedals on the onroad UI below the steering wheel icon."), ""}, + {"RoadNameUI", tr("Road Name"), tr("Display the current road's name at the bottom of the screen. Sourced from OpenStreetMap."), ""}, + {"WheelIcon", tr("Steering Wheel Icon"), tr("Replace the default steering wheel icon with a custom icon."), ""}, + + {"CustomTheme", tr("Custom Themes"), tr("Enable the ability to use custom themes."), "../frogpilot/assets/wheel_images/frog.png"}, + {"CustomColors", tr("Color Theme"), tr("Switch out the standard openpilot color scheme with themed colors.\n\nWant to submit your own color scheme? Post it in the 'feature-request' channel in the FrogPilot Discord!"), ""}, + {"CustomIcons", tr("Icon Pack"), tr("Switch out the standard openpilot icons with a set of themed icons.\n\nWant to submit your own icon pack? Post it in the 'feature-request' channel in the FrogPilot Discord!"), ""}, + {"CustomSounds", tr("Sound Pack"), tr("Switch out the standard openpilot sounds with a set of themed sounds.\n\nWant to submit your own sound pack? Post it in the 'feature-request' channel in the FrogPilot Discord!"), ""}, + {"CustomSignals", tr("Turn Signals"), tr("Add themed animation for your turn signals.\n\nWant to submit your own turn signal animation? Post it in the 'feature-request' channel in the FrogPilot Discord!"), ""}, + {"HolidayThemes", tr("Holiday Themes"), tr("The openpilot theme changes according to the current/upcoming holiday. Minor holidays last a day, while major holidays (Easter, Christmas, Halloween, etc.) last a week."), ""}, + {"RandomEvents", tr("Random Events"), tr("Enjoy a bit of unpredictability with random events that can occur during certain driving conditions. This is purely cosmetic and has no impact on driving controls!"), ""}, + + {"DeveloperUI", tr("Developer UI"), tr("Get various detailed information of what openpilot is doing behind the scenes."), "../frogpilot/assets/toggle_icons/icon_device.png"}, + {"BorderMetrics", tr("Border Metrics"), tr("Display metrics in onroad UI border."), ""}, + {"FPSCounter", tr("FPS Counter"), tr("Display the 'Frames Per Second' (FPS) of your onroad UI for monitoring system performance."), ""}, + {"LateralMetrics", tr("Lateral Metrics"), tr("Display various metrics related to the lateral performance of openpilot."), ""}, + {"LongitudinalMetrics", tr("Longitudinal Metrics"), tr("Display various metrics related to the longitudinal performance of openpilot."), ""}, + {"NumericalTemp", tr("Numerical Temperature Gauge"), tr("Replace the 'GOOD', 'OK', and 'HIGH' temperature statuses with a numerical temperature gauge based on the highest temperature between the memory, CPU, and GPU."), ""}, + {"SidebarMetrics", tr("Sidebar"), tr("Display various custom metrics on the sidebar for the CPU, GPU, RAM, IP, and storage used/left."), ""}, + {"UseSI", tr("Use International System of Units"), tr("Display relevant metrics in the SI format."), ""}, + + {"ModelUI", tr("Model UI"), tr("Customize the model visualizations on the screen."), "../assets/offroad/icon_calibration.png"}, + {"DynamicPathWidth", tr("Dynamic Path Width"), tr("Have the path width dynamically adjust based on the current engagement state of openpilot."), ""}, + {"HideLeadMarker", tr("Hide Lead Marker"), tr("Hide the lead marker from the onroad UI."), ""}, + {"LaneLinesWidth", tr("Lane Lines"), tr("Adjust the visual thickness of lane lines on your display.\n\nDefault matches the MUTCD average of 4 inches."), ""}, + {"PathEdgeWidth", tr("Path Edges"), tr("Adjust the width of the path edges shown on your UI to represent different driving modes and statuses.\n\nDefault is 20% of the total path.\n\nBlue = Navigation\nLight Blue = 'Always On Lateral'\nGreen = Default\nOrange = 'Experimental Mode'\nRed = 'Traffic Mode'\nYellow = 'Conditional Experimental Mode' Overriden"), ""}, + {"PathWidth", tr("Path Width"), tr("Customize the width of the driving path shown on your UI.\n\nDefault matches the width of a 2019 Lexus ES 350."), ""}, + {"RoadEdgesWidth", tr("Road Edges"), tr("Adjust the visual thickness of road edges on your display.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches."), ""}, + {"UnlimitedLength", tr("'Unlimited' Road UI Length"), tr("Extend the display of the path, lane lines, and road edges out as far as the model can see."), ""}, + + {"QOLVisuals", tr("Quality of Life"), tr("Miscellaneous quality of life changes to improve your overall openpilot experience."), "../frogpilot/assets/toggle_icons/quality_of_life.png"}, + {"BigMap", tr("Big Map"), tr("Increase the size of the map in the onroad UI."), ""}, + {"CameraView", tr("Camera View"), tr("Choose your preferred camera view for the onroad UI. This is purely a visual change and doesn't impact how openpilot drives."), ""}, + {"DriverCamera", tr("Driver Camera On Reverse"), tr("Show the driver camera feed when in reverse."), ""}, + {"HideSpeed", tr("Hide Speed"), tr("Hide the speed indicator in the onroad UI. Additional toggle allows it to be hidden/shown via tapping the speed itself."), ""}, + {"MapStyle", tr("Map Style"), tr("Select a map style to use with navigation."), ""}, + {"WheelSpeed", tr("Use Wheel Speed"), tr("Use the wheel speed instead of the cluster speed in the onroad UI."), ""}, + + {"ScreenManagement", tr("Screen Management"), tr("Manage your screen's brightness, timeout settings, and hide onroad UI elements."), "../frogpilot/assets/toggle_icons/icon_light.png"}, + {"HideUIElements", tr("Hide UI Elements"), tr("Hide the selected UI elements from the onroad screen."), ""}, + {"ScreenBrightness", tr("Screen Brightness"), tr("Customize your screen brightness when offroad."), ""}, + {"ScreenBrightnessOnroad", tr("Screen Brightness (Onroad)"), tr("Customize your screen brightness when onroad."), ""}, + {"ScreenRecorder", tr("Screen Recorder"), tr("Enable the ability to record the screen while onroad."), ""}, + {"ScreenTimeout", tr("Screen Timeout"), tr("Customize how long it takes for your screen to turn off."), ""}, + {"ScreenTimeoutOnroad", tr("Screen Timeout (Onroad)"), tr("Customize how long it takes for your screen to turn off when onroad."), ""}, + {"StandbyMode", tr("Standby Mode"), tr("Turn the screen off after your screen times out when onroad, but wake it back up when engagement state changes or important alerts are triggered."), ""}, + }; + + for (const auto &[param, title, desc, icon] : visualToggles) { + AbstractControl *toggle; + + if (param == "AlertVolumeControl") { + FrogPilotParamManageControl *alertVolumeControlToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(alertVolumeControlToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(alertVolumeControlKeys.find(key.c_str()) != alertVolumeControlKeys.end()); + } + }); + toggle = alertVolumeControlToggle; + } else if (alertVolumeControlKeys.find(param) != alertVolumeControlKeys.end()) { + if (param == "WarningImmediateVolume") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 25, 100, std::map(), this, false, "%"); + } else { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map(), this, false, "%"); + } + + } else if (param == "CustomAlerts") { + FrogPilotParamManageControl *customAlertsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customAlertsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedCustomAlertsKeys = customAlertsKeys; + + if (!hasBSM) { + modifiedCustomAlertsKeys.erase("LoudBlindspotAlert"); + } + + toggle->setVisible(modifiedCustomAlertsKeys.find(key.c_str()) != modifiedCustomAlertsKeys.end()); + } + }); + toggle = customAlertsToggle; + + } else if (param == "CustomTheme") { + FrogPilotParamManageControl *customThemeToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customThemeToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + 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(tr("Do you want to enable the bonus 'Goat' sound effect?"), this)) { + params.putBoolNonBlocking("GoatScream", true); + } else { + params.putBoolNonBlocking("GoatScream", false); + } + } + }); + } + + } else if (param == "CustomUI") { + FrogPilotParamManageControl *customUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedCustomOnroadUIKeys = customOnroadUIKeys; + + if (!hasOpenpilotLongitudinal && !hasAutoTune) { + modifiedCustomOnroadUIKeys.erase("DeveloperUI"); + } + + toggle->setVisible(modifiedCustomOnroadUIKeys.find(key.c_str()) != modifiedCustomOnroadUIKeys.end()); + } + }); + toggle = customUIToggle; + } else if (param == "CustomPaths") { + std::vector pathToggles{"AccelerationPath", "AdjacentPath", "BlindSpotPath", "AdjacentPathMetrics"}; + std::vector pathToggleNames{tr("Acceleration"), tr("Adjacent"), tr("Blind Spot"), tr("Metrics")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, pathToggles, pathToggleNames); + } else if (param == "PedalsOnUI") { + std::vector pedalsToggles{"DynamicPedalsOnUI", "StaticPedalsOnUI"}; + std::vector pedalsToggleNames{tr("Dynamic"), tr("Static")}; + FrogPilotParamToggleControl *pedalsToggle = new FrogPilotParamToggleControl(param, title, desc, icon, pedalsToggles, pedalsToggleNames); + QObject::connect(pedalsToggle, &FrogPilotParamToggleControl::buttonTypeClicked, this, [this, pedalsToggle](int index) { + if (index == 0) { + params.putBool("StaticPedalsOnUI", false); + } else if (index == 1) { + params.putBool("DynamicPedalsOnUI", false); + } + + pedalsToggle->updateButtonStates(); + }); + toggle = pedalsToggle; + + } else if (param == "WheelIcon") { + std::vector wheelToggles{"RotatingWheel"}; + std::vector wheelToggleNames{"Live Rotation"}; + std::map steeringWheelLabels = {{-1, tr("None")}, {0, tr("Stock")}, {1, tr("Lexus")}, {2, tr("Toyota")}, {3, tr("Frog")}, {4, tr("Rocket")}, {5, tr("Hyundai")}, {6, tr("Stalin")}}; + toggle = new FrogPilotParamValueToggleControl(param, title, desc, icon, -1, 6, steeringWheelLabels, this, true, "", 1, 1, wheelToggles, wheelToggleNames); + + } else if (param == "DeveloperUI") { + FrogPilotParamManageControl *developerUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(developerUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedDeveloperUIKeys = developerUIKeys ; + + toggle->setVisible(modifiedDeveloperUIKeys.find(key.c_str()) != modifiedDeveloperUIKeys.end()); + } + }); + toggle = developerUIToggle; + } else if (param == "BorderMetrics") { + std::vector borderToggles{"BlindSpotMetrics", "ShowSteering", "SignalMetrics"}; + std::vector borderToggleNames{tr("Blind Spot"), tr("Steering Torque"), tr("Turn Signal"), }; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, borderToggles, borderToggleNames); + } else if (param == "NumericalTemp") { + std::vector temperatureToggles{"Fahrenheit"}; + std::vector temperatureToggleNames{tr("Fahrenheit")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, temperatureToggles, temperatureToggleNames); + } else if (param == "SidebarMetrics") { + std::vector sidebarMetricsToggles{"ShowCPU", "ShowGPU", "ShowIP", "ShowMemoryUsage", "ShowStorageLeft", "ShowStorageUsed"}; + std::vector sidebarMetricsToggleNames{tr("CPU"), tr("GPU"), tr("IP"), tr("RAM"), tr("SSD Left"), tr("SSD Used")}; + FrogPilotParamToggleControl *sidebarMetricsToggle = new FrogPilotParamToggleControl(param, title, desc, icon, sidebarMetricsToggles, sidebarMetricsToggleNames, this, 125); + QObject::connect(sidebarMetricsToggle, &FrogPilotParamToggleControl::buttonTypeClicked, this, [this, sidebarMetricsToggle](int index) { + if (index == 0) { + params.putBool("ShowGPU", false); + } else if (index == 1) { + params.putBool("ShowCPU", false); + } else if (index == 3) { + params.putBool("ShowStorageLeft", false); + params.putBool("ShowStorageUsed", false); + } else if (index == 4) { + params.putBool("ShowMemoryUsage", false); + params.putBool("ShowStorageUsed", false); + } else if (index == 5) { + params.putBool("ShowMemoryUsage", false); + params.putBool("ShowStorageLeft", false); + } + + sidebarMetricsToggle->updateButtonStates(); + }); + toggle = sidebarMetricsToggle; + + } else if (param == "ModelUI") { + FrogPilotParamManageControl *modelUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(modelUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + std::set modifiedModelUIKeysKeys = modelUIKeys; + + if (!hasOpenpilotLongitudinal) { + modifiedModelUIKeysKeys.erase("HideLeadMarker"); + } + + toggle->setVisible(modifiedModelUIKeysKeys.find(key.c_str()) != modifiedModelUIKeysKeys.end()); + } + }); + toggle = modelUIToggle; + } else if (param == "LaneLinesWidth" || param == "RoadEdgesWidth") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 24, std::map(), this, false, tr(" inches")); + } else if (param == "PathEdgeWidth") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map(), this, false, tr("%")); + } else if (param == "PathWidth") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map(), this, false, tr(" feet"), 10); + + } else if (param == "QOLVisuals") { + FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end()); + } + }); + toggle = qolToggle; + } else if (param == "CameraView") { + std::vector cameraOptions{tr("Auto"), tr("Driver"), tr("Standard"), tr("Wide")}; + FrogPilotButtonParamControl *preferredCamera = new FrogPilotButtonParamControl(param, title, desc, icon, cameraOptions); + toggle = preferredCamera; + } else if (param == "BigMap") { + std::vector mapToggles{"FullMap"}; + std::vector mapToggleNames{tr("Full Map")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, mapToggles, mapToggleNames); + } else if (param == "HideSpeed") { + std::vector hideSpeedToggles{"HideSpeedUI"}; + std::vector hideSpeedToggleNames{tr("Control Via UI")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, hideSpeedToggles, hideSpeedToggleNames); + } else if (param == "MapStyle") { + QMap styleMap = { + {0, tr("Stock openpilot")}, + {1, tr("Mapbox Streets")}, + {2, tr("Mapbox Outdoors")}, + {3, tr("Mapbox Light")}, + {4, tr("Mapbox Dark")}, + {5, tr("Mapbox Satellite")}, + {6, tr("Mapbox Satellite Streets")}, + {7, tr("Mapbox Navigation Day")}, + {8, tr("Mapbox Navigation Night")}, + {9, tr("Mapbox Traffic Night")}, + {10, tr("mike854's (Satellite hybrid)")}, + }; + + QStringList styles = styleMap.values(); + ButtonControl *mapStyleButton = new ButtonControl(title, tr("SELECT"), desc); + QObject::connect(mapStyleButton, &ButtonControl::clicked, [=]() { + QStringList styles = styleMap.values(); + QString selection = MultiOptionDialog::getSelection(tr("Select a map style"), styles, "", this); + if (!selection.isEmpty()) { + int selectedStyle = styleMap.key(selection); + params.putIntNonBlocking("MapStyle", selectedStyle); + mapStyleButton->setValue(selection); + updateFrogPilotToggles(); + } + }); + + int currentStyle = params.getInt("MapStyle"); + mapStyleButton->setValue(styleMap[currentStyle]); + + toggle = mapStyleButton; + + } else if (param == "ScreenManagement") { + FrogPilotParamManageControl *screenToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(screenToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + openParentToggle(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(screenKeys.find(key.c_str()) != screenKeys.end()); + } + }); + toggle = screenToggle; + } else if (param == "HideUIElements") { + std::vector uiElementsToggles{"HideAlerts", "HideMapIcon", "HideMaxSpeed"}; + std::vector uiElementsToggleNames{tr("Alerts"), tr("Map Icon"), tr("Max Speed")}; + toggle = new FrogPilotParamToggleControl(param, title, desc, icon, uiElementsToggles, uiElementsToggleNames); + } else if (param == "ScreenBrightness" || param == "ScreenBrightnessOnroad") { + std::map brightnessLabels; + if (param == "ScreenBrightnessOnroad") { + for (int i = 0; i <= 101; i++) { + brightnessLabels[i] = (i == 0) ? tr("Screen Off") : (i == 101) ? tr("Auto") : QString::number(i) + "%"; + } + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 101, brightnessLabels, this, false); + } else { + for (int i = 1; i <= 101; i++) { + brightnessLabels[i] = (i == 101) ? tr("Auto") : QString::number(i) + "%"; + } + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 101, brightnessLabels, this, false); + } + } else if (param == "ScreenTimeout" || param == "ScreenTimeoutOnroad") { + toggle = new FrogPilotParamValueControl(param, title, desc, icon, 5, 60, std::map(), this, false, tr(" seconds")); + + } else { + toggle = new ParamControl(param, title, desc, icon, this); + } + + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(static_cast(toggle), &ToggleControl::toggleFlipped, &updateFrogPilotToggles); + QObject::connect(static_cast(toggle), &FrogPilotParamValueControl::valueChanged, &updateFrogPilotToggles); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() { + update(); + }); + } + + QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotVisualsPanel::hideToggles); + QObject::connect(parent, &SettingsWindow::updateMetric, this, &FrogPilotVisualsPanel::updateMetric); + QObject::connect(uiState(), &UIState::offroadTransition, this, &FrogPilotVisualsPanel::updateCarToggles); + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVisualsPanel::updateState); + + updateMetric(); +} + +void FrogPilotVisualsPanel::showEvent(QShowEvent *event) { + hasOpenpilotLongitudinal = hasOpenpilotLongitudinal && !params.getBool("DisableOpenpilotLongitudinal"); +} + +void FrogPilotVisualsPanel::updateState(const UIState &s) { + if (!isVisible()) return; + + started = s.scene.started; +} + +void FrogPilotVisualsPanel::updateCarToggles() { + auto carParams = params.get("CarParamsPersistent"); + if (!carParams.empty()) { + AlignedBuffer aligned_buf; + capnp::FlatArrayMessageReader cmsg(aligned_buf.align(carParams.data(), carParams.size())); + cereal::CarParams::Reader CP = cmsg.getRoot(); + auto carName = CP.getCarName(); + + hasAutoTune = (carName == "hyundai" || carName == "toyota") && CP.getLateralTuning().which() == cereal::CarParams::LateralTuning::TORQUE; + hasBSM = CP.getEnableBsm(); + hasOpenpilotLongitudinal = CP.getOpenpilotLongitudinalControl() && !params.getBool("DisableOpenpilotLongitudinal"); + } else { + hasBSM = true; + hasOpenpilotLongitudinal = true; + } + + hideToggles(); +} + +void FrogPilotVisualsPanel::updateMetric() { + bool previousIsMetric = isMetric; + isMetric = params.getBool("IsMetric"); + + if (isMetric != previousIsMetric) { + double distanceConversion = isMetric ? INCH_TO_CM : CM_TO_INCH; + double speedConversion = isMetric ? FOOT_TO_METER : METER_TO_FOOT; + params.putIntNonBlocking("LaneLinesWidth", std::nearbyint(params.getInt("LaneLinesWidth") * distanceConversion)); + params.putIntNonBlocking("RoadEdgesWidth", std::nearbyint(params.getInt("RoadEdgesWidth") * distanceConversion)); + params.putIntNonBlocking("PathWidth", std::nearbyint(params.getInt("PathWidth") * speedConversion)); + } + + FrogPilotParamValueControl *laneLinesWidthToggle = static_cast(toggles["LaneLinesWidth"]); + FrogPilotParamValueControl *roadEdgesWidthToggle = static_cast(toggles["RoadEdgesWidth"]); + FrogPilotParamValueControl *pathWidthToggle = static_cast(toggles["PathWidth"]); + + if (isMetric) { + laneLinesWidthToggle->setDescription(tr("Customize the lane line width.\n\nDefault matches the Vienna average of 10 centimeters.")); + roadEdgesWidthToggle->setDescription(tr("Customize the road edges width.\n\nDefault is 1/2 of the Vienna average lane line width of 10 centimeters.")); + + laneLinesWidthToggle->updateControl(0, 60, tr(" centimeters")); + roadEdgesWidthToggle->updateControl(0, 60, tr(" centimeters")); + pathWidthToggle->updateControl(0, 30, tr(" meters"), 10); + } else { + laneLinesWidthToggle->setDescription(tr("Customize the lane line width.\n\nDefault matches the MUTCD average of 4 inches.")); + roadEdgesWidthToggle->setDescription(tr("Customize the road edges width.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.")); + + laneLinesWidthToggle->updateControl(0, 24, tr(" inches")); + roadEdgesWidthToggle->updateControl(0, 24, tr(" inches")); + pathWidthToggle->updateControl(0, 100, tr(" feet"), 10); + } + + laneLinesWidthToggle->refresh(); + roadEdgesWidthToggle->refresh(); +} + +void FrogPilotVisualsPanel::hideToggles() { + for (auto &[key, toggle] : toggles) { + bool subToggles = alertVolumeControlKeys.find(key.c_str()) != alertVolumeControlKeys.end() || + customAlertsKeys.find(key.c_str()) != customAlertsKeys.end() || + customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() || + customThemeKeys.find(key.c_str()) != customThemeKeys.end() || + developerUIKeys.find(key.c_str()) != developerUIKeys.end() || + modelUIKeys.find(key.c_str()) != modelUIKeys.end() || + qolKeys.find(key.c_str()) != qolKeys.end() || + screenKeys.find(key.c_str()) != screenKeys.end(); + toggle->setVisible(!subToggles); + } + + update(); +} diff --git a/selfdrive/frogpilot/ui/qt/offroad/visual_settings.h b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.h new file mode 100644 index 0000000..98076a6 --- /dev/null +++ b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotVisualsPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotVisualsPanel(SettingsWindow *parent); + +signals: + void openParentToggle(); + +private: + void hideToggles(); + void showEvent(QShowEvent *event); + void updateCarToggles(); + void updateMetric(); + void updateState(const UIState &s); + + std::set alertVolumeControlKeys = {"DisengageVolume", "EngageVolume", "PromptDistractedVolume", "PromptVolume", "RefuseVolume", "WarningImmediateVolume", "WarningSoftVolume"}; + std::set customAlertsKeys = {"GreenLightAlert", "LeadDepartingAlert", "LoudBlindspotAlert"}; + std::set customOnroadUIKeys = {"Compass", "CustomPaths", "PedalsOnUI", "RoadNameUI", "WheelIcon"}; + std::set customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds", "HolidayThemes", "RandomEvents"}; + std::set developerUIKeys = {"BorderMetrics", "FPSCounter", "LateralMetrics", "LongitudinalMetrics", "NumericalTemp", "SidebarMetrics", "UseSI"}; + std::set modelUIKeys = {"DynamicPathWidth", "HideLeadMarker", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"}; + std::set qolKeys = {"BigMap", "CameraView", "DriverCamera", "FullMap", "HideSpeed", "MapStyle", "WheelSpeed"}; + std::set screenKeys = {"HideUIElements", "ScreenBrightness", "ScreenBrightnessOnroad", "ScreenRecorder", "ScreenTimeout", "ScreenTimeoutOnroad", "StandbyMode"}; + + std::map toggles; + + Params params; + + bool hasAutoTune; + bool hasBSM; + bool hasOpenpilotLongitudinal; + bool isMetric = params.getBool("IsMetric"); + bool isRelease; + bool started; +}; diff --git a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc index 771e6c8..de18052 100644 --- a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc +++ b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc @@ -1,3 +1,5 @@ +#include + #include "selfdrive/ui/ui.h" Params paramsMemory{"/dev/shm/params"}; @@ -9,3 +11,41 @@ void updateFrogPilotToggles() { paramsMemory.putBool("FrogPilotTogglesUpdated", false); }).detach(); } + +bool FrogPilotConfirmationDialog::toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, confirm_text, tr("Reboot Later"), false, parent); + return d.exec(); +} + +bool FrogPilotConfirmationDialog::toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, button_text, "", false, parent); + return d.exec(); +} + +bool FrogPilotConfirmationDialog::yesorno(const QString &prompt_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Yes"), tr("No"), false, parent); + return d.exec(); +} + +FrogPilotButtonIconControl::FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc, const QString &icon, QWidget *parent) : AbstractControl(title, desc, icon, parent) { + btn.setText(text); + btn.setStyleSheet(R"( + QPushButton { + padding: 0; + border-radius: 50px; + font-size: 35px; + font-weight: 500; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"); + btn.setFixedSize(250, 100); + QObject::connect(&btn, &QPushButton::clicked, this, &FrogPilotButtonIconControl::clicked); + hlayout->addWidget(&btn); +} diff --git a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h index 3364551..a1e1011 100644 --- a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h +++ b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h @@ -1,3 +1,708 @@ #pragma once +#include + +#include + +#include "selfdrive/ui/qt/widgets/controls.h" + void updateFrogPilotToggles(); + +class FrogPilotConfirmationDialog : public ConfirmationDialog { + Q_OBJECT + +public: + explicit FrogPilotConfirmationDialog(const QString &prompt_text, const QString &confirm_text, + const QString &cancel_text, const bool rich, QWidget *parent); + static bool toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent); + static bool toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent); + static bool yesorno(const QString &prompt_text, QWidget *parent); +}; + +class FrogPilotListWidget : public QWidget { + Q_OBJECT +public: + explicit FrogPilotListWidget(QWidget *parent = nullptr) : QWidget(parent), outer_layout(this) { + outer_layout.setMargin(0); + outer_layout.setSpacing(0); + outer_layout.addLayout(&inner_layout); + inner_layout.setMargin(0); + inner_layout.setSpacing(25); // default spacing is 25 + } + + inline void addItem(QWidget *w) { + inner_layout.addWidget(w); + adjustStretch(); + } + + inline void addItem(QLayout *layout) { + inner_layout.addLayout(layout); + adjustStretch(); + } + + inline void setSpacing(int spacing) { + inner_layout.setSpacing(spacing); + adjustStretch(); + } + +private: + void adjustStretch() { + if (inner_layout.stretch(inner_layout.count() - 1) > 0) { + inner_layout.setStretch(inner_layout.count() - 1, 0); + } + if (inner_layout.count() > 3) { + outer_layout.addStretch(); + } + } + + void paintEvent(QPaintEvent *event) override { + QPainter p(this); + p.setPen(Qt::gray); + + int visibleWidgetCount = 0; + std::vector visibleRects; + + for (int i = 0; i < inner_layout.count(); ++i) { + QWidget *widget = inner_layout.itemAt(i)->widget(); + if (widget && widget->isVisible()) { + visibleWidgetCount++; + visibleRects.push_back(inner_layout.itemAt(i)->geometry()); + } + } + + for (int i = 0; i < visibleWidgetCount - 1; ++i) { + int bottom = visibleRects[i].bottom() + inner_layout.spacing() / 2; + p.drawLine(visibleRects[i].left() + 40, bottom, visibleRects[i].right() - 40, bottom); + } + } + + QVBoxLayout outer_layout; + QVBoxLayout inner_layout; +}; + +class FrogPilotDualParamControl : public QFrame { + Q_OBJECT + +public: + FrogPilotDualParamControl(ParamControl *control1, ParamControl *control2, QWidget *parent = nullptr, bool split=false) + : QFrame(parent) { + QHBoxLayout *hlayout = new QHBoxLayout(this); + + control1->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + control1->setMaximumWidth(split ? 850 : 700); + + control2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + control2->setMaximumWidth(split ? 700 : 850); + + hlayout->addWidget(control1); + hlayout->addWidget(control2); + } +}; + +class FrogPilotButtonControl : public AbstractControl { + Q_OBJECT + +public: + FrogPilotButtonControl(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr); + inline void setText(const QString &text) { btn.setText(text); } + inline QString text() const { return btn.text(); } + +signals: + void clicked(); + +public slots: + void setEnabled(bool enabled) { btn.setEnabled(enabled); } + +private: + QPushButton btn; +}; + +class FrogPilotButtonIconControl : public AbstractControl { + Q_OBJECT + +public: + FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); + inline void setText(const QString &text) { btn.setText(text); } + inline QString text() const { return btn.text(); } + +signals: + void clicked(); + +public slots: + void setEnabled(bool enabled) { btn.setEnabled(enabled); } + +private: + QPushButton btn; +}; + +class FrogPilotButtonParamControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const std::vector &button_texts, const int minimum_button_width = 225) + : ParamControl(param, title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + key = param.toStdString(); + int value = atoi(params.get(key).c_str()); + + button_group = new QButtonGroup(this); + button_group->setExclusive(true); + for (size_t i = 0; i < button_texts.size(); i++) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setChecked(i == value); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + hlayout->addWidget(button); + button_group->addButton(button, i); + } + + QObject::connect(button_group, QOverload::of(&QButtonGroup::buttonToggled), [=](int id, bool checked) { + if (checked) { + params.put(key, std::to_string(id)); + refresh(); + emit buttonClicked(id); + } + }); + + toggle.hide(); + } + + void setEnabled(bool enable) { + for (auto btn : button_group->buttons()) { + btn->setEnabled(enable); + } + } + +signals: + void buttonClicked(int id); + +private: + std::string key; + Params params; + QButtonGroup *button_group; +}; + +class FrogPilotButtonsControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonsControl(const QString &title, const QString &desc, const QString &icon, + const std::vector &button_texts, const int minimum_button_width = 225) + : ParamControl("", title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height: 100px; + padding: 0 25px 0 25px; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + + for (size_t i = 0; i < button_texts.size(); i++) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + hlayout->addWidget(button); + button_group->addButton(button, static_cast(i)); + + connect(button, &QPushButton::clicked, this, [this, i]() { + emit buttonClicked(static_cast(i)); + }); + } + + toggle.hide(); + } + +signals: + void buttonClicked(int id); + +private: + QButtonGroup *button_group; +}; + +class FrogPilotButtonsParamControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonsParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const std::vector> &button_params) + : ParamControl(param, title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(true); + + for (const auto ¶m_pair : button_params) { + const QString ¶m_toggle = param_pair.first; + const QString &button_text = param_pair.second; + + QPushButton *button = new QPushButton(button_text, this); + button->setCheckable(true); + + bool value = params.getBool(param_toggle.toStdString()); + button->setChecked(value); + button->setStyleSheet(style); + button->setMinimumWidth(225); + hlayout->addWidget(button); + + QObject::connect(button, &QPushButton::toggled, this, [=](bool checked) { + if (checked) { + for (const auto &inner_param_pair : button_params) { + const QString &inner_param = inner_param_pair.first; + params.putBool(inner_param.toStdString(), inner_param == param_toggle); + } + refresh(); + emit buttonClicked(); + } + }); + + button_group->addButton(button); + } + + toggle.hide(); + } + + void setEnabled(bool enable) { + for (auto btn : button_group->buttons()) { + btn->setEnabled(enable); + } + } + +signals: + void buttonClicked(); + +private: + Params params; + QButtonGroup *button_group; +}; + +class FrogPilotParamManageControl : public ParamControl { + Q_OBJECT + +public: + FrogPilotParamManageControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr, bool hideToggle = false) + : ParamControl(param, title, desc, icon, parent), + hideToggle(hideToggle), + key(param.toStdString()), + manageButton(new ButtonControl(tr(""), tr("MANAGE"), tr(""))) { + hlayout->insertWidget(hlayout->indexOf(&toggle) - 1, manageButton); + + connect(this, &ToggleControl::toggleFlipped, this, [this](bool state) { + refresh(); + }); + + connect(manageButton, &ButtonControl::clicked, this, &FrogPilotParamManageControl::manageButtonClicked); + + if (hideToggle) { + toggle.hide(); + } + } + + void refresh() { + ParamControl::refresh(); + manageButton->setVisible(params.getBool(key) || hideToggle); + } + + void setEnabled(bool enabled) { + manageButton->setEnabled(enabled); + toggle.setEnabled(enabled); + toggle.update(); + } + + void showEvent(QShowEvent *event) override { + ParamControl::showEvent(event); + refresh(); + } + +signals: + void manageButtonClicked(); + +private: + bool hideToggle; + std::string key; + Params params; + ButtonControl *manageButton; +}; + +class FrogPilotParamToggleControl : public ParamControl { + Q_OBJECT +public: + FrogPilotParamToggleControl(const QString ¶m, const QString &title, const QString &desc, + const QString &icon, const std::vector &button_params, + const std::vector &button_texts, QWidget *parent = nullptr, + const int minimum_button_width = 225) + : ParamControl(param, title, desc, icon, parent) { + + key = param.toStdString(); + + connect(this, &ToggleControl::toggleFlipped, this, [this](bool state) { + refreshButtons(state); + }); + + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(false); + this->button_params = button_params; + + for (int i = 0; i < button_texts.size(); ++i) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + button_group->addButton(button, i); + + connect(button, &QPushButton::clicked, [this, i](bool checked) { + params.putBool(this->button_params[i].toStdString(), checked); + button_group->button(i)->setChecked(checked); + emit buttonClicked(checked); + emit buttonTypeClicked(i); + }); + + hlayout->insertWidget(hlayout->indexOf(&toggle) - 1, button); + } + } + + void refresh() { + bool state = params.getBool(key); + if (state != toggle.on) { + toggle.togglePosition(); + } + + refreshButtons(state); + updateButtonStates(); + } + + void refreshButtons(bool state) { + for (QAbstractButton *button : button_group->buttons()) { + button->setVisible(state); + } + } + + void updateButtonStates() { + for (int i = 0; i < button_group->buttons().size(); ++i) { + bool checked = params.getBool(button_params[i].toStdString()); + QAbstractButton *button = button_group->button(i); + if (button) { + button->setChecked(checked); + } + } + } + + void showEvent(QShowEvent *event) override { + refresh(); + QWidget::showEvent(event); + } + +signals: + void buttonClicked(const bool checked); + void buttonTypeClicked(int i); + +private: + std::string key; + Params params; + QButtonGroup *button_group; + std::vector button_params; +}; + +class FrogPilotParamValueControl : public ParamControl { + Q_OBJECT + +public: + FrogPilotParamValueControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const float &minValue, const float &maxValue, const std::map &valueLabels, + QWidget *parent = nullptr, const bool &loop = true, const QString &label = "", + const float &division = 1.0f, const float &interval = 1.0f) + : ParamControl(param, title, desc, icon, parent), + minValue(minValue), maxValue(maxValue), valueLabelMappings(valueLabels), loop(loop), labelText(label), + division(division), interval(interval), previousValue(0.0f), value(0.0f) { + key = param.toStdString(); + + valueLabel = new QLabel(this); + hlayout->addWidget(valueLabel); + + QPushButton *decrementButton = createButton("-", this); + QPushButton *incrementButton = createButton("+", this); + + hlayout->addWidget(decrementButton); + hlayout->addWidget(incrementButton); + + countdownTimer = new QTimer(this); + countdownTimer->setInterval(150); + countdownTimer->setSingleShot(true); + + connect(countdownTimer, &QTimer::timeout, this, &FrogPilotParamValueControl::handleTimeout); + + connect(decrementButton, &QPushButton::pressed, this, [=]() { updateValue(-interval); }); + connect(incrementButton, &QPushButton::pressed, this, [=]() { updateValue(interval); }); + + connect(decrementButton, &QPushButton::released, this, &FrogPilotParamValueControl::restartTimer); + connect(incrementButton, &QPushButton::released, this, &FrogPilotParamValueControl::restartTimer); + + toggle.hide(); + } + + void restartTimer() { + countdownTimer->stop(); + countdownTimer->start(); + + emit valueChanged(value); + } + + void handleTimeout() { + previousValue = value; + } + + void updateValue(float intervalChange) { + int previousValueAdjusted = round(previousValue * 100) / 100 / intervalChange; + int valueAdjusted = round(value * 100) / 100 / intervalChange; + + if (std::fabs(previousValueAdjusted - valueAdjusted) > 5 && std::fmod(valueAdjusted, 5) == 0) { + intervalChange *= 5; + } + + value += intervalChange; + + if (loop) { + if (value < minValue) { + value = maxValue; + } else if (value > maxValue) { + value = minValue; + } + } else { + value = std::max(minValue, std::min(maxValue, value)); + } + + params.putFloat(key, value); + refresh(); + } + + void refresh() { + value = params.getFloat(key); + + QString text; + auto it = valueLabelMappings.find(value); + int decimals = interval < 1.0f ? static_cast(-std::log10(interval)) : 2; + + if (division > 1.0f) { + text = QString::number(value / division, 'g', division >= 10.0f ? 4 : 3); + } else { + if (it != valueLabelMappings.end()) { + text = it->second; + } else { + if (value >= 100.0f) { + text = QString::number(value, 'f', 0); + } else { + text = QString::number(value, interval < 1.0f ? 'f' : 'g', decimals); + } + } + } + + if (!labelText.isEmpty()) { + text += labelText; + } + + valueLabel->setText(text); + valueLabel->setStyleSheet("QLabel { color: #E0E879; }"); + } + + void updateControl(float newMinValue, float newMaxValue, const QString &newLabel, float newDivision = 1.0f) { + minValue = newMinValue; + maxValue = newMaxValue; + labelText = newLabel; + division = newDivision; + } + + void showEvent(QShowEvent *event) override { + refresh(); + previousValue = value; + } + +signals: + void valueChanged(float value); + +private: + Params params; + + bool loop; + + float division; + float interval; + float maxValue; + float minValue; + float previousValue; + float value; + + QLabel *valueLabel; + QString labelText; + + std::map valueLabelMappings; + std::string key; + + QTimer *countdownTimer; + + QPushButton *createButton(const QString &text, QWidget *parent) { + QPushButton *button = new QPushButton(text, parent); + button->setFixedSize(150, 100); + button->setAutoRepeat(true); + button->setAutoRepeatInterval(150); + button->setAutoRepeatDelay(500); + button->setStyleSheet(R"( + QPushButton { + border-radius: 50px; + font-size: 50px; + font-weight: 500; + height: 100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + )"); + return button; + } +}; + +class FrogPilotParamValueToggleControl : public FrogPilotParamValueControl { + Q_OBJECT + +public: + FrogPilotParamValueToggleControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const float &minValue, const float &maxValue, const std::map &valueLabels, + QWidget *parent = nullptr, const bool &loop = true, const QString &label = "", + const float &division = 1.0f, const float &interval = 1.0f, + const std::vector &button_params = std::vector(), const std::vector &button_texts = std::vector(), + const int minimum_button_width = 225) + : FrogPilotParamValueControl(param, title, desc, icon, minValue, maxValue, valueLabels, parent, loop, label, division, interval) { + + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height: 100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(false); + + for (int i = 0; i < button_texts.size(); ++i) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setChecked(params.getBool(button_params[i].toStdString())); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + button_group->addButton(button, i); + + connect(button, &QPushButton::clicked, [this, button_params, i](bool checked) { + params.putBool(button_params[i].toStdString(), checked); + emit buttonClicked(); + refresh(); + }); + + buttons[button_params[i]] = button; + hlayout->insertWidget(3, button); + } + } + + void refresh() { + FrogPilotParamValueControl::refresh(); + + auto keys = buttons.keys(); + for (const QString ¶m : keys) { + QPushButton *button = buttons.value(param); + button->setChecked(params.getBool(param.toStdString())); + } + } + +signals: + void buttonClicked(); + +private: + Params params; + QButtonGroup *button_group; + QMap buttons; +}; diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index ea5734f..bff18d6 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -23,7 +23,10 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc", "qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc", - "qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"] + "qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc", + "../frogpilot/ui/qt/widgets/frogpilot_controls.cc", + "../frogpilot/ui/qt/offroad/control_settings.cc", "../frogpilot/ui/qt/offroad/vehicle_settings.cc", + "../frogpilot/ui/qt/offroad/visual_settings.cc"] qt_env['CPPDEFINES'] = [] if maps: diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index bc7989b..b7d83e8 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -7,6 +7,7 @@ #include #include +#include #include "selfdrive/ui/qt/network/networking.h" @@ -23,6 +24,10 @@ #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" +#include "selfdrive/frogpilot/ui/qt/offroad/control_settings.h" +#include "selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.h" +#include "selfdrive/frogpilot/ui/qt/offroad/visual_settings.h" + TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { // param, title, desc, icon std::vector> toggle_defs{ @@ -122,6 +127,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { connect(toggles["ExperimentalLongitudinalEnabled"], &ToggleControl::toggleFlipped, [=]() { updateToggles(); }); + + connect(toggles["IsMetric"], &ToggleControl::toggleFlipped, [=]() { + updateMetric(); + }); } void TogglesPanel::updateState(const UIState &s) { @@ -345,6 +354,16 @@ void DevicePanel::poweroff() { } } +void SettingsWindow::hideEvent(QHideEvent *event) { + closeParentToggle(); + + parentToggleOpen = false; + subParentToggleOpen = false; + subSubParentToggleOpen = false; + + previousScrollPosition = 0; +} + void SettingsWindow::showEvent(QShowEvent *event) { setCurrentPanel(0); } @@ -381,7 +400,20 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { close_btn->setFixedSize(200, 200); sidebar_layout->addSpacing(45); sidebar_layout->addWidget(close_btn, 0, Qt::AlignCenter); - QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindow::closeSettings); + QObject::connect(close_btn, &QPushButton::clicked, [this]() { + if (subSubParentToggleOpen) { + closeSubSubParentToggle(); + subSubParentToggleOpen = false; + } else if (subParentToggleOpen) { + closeSubParentToggle(); + subParentToggleOpen = false; + } else if (parentToggleOpen) { + closeParentToggle(); + parentToggleOpen = false; + } else { + closeSettings(); + } + }); // setup panels DevicePanel *device = new DevicePanel(this); @@ -390,12 +422,24 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { TogglesPanel *toggles = new TogglesPanel(this); QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription); + QObject::connect(toggles, &TogglesPanel::updateMetric, this, &SettingsWindow::updateMetric); + + FrogPilotControlsPanel *frogpilotControls = new FrogPilotControlsPanel(this); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openParentToggle, this, [this]() {parentToggleOpen=true;}); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openSubParentToggle, this, [this]() {subParentToggleOpen=true;}); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openSubSubParentToggle, this, [this]() {subSubParentToggleOpen=true;}); + + FrogPilotVisualsPanel *frogpilotVisuals = new FrogPilotVisualsPanel(this); + QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::openParentToggle, this, [this]() {parentToggleOpen=true;}); QList> panels = { {tr("Device"), device}, {tr("Network"), new Networking(this)}, {tr("Toggles"), toggles}, {tr("Software"), new SoftwarePanel(this)}, + {tr("Controls"), frogpilotControls}, + {tr("Vehicles"), new FrogPilotVehiclesPanel(this)}, + {tr("Visuals"), frogpilotVisuals}, }; nav_btns = new QButtonGroup(this); @@ -428,7 +472,25 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { ScrollView *panel_frame = new ScrollView(panel, this); panel_widget->addWidget(panel_frame); + if (name == tr("Controls") || name == tr("Visuals")) { + QScrollBar *scrollbar = panel_frame->verticalScrollBar(); + + QObject::connect(scrollbar, &QScrollBar::valueChanged, this, [this](int value) { + if (!parentToggleOpen) { + previousScrollPosition = value; + } + }); + + QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() { + if (!parentToggleOpen) { + panel_frame->restorePosition(previousScrollPosition); + } + }); + } + QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() { + closeParentToggle(); + previousScrollPosition = 0; btn->setChecked(true); panel_widget->setCurrentWidget(w); }); diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index cf27f83..01fa1dc 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -26,17 +26,33 @@ public: protected: void showEvent(QShowEvent *event) override; + // FrogPilot widgets + void hideEvent(QHideEvent *event) override; + signals: void closeSettings(); void reviewTrainingGuide(); void showDriverView(); void expandToggleDescription(const QString ¶m); + // FrogPilot signals + void closeParentToggle(); + void closeSubParentToggle(); + void closeSubSubParentToggle(); + void updateMetric(); + private: QPushButton *sidebar_alert_widget; QWidget *sidebar_widget; QButtonGroup *nav_btns; QStackedWidget *panel_widget; + + // FrogPilot variables + bool parentToggleOpen; + bool subParentToggleOpen; + bool subSubParentToggleOpen; + + int previousScrollPosition; }; class DevicePanel : public ListWidget { @@ -62,6 +78,10 @@ public: explicit TogglesPanel(SettingsWindow *parent); void showEvent(QShowEvent *event) override; +signals: + // FrogPilot signals + void updateMetric(); + public slots: void expandToggleDescription(const QString ¶m); diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index aa304e0..4a2c7f3 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -132,6 +132,10 @@ public: toggle.update(); } + void refresh() { + toggle.togglePosition(); + } + signals: void toggleFlipped(bool state); diff --git a/selfdrive/ui/qt/widgets/scrollview.cc b/selfdrive/ui/qt/widgets/scrollview.cc index 978bf83..2846007 100644 --- a/selfdrive/ui/qt/widgets/scrollview.cc +++ b/selfdrive/ui/qt/widgets/scrollview.cc @@ -44,6 +44,10 @@ ScrollView::ScrollView(QWidget *w, QWidget *parent) : QScrollArea(parent) { scroller->setScrollerProperties(sp); } +void ScrollView::restorePosition(int previousScrollPosition) { + verticalScrollBar()->setValue(previousScrollPosition); +} + void ScrollView::hideEvent(QHideEvent *e) { verticalScrollBar()->setValue(0); } diff --git a/selfdrive/ui/qt/widgets/scrollview.h b/selfdrive/ui/qt/widgets/scrollview.h index 024331a..51acc4c 100644 --- a/selfdrive/ui/qt/widgets/scrollview.h +++ b/selfdrive/ui/qt/widgets/scrollview.h @@ -7,6 +7,10 @@ class ScrollView : public QScrollArea { public: explicit ScrollView(QWidget *w = nullptr, QWidget *parent = nullptr); + + // FrogPilot functions + void restorePosition(int previousScrollPosition); + protected: void hideEvent(QHideEvent *e) override; }; diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index ce6245e..c58affa 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -218,6 +218,7 @@ static void update_state(UIState *s) { } if (sm.updated("deviceState")) { auto deviceState = sm["deviceState"].getDeviceState(); + scene.online = deviceState.getNetworkType() != cereal::DeviceState::NetworkType::NONE; } if (sm.updated("frogpilotCarControl")) { auto frogpilotCarControl = sm["frogpilotCarControl"].getFrogpilotCarControl();