OSDN Git Service

Winter cleanup: revisit enable_buffer function
[android-x86/hardware-intel-libsensors.git] / gyro-calibration.c
1 /*
2  * Copyright (C) 2014 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         fclose(data_file);
51 }
52
53
54 void gyro_store_data (sensor_info_t* info)
55 {
56         int ret;
57         gyro_cal_t* cal_data = (gyro_cal_t*) info->cal_data;
58         FILE* data_file;
59
60         if (cal_data == NULL)
61                 return;
62
63         data_file = fopen (GYRO_CALIBRATION_PATH, "w");
64
65         if (data_file == NULL)
66                 return;
67
68         ret = fprintf(data_file, "%f %f %f",
69                 cal_data->bias_x, cal_data->bias_y, cal_data->bias_z);
70
71         if (ret < 0)
72                 ALOGE ("Gyro calibration - store data failed!");
73
74         fclose(data_file);
75 }
76
77
78 static int gyro_collect (float x, float y, float z, gyro_cal_t* cal_data)
79 {
80         /* Analyze gyroscope data */
81
82         if (fabs(x) >= 1 || fabs(y) >= 1 || fabs(z) >= 1) {
83
84                 /* We're supposed to be standing still ; start over */
85                 reset(cal_data);
86
87                 return 0; /* Uncalibrated */
88         }
89
90         if (cal_data->count < GYRO_DS_SIZE) {
91
92                 if (x < cal_data->min_x)
93                         cal_data->min_x = x;
94
95                 if (y < cal_data->min_y)
96                         cal_data->min_y = y;
97
98                 if (z < cal_data->min_z)
99                         cal_data->min_z = z;
100
101                 if (x > cal_data->max_x)
102                         cal_data->max_x = x;
103
104                 if (y > cal_data->max_y)
105                         cal_data->max_y = y;
106
107                 if (z > cal_data->max_z)
108                         cal_data->max_z = z;
109
110                 if (fabs(cal_data->max_x - cal_data->min_x) <= GYRO_MAX_ERR &&
111                     fabs(cal_data->max_y - cal_data->min_y) <= GYRO_MAX_ERR &&
112                     fabs(cal_data->max_z - cal_data->min_z) <= GYRO_MAX_ERR)
113                         cal_data->count++; /* One more conformant sample */
114                 else
115                         reset(cal_data); /* Out of spec sample ; start over */
116
117                 return 0; /* Still uncalibrated */
118         }
119
120         /* We got enough stable samples to estimate gyroscope bias */
121         cal_data->bias_x = (cal_data->max_x + cal_data->min_x) / 2;
122         cal_data->bias_y = (cal_data->max_y + cal_data->min_y) / 2;
123         cal_data->bias_z = (cal_data->max_z + cal_data->min_z) / 2;
124
125         return 1; /* Calibrated! */
126 }
127
128
129 void calibrate_gyro (sensors_event_t* event, sensor_info_t* info)
130 {
131         gyro_cal_t* cal_data = (gyro_cal_t*) info->cal_data;
132
133         if (cal_data == NULL)
134                 return;
135
136         /* Attempt gyroscope calibration if we have not reached this state */
137         if (info->cal_level == 0)
138                 info->cal_level = gyro_collect(event->data[0], event->data[1],
139                                                event->data[2], cal_data);
140
141
142         event->data[0] = event->data[0] - cal_data->bias_x;
143         event->data[1] = event->data[1] - cal_data->bias_y;
144         event->data[2] = event->data[2] - cal_data->bias_z;
145
146         if (info->cal_level)
147                event->gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
148 }