diff --git a/common/params_keys.h b/common/params_keys.h index ef32cbcbb3..6d4ce33be3 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -164,6 +164,7 @@ inline static std::unordered_map keys = { {"StandstillTimer", {PERSISTENT | BACKUP, BOOL, "0"}}, {"VisualStyle", {PERSISTENT | BACKUP, INT, "0"}}, {"VisualStyleBlend", {PERSISTENT | BACKUP, BOOL, "0"}}, + {"VisualStyleOverheadBlend", {PERSISTENT | BACKUP, BOOL, "0"}}, {"VisualStyleBlendThreshold", {PERSISTENT | BACKUP, INT, "20"}}, {"VisualRadarTracks", {PERSISTENT | BACKUP, BOOL, "0"}}, {"VisualRadarTracksDelay", {PERSISTENT | BACKUP, FLOAT, "0.0"}}, diff --git a/selfdrive/ui/qt/onroad/model.cc b/selfdrive/ui/qt/onroad/model.cc index f4de7941ac..50efa192e6 100644 --- a/selfdrive/ui/qt/onroad/model.cc +++ b/selfdrive/ui/qt/onroad/model.cc @@ -128,7 +128,7 @@ void ModelRenderer::update_model(const cereal::ModelDataV2::Reader &model, const if (s->scene.visual_style == 0) { max_distance = std::clamp(*(model_position.getX().end() - 1), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE); } else { - max_distance = std::clamp(*(model_position.getX().end() - 1), 0.0f, 300.0f); + max_distance = std::clamp(*(model_position.getX().end() - 1), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE); } // update lane lines @@ -592,6 +592,18 @@ bool ModelRenderer::mapToScreen(float in_x, float in_y, float in_z, QPointF *out // Normal perspective (3D) Eigen::Vector3f input(in_x, in_y, in_z); + + if (s->scene.visual_style_blend == 1 && s->scene.visual_style != 0) { + float IN_X_OFFSET = mapRange(blend_speed_mph, 20.0f, 50.0f, 0.0f, 24.0f); + float IN_Y_OFFSET = mapRange(blend_speed_mph, 20.0f, 50.0f, 1.0f, 2.0f); + float IN_Z_OFFSET = mapRange(blend_speed_mph, 20.0f, 50.0f, 0.0f, 5.0f); + float PITCH_DEG = mapRange(blend_speed_mph, 20.0f, 50.0f, 0.0f, 5.0f); + + input = Eigen::Vector3f(in_x + IN_X_OFFSET, in_y / IN_Y_OFFSET, in_z + IN_Z_OFFSET); + Eigen::AngleAxisf pitch_rot(PITCH_DEG * M_PI / 180.0f, Eigen::Vector3f::UnitY()); + input = pitch_rot * input; + } + auto pt = car_space_transform * input; bool normal_valid = (pt.z() > 1e-3f && std::isfinite(pt.x()) && std::isfinite(pt.y())); @@ -624,15 +636,15 @@ bool ModelRenderer::mapToScreen(float in_x, float in_y, float in_z, QPointF *out } // Blending mode - if (s->scene.visual_blend == 1 && s->scene.visual_style != 0) { + if (s->scene.visual_style_overhead_blend == 1 && s->scene.visual_style != 0) { static float blend = 0.0f; // 0 = 3D, 1 = 2D static float target_blend = 0.0f; // where we want to go static double last_t = millis_since_boot(); // Hysteresis logic - if (target_blend < 0.5f && blend_speed_mph > s->scene.visual_blend_threshold) { + if (target_blend < 0.5f && blend_speed_mph > s->scene.visual_style_blend_threshold) { target_blend = 1.0f; // switch to 2D - } else if (target_blend > 0.5f && blend_speed_mph < (s->scene.visual_blend_threshold - 5)) { + } else if (target_blend > 0.5f && blend_speed_mph < (s->scene.visual_style_blend_threshold - 5)) { target_blend = 0.0f; // switch back to 3D } diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc index e33c192453..2e31d1e7d6 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/visuals_panel.cc @@ -72,6 +72,13 @@ VisualsPanel::VisualsPanel(QWidget *parent) : QWidget(parent) { }, { "VisualStyleBlend", + tr("Blend to Visual Style"), + tr("Blend to view when using Minimal/Vision visual style."), + "../assets/offroad/icon_monitoring.png", + false, + }, + { + "VisualStyleOverheadBlend", tr("Blend to Overhead Visual Style"), tr("Blend to Overhead view when using Minimal/Vision visual style."), "../assets/offroad/icon_monitoring.png", diff --git a/selfdrive/ui/sunnypilot/ui.cc b/selfdrive/ui/sunnypilot/ui.cc index ee0c42cea3..3b8776bc65 100644 --- a/selfdrive/ui/sunnypilot/ui.cc +++ b/selfdrive/ui/sunnypilot/ui.cc @@ -37,6 +37,7 @@ UIStateSP::UIStateSP(QObject *parent) : UIState(parent) { param_watcher->addParam("StandstillTimer"); param_watcher->addParam("VisualStyle"); param_watcher->addParam("VisualStyleBlend"); + param_watcher->addParam("VisualStyleOverheadBlend"); param_watcher->addParam("VisualStyleBlendThreshold"); param_watcher->addParam("VisualRadarTracks"); param_watcher->addParam("VisualRadarTracksDelay"); @@ -63,8 +64,9 @@ void ui_update_params_sp(UIStateSP *s) { s->scene.speed_limit_mode = std::atoi(params.get("SpeedLimitMode").c_str()); s->scene.road_name = params.getBool("RoadNameToggle"); s->scene.visual_style = QString::fromStdString(params.get("VisualStyle")).toInt(); - s->scene.visual_blend = QString::fromStdString(params.get("VisualStyleBlend")).toInt(); - s->scene.visual_blend_threshold = QString::fromStdString(params.get("VisualStyleBlendThreshold")).toInt(); + s->scene.visual_style_blend = QString::fromStdString(params.get("VisualStyleBlend")).toInt(); + s->scene.visual_style_overhead_blend = QString::fromStdString(params.get("VisualStyleOverheadBlend")).toInt(); + s->scene.visual_style_blend_threshold = QString::fromStdString(params.get("VisualStyleBlendThreshold")).toInt(); s->scene.visual_radar_tracks = QString::fromStdString(params.get("VisualRadarTracks")).toInt(); s->scene.visual_radar_tracks_delay = QString::fromStdString(params.get("VisualRadarTracksDelay")).toFloat(); s->scene.visual_wide_cam = QString::fromStdString(params.get("VisualWideCam")).toInt(); diff --git a/selfdrive/ui/sunnypilot/ui_scene.h b/selfdrive/ui/sunnypilot/ui_scene.h index 7c555483a2..fb22c17f7a 100644 --- a/selfdrive/ui/sunnypilot/ui_scene.h +++ b/selfdrive/ui/sunnypilot/ui_scene.h @@ -13,8 +13,9 @@ typedef struct UISceneSP : UIScene { int speed_limit_mode = 0; bool road_name = false; int visual_style = 0; - int visual_blend = 0; - int visual_blend_threshold = 20.0; + int visual_style_blend = 0; + int visual_style_overhead_blend = 0; + int visual_style_blend_threshold = 20.0; int visual_radar_tracks = 0; float visual_radar_tracks_delay = 0; int visual_wide_cam = 0;