diff --git a/common/params.cc b/common/params.cc index be3a034..301d42a 100644 --- a/common/params.cc +++ b/common/params.cc @@ -247,6 +247,7 @@ std::unordered_map keys = { {"DisableOnroadUploads", PERSISTENT}, {"DriverCamera", PERSISTENT}, {"ExperimentalModeViaPress", PERSISTENT}, + {"FireTheBabysitter", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT}, {"GasRegenCmd", PERSISTENT}, {"GoatScream", PERSISTENT}, @@ -255,6 +256,11 @@ std::unordered_map keys = { {"LeadInfo", PERSISTENT}, {"LongitudinalTune", PERSISTENT}, {"ModelUI", PERSISTENT}, + {"MuteDM", PERSISTENT}, + {"MuteDoor", PERSISTENT}, + {"MuteOverheated", PERSISTENT}, + {"MuteSeatbelt", PERSISTENT}, + {"NoLogging", PERSISTENT}, {"OfflineMode", PERSISTENT}, {"PathEdgeWidth", PERSISTENT}, {"PathWidth", PERSISTENT}, diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index ebecde4..7834a09 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -251,9 +251,9 @@ class CarInterfaceBase(ABC): enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)): events = Events() - if cs_out.doorOpen: + if cs_out.doorOpen and not self.mute_door: events.add(EventName.doorOpen) - if cs_out.seatbeltUnlatched: + if cs_out.seatbeltUnlatched and not self.mute_seatbelt: events.add(EventName.seatbeltNotLatched) if cs_out.gearShifter != GearShifter.drive and (extra_gears is None or cs_out.gearShifter not in extra_gears): @@ -324,6 +324,10 @@ class CarInterfaceBase(ABC): if hasattr(self.CC, 'update_frogpilot_variables'): self.CC.update_frogpilot_variables(params) + fire_the_babysitter = params.get_bool("FireTheBabysitter") + self.mute_door = fire_the_babysitter and params.get_bool("MuteDoor") + self.mute_seatbelt = fire_the_babysitter and params.get_bool("MuteSeatbelt") + class RadarInterfaceBase(ABC): def __init__(self, CP): self.rcp = None diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6e25c4b..fea72a4 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -79,9 +79,15 @@ class Controls: self.params = Params() self.params_memory = Params("/dev/shm/params") + fire_the_babysitter = self.params.get_bool("FireTheBabysitter") + mute_dm = fire_the_babysitter and self.params.get_bool("MuteDM") + ignore = self.sensor_packets + ['testJoystick'] if SIMULATION: ignore += ['driverCameraState', 'managerState'] + if mute_dm: + ignore += ['driverMonitoringState'] + self.params.put_bool("DmModelInitialized", True) self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', 'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters', 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 0000000..9789aeb 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 320ea21..7481939 100644 --- a/selfdrive/frogpilot/ui/control_settings.cc +++ b/selfdrive/frogpilot/ui/control_settings.cc @@ -16,6 +16,13 @@ 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"}, {"ExperimentalModeViaPress", "Experimental Mode Via 'LKAS' Button / Screen", "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"}, + {"NoLogging", "Disable All 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!", ""}, + {"MuteDoor", "Mute Door Open Alert", "Disable alerts for open doors.", ""}, + {"MuteDM", "Mute Driver Monitoring", "Disable driver monitoring.", ""}, + {"MuteOverheated", "Mute Overheated System Alert", "Disable alerts for the device being overheated.", ""}, + {"MuteSeatbelt", "Mute Seatbelt Unlatched Alert", "Disable alerts for unlatched seatbelts.", ""}, + {"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"}, {"AverageCurvature", "Average Desired Curvature", "Use Pfeiferj's distance-based curvature adjustment for improved curve handling.", ""}, @@ -123,6 +130,16 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil } toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false); + } 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]() { @@ -178,7 +195,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil }); } - std::set rebootKeys = {"AlwaysOnLateral"}; + std::set rebootKeys = {"AlwaysOnLateral", "FireTheBabysitter", "MuteDM"}; for (const std::string &key : rebootKeys) { QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() { if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { @@ -188,7 +205,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil } conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"}; - fireTheBabysitterKeys = {}; + fireTheBabysitterKeys = {"NoLogging", "MuteDM", "MuteDoor", "MuteOverheated", "MuteSeatbelt"}; laneChangeKeys = {}; lateralTuneKeys = {"AverageCurvature"}; longitudinalTuneKeys = {"AccelerationProfile", "AggressiveAcceleration"}; diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 738fff1..c6bb087 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -45,23 +45,30 @@ def only_offroad(started, params, CP: car.CarParams) -> bool: # FrogPilot functions def allow_uploads(started, params, CP: car.CarParams) -> bool: + enable_logging = not (params.get_bool("FireTheBabysitter") and params.get_bool("NoLogging")) wifi_connected = HARDWARE.get_network_type() == WIFI and not started - return wifi_connected if params.get_bool("DisableOnroadUploads") else True + return wifi_connected if params.get_bool("DisableOnroadUploads") else enable_logging + +def enable_dm(started, params, CP: car.CarParams) -> bool: + return (started or params.get_bool("IsDriverViewEnabled")) and not (params.get_bool("FireTheBabysitter") and params.get_bool("MuteDM")) + +def enable_logging(started, params, CP: car.CarParams) -> bool: + return not (params.get_bool("FireTheBabysitter") and params.get_bool("NoLogging")) procs = [ DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), NativeProcess("camerad", "system/camerad", ["./camerad"], driverview), - NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad), + NativeProcess("logcatd", "system/logcatd", ["./logcatd"], (enable_logging and only_onroad)), NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad), - PythonProcess("logmessaged", "system.logmessaged", always_run), + PythonProcess("logmessaged", "system.logmessaged", enable_logging), PythonProcess("micd", "system.micd", iscar), PythonProcess("timezoned", "system.timezoned", always_run, enabled=not PC), - PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(not PC or WEBCAM)), + PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", enable_dm, enabled=(not PC or WEBCAM)), NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), 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), @@ -74,7 +81,7 @@ procs = [ PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), PythonProcess("controlsd", "selfdrive.controls.controlsd", only_onroad), PythonProcess("deleter", "system.loggerd.deleter", always_run), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)), + PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enable_dm, enabled=(not PC or WEBCAM)), PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), PythonProcess("navd", "selfdrive.navd.navd", only_onroad), PythonProcess("pandad", "selfdrive.boardd.pandad", always_run), @@ -84,7 +91,7 @@ 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), diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index beb85f9..c439298 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -298,6 +298,10 @@ 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"): + if params.get_bool("MuteOverheated"): + thermal_status = ThermalStatus.green + # **** starting logic **** # Ensure date/time are valid diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 0d34a4a..688fc7f 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -974,7 +974,7 @@ void AnnotatedCameraWidget::paintGL() { } // DMoji - if (!hideBottomIcons && (sm.rcv_frame("driverStateV2") > s->scene.started_frame)) { + if (!hideBottomIcons && (sm.rcv_frame("driverStateV2") > s->scene.started_frame) && !muteDM) { update_dmonitoring(s, sm["driverStateV2"].getDriverStateV2(), dm_fade_state, rightHandDM); drawDriverState(painter, s); } @@ -1058,6 +1058,7 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { laneWidthRight = scene.lane_width_right; leadInfo = scene.lead_info; mapOpen = scene.map_open; + muteDM = scene.mute_dm; obstacleDistance = scene.obstacle_distance; obstacleDistanceStock = scene.obstacle_distance_stock; showDriverCamera = scene.show_driver_camera; diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index af91aad..50c36d5 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -135,6 +135,7 @@ private: bool experimentalMode; bool leadInfo; bool mapOpen; + bool muteDM; bool showDriverCamera; bool turnSignalLeft; bool turnSignalRight; diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index f0e8e2e..1d3ded0 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -306,6 +306,7 @@ void ui_update_params(UIState *s) { scene.driver_camera = params.getBool("DriverCamera"); scene.experimental_mode_via_press = params.getBool("ExperimentalModeViaPress"); + scene.mute_dm = params.getBool("FireTheBabysitter") && params.getBool("MuteDM"); scene.screen_brightness = params.getInt("ScreenBrightness"); scene.wheel_icon = params.getInt("WheelIcon"); } diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 7fc8764..bcbba67 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -186,6 +186,7 @@ typedef struct UIScene { bool lead_info; bool map_open; bool model_ui; + bool mute_dm; bool show_driver_camera; bool show_fps; bool turn_signal_left;