From f4cb7dc91324cc194d1503743027e8937cd712e8 Mon Sep 17 00:00:00 2001 From: Patrick Porlan Date: Fri, 24 Oct 2014 15:17:45 +0200 Subject: [PATCH] GMINL-2659: Keep recent events history for fusion-like processing We may wish to correlate recent input from several active sensors. In preparation to that, keep the last 100 events we got for the entire sensors collection. This is intended as a lightweight record, built and used from the main sensor sample retrieval thread exclusively so we don't have to deal with performance-degrading synchronization primitives. This data will enable multi-sensors filtering decisions. Change-Id: Ied6559c7dd91e94bebbeb1bc60182d1db3103d8c Signed-off-by: Patrick Porlan --- common.h | 12 +++++++++++- control.c | 13 +++++++------ filtering.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ filtering.h | 2 ++ transform.c | 6 ++++++ 5 files changed, 79 insertions(+), 7 deletions(-) diff --git a/common.h b/common.h index 48e2124..fd673ac 100644 --- a/common.h +++ b/common.h @@ -101,6 +101,15 @@ struct sample_ops_t int (*finalize)(int s, struct sensors_event_t* data); }; +/* + * Whenever we have sensor data recorded for a sensor in the associated + * sensor_info cell, its report_pending field is set to a non-zero value + * indicating how we got this data. + */ +#define DATA_TRIGGER 1 /* From /dev/iio:device fd */ +#define DATA_SYSFS 2 /* Through polling */ +#define DATA_DUPLICATE 3 /* Duplicate of triggered motion sample */ + struct sensor_info_t { char friendly_name[MAX_NAME_SIZE]; /* ex: Accelerometer */ @@ -149,7 +158,8 @@ struct sensor_info_t /* * This flag is set if we acquired data from the sensor but did not * forward it to upper layers (i.e. Android) yet. If so, report_buffer - * contains that data. + * contains that data. Valid values are 0: empty, 1: normal, 2: repeat + * of last acquired value after timeout. */ int report_pending; diff --git a/control.c b/control.c index 1124a0f..b7ed570 100644 --- a/control.c +++ b/control.c @@ -772,7 +772,7 @@ void set_report_ts(int s, int64_t ts) } } -static int integrate_device_report(int dev_num) +static int integrate_device_report (int dev_num) { int len; int s,c; @@ -833,7 +833,7 @@ static int integrate_device_report(int dev_num) sr_offset); set_report_ts(s, get_timestamp()); - sensor_info[s].report_pending = 1; + sensor_info[s].report_pending = DATA_TRIGGER; sensor_info[s].report_initialized = 1; } @@ -945,7 +945,7 @@ static void synthetize_duplicate_samples (void) if (target_ts <= current_ts) { /* Mark the sensor for event generation */ set_report_ts(s, current_ts); - sensor_info[s].report_pending = 1; + sensor_info[s].report_pending = DATA_DUPLICATE; } } } @@ -965,7 +965,7 @@ static void integrate_thread_report (uint32_t tag) if (len == expected_len) { set_report_ts(s, get_timestamp()); - sensor_info[s].report_pending = 1; + sensor_info[s].report_pending = DATA_SYSFS; } } @@ -1038,12 +1038,13 @@ return_available_sensor_reports: for (s=0; sidx = (f_data->idx + 1) % f_data->sample_size; } + +#define GLOBAL_HISTORY_SIZE 100 + +struct recorded_sample_t +{ + int sensor; + int motion_trigger; + sensors_event_t data; +}; + +/* + * This is a circular buffer holding the last GLOBAL_HISTORY_SIZE events, + * covering the entire sensor collection. It is intended as a way to correlate + * data coming from active sensors, no matter the sensor type, over a recent + * window of time. The array is not sorted ; we simply evict the oldest cell + * (by insertion time) and replace its contents. Timestamps don't necessarily + * grow monotonically as they tell the data acquisition type, and that there can + * be a delay between acquisition and insertion into this table. + */ + +static struct recorded_sample_t global_history[GLOBAL_HISTORY_SIZE]; + +static int initialized_entries; /* How many of these are initialized */ +static int insertion_index; /* Index of sample to evict next time */ + + +void record_sample (int s, const struct sensors_event_t* event) +{ + struct recorded_sample_t *cell; + int i; + + /* Don't record duplicate samples, as they are not useful for filters */ + if (sensor_info[s].report_pending == DATA_DUPLICATE) + return; + + if (initialized_entries == GLOBAL_HISTORY_SIZE) { + i = insertion_index; + insertion_index = (insertion_index+1) % GLOBAL_HISTORY_SIZE; + } else { + i = initialized_entries; + initialized_entries++; + } + + cell = &global_history[i]; + + cell->sensor = s; + + cell->motion_trigger = (sensor_info[s].selected_trigger == + sensor_info[s].motion_trigger_name); + + memcpy(&cell->data, event, sizeof(sensors_event_t)); +} diff --git a/filtering.h b/filtering.h index 6543a7d..bd98ffa 100644 --- a/filtering.h +++ b/filtering.h @@ -6,4 +6,6 @@ void denoise_median(struct sensor_info_t* info, struct sensors_event_t* event, void denoise_median_init(int s, unsigned int sample_size, unsigned int num_fields); void denoise_median_release(int s); + +void record_sample(int s, const sensors_event_t* data); #endif diff --git a/transform.c b/transform.c index 97837f7..a49300d 100644 --- a/transform.c +++ b/transform.c @@ -335,6 +335,9 @@ static int finalize_sample_default (int s, struct sensors_event_t* data) break; } + /* Add this event to our global records, for filtering purposes */ + record_sample(s, data); + return 1; /* Return sample to Android */ } @@ -373,6 +376,9 @@ static int finalize_sample_ISH (int s, struct sensors_event_t* data) data->data[2] = -roll; } + /* Add this event to our global records, for filtering purposes */ + record_sample(s, data); + return 1; /* Return sample to Android */ } -- 2.11.0