From 2fa66d6f4d37a371e048dfc6ab1ad564ff004222 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 22 Sep 2025 01:35:13 -0400 Subject: [PATCH 1/3] ui: include Speed Limit Offset for Speed Limit Warning (#1276) * ui: include Speed Limit Offset for Speed Limit Warning * fix --- selfdrive/ui/sunnypilot/qt/onroad/hud.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc index 680542239..db6ca1952 100644 --- a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc +++ b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc @@ -335,7 +335,8 @@ void HudRendererSP::drawStandstillTimer(QPainter &p, int x, int y) { void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { bool speedLimitValid = speedLimit > 0; int speedLimitRounded = std::nearbyint(speedLimit); - bool overspeed = speedLimitRounded < std::nearbyint(speed) && speedLimitRounded > 0; + int speedLimitFinalRounded = std::nearbyint(speedLimit + speedLimitOffset); + bool overspeed = speedLimitFinalRounded < std::nearbyint(speed) && speedLimitRounded > 0; bool speedLimitWarningEnabled = speedLimitMode == SpeedLimitMode::WARNING; QString speedLimitStr = speedLimitValid ? QString::number(speedLimitRounded) : "---"; From 005c6aed95eee2c2896601ed2d7a51e81e14383e Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 22 Sep 2025 08:54:16 -0400 Subject: [PATCH 2/3] ui: separate road name toggle param and bigger fonts (#1277) * ui: separate road name toggle param and bigger fonts * slightly lower --- common/params_keys.h | 3 ++- selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc | 2 +- selfdrive/ui/sunnypilot/qt/onroad/hud.cc | 4 ++-- selfdrive/ui/sunnypilot/ui.cc | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index e9ffcfc1f..32a7695b3 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -224,7 +224,8 @@ inline static std::unordered_map keys = { {"OsmStateName", {PERSISTENT, STRING, "All"}}, {"OsmStateTitle", {PERSISTENT, STRING}}, {"OsmWayTest", {PERSISTENT, STRING}}, - {"RoadName", {PERSISTENT, STRING}}, + {"RoadName", {CLEAR_ON_ONROAD_TRANSITION, STRING}}, + {"RoadNameToggle", {PERSISTENT, STRING}}, // Speed Limit {"SpeedLimitMode", {PERSISTENT | BACKUP, INT, "1"}}, diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc index ca58282a3..10ead5377 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc @@ -43,7 +43,7 @@ VisualsPanel::VisualsPanel(QWidget *parent) : QWidget(parent) { false, }, { - "RoadName", + "RoadNameToggle", tr("Display Road Name"), tr("Displays the name of the road the car is traveling on. The OpenStreetMap database of the location must be downloaded from the OSM panel to fetch the road name."), "", diff --git a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc index db6ca1952..9409612f4 100644 --- a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc +++ b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc @@ -528,7 +528,7 @@ void HudRendererSP::drawRoadName(QPainter &p, const QRect &surface_rect) { if (!roadName || roadNameStr.isEmpty()) return; // Measure text to size container - p.setFont(InterFont(40, QFont::Normal)); + p.setFont(InterFont(46, QFont::DemiBold)); QFontMetrics fm(p.font()); int text_width = fm.horizontalAdvance(roadNameStr); @@ -541,7 +541,7 @@ void HudRendererSP::drawRoadName(QPainter &p, const QRect &surface_rect) { rect_width = std::max(min_width, std::min(rect_width, max_width)); // Center at top of screen - QRect road_rect(surface_rect.width() / 2 - rect_width / 2, -6, rect_width, 60); + QRect road_rect(surface_rect.width() / 2 - rect_width / 2, -4, rect_width, 60); p.setPen(Qt::NoPen); p.setBrush(QColor(0, 0, 0, 120)); diff --git a/selfdrive/ui/sunnypilot/ui.cc b/selfdrive/ui/sunnypilot/ui.cc index 9acf84408..fd7365821 100644 --- a/selfdrive/ui/sunnypilot/ui.cc +++ b/selfdrive/ui/sunnypilot/ui.cc @@ -54,7 +54,7 @@ void ui_update_params_sp(UIStateSP *s) { s->scene.dev_ui_info = std::atoi(params.get("DevUIInfo").c_str()); s->scene.standstill_timer = params.getBool("StandstillTimer"); s->scene.speed_limit_mode = std::atoi(params.get("SpeedLimitMode").c_str()); - s->scene.road_name = params.getBool("RoadName"); + s->scene.road_name = params.getBool("RoadNameToggle"); } DeviceSP::DeviceSP(QObject *parent) : Device(parent) { From b64d5a0fa4df9ea130056d91cfe68d20f6b4d208 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 22 Sep 2025 09:39:22 -0400 Subject: [PATCH 3/3] liveMapDataSP: parse bearing from GPS (#1279) * simpler approach pls * fix --- .../mapd/live_map_data/base_map_data.py | 22 +++---------------- sunnypilot/mapd/live_map_data/osm_map_data.py | 17 +++++++++++--- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/sunnypilot/mapd/live_map_data/base_map_data.py b/sunnypilot/mapd/live_map_data/base_map_data.py index 6c7679420..f386eab96 100644 --- a/sunnypilot/mapd/live_map_data/base_map_data.py +++ b/sunnypilot/mapd/live_map_data/base_map_data.py @@ -9,8 +9,7 @@ from abc import abstractmethod, ABC from cereal import messaging from openpilot.common.gps import get_gps_location_service from openpilot.common.params import Params -from openpilot.common.realtime import DT_MDL -from openpilot.sunnypilot.navd.helpers import Coordinate, coordinate_from_param +from openpilot.sunnypilot.navd.helpers import coordinate_from_param class BaseMapData(ABC): @@ -23,8 +22,8 @@ class BaseMapData(ABC): ignore_valid=gps_packets, poll='livePose') self.pm = messaging.PubMaster(['liveMapDataSP']) + self.last_bearing = None self.last_position = coordinate_from_param("LastGPSPosition", self.params) - self.last_altitude = None @abstractmethod def update_location(self) -> None: @@ -42,20 +41,6 @@ class BaseMapData(ABC): def get_current_road_name(self) -> str: pass - def get_current_location(self) -> None: - gps = self.sm[self.gps_location_service] - - # ignore the message if the fix is invalid - gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_MDL < 2.0 - if not gps_ok and self.sm['livePose'].inputsOK: - return - - # livePose has these data, but aren't on cereal - self.last_position = Coordinate(gps.latitude, gps.longitude) - self.last_altitude = gps.altitude - - return - def publish(self) -> None: speed_limit = self.get_current_speed_limit() next_speed_limit, next_speed_limit_distance = self.get_next_speed_limit_and_distance() @@ -74,7 +59,6 @@ class BaseMapData(ABC): self.pm.send('liveMapDataSP', mapd_sp_send) def tick(self) -> None: - self.sm.update() - self.get_current_location() + self.sm.update(0) self.update_location() self.publish() diff --git a/sunnypilot/mapd/live_map_data/osm_map_data.py b/sunnypilot/mapd/live_map_data/osm_map_data.py index 1eaf76dc8..c5187a8e0 100644 --- a/sunnypilot/mapd/live_map_data/osm_map_data.py +++ b/sunnypilot/mapd/live_map_data/osm_map_data.py @@ -5,9 +5,11 @@ 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. """ import json +import math import platform from openpilot.common.params import Params +from openpilot.common.realtime import DT_MDL from openpilot.sunnypilot.mapd.live_map_data.base_map_data import BaseMapData from openpilot.sunnypilot.navd.helpers import Coordinate @@ -15,17 +17,26 @@ from openpilot.sunnypilot.navd.helpers import Coordinate class OsmMapData(BaseMapData): def __init__(self): super().__init__() - self.params = Params() self.mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else self.params def update_location(self) -> None: - if self.last_position is None or self.last_altitude is None: + gps = self.sm[self.gps_location_service] + gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_MDL < 2.0 + + if gps_ok: + self.last_bearing = gps.bearingDeg * 180/math.pi + self.last_position = Coordinate(gps.latitude, gps.longitude) + + if not gps_ok and self.sm['livePose'].inputsOK: + return + + if self.last_position is None: return params = { "latitude": self.last_position.latitude, "longitude": self.last_position.longitude, - "altitude": self.last_altitude, + "bearing": self.last_bearing, } self.mem_params.put("LastGPSPosition", json.dumps(params))