OSDN Git Service

[REVERTME] Revert "Pass iio provided timestamps without further processing."
[android-x86/hardware-intel-libsensors.git] / gyro-calibration.c
1 /*
2  * Copyright (C) 2014-2015 Intel Corporation.
3  */
4
5 #include <stdio.h>
6 #include <math.h>
7 #include <sys/time.h>
8 #include <utils/Log.h>
9 #include <hardware/sensors.h>
10 #include "common.h"
11 #include "calibration.h"
12
13
14 /* Gyro defines */
15 #define GYRO_MAX_ERR 0.05
16 #define GYRO_DS_SIZE 100
17 #define GYRO_CALIBRATION_PATH "/data/gyro.conf"
18
19
20 static void reset (gyro_cal_t* cal_data)
21 {
22         cal_data->count = 0;
23
24         cal_data->bias_x = cal_data->bias_y = cal_data->bias_z = 0;
25
26         cal_data->min_x  = cal_data->min_y  = cal_data->min_z  = 1.0;
27         cal_data->max_x  = cal_data->max_y  = cal_data->max_z  =-1.0;
28 }
29
30
31 void gyro_cal_init (sensor_info_t* info)
32 {
33         int ret;
34         gyro_cal_t* cal_data = (gyro_cal_t*) info->cal_data;
35         FILE* data_file;
36
37         info->cal_level = 0;
38
39         if (cal_data == NULL)
40                 return;
41
42         reset(cal_data);
43
44         data_file = fopen (GYRO_CALIBRATION_PATH, "r");
45         if (data_file == NULL)
46                 return;
47
48         ret = fscanf(data_file, "%f %f %f",
49                         &cal_data->bias_x, &cal_data->bias_y, &cal_data->bias_z);
50         if (ret != 3)
51                 ALOGE("Gyro calibration - init failed!\n");
52
53         fclose(data_file);
54 }
55
56
57 void gyro_store_data (sensor_info_t* info)
58 {
59         int ret;
60         gyro_cal_t* cal_data = (gyro_cal_t*) info->cal_data;
61         FILE* data_file;
62
63         if (cal_data == NULL)
64                 return;
65
66         data_file = fopen (GYRO_CALIBRATION_PATH, "w");
67
68         if (data_file == NULL)
69                 return;
70
71         ret = fprintf(data_file, "%f %f %f",
72                 cal_data->bias_x, cal_data->bias_y, cal_data->bias_z);
73
74         if (ret < 0)
75                 ALOGE ("Gyro calibration - store data failed!");
76
77         fclose(data_file);
78 }
79
80
81 static int gyro_collect (float x, float y, float z, gyro_cal_t* cal_data)
82 {
83         /* Analyze gyroscope data */
84
85         if (fabs(x) >= 1 || fabs(y) >= 1 || fabs(z) >= 1) {
86
87                 /* We're supposed to be standing still ; start over */
88                 reset(cal_data);
89
90                 return 0; /* Uncalibrated */
91         }
92
93         if (cal_data->count < GYRO_DS_SIZE) {
94
95                 if (x < cal_data->min_x)
96                         cal_data->min_x = x;
97
98                 if (y < cal_data->min_y)
99                         cal_data->min_y = y;
100
101                 if (z < cal_data->min_z)
102                         cal_data->min_z = z;
103
104                 if (x > cal_data->max_x)
105                         cal_data->max_x = x;
106
107                 if (y > cal_data->max_y)
108                         cal_data->max_y = y;
109
110                 if (z > cal_data->max_z)
111                         cal_data->max_z = z;
112
113                 if (fabs(cal_data->max_x - cal_data->min_x) <= GYRO_MAX_ERR &&
114                     fabs(cal_data->max_y - cal_data->min_y) <= GYRO_MAX_ERR &&
115                     fabs(cal_data->max_z - cal_data->min_z) <= GYRO_MAX_ERR)
116                         cal_data->count++; /* One more conformant sample */
117                 else
118                         reset(cal_data); /* Out of spec sample ; start over */
119
120                 return 0; /* Still uncalibrated */
121         }
122
123         /* We got enough stable samples to estimate gyroscope bias */
124         cal_data->bias_x = (cal_data->max_x + cal_data->min_x) / 2;
125         cal_data->bias_y = (cal_data->max_y + cal_data->min_y) / 2;
126         cal_data->bias_z = (cal_data->max_z + cal_data->min_z) / 2;
127
128         return 1; /* Calibrated! */
129 }
130
131
132 void calibrate_gyro (sensors_event_t* event, sensor_info_t* info)
133 {
134         gyro_cal_t* cal_data = (gyro_cal_t*) info->cal_data;
135
136         if (cal_data == NULL)
137                 return;
138
139         /* Attempt gyroscope calibration if we have not reached this state */
140         if (info->cal_level == 0)
141                 info->cal_level = gyro_collect(event->data[0], event->data[1],
142                                                event->data[2], cal_data);
143
144
145         event->data[0] = event->data[0] - cal_data->bias_x;
146         event->data[1] = event->data[1] - cal_data->bias_y;
147         event->data[2] = event->data[2] - cal_data->bias_z;
148
149         if (info->cal_level)
150                event->gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
151 }