From 6df1edbbafa6dc7d26db0239a479d4beea4f4761 Mon Sep 17 00:00:00 2001 From: discountchubbs Date: Wed, 5 Nov 2025 06:57:21 -0800 Subject: [PATCH] offroad panel stuffs --- common/params_keys.h | 1 + selfdrive/ui/sunnypilot/SConscript | 1 + .../qt/offroad/settings/navigation_panel.cc | 85 +++++++++++++++++++ .../qt/offroad/settings/navigation_panel.h | 39 +++++++++ .../qt/offroad/settings/settings.cc | 2 + sunnypilot/navd/navigationd.py | 9 +- 6 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.cc create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.h diff --git a/common/params_keys.h b/common/params_keys.h index 7157629f14..d0dc97f070 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -188,6 +188,7 @@ inline static std::unordered_map keys = { {"ModelManager_ModelsCache", {PERSISTENT | BACKUP, JSON}}, // Navigation params + {"AllowNavigation", {PERSISTENT | BACKUP, BOOL, "0"}}, {"MapboxToken", {PERSISTENT | BACKUP, STRING}}, {"MapboxSettings", {CLEAR_ON_MANAGER_START, JSON}}, {"MapboxRoute", {PERSISTENT, STRING}}, diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index be92c14261..08108926d8 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -30,6 +30,7 @@ qt_src = [ "sunnypilot/qt/offroad/settings/max_time_offroad.cc", "sunnypilot/qt/offroad/settings/brightness.cc", "sunnypilot/qt/offroad/settings/models_panel.cc", + "sunnypilot/qt/offroad/settings/navigation_panel.cc", "sunnypilot/qt/offroad/settings/osm_panel.cc", "sunnypilot/qt/offroad/settings/settings.cc", "sunnypilot/qt/offroad/settings/software_panel.cc", diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.cc new file mode 100644 index 0000000000..27d89e07ce --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.cc @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other 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/navigation_panel.h" + +NavigationPanel::NavigationPanel(QWidget* parent) : QWidget(parent) { + QVBoxLayout* main_layout = new QVBoxLayout(this); + main_layout->setContentsMargins(50, 25, 50, 25); + + list = new ListWidget(this, false); + scroller = new ScrollViewSP(list, this); + main_layout->addWidget(scroller); + + // Mapbox Token + mapbox_token = new ButtonControl(tr("Mapbox Token"), tr("Edit"), tr("Enter your Mapbox API token")); + QObject::connect(mapbox_token, &ButtonControl::clicked, [=]() { + QString current = QString::fromStdString(params.get("MapboxToken")); + QString token = InputDialog::getText(tr("Enter Mapbox Token"), this, "", false, -1, current); + if (!token.isEmpty()) { + params.put("MapboxToken", token.toStdString()); + refresh(); + } + }); + list->addItem(mapbox_token); + + // Mapbox Route + mapbox_route = new ButtonControl(tr("Mapbox Route"), tr("Edit"), tr("Enter Mapbox route data")); + QObject::connect(mapbox_route, &ButtonControl::clicked, [=]() { + QString current = QString::fromStdString(params.get("MapboxRoute")); + QString route = InputDialog::getText(tr("Enter Mapbox Route"), this, "", false, -1, current); + if (!route.isEmpty()) { + params.put("MapboxRoute", route.toStdString()); + refresh(); + } + }); + list->addItem(mapbox_route); + + // Allow Navigation + allow_navigation = new ParamControlSP("AllowNavigation", tr("Allow Navigation"), tr("Enable navigation features and start navigationd"), "", this); + QObject::connect(allow_navigation, &ParamControlSP::toggleFlipped, this, &NavigationPanel::updateNavigationVisibility); + list->addItem(allow_navigation); + + // Mapbox Recompute + mapbox_recompute = new ParamControlSP("MapboxRecompute", tr("Mapbox Recompute"), tr("Enable automatic route recomputation"), "", this); + list->addItem(mapbox_recompute); + + // Nav Allowed + nav_allowed = new ParamControlSP("NavAllowed", tr("Navigation Allowed"), tr("Allow navigation features"), "", this); + list->addItem(nav_allowed); + + // Nav Events + nav_events = new ParamControlSP("NavEvents", tr("Navigation Events"), tr("Enable navigation event notifications"), "", this); + list->addItem(nav_events); +} + +void NavigationPanel::updateNavigationVisibility(bool state) { + mapbox_recompute->setVisible(state); + nav_allowed->setVisible(state); + nav_events->setVisible(state); +} + +void NavigationPanel::showEvent(QShowEvent *event) { + refresh(); +} + +void NavigationPanel::refresh() { + allow_navigation->refresh(); + + bool nav_enabled = allow_navigation->isToggled(); + updateNavigationVisibility(nav_enabled); + + QString token = QString::fromStdString(params.get("MapboxToken")); + mapbox_token->setValue(token.isEmpty() ? tr("Not set") : token); + + QString route = QString::fromStdString(params.get("MapboxRoute")); + mapbox_route->setValue(route.isEmpty() ? tr("Not set") : route); + + mapbox_recompute->refresh(); + nav_allowed->refresh(); + nav_events->refresh(); +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.h new file mode 100644 index 0000000000..c327a1d19d --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other 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 "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/qt/widgets/controls.h" +#include "selfdrive/ui/qt/widgets/input.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h" +#include "selfdrive/ui/sunnypilot/qt/util.h" + + +class NavigationPanel : public QWidget { + Q_OBJECT + +public: + explicit NavigationPanel(QWidget* parent = nullptr); + void showEvent(QShowEvent *event) override; + void refresh(); + +public slots: + void updateNavigationVisibility(bool state); + +private: + Params params; + ListWidget* list; + ScrollViewSP* scroller; + ParamControlSP* allow_navigation; + ButtonControl* mapbox_token; + ButtonControl* mapbox_route; + ParamControlSP* mapbox_recompute; + ParamControlSP* nav_allowed; + ParamControlSP* nav_events; +}; diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc index c712442df3..d8393d3a99 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc @@ -15,6 +15,7 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/display_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/navigation_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/lateral_panel.h" @@ -85,6 +86,7 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) { PanelInfo(" " + tr("Toggles"), toggles, "../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"), PanelInfo(" " + tr("Software"), new SoftwarePanelSP(this), "../../sunnypilot/selfdrive/assets/offroad/icon_software.png"), PanelInfo(" " + tr("Models"), new ModelsPanel(this), "../../sunnypilot/selfdrive/assets/offroad/icon_models.png"), + PanelInfo(" " + tr("Navigation"), new NavigationPanel(this), "../../sunnypilot/selfdrive/assets/offroad/icon_map.png"), PanelInfo(" " + tr("Steering"), new LateralPanel(this), "../../sunnypilot/selfdrive/assets/offroad/icon_lateral.png"), PanelInfo(" " + tr("Cruise"), new LongitudinalPanel(this), "../assets/icons/speed_limit.png"), PanelInfo(" " + tr("Visuals"), new VisualsPanel(this), "../../sunnypilot/selfdrive/assets/offroad/icon_visuals.png"), diff --git a/sunnypilot/navd/navigationd.py b/sunnypilot/navd/navigationd.py index 57c10bc040..3720ce724c 100755 --- a/sunnypilot/navd/navigationd.py +++ b/sunnypilot/navd/navigationd.py @@ -31,6 +31,7 @@ class Navigationd: self.destination: str | None = None self.new_destination: str = '' + self.allow_navigation: bool = False self.recompute_allowed: bool = False self.allow_recompute: bool = False self.reroute_counter: int = 0 @@ -46,6 +47,7 @@ class Navigationd: if self.last_position is not None: self.frame += 1 if self.frame % 9 == 0: + self.allow_navigation = self.params.get('AllowNavigation', return_default=True) self.is_metric = self.params.get('IsMetric', return_default=True) self.new_destination = self.params.get('MapboxRoute') self.recompute_allowed = self.params.get('MapboxRecompute', return_default=True) @@ -76,7 +78,7 @@ class Navigationd: banner_instructions: str = '' progress: dict | None = None nav_data: dict = {} - if self.last_position is not None: + if self.allow_navigation and self.last_position is not None: if progress := self.nav_instructions.get_route_progress(self.last_position.latitude, self.last_position.longitude): nav_data['upcoming_turn'] = self.nav_instructions.get_upcoming_turn_from_progress(progress, self.last_position.latitude, self.last_position.longitude) nav_data['current_speed_limit'] = self.nav_instructions.get_current_speed_limit_from_progress(progress, self.is_metric) @@ -102,6 +104,11 @@ class Navigationd: if self.route: if progress['current_step_idx'] == len(self.route['steps']) - 1: self.allow_recompute = False + else: + banner_instructions = '' + progress = None + nav_data = {} + self.valid = False return banner_instructions, progress, nav_data