This commit is contained in:
Your Name
2024-02-17 18:36:29 -06:00
parent a75f80af27
commit cf322c6e67
5 changed files with 58 additions and 236 deletions

View File

@@ -1,137 +1,15 @@
#include "selfdrive/oscarpilot/settings/basic.h" #include "selfdrive/oscarpilot/settings/basic.h"
#include "selfdrive/ui/ui.h" #include "selfdrive/ui/ui.h"
OscarPilotVisualsPanel::OscarPilotVisualsPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) { OscarPilotBasicPanel::OscarPilotBasicPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) {
const std::vector<std::tuple<QString, QString, QString, QString>> visualToggles { const std::vector<std::tuple<QString, QString, QString, QString>> visualToggles {
{"CustomTheme", "Custom Themes", "Enable the ability to use custom themes.", "../frogpilot/assets/wheel_images/frog.png"}, {"HelloWorld", "Hello World", "Hi!", "../frogpilot/assets/wheel_images/frog.png"},
{"CustomColors", "Color Theme", "Switch out the standard openpilot color scheme with a custom color scheme.\n\nWant to submit your own color scheme? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
{"CustomIcons", "Icon Pack", "Switch out the standard openpilot icons with a set of custom icons.\n\nWant to submit your own icon pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
{"CustomSignals", "Turn Signals", "Add custom animations for your turn signals for a personal touch!\n\nWant to submit your own turn signal animation? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
{"CustomSounds", "Sound Pack", "Switch out the standard openpilot sounds with a set of custom sounds.\n\nWant to submit your own sound pack? Post it in the 'feature-request' channel in the FrogPilot Discord!", ""},
{"CameraView", "Camera View", "Choose your preferred camera view for the onroad UI. This is a visual change only and doesn't impact openpilot.", "../frogpilot/assets/toggle_icons/icon_camera.png"},
{"Compass", "Compass", "Add a compass to your onroad UI.", "../frogpilot/assets/toggle_icons/icon_compass.png"},
{"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"},
{"AdjacentPath", "Adjacent Paths", "Display paths to the left and right of your car, visualizing where the model detects lanes.", ""},
{"BlindSpotPath", "Blind Spot Path", "Visualize your blind spots with a red path when another vehicle is detected nearby.", ""},
{"ShowFPS", "FPS Counter", "Display the Frames Per Second (FPS) of your onroad UI for monitoring system performance.", ""},
{"LeadInfo", "Lead Info and Logics", "Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance.", ""},
{"RoadNameUI", "Road Name", "See the name of the road you're on at the bottom of your screen. Sourced from OpenStreetMap.", ""},
{"UseVienna", "Use Vienna Speed Limit Signs", "Use the Vienna (EU) speed limit style signs as opposed to MUTCD (US).", ""},
{"DriverCamera", "Driver Camera On Reverse", "Show the driver's camera feed when you shift to reverse.", "../assets/img_driver_face_static.png"},
{"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", "../frogpilot/assets/toggle_icons/icon_green_light.png"},
{"ModelUI", "Model UI", "Personalize how the model's visualizations appear on your screen.", "../assets/offroad/icon_calibration.png"},
{"AccelerationPath", "Acceleration Path", "Visualize the car's intended acceleration or deceleration with a color-coded path.", ""},
{"LaneLinesWidth", "Lane Lines", "Adjust the visual thickness of lane lines on your display.\n\nDefault matches the MUTCD average of 4 inches.", ""},
{"PathEdgeWidth", "Path Edges", "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 with 'FrogPilot Colors'\nLight Green = Default with stock colors\nOrange = Experimental Mode Active\nYellow = Conditional Overriden", ""},
{"PathWidth", "Path Width", "Customize the width of the driving path shown on your UI.\n\nDefault matches the width of a 2019 Lexus ES 350.", ""},
{"RoadEdgesWidth", "Road Edges", "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", "'Unlimited' Road UI Length", "Extend the display of the path, lane lines, and road edges as far as the system can detect, providing a more expansive view of the road ahead.", ""},
{"QOLVisuals", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"},
{"DriveStats", "Drive Stats In Home Screen", "Display your device's drive stats in the home screen.", ""},
{"HideSpeed", "Hide Speed", "Hide the speed indicator in the onroad UI.", ""},
{"ShowSLCOffset", "Show Speed Limit Offset", "Show the speed limit offset seperated from the speed limit in the onroad UI when using 'Speed Limit Controller'.", ""},
{"RandomEvents", "Random Events", "Enjoy a bit of unpredictability with random events that can occur during certain driving conditions.", "../frogpilot/assets/toggle_icons/icon_random.png"},
{"ScreenBrightness", "Screen Brightness", "Customize your screen brightness.", "../frogpilot/assets/toggle_icons/icon_light.png"},
{"SilentMode", "Silent Mode", "Mute openpilot sounds for a quieter driving experience.", "../frogpilot/assets/toggle_icons/icon_mute.png"},
{"WheelIcon", "Steering Wheel Icon", "Replace the default steering wheel icon with a custom design, adding a unique touch to your interface.", "../assets/offroad/icon_openpilot.png"},
}; };
for (const auto &[param, title, desc, icon] : visualToggles) { for (const auto &[param, title, desc, icon] : visualToggles) {
ParamControl *toggle; ParamControl *toggle;
if (param == "CameraView") { toggle = new ParamControl(param, title, desc, icon, this);
std::vector<QString> cameraOptions{tr("Auto"), tr("Standard"), tr("Wide"), tr("Driver")};
FrogPilotButtonParamControl *preferredCamera = new FrogPilotButtonParamControl(param, title, desc, icon, cameraOptions);
toggle = preferredCamera;
} else if (param == "CustomTheme") {
FrogPilotParamManageControl *customThemeToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(customThemeToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(customThemeKeys.find(key.c_str()) != customThemeKeys.end());
}
});
toggle = customThemeToggle;
} else if (param == "CustomColors" || param == "CustomIcons" || param == "CustomSignals" || param == "CustomSounds") {
std::vector<QString> 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<FrogPilotButtonParamControl*>(toggle), &FrogPilotButtonParamControl::buttonClicked, [this](int id) {
if (id == 1) {
if (FrogPilotConfirmationDialog::yesorno("Do you want to enable the bonus 'Goat' sound effect?", this)) {
params.putBool("GoatScream", true);
} else {
params.putBool("GoatScream", false);
}
}
});
}
} else if (param == "CustomUI") {
FrogPilotParamManageControl *customUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(customUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end());
}
});
toggle = customUIToggle;
} else if (param == "LeadInfo") {
std::vector<QString> leadInfoToggles{tr("UseSI")};
std::vector<QString> leadInfoToggleNames{tr("Use SI Values")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, leadInfoToggles, leadInfoToggleNames);
} else if (param == "ModelUI") {
FrogPilotParamManageControl *modelUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(modelUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(modelUIKeys.find(key.c_str()) != modelUIKeys.end());
}
});
toggle = modelUIToggle;
} else if (param == "LaneLinesWidth" || param == "RoadEdgesWidth") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 24, std::map<int, QString>(), this, false, " inches");
} else if (param == "PathEdgeWidth") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, "%");
} else if (param == "PathWidth") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, " feet", 10);
} else if (param == "QOLVisuals") {
FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end());
}
});
toggle = qolToggle;
} else if (param == "ScreenBrightness") {
std::map<int, QString> brightnessLabels;
for (int i = 0; i <= 101; ++i) {
brightnessLabels[i] = i == 0 ? "Screen Off" : i == 101 ? "Auto" : QString::number(i) + "%";
}
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 101, brightnessLabels, this, false);
} else if (param == "WheelIcon") {
std::vector<QString> wheelToggles{"RotatingWheel"};
std::vector<QString> wheelToggleNames{tr("Rotating")};
std::map<int, QString> steeringWheelLabels = {{0, "Stock"}, {1, "Lexus"}, {2, "Toyota"}, {3, "Frog"}, {4, "Rocket"}, {5, "Hyundai"}, {6, "Stalin"}};
toggle = new FrogPilotParamValueToggleControl(param, title, desc, icon, 0, 6, steeringWheelLabels, this, true, "", 1, wheelToggles, wheelToggleNames);
} else {
toggle = new ParamControl(param, title, desc, icon, this);
}
addItem(toggle); addItem(toggle);
toggles[param.toStdString()] = toggle; toggles[param.toStdString()] = toggle;
@@ -153,26 +31,14 @@ OscarPilotVisualsPanel::OscarPilotVisualsPanel(OscarSettingsWindow *parent) : Fr
}); });
} }
std::set<std::string> rebootKeys = {"DriveStats"}; // std::set<std::string> rebootKeys = {"DriveStats"};
for (const std::string &key : rebootKeys) { // for (const std::string &key : rebootKeys) {
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() { // QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { // if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
Hardware::reboot(); // Hardware::reboot();
} // }
}); // });
} // }
customOnroadUIKeys = {"AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI", "UseVienna"};
customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"};
modelUIKeys = {"AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"};
qolKeys = {"DriveStats", "HideSpeed", "ShowSLCOffset"};
QObject::connect(device(), &Device::interactiveTimeout, this, &OscarPilotVisualsPanel::hideSubToggles);
QObject::connect(parent, &OscarSettingsWindow::closeParentToggle, this, &OscarPilotVisualsPanel::hideSubToggles);
// QObject::connect(parent, &OscarSettingsWindow::updateMetric, this, &OscarPilotVisualsPanel::updateMetric);
hideSubToggles();
// updateMetric();
} }
void OscarPilotVisualsPanel::updateToggles() { void OscarPilotVisualsPanel::updateToggles() {
@@ -183,94 +49,18 @@ void OscarPilotVisualsPanel::updateToggles() {
}).detach(); }).detach();
} }
// void OscarPilotVisualsPanel::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.putInt("LaneLinesWidth", std::nearbyint(params.getInt("LaneLinesWidth") * distanceConversion));
// params.putInt("RoadEdgesWidth", std::nearbyint(params.getInt("RoadEdgesWidth") * distanceConversion));
// params.putInt("PathWidth", std::nearbyint(params.getInt("PathWidth") * speedConversion));
// }
// FrogPilotParamValueControl *laneLinesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["LaneLinesWidth"]);
// FrogPilotParamValueControl *roadEdgesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["RoadEdgesWidth"]);
// FrogPilotParamValueControl *pathWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["PathWidth"]);
// if (isMetric) {
// laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the Vienna average of 10 centimeters.");
// roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the Vienna average lane line width of 10 centimeters.");
// laneLinesWidthToggle->updateControl(0, 60, " centimeters");
// roadEdgesWidthToggle->updateControl(0, 60, " centimeters");
// pathWidthToggle->updateControl(0, 30, " meters");
// } else {
// laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the MUTCD average of 4 inches.");
// roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.");
// laneLinesWidthToggle->updateControl(0, 24, " inches");
// roadEdgesWidthToggle->updateControl(0, 24, " inches");
// pathWidthToggle->updateControl(0, 100, " feet");
// }
// laneLinesWidthToggle->refresh();
// roadEdgesWidthToggle->refresh();
// previousIsMetric = isMetric;
// }
// void OscarPilotVisualsPanel::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.putInt("LaneLinesWidth", std::nearbyint(params.getInt("LaneLinesWidth") * distanceConversion));
// params.putInt("RoadEdgesWidth", std::nearbyint(params.getInt("RoadEdgesWidth") * distanceConversion));
// params.putInt("PathWidth", std::nearbyint(params.getInt("PathWidth") * speedConversion));
// }
// FrogPilotParamValueControl *laneLinesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["LaneLinesWidth"]);
// FrogPilotParamValueControl *roadEdgesWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["RoadEdgesWidth"]);
// FrogPilotParamValueControl *pathWidthToggle = static_cast<FrogPilotParamValueControl*>(toggles["PathWidth"]);
// if (isMetric) {
// laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the Vienna average of 10 centimeters.");
// roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the Vienna average lane line width of 10 centimeters.");
// laneLinesWidthToggle->updateControl(0, 60, " centimeters");
// roadEdgesWidthToggle->updateControl(0, 60, " centimeters");
// pathWidthToggle->updateControl(0, 30, " meters");
// } else {
// laneLinesWidthToggle->setDescription("Customize the lane line width.\n\nDefault matches the MUTCD average of 4 inches.");
// roadEdgesWidthToggle->setDescription("Customize the road edges width.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.");
// laneLinesWidthToggle->updateControl(0, 24, " inches");
// roadEdgesWidthToggle->updateControl(0, 24, " inches");
// pathWidthToggle->updateControl(0, 100, " feet");
// }
// laneLinesWidthToggle->refresh();
// roadEdgesWidthToggle->refresh();
// previousIsMetric = isMetric;
// }
void OscarPilotVisualsPanel::parentToggleClicked() { void OscarPilotVisualsPanel::parentToggleClicked() {
this->openParentToggle(); this->openParentToggle();
} }
void OscarPilotVisualsPanel::hideSubToggles() { void OscarPilotVisualsPanel::hideSubToggles() {
for (auto &[key, toggle] : toggles) { // for (auto &[key, toggle] : toggles) {
bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() || // bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() ||
customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() || // customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() ||
customThemeKeys.find(key.c_str()) != customThemeKeys.end() || // customThemeKeys.find(key.c_str()) != customThemeKeys.end() ||
qolKeys.find(key.c_str()) != qolKeys.end(); // qolKeys.find(key.c_str()) != qolKeys.end();
toggle->setVisible(!subToggles); // toggle->setVisible(!subToggles);
} // }
this->closeParentToggle(); this->closeParentToggle();
} }

