From 396576cd015501afe842b8d7ed3f8d135b6be210 Mon Sep 17 00:00:00 2001 From: Rick Lan Date: Mon, 12 May 2025 13:58:07 +0800 Subject: [PATCH] Rainbow Path - init --- common/params_keys.h | 1 + selfdrive/ui/qt/offroad/dp_panel.cc | 5 +++++ selfdrive/ui/qt/onroad/model.cc | 34 ++++++++++++++++++++++++++++- selfdrive/ui/qt/onroad/model.h | 3 +++ selfdrive/ui/ui.cc | 1 + selfdrive/ui/ui.h | 1 + system/manager/manager.py | 1 + 7 files changed, 45 insertions(+), 1 deletion(-) diff --git a/common/params_keys.h b/common/params_keys.h index b576f1a97..30b9e5d4c 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -119,4 +119,5 @@ inline static std::unordered_map keys = { {"Version", PERSISTENT}, {"dp_device_last_log", CLEAR_ON_MANAGER_START}, {"dp_device_reset_conf", CLEAR_ON_MANAGER_START}, + {"dp_ui_rainbow", PERSISTENT}, }; diff --git a/selfdrive/ui/qt/offroad/dp_panel.cc b/selfdrive/ui/qt/offroad/dp_panel.cc index 548b02be5..b1c0d36b9 100644 --- a/selfdrive/ui/qt/offroad/dp_panel.cc +++ b/selfdrive/ui/qt/offroad/dp_panel.cc @@ -172,6 +172,11 @@ void DPPanel::add_ui_toggles() { QString::fromUtf8("🐉 ") + tr("UI"), "", }, + { + "dp_ui_rainbow", + tr("Rainbow Driving Path like Tesla"), + tr("Why not?"), + }, }; QWidget *label = nullptr; diff --git a/selfdrive/ui/qt/onroad/model.cc b/selfdrive/ui/qt/onroad/model.cc index 52902abdc..5dc6117cc 100644 --- a/selfdrive/ui/qt/onroad/model.cc +++ b/selfdrive/ui/qt/onroad/model.cc @@ -107,7 +107,39 @@ 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) { + + auto *s = uiState(); + if (s->scene.dp_ui_rainbow) { + constexpr int NUM_COLORS = 25; + constexpr int ALPHA = 128; + + float v_ego = (*uiState()->sm)["carState"].getCarState().getVEgo(); + + if (!dp_rainbow_init) { + dp_rainbow_color_list.reserve(NUM_COLORS); + for (int i = 0; i < NUM_COLORS; ++i) { + qreal t = static_cast(i) / (NUM_COLORS - 1); + dp_rainbow_color_list.append(QColor::fromHsvF(t, 1.0, 1.0, ALPHA / 255.0)); + } + dp_rainbow_init = true; + } + bg.setSpread(QGradient::RepeatSpread); + // bigger = faster, however it is still limited to the global UI_FREQ (refresh rate) + // only way to make it move faster is to reduce NUM_COLORS, but that will also reduce the color smoothness. + qreal rotation_speed = std::max(0.01f, v_ego) / UI_FREQ; + dp_rainbow_rotation -= rotation_speed; + + if (dp_rainbow_rotation < 0.0) { + dp_rainbow_rotation += 1.0; + dp_rainbow_color_list.append(dp_rainbow_color_list.takeFirst()); + } + // fill color + const qreal step = 1.0 / (NUM_COLORS - 1); + for (int i = 0; i < NUM_COLORS; ++i) { + bg.setColorAt(i * step, dp_rainbow_color_list.at(i)); + } + + } else if (experimental_mode) { // 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()); diff --git a/selfdrive/ui/qt/onroad/model.h b/selfdrive/ui/qt/onroad/model.h index 79547e4b8..ea2d1ddda 100644 --- a/selfdrive/ui/qt/onroad/model.h +++ b/selfdrive/ui/qt/onroad/model.h @@ -36,4 +36,7 @@ private: QPointF lead_vertices[2] = {}; Eigen::Matrix3f car_space_transform = Eigen::Matrix3f::Zero(); QRectF clip_region; + QVector dp_rainbow_color_list; + qreal dp_rainbow_rotation = 0; + bool dp_rainbow_init = false; }; diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index ec3d40961..3892e43f5 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -65,6 +65,7 @@ static void update_state(UIState *s) { void ui_update_params(UIState *s) { auto params = Params(); s->scene.is_metric = params.getBool("IsMetric"); + s->scene.dp_ui_rainbow = params.getBool("dp_ui_rainbow"); } void UIState::updateStatus() { diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 6ff67cacd..fcdb27f91 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -59,6 +59,7 @@ typedef struct UIScene { float light_sensor = -1; bool started, ignition, is_metric; + bool dp_ui_rainbow; uint64_t started_frame; } UIScene; diff --git a/system/manager/manager.py b/system/manager/manager.py index 9fe81947f..a5cc2ed55 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -41,6 +41,7 @@ def manager_init() -> None: ("OpenpilotEnabledToggle", "1"), ("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)), ("DisableLogging", "0"), + ("dp_ui_rainbow", "0"), ] if params.get_bool("RecordFrontLock"):