From 812d2e7d5333d2d5051fe05b0c83c30eb14a3d79 Mon Sep 17 00:00:00 2001 From: Patrick Porlan Date: Tue, 27 Jan 2015 16:34:59 +0100 Subject: [PATCH] IRDA-3484: Add support for filter property As of today, filtering is only engaged if a sensor has the noisy quirk. If it is, we use median filtering for gyroscopes and moving average for magnetometers. Let's allow for a filter configuration item that would force any of the available filters selectively. filter=median filter=average will supersede the default choice. There's no reason to support a none setting, as it's the default. Change-Id: I7f85738e3b770d86efe9a709495c08ca36ba4024 Tracked-On: https://jira01.devtools.intel.com/browse/IRDA-3484 Signed-off-by: Patrick Porlan --- common.h | 5 +++++ control.c | 2 +- description.c | 2 +- description.h | 1 + filtering.c | 40 ++++++++++++++++++++++++++++++++++------ transform.c | 8 +++----- 6 files changed, 45 insertions(+), 13 deletions(-) diff --git a/common.h b/common.h index e8d5497..baf0632 100644 --- a/common.h +++ b/common.h @@ -38,6 +38,9 @@ #define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0]) #define REPORTING_MODE(x) ((x) & 0x06) +#define FILTER_TYPE_NONE 0 +#define FILTER_TYPE_MOVING_AVERAGE 1 +#define FILTER_TYPE_MEDIAN 2 typedef struct { @@ -242,6 +245,8 @@ typedef struct * events before filtering kicks in. We can also use it for statistics. */ uint64_t event_count; + + int filter_type; /* FILTER_ specification for this sensor ; default is FILTER_NONE */ } sensor_info_t; diff --git a/control.c b/control.c index e63695c..3751131 100644 --- a/control.c +++ b/control.c @@ -919,7 +919,7 @@ int sensor_activate (int s, int enabled, int from_virtual) sensor[s].event_count = 0; sensor[s].meta_data_pending = 0; - if (enabled && (sensor[s].quirks & QUIRK_NOISY)) + if (enabled) setup_noise_filtering(s); /* Initialize filtering data if required */ if (!sensor[s].is_polling) { diff --git a/description.c b/description.c index 36730cc..539358e 100644 --- a/description.c +++ b/description.c @@ -83,7 +83,7 @@ * properties values happen to have its iio device name set to bmg160. */ -static int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]) +int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]) { char prop_name[PROP_NAME_MAX]; char prop_val[PROP_VALUE_MAX]; diff --git a/description.h b/description.h index aef3f21..a5f50f4 100644 --- a/description.h +++ b/description.h @@ -38,5 +38,6 @@ int sensor_get_fl_prop (int s, const char* sel, float* val); int sensor_get_order (int s,unsigned char map[MAX_CHANNELS]); int sensor_get_cal_steps (int s); char* sensor_get_string_type (int s); +int sensor_get_st_prop (int s, const char* sel, char val[MAX_NAME_SIZE]); #endif diff --git a/filtering.c b/filtering.c index 4d82869..510737c 100644 --- a/filtering.c +++ b/filtering.c @@ -6,7 +6,7 @@ #include #include "common.h" #include "filtering.h" - +#include "description.h" typedef struct { @@ -200,8 +200,36 @@ static void denoise_average (sensor_info_t* si, sensors_event_t* data, int num_f void setup_noise_filtering (int s) { - switch (sensor[s].type) { - case SENSOR_TYPE_GYROSCOPE: + char filter_buf[MAX_NAME_SIZE]; + + /* By default, don't apply filtering */ + sensor[s].filter_type = FILTER_TYPE_NONE; + + /* If noisy, start with default filter for sensor type */ + if (sensor[s].quirks & QUIRK_NOISY) + switch (sensor[s].type) { + case SENSOR_TYPE_GYROSCOPE: + sensor[s].filter_type = FILTER_TYPE_MEDIAN; + break; + + case SENSOR_TYPE_MAGNETIC_FIELD: + sensor[s].filter_type = FILTER_TYPE_MOVING_AVERAGE; + break; + } + + /* Use whatever was specified if there's an explicit configuration choice for this sensor */ + + filter_buf[0] = '\0'; + sensor_get_st_prop(s, "filter", filter_buf); + + if (strstr(filter_buf, "median")) + sensor[s].filter_type = FILTER_TYPE_MEDIAN; + + if (strstr(filter_buf, "average")) + sensor[s].filter_type = FILTER_TYPE_MOVING_AVERAGE; + + switch (sensor[s].filter_type) { + case FILTER_TYPE_MEDIAN: denoise_median_init(s, 3, 5); break; } @@ -210,12 +238,12 @@ void setup_noise_filtering (int s) void denoise (int s, sensors_event_t* data) { - switch (sensor[s].type) { - case SENSOR_TYPE_GYROSCOPE: + switch (sensor[s].filter_type) { + case FILTER_TYPE_MEDIAN: denoise_median(&sensor[s], data, 3); break; - case SENSOR_TYPE_MAGNETIC_FIELD: + case FILTER_TYPE_MOVING_AVERAGE: denoise_average(&sensor[s], data, 3 , 20); break; } diff --git a/transform.c b/transform.c index 9911bee..bc6178d 100644 --- a/transform.c +++ b/transform.c @@ -299,14 +299,12 @@ static int finalize_sample_default (int s, sensors_event_t* data) case SENSOR_TYPE_ACCELEROMETER: /* Always consider the accelerometer accurate */ data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; - if (sensor[s].quirks & QUIRK_NOISY) - denoise(s, data); + denoise(s, data); break; case SENSOR_TYPE_MAGNETIC_FIELD: calibrate_compass (data, &sensor[s]); - if (sensor[s].quirks & QUIRK_NOISY) - denoise(s, data); + denoise(s, data); break; case SENSOR_TYPE_GYROSCOPE: @@ -326,7 +324,7 @@ static int finalize_sample_default (int s, sensors_event_t* data) * For noisy sensors drop a few samples to make sure we have at least GYRO_MIN_SAMPLES events in the * filtering queue. This improves mean and std dev. */ - if (sensor[s].quirks & QUIRK_NOISY) { + if (sensor[s].filter_type) { if (sensor[s].selected_trigger != sensor[s].motion_trigger_name && sensor[s].event_count < GYRO_MIN_SAMPLES) -- 2.11.0