diff --git a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc index 4294b16a..d99f39af 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc +++ b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.cc @@ -623,6 +623,41 @@ void FrogPilotAnnotatedCameraWidget::paintLongitudinalPaused(QPainter &p) { p.restore(); } +void FrogPilotAnnotatedCameraWidget::paintPathEdges(QPainter &p, int height) { + p.save(); + + QLinearGradient gradient(0, height, 0, 0); + + std::function setPathEdgeColors = [&gradient](const QColor &baseColor) { + gradient.setColorAt(0.0f, QColor(baseColor.red(), baseColor.green(), baseColor.blue(), 255.0f * 0.4f)); + gradient.setColorAt(0.5f, QColor(baseColor.red(), baseColor.green(), baseColor.blue(), 255.0f * 0.35f)); + gradient.setColorAt(1.0f, QColor(baseColor.red(), baseColor.green(), baseColor.blue(), 255.0f * 0.0f)); + }; + + if (frogpilot_scene.always_on_lateral_active) { + setPathEdgeColors(bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE]); + } else if (frogpilot_scene.conditional_status == 1) { + setPathEdgeColors(bg_colors[STATUS_CEM_DISABLED]); + } else if (experimentalMode) { + setPathEdgeColors(bg_colors[STATUS_EXPERIMENTAL_MODE_ENABLED]); + } else if (frogpilot_toggles.value("color_scheme").toString() != "stock") { + setPathEdgeColors(QColor(frogpilot_toggles.value("path_edges_color").toString())); + } else { + gradient.setColorAt(0.0f, QColor::fromHslF(148.0f / 360.0f, 0.94f, 0.41f, 0.4f)); + gradient.setColorAt(0.5f, QColor::fromHslF(112.0f / 360.0f, 1.0f, 0.54f, 0.35f)); + gradient.setColorAt(1.0f, QColor::fromHslF(112.0f / 360.0f, 1.0f, 0.54f, 0.0f)); + } + + p.setBrush(gradient); + + QPainterPath path; + path.addPolygon(track_vertices); + path.addPolygon(track_edge_vertices); + p.drawPath(path); + + p.restore(); +} + void FrogPilotAnnotatedCameraWidget::paintPedalIcons(QPainter &p) { p.save(); diff --git a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h index 57148aaf..115db0b6 100644 --- a/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h +++ b/frogpilot/ui/qt/onroad/frogpilot_annotated_camera.h @@ -16,6 +16,7 @@ public: void paintBlindSpotPath(QPainter &p); 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 updateState(const UIState &s, const FrogPilotUIState &fs); bool hideBottomIcons; @@ -41,6 +42,8 @@ public: QPoint experimentalButtonPosition; QPolygonF track_adjacent_vertices[2]; + QPolygonF track_edge_vertices; + QPolygonF track_vertices; QRect adjacentLeadTextRect; QRect leadTextRect; diff --git a/selfdrive/ui/qt/onroad/model.cc b/selfdrive/ui/qt/onroad/model.cc index 21936bab..0f47d3af 100644 --- a/selfdrive/ui/qt/onroad/model.cc +++ b/selfdrive/ui/qt/onroad/model.cc @@ -127,7 +127,7 @@ void ModelRenderer::update_model(const cereal::ModelDataV2::Reader &model, const UIState *s = uiState(); path_width *= s->status == STATUS_ENGAGED ? 1.0f : s->status == STATUS_ALWAYS_ON_LATERAL_ACTIVE ? 0.75f : 0.50f; } - mapLineToPolygon(model_position, frogpilot_toggles.value("model_ui").toBool() ? path_width : 0.9, path_offset_z, &track_vertices, max_idx, false); + mapLineToPolygon(model_position, frogpilot_toggles.value("model_ui").toBool() ? path_width * (1 - (frogpilot_toggles.value("path_edge_width").toDouble() / 100.0f)) : 0.9, path_offset_z, &track_vertices, max_idx, false); // FrogPilot variables FrogPilotUIState *fs = frogpilotUIState(); @@ -135,6 +135,10 @@ void ModelRenderer::update_model(const cereal::ModelDataV2::Reader &model, const const cereal::FrogPilotPlan::Reader &frogpilotPlan = fpsm["frogpilotPlan"].getFrogpilotPlan(); + frogpilot_nvg->track_vertices = track_vertices; + + mapLineToPolygon(model_position, frogpilot_toggles.value("model_ui").toBool() ? path_width : 0, path_offset_z, &frogpilot_nvg->track_edge_vertices, max_idx, false); + mapAveragedLineToPolygon(lane_lines[0], lane_lines[1], frogpilotPlan.getLaneWidthLeft() / 2.0f, 0, &frogpilot_nvg->track_adjacent_vertices[0], max_idx, height, false); mapAveragedLineToPolygon(lane_lines[2], lane_lines[3], frogpilotPlan.getLaneWidthRight() / 2.0f, 0, &frogpilot_nvg->track_adjacent_vertices[1], max_idx, height, false); } @@ -207,6 +211,8 @@ void ModelRenderer::drawPath(QPainter &painter, const cereal::ModelDataV2::Reade } else if (frogpilot_toggles.value("blind_spot_path").toBool()) { frogpilot_nvg->paintBlindSpotPath(painter); } + + frogpilot_nvg->paintPathEdges(painter, height); } void ModelRenderer::updatePathGradient(QLinearGradient &bg) {