wip
This commit is contained in:
1
scp/settings/advanced.cc
Normal file
1
scp/settings/advanced.cc
Normal file
@@ -0,0 +1 @@
|
||||
// Should show a UI showing the settings menu for stock frogpilot
|
||||
0
scp/settings/advanced.h
Normal file
0
scp/settings/advanced.h
Normal file
149
scp/settings/basic.cc
Normal file
149
scp/settings/basic.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "selfdrive/oscarpilot/settings/basic.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
OscarPilotBasicPanel::OscarPilotBasicPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) {
|
||||
|
||||
const std::vector<std::tuple<QString, QString, QString, QString>> visualToggles {
|
||||
// {"HelloWorld", "Hello World", "Hi!", "../frogpilot/assets/wheel_images/frog.png"},
|
||||
{
|
||||
"OpenpilotEnabledToggle","Enable OpenPilot",
|
||||
"Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.",
|
||||
"../assets/offroad/icon_openpilot.png",
|
||||
},
|
||||
{
|
||||
"AlwaysOnLateral", "Always on Lateral",
|
||||
"Maintain openpilot lateral control when the brake pedal is used.\n\nDeactivation occurs only through the 'Cruise Control' button.", "../frogpilot/assets/toggle_icons/icon_always_on_lateral.png"
|
||||
},
|
||||
{"VisionTurnControl", "Vision Turn Speed Controller", "Slow down for detected road curvature for smoother curve handling.", "../frogpilot/assets/toggle_icons/icon_vtc.png"},
|
||||
|
||||
// {
|
||||
// "ConditionalExperimental", "Slow for curves",
|
||||
// "Engages 'experimental mode' when a curve is detected, temporairly reducing max speed.", "../frogpilot/assets/toggle_icons/icon_conditional.png"
|
||||
// },
|
||||
// Alert on stopsign / stoplight
|
||||
|
||||
{"LaneChangeAssist", "Lane Change Assist", "Automatically change lanes on turn signal and wheel nudge at highway speeds.", "../frogpilot/assets/toggle_icons/icon_lane.png"},
|
||||
{"HyundaiLKAS", "Use Hyundai LKAS when available", "Let the Hyundai LKAS feature steer the car when lanes are detected and HDA mode is available.", ""},
|
||||
{"FireTheBabysitter", "Relaxed Driver Monitoring", "Increases driver attention warning timeout from 6 to 15 seconds during the daytime and when no lead car is detected.", ""},
|
||||
// - Hands On Wheel: Always / At Dusk / 2+ hrs driving
|
||||
|
||||
// Move this to dashcam subgroup
|
||||
//{"DashCam", "Dash Cam Recording", "Record video and gps data for all drives automatically.", ""}
|
||||
};
|
||||
|
||||
for (const auto &[param, title, desc, icon] : visualToggles) {
|
||||
ParamControl *toggle;
|
||||
|
||||
toggle = new ParamControl(param, title, desc, icon, this);
|
||||
|
||||
addItem(toggle);
|
||||
toggles[param.toStdString()] = toggle;
|
||||
|
||||
QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamValueControl*>(toggle), &FrogPilotParamValueControl::buttonPressed, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamManageControl*>(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() {
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
// std::set<std::string> rebootKeys = {"DriveStats"};
|
||||
// for (const std::string &key : rebootKeys) {
|
||||
// QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
|
||||
// if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||
// Hardware::reboot();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// power buttons
|
||||
QHBoxLayout *power_layout = new QHBoxLayout();
|
||||
power_layout->setSpacing(30);
|
||||
|
||||
QPushButton *reboot_btn = new QPushButton(tr("Reboot"));
|
||||
reboot_btn->setObjectName("reboot_btn");
|
||||
power_layout->addWidget(reboot_btn);
|
||||
QObject::connect(reboot_btn, &QPushButton::clicked, this, &OscarPilotBasicPanel::reboot);
|
||||
|
||||
QPushButton *poweroff_btn = new QPushButton(tr("Power Off"));
|
||||
poweroff_btn->setObjectName("poweroff_btn");
|
||||
power_layout->addWidget(poweroff_btn);
|
||||
QObject::connect(poweroff_btn, &QPushButton::clicked, this, &OscarPilotBasicPanel::poweroff);
|
||||
|
||||
if (!Hardware::PC()) {
|
||||
connect(uiState(), &UIState::offroadTransition, poweroff_btn, &QPushButton::setVisible);
|
||||
}
|
||||
|
||||
setStyleSheet(R"(
|
||||
#reboot_btn { height: 120px; border-radius: 15px; background-color: #393939; }
|
||||
#reboot_btn:pressed { background-color: #4a4a4a; }
|
||||
#poweroff_btn { height: 120px; border-radius: 15px; background-color: #E22C2C; }
|
||||
#poweroff_btn:pressed { background-color: #FF2424; }
|
||||
)");
|
||||
addItem(power_layout);
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::updateToggles() {
|
||||
std::thread([this]() {
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", true);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", false);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::parentToggleClicked() {
|
||||
this->openParentToggle();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::hideSubToggles() {
|
||||
// for (auto &[key, toggle] : toggles) {
|
||||
// bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() ||
|
||||
// customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() ||
|
||||
// customThemeKeys.find(key.c_str()) != customThemeKeys.end() ||
|
||||
// qolKeys.find(key.c_str()) != qolKeys.end();
|
||||
// toggle->setVisible(!subToggles);
|
||||
// }
|
||||
|
||||
this->closeParentToggle();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::hideEvent(QHideEvent *event) {
|
||||
hideSubToggles();
|
||||
}
|
||||
|
||||
|
||||
void OscarPilotBasicPanel::reboot() {
|
||||
if (!uiState()->engaged()) {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to reboot?"), tr("Reboot"), this)) {
|
||||
// Check engaged again in case it changed while the dialog was open
|
||||
if (!uiState()->engaged()) {
|
||||
params.putBool("DoReboot", true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ConfirmationDialog::alert(tr("Disengage to Reboot"), this);
|
||||
}
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::poweroff() {
|
||||
if (!uiState()->engaged()) {
|
||||
if (ConfirmationDialog::confirm(tr("Are you sure you want to power off?"), tr("Power Off"), this)) {
|
||||
// Check engaged again in case it changed while the dialog was open
|
||||
if (!uiState()->engaged()) {
|
||||
params.putBool("DoShutdown", true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ConfirmationDialog::alert(tr("Disengage to Power Off"), this);
|
||||
}
|
||||
}
|
||||
280
scp/settings/basic.example
Normal file
280
scp/settings/basic.example
Normal file
@@ -0,0 +1,280 @@
|
||||
#include "selfdrive/oscarpilot/settings/basic.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
OscarPilotBasicPanel::OscarPilotBasicPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) {
|
||||
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"},
|
||||
{"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) {
|
||||
ParamControl *toggle;
|
||||
|
||||
if (param == "CameraView") {
|
||||
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);
|
||||
toggles[param.toStdString()] = toggle;
|
||||
|
||||
QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamValueControl*>(toggle), &FrogPilotParamValueControl::buttonPressed, [this]() {
|
||||
updateToggles();
|
||||
});
|
||||
|
||||
QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
|
||||
QObject::connect(static_cast<FrogPilotParamManageControl*>(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() {
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
std::set<std::string> rebootKeys = {"DriveStats"};
|
||||
for (const std::string &key : rebootKeys) {
|
||||
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
|
||||
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
||||
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, &OscarPilotBasicPanel::hideSubToggles);
|
||||
QObject::connect(parent, &OscarSettingsWindow::closeParentToggle, this, &OscarPilotBasicPanel::hideSubToggles);
|
||||
// QObject::connect(parent, &OscarSettingsWindow::updateMetric, this, &OscarPilotBasicPanel::updateMetric);
|
||||
|
||||
hideSubToggles();
|
||||
// updateMetric();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::updateToggles() {
|
||||
std::thread([this]() {
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", true);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
paramsMemory.putBool("FrogPilotTogglesUpdated", false);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
// void OscarPilotBasicPanel::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 OscarPilotBasicPanel::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 OscarPilotBasicPanel::parentToggleClicked() {
|
||||
this->openParentToggle();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::hideSubToggles() {
|
||||
for (auto &[key, toggle] : toggles) {
|
||||
bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() ||
|
||||
customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() ||
|
||||
customThemeKeys.find(key.c_str()) != customThemeKeys.end() ||
|
||||
qolKeys.find(key.c_str()) != qolKeys.end();
|
||||
toggle->setVisible(!subToggles);
|
||||
}
|
||||
|
||||
this->closeParentToggle();
|
||||
}
|
||||
|
||||
void OscarPilotBasicPanel::hideEvent(QHideEvent *event) {
|
||||
hideSubToggles();
|
||||
}
|
||||
34
scp/settings/basic.h
Normal file
34
scp/settings/basic.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/oscarpilot/settings/settings.h"
|
||||
|
||||
class OscarPilotBasicPanel : public FrogPilotListWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OscarPilotBasicPanel(OscarSettingsWindow *parent);
|
||||
|
||||
signals:
|
||||
void closeParentToggle();
|
||||
void openParentToggle();
|
||||
|
||||
private:
|
||||
void hideEvent(QHideEvent *event);
|
||||
void hideSubToggles();
|
||||
void parentToggleClicked();
|
||||
void updateToggles();
|
||||
void poweroff();
|
||||
void reboot();
|
||||
|
||||
std::set<QString> customOnroadUIKeys;
|
||||
|
||||
std::map<std::string, ParamControl*> toggles;
|
||||
|
||||
Params params;
|
||||
Params paramsMemory{"/dev/shm/params"};
|
||||
|
||||
bool isMetric = params.getBool("IsMetric");
|
||||
};
|
||||
36
scp/settings/basic.h.example
Normal file
36
scp/settings/basic.h.example
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/oscarpilot/settings/settings.h"
|
||||
|
||||
class OscarPilotBasicPanel : public FrogPilotListWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OscarPilotBasicPanel(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");
|
||||
};
|
||||
177
scp/settings/defaults.cc
Normal file
177
scp/settings/defaults.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void setDefaultParams() {
|
||||
Params params = Params();
|
||||
bool FrogsGoMoo = params.get("DongleId").substr(0, 3) == "be6";
|
||||
|
||||
bool brianbot = params.get("DongleId").substr(0, 6) == "90bb71";
|
||||
|
||||
std::map<std::string, std::string> defaultValues {
|
||||
{"AccelerationPath", brianbot ? "1" : "0"},
|
||||
{"AccelerationProfile", brianbot ? "2" : "2"},
|
||||
{"AdjacentPath", FrogsGoMoo ? "1" : "0"},
|
||||
{"AdjustablePersonalities", "0"},
|
||||
{"AggressiveAcceleration", "1"},
|
||||
{"AggressiveFollow", FrogsGoMoo ? "10" : "12"},
|
||||
{"AggressiveJerk", FrogsGoMoo ? "6" : "5"},
|
||||
{"AlwaysOnLateral", "1"},
|
||||
{"AlwaysOnLateralMain", brianbot ? "1" : "0"},
|
||||
{"AverageCurvature", brianbot ? "1" : "0"},
|
||||
{"BlindSpotPath", "1"},
|
||||
{"CameraView", FrogsGoMoo ? "1" : "0"},
|
||||
{"CECurves", "1"},
|
||||
{"CECurvesLead", "0"},
|
||||
{"CENavigation", "1"},
|
||||
{"CESignal", "1"},
|
||||
{"CESlowerLead", "0"},
|
||||
{"CESpeed", "0"},
|
||||
{"CESpeedLead", "0"},
|
||||
{"CEStopLights", "0"},
|
||||
{"CEStopLightsLead", FrogsGoMoo ? "0" : "0"},
|
||||
{"Compass", FrogsGoMoo ? "1" : "0"},
|
||||
{"ConditionalExperimental", "1"},
|
||||
{"CurveSensitivity", FrogsGoMoo ? "125" : "100"},
|
||||
{"CustomColors", "1"},
|
||||
{"CustomIcons", "1"},
|
||||
{"CustomPersonalities", "0"},
|
||||
{"CustomSignals", "0"},
|
||||
{"CustomSounds", "1"},
|
||||
{"CustomTheme", "1"},
|
||||
{"CustomUI", "0"},
|
||||
{"DeviceShutdown", "1"},
|
||||
{"DisableOnroadUploads", "1"},
|
||||
{"DriverCamera", "0"},
|
||||
{"DriveStats", "1"},
|
||||
{"EVTable", FrogsGoMoo ? "0" : "1"},
|
||||
{"ExperimentalModeActivation", "1"},
|
||||
{"ExperimentalModeViaLKAS", "0"},
|
||||
{"ExperimentalModeViaScreen", FrogsGoMoo ? "0" : "1"},
|
||||
{"Fahrenheit", "0"},
|
||||
{"FireTheBabysitter", FrogsGoMoo ? "1" : "0"},
|
||||
{"FullMap", "0"},
|
||||
{"GasRegenCmd", "0"},
|
||||
{"GoatScream", "0"},
|
||||
{"GreenLightAlert", "0"},
|
||||
{"HideSpeed", "0"},
|
||||
{"HigherBitrate", "0"},
|
||||
{"LaneChangeTime", "0"},
|
||||
{"LaneDetection", "1"},
|
||||
{"LaneLinesWidth", "4"},
|
||||
{"LateralTune", "1"},
|
||||
{"LeadInfo", FrogsGoMoo ? "1" : "0"},
|
||||
{"LockDoors", "0"},
|
||||
{"LongitudinalTune", "1"},
|
||||
{"LongPitch", FrogsGoMoo ? "0" : "1"},
|
||||
{"LowerVolt", FrogsGoMoo ? "0" : "1"},
|
||||
{"Model", "3"},
|
||||
{"ModelUI", "1"},
|
||||
{"MTSCEnabled", "1"},
|
||||
{"MuteDM", FrogsGoMoo ? "1" : "1"},
|
||||
{"MuteDoor", FrogsGoMoo ? "1" : "1"},
|
||||
{"MuteOverheated", FrogsGoMoo ? "1" : "0"},
|
||||
{"MuteSeatbelt", FrogsGoMoo ? "1" : "0"},
|
||||
{"NNFF", FrogsGoMoo ? "1" : "1"},
|
||||
{"NoLogging", "1"},
|
||||
{"NudgelessLaneChange", "0"},
|
||||
{"NumericalTemp", FrogsGoMoo ? "1" : "0"},
|
||||
{"Offset1", "3"},
|
||||
{"Offset2", FrogsGoMoo ? "7" : "5"},
|
||||
{"Offset3", "7"},
|
||||
{"Offset4", FrogsGoMoo ? "20" : "7"},
|
||||
{"OneLaneChange", "1"},
|
||||
{"PathEdgeWidth", "20"},
|
||||
{"PathWidth", "61"},
|
||||
{"PauseLateralOnSignal", "20"},
|
||||
{"PreferredSchedule", "0"},
|
||||
{"QOLControls", "1"},
|
||||
{"QOLVisuals", "1"},
|
||||
{"RandomEvents", FrogsGoMoo ? "1" : "0"},
|
||||
{"RelaxedFollow", "30"},
|
||||
{"RelaxedJerk", "50"},
|
||||
{"ReverseCruise", "0"},
|
||||
{"RoadEdgesWidth", "2"},
|
||||
{"RoadNameUI", "1"},
|
||||
{"RotatingWheel", "1"},
|
||||
{"ScreenBrightness", "101"},
|
||||
{"SearchInput", "0"},
|
||||
{"ShowCPU", FrogsGoMoo ? "1" : "0"},
|
||||
{"ShowFPS", FrogsGoMoo ? "1" : "0"},
|
||||
{"ShowGPU", "0"},
|
||||
{"ShowMemoryUsage", FrogsGoMoo ? "1" : "0"},
|
||||
{"Sidebar", FrogsGoMoo ? "1" : "0"},
|
||||
{"SilentMode", "0"},
|
||||
{"SLCFallback", "2"},
|
||||
{"SLCOverride", FrogsGoMoo ? "2" : "1"},
|
||||
{"SLCPriority", "1"},
|
||||
{"SmoothBraking", "1"},
|
||||
{"SNGHack", FrogsGoMoo ? "0" : "1"},
|
||||
{"SpeedLimitController", "1"},
|
||||
{"StandardFollow", "15"},
|
||||
{"StandardJerk", "10"},
|
||||
{"StoppingDistance", FrogsGoMoo ? "6" : "0"},
|
||||
{"TSS2Tune", "1"},
|
||||
{"TurnAggressiveness", FrogsGoMoo ? "150" : "100"}, // Test 90?
|
||||
{"TurnDesires", "0"},
|
||||
{"UnlimitedLength", "1"},
|
||||
{"UseSI", FrogsGoMoo ? "1" : "0"},
|
||||
{"UseVienna", "0"},
|
||||
{"VisionTurnControl", "1"},
|
||||
{"WheelIcon", FrogsGoMoo ? "1" : "0"}
|
||||
};
|
||||
|
||||
bool rebootRequired = false;
|
||||
for (const auto &[key, value] : defaultValues) {
|
||||
if (params.get(key).empty()) {
|
||||
params.put(key, value);
|
||||
rebootRequired = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebootRequired) {
|
||||
while (!std::filesystem::exists("/data/openpilot/prebuilt")) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
Hardware::reboot();
|
||||
}
|
||||
}
|
||||
0
scp/settings/defaults.h
Normal file
0
scp/settings/defaults.h
Normal file
38
scp/settings/newmenus
Normal file
38
scp/settings/newmenus
Normal file
@@ -0,0 +1,38 @@
|
||||
Device
|
||||
Network & Services
|
||||
- Standard Wifi
|
||||
- Metered Wifi
|
||||
- SSH
|
||||
- Web companion
|
||||
- Route logging
|
||||
- Dashcam upload
|
||||
- Live driver monitoring / fleet mgr
|
||||
- Weather
|
||||
- Display alerts
|
||||
- API key
|
||||
- Random facts
|
||||
- Get random fact about area driver is in (spoken, ai)
|
||||
Basic
|
||||
- Enable openpilot / Dashcam only
|
||||
- Always on Lateral: True / False
|
||||
- Longitudial Control scheme: Stock / Stock+SLC / OpenPilot
|
||||
- Experimental Mode: never / on curves / always
|
||||
- Longitudial Control scheme: Stock / Stock+SLC / Experimental
|
||||
- Speed Limit offset customization:
|
||||
- Lane Change Assist: Disabled / Nudge Wheel
|
||||
- Driver Attention Monitoring: Strict / Relaxed
|
||||
- Hands On Wheel: Always / At Dusk / 2+ hrs driving
|
||||
Advanced
|
||||
Navigation
|
||||
Customization
|
||||
Extras
|
||||
- Window down notification
|
||||
- Set climate on drive mode
|
||||
|
||||
Fleet Mgr Notes:
|
||||
- Seperate fork for fleet mgr
|
||||
- Self drive preferences
|
||||
- Distance traveled
|
||||
- SLC
|
||||
- Driver camera
|
||||
|
||||
20
scp/settings/notes
Normal file
20
scp/settings/notes
Normal file
@@ -0,0 +1,20 @@
|
||||
Goals:
|
||||
|
||||
- slow down on experimental mode
|
||||
- LKAS button - should toggle between drive, weather, weather radar. Hold for screen off
|
||||
- car dashboard should have enough indicators that it is able to represent drive state without screen on
|
||||
- set speed limit on engage cruise control
|
||||
|
||||
qol:
|
||||
- customize babysitter - driver awareness timeouts daytime, nighttime, require steering wheel
|
||||
- set climate on start, roll up windows on stop
|
||||
- upload park location on stop
|
||||
- low bandwidth / high bandwidth wifi, upload recordings on high bandwidth
|
||||
- list drives w/ image on stop
|
||||
- stop light / stop sign warning alert
|
||||
|
||||
release:
|
||||
- reenable training screen
|
||||
- - disregard for my device id
|
||||
- cleanup code
|
||||
- rename to diamondpilot
|
||||
176
scp/settings/settings.cc
Normal file
176
scp/settings/settings.cc
Normal file
@@ -0,0 +1,176 @@
|
||||
#include "selfdrive/ui/qt/offroad/settings.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "selfdrive/ui/qt/network/networking.h"
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/watchdog.h"
|
||||
#include "common/util.h"
|
||||
#include "system/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
#include "selfdrive/ui/qt/widgets/input.h"
|
||||
#include "selfdrive/ui/qt/widgets/scrollview.h"
|
||||
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
|
||||
#include "selfdrive/ui/qt/widgets/toggle.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
|
||||
#include "selfdrive/frogpilot/navigation/ui/navigation_settings.h"
|
||||
#include "selfdrive/frogpilot/ui/control_settings.h"
|
||||
#include "selfdrive/oscarpilot/settings/basic.h"
|
||||
#include "selfdrive/frogpilot/ui/visual_settings.h"
|
||||
|
||||
#include "selfdrive/oscarpilot/settings/settings.h"
|
||||
|
||||
|
||||
void OscarSettingsWindow::showEvent(QShowEvent *event) {
|
||||
setCurrentPanel(0);
|
||||
}
|
||||
|
||||
void OscarSettingsWindow::setCurrentPanel(int index, const QString ¶m) {
|
||||
panel_widget->setCurrentIndex(index);
|
||||
nav_btns->buttons()[index]->setChecked(true);
|
||||
if (!param.isEmpty()) {
|
||||
emit expandToggleDescription(param);
|
||||
}
|
||||
}
|
||||
|
||||
OscarSettingsWindow::OscarSettingsWindow(QWidget *parent) : QFrame(parent) {
|
||||
|
||||
// setup two main layouts
|
||||
sidebar_widget = new QWidget;
|
||||
QVBoxLayout *sidebar_layout = new QVBoxLayout(sidebar_widget);
|
||||
sidebar_layout->setMargin(0);
|
||||
panel_widget = new QStackedWidget();
|
||||
|
||||
// close button
|
||||
QPushButton *close_btn = new QPushButton(tr("← Back"));
|
||||
close_btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
font-size: 50px;
|
||||
padding-bottom: 0px;
|
||||
border 1px grey solid;
|
||||
border-radius: 25px;
|
||||
background-color: #292929;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #3B3B3B;
|
||||
}
|
||||
)");
|
||||
close_btn->setFixedSize(300, 125);
|
||||
sidebar_layout->addSpacing(10);
|
||||
sidebar_layout->addWidget(close_btn, 0, Qt::AlignRight);
|
||||
QObject::connect(close_btn, &QPushButton::clicked, [this]() {
|
||||
if (frogPilotTogglesOpen) {
|
||||
frogPilotTogglesOpen = false;
|
||||
this->closeParentToggle();
|
||||
} else {
|
||||
this->closeSettings();
|
||||
}
|
||||
});
|
||||
|
||||
FrogPilotControlsPanel *frogpilotControls = new FrogPilotControlsPanel(this);
|
||||
QObject::connect(frogpilotControls, &FrogPilotControlsPanel::closeParentToggle, this, [this]() {frogPilotTogglesOpen = false;});
|
||||
QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openParentToggle, this, [this]() {frogPilotTogglesOpen = true;});
|
||||
|
||||
// DevicePanel *device = new DevicePanel(this);
|
||||
// QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide);
|
||||
// QObject::connect(device, &DevicePanel::showDriverView, this, &SettingsWindow::showDriverView);
|
||||
|
||||
QList<QPair<QString, QWidget *>> panels = {
|
||||
{tr("Basic"), new OscarPilotBasicPanel(this)},
|
||||
{tr("Advanced"), frogpilotControls},
|
||||
{tr("Network"), new Networking(this)},
|
||||
{tr("Software"), new SoftwarePanel(this)},
|
||||
// {tr("Device"), new DevicePanel(this)},
|
||||
// FrogPilotControlsPanel
|
||||
// {tr("OscarCloud"), basic},
|
||||
// {tr("Logging"), basic}, // Log / Upload driver cam, Routes
|
||||
// {tr("System"), new OscarPilotBasicPanel(this)}, // Debugging
|
||||
// {tr("Status"), basic}, // Report on stuff like connectivity, free space, detected features
|
||||
// {tr("Extra"), basic}, // Custom cloud services, QOL automations
|
||||
};
|
||||
|
||||
nav_btns = new QButtonGroup(this);
|
||||
for (auto &[name, panel] : panels) {
|
||||
QPushButton *btn = new QPushButton(name);
|
||||
btn->setCheckable(true);
|
||||
btn->setChecked(nav_btns->buttons().size() == 0);
|
||||
btn->setStyleSheet(R"(
|
||||
QPushButton {
|
||||
color: grey;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 65px;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:checked {
|
||||
color: white;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
color: #ADADAD;
|
||||
}
|
||||
)");
|
||||
btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
nav_btns->addButton(btn);
|
||||
sidebar_layout->addWidget(btn, 0, Qt::AlignRight);
|
||||
|
||||
const int lr_margin = name != tr("Network") ? 50 : 0; // Network panel handles its own margins
|
||||
panel->setContentsMargins(lr_margin, 25, lr_margin, 25);
|
||||
|
||||
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 (!frogPilotTogglesOpen) {
|
||||
previousScrollPosition = value;
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() {
|
||||
panel_frame->restorePosition(previousScrollPosition);
|
||||
});
|
||||
}
|
||||
|
||||
QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() {
|
||||
previousScrollPosition = 0;
|
||||
btn->setChecked(true);
|
||||
panel_widget->setCurrentWidget(w);
|
||||
});
|
||||
}
|
||||
sidebar_layout->setContentsMargins(50, 50, 100, 50);
|
||||
|
||||
// main settings layout, sidebar + main panel
|
||||
QHBoxLayout *main_layout = new QHBoxLayout(this);
|
||||
|
||||
sidebar_widget->setFixedWidth(500);
|
||||
main_layout->addWidget(sidebar_widget);
|
||||
main_layout->addWidget(panel_widget);
|
||||
|
||||
setStyleSheet(R"(
|
||||
* {
|
||||
color: white;
|
||||
font-size: 50px;
|
||||
}
|
||||
OscarSettingsWindow {
|
||||
background-color: black;
|
||||
}
|
||||
QStackedWidget, ScrollView {
|
||||
background-color: #292929;
|
||||
border-radius: 30px;
|
||||
}
|
||||
)");
|
||||
}
|
||||
43
scp/settings/settings.h
Normal file
43
scp/settings/settings.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QStackedWidget>
|
||||
#include <QWidget>
|
||||
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
#include "selfdrive/ui/qt/widgets/controls.h"
|
||||
|
||||
// ********** settings window + top-level panels **********
|
||||
class OscarSettingsWindow : public QFrame {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OscarSettingsWindow(QWidget *parent = 0);
|
||||
void setCurrentPanel(int index, const QString ¶m = "");
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void closeSettings();
|
||||
void showDriverView();
|
||||
void expandToggleDescription(const QString ¶m);
|
||||
|
||||
// FrogPilot signals
|
||||
void closeParentToggle();
|
||||
private:
|
||||
QWidget *sidebar_widget;
|
||||
QButtonGroup *nav_btns;
|
||||
QStackedWidget *panel_widget;
|
||||
|
||||
// FrogPilot variables
|
||||
bool frogPilotTogglesOpen;
|
||||
int previousScrollPosition;
|
||||
};
|
||||
|
||||
42
scp/settings/style.cc
Normal file
42
scp/settings/style.cc
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <filesystem>
|
||||
|
||||
#include "selfdrive/frogpilot/ui/frogpilot_functions.h"
|
||||
#include "selfdrive/ui/ui.h"
|
||||
|
||||
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);
|
||||
}
|
||||
16
scp/settings/style.h
Normal file
16
scp/settings/style.h
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
const button_style = R"(
|
||||
QPushButton {
|
||||
color: grey;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 65px;
|
||||
font-weight: 500;
|
||||
}
|
||||
QPushButton:checked {
|
||||
color: white;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
color: #ADADAD;
|
||||
}
|
||||
)";
|
||||
Reference in New Issue
Block a user