View File

@@ -5,11 +5,11 @@
#include "selfdrive/frogpilot/ui/frogpilot_functions.h" #include "selfdrive/frogpilot/ui/frogpilot_functions.h"
#include "selfdrive/oscarpilot/settings/settings.h" #include "selfdrive/oscarpilot/settings/settings.h"
class OscarPilotVisualsPanel : public FrogPilotListWidget { class OscarPilotBasicPanel : public FrogPilotListWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit OscarPilotVisualsPanel(OscarSettingsWindow *parent); explicit OscarPilotBasicPanel(OscarSettingsWindow *parent);
signals: signals:
void closeParentToggle(); void closeParentToggle();
@@ -19,13 +19,9 @@ private:
void hideEvent(QHideEvent *event); void hideEvent(QHideEvent *event);
void hideSubToggles(); void hideSubToggles();
void parentToggleClicked(); void parentToggleClicked();
void updateMetric();
void updateToggles(); void updateToggles();
std::set<QString> customOnroadUIKeys; std::set<QString> customOnroadUIKeys;
std::set<QString> customThemeKeys;
std::set<QString> modelUIKeys;
std::set<QString> qolKeys;
std::map<std::string, ParamControl*> toggles; std::map<std::string, ParamControl*> toggles;

View File

@@ -0,0 +1,36 @@
#pragma once
#include <set>
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
#include "selfdrive/oscarpilot/settings/settings.h"
class OscarPilotVisualsPanel : public FrogPilotListWidget {
Q_OBJECT
public:
explicit OscarPilotVisualsPanel(OscarSettingsWindow *parent);
signals:
void closeParentToggle();
void openParentToggle();
private:
void hideEvent(QHideEvent *event);
void hideSubToggles();
void parentToggleClicked();
void updateMetric();
void updateToggles();
std::set<QString> customOnroadUIKeys;
std::set<QString> customThemeKeys;
std::set<QString> modelUIKeys;
std::set<QString> qolKeys;
std::map<std::string, ParamControl*> toggles;
Params params;
Params paramsMemory{"/dev/shm/params"};
bool isMetric = params.getBool("IsMetric");
};

View File

@@ -82,11 +82,11 @@ OscarSettingsWindow::OscarSettingsWindow(QWidget *parent) : QFrame(parent) {
// QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView); // QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView);
QList<QPair<QString, QWidget *>> panels = { QList<QPair<QString, QWidget *>> panels = {
// {tr("Basic"), basic}, {tr("Basic"), new OscarPilotBasicPanel(this)},
// {tr("Software"), new SoftwarePanel(this)}, // {tr("Software"), new SoftwarePanel(this)},
// {tr("Advanced"), basic}, // {tr("Advanced"), basic},
// {tr("Logging"), basic}, // Log / Upload driver cam, Routes // {tr("Logging"), basic}, // Log / Upload driver cam, Routes
{tr("System"), new OscarPilotVisualsPanel(this)}, // Debugging // {tr("System"), new OscarPilotVisualsPanel(this)}, // Debugging
// {tr("Status"), basic}, // Report on stuff like connectivity, free space, detected features // {tr("Status"), basic}, // Report on stuff like connectivity, free space, detected features
// {tr("Extra"), basic}, // Custom cloud services, QOL automations // {tr("Extra"), basic}, // Custom cloud services, QOL automations
}; };