offroad/ui: Transparent layout mode and msgq-based layout control (#1337)

* offroadLayout

* replace broadcasts with offroadLayout socket

* apk

* set 'none' layoutstate for transparent offroad

* refactor, hide offroad when vision connected

* apk supporting transparency

* reset layout state when stopping

* apk

* cleanup includes

* permit offroad to mangae sidebar state only when vision disconnected

* apk

* use c-capnp

* always upd

* send that too

* sync layout state with offroad

* apk

* fix regression in onboarding (mock engage green border)

* apk

* bump apks

* simplify event processing

* bump cereal to master

* in case ui exited in a bad state

Co-authored-by: Comma Device <device@comma.ai>
pull/1347/head
Andy 5 years ago committed by GitHub
parent 1ac5c48e5d
commit 35b34fb700
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      apk/ai.comma.plus.offroad.apk
  2. 2
      apks
  3. 2
      selfdrive/ui/paint.cc
  4. 76
      selfdrive/ui/ui.cc
  5. 4
      selfdrive/ui/ui.hpp

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:deb70c5a5b284e73d4960b60ac7a6dcc1263597762554749adf675c23efc383e oid sha256:9b19831e278e17ccecd1af02d8cab1f523dc5d4bb5056c5c7aa1c05d9157f515
size 13688133 size 13691048

@ -1 +1 @@
Subproject commit d94f8663913f12142754b2501b174c8bcd5996ce Subproject commit 25e8e25624365d244a1aa70e6b96a09db514242d

@ -890,7 +890,7 @@ void ui_draw(UIState *s) {
#else #else
ui_draw_background(s); ui_draw_background(s);
#endif #endif
if (s->vision_connected && s->active_app == cereal_UiLayoutState_App_home && s->status != STATUS_STOPPED) { if (s->vision_connected && s->active_app == cereal_UiLayoutState_App_none && s->status != STATUS_STOPPED) {
ui_draw_sidebar(s); ui_draw_sidebar(s);
ui_draw_vision(s); ui_draw_vision(s);
} else { } else {

@ -30,6 +30,17 @@ static void set_brightness(UIState *s, int brightness) {
} }
} }
int event_processing_enabled = -1;
static void enable_event_processing(bool yes) {
if (event_processing_enabled != 1 && yes) {
system("service call window 18 i32 1"); // enable event processing
event_processing_enabled = 1;
} else if (event_processing_enabled != 0 && !yes) {
system("service call window 18 i32 0"); // disable event processing
event_processing_enabled = 0;
}
}
static void set_awake(UIState *s, bool awake) { static void set_awake(UIState *s, bool awake) {
#ifdef QCOM #ifdef QCOM
if (awake) { if (awake) {
@ -43,10 +54,12 @@ static void set_awake(UIState *s, bool awake) {
if (awake) { if (awake) {
LOGW("awake normal"); LOGW("awake normal");
framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL);
enable_event_processing(true);
} else { } else {
LOGW("awake off"); LOGW("awake off");
set_brightness(s, 0); set_brightness(s, 0);
framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF); framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF);
enable_event_processing(false);
} }
} }
#else #else
@ -55,21 +68,36 @@ static void set_awake(UIState *s, bool awake) {
#endif #endif
} }
int event_processing_enabled = -1; static void update_offroad_layout_state(UIState *s) {
static void enable_event_processing(bool yes) { struct capn rc;
if (event_processing_enabled != 1 && yes) { capn_init_malloc(&rc);
system("service call window 18 i32 1"); // enable event processing struct capn_segment *cs = capn_root(&rc).seg;
event_processing_enabled = 1;
} else if (event_processing_enabled != 0 && !yes) { cereal_UiLayoutState_ptr layoutp = cereal_new_UiLayoutState(cs);
system("service call window 18 i32 0"); // disable event processing struct cereal_UiLayoutState layoutd = {
event_processing_enabled = 0; .activeApp = (cereal_UiLayoutState_App)s->active_app,
} .sidebarCollapsed = s->scene.uilayout_sidebarcollapsed,
};
cereal_write_UiLayoutState(&layoutd, layoutp);
cereal_Event_ptr eventp = cereal_new_Event(cs);
struct cereal_Event event = {
.logMonoTime = nanos_since_boot(),
.which = cereal_Event_uiLayoutState,
.uiLayoutState = layoutp,
};
cereal_write_Event(&event, eventp);
capn_setp(capn_root(&rc), 0, eventp.p);
uint8_t buf[4096];
ssize_t rs = capn_write_mem(&rc, buf, sizeof(buf), 0);
s->offroad_sock->send((char*)buf, rs);
capn_free(&rc);
} }
static void navigate_to_settings(UIState *s) { static void navigate_to_settings(UIState *s) {
#ifdef QCOM #ifdef QCOM
enable_event_processing(true); s->active_app = cereal_UiLayoutState_App_settings;
system("am broadcast -a 'ai.comma.plus.SidebarSettingsTouchUpInside'"); update_offroad_layout_state(s);
#else #else
// computer UI doesn't have offroad settings // computer UI doesn't have offroad settings
#endif #endif
@ -78,9 +106,11 @@ static void navigate_to_settings(UIState *s) {
static void navigate_to_home(UIState *s) { static void navigate_to_home(UIState *s) {
#ifdef QCOM #ifdef QCOM
if (s->vision_connected) { if (s->vision_connected) {
enable_event_processing(false); s->active_app = cereal_UiLayoutState_App_none;
} else {
s->active_app = cereal_UiLayoutState_App_home;
} }
system("am broadcast -a 'ai.comma.plus.HomeButtonTouchUpInside'"); update_offroad_layout_state(s);
#else #else
// computer UI doesn't have offroad home // computer UI doesn't have offroad home
#endif #endif
@ -97,6 +127,7 @@ static void handle_sidebar_touch(UIState *s, int touch_x, int touch_y) {
navigate_to_home(s); navigate_to_home(s);
if (s->vision_connected) { if (s->vision_connected) {
s->scene.uilayout_sidebarcollapsed = true; s->scene.uilayout_sidebarcollapsed = true;
update_offroad_layout_state(s);
} }
} }
} }
@ -106,6 +137,7 @@ static void handle_vision_touch(UIState *s, int touch_x, int touch_y) {
if (s->vision_connected && (touch_x >= s->scene.ui_viz_rx - bdr_s) if (s->vision_connected && (touch_x >= s->scene.ui_viz_rx - bdr_s)
&& (s->active_app != cereal_UiLayoutState_App_settings)) { && (s->active_app != cereal_UiLayoutState_App_settings)) {
s->scene.uilayout_sidebarcollapsed = !s->scene.uilayout_sidebarcollapsed; s->scene.uilayout_sidebarcollapsed = !s->scene.uilayout_sidebarcollapsed;
update_offroad_layout_state(s);
} }
} }
@ -185,6 +217,7 @@ static void ui_init(UIState *s) {
s->thermal_sock = SubSocket::create(s->ctx, "thermal"); s->thermal_sock = SubSocket::create(s->ctx, "thermal");
s->health_sock = SubSocket::create(s->ctx, "health"); s->health_sock = SubSocket::create(s->ctx, "health");
s->ubloxgnss_sock = SubSocket::create(s->ctx, "ubloxGnss"); s->ubloxgnss_sock = SubSocket::create(s->ctx, "ubloxGnss");
s->offroad_sock = PubSocket::create(s->ctx, "offroadLayout");
assert(s->model_sock != NULL); assert(s->model_sock != NULL);
assert(s->controlsstate_sock != NULL); assert(s->controlsstate_sock != NULL);
@ -194,6 +227,7 @@ static void ui_init(UIState *s) {
assert(s->thermal_sock != NULL); assert(s->thermal_sock != NULL);
assert(s->health_sock != NULL); assert(s->health_sock != NULL);
assert(s->ubloxgnss_sock != NULL); assert(s->ubloxgnss_sock != NULL);
assert(s->offroad_sock != NULL);
s->poller = Poller::create({ s->poller = Poller::create({
s->model_sock, s->model_sock,
@ -485,6 +519,10 @@ void handle_message(UIState *s, Message * msg) {
cereal_read_UiLayoutState(&datad, eventd.uiLayoutState); cereal_read_UiLayoutState(&datad, eventd.uiLayoutState);
s->active_app = datad.activeApp; s->active_app = datad.activeApp;
s->scene.uilayout_sidebarcollapsed = datad.sidebarCollapsed; s->scene.uilayout_sidebarcollapsed = datad.sidebarCollapsed;
if (datad.mockEngaged != s->scene.uilayout_mockengaged) {
s->scene.uilayout_mockengaged = datad.mockEngaged;
pthread_cond_signal(&s->bg_cond);
}
} else if (eventd.which == cereal_Event_liveMapData) { } else if (eventd.which == cereal_Event_liveMapData) {
struct cereal_LiveMapData datad; struct cereal_LiveMapData datad;
cereal_read_LiveMapData(&datad, eventd.liveMapData); cereal_read_LiveMapData(&datad, eventd.liveMapData);
@ -606,6 +644,7 @@ static void ui_update(UIState *s) {
assert(glGetError() == GL_NO_ERROR); assert(glGetError() == GL_NO_ERROR);
s->scene.uilayout_sidebarcollapsed = true; s->scene.uilayout_sidebarcollapsed = true;
update_offroad_layout_state(s);
s->scene.ui_viz_rx = (box_x-sbr_w+bdr_s*2); 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_rw = (box_w+sbr_w-(bdr_s*2));
s->scene.ui_viz_ro = 0; s->scene.ui_viz_ro = 0;
@ -755,7 +794,6 @@ static void* vision_connect_thread(void *args) {
s->vision_connected = true; s->vision_connected = true;
s->vision_connect_firstrun = true; s->vision_connect_firstrun = true;
enable_event_processing(false);
// Drain sockets // Drain sockets
while (true){ while (true){
@ -847,6 +885,9 @@ static void* bg_thread(void* args) {
assert(bg_status < ARRAYSIZE(bg_colors)); assert(bg_status < ARRAYSIZE(bg_colors));
const uint8_t *color = bg_colors[bg_status]; const uint8_t *color = bg_colors[bg_status];
if (s->scene.uilayout_mockengaged) {
color = bg_colors[STATUS_ENGAGED];
}
glClearColor(color[0]/256.0, color[1]/256.0, color[2]/256.0, 0.0); glClearColor(color[0]/256.0, color[1]/256.0, color[2]/256.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -887,6 +928,7 @@ int main(int argc, char* argv[]) {
UIState uistate; UIState uistate;
UIState *s = &uistate; UIState *s = &uistate;
ui_init(s); ui_init(s);
enable_event_processing(true);
pthread_t connect_thread_handle; pthread_t connect_thread_handle;
err = pthread_create(&connect_thread_handle, NULL, err = pthread_create(&connect_thread_handle, NULL,
@ -961,15 +1003,18 @@ int main(int argc, char* argv[]) {
if (!s->vision_connected) { if (!s->vision_connected) {
// always process events offroad // always process events offroad
enable_event_processing(true);
if (s->status != STATUS_STOPPED) { if (s->status != STATUS_STOPPED) {
update_status(s, STATUS_STOPPED); update_status(s, STATUS_STOPPED);
s->active_app = cereal_UiLayoutState_App_home;
update_offroad_layout_state(s);
} }
check_messages(s); check_messages(s);
} else { } else {
set_awake(s, true); set_awake(s, true);
if (s->status == STATUS_STOPPED) { if (s->status == STATUS_STOPPED) {
update_status(s, STATUS_DISENGAGED); update_status(s, STATUS_DISENGAGED);
s->active_app = cereal_UiLayoutState_App_none;
update_offroad_layout_state(s);
} }
// Car started, fetch a new rgb image from ipc and peek for zmq events. // Car started, fetch a new rgb image from ipc and peek for zmq events.
ui_update(s); ui_update(s);
@ -977,6 +1022,7 @@ int main(int argc, char* argv[]) {
// Visiond process is just stopped, force a redraw to make screen blank again. // Visiond process is just stopped, force a redraw to make screen blank again.
s->scene.satelliteCount = -1; s->scene.satelliteCount = -1;
s->scene.uilayout_sidebarcollapsed = false; s->scene.uilayout_sidebarcollapsed = false;
update_offroad_layout_state(s);
ui_draw(s); ui_draw(s);
glFinish(); glFinish();
should_swap = true; should_swap = true;

@ -12,6 +12,7 @@
#define nvgCreate nvgCreateGLES3 #define nvgCreate nvgCreateGLES3
#endif #endif
#include <capnp/serialize.h>
#include <pthread.h> #include <pthread.h>
#include "nanovg.h" #include "nanovg.h"
@ -22,7 +23,6 @@
#include "common/framebuffer.h" #include "common/framebuffer.h"
#include "common/modeldata.h" #include "common/modeldata.h"
#include "messaging.hpp" #include "messaging.hpp"
#include "cereal/gen/c/log.capnp.h" #include "cereal/gen/c/log.capnp.h"
#include "sound.hpp" #include "sound.hpp"
@ -128,6 +128,7 @@ typedef struct UIScene {
bool uilayout_sidebarcollapsed; bool uilayout_sidebarcollapsed;
bool uilayout_mapenabled; bool uilayout_mapenabled;
bool uilayout_mockengaged;
// responsive layout // responsive layout
int ui_viz_rx; int ui_viz_rx;
int ui_viz_rw; int ui_viz_rw;
@ -216,6 +217,7 @@ typedef struct UIState {
SubSocket *thermal_sock; SubSocket *thermal_sock;
SubSocket *health_sock; SubSocket *health_sock;
SubSocket *ubloxgnss_sock; SubSocket *ubloxgnss_sock;
PubSocket *offroad_sock;
Poller * poller; Poller * poller;
Poller * ublox_poller; Poller * ublox_poller;

Loading…
Cancel
Save