From 5f10529a88b91f46ed14caac6a58c47cb1aa4a80 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 20 Jan 2025 16:59:54 -0500 Subject: [PATCH] Device: Offroad Mode (#596) * try scrolling * Revert "try scrolling" This reverts commit 18cc0828c0efe1ea0ed9d56c1788756a37b011d3. * init * event * add logic * last bit * expose toggle * update toggle * add offroad btn to it * fix * update --- common/params.cc | 2 + selfdrive/pandad/panda_safety.cc | 5 ++ selfdrive/pandad/pandad.cc | 10 ++-- selfdrive/pandad/pandad.h | 1 + selfdrive/selfdrived/alerts_offroad.json | 4 ++ .../qt/offroad/settings/device_panel.cc | 51 ++++++++++++++++++- .../qt/offroad/settings/device_panel.h | 34 +++++++++++++ selfdrive/ui/translations/main_ar.ts | 32 ++++++++++++ selfdrive/ui/translations/main_de.ts | 32 ++++++++++++ selfdrive/ui/translations/main_es.ts | 32 ++++++++++++ selfdrive/ui/translations/main_fr.ts | 32 ++++++++++++ selfdrive/ui/translations/main_ja.ts | 32 ++++++++++++ selfdrive/ui/translations/main_ko.ts | 32 ++++++++++++ selfdrive/ui/translations/main_pt-BR.ts | 32 ++++++++++++ selfdrive/ui/translations/main_th.ts | 32 ++++++++++++ selfdrive/ui/translations/main_tr.ts | 32 ++++++++++++ selfdrive/ui/translations/main_zh-CHS.ts | 32 ++++++++++++ selfdrive/ui/translations/main_zh-CHT.ts | 32 ++++++++++++ system/hardware/hardwared.py | 8 ++- 19 files changed, 459 insertions(+), 8 deletions(-) diff --git a/common/params.cc b/common/params.cc index e8e05ff6b..82bce27d0 100644 --- a/common/params.cc +++ b/common/params.cc @@ -204,6 +204,8 @@ std::unordered_map keys = { {"ApiCache_DriveStats", PERSISTENT}, {"EnableGithubRunner", PERSISTENT | BACKUP}, {"ModelRunnerTypeCache", CLEAR_ON_ONROAD_TRANSITION}, + {"OffroadMode", CLEAR_ON_MANAGER_START}, + {"OffroadMode_Status", CLEAR_ON_MANAGER_START}, // MADS params {"Mads", PERSISTENT | BACKUP}, diff --git a/selfdrive/pandad/panda_safety.cc b/selfdrive/pandad/panda_safety.cc index 0a1489467..6d5e5ce4f 100644 --- a/selfdrive/pandad/panda_safety.cc +++ b/selfdrive/pandad/panda_safety.cc @@ -81,3 +81,8 @@ void PandaSafety::setSafetyMode(const std::string ¶ms_string) { pandas_[i]->set_safety_model(safety_model, safety_param); } } + +bool PandaSafety::getOffroadMode() { + auto offroad_mode = params_.getBool("OffroadMode"); + return offroad_mode; +} diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index 470836ec8..7d3af5fe5 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -205,7 +205,7 @@ void fill_panda_can_state(cereal::PandaState::PandaCanState::Builder &cs, const cs.setCanCoreResetCnt(can_health.can_core_reset_cnt); } -std::optional send_panda_states(PubMaster *pm, const std::vector &pandas, bool spoofing_started) { +std::optional send_panda_states(PubMaster *pm, const std::vector &pandas, bool spoofing_started, PandaSafety *panda_safety) { bool ignition_local = false; const uint32_t pandas_cnt = pandas.size(); @@ -253,7 +253,7 @@ std::optional send_panda_states(PubMaster *pm, const std::vector health.ignition_line_pkt = 0; } - ignition_local |= ((health.ignition_line_pkt != 0) || (health.ignition_can_pkt != 0)); + ignition_local |= ((health.ignition_line_pkt != 0) || (health.ignition_can_pkt != 0)) && !panda_safety->getOffroadMode(); pandaStates.push_back(health); } @@ -340,7 +340,7 @@ void send_peripheral_state(Panda *panda, PubMaster *pm) { pm->send("peripheralState", msg); } -void process_panda_state(std::vector &pandas, PubMaster *pm, bool spoofing_started) { +void process_panda_state(std::vector &pandas, PubMaster *pm, bool spoofing_started, PandaSafety *panda_safety) { static SubMaster sm({"selfdriveState", "selfdriveStateSP", "carParams"}); std::vector connected_serials; @@ -349,7 +349,7 @@ void process_panda_state(std::vector &pandas, PubMaster *pm, bool spoof } { - auto ignition_opt = send_panda_states(pm, pandas, spoofing_started); + auto ignition_opt = send_panda_states(pm, pandas, spoofing_started, panda_safety); if (!ignition_opt) { LOGE("Failed to get ignition_opt"); return; @@ -461,7 +461,7 @@ void pandad_run(std::vector &pandas) { // Process panda state at 10 Hz if (rk.frame() % 10 == 0) { - process_panda_state(pandas, &pm, spoofing_started); + process_panda_state(pandas, &pm, spoofing_started, &panda_safety); panda_safety.configureSafetyMode(); } diff --git a/selfdrive/pandad/pandad.h b/selfdrive/pandad/pandad.h index dedd8ae79..b338b7037 100644 --- a/selfdrive/pandad/pandad.h +++ b/selfdrive/pandad/pandad.h @@ -12,6 +12,7 @@ class PandaSafety { public: PandaSafety(const std::vector &pandas) : pandas_(pandas) {} void configureSafetyMode(); + bool getOffroadMode(); private: void updateMultiplexingMode(); diff --git a/selfdrive/selfdrived/alerts_offroad.json b/selfdrive/selfdrived/alerts_offroad.json index 86e07d321..1660e5d92 100644 --- a/selfdrive/selfdrived/alerts_offroad.json +++ b/selfdrive/selfdrived/alerts_offroad.json @@ -44,5 +44,9 @@ "Offroad_Recalibration": { "text": "openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.", "severity": 0 + }, + "OffroadMode_Status": { + "text": "sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to \"Settings\" -> \"Device\" to exit Always Offroad mode.", + "severity": 1 } } diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc index 89fe0bacf..1d9e973b5 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.cc @@ -93,13 +93,60 @@ DevicePanelSP::DevicePanelSP(SettingsWindowSP *parent) : DevicePanel(parent) { connect(uiState(), &UIState::offroadTransition, poweroffBtn, &PushButtonSP::setVisible); } - addItem(power_layout); + offroadBtn = new PushButtonSP(tr("Offroad Mode")); + offroadBtn->setFixedWidth(power_layout->sizeHint().width()); + QObject::connect(offroadBtn, &PushButtonSP::clicked, this, &DevicePanelSP::setOffroadMode); + + QVBoxLayout *power_group_layout = new QVBoxLayout(); + power_group_layout->setSpacing(30); + power_group_layout->addWidget(offroadBtn, 0, Qt::AlignHCenter); + power_group_layout->addLayout(power_layout); + + addItem(power_group_layout); QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { for (auto btn : findChildren()) { - if (btn != rebootBtn && btn != poweroffBtn) { + if (btn != rebootBtn && btn != poweroffBtn && btn != offroadBtn) { btn->setEnabled(offroad); } } }); } + +void DevicePanelSP::setOffroadMode() { + if (!uiState()->engaged()) { + if (params.getBool("OffroadMode")) { + if (ConfirmationDialog::confirm(tr("Are you sure you want to exit Always Offroad mode?"), tr("Confirm"), this)) { + // Check engaged again in case it changed while the dialog was open + if (!uiState()->engaged()) { + params.remove("OffroadMode"); + } + } + } else { + if (ConfirmationDialog::confirm(tr("Are you sure you want to enter Always Offroad mode?"), tr("Confirm"), this)) { + // Check engaged again in case it changed while the dialog was open + if (!uiState()->engaged()) { + params.putBool("OffroadMode", true); + } + } + } + } else { + ConfirmationDialog::alert(tr("Disengage to Enter Always Offroad Mode"), this); + } + + updateState(); +} + +void DevicePanelSP::showEvent(QShowEvent *event) { + updateState(); +} + +void DevicePanelSP::updateState() { + if (!isVisible()) { + return; + } + + bool offroad_mode_param = params.getBool("OffroadMode"); + offroadBtn->setText(offroad_mode_param ? tr("Exit Always Offroad") : tr("Always Offroad")); + offroadBtn->setStyleSheet(offroad_mode_param ? alwaysOffroadStyle : autoOffroadStyle); +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h index f1a18a825..a781019e5 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h @@ -15,9 +15,43 @@ class DevicePanelSP : public DevicePanel { public: explicit DevicePanelSP(SettingsWindowSP *parent = 0); + void showEvent(QShowEvent *event) override; + void setOffroadMode(); + void updateState(); private: std::map buttons; + PushButtonSP *offroadBtn; + + const QString alwaysOffroadStyle = R"( + PushButtonSP { + border-radius: 20px; + font-size: 50px; + font-weight: 450; + height: 150px; + padding: 0 25px 0 25px; + color: #FFFFFF; + background-color: #393939; + } + PushButtonSP:pressed { + background-color: #4A4A4A; + } + )"; + + const QString autoOffroadStyle = R"( + PushButtonSP { + border-radius: 20px; + font-size: 50px; + font-weight: 450; + height: 150px; + padding: 0 25px 0 25px; + color: #FFFFFF; + background-color: #E22C2C; + } + PushButtonSP:pressed { + background-color: #FF2424; + } + )"; const QString rebootButtonStyle = R"( PushButtonSP { diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 9d81ba753..9bcda5568 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -321,6 +321,34 @@ Power Off إيقاف التشغيل + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + تأكيد + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -527,6 +555,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. لقد اكتشف openpilot تغييراً في موقع تركيب الجهاز. تأكد من تثبيت الجهاز بشكل كامل في موقعه وتثبيته بإحكام على الزجاج الأمامي. + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 690b0e4be..9b83f7456 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -321,6 +321,34 @@ Power Off Ausschalten + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + Bestätigen + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -522,6 +550,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index 93c275403..0e50b06ce 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -321,6 +321,34 @@ Power Off Apagar + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + Confirmar + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -523,6 +551,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. openpilot detectó un cambio en la posición de montaje del dispositivo. Asegúrese de que el dispositivo esté completamente asentado en el soporte y que el soporte esté firmemente asegurado al parabrisas. + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index 56a08ca63..bb6b95eb6 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -321,6 +321,34 @@ Power Off Éteindre + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + Confirmer + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -523,6 +551,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. openpilot a détecté un changement dans la position de montage de l'appareil. Assurez-vous que l'appareil est totalement inséré dans le support et que le support est fermement fixé au pare-brise. + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 6fa9925ff..a6104916e 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -321,6 +321,34 @@ Power Off 電源を切る + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + 確認 + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -521,6 +549,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 3b425b054..25add5004 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -321,6 +321,34 @@ Power Off 전원 끄기 + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + 확인 + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -522,6 +550,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 장치 온도가 너무 높습니다. 시작하기 전에 온도를 낮춰주세요. 현재 내부 부품 온도: %1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 86add7472..e1c0fc11c 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -321,6 +321,34 @@ Power Off Desligar + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + Confirmar + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -523,6 +551,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 Temperatura do dispositivo muito alta. O sistema está sendo resfriado antes de iniciar. A temperatura atual do componente interno é: %1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index d28da2a63..a79c23d1c 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -321,6 +321,34 @@ Power Off ปิดเครื่อง + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + ยืนยัน + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -522,6 +550,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. openpilot ตรวจพบการเปลี่ยนแปลงของตำแหน่งที่ติดตั้ง กรุณาตรวจสอบว่าได้เลื่อนอุปกรณ์เข้ากับจุดติดตั้งจนสุดแล้ว และจุดติดตั้งได้ยึดติดกับกระจกหน้าอย่างแน่นหนา + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 8cc5bb013..f43c332a7 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -321,6 +321,34 @@ Power Off Sistemi kapat + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + Onayla + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -521,6 +549,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 197341653..204171430 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -321,6 +321,34 @@ Power Off 关机 + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + 确认 + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -522,6 +550,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 设备温度过高。系统正在冷却中,等冷却完毕后才会启动。目前内部组件温度:%1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index dc82be95c..f5cf33d54 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -321,6 +321,34 @@ Power Off 關機 + + Offroad Mode + + + + Are you sure you want to exit Always Offroad mode? + + + + Confirm + 確認 + + + Are you sure you want to enter Always Offroad mode? + + + + Disengage to Enter Always Offroad Mode + + + + Exit Always Offroad + + + + Always Offroad + + DriveStats @@ -522,6 +550,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Device temperature too high. System cooling down before starting. Current internal component temperature: %1 裝置溫度過高。系統正在冷卻中,等冷卻完畢後才會啟動。目前內部組件溫度:%1 + + sunnypilot is now in Always Offroad mode. sunnypilot won't start until Always Offroad mode is disabled. Go to "Settings" -> "Device" to exit Always Offroad mode. + + OffroadHome diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index b6de91818..bb90c12ba 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -310,6 +310,12 @@ def hardware_thread(end_event, hw_queue) -> None: # ensure device is fully booted startup_conditions["device_booted"] = startup_conditions.get("device_booted", False) or HARDWARE.booted() + # user-forced status + offroad_mode = params.get_bool("OffroadMode") + startup_conditions["not_always_offroad"] = not offroad_mode + onroad_conditions["not_always_offroad"] = not offroad_mode + set_offroad_alert("OffroadMode_Status", offroad_mode) + # if the temperature enters the danger zone, go offroad to cool down onroad_conditions["device_temp_good"] = thermal_status < ThermalStatus.danger extra_text = f"{offroad_comp_temp:.1f}C" @@ -392,7 +398,7 @@ def hardware_thread(end_event, hw_queue) -> None: cloudlog.warning(f"shutting device down, offroad since {off_ts}") params.put_bool("DoShutdown", True) - msg.deviceState.started = started_ts is not None + msg.deviceState.started = started_ts is not None and not offroad_mode msg.deviceState.startedMonoTime = int(1e9*(started_ts or 0)) last_ping = params.get("LastAthenaPingTime")