From f833819143926bf987070632588a0dc271e84c55 Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Fri, 31 Oct 2025 17:54:39 +0100 Subject: [PATCH 1/6] ci: update trigger for prebuilt (#1439) Updated workflow `if` conditions to use `vars.PREBUILT_PR_LABEL`. --- .github/workflows/sunnypilot-master-dev-prep.yaml | 4 ++-- .../ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sunnypilot-master-dev-prep.yaml b/.github/workflows/sunnypilot-master-dev-prep.yaml index 968540955..e93e778aa 100644 --- a/.github/workflows/sunnypilot-master-dev-prep.yaml +++ b/.github/workflows/sunnypilot-master-dev-prep.yaml @@ -42,7 +42,7 @@ jobs: if: ( (github.event_name == 'workflow_dispatch') || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) - || (contains(github.event_name, 'pull_request') && ((github.event.action == 'labeled' && (github.event.label.name == 'dev' || github.event.label.name == 'trust-fork-pr') && contains(github.event.pull_request.labels.*.name, 'dev')))) + || (contains(github.event_name, 'pull_request') && ((github.event.action == 'labeled' && (github.event.label.name == vars.PREBUILT_PR_LABEL || github.event.label.name == 'trust-fork-pr') && contains(github.event.pull_request.labels.*.name, vars.PREBUILT_PR_LABEL)))) ) steps: - uses: actions/checkout@v4 @@ -54,7 +54,7 @@ jobs: uses: ./.github/workflows/wait-for-action # Path to where you place the action if: ( (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)) - || (contains(github.event_name, 'pull_request') && ((github.event.action == 'labeled' && (github.event.label.name == 'dev' || github.event.label.name == 'trust-fork-pr') && contains(github.event.pull_request.labels.*.name, 'dev')))) + || (contains(github.event_name, 'pull_request') && ((github.event.action == 'labeled' && (github.event.label.name == vars.PREBUILT_PR_LABEL || github.event.label.name == 'trust-fork-pr') && contains(github.event.pull_request.labels.*.name, vars.PREBUILT_PR_LABEL)))) ) with: workflow: selfdrive_tests.yaml # The workflow file to monitor diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc index 4bbf89457..86b5b93e2 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc @@ -290,7 +290,7 @@ void SunnylinkPanel::updatePanel() { pairSponsorBtn->setEnabled(!is_onroad && is_sunnylink_enabled); pairSponsorBtn->setValue(is_paired ? tr("Paired") : tr("Not Paired")); - sunnylinkUploaderEnabledBtn->setEnabled(max_current_sponsor_rule.roleTier == SponsorTier::Guardian && is_sunnylink_enabled); + sunnylinkUploaderEnabledBtn->setEnabled(max_current_sponsor_rule.roleTier >= SponsorTier::Novice && is_sunnylink_enabled); if (!is_sunnylink_enabled) { sunnylinkEnabledBtn->setValue(""); From f60c2b6a835201ac06fa109ae98b14c36afabe18 Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Sat, 1 Nov 2025 12:14:57 +0100 Subject: [PATCH 2/6] sunnylink: update uploader button logic to support novice tier and above (#1438) * sunnylink: update uploader button logic to support novice tier and above - Adjusted the enable condition to include SponsorTier::Novice and above. * sunnylink: improve uploader button visibility and accessibility logic - Made uploader button conditionally visible based on user tier and settings. - Clarified button label to specify testing purposes only. --- .../ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc index 86b5b93e2..924d1d3c0 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc @@ -90,7 +90,7 @@ SunnylinkPanel::SunnylinkPanel(QWidget *parent) : QFrame(parent) { QString sunnylinkUploaderDesc = tr("Enable sunnylink uploader to allow sunnypilot to upload your driving data to sunnypilot servers. (only for highest tiers, and does NOT bring ANY benefit to you. We are just testing data volume.)"); sunnylinkUploaderEnabledBtn = new ParamControlSP( "EnableSunnylinkUploader", - tr("[Don't use] Enable sunnylink uploader"), + tr("Enable sunnylink uploader (just for testing infrastructure)"), sunnylinkUploaderDesc, "", nullptr, true); list->addItem(sunnylinkUploaderEnabledBtn); @@ -290,7 +290,10 @@ void SunnylinkPanel::updatePanel() { pairSponsorBtn->setEnabled(!is_onroad && is_sunnylink_enabled); pairSponsorBtn->setValue(is_paired ? tr("Paired") : tr("Not Paired")); - sunnylinkUploaderEnabledBtn->setEnabled(max_current_sponsor_rule.roleTier >= SponsorTier::Novice && is_sunnylink_enabled); + bool can_do_uploads = max_current_sponsor_rule.roleTier >= SponsorTier::Novice && is_sunnylink_enabled; + sunnylinkUploaderEnabledBtn->setVisible(can_do_uploads); + sunnylinkUploaderEnabledBtn->setEnabled(can_do_uploads); + if (!is_sunnylink_enabled) { sunnylinkEnabledBtn->setValue(""); From 682d738ffac3432549643a9889e1424192f88291 Mon Sep 17 00:00:00 2001 From: Amy Jeanes Date: Sun, 2 Nov 2025 02:47:30 +0000 Subject: [PATCH 3/6] Tesla: Coop Steering (#1283) * Tesla: Coop Steering * bump * bump * sync with opendbc/master * resolve comment * add oscillation warning and add confirmation * styling desc * beta --------- Co-authored-by: Jason Wen --- common/params_keys.h | 1 + opendbc_repo | 2 +- .../settings/vehicle/tesla_settings.cc | 34 +++++++++++++++++++ .../offroad/settings/vehicle/tesla_settings.h | 2 +- sunnypilot/selfdrive/car/interfaces.py | 5 +++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index d8485be15..df53261eb 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -208,6 +208,7 @@ inline static std::unordered_map keys = { {"HyundaiLongitudinalTuning", {PERSISTENT | BACKUP, INT, "0"}}, {"SubaruStopAndGo", {PERSISTENT | BACKUP, BOOL, "0"}}, {"SubaruStopAndGoManualParkingBrake", {PERSISTENT | BACKUP, BOOL, "0"}}, + {"TeslaCoopSteering", {PERSISTENT | BACKUP, BOOL, "0"}}, {"DynamicExperimentalControl", {PERSISTENT | BACKUP, BOOL, "0"}}, {"BlindSpot", {PERSISTENT | BACKUP, BOOL, "0"}}, diff --git a/opendbc_repo b/opendbc_repo index e0e162682..c7126f8ba 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit e0e1626820d6a18a984ae69eebc012180699d41c +Subproject commit c7126f8ba620eb06fe345013081e97503331bbe1 diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.cc index 50ab02302..2fffdb8ad 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.cc @@ -8,7 +8,41 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.h" TeslaSettings::TeslaSettings(QWidget *parent) : BrandSettingsInterface(parent) { + constexpr int coopSteeringMinKmh = 23; // minimum speed for cooperative steering (enforced by Tesla firmware) + constexpr int oemSteeringMinKmh = 48; // minimum speed for OEM lane departure avoidance (enforced by Tesla firmware) + bool is_metric = params.getBool("IsMetric"); + QString unit = is_metric ? "km/h" : "mph"; + int display_value_coop; + int display_value_oem; + if (is_metric) { + display_value_coop = coopSteeringMinKmh; + display_value_oem = oemSteeringMinKmh; + } else { + display_value_coop = static_cast(std::round(coopSteeringMinKmh * KM_TO_MILE)); + display_value_oem = static_cast(std::round(oemSteeringMinKmh * KM_TO_MILE)); + } + const QString coop_desc = QString("%1

" + "%2
" + "%3
") + .arg(tr("Warning: May experience steering oscillations below %5 %6 during turns, recommend disabling this feature if you experience these.")) + .arg(tr("Allows the driver to provide limited steering input while openpilot is engaged.")) + .arg(tr("Only works above %4 %6.")) + .arg(display_value_coop) + .arg(display_value_oem) + .arg(unit); + + coopSteeringToggle = new ParamControlSP( + "TeslaCoopSteering", + tr("Cooperative Steering (Beta)"), + coop_desc, + "", + this + ); + list->addItem(coopSteeringToggle); + coopSteeringToggle->showDescription(); + coopSteeringToggle->setConfirmation(true, false); } void TeslaSettings::updateSettings() { + coopSteeringToggle->setEnabled(offroad); } diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.h index 37f2936cd..a1294513e 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.h +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/vehicle/tesla_settings.h @@ -22,5 +22,5 @@ public: void updateSettings() override; private: - bool offroad = false; + ParamControlSP *coopSteeringToggle = nullptr; }; diff --git a/sunnypilot/selfdrive/car/interfaces.py b/sunnypilot/selfdrive/car/interfaces.py index 7d63d3c5b..59cfeabd6 100644 --- a/sunnypilot/selfdrive/car/interfaces.py +++ b/sunnypilot/selfdrive/car/interfaces.py @@ -115,4 +115,9 @@ def initialize_params(params) -> list[dict[str, Any]]: "SubaruStopAndGoManualParkingBrake", ]) + # tesla + keys.extend([ + "TeslaCoopSteering", + ]) + return [{k: params.get(k, return_default=True)} for k in keys] From b81d5bca3c4418fad601f103f070f309077c16ed Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Sun, 2 Nov 2025 06:50:41 +0100 Subject: [PATCH 4/6] ui: update discord references and add forum widget (#1440) * sunnylink: introduce community popup with QR code embedding - Added `SunnylinkCommunityPopup` widget to promote the sunnypilot Community Forum. - Integrated a QR code generator and display for quick access. - Updated `WiFiPromptWidget` to include a "Learn More" button triggering the community popup. * sunnylink: adjust community popup styling for better layout - Reduced font size of description text slightly for consistency. - Decreased QR code dimensions to improve visual balance. * Making more space out of thin air * sunnylink: update community references to use forum links - Replaced Discord links with Community Forum URLs for better alignment. - Improved clarity in sponsorship instructions. --- selfdrive/ui/qt/widgets/wifi.cc | 11 +- selfdrive/ui/qt/widgets/wifi.h | 5 + selfdrive/ui/sunnypilot/SConscript | 1 + .../settings/sunnylink/community_widget.cc | 139 ++++++++++++++++++ .../settings/sunnylink/community_widget.h | 40 +++++ .../settings/sunnylink/sponsor_widget.cc | 4 +- 6 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h diff --git a/selfdrive/ui/qt/widgets/wifi.cc b/selfdrive/ui/qt/widgets/wifi.cc index d7eb8beeb..8958e48c9 100644 --- a/selfdrive/ui/qt/widgets/wifi.cc +++ b/selfdrive/ui/qt/widgets/wifi.cc @@ -11,17 +11,18 @@ WiFiPromptWidget::WiFiPromptWidget(QWidget *parent) : QFrame(parent) { main_layout->setContentsMargins(56, 40, 56, 40); main_layout->setSpacing(42); - QLabel *title = new QLabel(tr("🔥 Firehose Mode 🔥")); - title->setStyleSheet("font-size: 64px; font-weight: 500;"); + community_popup = new SunnylinkCommunityPopup(this); + QLabel *title = new QLabel(tr("sunnypilot Community")); + title->setStyleSheet("font-size: 56px; font-weight: 500;"); main_layout->addWidget(title); - QLabel *desc = new QLabel(tr("Maximize your training data uploads to improve openpilot's driving models.")); + QLabel *desc = new QLabel(tr("Need help or have ideas?
Join our community now!")); desc->setStyleSheet("font-size: 40px; font-weight: 400;"); desc->setWordWrap(true); main_layout->addWidget(desc); - QPushButton *settings_btn = new QPushButton(tr("Open")); - connect(settings_btn, &QPushButton::clicked, [=]() { emit openSettings(1, "FirehosePanel"); }); + QPushButton *settings_btn = new QPushButton(tr("Learn More")); + connect(settings_btn, &QPushButton::clicked, [=]() { community_popup->exec(); }); settings_btn->setStyleSheet(R"( QPushButton { font-size: 48px; diff --git a/selfdrive/ui/qt/widgets/wifi.h b/selfdrive/ui/qt/widgets/wifi.h index 3e68a15b7..8ef9dca91 100644 --- a/selfdrive/ui/qt/widgets/wifi.h +++ b/selfdrive/ui/qt/widgets/wifi.h @@ -3,12 +3,17 @@ #include #include +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h" + class WiFiPromptWidget : public QFrame { Q_OBJECT public: explicit WiFiPromptWidget(QWidget* parent = 0); +private: + SunnylinkCommunityPopup *community_popup; + signals: void openSettings(int index = 0, const QString ¶m = ""); }; diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index be92c1426..449093886 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -35,6 +35,7 @@ qt_src = [ "sunnypilot/qt/offroad/settings/software_panel.cc", "sunnypilot/qt/offroad/settings/sunnylink_panel.cc", "sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc", + "sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc", "sunnypilot/qt/offroad/settings/trips_panel.cc", "sunnypilot/qt/offroad/settings/vehicle_panel.cc", "sunnypilot/qt/offroad/settings/visuals_panel.cc", diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc new file mode 100644 index 000000000..e29e89ee9 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.cc @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2025-, sunnypilot contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h" + +#include "selfdrive/ui/sunnypilot/ui.h" +#include "selfdrive/ui/sunnypilot/qt/util.h" + +using qrcodegen::QrCode; + +// --- SunnylinkCommunityQRWidget --- + +SunnylinkCommunityQRWidget::SunnylinkCommunityQRWidget(QWidget* parent) + : QWidget(parent) {} + +void SunnylinkCommunityQRWidget::showEvent(QShowEvent *event) { + updateQrCode(SUNNYLINK_COMMUNITY_URL); + update(); +} + +void SunnylinkCommunityQRWidget::updateQrCode(const QString &text) { + QrCode qr = QrCode::encodeText(text.toUtf8().data(), QrCode::Ecc::LOW); + qint32 sz = qr.getSize(); + QImage im(sz, sz, QImage::Format_RGB32); + + QRgb black = qRgb(0, 0, 0); + QRgb white = qRgb(255, 255, 255); + for (int y = 0; y < sz; y++) { + for (int x = 0; x < sz; x++) { + im.setPixel(x, y, qr.getModule(x, y) ? black : white); + } + } + + int final_sz = ((width() / sz) - 1) * sz; + img = QPixmap::fromImage(im.scaled(final_sz, final_sz, Qt::KeepAspectRatio), Qt::MonoOnly); +} + +void SunnylinkCommunityQRWidget::paintEvent(QPaintEvent *e) { + QPainter p(this); + p.fillRect(rect(), Qt::white); + + if (!img.isNull()) { + QSize s = (size() - img.size()) / 2; + p.drawPixmap(s.width(), s.height(), img); + } +} + +// --- SunnylinkCommunityPopup --- + +QStringList SunnylinkCommunityPopup::getInstructions() { + QStringList instructions; + instructions << tr("Scan the QR code and join us!"); + return instructions; +} + +SunnylinkCommunityPopup::SunnylinkCommunityPopup(QWidget* parent) + : DialogBase(parent) { + auto *mainLayout = new QVBoxLayout(this); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + + // Solarized Light base3 background + setStyleSheet("SunnylinkCommunityPopup { background-color: #FDF6E3; }"); + + // Header spanning full width + auto headerWidget = new QWidget(this); + auto headerLayout = new QHBoxLayout(headerWidget); + headerLayout->setContentsMargins(85, 50, 85, 30); + headerLayout->setSpacing(30); + + auto close = new QPushButton(QIcon(":/icons/close.svg"), "", this); + close->setIconSize(QSize(80, 80)); + close->setStyleSheet("border: none;"); + connect(close, &QPushButton::clicked, this, &QDialog::reject); + headerLayout->addWidget(close, 0, Qt::AlignLeft | Qt::AlignVCenter); + + const auto title = new QLabel(tr("Join the sunnypilot Community Forum"), this); + // Solarized base02 for text + title->setStyleSheet("font-size: 65px; color: #073642;"); + title->setWordWrap(false); + title->setAlignment(Qt::AlignCenter); + headerLayout->addWidget(title, 1); + + // Spacer to balance the close button on the right + auto spacer = new QWidget(this); + spacer->setFixedSize(80, 80); + headerLayout->addWidget(spacer, 0); + + mainLayout->addWidget(headerWidget); + + // Two-column content layout + auto contentLayout = new QHBoxLayout(); + contentLayout->setContentsMargins(0, 0, 0, 0); + contentLayout->setSpacing(0); + mainLayout->addLayout(contentLayout, 66); + + // Left side: description + auto leftLayout = new QVBoxLayout(); + leftLayout->setContentsMargins(85, 40, 50, 70); + leftLayout->setSpacing(35); + contentLayout->addLayout(leftLayout, 40); + + // Hype / intro paragraph + const auto desc = new QLabel(tr( + "We're excited to announce our sunnypilot Community Forum

" + "Over the years, Discord just hasn't scaled well for our growing community.
" + "It's noisy, unsearchable, and great discussions disappear too easily.
" + "Our new community forum aims to fix that by making it easier to find answers, share ideas, track feedback, report bugs, help newcomers and more!

" + "Here's what's waiting for you:
" + "• Fully indexable and discoverable through search engines 🔎
" + "• AI-powered🤖 topic and chat summaries, spam detection, and more
" + "• A trust-level system✅ that rewards meaningful contributions
" + "• Designed to work on your own time.🧘

" + "Scan the QR code on the right and join the discussion!" + ), this); + // Solarized base01 for body text + desc->setStyleSheet("font-size: 40px; color: #586E75;"); + desc->setWordWrap(true); + leftLayout->addWidget(desc); + + leftLayout->addStretch(); + + // Right side: QR code and instructions + auto rightLayout = new QVBoxLayout(); + rightLayout->setContentsMargins(50, 40, 85, 70); + rightLayout->setSpacing(40); + contentLayout->addLayout(rightLayout, 1); + + // QR code (smaller, fixed size) + auto *qr = new SunnylinkCommunityQRWidget(this); + qr->setFixedSize(500, 500); + rightLayout->addStretch(); + rightLayout->addWidget(qr, 0, Qt::AlignCenter); + rightLayout->addStretch(); +} \ No newline at end of file diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h new file mode 100644 index 000000000..613375d12 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/community_widget.h @@ -0,0 +1,40 @@ +/** +* Copyright (c) 2025-, sunnypilot contributors. + * + * This file is part of sunnypilot and is licensed under the MIT License. + * See the LICENSE.md file in the root directory for more details. + */ + +#pragma once + +#include +#include + +#include "common/util.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" + +const QString SUNNYLINK_COMMUNITY_URL = "https://community.sunnypilot.ai/sp-qr"; + +class SunnylinkCommunityQRWidget : public QWidget { + Q_OBJECT + +public: + explicit SunnylinkCommunityQRWidget(QWidget* parent = nullptr); + void paintEvent(QPaintEvent*) override; + +private: + QPixmap img; + void updateQrCode(const QString &text); + void showEvent(QShowEvent *event) override; +}; + +// Popup widget +class SunnylinkCommunityPopup : public DialogBase { + Q_OBJECT + +public: + explicit SunnylinkCommunityPopup(QWidget* parent = nullptr); + +private: + static QStringList getInstructions(); +}; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc index 7b5ce4823..a014eddac 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink/sponsor_widget.cc @@ -79,11 +79,11 @@ QStringList SunnylinkSponsorPopup::getInstructions(bool sponsor_pair) { instructions << tr("Scan the QR code to login to your GitHub account") << tr("Follow the prompts to complete the pairing process") << tr("Re-enter the \"sunnylink\" panel to verify sponsorship status") - << tr("If sponsorship status was not updated, please contact a moderator on Discord at https://discord.gg/sunnypilot"); + << tr("If sponsorship status was not updated, please contact a moderator on our forum at https://community.sunnypilot.ai"); } else { instructions << tr("Scan the QR code to visit sunnyhaibin's GitHub Sponsors page") << tr("Choose your sponsorship tier and confirm your support") - << tr("Join our community on Discord at https://discord.gg/sunnypilot and reach out to a moderator to confirm your sponsor status"); + << tr("Join our Community Forum at https://community.sunnypilot.ai and reach out to a moderator if you have issues"); } return instructions; } From 18af4d6ad6db657bcdbe892614851d24a33f9dcc Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Sun, 2 Nov 2025 20:26:17 +0100 Subject: [PATCH 5/6] ui: Fix spacing in sunnylink panel (#1450) Fix spacing --- selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc index 924d1d3c0..1b170bb0c 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc @@ -90,7 +90,7 @@ SunnylinkPanel::SunnylinkPanel(QWidget *parent) : QFrame(parent) { QString sunnylinkUploaderDesc = tr("Enable sunnylink uploader to allow sunnypilot to upload your driving data to sunnypilot servers. (only for highest tiers, and does NOT bring ANY benefit to you. We are just testing data volume.)"); sunnylinkUploaderEnabledBtn = new ParamControlSP( "EnableSunnylinkUploader", - tr("Enable sunnylink uploader (just for testing infrastructure)"), + tr("Enable sunnylink uploader (infrastructure test)"), sunnylinkUploaderDesc, "", nullptr, true); list->addItem(sunnylinkUploaderEnabledBtn); From 071147baafae09c0a3f8305187596f8af16f800b Mon Sep 17 00:00:00 2001 From: Matt Purnell <65473602+mpurnell1@users.noreply.github.com> Date: Sun, 2 Nov 2025 23:52:17 -0600 Subject: [PATCH 6/6] docs: Update README installation branches and discord links (#1453) * Use sunnypilot CARS.md, update number of supported cars, add comma * Update device reference * Update discord links to forum links * Update references to -c3-new branches and release * Update broken link to branches table * Update README.md --------- Co-authored-by: DevTekVE --- README.md | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 7e686cef5..598e1273a 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,9 @@ ## 🌞 What is sunnypilot? [sunnypilot](https://github.com/sunnyhaibin/sunnypilot) is a fork of comma.ai's openpilot, an open source driver assistance system. sunnypilot offers the user a unique driving experience for over 300+ supported car makes and models with modified behaviors of driving assist engagements. sunnypilot complies with comma.ai's safety rules as accurately as possible. -## 💭 Join our Discord -Join the official sunnypilot Discord server to stay up to date with all the latest features and be a part of shaping the future of sunnypilot! -* https://discord.gg/sunnypilot - - ![](https://dcbadge.vercel.app/api/server/wRW3meAgtx?style=flat) ![Discord Shield](https://discordapp.com/api/guilds/880416502577266699/widget.png?style=shield) +## 💭 Join our Community Forum +Join the official sunnypilot community forum to stay up to date with all the latest features and be a part of shaping the future of sunnypilot! +* https://community.sunnypilot.ai/ ## Documentation https://docs.sunnypilot.ai/ is your one stop shop for everything from features to installation to FAQ about the sunnypilot @@ -16,13 +14,13 @@ https://docs.sunnypilot.ai/ is your one stop shop for everything from features t * A supported device to run this software * a [comma three](https://comma.ai/shop/products/three) or a [C3X](https://comma.ai/shop/comma-3x) * This software -* One of [the 300+ supported cars](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run sunnypilot. +* One of [the 325+ supported cars](https://github.com/sunnypilot/sunnypilot/blob/master/docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford, and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run sunnypilot. * A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car Detailed instructions for [how to mount the device in a car](https://comma.ai/setup). ## Installation -Please refer to [Recommended Branches](#-recommended-branches) to find your preferred/supported branch. This guide will assume you want to install the latest `staging-c3-new` branch. +Please refer to [Recommended Branches](#recommended-branches) to find your preferred/supported branch. This guide will assume you want to install the latest `staging` branch. ### If you want to use our newest branches (our rewrite) > [!TIP] @@ -31,28 +29,28 @@ Please refer to [Recommended Branches](#-recommended-branches) to find your pref * sunnypilot not installed or you installed a version before 0.8.17? 1. [Factory reset/uninstall](https://github.com/commaai/openpilot/wiki/FAQ#how-can-i-reset-the-device) the previous software if you have another software/fork installed. 2. After factory reset/uninstall and upon reboot, select `Custom Software` when given the option. - 3. Input the installation URL per [Recommended Branches](#-recommended-branches). Example: ```https://staging-c3-new.sunnypilot.ai```. + 3. Input the installation URL per [Recommended Branches](#recommended-branches). Example: ```https://staging.sunnypilot.ai```. 4. Complete the rest of the installation following the onscreen instructions. * sunnypilot already installed and you installed a version after 0.8.17? - 1. On the comma three, go to `Settings` ▶️ `Software`. + 1. On the comma three/3X, go to `Settings` ▶️ `Software`. 2. At the `Download` option, press `CHECK`. This will fetch the list of latest branches from sunnypilot. 3. At the `Target Branch` option, press `SELECT` to open the Target Branch selector. - 4. Scroll to select the desired branch per Recommended Branches (see below). Example: `staging-c3-new` + 4. Scroll to select the desired branch per Recommended Branches (see below). Example: `staging` - -| Branch | Installation URL | -|:----------------:|:---------------------------------------------:| -| `staging-c3-new` | `https://staging-c3-new.sunnypilot.ai` | -| `dev-c3-new` | `https://dev-c3-new.sunnypilot.ai` | -| `custom-branch` | `https://install.sunnypilot.ai/{branch_name}` | -| `release-c3-new` | **Not yet available**. | +### Recommended Branches +| Branch | Installation URL | +|:---------------:|:---------------------------------------------:| +| `release` | `https://release.sunnypilot.ai` | +| `staging` | `https://staging.sunnypilot.ai` | +| `dev` | `https://dev.sunnypilot.ai` | +| `custom-branch` | `https://install.sunnypilot.ai/{branch_name}` | > [!TIP] -> You can use sunnypilot/targetbranch as an install URL. Example: 'sunnypilot/staging-c3-new'. +> You can use sunnypilot/targetbranch as an install URL. Example: 'sunnypilot/staging'. > [!NOTE] -> Do you require further assistance with software installation? Join the [sunnypilot Discord server](https://discord.sunnypilot.com) and message us in the `#installation-help` channel. +> Do you require further assistance with software installation? Join the [sunnypilot community forum](https://community.sunnypilot.ai/new-topic?category=general/qa) and create a topic in the General/Q&A Category channel.