OSDN Git Service

GMINL-2659: Keep recent events history for fusion-like processing
authorPatrick Porlan <patrick.porlan@intel.com>
Fri, 24 Oct 2014 13:17:45 +0000 (15:17 +0200)
committerAdriana Reus <adriana.reus@intel.com>
Mon, 27 Oct 2014 13:39:51 +0000 (15:39 +0200)
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 <patrick.porlan@intel.com>
common.h
control.c
filtering.c
filtering.h
transform.c

index 48e2124..fd673ac 100644 (file)
--- 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;
 
index 1124a0f..b7ed570 100644 (file)
--- 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; s<sensor_count && returned_events < count; s++) {
                if (sensor_info[s].report_pending) {
                        event_count = 0;
-                       /* Lower flag */
-                       sensor_info[s].report_pending = 0;
 
                        /* Report this event if it looks OK */
                        event_count = propagate_sensor_report(s, &data[returned_events]);
 
+                       /* Lower flag */
+                       sensor_info[s].report_pending = 0;
+
                        /* Duplicate only if both cal & uncal are active */
                        if (sensor_info[s].type == SENSOR_TYPE_GYROSCOPE &&
                                        sensor_info[s].pair_idx && sensor_info[sensor_info[s].pair_idx].enable_count != 0) {
index 45e846d..bcaaada 100644 (file)
@@ -96,6 +96,7 @@ void denoise_median_release(int s)
        free(sensor_info[s].filter);
        sensor_info[s].filter = NULL;
 }
+
 void denoise_median(struct sensor_info_t* info, struct sensors_event_t* data,
                                        unsigned int num_fields)
 {
@@ -121,3 +122,55 @@ void denoise_median(struct sensor_info_t* info, struct sensors_event_t* data,
        f_data->idx = (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));
+}
index 6543a7d..bd98ffa 100644 (file)
@@ -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
index 97837f7..a49300d 100644 (file)
@@ -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 */
 }