diff --git a/common/params_keys.h b/common/params_keys.h index e0af53b29..afb6b348e 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -154,6 +154,7 @@ inline static std::unordered_map keys = { {"MaxTimeOffroad", {PERSISTENT | BACKUP, INT, "1800"}}, {"ModelRunnerTypeCache", {CLEAR_ON_ONROAD_TRANSITION, INT}}, {"OffroadMode", {CLEAR_ON_MANAGER_START, BOOL}}, + {"Offroad_TiciSupport", {CLEAR_ON_MANAGER_START, JSON}}, {"QuickBootToggle", {PERSISTENT | BACKUP, BOOL, "0"}}, {"QuietMode", {PERSISTENT | BACKUP, BOOL, "0"}}, {"RainbowMode", {PERSISTENT | BACKUP, BOOL, "0"}}, diff --git a/selfdrive/selfdrived/alerts_offroad.json b/selfdrive/selfdrived/alerts_offroad.json index 183c1f854..87a007211 100644 --- a/selfdrive/selfdrived/alerts_offroad.json +++ b/selfdrive/selfdrived/alerts_offroad.json @@ -49,5 +49,10 @@ "text": "openpilot detected excessive %1 actuation on your last drive. Please contact support at https://comma.ai/support and share your device's Dongle ID for troubleshooting.", "severity": 1, "_comment": "Set extra field to lateral or longitudinal." + }, + "Offroad_TiciSupport": { + "text": "Unsupported branch detected - The current version of %1 branch is no longer supported on the comma three. Please go to [Device > Software] and install a supported branch with -tici in the branch name for the comma three.", + "severity": 1, + "_comment": "Set extra field to the current branch name." } } diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.cc index a1961cb1e..8bdb7703f 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.cc @@ -11,12 +11,39 @@ SoftwarePanelSP::SoftwarePanelSP(QWidget *parent) : SoftwarePanel(parent) { // branch selector QObject::disconnect(targetBranchBtn, nullptr, nullptr, nullptr); connect(targetBranchBtn, &ButtonControlSP::clicked, [=]() { - InputDialog d(tr("Search Branch"), this, tr("Enter search keywords, or leave blank to list all branches."), false); + if (Hardware::get_device_type() == cereal::InitData::DeviceType::TICI) { + auto current = params.get("GitBranch"); + QStringList allBranches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(","); + QStringList branches; + for (const QString &b : allBranches) { + if (b.endsWith("-tici")) { + branches.append(b); + } + } + + for (QString b : {current.c_str(), "master-tici", "staging-tici", "release-tici"}) { + auto i = branches.indexOf(b); + if (i >= 0) { + branches.removeAt(i); + branches.insert(0, b); + } + } + + QString cur = QString::fromStdString(params.get("UpdaterTargetBranch")); + QString selection = MultiOptionDialog::getSelection(tr("Select a branch"), branches, cur, this); + if (!selection.isEmpty()) { + params.put("UpdaterTargetBranch", selection.toStdString()); + targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch"))); + checkForUpdates(); + } + } else { + InputDialog d(tr("Search Branch"), this, tr("Enter search keywords, or leave blank to list all branches."), false); d.setMinLength(0); const int ret = d.exec(); if (ret) { searchBranches(d.text()); } + } }); // Disable Updates toggle diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index d702334fa..af0115414 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -24,7 +24,7 @@ from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog from openpilot.system.hardware.power_monitoring import PowerMonitoring from openpilot.system.hardware.fan_controller import TiciFanController -from openpilot.system.version import terms_version, training_version +from openpilot.system.version import terms_version, training_version, get_build_metadata ThermalStatus = log.DeviceState.ThermalStatus NetworkType = log.DeviceState.NetworkType @@ -326,6 +326,16 @@ def hardware_thread(end_event, hw_queue) -> None: startup_conditions["not_always_offroad"] = not offroad_mode onroad_conditions["not_always_offroad"] = not offroad_mode + # if an unsupported device and branch is detected, going onroad is blocked + # only allow going onroad when: + # - TIZI, or + # - TICI and channel_type is "tici" + build_metadata = get_build_metadata() + is_unsupported_combo = TICI and build_metadata.channel_type != "tici" + startup_conditions["not_tici"] = not is_unsupported_combo + onroad_conditions["not_tici"] = not is_unsupported_combo + set_offroad_alert("Offroad_TiciSupport", is_unsupported_combo, extra_text=build_metadata.channel) + # 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" diff --git a/system/updated/updated.py b/system/updated/updated.py index dfeaf88cb..7ab9e070d 100755 --- a/system/updated/updated.py +++ b/system/updated/updated.py @@ -18,7 +18,7 @@ from openpilot.common.markdown import parse_markdown from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.system.hardware import AGNOS, HARDWARE -from openpilot.system.version import get_build_metadata +from openpilot.system.version import get_build_metadata, SP_BRANCH_MIGRATIONS LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") @@ -232,9 +232,7 @@ class Updater: b: str | None = self.params.get("UpdaterTargetBranch") if b is None: b = self.get_branch(BASEDIR) - b = { - ("tici", "release3"): "release-tici" - }.get((HARDWARE.get_device_type(), b), b) + b = SP_BRANCH_MIGRATIONS.get((HARDWARE.get_device_type(), b), b) return b @property diff --git a/system/version.py b/system/version.py index 5e65a7c64..87044b84a 100755 --- a/system/version.py +++ b/system/version.py @@ -16,6 +16,13 @@ MASTER_SP_BRANCHES = ['master'] RELEASE_BRANCHES = ['release3-staging', 'release3', 'release-tici', 'nightly'] + RELEASE_SP_BRANCHES TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging', 'nightly-dev'] + TESTED_SP_BRANCHES +SP_BRANCH_MIGRATIONS = { + ("tici", "staging-c3-new"): "staging-tici", + ("tici", "dev-c3-new"): "staging-tici", + ("tici", "master"): "master-tici", + ("tici", "master-dev-c3-new"): "master-tici", +} + BUILD_METADATA_FILENAME = "build.json" training_version: str = "0.2.0" @@ -128,7 +135,9 @@ class BuildMetadata: @property def channel_type(self) -> str: - if self.development_channel: + if self.channel.endswith("-tici"): + return "tici" + elif self.development_channel: return "development" elif self.channel.startswith("staging-"): return "staging"