diff --git a/selfdrive/manager.py b/selfdrive/manager.py index 93b7b697f1..5e3e2e820f 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -224,6 +224,7 @@ if not PC: 'updated', 'logcatd', 'tombstoned', + 'sensord', ] car_started_processes = [ @@ -254,7 +255,6 @@ if WEBCAM: if not PC: car_started_processes += [ 'ubloxd', - 'sensord', 'dmonitoringd', 'dmonitoringmodeld', ] diff --git a/selfdrive/sensord/sensors_qcom.cc b/selfdrive/sensord/sensors_qcom.cc index 4119d8ede6..389014f2e5 100644 --- a/selfdrive/sensord/sensors_qcom.cc +++ b/selfdrive/sensord/sensors_qcom.cc @@ -48,7 +48,12 @@ void sigpipe_handler(int sig) { void sensor_loop() { LOG("*** sensor loop"); + + uint64_t frame = 0; + bool low_power_mode = false; + while (!do_exit) { + SubMaster sm({"thermal"}); PubMaster pm({"sensorEvents"}); struct sensors_poll_device_t* device; @@ -90,6 +95,13 @@ void sensor_loop() { {SENSOR_LIGHT, ms2ns(100)} }; + // sensors needed while offroad + std::set offroad_sensors = { + SENSOR_LIGHT, + SENSOR_ACCELEROMETER, + }; + + // init all the sensors for (auto &s : sensors) { device->activate(device, s.first, 0); device->activate(device, s.first, 1); @@ -189,6 +201,22 @@ void sensor_loop() { re_init_sensors = false; break; } + + // Check whether to go into low power mode at 5Hz + if (frame % 20 == 0 && sm.update(0) > 0) { + bool offroad = !sm["thermal"].getThermal().getStarted(); + if (low_power_mode != offroad) { + for (auto &s : sensors) { + device->activate(device, s.first, 0); + if (!offroad || offroad_sensors.find(s.first) != offroad_sensors.end()) { + device->activate(device, s.first, 1); + } + } + low_power_mode = offroad; + } + } + + frame++; } sensors_close(device); } diff --git a/selfdrive/ui/android/ui.cc b/selfdrive/ui/android/ui.cc index e64ab6cded..20640068ee 100644 --- a/selfdrive/ui/android/ui.cc +++ b/selfdrive/ui/android/ui.cc @@ -3,6 +3,8 @@ #include #include +#include + #include "common/util.h" #include "common/utilpp.h" #include "common/params.h" @@ -13,65 +15,11 @@ #include "paint.hpp" #include "android/sl_sound.hpp" -// Includes for light sensor -#include -#include -#include - volatile sig_atomic_t do_exit = 0; static void set_do_exit(int sig) { do_exit = 1; } - -static void* light_sensor_thread(void *args) { - set_thread_name("light_sensor"); - - int err; - UIState *s = (UIState*)args; - s->light_sensor = 0.0; - - struct sensors_poll_device_t* device; - struct sensors_module_t* module; - - hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&module); - sensors_open(&module->common, &device); - - // need to do this - struct sensor_t const* list; - module->get_sensors_list(module, &list); - - int SENSOR_LIGHT = 7; - - err = device->activate(device, SENSOR_LIGHT, 0); - if (err != 0) goto fail; - err = device->activate(device, SENSOR_LIGHT, 1); - if (err != 0) goto fail; - - device->setDelay(device, SENSOR_LIGHT, ms2ns(100)); - - while (!do_exit) { - static const size_t numEvents = 1; - sensors_event_t buffer[numEvents]; - - int n = device->poll(device, buffer, numEvents); - if (n < 0) { - LOG_100("light_sensor_poll failed: %d", n); - } - if (n > 0) { - s->light_sensor = buffer[0].light; - } - } - sensors_close(device); - return NULL; - -fail: - LOGE("LIGHT SENSOR IS MISSING"); - s->light_sensor = 255; - - return NULL; -} - static void ui_set_brightness(UIState *s, int brightness) { static int last_brightness = -1; if (last_brightness != brightness && (s->awake || brightness == 0)) { @@ -92,24 +40,35 @@ static void enable_event_processing(bool yes) { } } -static void set_awake(UIState *s, bool awake) { - if (awake) { - // 30 second timeout - s->awake_timeout = 30*UI_FREQ; +// TODO: implement double tap to wake and actually turn display off +static void handle_display_state(UIState *s, bool user_input) { + + static int display_mode = HWC_POWER_MODE_OFF; + static int display_timeout = 0; + + // determine desired state + int desired_mode = display_mode; + if (user_input || s->ignition || s->started) { + desired_mode = HWC_POWER_MODE_NORMAL; + display_timeout = 30*UI_FREQ; + } else { + display_timeout = std::max(display_timeout-1, 0); + if (display_timeout == 0) { + desired_mode = HWC_POWER_MODE_OFF; + } } - if (s->awake != awake) { - s->awake = awake; - - // TODO: replace command_awake and command_sleep with direct calls to android - if (awake) { - LOGW("awake normal"); - framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); - enable_event_processing(true); - } else { - LOGW("awake off"); + + // handle state transition + if (display_mode != desired_mode) { + LOGW("setting display mode %d", desired_mode); + + display_mode = desired_mode; + s->awake = display_mode == HWC_POWER_MODE_NORMAL; + framebuffer_set_power(s->fb, display_mode); + enable_event_processing(s->awake); + + if (!s->awake) { ui_set_brightness(s, 0); - framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF); - enable_event_processing(false); } } } @@ -161,9 +120,7 @@ static void update_offroad_layout_state(UIState *s, PubMaster *pm) { } int main(int argc, char* argv[]) { - int err; setpriority(PRIO_PROCESS, 0, -14); - signal(SIGINT, (sighandler_t)set_do_exit); SLSound sound; @@ -172,14 +129,10 @@ int main(int argc, char* argv[]) { ui_init(s); s->sound = &sound; - set_awake(s, true); + handle_display_state(s, true); enable_event_processing(true); PubMaster *pm = new PubMaster({"offroadLayout"}); - pthread_t light_sensor_thread_handle; - err = pthread_create(&light_sensor_thread_handle, NULL, - light_sensor_thread, s); - assert(err == 0); TouchState touch = {0}; touch_init(&touch); @@ -215,23 +168,12 @@ int main(int argc, char* argv[]) { int touch_x = -1, touch_y = -1; int touched = touch_poll(&touch, &touch_x, &touch_y, 0); if (touched == 1) { - set_awake(s, true); handle_sidebar_touch(s, touch_x, touch_y); handle_vision_touch(s, touch_x, touch_y); } - // manage wakefulness - if (s->started || s->ignition) { - set_awake(s, true); - } - - if (s->awake_timeout > 0) { - s->awake_timeout--; - } else { - set_awake(s, false); - } - // Don't waste resources on drawing in case screen is off + handle_display_state(s, touched == 1); if (!s->awake) { continue; } @@ -255,10 +197,7 @@ int main(int argc, char* argv[]) { framebuffer_swap(s->fb); } - set_awake(s, true); - - err = pthread_join(light_sensor_thread_handle, NULL); - assert(err == 0); + handle_display_state(s, true); delete s->sm; delete pm; return 0; diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 8ca5d0170c..1715b7faf5 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -217,8 +217,6 @@ void update_sockets(UIState *s) { } else if ((sm.frame - sm.rcv_frame("dMonitoringState")) > UI_FREQ/2) { scene.frontview = false; } - -#ifdef QCOM2 // TODO: use this for QCOM too if (sm.updated("sensorEvents")) { for (auto sensor : sm["sensorEvents"].getSensorEvents()) { if (sensor.which() == cereal::SensorEventData::LIGHT) { @@ -226,7 +224,6 @@ void update_sockets(UIState *s) { } } } -#endif s->started = scene.thermal.getStarted() || scene.frontview; } diff --git a/selfdrive/ui/ui.hpp b/selfdrive/ui/ui.hpp index 1255e54b7a..a9016dd61e 100644 --- a/selfdrive/ui/ui.hpp +++ b/selfdrive/ui/ui.hpp @@ -183,8 +183,7 @@ typedef struct UIState { // device state bool awake; - int awake_timeout; - std::atomic light_sensor; + float light_sensor; bool started; bool ignition;