diff --git a/common/params_keys.h b/common/params_keys.h index 92853f92f..828fd7ab4 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -122,4 +122,7 @@ inline static std::unordered_map keys = { {"Version", PERSISTENT}, {"dp_device_last_log", CLEAR_ON_ONROAD_TRANSITION}, {"dp_device_reset_conf", CLEAR_ON_MANAGER_START}, + {"dp_device_is_rhd", PERSISTENT}, + {"dp_device_monitoring_disabled", PERSISTENT}, + {"dp_device_beep", PERSISTENT}, }; diff --git a/dragonpilot/selfdrive/ui/beepd.py b/dragonpilot/selfdrive/ui/beepd.py new file mode 100644 index 000000000..665cbdbb0 --- /dev/null +++ b/dragonpilot/selfdrive/ui/beepd.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python3 +''' +MIT Non-Commercial License + +Copyright (c) 2019, dragonpilot + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, for non-commercial purposes only, subject to the following conditions: + +- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +- Commercial use (e.g., use in a product, service, or activity intended to generate revenue) is prohibited without explicit written permission from dragonpilot. Contact ricklan@gmail.com for inquiries. +- Any project that uses the Software must visibly mention the following acknowledgment: "This project uses software from dragonpilot and is licensed under a custom license requiring permission for use." + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +beepd is a soundd replacement that makes beep alerts via GPIO +''' + +import subprocess +import time +from cereal import car, messaging +from openpilot.common.realtime import Ratekeeper +import threading + +AudibleAlert = car.CarControl.HUDControl.AudibleAlert + +class Beepd: + def __init__(self): + self.current_alert = AudibleAlert.none + self.enable_gpio() + + def enable_gpio(self): + try: + subprocess.run("echo 42 | sudo tee /sys/class/gpio/export", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + except Exception: + pass + subprocess.run("echo \"out\" | sudo tee /sys/class/gpio/gpio42/direction", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + + def _beep(self, on): + val = "1" if on else "0" + subprocess.run(f"echo \"{val}\" | sudo tee /sys/class/gpio/gpio42/value", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + + def engage(self): + self._beep(True) + time.sleep(0.05) + self._beep(False) + + def disengage(self): + for _ in range(2): + self._beep(True) + time.sleep(0.01) + self._beep(False) + time.sleep(0.01) + + def warning(self): + for _ in range(3): + self._beep(True) + time.sleep(0.01) + self._beep(False) + time.sleep(0.01) + + def warning_immediate(self): + for _ in range(5): + self._beep(True) + time.sleep(0.01) + self._beep(False) + time.sleep(0.01) + + def dispatch_beep(self, func): + threading.Thread(target=func, daemon=True).start() + + def update_alert(self, new_alert): + current_alert_played_once = self.current_alert == AudibleAlert.none + if self.current_alert != new_alert and (new_alert != AudibleAlert.none or current_alert_played_once): + self.current_alert = new_alert + # if new_alert == AudibleAlert.engage: + # self.dispatch_beep(self.engage) + # if new_alert == AudibleAlert.disengage: + # self.dispatch_beep(self.disengage) + if new_alert == AudibleAlert.warningImmediate: + self.dispatch_beep(self.warning_immediate) + + def get_audible_alert(self, sm): + if sm.updated['selfdriveState']: + new_alert = sm['selfdriveState'].alertSound.raw + self.update_alert(new_alert) + + def test_beepd_thread(self): + frame = 0 + rk = Ratekeeper(20) + pm = messaging.PubMaster(['selfdriveState']) + while True: + cs = messaging.new_message('selfdriveState') + if frame == 20: + cs.selfdriveState.alertSound = AudibleAlert.engage + if frame == 40: + cs.selfdriveState.alertSound = AudibleAlert.disengage + if frame == 60: + cs.selfdriveState.alertSound = AudibleAlert.prompt + if frame == 80: + cs.selfdriveState.alertSound = AudibleAlert.disengage + if frame == 85: + cs.selfdriveState.alertSound = AudibleAlert.prompt + + pm.send("selfdriveState", cs) + frame += 1 + rk.keep_time() + + def beepd_thread(self, test=False): + if test: + threading.Thread(target=self.test_beepd_thread, daemon=True).start() + + sm = messaging.SubMaster(['selfdriveState']) + rk = Ratekeeper(20) + + while True: + sm.update(0) + self.get_audible_alert(sm) + rk.keep_time() + +def main(): + s = Beepd() + s.beepd_thread(test=False) + +if __name__ == "__main__": + main() diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index d4689aae5..b363381e7 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -27,6 +27,24 @@ function agnos_init { fi } +no_amp() { + output=$(i2cget -y 0 0x10 0x00 2>/dev/null) + if [ -z "$output" ]; then + return 0 + else + return 1 + fi +} + +function check_device_mode { + if no_amp; then + echo "O3 Lite Mode" + export DISABLE_DRIVER=1 + else + echo "C3 Mode" + fi +} + function launch { # Remove orphaned git lock if it exists on boot [ -f "$DIR/.git/index.lock" ] && rm -f $DIR/.git/index.lock @@ -71,6 +89,7 @@ function launch { # hardware specific init if [ -f /AGNOS ]; then + check_device_mode agnos_init fi diff --git a/selfdrive/monitoring/dpmonitoringd.py b/selfdrive/monitoring/dpmonitoringd.py new file mode 100644 index 000000000..668782d01 --- /dev/null +++ b/selfdrive/monitoring/dpmonitoringd.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +import time +import cereal.messaging as messaging +from openpilot.common.params import Params +from openpilot.common.realtime import config_realtime_process, Ratekeeper, DT_DMON +from cereal import log + +EventName = log.OnroadEvent.EventName + +class SimpleDriverMonitoring: + def __init__(self): + # Timing configuration (in seconds) + self.FIRST_WARNING_TIME = 45.0 + self.SECOND_WARNING_TIME = 60.0 + self.THIRD_WARNING_TIME = 75.0 + + # State variables + self.awareness = 1.0 # Full awareness + self.current_events = [] + # self.last_interaction_time = 0 + self.hands_on_steering = False + + # Warning thresholds (normalized to 0-1 scale) + self.threshold_prompt = self.FIRST_WARNING_TIME / self.THIRD_WARNING_TIME # ~0.643 for first warning + self.threshold_critical = self.SECOND_WARNING_TIME / self.THIRD_WARNING_TIME # ~0.857 for second warning + + # Step change (how much awareness decreases per step) + self.step_change = DT_DMON / self.THIRD_WARNING_TIME + + params = Params() + self.is_rhd = params.get_bool("dp_device_is_rhd") + self.monitoring_disabled = params.get_bool("dp_device_monitoring_disabled") + + def update_events(self, reset_condition, op_engaged): + self.current_events = [] + + if self.monitoring_disabled: + return + + # If not engaged, reset awareness and return + if not op_engaged: + self.awareness = 1.0 + return + + # Reset awareness on any reset condition (standstill, any input) + if reset_condition: + self.awareness = 1.0 + return + + # Only decrease awareness if we're not detecting hands on steering + self.awareness = max(self.awareness - self.step_change, 0.0) + + # Determine alert level based on awareness + if self.awareness <= 0.0: + # Third warning (red alert) at 70 seconds + self.current_events.append(EventName.driverUnresponsive) + elif self.awareness <= (1.0 - self.threshold_critical): + # Second warning (orange alert) at 60 seconds + self.current_events.append(EventName.promptDriverUnresponsive) + elif self.awareness <= (1.0 - self.threshold_prompt): + # First warning (green alert) at 45 seconds + self.current_events.append(EventName.preDriverUnresponsive) + + def get_state_packet(self, valid=True): + # Create driver monitoring state message + dat = messaging.new_message('driverMonitoringState', valid=valid) + events = [] + + for event_name in self.current_events: + event = log.OnroadEvent.new_message() + event.name = event_name + events.append(event) + + dat.driverMonitoringState = { + "events": events, + "faceDetected": False, # Not using face detection + "isDistracted": self.awareness <= (1.0 - self.threshold_prompt), + "distractedType": 0, # Not using distraction types + "awarenessStatus": 1.0, #self.awareness, (always 1.0 so no decel) + "posePitchOffset": 0.0, + "posePitchValidCount": 0, + "poseYawOffset": 0.0, + "poseYawValidCount": 0, + "stepChange": self.step_change, + "awarenessActive": self.awareness, + "awarenessPassive": self.awareness, + "isLowStd": True, + "hiStdCount": 0, + "isActiveMode": True, + "isRHD": self.is_rhd, + } + return dat + +def dmonitoringd_thread(): + # Configure process priority + config_realtime_process([0, 1, 2, 3], 5) + + # Initialize parameters and messaging + pm = messaging.PubMaster(['driverMonitoringState']) + sm = messaging.SubMaster(['carState', 'selfdriveState']) + + # Initialize driver monitoring system + DM = SimpleDriverMonitoring() + + # Create ratekeeper for 20Hz operation + rk = Ratekeeper(20, None) + + # Main loop running at 20Hz + while True: + sm.update() + + # Check if steering is touched (only monitoring steering for hands-on) + + # Reset conditions: not engaged, standstill, or any input + reset_condition = ( + sm['carState'].standstill or + sm['carState'].steeringPressed or + sm['carState'].gasPressed or + sm['carState'].brakePressed or + sm['carState'].leftBlinker or + sm['carState'].rightBlinker + ) + + # Process driver monitoring - monitoring only steering for hands-on + # but resetting on any input + DM.update_events( + reset_condition=reset_condition, + op_engaged=sm['selfdriveState'].enabled + ) + + # Publish driver monitoring state + dat = DM.get_state_packet() + pm.send('driverMonitoringState', dat) + + # Maintain 20Hz + rk.keep_time() + +def main(): + dmonitoringd_thread() + +if __name__ == '__main__': + main() diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index 1666c6229..eef00a05b 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -372,6 +372,7 @@ void process_peripheral_state(Panda *panda, PubMaster *pm, bool no_fan_control) static uint16_t prev_fan_speed = 999; static uint16_t ir_pwr = 0; static uint16_t prev_ir_pwr = 999; + const bool disable_driver = getenv("DISABLE_DRIVER"); static FirstOrderFilter integ_lines_filter(0, 30.0, 0.05); @@ -386,7 +387,7 @@ void process_peripheral_state(Panda *panda, PubMaster *pm, bool no_fan_control) } } - if (sm.updated("driverCameraState")) { + if (!disable_driver && sm.updated("driverCameraState")) { auto event = sm["driverCameraState"]; int cur_integ_lines = event.getDriverCameraState().getIntegLines(); @@ -403,7 +404,7 @@ void process_peripheral_state(Panda *panda, PubMaster *pm, bool no_fan_control) } // Disable IR on input timeout - if (nanos_since_boot() - last_driver_camera_t > 1e9) { + if (!disable_driver && nanos_since_boot() - last_driver_camera_t > 1e9) { ir_pwr = 0; } diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 3065f6b80..4e735093d 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -72,6 +72,8 @@ class SelfdriveD: if REPLAY: # no vipc in replay will make them ignored anyways ignore += ['roadCameraState', 'wideRoadCameraState'] + if os.getenv("DISABLE_DRIVER"): + ignore += ['driverCameraState'] self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration', 'carOutput', 'driverMonitoringState', 'longitudinalPlan', 'livePose', 'liveDelay', 'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters', diff --git a/selfdrive/ui/qt/offroad/dp_panel.cc b/selfdrive/ui/qt/offroad/dp_panel.cc index 548b02be5..93384bdb1 100644 --- a/selfdrive/ui/qt/offroad/dp_panel.cc +++ b/selfdrive/ui/qt/offroad/dp_panel.cc @@ -205,17 +205,36 @@ void DPPanel::add_device_toggles() { QString::fromUtf8("🐉 ") + tr("Device"), "", }, + { + "dp_device_is_rhd", + tr("Enable Right-Hand Drive Mode"), + tr("Allow openpilot to obey right-hand traffic conventions on right driver seat."), + }, + { + "dp_device_monitoring_disabled", + tr("Disable Driver Monitoring"), + "", + }, + { + "dp_device_beep", + tr("Enable Beep (Warning)"), + "", + } }; QWidget *label = nullptr; bool has_toggle = false; + const bool disable_driver = getenv("DISABLE_DRIVER"); for (auto &[param, title, desc] : toggle_defs) { if (param.isEmpty()) { label = new LabelControl(title, ""); addItem(label); continue; } + if ((param == "dp_device_is_rhd" || param == "dp_device_monitoring_disabled" || param == "dp_device_beep") && !disable_driver) { + continue; + } has_toggle = true; auto toggle = new ParamControl(param, title, desc, "", this); diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 528355ef9..619bece14 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -96,8 +96,11 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { // set up uiState update for personality setting QObject::connect(uiState(), &UIState::uiUpdate, this, &TogglesPanel::updateState); - + const bool disable_driver = getenv("DISABLE_DRIVER"); for (auto &[param, title, desc, icon, needs_restart] : toggle_defs) { + if ((param == "AlwaysOnDM" || param == "RecordFront") && disable_driver) { + continue; + } auto toggle = new ParamControl(param, title, desc, icon, this); bool locked = params.getBool((param + "Lock").toStdString()); @@ -207,6 +210,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(new LabelControl(tr("Dongle ID"), getDongleId().value_or(tr("N/A")))); addItem(new LabelControl(tr("Serial"), params.get("HardwareSerial").c_str())); + const bool disable_driver = getenv("DISABLE_DRIVER"); pair_device = new ButtonControl(tr("Pair Device"), tr("PAIR"), tr("Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.")); connect(pair_device, &ButtonControl::clicked, [=]() { @@ -216,12 +220,12 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(pair_device); // offroad-only buttons - + if (!disable_driver) { auto dcamBtn = new ButtonControl(tr("Driver Camera"), tr("PREVIEW"), tr("Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off)")); connect(dcamBtn, &ButtonControl::clicked, [=]() { emit showDriverView(); }); addItem(dcamBtn); - + } auto resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), ""); connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription); connect(resetCalibBtn, &ButtonControl::clicked, [&]() { diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index f504ad69f..24addec40 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -24,7 +24,9 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget *par void AnnotatedCameraWidget::updateState(const UIState &s) { // update engageability/experimental mode button experimental_btn->updateState(s); - dmon.updateState(s); + if (!s.scene.disable_driver) { + dmon.updateState(s); + } } void AnnotatedCameraWidget::initializeGL() { @@ -130,7 +132,9 @@ void AnnotatedCameraWidget::paintGL() { painter.setPen(Qt::NoPen); model.draw(painter, rect()); - dmon.draw(painter, rect()); + if (!s->scene.disable_driver) { + dmon.draw(painter, rect()); + } hud.updateState(*s); hud.draw(painter, rect()); diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc index bcdb72bbe..d1ec6633a 100644 --- a/selfdrive/ui/qt/util.cc +++ b/selfdrive/ui/qt/util.cc @@ -26,7 +26,8 @@ QString getVersion() { } QString getBrand() { - return QObject::tr("dragonpilot"); + const bool disable_driver = getenv("DISABLE_DRIVER"); + return QObject::tr("dragonpilot") + (disable_driver ? QString::fromStdString(" - Lite") : QString("")); } QString getUserAgent() { diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 79a245a0e..09f43803b 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -65,6 +65,7 @@ static void update_state(UIState *s) { void ui_update_params(UIState *s) { auto params = Params(); s->scene.is_metric = params.getBool("IsMetric"); + s->scene.disable_driver = getenv("DISABLE_DRIVER"); } void UIState::updateStatus() { diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index fd2aee771..f0e68bac2 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -60,6 +60,7 @@ typedef struct UIScene { float light_sensor = -1; bool started, ignition, is_metric; uint64_t started_frame; + bool disable_driver = false; } UIScene; class UIState : public QObject { diff --git a/system/athena/registration.py b/system/athena/registration.py index ce7fcea89..3a9bf9bc3 100755 --- a/system/athena/registration.py +++ b/system/athena/registration.py @@ -11,6 +11,7 @@ from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.system.hardware import HARDWARE, PC from openpilot.system.hardware.hw import Paths from openpilot.common.swaglog import cloudlog +import os UNREGISTERED_DONGLE_ID = "UnregisteredDevice" @@ -43,6 +44,9 @@ def register(show_spinner=False) -> str | None: dongle_id = UNREGISTERED_DONGLE_ID cloudlog.warning(f"missing public key: {pubkey}") elif dongle_id is None: + if os.getenv("DISABLE_DRIVER"): + params.put("DongleId", UNREGISTERED_DONGLE_ID) + return dongle_id if show_spinner: from openpilot.system.ui.spinner import Spinner spinner = Spinner() @@ -74,7 +78,7 @@ def register(show_spinner=False) -> str | None: try: register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)}, private_key, algorithm='RS256') cloudlog.info("getting pilotauth") - resp = api_get("v2/pilotauth/", method='POST', timeout=15, + resp = api_get("v2/pilotauth/", method='POST', timeout=5, imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token) if resp.status_code in (402, 403): diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 8c4602bb3..d6ace8d76 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -270,6 +270,7 @@ void camerad_thread() { // *** per-cam init *** std::vector> cams; for (const auto &config : ALL_CAMERA_CONFIGS) { + if (!config.enabled) continue; auto cam = std::make_unique(&m, config); cam->init(&v, device_id, ctx); cams.emplace_back(std::move(cam)); diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 15a191adc..4204818af 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -326,7 +326,7 @@ def hardware_thread(end_event, hw_queue) -> None: set_offroad_alert_if_changed("Offroad_TemperatureTooHigh", show_alert, extra_text=extra_text) # TODO: this should move to TICI.initialize_hardware, but we currently can't import params there - if TICI and HARDWARE.get_device_type() == "tici": + if TICI and HARDWARE.get_device_type() == "tici" and not os.getenv("DISABLE_DRIVER"): if not os.path.isfile("/persist/comma/living-in-the-moment"): if not Path("/data/media").is_mount(): set_offroad_alert_if_changed("Offroad_StorageMissing", True) diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 8e4ba722c..5f28976e1 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -95,7 +95,7 @@ class Tici(HardwareBase): @cached_property def amplifier(self): - if self.get_device_type() == "mici": + if self.get_device_type() == "mici" or os.getenv("DISABLE_DRIVER"): return None return Amplifier() @@ -191,7 +191,7 @@ class Tici(HardwareBase): return str(self.get_modem().Get(MM_MODEM, 'EquipmentIdentifier', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)) def get_network_info(self): - if self.get_device_type() == "mici": + if self.get_device_type() == "mici" or os.getenv("DISABLE_DRIVER"): return None try: modem = self.get_modem() @@ -283,6 +283,8 @@ class Tici(HardwareBase): return None def get_modem_temperatures(self): + if os.getenv("DISABLE_DRIVER"): + return [] timeout = 0.2 # Default timeout is too short try: modem = self.get_modem() diff --git a/system/loggerd/loggerd.cc b/system/loggerd/loggerd.cc index 2d2d4640e..f2f5cdde9 100644 --- a/system/loggerd/loggerd.cc +++ b/system/loggerd/loggerd.cc @@ -222,11 +222,23 @@ void loggerd_thread() { std::unique_ptr ctx(Context::create()); std::unique_ptr poller(Poller::create()); + const bool disable_driver = getenv("DISABLE_DRIVER"); + const std::set driver_signals = { + "driverCameraState", + "driverEncodeIdx", + "driverStateV2", + "driverMonitoringState", + "driverEncodeData", + "livestreamDriverEncodeIdx", + "livestreamDriverEncodeData" + }; + // subscribe to all socks for (const auto& [_, it] : services) { const bool encoder = util::ends_with(it.name, "EncodeData"); const bool livestream_encoder = util::starts_with(it.name, "livestream"); if (!it.should_log && (!encoder || livestream_encoder)) continue; + if (disable_driver && driver_signals.count(it.name)) continue; LOGD("logging %s", it.name.c_str()); SubSocket * sock = SubSocket::create(ctx.get(), it.name); @@ -249,7 +261,15 @@ void loggerd_thread() { std::map encoder_infos_dict; for (const auto &cam : cameras_logged) { for (const auto &encoder_info : cam.encoder_infos) { - encoder_infos_dict[encoder_info.publish_name] = encoder_info; + const std::string &name = encoder_info.publish_name; + if (disable_driver && ( + name == "driverEncodeData" || + name == "driverEncodeIdx" || + name == "livestreamDriverEncodeData" || + name == "livestreamDriverEncodeIdx")) { + continue; + } + encoder_infos_dict[name] = encoder_info; s.max_waiting++; } } diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 27d2d37fc..4cb925497 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -70,7 +70,7 @@ const EncoderInfo main_wide_road_encoder_info = { const EncoderInfo main_driver_encoder_info = { .publish_name = "driverEncodeData", .filename = "dcamera.hevc", - .record = Params().getBool("RecordFront"), + .record = !getenv("DISABLE_DRIVER") && Params().getBool("RecordFront"), INIT_ENCODE_FUNCTIONS(DriverEncode), }; diff --git a/system/manager/manager.py b/system/manager/manager.py index 5dc08c6d3..2c84ea5e5 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -40,6 +40,9 @@ def manager_init() -> None: ("OpenpilotEnabledToggle", "1"), ("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)), ("DisableLogging", "0"), + ("dp_device_is_rhd", "0"), + ("dp_device_monitoring_disabled", "0"), + ("dp_device_beep", "0"), ] if params.get_bool("RecordFrontLock"): diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 50845e988..78e39aa06 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -73,15 +73,16 @@ procs = [ PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM), NativeProcess("logcatd", "system/logcatd", ["./logcatd"], only_onroad, platform.system() != "Darwin"), NativeProcess("proclogd", "system/proclogd", ["./proclogd"], only_onroad, platform.system() != "Darwin"), - PythonProcess("micd", "system.micd", iscar), + PythonProcess("micd", "system.micd", iscar, enabled=not os.getenv("DISABLE_DRIVER")), PythonProcess("timed", "system.timed", always_run, enabled=not PC), PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad), - PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), + PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC) and not os.getenv("DISABLE_DRIVER")), PythonProcess("sensord", "system.sensord.sensord", only_onroad, enabled=not PC), NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), - PythonProcess("soundd", "selfdrive.ui.soundd", only_onroad), + PythonProcess("soundd", "selfdrive.ui.soundd", only_onroad, enabled=not os.getenv("DISABLE_DRIVER")), + PythonProcess("beepd", "dragonpilot.selfdrive.ui.beepd", only_onroad, enabled=(Params().get_bool("dp_device_beep") and os.getenv("DISABLE_DRIVER"))), PythonProcess("locationd", "selfdrive.locationd.locationd", only_onroad), NativeProcess("_pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False), PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), @@ -91,7 +92,8 @@ procs = [ PythonProcess("selfdrived", "selfdrive.selfdrived.selfdrived", only_onroad), PythonProcess("card", "selfdrive.car.card", only_onroad), PythonProcess("deleter", "system.loggerd.deleter", always_run), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), + PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC) and not os.getenv("DISABLE_DRIVER")), + PythonProcess("dpmonitoringd", "selfdrive.monitoring.dpmonitoringd", only_onroad, enabled=os.getenv("DISABLE_DRIVER")), PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),