accel: Fix accelerometer unit confusion

The original orientation code was based upon code that expected 1G to
roughly correspond to a reading of 256, to work-around the fact that the
input layer could not pass fractional values easily.

So the orientation_calc() code expected that too. But IIO readings after
scaling are properly in m/s², and our readings are integers.

We'll pass the scaling around to be applied at the last minute, when
doing calculations.

Closes: #100
This commit is contained in:
Bastien Nocera
2016-09-14 14:12:01 +02:00
parent 5ff39aea7d
commit 07299fb51b
7 changed files with 30 additions and 19 deletions

View File

@@ -40,6 +40,7 @@ typedef struct {
int accel_x;
int accel_y;
int accel_z;
gdouble scale;
} AccelReadings;
typedef struct {

View File

@@ -14,10 +14,6 @@
#include <string.h>
#include <errno.h>
/* 1G (9.81m/s²) corresponds to "256"
* value x scale is in m/s² */
#define SCALE_TO_FF(scale) (scale * 256 / 9.81)
typedef struct {
guint timeout_id;
ReadingsUpdateFunc callback_func;
@@ -69,9 +65,10 @@ process_scan (IIOSensorData data, DrvData *or_data)
accel_y = -accel_y;
//FIXME report errors
readings.accel_x = accel_x * scale;
readings.accel_y = accel_y * scale;
readings.accel_z = accel_z * scale;
readings.accel_x = accel_x;
readings.accel_y = accel_y;
readings.accel_z = accel_z;
readings.scale = scale;
or_data->callback_func (&iio_buffer_accel, (gpointer) &readings, or_data->user_data);
return 1;

View File

@@ -15,10 +15,6 @@
#include <stdio.h>
#include <stdlib.h>
/* 1G (9.81m/s²) corresponds to "256"
* value x scale is in m/s² */
#define SCALE_TO_FF(scale) (scale * 256 / 9.81)
typedef struct DrvData {
guint timeout_id;
ReadingsUpdateFunc callback_func;
@@ -56,9 +52,10 @@ poll_orientation (gpointer user_data)
int accel_x, accel_y, accel_z;
AccelReadings readings;
accel_x = sysfs_get_int (data->dev, "in_accel_x_raw") * data->scale;
accel_y = sysfs_get_int (data->dev, "in_accel_y_raw") * data->scale;
accel_z = sysfs_get_int (data->dev, "in_accel_z_raw") * data->scale;
accel_x = sysfs_get_int (data->dev, "in_accel_x_raw");
accel_y = sysfs_get_int (data->dev, "in_accel_y_raw");
accel_z = sysfs_get_int (data->dev, "in_accel_z_raw");
readings.scale = data->scale;
//FIXME report errors
if (g_strcmp0 ("i2c-SMO8500:00", g_udev_device_get_sysfs_attr (data->dev, "name")) == 0) {
@@ -127,7 +124,7 @@ iio_poll_accel_open (GUdevDevice *device,
drv_data->callback_func = callback_func;
drv_data->user_data = user_data;
drv_data->scale = SCALE_TO_FF(g_udev_device_get_sysfs_attr_as_double (device, "in_accel_scale"));
drv_data->scale = g_udev_device_get_sysfs_attr_as_double (device, "in_accel_scale");
if (drv_data->scale == 0.0)
drv_data->scale = 1.0;

View File

@@ -76,6 +76,9 @@ accelerometer_changed (void)
readings.accel_x = accel_x;
readings.accel_y = accel_y;
readings.accel_z = accel_z;
/* Scale from 1G ~= 256 to a value in m/s² */
readings.scale = 1.0 / 256 * 9.81;
drv_data->callback_func (&input_accel, (gpointer) &readings, drv_data->user_data);
}

View File

@@ -589,9 +589,10 @@ accel_changed_func (SensorDriver *driver,
OrientationUp orientation = data->previous_orientation;
//FIXME handle errors
g_debug ("Accel sent by driver (quirk applied): %d, %d, %d", readings->accel_x, readings->accel_y, readings->accel_z);
g_debug ("Accel sent by driver (quirk applied): %d, %d, %d (scale: %lf)",
readings->accel_x, readings->accel_y, readings->accel_z, readings->scale);
orientation = orientation_calc (data->previous_orientation, readings->accel_x, readings->accel_y, readings->accel_z);
orientation = orientation_calc (data->previous_orientation, readings->accel_x, readings->accel_y, readings->accel_z, readings->scale);
data->accel_x = readings->accel_x;
data->accel_y = readings->accel_y;

View File

@@ -56,12 +56,23 @@ string_to_orientation (const char *orientation)
#define THRESHOLD_LANDSCAPE 35
#define THRESHOLD_PORTRAIT 35
/* First apply scale to get m/s², then
* convert to 1G ~= 256 as the code expects */
#define SCALE(a) ((int) ((gdouble) a * scale * 256.0 / 9.81))
OrientationUp
orientation_calc (OrientationUp prev,
int x, int y, int z)
int in_x, int in_y, int in_z,
gdouble scale)
{
int rotation;
OrientationUp ret = prev;
int x, y, z;
/* this code expects 1G ~= 256 */
x = SCALE(in_x);
y = SCALE(in_y);
z = SCALE(in_z);
/* Portrait check */
rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES);

View File

@@ -30,4 +30,5 @@ OrientationUp string_to_orientation (const char *orientation);
OrientationUp orientation_calc (OrientationUp prev,
int x,
int y,
int z);
int z,
gdouble scale);