UI: refactor light sensor (#2129)

* refactor light thread

* qcom low power mode

Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: 06cb2f963d
commatwo_master
Adeeb Shihadeh 5 years ago committed by GitHub
parent 37529e23a9
commit f27bdfbee7
  1. 2
      selfdrive/manager.py
  2. 28
      selfdrive/sensord/sensors_qcom.cc
  3. 123
      selfdrive/ui/android/ui.cc
  4. 3
      selfdrive/ui/ui.cc
  5. 3
      selfdrive/ui/ui.hpp

@ -224,6 +224,7 @@ if not PC:
'updated', 'updated',
'logcatd', 'logcatd',
'tombstoned', 'tombstoned',
'sensord',
] ]
car_started_processes = [ car_started_processes = [
@ -254,7 +255,6 @@ if WEBCAM:
if not PC: if not PC:
car_started_processes += [ car_started_processes += [
'ubloxd', 'ubloxd',
'sensord',
'dmonitoringd', 'dmonitoringd',
'dmonitoringmodeld', 'dmonitoringmodeld',
] ]

@ -48,7 +48,12 @@ void sigpipe_handler(int sig) {
void sensor_loop() { void sensor_loop() {
LOG("*** sensor loop"); LOG("*** sensor loop");
uint64_t frame = 0;
bool low_power_mode = false;
while (!do_exit) { while (!do_exit) {
SubMaster sm({"thermal"});
PubMaster pm({"sensorEvents"}); PubMaster pm({"sensorEvents"});
struct sensors_poll_device_t* device; struct sensors_poll_device_t* device;
@ -90,6 +95,13 @@ void sensor_loop() {
{SENSOR_LIGHT, ms2ns(100)} {SENSOR_LIGHT, ms2ns(100)}
}; };
// sensors needed while offroad
std::set<int> offroad_sensors = {
SENSOR_LIGHT,
SENSOR_ACCELEROMETER,
};
// init all the sensors
for (auto &s : sensors) { for (auto &s : sensors) {
device->activate(device, s.first, 0); device->activate(device, s.first, 0);
device->activate(device, s.first, 1); device->activate(device, s.first, 1);
@ -189,6 +201,22 @@ void sensor_loop() {
re_init_sensors = false; re_init_sensors = false;
break; 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); sensors_close(device);
} }

@ -3,6 +3,8 @@
#include <math.h> #include <math.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <algorithm>
#include "common/util.h" #include "common/util.h"
#include "common/utilpp.h" #include "common/utilpp.h"
#include "common/params.h" #include "common/params.h"
@ -13,65 +15,11 @@
#include "paint.hpp" #include "paint.hpp"
#include "android/sl_sound.hpp" #include "android/sl_sound.hpp"
// Includes for light sensor
#include <cutils/properties.h>
#include <hardware/sensors.h>
#include <utils/Timers.h>
volatile sig_atomic_t do_exit = 0; volatile sig_atomic_t do_exit = 0;
static void set_do_exit(int sig) { static void set_do_exit(int sig) {
do_exit = 1; 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 void ui_set_brightness(UIState *s, int brightness) {
static int last_brightness = -1; static int last_brightness = -1;
if (last_brightness != brightness && (s->awake || brightness == 0)) { 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) { // TODO: implement double tap to wake and actually turn display off
if (awake) { static void handle_display_state(UIState *s, bool user_input) {
// 30 second timeout
s->awake_timeout = 30*UI_FREQ;
}
if (s->awake != awake) {
s->awake = awake;
// TODO: replace command_awake and command_sleep with direct calls to android static int display_mode = HWC_POWER_MODE_OFF;
if (awake) { static int display_timeout = 0;
LOGW("awake normal");
framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); // determine desired state
enable_event_processing(true); int desired_mode = display_mode;
if (user_input || s->ignition || s->started) {
desired_mode = HWC_POWER_MODE_NORMAL;
display_timeout = 30*UI_FREQ;
} else { } else {
LOGW("awake off"); display_timeout = std::max(display_timeout-1, 0);
if (display_timeout == 0) {
desired_mode = HWC_POWER_MODE_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); 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 main(int argc, char* argv[]) {
int err;
setpriority(PRIO_PROCESS, 0, -14); setpriority(PRIO_PROCESS, 0, -14);
signal(SIGINT, (sighandler_t)set_do_exit); signal(SIGINT, (sighandler_t)set_do_exit);
SLSound sound; SLSound sound;
@ -172,14 +129,10 @@ int main(int argc, char* argv[]) {
ui_init(s); ui_init(s);
s->sound = &sound; s->sound = &sound;
set_awake(s, true); handle_display_state(s, true);
enable_event_processing(true); enable_event_processing(true);
PubMaster *pm = new PubMaster({"offroadLayout"}); 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}; TouchState touch = {0};
touch_init(&touch); touch_init(&touch);
@ -215,23 +168,12 @@ int main(int argc, char* argv[]) {
int touch_x = -1, touch_y = -1; int touch_x = -1, touch_y = -1;
int touched = touch_poll(&touch, &touch_x, &touch_y, 0); int touched = touch_poll(&touch, &touch_x, &touch_y, 0);
if (touched == 1) { if (touched == 1) {
set_awake(s, true);
handle_sidebar_touch(s, touch_x, touch_y); handle_sidebar_touch(s, touch_x, touch_y);
handle_vision_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 // Don't waste resources on drawing in case screen is off
handle_display_state(s, touched == 1);
if (!s->awake) { if (!s->awake) {
continue; continue;
} }
@ -255,10 +197,7 @@ int main(int argc, char* argv[]) {
framebuffer_swap(s->fb); framebuffer_swap(s->fb);
} }
set_awake(s, true); handle_display_state(s, true);
err = pthread_join(light_sensor_thread_handle, NULL);
assert(err == 0);
delete s->sm; delete s->sm;
delete pm; delete pm;
return 0; return 0;

@ -217,8 +217,6 @@ void update_sockets(UIState *s) {
} else if ((sm.frame - sm.rcv_frame("dMonitoringState")) > UI_FREQ/2) { } else if ((sm.frame - sm.rcv_frame("dMonitoringState")) > UI_FREQ/2) {
scene.frontview = false; scene.frontview = false;
} }
#ifdef QCOM2 // TODO: use this for QCOM too
if (sm.updated("sensorEvents")) { if (sm.updated("sensorEvents")) {
for (auto sensor : sm["sensorEvents"].getSensorEvents()) { for (auto sensor : sm["sensorEvents"].getSensorEvents()) {
if (sensor.which() == cereal::SensorEventData::LIGHT) { if (sensor.which() == cereal::SensorEventData::LIGHT) {
@ -226,7 +224,6 @@ void update_sockets(UIState *s) {
} }
} }
} }
#endif
s->started = scene.thermal.getStarted() || scene.frontview; s->started = scene.thermal.getStarted() || scene.frontview;
} }

@ -183,8 +183,7 @@ typedef struct UIState {
// device state // device state
bool awake; bool awake;
int awake_timeout; float light_sensor;
std::atomic<float> light_sensor;
bool started; bool started;
bool ignition; bool ignition;

Loading…
Cancel
Save