diff --git a/cereal/car.capnp b/cereal/car.capnp index 177ba4d62eceff..7bd002504850dd 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -72,12 +72,12 @@ struct CarEvent @0x9b1657f34caf3ad3 { calibrationProgress @47; lowBattery @48; invalidGiraffeHonda @49; - manualSteeringRequired @50; - manualSteeringRequiredBlinkersOn @51; - vehicleModelInvalid @52; - controlsFailed @53; - sensorDataInvalid @54; - commIssue @55; + vehicleModelInvalid @50; + controlsFailed @51; + sensorDataInvalid @52; + commIssue @53; + manualSteeringRequired @54; + manualSteeringRequiredBlinkersOn @55; } } @@ -122,13 +122,13 @@ struct CarState { leftBlinker @20 :Bool; rightBlinker @21 :Bool; genericToggle @23 :Bool; - readdistancelines @26 :Float32; - lkMode @27 :Bool; + readdistancelines @27 :Float32; + lkMode @28 :Bool; # lock info doorOpen @24 :Bool; seatbeltUnlatched @25 :Bool; - canValid @28 :Bool; + canValid @26 :Bool; # which packets this state came from canMonoTimes @12: List(UInt64); @@ -348,6 +348,8 @@ struct CarParams { kiBP @2 :List(Float32); kiV @3 :List(Float32); kf @4 :Float32; + dampTime @5 :Float32; + reactMPC @6 :Float32; } struct LongitudinalPIDTuning { @@ -365,6 +367,7 @@ struct CarParams { innerLoopGain @1 :Float32; timeConstant @2 :Float32; actuatorEffectiveness @3 :Float32; + reactMPC @4 :Float32; } diff --git a/cereal/log.capnp b/cereal/log.capnp index adf76c488dacd3..28efb879540d80 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -403,6 +403,7 @@ struct ControlsState @0x97ff69c53601abf1 { jerkFactor @12 :Float32; angleSteers @13 :Float32; # Steering angle in degrees. angleSteersDes @29 :Float32; + dampAngleSteersDes @54 :Float32; curvature @37 :Float32; # path curvature from vehicle model hudLeadDEPRECATED @14 :Int32; cumLagMs @15 :Float32; @@ -662,6 +663,9 @@ struct PathPlan { angleOffset @11 :Float32; sensorValid @14 :Bool; commIssue @15 :Bool; + mpcAngles @16 :List(Float32); + mpcRates @17 :List(Float32); + mpcTimes @18 :List(Float32); } struct LiveLocationData { @@ -1695,6 +1699,11 @@ struct KalmanOdometry { rotStd @3 :List(Float32); # std rad/s in device frame } +struct DynamicFollowData { + gas @0 :Float32; + brake @1 :Float32; +} + struct Event { # in nanoseconds? logMonoTime @0 :UInt64; diff --git a/opendbc/honda_insight_ex_2019_can_generated.dbc b/opendbc/honda_insight_ex_2019_can_generated.dbc index cbeff828b88502..23c83b1f07eff6 100644 --- a/opendbc/honda_insight_ex_2019_can_generated.dbc +++ b/opendbc/honda_insight_ex_2019_can_generated.dbc @@ -200,7 +200,7 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ IMPERIAL_UNIT : 55|2@0+ (1,0) [0|3] "" XXX SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index f52bec1ede0a8b..6c001b5a8a860f 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -96,7 +96,8 @@ def get_can_signals(CP): signals += [("CAR_GAS", "GAS_PEDAL_2", 0), ("MAIN_ON", "SCM_FEEDBACK", 0), ("EPB_STATE", "EPB_STATUS", 0), - ("CRUISE_SPEED", "ACC_HUD", 0)] + ("CRUISE_SPEED", "ACC_HUD", 0), + ("IMPERIAL_UNIT", "ACC_HUD", 0)] checks += [("GAS_PEDAL_2", 100)] else: # Nidec signals. @@ -382,6 +383,7 @@ def update(self, cp, cp_cam): # TODO: discover the CAN msg that has the imperial unit bit for all other cars self.is_metric = not cp.vl["HUD_SETTING"]['IMPERIAL_UNIT'] if self.CP.carFingerprint in (CAR.CIVIC) else False + self.is_metric = 3 # carstate standalone tester if __name__ == '__main__': diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 34110a34ad4419..2281f2163e4543 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -65,11 +65,10 @@ def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx): 'CRUISE_SPEED': hud.v_cruise, 'ENABLE_MINI_CAR': hud.mini_car, 'HUD_LEAD': hud.car, - 'SET_ME_X01': 0x01, - 'HUD_DISTANCE_3': 1, - 'HUD_DISTANCE': hud.dist_lines, # max distance setting on display + 'HUD_DISTANCE': 3, # max distance setting on display 'IMPERIAL_UNIT': int(not is_metric), 'SET_ME_X01_2': 1, + 'SET_ME_X01': 1, } commands.append(packer.make_can_msg("ACC_HUD", 0, acc_hud_values, idx)) diff --git a/selfdrive/ui/Makefile b/selfdrive/ui/Makefile index c6cce40a5ef636..c00d9df28d70ed 100644 --- a/selfdrive/ui/Makefile +++ b/selfdrive/ui/Makefile @@ -16,7 +16,7 @@ CXXFLAGS = -std=c++11 -fPIC -O2 $(WARN_FLAGS) ZMQ_LIBS = -l:libczmq.a -l:libzmq.a -lgnustl_shared CEREAL_LIBS = -l:libcapn.a -CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o +CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o ../../cereal/gen/c/car.capnp.o NANOVG_FLAGS = -I$(PHONELIBS)/nanovg JSON_FLAGS = -I$(PHONELIBS)/json/src diff --git a/selfdrive/ui/ui.c b/selfdrive/ui/ui.c index 6e24c9220b862b..b35ebc1c8baf6a 100644 --- a/selfdrive/ui/ui.c +++ b/selfdrive/ui/ui.c @@ -36,6 +36,8 @@ #include "cereal/gen/c/log.capnp.h" #include "slplay.h" +#include "devicestate.c" + #define STATUS_STOPPED 0 #define STATUS_DISENGAGED 1 #define STATUS_ENGAGED 2 @@ -58,8 +60,9 @@ const int vwp_w = 1920; const int vwp_h = 1080; const int nav_w = 640; const int nav_ww= 760; -const int sbr_w = 300; -const int bdr_s = 30; +const int sbr_w = 0; //300; +const int bdr_s = 0; //30; +const int bdr_is = 30; const int box_x = sbr_w+bdr_s; const int box_y = bdr_s; const int box_w = vwp_w-sbr_w-(bdr_s*2); @@ -69,7 +72,7 @@ const int header_h = 420; const int footer_h = 280; const int footer_y = vwp_h-bdr_s-footer_h; -const int UI_FREQ = 30; // Hz +const int UI_FREQ = 60; // Hz const int MODEL_PATH_MAX_VERTICES_CNT = 98; const int MODEL_LANE_PATH_CNT = 3; @@ -98,6 +101,17 @@ const int alert_sizes[] = { [ALERTSIZE_FULL] = vwp_h, }; +#define UIEVENT_BTN1 1 +#define UIEVENT_BTN2 2 +#define UIEVENT_BTN3 3 +#define UIEVENT_BTN4 4 +#define UIEVENT_BTN5 5 +#define UIEVENT_BTN6 6 +#define UIEVENT_BTN7 7 +#define UIEVENT_BTN8 8 +#define UIEVENT_STARTUP 10 +#define UIEVENT_SHUTDOWN 11 + const int SET_SPEED_NA = 255; // TODO: this is also hardcoded in common/transformations/camera.py @@ -160,9 +174,29 @@ typedef struct UIScene { uint64_t started_ts; + //BB CPU TEMP + uint16_t maxCpuTemp; + uint32_t maxBatTemp; + float gpsAccuracy; + float freeSpace; + float angleSteers; + float angleSteersDes; + //BB END CPU TEMP + bool steerOverride; + // Used to display calibration progress + int cal_status; + int cal_perc; + // Used to show gps planner status bool gps_planner_active; + bool brakeLights; + bool leftBlinker; + bool rightBlinker; + int blinker_blinkingrate; + int spammedButton; + int spammedButtonTimeout; + bool is_playing_alert; } UIScene; @@ -200,6 +234,7 @@ typedef struct UIState { int img_turn; int img_face; int img_map; + int img_brake; void *ctx; @@ -211,6 +246,8 @@ typedef struct UIState { void *livempc_sock_raw; void *plus_sock_raw; void *map_data_sock_raw; + void *gps_sock_raw; + void *carstate_sock_raw; void *uilayout_sock_raw; @@ -285,8 +322,15 @@ typedef struct UIState { model_path_vertices_data model_path_vertices[MODEL_LANE_PATH_CNT * 2]; track_vertices_data track_vertices[2]; + + bool ignoreLayout; + unsigned long lastdriveEnd; + int touchTimeout; + } UIState; +#include "dashcam.h" + static int last_brightness = -1; static void set_brightness(UIState *s, int brightness) { if (last_brightness != brightness && (s->awake || brightness == 0)) { @@ -471,6 +515,7 @@ void ui_sound_init(char **error) { static void ui_init(UIState *s) { memset(s, 0, sizeof(UIState)); + s->ignoreLayout = true; pthread_mutex_init(&s->lock, NULL); pthread_cond_init(&s->bg_cond, NULL); @@ -485,6 +530,7 @@ static void ui_init(UIState *s) { s->radarstate_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8012"); s->livempc_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8035"); s->plus_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8037"); + s->gps_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8032"); #ifdef SHOW_SPEEDLIMIT s->map_data_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8065"); @@ -524,6 +570,9 @@ static void ui_init(UIState *s) { assert(s->img_map >= 0); s->img_map = nvgCreateImage(s->vg, "../assets/img_map.png", 1); + assert(s->img_brake >= 0); + s->img_brake = nvgCreateImage(s->vg, "../assets/img_brake_disc.png", 1); + // init gl s->frame_program = load_program(frame_vertex_shader, frame_fragment_shader); assert(s->frame_program); @@ -627,6 +676,7 @@ static void ui_init_vision(UIState *s, const VisionStreamBufs back_bufs, .front_box_height = ui_info.front_box_height, .world_objects_visible = false, // Invisible until we receive a calibration message. .gps_planner_active = false, + .spammedButton = -1, }; s->rgb_width = back_bufs.width; @@ -823,7 +873,9 @@ static void update_track_data(UIState *s, bool is_mpc, track_vertices_data *pvd) vec4 p_car_space = (vec4){{px, py, 0., 1.}}; vec3 p_full_frame = car_space_to_full_frame(s, p_car_space); - if (p_full_frame.v[0] < 0. || p_full_frame.v[1] < 0.) { + float x = p_full_frame.v[0]; + float y = p_full_frame.v[1]; + if (x < 0 || y < 0) { continue; } pvd->v[pvd->cnt].x = p_full_frame.v[0]; @@ -926,14 +978,12 @@ static void draw_steering(UIState *s, float curvature) { static void draw_frame(UIState *s) { const UIScene *scene = &s->scene; - float x1, x2, y1, y2; if (s->scene.frontview) { glBindVertexArray(s->frame_vao[1]); } else { glBindVertexArray(s->frame_vao[0]); } - mat4 *out_mat; if (s->scene.frontview || s->scene.fullview) { out_mat = &s->front_frame_mat; @@ -946,11 +996,9 @@ static void draw_frame(UIState *s) { } else if (!scene->frontview && s->cur_vision_idx >= 0) { glBindTexture(GL_TEXTURE_2D, s->frame_texs[s->cur_vision_idx]); } - glUseProgram(s->frame_program); glUniform1i(s->frame_texture_loc, 0); glUniformMatrix4fv(s->frame_transform_loc, 1, GL_TRUE, out_mat->v); - assert(glGetError() == GL_NO_ERROR); glEnableVertexAttribArray(0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void*)0); @@ -1060,10 +1108,391 @@ static void ui_draw_world(UIState *s) { fillAlpha = (int)(min(fillAlpha, 255)); } draw_chevron(s, scene->lead_d_rel+2.7, scene->lead_y_rel, 25, - nvgRGBA(201, 34, 49, fillAlpha), nvgRGBA(218, 202, 37, 255)); + nvgRGBA(201, 34, 49, fillAlpha), nvgRGBA(255, 255, 255, 255)); + } +} + +//BB START: functions added for the display of various items +static int bb_ui_draw_measure(UIState *s, const char* bb_value, const char* bb_uom, const char* bb_label, + int bb_x, int bb_y, int bb_uom_dx, + NVGcolor bb_valueColor, NVGcolor bb_labelColor, NVGcolor bb_uomColor, + int bb_valueFontSize, int bb_labelFontSize, int bb_uomFontSize ) { + const UIScene *scene = &s->scene; + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + int dx = 0; + if (strlen(bb_uom) > 0) { + dx = (int)(bb_uomFontSize*2.5/2); + } + //print value + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, bb_valueFontSize*2.5); + nvgFillColor(s->vg, bb_valueColor); + nvgText(s->vg, bb_x-dx/2, bb_y+ (int)(bb_valueFontSize*2.5)+5, bb_value, NULL); + //print label + nvgFontFace(s->vg, "sans-regular"); + nvgFontSize(s->vg, bb_labelFontSize*2.5); + nvgFillColor(s->vg, bb_labelColor); + nvgText(s->vg, bb_x, bb_y + (int)(bb_valueFontSize*2.5)+5 + (int)(bb_labelFontSize*2.5)+5, bb_label, NULL); + //print uom + if (strlen(bb_uom) > 0) { + nvgSave(s->vg); + int rx =bb_x + bb_uom_dx + bb_valueFontSize -3; + int ry = bb_y + (int)(bb_valueFontSize*2.5/2)+25; + nvgTranslate(s->vg,rx,ry); + nvgRotate(s->vg, -1.5708); //-90deg in radians + nvgFontFace(s->vg, "sans-regular"); + nvgFontSize(s->vg, (int)(bb_uomFontSize*2.5)); + nvgFillColor(s->vg, bb_uomColor); + nvgText(s->vg, 0, 0, bb_uom, NULL); + nvgRestore(s->vg); + } + return (int)((bb_valueFontSize + bb_labelFontSize)*2.5) + 5; +} + +static void bb_ui_draw_measures_left(UIState *s, int bb_x, int bb_y, int bb_w ) { + const UIScene *scene = &s->scene; + int bb_rx = bb_x + (int)(bb_w/2); + int bb_ry = bb_y; + int bb_h = 5; + NVGcolor lab_color = nvgRGBA(255, 255, 255, 200); + NVGcolor uom_color = nvgRGBA(255, 255, 255, 200); + int value_fontSize=30; + int label_fontSize=15; + int uom_fontSize = 15; + int bb_uom_dx = (int)(bb_w /2 - uom_fontSize*2.5) ; + + //add CPU temperature + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + if((int)(scene->maxCpuTemp/10) > 80) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if((int)(scene->maxCpuTemp/10) > 92) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // temp is alway in C * 10 + snprintf(val_str, sizeof(val_str), "%d°C", (int)(scene->maxCpuTemp/10)); + snprintf(uom_str, sizeof(uom_str), ""); + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "CPU TEMP", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add battery temperature + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + if((int)(scene->maxBatTemp/1000) > 40) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if((int)(scene->maxBatTemp/1000) > 50) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // temp is alway in C * 1000 + snprintf(val_str, sizeof(val_str), "%d°C", (int)(scene->maxBatTemp/1000)); + snprintf(uom_str, sizeof(uom_str), ""); + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "BAT TEMP", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add grey panda GPS accuracy + if (true) { + char val_str[16]; + char uom_str[3]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + //show red/orange if gps accuracy is high + if(scene->gpsAccuracy > 0.59) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if(scene->gpsAccuracy > 0.8) { + val_color = nvgRGBA(255, 0, 0, 200); + } + + // gps accuracy is always in meters + snprintf(val_str, sizeof(val_str), "%.2f", (s->scene.gpsAccuracy)); + snprintf(uom_str, sizeof(uom_str), "m");; + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "GPS PREC", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add free space - from bthaler1 + if (true) { + char val_str[16]; + char uom_str[3]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + + //show red/orange if free space is low + if(scene->freeSpace < 0.4) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if(scene->freeSpace < 0.2) { + val_color = nvgRGBA(255, 0, 0, 200); + } + + snprintf(val_str, sizeof(val_str), "%.0f%%", s->scene.freeSpace* 100); + snprintf(uom_str, sizeof(uom_str), ""); + + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "FREE SPACE", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + //finally draw the frame + bb_h += 20; + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, bb_x, bb_y, bb_w, bb_h, 20); + nvgStrokeColor(s->vg, nvgRGBA(255,255,255,80)); + nvgStrokeWidth(s->vg, 6); + nvgStroke(s->vg); +} + + +static void bb_ui_draw_measures_right(UIState *s, int bb_x, int bb_y, int bb_w ) { + const UIScene *scene = &s->scene; + int bb_rx = bb_x + (int)(bb_w/2); + int bb_ry = bb_y; + int bb_h = 5; + NVGcolor lab_color = nvgRGBA(255, 255, 255, 200); + NVGcolor uom_color = nvgRGBA(255, 255, 255, 200); + int value_fontSize=30; + int label_fontSize=15; + int uom_fontSize = 15; + int bb_uom_dx = (int)(bb_w /2 - uom_fontSize*2.5) ; + + //add visual radar relative distance + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + if (scene->lead_status) { + //show RED if less than 5 meters + //show orange if less than 15 meters + if((int)(scene->lead_d_rel) < 15) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if((int)(scene->lead_d_rel) < 5) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // lead car relative distance is always in meters + snprintf(val_str, sizeof(val_str), "%d", (int)scene->lead_d_rel); + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + snprintf(uom_str, sizeof(uom_str), "m "); + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "REL DIST", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add visual radar relative speed + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + if (scene->lead_status) { + //show Orange if negative speed (approaching) + //show Orange if negative speed faster than 5mph (approaching fast) + if((int)(scene->lead_v_rel) < 0) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if((int)(scene->lead_v_rel) < -5) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // lead car relative speed is always in meters + if (s->is_metric) { + snprintf(val_str, sizeof(val_str), "%d", (int)(scene->lead_v_rel * 3.6 + 0.5)); + } else { + snprintf(val_str, sizeof(val_str), "%d", (int)(scene->lead_v_rel * 2.2374144 + 0.5)); + } + } else { + snprintf(val_str, sizeof(val_str), "-"); + } + if (s->is_metric) { + snprintf(uom_str, sizeof(uom_str), "km/h");; + } else { + snprintf(uom_str, sizeof(uom_str), "mph"); + } + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "REL SPEED", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add steering angle + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + //show Orange if more than 6 degrees + //show red if more than 12 degrees + if(((int)(scene->angleSteers) < -6) || ((int)(scene->angleSteers) > 6)) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if(((int)(scene->angleSteers) < -12) || ((int)(scene->angleSteers) > 12)) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // steering is in degrees + snprintf(val_str, sizeof(val_str), "%.0f°",(scene->angleSteers)); + + snprintf(uom_str, sizeof(uom_str), ""); + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "REAL STEER", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + //add desired steering angle + if (true) { + char val_str[16]; + char uom_str[6]; + NVGcolor val_color = nvgRGBA(255, 255, 255, 200); + //show Orange if more than 6 degrees + //show red if more than 12 degrees + if(((int)(scene->angleSteersDes) < -6) || ((int)(scene->angleSteersDes) > 6)) { + val_color = nvgRGBA(255, 188, 3, 200); + } + if(((int)(scene->angleSteersDes) < -12) || ((int)(scene->angleSteersDes) > 12)) { + val_color = nvgRGBA(255, 0, 0, 200); + } + // steering is in degrees + snprintf(val_str, sizeof(val_str), "%.0f°",(scene->angleSteersDes)); + + snprintf(uom_str, sizeof(uom_str), ""); + bb_h +=bb_ui_draw_measure(s, val_str, uom_str, "DESIR STEER", + bb_rx, bb_ry, bb_uom_dx, + val_color, lab_color, uom_color, + value_fontSize, label_fontSize, uom_fontSize ); + bb_ry = bb_y + bb_h; + } + + + //finally draw the frame + bb_h += 20; + nvgBeginPath(s->vg); + nvgRoundedRect(s->vg, bb_x, bb_y, bb_w, bb_h, 20); + nvgStrokeColor(s->vg, nvgRGBA(255,255,255,80)); + nvgStrokeWidth(s->vg, 6); + nvgStroke(s->vg); +} + +//draw grid from wiki +static void ui_draw_vision_grid(UIState *s) +{ + const UIScene *scene = &s->scene; + bool is_cruise_set = (s->scene.v_cruise != 0 && s->scene.v_cruise != 255); + if (!is_cruise_set) + { + const int grid_spacing = 30; + + int ui_viz_rx = scene->ui_viz_rx; + int ui_viz_rw = scene->ui_viz_rw; + + nvgSave(s->vg); + + // path coords are worked out in rgb-box space + nvgTranslate(s->vg, 240.0f, 0.0); + + // zooom in 2x + nvgTranslate(s->vg, -1440.0f / 2, -1080.0f / 2); + nvgScale(s->vg, 2.0, 2.0); + + nvgScale(s->vg, 1440.0f / s->rgb_width, 1080.0f / s->rgb_height); + + nvgBeginPath(s->vg); + nvgStrokeColor(s->vg, nvgRGBA(255, 255, 255, 128)); + nvgStrokeWidth(s->vg, 1); + + for (int i = box_y; i < box_h; i += grid_spacing) + { + nvgMoveTo(s->vg, ui_viz_rx, i); + //nvgLineTo(s->vg, ui_viz_rx, i); + nvgLineTo(s->vg, ((ui_viz_rw + ui_viz_rx) / 2) + 10, i); + } + + for (int i = ui_viz_rx + 12; i <= ui_viz_rw; i += grid_spacing) + { + nvgMoveTo(s->vg, i, 0); + nvgLineTo(s->vg, i, 1000); + } + nvgStroke(s->vg); + nvgRestore(s->vg); + } +} + +static void ui_draw_button(NVGcontext *vg, int x, int y, int w, int h, const char *label, bool highlight) { + nvgBeginPath(vg); + nvgRoundedRect(vg, x, y, w, h, 20); + nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 80)); + nvgStrokeWidth(vg, 6); + nvgStroke(vg); + if(highlight) { + nvgFillColor(vg, nvgRGBA(128, 128, 128, 160)); + nvgFill(vg); + } + + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); + nvgFontFace(vg, "sans-semibold"); + nvgFontSize(vg, (strlen(label)>2?30:40) * 2.5); + nvgFillColor(vg, nvgRGBA(255, 255, 255, 200)); + nvgText(vg, x + w/2, y + (int)(40 * 2.5) + 5, label, NULL); +} +static void bb_ui_draw_UI(UIState *s) +{ + /* + //get 3-state switch position + int tri_state_fd; + int tri_state_switch; + char buffer[10]; + tri_state_switch = 0; + tri_state_fd = open("/sys/devices/virtual/switch/tri-state-key/state", O_RDONLY); + //if we can't open then switch should be considered in the middle, nothing done + if (tri_state_fd == -1) + { + tri_state_switch = 1; + } + else + { + read(tri_state_fd, &buffer, 10); + tri_state_switch = buffer[0] - 48; + close(tri_state_fd); } + s->ignoreLayout = (tri_state_switch==3); + if (tri_state_switch >= 2) + { + */ + const UIScene *scene = &s->scene; + const int bb_dml_w = 180; + const int bb_dml_x = (scene->ui_viz_rx + (bdr_is * 2)); + const int bb_dml_y = (box_y + (bdr_is * 1.5)) + 220; + + const int bb_dmr_w = 180; + const int bb_dmr_x = scene->ui_viz_rx + scene->ui_viz_rw - bb_dmr_w - (bdr_is * 2); + const int bb_dmr_y = (box_y + (bdr_is * 1.5)) + 220; + //bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; + + 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); + } +//BB END: functions added for the display of various items + static void ui_draw_vision_maxspeed(UIState *s) { /*if (!s->longitudinal_control){ return; @@ -1092,8 +1521,8 @@ static void ui_draw_vision_maxspeed(UIState *s) { int viz_maxspeed_w = 184; int viz_maxspeed_h = 202; - int viz_maxspeed_x = (ui_viz_rx + (bdr_s*2)); - int viz_maxspeed_y = (box_y + (bdr_s*1.5)); + int viz_maxspeed_x = (ui_viz_rx + (bdr_is*2)); + int viz_maxspeed_y = (box_y + (bdr_is*1.5)); int viz_maxspeed_xo = 180; #ifdef SHOW_SPEEDLIMIT @@ -1115,7 +1544,7 @@ static void ui_draw_vision_maxspeed(UIState *s) { // Draw Border nvgBeginPath(s->vg); - nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 20); + nvgRoundedRect(s->vg, viz_maxspeed_x, viz_maxspeed_y, viz_maxspeed_w, viz_maxspeed_h, 30); if (is_set_over_limit) { nvgStrokeColor(s->vg, nvgRGBA(218, 111, 37, 255)); } else if (is_speedlim_valid && !s->is_ego_over_limit) { @@ -1150,7 +1579,7 @@ static void ui_draw_vision_maxspeed(UIState *s) { nvgFontFace(s->vg, "sans-semibold"); nvgFontSize(s->vg, 42*2.5); nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 100)); - nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, "N/A", NULL); + nvgText(s->vg, viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, "-", NULL); } #ifdef DEBUG_TURN @@ -1164,6 +1593,9 @@ static void ui_draw_vision_maxspeed(UIState *s) { nvgText(s->vg, 200 + viz_maxspeed_x+(viz_maxspeed_xo/2)+(viz_maxspeed_w/2), 242, maxspeed_str, NULL); } #endif + //BB START: add new measures panel const int bb_dml_w = 180; + bb_ui_draw_UI(s); + //BB END: add new measures panel } static void ui_draw_vision_speedlimit(UIState *s) { @@ -1187,8 +1619,8 @@ static void ui_draw_vision_speedlimit(UIState *s) { int viz_speedlim_w = 180; int viz_speedlim_h = 202; - int viz_speedlim_x = (ui_viz_rx + (bdr_s*2)); - int viz_speedlim_y = (box_y + (bdr_s*1.5)); + int viz_speedlim_x = (ui_viz_rx + (bdr_is*2)); + int viz_speedlim_y = (box_y + (bdr_is*1.5)); if (!is_speedlim_valid) { viz_speedlim_w -= 5; viz_speedlim_h -= 10; @@ -1247,7 +1679,7 @@ static void ui_draw_vision_speedlimit(UIState *s) { } else { nvgFontFace(s->vg, "sans-semibold"); nvgFontSize(s->vg, 42*2.5); - nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), "N/A", NULL); + nvgText(s->vg, viz_speedlim_x+viz_speedlim_w/2, viz_speedlim_y + (is_speedlim_valid ? 170 : 165), "-", NULL); } } @@ -1261,8 +1693,33 @@ static void ui_draw_vision_speed(UIState *s) { const int viz_speed_x = ui_viz_rx+((ui_viz_rw/2)-(viz_speed_w/2)); char speed_str[32]; - nvgBeginPath(s->vg); - nvgRect(s->vg, viz_speed_x, box_y, viz_speed_w, header_h); + if(s->scene.leftBlinker) { + nvgBeginPath(s->vg); + nvgMoveTo(s->vg, viz_speed_x, box_y + header_h/4); + nvgLineTo(s->vg, viz_speed_x - viz_speed_w/2, box_y + header_h/4 + header_h/4); + nvgLineTo(s->vg, viz_speed_x, box_y + header_h/2 + header_h/4); + nvgClosePath(s->vg); + nvgFillColor(s->vg, nvgRGBA(23,134,68,s->scene.blinker_blinkingrate>=50?210:60)); + nvgFill(s->vg); + } + + if(s->scene.rightBlinker) { + nvgBeginPath(s->vg); + nvgMoveTo(s->vg, viz_speed_x+viz_speed_w, box_y + header_h/4); + nvgLineTo(s->vg, viz_speed_x+viz_speed_w + viz_speed_w/2, box_y + header_h/4 + header_h/4); + nvgLineTo(s->vg, viz_speed_x+viz_speed_w, box_y + header_h/2 + header_h/4); + nvgClosePath(s->vg); + nvgFillColor(s->vg, nvgRGBA(23,134,68,s->scene.blinker_blinkingrate>=50?210:60)); + nvgFill(s->vg); + } + + if(s->scene.leftBlinker || s->scene.rightBlinker) { + s->scene.blinker_blinkingrate -= 3; + if(s->scene.blinker_blinkingrate<0) s->scene.blinker_blinkingrate = 120; + } + + //nvgBeginPath(s->vg); + //nvgRect(s->vg, viz_speed_x, box_y, viz_speed_w, header_h); nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE); if (s->is_metric) { @@ -1291,14 +1748,14 @@ static void ui_draw_vision_event(UIState *s) { const int ui_viz_rx = scene->ui_viz_rx; const int ui_viz_rw = scene->ui_viz_rw; const int viz_event_w = 220; - const int viz_event_x = ((ui_viz_rx + ui_viz_rw) - (viz_event_w + (bdr_s*2))); - const int viz_event_y = (box_y + (bdr_s*1.5)); - const int viz_event_h = (header_h - (bdr_s*1.5)); + const int viz_event_x = ((ui_viz_rx + ui_viz_rw) - (viz_event_w + (bdr_is*2))); + const int viz_event_y = (box_y + (bdr_is*1.5)); + const int viz_event_h = (header_h - (bdr_is*1.5)); if (s->scene.decel_for_turn && s->scene.engaged && s->limit_set_speed) { // draw winding road sign const int img_turn_size = 160*1.5; const int img_turn_x = viz_event_x-(img_turn_size/4); - const int img_turn_y = viz_event_y+bdr_s-25; + const int img_turn_y = viz_event_y+bdr_is-25; float img_turn_alpha = 1.0f; nvgBeginPath(s->vg); NVGpaint imgPaint = nvgImagePattern(s->vg, img_turn_x, img_turn_y, @@ -1315,12 +1772,12 @@ static void ui_draw_vision_event(UIState *s) { const int img_wheel_x = bg_wheel_x-(img_wheel_size/2); const int img_wheel_y = bg_wheel_y-25; float img_wheel_alpha = 0.1f; - bool is_engaged = (s->status == STATUS_ENGAGED); + bool is_engaged = (s->status == STATUS_ENGAGED) && !scene->steerOverride; bool is_warning = (s->status == STATUS_WARNING); bool is_engageable = scene->engageable; if (is_engaged || is_warning || is_engageable) { nvgBeginPath(s->vg); - nvgCircle(s->vg, bg_wheel_x, (bg_wheel_y + (bdr_s*1.5)), bg_wheel_size); + nvgCircle(s->vg, bg_wheel_x, (bg_wheel_y + (bdr_is*1.5)), bg_wheel_size); if (is_engaged) { nvgFillColor(s->vg, nvgRGBA(23, 134, 68, 255)); } else if (is_warning) { @@ -1343,7 +1800,7 @@ static void ui_draw_vision_event(UIState *s) { static void ui_draw_vision_map(UIState *s) { const UIScene *scene = &s->scene; const int map_size = 96; - const int map_x = (scene->ui_viz_rx + (map_size * 3) + (bdr_s * 3)); + const int map_x = (scene->ui_viz_rx + (map_size * 3) + (bdr_is * 3)); const int map_y = (footer_y + ((footer_h - map_size) / 2)); const int map_img_size = (map_size * 1.5); const int map_img_x = (map_x - (map_img_size / 2)); @@ -1357,7 +1814,7 @@ static void ui_draw_vision_map(UIState *s) { map_img_size, map_img_size, 0, s->img_map, map_img_alpha); nvgBeginPath(s->vg); - nvgCircle(s->vg, map_x, (map_y + (bdr_s * 1.5)), map_size); + nvgCircle(s->vg, map_x, (map_y + (bdr_is * 1.5)), map_size); nvgFillColor(s->vg, map_bg); nvgFill(s->vg); @@ -1370,7 +1827,7 @@ static void ui_draw_vision_map(UIState *s) { static void ui_draw_vision_face(UIState *s) { const UIScene *scene = &s->scene; const int face_size = 96; - const int face_x = (scene->ui_viz_rx + face_size + (bdr_s * 2)); + const int face_x = (scene->ui_viz_rx + face_size + (bdr_is * 2)); const int face_y = (footer_y + ((footer_h - face_size) / 2)); const int face_img_size = (face_size * 1.5); const int face_img_x = (face_x - (face_img_size / 2)); @@ -1382,7 +1839,7 @@ static void ui_draw_vision_face(UIState *s) { face_img_size, face_img_size, 0, s->img_face, face_img_alpha); nvgBeginPath(s->vg); - nvgCircle(s->vg, face_x, (face_y + (bdr_s * 1.5)), face_size); + nvgCircle(s->vg, face_x, (face_y + (bdr_is * 1.5)), face_size); nvgFillColor(s->vg, face_bg); nvgFill(s->vg); @@ -1392,6 +1849,33 @@ static void ui_draw_vision_face(UIState *s) { nvgFill(s->vg); } +static void ui_draw_vision_brake(UIState *s) { + const UIScene *scene = &s->scene; + const int brake_size = 96; + const int brake_x = (scene->ui_viz_rx + (brake_size * 5) + (bdr_is * 4)); + const int brake_y = (footer_y + ((footer_h - brake_size) / 2)); + const int brake_img_size = (brake_size * 1.5); + const int brake_img_x = (brake_x - (brake_img_size / 2)); + const int brake_img_y = (brake_y - (brake_size / 4)); + + bool brake_valid = scene->brakeLights; + float brake_img_alpha = brake_valid ? 1.0f : 0.15f; + float brake_bg_alpha = brake_valid ? 0.3f : 0.1f; + NVGcolor brake_bg = nvgRGBA(0, 0, 0, (255 * brake_bg_alpha)); + NVGpaint brake_img = nvgImagePattern(s->vg, brake_img_x, brake_img_y, + brake_img_size, brake_img_size, 0, s->img_brake, brake_img_alpha); + + nvgBeginPath(s->vg); + nvgCircle(s->vg, brake_x, (brake_y + (bdr_is * 1.5)), brake_size); + nvgFillColor(s->vg, brake_bg); + nvgFill(s->vg); + + nvgBeginPath(s->vg); + nvgRect(s->vg, brake_img_x, brake_img_y, brake_img_size, brake_img_size); + nvgFillPaint(s->vg, brake_img); + nvgFill(s->vg); +} + static void ui_draw_vision_header(UIState *s) { const UIScene *scene = &s->scene; int ui_viz_rx = scene->ui_viz_rx; @@ -1406,6 +1890,7 @@ static void ui_draw_vision_header(UIState *s) { nvgRect(s->vg, ui_viz_rx, box_y, ui_viz_rw, header_h); nvgFill(s->vg); + //bool hasSidebar = !s->scene.uilayout_sidebarcollapsed; ui_draw_vision_maxspeed(s); #ifdef SHOW_SPEEDLIMIT @@ -1424,6 +1909,7 @@ static void ui_draw_vision_footer(UIState *s) { nvgRect(s->vg, ui_viz_rx, footer_y, ui_viz_rw, footer_h); ui_draw_vision_face(s); + ui_draw_vision_brake(s); #ifdef SHOW_SPEEDLIMIT ui_draw_vision_map(s); @@ -1441,9 +1927,9 @@ static void ui_draw_vision_alert(UIState *s, int va_size, int va_color, const uint8_t *color = alert_colors[va_color]; const int alr_s = alert_sizes[va_size]; - const int alr_x = ui_viz_rx-(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)-bdr_s; - const int alr_w = ui_viz_rw+(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)+(bdr_s*2); - const int alr_h = alr_s+(va_size==ALERTSIZE_NONE?0:bdr_s); + const int alr_x = ui_viz_rx-(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)-bdr_is; + const int alr_w = ui_viz_rw+(mapEnabled?(hasSidebar?nav_w:(nav_ww)):0)+(bdr_is*2); + const int alr_h = alr_s+(va_size==ALERTSIZE_NONE?0:bdr_is); const int alr_y = vwp_h-alr_h; nvgBeginPath(s->vg); @@ -1538,6 +2024,18 @@ static void ui_draw_vision(UIState *s) { static void ui_draw_blank(UIState *s) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + // draw IP address + nvgBeginPath(s->vg); + nvgTextAlign(s->vg, NVG_ALIGN_CENTER| NVG_ALIGN_TOP); + nvgFontFace(s->vg, "sans-semibold"); + nvgFontSize(s->vg, 15 * 2.5); + nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 200)); + nvgText(s->vg, 150, 292, ds.ipAddress, NULL); + if(ds.tx_throughput>0) { + char str[64]; + sprintf(str, "%d KB/s", ds.tx_throughput); + nvgText(s->vg, 150, 217, str, NULL); + } } static void ui_draw(UIState *s) { @@ -1557,6 +2055,7 @@ static void ui_draw(UIState *s) { nvgEndFrame(s->vg); glDisable(GL_BLEND); } + assert(glGetError() == GL_NO_ERROR); } static PathData read_path(cereal_ModelData_PathData_ptr pathp) { @@ -1635,6 +2134,9 @@ void handle_message(UIState *s, void *which) { } s->scene.v_cruise = datad.vCruise; s->scene.v_ego = datad.vEgo; + s->scene.angleSteers = datad.angleSteers; + s->scene.angleSteersDes = datad.angleSteersDes; + s->scene.steerOverride = datad.steerOverride; s->scene.curvature = datad.curvature; s->scene.engaged = datad.enabled; s->scene.engageable = datad.engageable; @@ -1791,6 +2293,23 @@ void handle_message(UIState *s, void *which) { } s->scene.started_ts = datad.startedTs; + //BBB CPU TEMP + s->scene.maxCpuTemp = datad.cpu0; + if (s->scene.maxCpuTemp < datad.cpu1) + { + s->scene.maxCpuTemp = datad.cpu1; + } + else if (s->scene.maxCpuTemp < datad.cpu2) + { + s->scene.maxCpuTemp = datad.cpu2; + } + else if (s->scene.maxCpuTemp < datad.cpu3) + { + s->scene.maxCpuTemp = datad.cpu3; + } + s->scene.maxBatTemp = datad.bat; + s->scene.freeSpace = datad.freeSpace; + //BBB END CPU TEMP } else if (eventd.which == cereal_Event_uiLayoutState) { struct cereal_UiLayoutState datad; cereal_read_UiLayoutState(&datad, eventd.uiLayoutState); @@ -1814,6 +2333,14 @@ void handle_message(UIState *s, void *which) { s->scene.speedlimit = datad.speedLimit; s->scene.speedlimit_valid = datad.speedLimitValid; s->scene.map_valid = datad.mapValid; + } else if (eventd.which == cereal_Event_carState) { + struct cereal_CarState datad; + cereal_read_CarState(&datad, eventd.carState); + s->scene.brakeLights = datad.brakeLights; + if(s->scene.leftBlinker!=datad.leftBlinker || s->scene.rightBlinker!=datad.rightBlinker) + s->scene.blinker_blinkingrate = 100; + s->scene.leftBlinker = datad.leftBlinker; + s->scene.rightBlinker = datad.rightBlinker; } capn_free(&ctx); zmq_msg_close(&msg); @@ -1823,6 +2350,9 @@ static void ui_update(UIState *s) { int err; if (s->vision_connect_firstrun) { + s->carstate_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8021"); + assert(s->carstate_sock_raw); + s->lastdriveEnd = 0; // cant run this in connector thread because opengl. // do this here for now in lieu of a run_on_main_thread event @@ -1883,8 +2413,8 @@ static void ui_update(UIState *s) { assert(glGetError() == GL_NO_ERROR); // Default UI Measurements (Assumes sidebar collapsed) - s->scene.ui_viz_rx = (box_x-sbr_w+bdr_s*2); - s->scene.ui_viz_rw = (box_w+sbr_w-(bdr_s*2)); + s->scene.ui_viz_rx = (box_x-sbr_w+bdr_is*2); + s->scene.ui_viz_rw = (box_w+sbr_w-(bdr_is*2)); s->scene.ui_viz_ro = 0; s->vision_connect_firstrun = false; @@ -1893,7 +2423,7 @@ static void ui_update(UIState *s) { s->alert_blinked = false; } - zmq_pollitem_t polls[9] = {{0}}; + zmq_pollitem_t polls[13] = {{0}}; // Wait for next rgb image from visiond while(true) { assert(s->ipc_fd >= 0); @@ -1979,6 +2509,17 @@ static void ui_update(UIState *s) { polls[7].events = ZMQ_POLLIN; #endif + if (s->vision_connected) { + num_polls++; + plus_sock_num++; + polls[8].socket = s->carstate_sock_raw; + polls[8].events = ZMQ_POLLIN; + num_polls++; + plus_sock_num++; + polls[9].socket = s->gps_sock_raw; + polls[9].events = ZMQ_POLLIN; + } + polls[plus_sock_num].socket = s->plus_sock_raw; // plus_sock should be last polls[plus_sock_num].events = ZMQ_POLLIN; @@ -1993,11 +2534,44 @@ static void ui_update(UIState *s) { if (polls[0].revents || polls[1].revents || polls[2].revents || polls[3].revents || polls[4].revents || polls[6].revents || - polls[plus_sock_num].revents) { + polls[7].revents || polls[plus_sock_num].revents) { // awake on any (old) activity set_awake(s, true); } + if (polls[9].revents) { + // gps socket + + zmq_msg_t msg; + err = zmq_msg_init(&msg); + assert(err == 0); + err = zmq_msg_recv(&msg, s->gps_sock_raw, 0); + assert(err >= 0); + + struct capn ctx; + capn_init_mem(&ctx, zmq_msg_data(&msg), zmq_msg_size(&msg), 0); + + cereal_Event_ptr eventp; + eventp.p = capn_getp(capn_root(&ctx), 0, 1); + struct cereal_Event eventd; + cereal_read_Event(&eventd, eventp); + + struct cereal_GpsLocationData datad; + cereal_read_GpsLocationData(&datad, eventd.gpsLocation); + + s->scene.gpsAccuracy = datad.accuracy; + if (s->scene.gpsAccuracy > 100) + { + s->scene.gpsAccuracy = 99.99; + } + else if (s->scene.gpsAccuracy == 0) + { + s->scene.gpsAccuracy = 99.8; + } + capn_free(&ctx); + zmq_msg_close(&msg); + } + if (polls[plus_sock_num].revents) { // plus socket zmq_msg_t msg; @@ -2208,6 +2782,17 @@ int main(int argc, char* argv[]) { UIState uistate; UIState *s = &uistate; ui_init(s); + ds_init(); + s->scene = (UIScene){ + .frontview = getenv("FRONTVIEW") != NULL, + .fullview = getenv("FULLVIEW") != NULL, + .world_objects_visible = true, // Invisible until we receive a calibration message. + .gps_planner_active = true, + .ui_viz_rx = (box_x - sbr_w + bdr_is * 2), + .ui_viz_rw = (box_w + sbr_w - (bdr_is * 2)), + .ui_viz_ro = 0, + .spammedButton = -1, + }; pthread_t connect_thread_handle; err = pthread_create(&connect_thread_handle, NULL, @@ -2284,21 +2869,50 @@ int main(int argc, char* argv[]) { } else { // Car started, fetch a new rgb image from ipc and peek for zmq events. ui_update(s); - if(!s->vision_connected) { - // Visiond process is just stopped, force a redraw to make screen blank again. - ui_draw(s); - glFinish(); - should_swap = true; + ds_update(s->awake && (!s->vision_connected || s->plus_state != 0), s->awake); + } + if (s->awake) { + ds_update(s->awake, s->awake); + } + + // wake up on button press while not driving + if(ds.statePwr && (!s->vision_connected || s->plus_state != 0)) + set_awake(s, !s->awake); + if(ds.stateVol && (!s->vision_connected || s->plus_state != 0) && !s->awake) + set_awake(s, true); + + // awake on any touch + int touch_x = -1, touch_y = -1; + int touched = touch_poll(&touch, &touch_x, &touch_y, s->awake ? 0 : 100); + if (touched == 1) { + // touch event will still happen :( + set_awake(s, true); + + if(touch_x>=vwp_w-100 && touch_y>=vwp_h-100 && s->touchTimeout==0) { + s->touchTimeout = 30; + } else if(touch_x>=vwp_w-100 && touch_y<=100 && s->touchTimeout==0) { + s->touchTimeout = 30; } } + if(s->touchTimeout>0) + s->touchTimeout--; + + if(!s->vision_connected) { + // Visiond process is just stopped, force a redraw to make screen blank again. + ui_draw(s); + glFinish(); + should_swap = true; + } + // manage wakefulness if (s->awake_timeout > 0) { s->awake_timeout--; - } else { + } else if(!ds.logOn) { set_awake(s, false); } // Don't waste resources on drawing in case screen is off or car is not started. if (s->awake && s->vision_connected) { + dashcam(s, touch_x, touch_y); ui_draw(s); glFinish(); should_swap = true; @@ -2313,7 +2927,11 @@ int main(int argc, char* argv[]) { } #endif } - + if(s->scene.spammedButton!=-1) { + s->scene.spammedButtonTimeout--; + if(s->scene.spammedButtonTimeout<=0) + s->scene.spammedButton=-1; + } if (s->volume_timeout > 0) { s->volume_timeout--; } else {