From fec050a3c15841421e5664c11f13800c8a0a89d2 Mon Sep 17 00:00:00 2001 From: James <91348155+FrogAi@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:00:00 -0700 Subject: [PATCH] =?UTF-8?q?Rainbow=20Road=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qt/onroad/frogpilot_annotated_camera.cc | 21 +++++++++++++++++++ .../ui/qt/onroad/frogpilot_annotated_camera.h | 1 + selfdrive/ui/qt/onroad/model.cc | 6 ++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc index dc7894158..9d177d33a 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc +++ b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc @@ -725,6 +725,27 @@ void FrogPilotAnnotatedCameraWidget::paintPedalIcons(QPainter &p) { p.restore(); } +void FrogPilotAnnotatedCameraWidget::paintRainbowPath(QPainter &p, QLinearGradient &bg, float lin_grad_point) { + p.save(); + + static float hueOffset = 0.0f; + if (speed > 0) { + hueOffset += speed / speedConversion * 0.02f; + + if (hueOffset >= 360.0f) { + hueOffset = fmodf(hueOffset, 360.0f); + } + } + + float alpha = util::map_val(lin_grad_point, 0.0f, 1.0f, 0.5f, 0.1f); + float pathHue = fmodf(lin_grad_point * 120.0f + hueOffset, 360.0f); + + bg.setColorAt(lin_grad_point, QColor::fromHslF(pathHue / 360.0f, 1.0f, 0.5f, alpha)); + bg.setSpread(QGradient::RepeatSpread); + + p.restore(); +} + void FrogPilotAnnotatedCameraWidget::paintRadarTracks(QPainter &p) { if (radar_tracks.empty()) { return; diff --git a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h index 9e2ed12bc..d5fe444db 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h +++ b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h @@ -17,6 +17,7 @@ public: void paintFrogPilotWidgets(QPainter &p, UIState &s); void paintLeadMetrics(QPainter &p, bool adjacent, QPointF *chevron, const cereal::RadarState::LeadData::Reader &lead_data); void paintPathEdges(QPainter &p, int height); + void paintRainbowPath(QPainter &p, QLinearGradient &bg, float lin_grad_point); void updateState(const UIState &s, const FrogPilotUIState &fs); bool hideBottomIcons; diff --git a/selfdrive/ui/qt/onroad/model.cc b/selfdrive/ui/qt/onroad/model.cc index 0f47d3afb..54df14380 100644 --- a/selfdrive/ui/qt/onroad/model.cc +++ b/selfdrive/ui/qt/onroad/model.cc @@ -165,7 +165,7 @@ void ModelRenderer::drawLaneLines(QPainter &painter) { void ModelRenderer::drawPath(QPainter &painter, const cereal::ModelDataV2::Reader &model, int height) { QLinearGradient bg(0, height, 0, 0); - if (experimental_mode || frogpilot_toggles.value("acceleration_path").toBool()) { + if (experimental_mode || frogpilot_toggles.value("acceleration_path").toBool() || frogpilot_toggles.value("rainbow_path").toBool()) { // The first half of track_vertices are the points for the right side of the path const auto &acceleration = model.getAcceleration().getX(); const int max_len = std::min(track_vertices.length() / 2, acceleration.size()); @@ -178,7 +178,9 @@ void ModelRenderer::drawPath(QPainter &painter, const cereal::ModelDataV2::Reade // Flip so 0 is bottom of frame float lin_grad_point = (height - track_vertices[track_idx].y()) / height; - if (fabs(acceleration[i]) < 0.25 && frogpilot_toggles.value("color_scheme").toString() != "stock") { + if ((fabs(acceleration[i]) < 0.25 || !frogpilot_toggles.value("acceleration_path").toBool()) && frogpilot_toggles.value("rainbow_path").toBool()) { + frogpilot_nvg->paintRainbowPath(painter, bg, lin_grad_point); + } else if (fabs(acceleration[i]) < 0.25 && frogpilot_toggles.value("color_scheme").toString() != "stock") { QColor color = QColor(frogpilot_toggles.value("path_color").toString()); color.setAlphaF(util::map_val(lin_grad_point, 0.0f, 1.0f, 1.0f, 0.1f)); bg.setColorAt(lin_grad_point, color);