UI: refactor light sensor (#2129)

* refactor light thread

* qcom low power mode

Co-authored-by: Comma Device <device@comma.ai>
albatross
Adeeb Shihadeh 2020-10-03 20:58:46 -07:00 committed by GitHub
parent 47a42ff432
commit 06cb2f963d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 99 deletions

View File

@ -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',
]

View File

@ -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<int> 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);
}

View File

@ -3,6 +3,8 @@
#include <math.h>
#include <sys/resource.h>
#include <algorithm>
#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 <cutils/properties.h>
#include <hardware/sensors.h>
#include <utils/Timers.h>
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;
}
if (s->awake != awake) {
s->awake = awake;
// TODO: implement double tap to wake and actually turn display off
static void handle_display_state(UIState *s, bool user_input) {
// 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");
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;
}
}
// 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;

View File

@ -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;
}

View File

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