diff --git a/common/params.cc b/common/params.cc index 3347d6dad..dc9b55693 100644 --- a/common/params.cc +++ b/common/params.cc @@ -257,6 +257,7 @@ std::unordered_map keys = { {"ExperimentalModeActivation", PERSISTENT}, {"ExperimentalModeViaLKAS", PERSISTENT}, {"ExperimentalModeViaScreen", PERSISTENT}, + {"FireTheBabysitter", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT}, {"GoatScream", PERSISTENT}, {"LaneLinesWidth", PERSISTENT}, @@ -265,6 +266,9 @@ std::unordered_map keys = { {"LongitudinalTune", PERSISTENT}, {"ManualUpdateInitiated", CLEAR_ON_MANAGER_START}, {"ModelUI", PERSISTENT}, + {"MuteOverheated", PERSISTENT}, + {"NoLogging", PERSISTENT}, + {"NoUploads", PERSISTENT}, {"PathEdgeWidth", PERSISTENT}, {"PathWidth", PERSISTENT}, {"PromptVolume", PERSISTENT}, diff --git a/selfdrive/assets/offroad/icon_wifi_uploading_disabled.svg b/selfdrive/assets/offroad/icon_wifi_uploading_disabled.svg new file mode 100644 index 000000000..156052556 --- /dev/null +++ b/selfdrive/assets/offroad/icon_wifi_uploading_disabled.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_babysitter.png b/selfdrive/frogpilot/assets/toggle_icons/icon_babysitter.png new file mode 100644 index 000000000..9789aebfe Binary files /dev/null and b/selfdrive/frogpilot/assets/toggle_icons/icon_babysitter.png differ diff --git a/selfdrive/frogpilot/ui/control_settings.cc b/selfdrive/frogpilot/ui/control_settings.cc index 41a9f1688..264aca769 100644 --- a/selfdrive/frogpilot/ui/control_settings.cc +++ b/selfdrive/frogpilot/ui/control_settings.cc @@ -15,6 +15,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil {"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 Via", "Toggle Experimental Mode by double-clicking the 'Lane Departure'/'LKAS' button or double tapping screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"}, + {"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"}, {"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, @@ -148,6 +153,16 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil std::vector experimentalModeNames{tr("LKAS Button"), tr("Screen")}; toggle = new FrogPilotParamToggleControl(param, title, desc, icon, experimentalModeToggles, experimentalModeNames); + } 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]() { @@ -217,6 +232,14 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil }); } + 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 rebootKeys = {"AlwaysOnLateral"}; for (const std::string &key : rebootKeys) { QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this, key]() { diff --git a/selfdrive/frogpilot/ui/control_settings.h b/selfdrive/frogpilot/ui/control_settings.h index 11149e816..575d0b5b7 100644 --- a/selfdrive/frogpilot/ui/control_settings.h +++ b/selfdrive/frogpilot/ui/control_settings.h @@ -36,7 +36,7 @@ private: FrogPilotDualParamControl *relaxedProfile; std::set conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"}; - std::set fireTheBabysitterKeys = {}; + std::set fireTheBabysitterKeys = {"NoLogging", "MuteOverheated", "NoUploads"}; std::set laneChangeKeys = {}; std::set lateralTuneKeys = {}; std::set longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "AggressiveAcceleration"}; diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 1927ada2d..6f9d456b5 100644 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -300,7 +300,7 @@ def manager_cleanup() -> None: def update_frogpilot_params(params, params_memory): - keys = ["DisableOnroadUploads"] + keys = ["DisableOnroadUploads", "FireTheBabysitter", "NoLogging", "NoUploads"] for key in keys: params_memory.put_bool(key, params.get_bool(key)) diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index bd314b943..8ea4736a1 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -43,22 +43,28 @@ def only_offroad(started, params, params_memory, CP: car.CarParams) -> bool: # FrogPilot functions def allow_uploads(started, params, params_memory, CP: car.CarParams) -> bool: - return not started if params_memory.get_bool("DisableOnroadUploads") else True + return not started if params_memory.get_bool("DisableOnroadUploads") else enable_uploading(started, params, params_memory, CP) + +def enable_logging(started, params, params_memory, CP: car.CarParams) -> bool: + return not (params_memory.get_bool("FireTheBabysitter") and params_memory.get_bool("NoLogging")) + +def enable_uploading(started, params, params_memory, CP: car.CarParams) -> bool: + return not (params_memory.get_bool("FireTheBabysitter") and params_memory.get_bool("NoUploads")) procs = [ DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), NativeProcess("camerad", "system/camerad", ["./camerad"], driverview), - NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad), - NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad), - PythonProcess("logmessaged", "system.logmessaged", always_run), + NativeProcess("logcatd", "system/logcatd", ["./logcatd"], (enable_logging and only_onroad)), + NativeProcess("proclogd", "system/proclogd", ["./proclogd"], enable_logging), + PythonProcess("logmessaged", "system.logmessaged", enable_logging), PythonProcess("micd", "system.micd", iscar), PythonProcess("timed", "system.timed", always_run, enabled=not PC), PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(not PC or WEBCAM)), - NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), + NativeProcess("encoderd", "system/loggerd", ["./encoderd"], enable_logging), NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar), - NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), + NativeProcess("loggerd", "system/loggerd", ["./loggerd"], (enable_logging and logging)), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"], only_onroad), NativeProcess("mapsd", "selfdrive/navd", ["./mapsd"], only_onroad), PythonProcess("navmodeld", "selfdrive.modeld.navmodeld", only_onroad), @@ -81,10 +87,10 @@ procs = [ PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad), PythonProcess("radard", "selfdrive.controls.radard", only_onroad), PythonProcess("thermald", "selfdrive.thermald.thermald", always_run), - PythonProcess("tombstoned", "selfdrive.tombstoned", always_run, enabled=not PC), + PythonProcess("tombstoned", "selfdrive.tombstoned", enable_logging, enabled=not PC), PythonProcess("updated", "selfdrive.updated", only_offroad, enabled=not PC), PythonProcess("uploader", "system.loggerd.uploader", allow_uploads), - PythonProcess("statsd", "selfdrive.statsd", always_run), + PythonProcess("statsd", "selfdrive.statsd", enable_logging), # debug procs NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 33ef4e238..93b7a7839 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -297,6 +297,9 @@ def thermald_thread(end_event, hw_queue) -> None: elif current_band.max_temp is not None and all_comp_temp > current_band.max_temp: thermal_status = list(THERMAL_BANDS.keys())[band_idx + 1] + if params.get_bool("FireTheBabysitter") and params.get_bool("MuteOverheated"): + thermal_status = ThermalStatus.green + # **** starting logic **** startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate") diff --git a/selfdrive/ui/qt/widgets/wifi.cc b/selfdrive/ui/qt/widgets/wifi.cc index 9c5289a22..95beab428 100644 --- a/selfdrive/ui/qt/widgets/wifi.cc +++ b/selfdrive/ui/qt/widgets/wifi.cc @@ -81,6 +81,34 @@ WiFiPromptWidget::WiFiPromptWidget(QWidget *parent) : QFrame(parent) { } stack->addWidget(uploading); + QWidget *notUploading = new QWidget; + QVBoxLayout *not_uploading_layout = new QVBoxLayout(notUploading); + not_uploading_layout->setContentsMargins(64, 56, 64, 56); + not_uploading_layout->setSpacing(36); + { + QHBoxLayout *title_layout = new QHBoxLayout; + { + QLabel *title = new QLabel(tr("Uploading disabled")); + title->setStyleSheet("font-size: 64px; font-weight: 600;"); + title->setWordWrap(true); + title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + title_layout->addWidget(title); + title_layout->addStretch(); + + QLabel *icon = new QLabel; + QPixmap pixmap("../assets/offroad/icon_wifi_uploading_disabled.svg"); + icon->setPixmap(pixmap.scaledToWidth(120, Qt::SmoothTransformation)); + title_layout->addWidget(icon); + } + not_uploading_layout->addLayout(title_layout); + + QLabel *desc = new QLabel(tr("Training data wont be pulled periodically until you disable the 'Disable Uploading' toggle")); + desc->setStyleSheet("font-size: 48px; font-weight: 400;"); + desc->setWordWrap(true); + not_uploading_layout->addWidget(desc); + } + stack->addWidget(notUploading); + setStyleSheet(R"( WiFiPromptWidget { background-color: #333333; @@ -99,5 +127,6 @@ void WiFiPromptWidget::updateState(const UIState &s) { auto network_type = sm["deviceState"].getDeviceState().getNetworkType(); auto uploading = network_type == cereal::DeviceState::NetworkType::WIFI || network_type == cereal::DeviceState::NetworkType::ETHERNET; - stack->setCurrentIndex(uploading ? 1 : 0); + auto uploading_disabled = params.getBool("NoUploads"); + stack->setCurrentIndex(uploading_disabled ? 2 : uploading ? 1 : 0); }