From 01a0ad496d7c78daafb2ff65f9fe17b6c221a1c6 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 22 Sep 2025 19:50:59 -0400 Subject: [PATCH] ui: more speed limit improvements (#1278) * ui: more speed limit improvements - show speed limit offset with last valid speed limit - show last valid speed limit if current speed limit is not valid * rename * round it * update logic * in its own var and 5 frames now * new offset vals * slightly more * apply suggestions --- selfdrive/ui/sunnypilot/qt/onroad/hud.cc | 38 ++++++++++++++++-------- selfdrive/ui/sunnypilot/qt/onroad/hud.h | 5 ++++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc index 9409612f4..33462e620 100644 --- a/selfdrive/ui/sunnypilot/qt/onroad/hud.cc +++ b/selfdrive/ui/sunnypilot/qt/onroad/hud.cc @@ -31,6 +31,8 @@ void HudRendererSP::updateState(const UIState &s) { float speedConv = is_metric ? MS_TO_KPH : MS_TO_MPH; speedLimit = lp_sp.getSpeedLimit().getResolver().getSpeedLimit() * speedConv; speedLimitOffset = lp_sp.getSpeedLimit().getResolver().getSpeedLimitOffset() * speedConv; + speedLimitValid = speedLimit > 0; + speedLimitLastValid = speedLimitLast > 0; speedLimitMode = static_cast(s.scene.speed_limit_mode); roadName = s.scene.road_name; if (sm.updated("liveMapDataSP")) { @@ -38,7 +40,7 @@ void HudRendererSP::updateState(const UIState &s) { speedLimitAheadValid = lmd.getSpeedLimitAheadValid(); speedLimitAhead = lmd.getSpeedLimitAhead() * speedConv; speedLimitAheadDistance = lmd.getSpeedLimitAheadDistance(); - if (speedLimitAheadDistance < speedLimitAheadDistancePrev && speedLimitAheadValidFrame < 2) { + if (speedLimitAheadDistance < speedLimitAheadDistancePrev && speedLimitAheadValidFrame < SPEED_LIMIT_AHEAD_VALID_FRAME_THRESHOLD) { speedLimitAheadValidFrame++; } else if (speedLimitAheadDistance > speedLimitAheadDistancePrev && speedLimitAheadValidFrame > 0) { speedLimitAheadValidFrame--; @@ -46,6 +48,10 @@ void HudRendererSP::updateState(const UIState &s) { } speedLimitAheadDistancePrev = speedLimitAheadDistance; + if (speedLimitValid) { + speedLimitLast = speedLimit; + } + static int reverse_delay = 0; bool reverse_allowed = false; if (int(car_state.getGearShifter()) != 4) { @@ -333,17 +339,22 @@ void HudRendererSP::drawStandstillTimer(QPainter &p, int x, int y) { } void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { - bool speedLimitValid = speedLimit > 0; - int speedLimitRounded = std::nearbyint(speedLimit); - 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) : "---"; + bool hasSpeedLimit = speedLimitValid || speedLimitLastValid; + int speedLimitFinal = std::nearbyint(speedLimitValid ? speedLimit : speedLimitLast); + int speedLimitOffsetFinal = speedLimitFinal + std::nearbyint(speedLimitOffset); + bool overspeed = hasSpeedLimit && speedLimitOffsetFinal < std::nearbyint(speed); + bool speedLimitWarningEnabled = speedLimitMode == SpeedLimitMode::WARNING; // TODO-SP: update to include SpeedLimitMode::ASSIST + QString speedLimitStr = hasSpeedLimit ? QString::number(speedLimitFinal) : "---"; // Offset display text QString speedLimitSubText = ""; if (speedLimitOffset != 0) { - speedLimitSubText = (speedLimitOffset > 0 ? "+" : "-") + QString::number(std::nearbyint(speedLimitOffset)); + speedLimitSubText = (speedLimitOffset > 0 ? "" : "-") + QString::number(std::nearbyint(speedLimitOffset)); + } + + float speedLimitSubTextFactor = is_metric ? 0.5 : 0.6; + if (speedLimitSubText.size() >= 3) { + speedLimitSubTextFactor = 0.475; } // Position next to MAX speed box @@ -355,7 +366,8 @@ void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { int alpha = 255; QColor red_color = QColor(255, 0, 0, alpha); - QColor speed_color = (speedLimitWarningEnabled && overspeed) ? red_color : QColor(0, 0, 0, alpha); + QColor speed_color = (speedLimitWarningEnabled && overspeed) ? red_color : + (!speedLimitValid && speedLimitLastValid ? QColor(0x91, 0x9b, 0x95, 0xf1) : QColor(0, 0, 0, alpha)); if (is_metric) { // EU Vienna Convention style circular sign @@ -394,7 +406,7 @@ void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { p.drawText(center_circle, Qt::AlignCenter, speedLimitStr); // Offset value in small circular box - if (!speedLimitSubText.isEmpty() && speedLimitValid) { + if (!speedLimitSubText.isEmpty() && hasSpeedLimit) { int offset_circle_size = circle_size * 0.4; int overlap = offset_circle_size * 0.25; QRect offset_circle_rect( @@ -408,7 +420,7 @@ void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { p.setBrush(QColor(0, 0, 0, alpha)); p.drawEllipse(offset_circle_rect); - p.setFont(InterFont(offset_circle_size * 0.45, QFont::Bold)); + p.setFont(InterFont(offset_circle_size * speedLimitSubTextFactor, QFont::Bold)); p.setPen(QColor(255, 255, 255, alpha)); p.drawText(offset_circle_rect, Qt::AlignCenter, speedLimitSubText); } @@ -439,7 +451,7 @@ void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { p.drawText(inner_rect.adjusted(0, 80, 0, 0), Qt::AlignTop | Qt::AlignHCenter, speedLimitStr); // Offset value in small box - if (!speedLimitSubText.isEmpty() && speedLimitValid) { + if (!speedLimitSubText.isEmpty() && hasSpeedLimit) { int offset_box_size = sign_rect.width() * 0.4; int overlap = offset_box_size * 0.25; QRect offset_box_rect( @@ -454,7 +466,7 @@ void HudRendererSP::drawSpeedLimitSigns(QPainter &p) { p.setBrush(QColor(0, 0, 0, alpha)); p.drawRoundedRect(offset_box_rect, corner_radius, corner_radius); - p.setFont(InterFont(offset_box_size * 0.45, QFont::Bold)); + p.setFont(InterFont(offset_box_size * speedLimitSubTextFactor, QFont::Bold)); p.setPen(QColor(255, 255, 255, alpha)); p.drawText(offset_box_rect, Qt::AlignCenter, speedLimitSubText); } diff --git a/selfdrive/ui/sunnypilot/qt/onroad/hud.h b/selfdrive/ui/sunnypilot/qt/onroad/hud.h index 073780bc1..bae1c3b71 100644 --- a/selfdrive/ui/sunnypilot/qt/onroad/hud.h +++ b/selfdrive/ui/sunnypilot/qt/onroad/hud.h @@ -11,6 +11,8 @@ #include "selfdrive/ui/sunnypilot/qt/offroad/settings/longitudinal/speed_limit/helpers.h" #include "selfdrive/ui/sunnypilot/qt/onroad/developer_ui/developer_ui.h" +constexpr int SPEED_LIMIT_AHEAD_VALID_FRAME_THRESHOLD = 5; + class HudRendererSP : public HudRenderer { Q_OBJECT @@ -68,7 +70,10 @@ private: bool smartCruiseControlVisionActive; int smartCruiseControlVisionFrame; float speedLimit; + float speedLimitLast; float speedLimitOffset; + bool speedLimitValid; + bool speedLimitLastValid; bool speedLimitAheadValid; float speedLimitAhead; float speedLimitAheadDistance;