Added toggle to enable NNFF. Credit goes to Twilsonco! https: //github.com/twilsonco Co-Authored-By: Tim Wilson <7284371+twilsonco@users.noreply.github.com>
440 lines
28 KiB
C++
440 lines
28 KiB
C++
#include "selfdrive/frogpilot/ui/control_settings.h"
|
|
|
|
FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) {
|
|
const std::vector<std::tuple<QString, QString, QString, QString>> controlToggles {
|
|
{"AlwaysOnLateral", "Always on Lateral", "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"},
|
|
|
|
{"ConditionalExperimental", "Conditional Experimental Mode", "Automatically switches to 'Experimental Mode' under predefined conditions.", "../frogpilot/assets/toggle_icons/icon_conditional.png"},
|
|
{"CECurves", "Curve Detected Ahead", "Switch to 'Experimental Mode' when a curve is detected.", ""},
|
|
{"CENavigation", "Navigation Based", "Switch to 'Experimental Mode' based on navigation data. (i.e. Intersections, stop signs, etc.)", ""},
|
|
{"CESlowerLead", "Slower Lead Detected Ahead", "Switch to 'Experimental Mode' when a slower lead vehicle is detected ahead.", ""},
|
|
{"CEStopLights", "Stop Lights and Stop Signs", "Switch to 'Experimental Mode' when a stop light or stop sign is detected.", ""},
|
|
{"CESignal", "Turn Signal When Below Highway Speeds", "Switch to 'Experimental Mode' when using turn signals below highway speeds to help assit with turns.", ""},
|
|
|
|
{"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"},
|
|
{"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"},
|
|
|
|
{"ExperimentalModeActivation", "Experimental Mode Activation", "Toggle Experimental Mode with either buttons on ethe steering wheel or the screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"},
|
|
{"ExperimentalModeViaLKAS", "Double Clicking the LKAS Button", "Enable/disable 'Experimental Mode' by double clicking the 'LKAS' button on your steering wheel.", ""},
|
|
{"ExperimentalModeViaScreen", "Double Taping the Onroad UI", "Enable/disable 'Experimental Mode' by double taping the onroad UI within a 0.5 second time frame.", ""},
|
|
{"ExperimentalModeViaDistance", "Long Pressing the Distance Button", "Enable/disable 'Experimental Mode' by holding down the 'distance' button on your steering wheel for 0.5 seconds.", ""},
|
|
|
|
{"FireTheBabysitter", "Fire the Babysitter", "Deactivate some of openpilot's 'Babysitter' protocols for more user autonomy.", "../frogpilot/assets/toggle_icons/icon_babysitter.png"},
|
|
{"MuteOverheated", "Bypass Thermal Safety Limits", "Allow the device to run at any temperature even above comma's recommended thermal limits.", ""},
|
|
{"NoLogging", "Disable Logging", "Turn off all data tracking to enhance privacy or reduce thermal load.\n\nWARNING: This action will prevent drive recording and data cannot be recovered!", ""},
|
|
{"NoUploads", "Disable Uploads", "Turn off all data uploads to comma's servers.\n\nWARNING: This action will prevent your drives from appearing on comma connect which may impact debugging and support!", ""},
|
|
|
|
{"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"},
|
|
{"ForceAutoTune", "Force Auto Tune", "Forces comma's auto lateral tuning for unsupported vehicles.", ""},
|
|
{"NNFF", "NNFF - Neural Network Feedforward", "Use Twilsonco's Neural Network Feedforward for enhanced precision in lateral control.", ""},
|
|
|
|
{"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"},
|
|
{"AccelerationProfile", "Acceleration Profile", "Change the acceleration rate to be either sporty or eco-friendly.", ""},
|
|
{"DecelerationProfile", "Deceleration Profile", "Change the deceleration rate to be either sporty or eco-friendly.", ""},
|
|
{"AggressiveAcceleration", "Aggressive Acceleration With Lead", "Increase acceleration aggressiveness when following a lead vehicle from a stop.", ""},
|
|
{"StoppingDistance", "Increase Stop Distance Behind Lead", "Increase the stopping distance for a more comfortable stop from lead vehicles.", ""},
|
|
|
|
{"Model", "Model Selector", "Choose your preferred openpilot model.", "../assets/offroad/icon_calibration.png"},
|
|
|
|
{"MTSCEnabled", "Map Turn Speed Control", "Slow down for anticipated curves detected by your downloaded maps.", "../frogpilot/assets/toggle_icons/icon_speed_map.png"},
|
|
{"DisableMTSCSmoothing", "Disable MTSC UI Smoothing", "Disables the smoothing for the requested speed in the onroad UI.", ""},
|
|
{"MTSCCurvatureCheck", "Model Curvature Detection Failsafe", "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.", ""},
|
|
{"MTSCLimit", "Speed Change Hard Cap", "Set a hard cap for MTSC. If MTSC requests a speed decrease greater than this value, it ignores the requested speed from MTSC. Purely used as a failsafe to prevent false positives. Leave this off if you never experience false positives.", ""},
|
|
{"MTSCAggressiveness", "Turn Speed Aggressiveness", "Set turn speed aggressiveness. Higher values result in faster turns, lower values yield gentler turns.\n\nA change of +- 1% results in the velocity being raised or lowered by about 1 mph.", ""},
|
|
|
|
{"QOLControls", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"},
|
|
{"DisableOnroadUploads", "Disable Onroad Uploads", "Prevent large data uploads when onroad.", ""},
|
|
{"HigherBitrate", "Higher Bitrate Recording", "Increases the quality of the footage uploaded to comma connect.", ""},
|
|
{"NavChill", "Navigate on Chill Mode", "Allows cars without longitudinal support to navigate. Allows navigation without experimental mode.", ""},
|
|
{"ReverseCruise", "Reverse Cruise Increase", "Reverses the 'long press' functionality when increasing the max set speed. Useful to increase the max speed quickly.", ""},
|
|
};
|
|
|
|
for (const auto &[param, title, desc, icon] : controlToggles) {
|
|
ParamControl *toggle;
|
|
|
|
if (param == "AlwaysOnLateral") {
|
|
std::vector<QString> aolToggles{"AlwaysOnLateralMain"};
|
|
std::vector<QString> aolToggleNames{tr("Enable On Cruise Main")};
|
|
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, aolToggles, aolToggleNames);
|
|
|
|
QObject::connect(static_cast<FrogPilotParamToggleControl*>(toggle), &FrogPilotParamToggleControl::buttonClicked, [this](const bool checked) {
|
|
if (checked) {
|
|
FrogPilotConfirmationDialog::toggleAlert("WARNING: This is very experimental and isn't guaranteed to work. If you run into any issues, please report it in the FrogPilot Discord!",
|
|
"I understand the risks.", this);
|
|
}
|
|
if (started) {
|
|
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
|
Hardware::soft_reboot();
|
|
}
|
|
}
|
|
});
|
|
|
|
} else if (param == "ConditionalExperimental") {
|
|
FrogPilotParamManageControl *conditionalExperimentalToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(conditionalExperimentalToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
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", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 99,
|
|
std::map<int, QString>(), this, false, " mph");
|
|
FrogPilotParamValueControl *CESpeedLeadImperial = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", 0, 99,
|
|
std::map<int, QString>(), this, false, " mph");
|
|
conditionalSpeedsImperial = new FrogPilotDualParamControl(CESpeedImperial, CESpeedLeadImperial, this);
|
|
addItem(conditionalSpeedsImperial);
|
|
|
|
FrogPilotParamValueControl *CESpeedMetric = new FrogPilotParamValueControl("CESpeed", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 150,
|
|
std::map<int, QString>(), this, false, " kph");
|
|
FrogPilotParamValueControl *CESpeedLeadMetric = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", 0, 150,
|
|
std::map<int, QString>(), this, false, " kph");
|
|
conditionalSpeedsMetric = new FrogPilotDualParamControl(CESpeedMetric, CESpeedLeadMetric, this);
|
|
addItem(conditionalSpeedsMetric);
|
|
|
|
std::vector<QString> curveToggles{"CECurvesLead"};
|
|
std::vector<QString> curveToggleNames{tr("With Lead")};
|
|
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, curveToggles, curveToggleNames);
|
|
} else if (param == "CENavigation") {
|
|
std::vector<QString> navigationToggles{"CENavigationIntersections", "CENavigationTurns", "CENavigationLead"};
|
|
std::vector<QString> navigationToggleNames{tr("Intersections"), tr("Turns"), tr("With Lead")};
|
|
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, navigationToggles, navigationToggleNames);
|
|
} else if (param == "CEStopLights") {
|
|
std::vector<QString> stopLightToggles{"CEStopLightsLead"};
|
|
std::vector<QString> stopLightToggleNames{tr("With Lead")};
|
|
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, stopLightToggles, stopLightToggleNames);
|
|
|
|
} else if (param == "CustomPersonalities") {
|
|
FrogPilotParamManageControl *customPersonalitiesToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(customPersonalitiesToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
for (auto &[key, toggle] : toggles) {
|
|
toggle->setVisible(false);
|
|
}
|
|
aggressiveProfile->setVisible(true);
|
|
standardProfile->setVisible(true);
|
|
relaxedProfile->setVisible(true);
|
|
});
|
|
toggle = customPersonalitiesToggle;
|
|
|
|
FrogPilotParamValueControl *aggressiveFollow = new FrogPilotParamValueControl("AggressiveFollow", "Follow",
|
|
"Set the 'Aggressive' personality' following distance. "
|
|
"Represents seconds to follow behind the lead vehicle.\n\nStock: 1.25 seconds.",
|
|
"../frogpilot/assets/other_images/aggressive.png",
|
|
1, 5, std::map<int, QString>(), this, false, " sec", 1, 0.01);
|
|
FrogPilotParamValueControl *aggressiveJerk = new FrogPilotParamValueControl("AggressiveJerk", " Jerk",
|
|
"Configure brake/gas pedal responsiveness for the 'Aggressive' personality. "
|
|
"Higher jerk value = smoother rides.\nLower jerk value = faster response.\n\nStock: 0.5.",
|
|
"",
|
|
0.01, 5, std::map<int, QString>(), this, false, "", 1, 0.01);
|
|
aggressiveProfile = new FrogPilotDualParamControl(aggressiveFollow, aggressiveJerk, this, true);
|
|
addItem(aggressiveProfile);
|
|
|
|
FrogPilotParamValueControl *standardFollow = new FrogPilotParamValueControl("StandardFollow", "Follow",
|
|
"Set the 'Standard' personality following distance. "
|
|
"Represents seconds to follow behind the lead vehicle.\n\nStock: 1.45 seconds.",
|
|
"../frogpilot/assets/other_images/standard.png",
|
|
1, 5, std::map<int, QString>(), this, false, " sec", 1, 0.01);
|
|
FrogPilotParamValueControl *standardJerk = new FrogPilotParamValueControl("StandardJerk", " Jerk",
|
|
"Adjust brake/gas pedal responsiveness for the 'Standard' personality. "
|
|
"Higher jerk value = smoother rides.\nLower jerk value = faster response.\n\nStock: 1.0.",
|
|
"",
|
|
0.01, 5, std::map<int, QString>(), this, false, "", 1, 0.01);
|
|
standardProfile = new FrogPilotDualParamControl(standardFollow, standardJerk, this, true);
|
|
addItem(standardProfile);
|
|
|
|
FrogPilotParamValueControl *relaxedFollow = new FrogPilotParamValueControl("RelaxedFollow", "Follow",
|
|
"Set the 'Relaxed' personality following distance. "
|
|
"Represents seconds to follow behind the lead vehicle.\n\nStock: 1.75 seconds.",
|
|
"../frogpilot/assets/other_images/relaxed.png",
|
|
1, 5, std::map<int, QString>(), this, false, " sec", 1, 0.01);
|
|
FrogPilotParamValueControl *relaxedJerk = new FrogPilotParamValueControl("RelaxedJerk", " Jerk",
|
|
"Set brake/gas pedal responsiveness for the 'Relaxed' personality. "
|
|
"Higher jerk value = smoother rides.\nLower jerk value = faster response.\n\nStock: 1.0.",
|
|
"",
|
|
0.01, 5, std::map<int, QString>(), this, false, "", 1, 0.01);
|
|
relaxedProfile = new FrogPilotDualParamControl(relaxedFollow, relaxedJerk, this, true);
|
|
addItem(relaxedProfile);
|
|
|
|
} else if (param == "DeviceShutdown") {
|
|
std::map<int, QString> shutdownLabels;
|
|
for (int i = 0; i <= 33; ++i) {
|
|
shutdownLabels[i] = i == 0 ? "Instant" : i <= 3 ? QString::number(i * 15) + " mins" : QString::number(i - 3) + (i == 4 ? " hour" : " hours");
|
|
}
|
|
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false);
|
|
|
|
} else if (param == "ExperimentalModeActivation") {
|
|
FrogPilotParamManageControl *experimentalModeActivationToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(experimentalModeActivationToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
for (auto &[key, toggle] : toggles) {
|
|
toggle->setVisible(experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end());
|
|
}
|
|
});
|
|
toggle = experimentalModeActivationToggle;
|
|
|
|
} else if (param == "FireTheBabysitter") {
|
|
FrogPilotParamManageControl *fireTheBabysitterToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(fireTheBabysitterToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
for (auto &[key, toggle] : toggles) {
|
|
toggle->setVisible(fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end());
|
|
}
|
|
});
|
|
toggle = fireTheBabysitterToggle;
|
|
|
|
} else if (param == "LateralTune") {
|
|
FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
for (auto &[key, toggle] : toggles) {
|
|
toggle->setVisible(lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end());
|
|
}
|
|
});
|
|
toggle = lateralTuneToggle;
|
|
|
|
} else if (param == "LongitudinalTune") {
|
|
FrogPilotParamManageControl *longitudinalTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(longitudinalTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
for (auto &[key, toggle] : toggles) {
|
|
toggle->setVisible(longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end());
|
|
}
|
|
});
|
|
toggle = longitudinalTuneToggle;
|
|
} else if (param == "AccelerationProfile") {
|
|
std::vector<QString> profileOptions{tr("Standard"), tr("Eco"), tr("Sport"), tr("Sport+")};
|
|
FrogPilotButtonParamControl *profileSelection = new FrogPilotButtonParamControl(param, title, desc, icon, profileOptions);
|
|
toggle = profileSelection;
|
|
|
|
QObject::connect(static_cast<FrogPilotButtonParamControl*>(toggle), &FrogPilotButtonParamControl::buttonClicked, [this](int id) {
|
|
if (id == 3) {
|
|
FrogPilotConfirmationDialog::toggleAlert("WARNING: This maxes out openpilot's acceleration from 2.0 m/s to 4.0 m/s and may cause oscillations when accelerating!",
|
|
"I understand the risks.", this);
|
|
}
|
|
});
|
|
} else if (param == "DecelerationProfile") {
|
|
std::vector<QString> 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<int, QString>(), this, false, " feet");
|
|
|
|
} else if (param == "Model") {
|
|
modelSelectorButton = new FrogPilotButtonIconControl(title, tr("SELECT"), desc, icon);
|
|
QStringList models = {"los-angeles", "certified-herbalist", "duck-amigo", "recertified-herbalist"};
|
|
QStringList modelLabels = {"Los Angeles (Default)", "Certified Herbalist", "Duck Amigo", "Recertified Herbalist"};
|
|
QObject::connect(modelSelectorButton, &FrogPilotButtonIconControl::clicked, this, [this, models, modelLabels]() {
|
|
QString selection = MultiOptionDialog::getSelection(tr("Select a driving model"), modelLabels, "", this);
|
|
|
|
if (!selection.isEmpty()) {
|
|
int selectedModelIndex = modelLabels.indexOf(selection);
|
|
QString selectedModelValue = models[selectedModelIndex];
|
|
params.put("Model", selectedModelValue.toStdString());
|
|
modelSelectorButton->setValue(selection);
|
|
if (FrogPilotConfirmationDialog::yesorno("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("Reboot required to take effect.", "Reboot Now", this)) {
|
|
Hardware::soft_reboot();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
int initialModelIndex = models.indexOf(QString::fromStdString(params.get("Model")));
|
|
QString initialModelLabel = modelLabels[initialModelIndex];
|
|
modelSelectorButton->setValue(initialModelLabel);
|
|
addItem(modelSelectorButton);
|
|
|
|
} else if (param == "MTSCEnabled") {
|
|
FrogPilotParamManageControl *mtscToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
|
|
QObject::connect(mtscToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
parentToggleClicked();
|
|
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<int, QString>(), this, false, "%");
|
|
} else if (param == "MTSCLimit") {
|
|
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map<int, QString>(), this, false, " mph");
|
|
|
|
} else if (param == "QOLControls") {
|
|
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 == "ReverseCruise") {
|
|
std::vector<QString> reverseCruiseToggles{"ReverseCruiseUI"};
|
|
std::vector<QString> reverseCruiseNames{tr("Control Via UI")};
|
|
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, reverseCruiseToggles, reverseCruiseNames);
|
|
|
|
} 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<FrogPilotButtonParamControl*>(toggle), &FrogPilotButtonParamControl::buttonClicked, [this]() {
|
|
updateToggles();
|
|
});
|
|
|
|
QObject::connect(static_cast<FrogPilotParamValueControl*>(toggle), &FrogPilotParamValueControl::valueChanged, [this]() {
|
|
updateToggles();
|
|
});
|
|
|
|
QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() {
|
|
update();
|
|
});
|
|
|
|
QObject::connect(static_cast<FrogPilotParamManageControl*>(toggle), &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
|
|
update();
|
|
});
|
|
}
|
|
|
|
QObject::connect(toggles["MuteOverheated"], &ToggleControl::toggleFlipped, [this]() {
|
|
if (params.getBool("MuteOverheated")) {
|
|
FrogPilotConfirmationDialog::toggleAlert(
|
|
"WARNING: This MAY cause premature wear or damage by running the device over comma's recommended temperature limits!",
|
|
"I understand the risks.", this);
|
|
}
|
|
});
|
|
|
|
std::set<std::string> rebootKeys = {"AlwaysOnLateral", "HigherBitrate", "NNFF"};
|
|
for (const std::string &key : rebootKeys) {
|
|
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this, key]() {
|
|
if (started) {
|
|
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
|
|
Hardware::soft_reboot();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotControlsPanel::hideSubToggles);
|
|
QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotControlsPanel::hideSubToggles);
|
|
QObject::connect(parent, &SettingsWindow::closeSubParentToggle, 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);
|
|
|
|
hideSubToggles();
|
|
updateMetric();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::updateState(const UIState &s) {
|
|
started = s.scene.started;
|
|
}
|
|
|
|
void FrogPilotControlsPanel::updateToggles() {
|
|
std::thread([this]() {
|
|
paramsMemory.putBool("FrogPilotTogglesUpdated", true);
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
paramsMemory.putBool("FrogPilotTogglesUpdated", false);
|
|
}).detach();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::updateCarToggles() {
|
|
}
|
|
|
|
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("MTSCLimit", std::nearbyint(params.getInt("MTSCLimit") * speedConversion));
|
|
params.putIntNonBlocking("StoppingDistance", std::nearbyint(params.getInt("StoppingDistance") * distanceConversion));
|
|
}
|
|
|
|
FrogPilotParamValueControl *mtscLimitToggle = static_cast<FrogPilotParamValueControl*>(toggles["MTSCLimit"]);
|
|
FrogPilotParamValueControl *stoppingDistanceToggle = static_cast<FrogPilotParamValueControl*>(toggles["StoppingDistance"]);
|
|
|
|
if (isMetric) {
|
|
mtscLimitToggle->updateControl(0, 99, " kph");
|
|
|
|
stoppingDistanceToggle->updateControl(0, 5, " meters");
|
|
} else {
|
|
mtscLimitToggle->updateControl(0, 99, " mph");
|
|
|
|
stoppingDistanceToggle->updateControl(0, 10, " feet");
|
|
}
|
|
|
|
mtscLimitToggle->refresh();
|
|
stoppingDistanceToggle->refresh();
|
|
|
|
previousIsMetric = isMetric;
|
|
}
|
|
|
|
void FrogPilotControlsPanel::parentToggleClicked() {
|
|
aggressiveProfile->setVisible(false);
|
|
conditionalSpeedsImperial->setVisible(false);
|
|
conditionalSpeedsMetric->setVisible(false);
|
|
modelSelectorButton->setVisible(false);
|
|
standardProfile->setVisible(false);
|
|
relaxedProfile->setVisible(false);
|
|
|
|
openParentToggle();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::subParentToggleClicked() {
|
|
openSubParentToggle();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::hideSubToggles() {
|
|
aggressiveProfile->setVisible(false);
|
|
conditionalSpeedsImperial->setVisible(false);
|
|
conditionalSpeedsMetric->setVisible(false);
|
|
modelSelectorButton->setVisible(true);
|
|
standardProfile->setVisible(false);
|
|
relaxedProfile->setVisible(false);
|
|
|
|
for (auto &[key, toggle] : toggles) {
|
|
bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() ||
|
|
experimentalModeActivationKeys.find(key.c_str()) != experimentalModeActivationKeys.end() ||
|
|
fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.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() ||
|
|
speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end() ||
|
|
visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end();
|
|
toggle->setVisible(!subToggles);
|
|
}
|
|
|
|
closeParentToggle();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::hideSubSubToggles() {
|
|
for (auto &[key, toggle] : toggles) {
|
|
bool isVisible = false;
|
|
toggle->setVisible(isVisible);
|
|
}
|
|
|
|
closeSubParentToggle();
|
|
update();
|
|
}
|
|
|
|
void FrogPilotControlsPanel::hideEvent(QHideEvent *event) {
|
|
hideSubToggles();
|
|
}
|