From 3b6e691902effb76274b051bc52c1a54a408af7f Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 14:51:43 -0700 Subject: [PATCH 1/9] bordershifter --- selfdrive/ui/paint.cc | 33 ++++++++++++++++++++------------- selfdrive/ui/paint_dp.cc | 10 +++++----- selfdrive/ui/ui.hpp | 3 ++- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 632cc2875fd85b..57be8940551186 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -1,3 +1,8 @@ +#include +#include +#include +#include +#include #include "ui.hpp" #include #include @@ -19,6 +24,8 @@ extern "C"{ #include "sidebar.hpp" #include "paint_dp.hpp" +int border_shifter = 20; + // TODO: this is also hardcoded in common/transformations/camera.py // TODO: choose based on frame input size @@ -303,8 +310,8 @@ static void ui_draw_vision_maxspeed(UIState *s) { int viz_maxspeed_w = 184; int viz_maxspeed_h = 202; - int viz_maxspeed_x = s->scene.viz_rect.x + (bdr_s*2); - int viz_maxspeed_y = s->scene.viz_rect.y + (bdr_s*1.5); + int viz_maxspeed_x = s->scene.viz_rect.x + (bdr_is*2); + int viz_maxspeed_y = s->scene.viz_rect.y + (bdr_is*1.5); int viz_maxspeed_xo = 180; viz_maxspeed_xo = 0; @@ -318,13 +325,13 @@ static void ui_draw_vision_maxspeed(UIState *s) { nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); const int text_x = viz_maxspeed_x + (viz_maxspeed_xo / 2) + (viz_maxspeed_w / 2); - ui_draw_text(s->vg, text_x, 148, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); + ui_draw_text(s->vg, text_x, 148-border_shifter, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); if (is_cruise_set) { snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", maxspeed_calc); - ui_draw_text(s->vg, text_x, 242, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); + ui_draw_text(s->vg, text_x, 242-border_shifter, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); } else { - ui_draw_text(s->vg, text_x, 242, "N/A", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); + ui_draw_text(s->vg, text_x, 242-border_shifter, "-", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); } } @@ -377,12 +384,12 @@ static void ui_draw_vision_speed(UIState *s) { static void ui_draw_vision_event(UIState *s) { const int viz_event_w = 220; - const int viz_event_x = s->scene.viz_rect.right() - (viz_event_w + bdr_s*2); - const int viz_event_y = s->scene.viz_rect.y + (bdr_s*1.5); + const int viz_event_x = s->scene.viz_rect.right() - (viz_event_w + bdr_is*2); + const int viz_event_y = s->scene.viz_rect.y + (bdr_is*1.5); if (s->scene.controls_state.getDecelForModel() && s->scene.controls_state.getEnabled()) { // draw winding road sign - const int img_turn_size = 160*1.5; - ui_draw_image(s->vg, viz_event_x - (img_turn_size / 4), viz_event_y + bdr_s - 25, img_turn_size, img_turn_size, s->img_turn, 1.0f); + const int img_turn_size = 160*1.5*0.82; + ui_draw_image(s->vg, viz_event_x - (img_turn_size / 4), viz_event_y + bdr_is - 25, img_turn_size, img_turn_size, s->img_turn, 1.0f); } else if (s->scene.controls_state.getEngageable()) { // draw steering wheel const int bg_wheel_size = 96; @@ -396,7 +403,7 @@ static void ui_draw_vision_event(UIState *s) { static void ui_draw_vision_face(UIState *s) { const int face_size = 96; - const int face_x = (s->scene.viz_rect.x + face_size + (bdr_s * 2)); + const int face_x = (s->scene.viz_rect.x + face_size + (bdr_is * 2)); const int face_y = (s->scene.viz_rect.bottom() - footer_h + ((footer_h - face_size) / 2)); ui_draw_circle_image(s->vg, face_x, face_y, face_size, s->img_face, s->scene.dmonitoring_state.getFaceDetected()); } @@ -510,9 +517,9 @@ void ui_draw_vision_alert(UIState *s, cereal::ControlsState::AlertSize va_size, color.a *= s->alert_blinking_alpha; int alr_s = alert_size_map[va_size]; - const int alr_x = scene->viz_rect.x - bdr_s + 100; - const int alr_w = scene->viz_rect.w + (bdr_s*2) - 200; - const int alr_h = alr_s+(va_size==cereal::ControlsState::AlertSize::NONE?0:bdr_s) - 100; + const int alr_x = scene->viz_rect.x - bdr_is + 100; + const int alr_w = scene->viz_rect.w + (bdr_is*2) - 200; + const int alr_h = alr_s+(va_size==cereal::ControlsState::AlertSize::NONE?0:bdr_is) - 100; const int alr_y = s->fb_h-alr_h - 100; ui_draw_rect(s->vg, alr_x, alr_y, alr_w, alr_h, color, 20); diff --git a/selfdrive/ui/paint_dp.cc b/selfdrive/ui/paint_dp.cc index 1a0515699a617e..4fbf7c413ab687 100644 --- a/selfdrive/ui/paint_dp.cc +++ b/selfdrive/ui/paint_dp.cc @@ -354,12 +354,12 @@ void bb_ui_draw_measures_right(UIState *s, int bb_x, int bb_y, int bb_w ) { void ui_draw_bbui(UIState *s) { const int bb_dml_w = 184; - const int bb_dml_x = s->scene.viz_rect.x + (bdr_s*2); - const int bb_dml_y = s->scene.viz_rect.y + (bdr_s*1.5) + 220; + const int bb_dml_x = s->scene.viz_rect.x + (bdr_is*2); + const int bb_dml_y = s->scene.viz_rect.y + (bdr_is*1.5) + 220; const int bb_dmr_w = 184; - const int bb_dmr_x =s->scene.viz_rect.x + s->scene.viz_rect.w - bb_dmr_w - (bdr_s * 2); - const int bb_dmr_y = s->scene.viz_rect.y + (bdr_s*1.5) + 220; + const int bb_dmr_x =s->scene.viz_rect.x + s->scene.viz_rect.w - bb_dmr_w - (bdr_is * 2); + const int bb_dmr_y = s->scene.viz_rect.y + (bdr_is*1.5) + 220; bb_ui_draw_measures_right(s, bb_dml_x, bb_dml_y, bb_dml_w); bb_ui_draw_measures_left(s, bb_dmr_x, bb_dmr_y, bb_dmr_w); -} \ No newline at end of file +} diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index afeb64468f7268..142b35889a4501 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -48,7 +48,8 @@ typedef struct Rect { } Rect; const int sbr_w = 300; -const int bdr_s = 30; +const int bdr_s = 10; +const int bdr_is = 30; const int header_h = 420; const int footer_h = 280; const Rect settings_btn = {50, 35, 200, 117}; From 7f463fd6c37c5b1cf07b22c3f5c35542fcb4d417 Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 14:59:12 -0700 Subject: [PATCH 2/9] smartspeed variables, sm logic, and img --- selfdrive/ui/ui.cc | 9 ++++++++- selfdrive/ui/ui.hpp | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 2fb22f64f11980..98c631a2241fbb 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -25,7 +25,7 @@ int write_param_float(float param, const char* param_name, bool persistent_param } void ui_init(UIState *s) { - s->sm = new SubMaster({"modelV2", "controlsState", "uiLayoutState", "liveCalibration", "radarState", "thermal", + s->sm = new SubMaster({"modelV2", "controlsState", "uiLayoutState", "liveCalibration", "radarState", "thermal", "liveMapData", "health", "carParams", "ubloxGnss", "driverState", "dMonitoringState", "sensorEvents", "dragonConf", "carState"}); @@ -204,6 +204,13 @@ void update_sockets(UIState *s) { if (sm.updated("thermal")) { scene.thermal = sm["thermal"].getThermal(); } + if (sm.updated("liveMapData")) { + scene.map_valid = sm["liveMapData"].getLiveMapData().getMapValid(); + scene.speedlimit = sm["liveMapData"].getLiveMapData().getSpeedLimit(); + scene.speedlimit_valid = sm["liveMapData"].getLiveMapData().getSpeedLimitValid(); + scene.speedlimitahead_valid = sm["liveMapData"].getLiveMapData().getSpeedLimitAheadValid(); + scene.speedlimitaheaddistance = sm["liveMapData"].getLiveMapData().getSpeedLimitAheadDistance(); + } if (sm.updated("ubloxGnss")) { auto data = sm["ubloxGnss"].getUbloxGnss(); if (data.which() == cereal::UbloxGnss::MEASUREMENT_REPORT) { diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index 142b35889a4501..1c5d6895d0176a 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -108,6 +108,12 @@ typedef struct UIScene { mat4 extrinsic_matrix; // Last row is 0 so we can use mat4. bool world_objects_visible; + float speedlimit; + bool speedlimit_valid; + float speedlimitaheaddistance; + bool speedlimitahead_valid; + bool map_valid; + bool is_rhd; bool frontview; bool uilayout_sidebarcollapsed; @@ -220,6 +226,8 @@ typedef struct UIState { int img_battery; int img_battery_charging; int img_network[6]; + int img_map; + int img_speed; SubMaster *sm; From 3824aadbd07e9ca772e5e65820626000661a632d Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:02:35 -0700 Subject: [PATCH 3/9] speedlimit ui elements --- selfdrive/ui/paint.cc | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 57be8940551186..4ee1af01b34b2f 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -386,7 +386,18 @@ static void ui_draw_vision_event(UIState *s) { const int viz_event_w = 220; const int viz_event_x = s->scene.viz_rect.right() - (viz_event_w + bdr_is*2); const int viz_event_y = s->scene.viz_rect.y + (bdr_is*1.5); - if (s->scene.controls_state.getDecelForModel() && s->scene.controls_state.getEnabled()) { + if (s->scene.speedlimitahead_valid && s->scene.speedlimitaheaddistance < 300 && s->scene.controls_state.getEnabled() && s->limit_set_speed) { + const int img_turn_size = 160; + const int img_turn_x = viz_event_x-(img_turn_size/4)+80; + const int img_turn_y = viz_event_y+bdr_s-25; + float img_turn_alpha = 1.0f; + nvgBeginPath(s->vg); + NVGpaint imgPaint = nvgImagePattern(s->vg, img_turn_x, img_turn_y, + img_turn_size, img_turn_size, 0, s->img_speed, img_turn_alpha); + nvgRect(s->vg, img_turn_x, img_turn_y, img_turn_size, img_turn_size); + nvgFillPaint(s->vg, imgPaint); + nvgFill(s->vg); + } else if (s->scene.controls_state.getDecelForModel() && s->scene.controls_state.getEnabled()) { // draw winding road sign const int img_turn_size = 160*1.5*0.82; ui_draw_image(s->vg, viz_event_x - (img_turn_size / 4), viz_event_y + bdr_is - 25, img_turn_size, img_turn_size, s->img_turn, 1.0f); @@ -401,6 +412,13 @@ static void ui_draw_vision_event(UIState *s) { } } +static void ui_draw_vision_map(UIState *s) { + const int map_size = 96; + const int map_x = (s->scene.ui_viz_rx + (map_size * 3) + (bdr_s * 3)); + const int map_y = (footer_y + ((footer_h - map_size) / 2)); + ui_draw_circle_image(s->vg, map_x, map_y, map_size, s->img_map, s->scene.map_valid); +} + static void ui_draw_vision_face(UIState *s) { const int face_size = 96; const int face_x = (s->scene.viz_rect.x + face_size + (bdr_is * 2)); @@ -484,6 +502,7 @@ static void ui_draw_vision_header(UIState *s) { static void ui_draw_vision_footer(UIState *s) { if (s->scene.dpUiFace) { ui_draw_vision_face(s); + ui_draw_vision_map(s); } if ((int)s->scene.dpDynamicFollow > 0) { ui_draw_df_button(s); @@ -709,6 +728,10 @@ void ui_nvg_init(UIState *s) { s->img_wheel = nvgCreateImage(s->vg, "../assets/img_chffr_wheel.png", 1); assert(s->img_wheel != 0); + s->img_map = nvgCreateImage(s->vg, "../assets/img_map.png", 1); + assert(s->img_map != 0); + s->img_speed = nvgCreateImage(s->vg, "../assets/img_trafficSign_speedahead.png", 1); + assert(s->img_speed != 0); s->img_turn = nvgCreateImage(s->vg, "../assets/img_trafficSign_turn.png", 1); assert(s->img_turn != 0); s->img_face = nvgCreateImage(s->vg, "../assets/img_driver_face.png", 1); From bff3d6b7d2866dd4db67798795087b4f87135516 Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:08:11 -0700 Subject: [PATCH 4/9] add back smartspeed --- selfdrive/ui/paint.cc | 87 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 4ee1af01b34b2f..904cad2e669a1e 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -301,37 +301,109 @@ static void ui_draw_world(UIState *s) { static void ui_draw_vision_maxspeed(UIState *s) { char maxspeed_str[32]; float maxspeed = s->scene.controls_state.getVCruise(); + float speedlimit = s->scene.speedlimit; + int speedlim_calc = speedlimit * 2.2369363 + 0.5; int maxspeed_calc = maxspeed * 0.6225 + 0.5; if (s->is_metric) { maxspeed_calc = maxspeed + 0.5; + speedlim_calc = speedlimit * 3.6 + 0.5; + } bool is_cruise_set = (maxspeed != 0 && maxspeed != SET_SPEED_NA); + bool is_speedlim_valid = s->scene.speedlimit_valid; + bool is_set_over_limit = is_speedlim_valid && s->scene.controls_state.getEnabled() && + is_cruise_set && maxspeed_calc > (speedlim_calc + speed_lim_off); int viz_maxspeed_w = 184; int viz_maxspeed_h = 202; - int viz_maxspeed_x = s->scene.viz_rect.x + (bdr_is*2); - int viz_maxspeed_y = s->scene.viz_rect.y + (bdr_is*1.5); + int viz_maxspeed_x = (s->scene.ui_viz_rx + (bdr_s*2)); + int viz_maxspeed_y = (box_y + (bdr_s*1.5)); int viz_maxspeed_xo = 180; - viz_maxspeed_xo = 0; + viz_maxspeed_w += viz_maxspeed_xo; + viz_maxspeed_x += viz_maxspeed_w - (viz_maxspeed_xo * 2); + //viz_maxspeed_xo = 0; // Draw Background - ui_draw_rect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, COLOR_BLACK_ALPHA(100), 30); + ui_draw_rect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, + is_set_over_limit ? nvgRGBA(218, 111, 37, 180) : COLOR_BLACK_ALPHA(100), 30); // Draw Border NVGcolor color = COLOR_WHITE_ALPHA(100); + if (is_set_over_limit) { + color = COLOR_OCHRE; + } else if (is_speedlim_valid) { + color = s->is_ego_over_limit ? COLOR_WHITE_ALPHA(20) : COLOR_WHITE; + } ui_draw_rect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, color, 20, 10); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); const int text_x = viz_maxspeed_x + (viz_maxspeed_xo / 2) + (viz_maxspeed_w / 2); - ui_draw_text(s->vg, text_x, 148-border_shifter, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); + ui_draw_text(s->vg, text_x, 148, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); if (is_cruise_set) { snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", maxspeed_calc); - ui_draw_text(s->vg, text_x, 242-border_shifter, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); + ui_draw_text(s->vg, text_x, 242, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); + } else { + ui_draw_text(s->vg, text_x, 242, "N/A", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); + } +} + +static void ui_draw_vision_speedlimit(UIState *s) { + char speedlim_str[32]; + float speedlimit = s->scene.speedlimit; + int speedlim_calc = speedlimit * 2.2369363 + 0.5; + if (s->is_metric) { + speedlim_calc = speedlimit * 3.6 + 0.5; + } + + bool is_speedlim_valid = s->scene.speedlimit_valid; + float hysteresis_offset = 0.5; + if (s->is_ego_over_limit) { + hysteresis_offset = 0.0; + } + s->is_ego_over_limit = is_speedlim_valid && s->scene.controls_state.getVEgo() > (speedlimit + hysteresis_offset); + + int viz_speedlim_w = 180; + int viz_speedlim_h = 202; + int viz_speedlim_x = (s->scene.ui_viz_rx + (bdr_s*2)); + int viz_speedlim_y = (box_y + (bdr_s*1.5)); + if (!is_speedlim_valid) { + viz_speedlim_w -= 5; + viz_speedlim_h -= 10; + viz_speedlim_x += 9; + viz_speedlim_y += 5; + } + // Draw Background + NVGcolor color = COLOR_WHITE_ALPHA(100); + if (is_speedlim_valid && s->is_ego_over_limit) { + color = nvgRGBA(218, 111, 37, 180); + } else if (is_speedlim_valid) { + color = COLOR_WHITE; + } + ui_draw_rect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, color, is_speedlim_valid ? 30 : 15); + + // Draw Border + if (is_speedlim_valid) { + ui_draw_rect(s->vg, viz_speedlim_x, viz_speedlim_y, viz_speedlim_w, viz_speedlim_h, + s->is_ego_over_limit ? COLOR_OCHRE : COLOR_WHITE, 20, 10); + } + const float text_x = viz_speedlim_x + viz_speedlim_w / 2; + const float text_y = viz_speedlim_y + (is_speedlim_valid ? 50 : 45); + // Draw "Speed Limit" Text + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + color = is_speedlim_valid && s->is_ego_over_limit ? COLOR_WHITE : COLOR_BLACK; + ui_draw_text(s->vg, text_x + (is_speedlim_valid ? 6 : 0), text_y, "SMART", 50, color, s->font_sans_semibold); + ui_draw_text(s->vg, text_x + (is_speedlim_valid ? 6 : 0), text_y + 40, "SPEED", 50, color, s->font_sans_semibold); + + // Draw Speed Text + color = s->is_ego_over_limit ? COLOR_WHITE : COLOR_BLACK; + if (is_speedlim_valid) { + snprintf(speedlim_str, sizeof(speedlim_str), "%d", speedlim_calc); + ui_draw_text(s->vg, text_x, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), speedlim_str, 48*2.5, color, s->font_sans_bold); } else { - ui_draw_text(s->vg, text_x, 242-border_shifter, "-", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); + ui_draw_text(s->vg, text_x, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), "N/A", 42*2.5, color, s->font_sans_semibold); } } @@ -490,6 +562,7 @@ static void ui_draw_vision_header(UIState *s) { } if (s->scene.dpUiMaxSpeed) { ui_draw_vision_maxspeed(s); + ui_draw_vision_speedlimit(s); } if (s->scene.dpUiSpeed) { ui_draw_vision_speed(s); From 614e5a002a64730c3b43a9f8e75cd7b70fd68359 Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:12:26 -0700 Subject: [PATCH 5/9] more speedlimit --- selfdrive/ui/paint.cc | 12 ++++++------ selfdrive/ui/ui.cc | 4 ++++ selfdrive/ui/ui.hpp | 5 +++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 904cad2e669a1e..444826c89a8c10 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -317,8 +317,8 @@ static void ui_draw_vision_maxspeed(UIState *s) { int viz_maxspeed_w = 184; int viz_maxspeed_h = 202; - int viz_maxspeed_x = (s->scene.ui_viz_rx + (bdr_s*2)); - int viz_maxspeed_y = (box_y + (bdr_s*1.5)); + int viz_maxspeed_x = (s->video_rect.x + (bdr_s*2)); + int viz_maxspeed_y = (s->video_rect.y + (bdr_s*1.5)); int viz_maxspeed_xo = 180; viz_maxspeed_w += viz_maxspeed_xo; @@ -367,8 +367,8 @@ static void ui_draw_vision_speedlimit(UIState *s) { int viz_speedlim_w = 180; int viz_speedlim_h = 202; - int viz_speedlim_x = (s->scene.ui_viz_rx + (bdr_s*2)); - int viz_speedlim_y = (box_y + (bdr_s*1.5)); + int viz_speedlim_x = (s->video_rect.x + (bdr_s*2)); + int viz_speedlim_y = (s->video_rect.y + (bdr_s*1.5)); if (!is_speedlim_valid) { viz_speedlim_w -= 5; viz_speedlim_h -= 10; @@ -485,8 +485,8 @@ static void ui_draw_vision_event(UIState *s) { } static void ui_draw_vision_map(UIState *s) { - const int map_size = 96; - const int map_x = (s->scene.ui_viz_rx + (map_size * 3) + (bdr_s * 3)); + const int map_x = (s->video_rect.x + (map_size * 3) + (bdr_s * 3)); + const int map_y = (s->scene.viz_rect.bottom() + ((footer_h - map_size) / 2)); const int map_y = (footer_y + ((footer_h - map_size) / 2)); ui_draw_circle_image(s->vg, map_x, map_y, map_size, s->img_map, s->scene.map_valid); } diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 98c631a2241fbb..0b2a110bacd8ad 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -339,6 +339,10 @@ void ui_update(UIState *s) { // Read params if ((s->sm)->frame % (5*UI_FREQ) == 0) { read_param(&s->is_metric, "IsMetric"); + } else if ((s->sm)->frame % (7*UI_FREQ) == 0) { + read_param(&s->speed_lim_off, "SpeedLimitOffset"); + } else if ((s->sm)->frame % (11*UI_FREQ) == 0) { + read_param(&s->limit_set_speed, "LimitSetSpeed"); } else if ((s->sm)->frame % (6*UI_FREQ) == 0) { int param_read = read_param(&s->last_athena_ping, "LastAthenaPingTime"); if (param_read != 0) { // Failed to read param diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index 1c5d6895d0176a..18a743559861ac 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -34,6 +34,8 @@ #define COLOR_YELLOW nvgRGBA(218, 202, 37, 255) #define COLOR_RED nvgRGBA(201, 34, 49, 255) #define COLOR_RED_ALPHA(x) nvgRGBA(201, 34, 49, x) +#define COLOR_OCHRE nvgRGBA(218, 111, 37, 255) +#define COLOR_OCHRE_ALPHA(x) nvgRGBA(218, 111, 37, x) #define UI_BUF_COUNT 4 @@ -259,6 +261,9 @@ typedef struct UIState { bool ignition; bool is_metric; bool longitudinal_control; + bool limit_set_speed; + bool is_ego_over_limit; + float speed_lim_off; uint64_t last_athena_ping; uint64_t started_frame; From 393d1bf0ba64d736cd995a5f39d3c001ba0ce75a Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:16:00 -0700 Subject: [PATCH 6/9] fixes --- selfdrive/ui/paint.cc | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 444826c89a8c10..3307ee23c8306a 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -301,26 +301,23 @@ static void ui_draw_world(UIState *s) { static void ui_draw_vision_maxspeed(UIState *s) { char maxspeed_str[32]; float maxspeed = s->scene.controls_state.getVCruise(); + int maxspeed_calc = maxspeed * 0.6225 + 0.5; float speedlimit = s->scene.speedlimit; int speedlim_calc = speedlimit * 2.2369363 + 0.5; - int maxspeed_calc = maxspeed * 0.6225 + 0.5; if (s->is_metric) { maxspeed_calc = maxspeed + 0.5; speedlim_calc = speedlimit * 3.6 + 0.5; - } - + int speed_lim_off = speedlim_calc * (1 + s->speed_lim_off / 100.0); bool is_cruise_set = (maxspeed != 0 && maxspeed != SET_SPEED_NA); bool is_speedlim_valid = s->scene.speedlimit_valid; bool is_set_over_limit = is_speedlim_valid && s->scene.controls_state.getEnabled() && is_cruise_set && maxspeed_calc > (speedlim_calc + speed_lim_off); - int viz_maxspeed_w = 184; int viz_maxspeed_h = 202; - int viz_maxspeed_x = (s->video_rect.x + (bdr_s*2)); - int viz_maxspeed_y = (s->video_rect.y + (bdr_s*1.5)); + int viz_maxspeed_x = (s->video_rect.x + (bdr_is*2)); + int viz_maxspeed_y = (s->video_rect.y + (bdr_is*1.5)); int viz_maxspeed_xo = 180; - viz_maxspeed_w += viz_maxspeed_xo; viz_maxspeed_x += viz_maxspeed_w - (viz_maxspeed_xo * 2); //viz_maxspeed_xo = 0; @@ -340,13 +337,13 @@ static void ui_draw_vision_maxspeed(UIState *s) { nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); const int text_x = viz_maxspeed_x + (viz_maxspeed_xo / 2) + (viz_maxspeed_w / 2); - ui_draw_text(s->vg, text_x, 148, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); + ui_draw_text(s->vg, text_x, 148-border_shifter, "MAX", 26 * 2.5, COLOR_WHITE_ALPHA(is_cruise_set ? 200 : 100), s->font_sans_regular); if (is_cruise_set) { snprintf(maxspeed_str, sizeof(maxspeed_str), "%d", maxspeed_calc); - ui_draw_text(s->vg, text_x, 242, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); + ui_draw_text(s->vg, text_x, 242-border_shifter, maxspeed_str, 48 * 2.5, COLOR_WHITE, s->font_sans_bold); } else { - ui_draw_text(s->vg, text_x, 242, "N/A", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); + ui_draw_text(s->vg, text_x, 242-border_shifter, "-", 42 * 2.5, COLOR_WHITE_ALPHA(100), s->font_sans_semibold); } } @@ -367,8 +364,8 @@ static void ui_draw_vision_speedlimit(UIState *s) { int viz_speedlim_w = 180; int viz_speedlim_h = 202; - int viz_speedlim_x = (s->video_rect.x + (bdr_s*2)); - int viz_speedlim_y = (s->video_rect.y + (bdr_s*1.5)); + int viz_speedlim_x = (s->video_rect.x + (bdr_is*2)); + int viz_speedlim_y = (s->video_rect.y + (bdr_is*1.5)); if (!is_speedlim_valid) { viz_speedlim_w -= 5; viz_speedlim_h -= 10; From 06d9d430009ee10f643bc1b3944970d7f39dd99e Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:18:41 -0700 Subject: [PATCH 7/9] map_size --- selfdrive/ui/paint.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc index 3307ee23c8306a..c0ee6f989f75cc 100644 --- a/selfdrive/ui/paint.cc +++ b/selfdrive/ui/paint.cc @@ -482,9 +482,9 @@ static void ui_draw_vision_event(UIState *s) { } static void ui_draw_vision_map(UIState *s) { + const int map_size = 96; const int map_x = (s->video_rect.x + (map_size * 3) + (bdr_s * 3)); const int map_y = (s->scene.viz_rect.bottom() + ((footer_h - map_size) / 2)); - const int map_y = (footer_y + ((footer_h - map_size) / 2)); ui_draw_circle_image(s->vg, map_x, map_y, map_size, s->img_map, s->scene.map_valid); } From 10f8209fb08ad2481340c84bc864fe9953820882 Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:24:33 -0700 Subject: [PATCH 8/9] missing assets --- selfdrive/assets/img_trafficSign_speedahead.png | Bin 0 -> 30278 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 selfdrive/assets/img_trafficSign_speedahead.png diff --git a/selfdrive/assets/img_trafficSign_speedahead.png b/selfdrive/assets/img_trafficSign_speedahead.png new file mode 100644 index 0000000000000000000000000000000000000000..8357ff8a9112fc7e630869f19868bbe9df2e96e5 GIT binary patch literal 30278 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 literal 0 HcmV?d00001 From fc6cac0133fb4327d2499facb0bd3fedbcdf2ae3 Mon Sep 17 00:00:00 2001 From: Prius <36933347+rav4kumar@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:45:52 -0700 Subject: [PATCH 9/9] missing param --- common/params_pyx.pyx | 4 ++++ selfdrive/manager.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index cb1753a04d18a9..af147697d3a01d 100755 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -45,7 +45,10 @@ keys = { b"LastAthenaPingTime": [TxType.PERSISTENT], b"LastUpdateTime": [TxType.PERSISTENT], b"LastUpdateException": [TxType.PERSISTENT], + b"LimitSetSpeed": [TxType.PERSISTENT], + b"LimitSetSpeedNeural": [TxType.PERSISTENT], b"LiveParameters": [TxType.PERSISTENT], + b"LongitudinalControl": [TxType.PERSISTENT], b"OpenpilotEnabledToggle": [TxType.PERSISTENT], b"LaneChangeEnabled": [TxType.PERSISTENT], b"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], @@ -56,6 +59,7 @@ keys = { b"ReleaseNotes": [TxType.PERSISTENT], b"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START], b"SubscriberInfo": [TxType.PERSISTENT], + b"SpeedLimitOffset": [TxType.PERSISTENT], b"TermsVersion": [TxType.PERSISTENT], b"TrainingVersion": [TxType.PERSISTENT], b"UpdateAvailable": [TxType.CLEAR_ON_MANAGER_START], diff --git a/selfdrive/manager.py b/selfdrive/manager.py index 9f1b1efdab2387..50f4975120b284 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -580,6 +580,10 @@ def main(): ("HasCompletedSetup", "0"), ("IsUploadRawEnabled", "1"), ("IsLdwEnabled", "1"), + ("SpeedLimitOffset", "0"), + ("LongitudinalControl", "1"), + ("LimitSetSpeed", "1"), + ("LimitSetSpeedNeural", "1"), ("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8')), ("OpenpilotEnabledToggle", "1"), ("LaneChangeEnabled", "1"),