#include "selfdrive/oscarpilot/settings/basic.h" #include "selfdrive/ui/ui.h" OscarPilotBasicPanel::OscarPilotBasicPanel(OscarSettingsWindow *parent) : FrogPilotListWidget(parent) { const std::vector> 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(toggle), &FrogPilotParamValueControl::buttonPressed, [this]() { updateToggles(); }); QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { update(); }); QObject::connect(static_cast(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() { update(); }); } // std::set 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); } }