• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "calibration/common/diversity_checker.h"
18 
19 #include <errno.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include "common/math/vec.h"
24 
25 // Struct initialization.
diversityCheckerInit(struct DiversityChecker * diverse_data,size_t min_num_diverse_vectors,size_t max_num_max_distance,float var_threshold,float max_min_threshold,float local_field,float threshold_tuning_param,float max_distance_tuning_param)26 void diversityCheckerInit(
27     struct DiversityChecker* diverse_data,
28     size_t min_num_diverse_vectors,
29     size_t max_num_max_distance,
30     float var_threshold,
31     float max_min_threshold,
32     float local_field,
33     float threshold_tuning_param,
34     float max_distance_tuning_param) {
35   ASSERT_NOT_NULL(diverse_data);
36 
37   // Initialize parameters.
38   diverse_data->threshold_tuning_param_sq =
39       (threshold_tuning_param * threshold_tuning_param);
40   diverse_data->max_distance_tuning_param_sq =
41       (max_distance_tuning_param * max_distance_tuning_param);
42 
43   // Updating the threshold and max_distance using assumed local field.
44   // Testing for zero and negative local_field.
45   if (local_field <= 0) {
46     local_field = 1;
47   }
48   diversityCheckerLocalFieldUpdate(diverse_data, local_field);
49   diverse_data->min_num_diverse_vectors = min_num_diverse_vectors;
50 
51   // Checking for min_num_diverse_vectors = 0.
52   if (min_num_diverse_vectors < 1) {
53     diverse_data->min_num_diverse_vectors = 1;
54   }
55   diverse_data->max_num_max_distance = max_num_max_distance;
56   diverse_data->var_threshold = var_threshold;
57   diverse_data->max_min_threshold = max_min_threshold;
58 
59   // Setting the rest to zero.
60   diversityCheckerReset(diverse_data);
61 
62    // Debug Messages
63 #ifdef DIVERSE_DEBUG_ENABLE
64   memset(&diverse_data->diversity_dbg, 0, sizeof(diverse_data->diversity_dbg));
65 #endif
66 }
67 
68 // Reset
diversityCheckerReset(struct DiversityChecker * diverse_data)69 void diversityCheckerReset(struct DiversityChecker* diverse_data) {
70   ASSERT_NOT_NULL(diverse_data);
71   // Clear data memory.
72   memset(&diverse_data->diverse_data, 0,
73          sizeof(diverse_data->diverse_data));
74 
75   // Resetting counters and data full bit.
76   diverse_data->num_points = 0;
77   diverse_data->num_max_dist_violations = 0;
78   diverse_data->data_full = false;
79 }
80 
diversityCheckerUpdate(struct DiversityChecker * diverse_data,float x,float y,float z)81 void diversityCheckerUpdate(
82     struct DiversityChecker* diverse_data, float x, float y, float z) {
83   ASSERT_NOT_NULL(diverse_data);
84 
85   // Converting three single inputs to a vector.
86   const float vec[3] = {x, y, z};
87 
88   // Result vector for vector difference.
89   float vec_diff[3];
90 
91   // normSquared result (k)
92   float norm_squared_result;
93 
94   // If memory is full, no need to run through the data.
95   if (!diverse_data->data_full) {
96     size_t i;
97     // Running over all existing data points
98     for (i = 0; i < diverse_data->num_points; ++i) {
99       // v = v1 - v2;
100       vecSub(vec_diff,
101              &diverse_data->diverse_data[i * THREE_AXIS_DATA_DIM],
102              vec,
103              THREE_AXIS_DATA_DIM);
104 
105       // k = |v|^2
106       norm_squared_result = vecNormSquared(vec_diff, THREE_AXIS_DATA_DIM);
107 
108       // if k < Threshold then leave the function.
109       if (norm_squared_result < diverse_data->threshold) {
110         return;
111       }
112 
113       // if k > max_distance, count and leave the function.
114       if (norm_squared_result > diverse_data->max_distance) {
115         diverse_data->num_max_dist_violations++;
116         return;
117       }
118     }
119 
120     // If none of the above caused to leave the function, data is diverse.
121     // Notice that the first data vector will be stored no matter what.
122     memcpy(&diverse_data->
123            diverse_data[diverse_data->num_points * THREE_AXIS_DATA_DIM],
124            vec,
125            sizeof(float) * THREE_AXIS_DATA_DIM);
126     // Count new data point.
127     diverse_data->num_points++;
128 
129     // Setting data_full to 1, if memory is full.
130     if (diverse_data->num_points == NUM_DIVERSE_VECTORS) {
131       diverse_data->data_full = true;
132     }
133   }
134 }
135 
diversityCheckerNormQuality(struct DiversityChecker * diverse_data,float x_bias,float y_bias,float z_bias)136 bool diversityCheckerNormQuality(struct DiversityChecker* diverse_data,
137                                  float x_bias,
138                                  float y_bias,
139                                  float z_bias) {
140   ASSERT_NOT_NULL(diverse_data);
141   // If not enough diverse data points or max distance violations return false.
142   if (diverse_data->num_points <= diverse_data->min_num_diverse_vectors ||
143       diverse_data->num_max_dist_violations >=
144       diverse_data->max_num_max_distance) {
145     return false;
146   }
147   float vec_bias[3] = {x_bias, y_bias, z_bias};
148   float vec_bias_removed[3];
149   float norm_results;
150   float acc_norm = 0.0f;
151   float acc_norm_square = 0.0f;
152   float max = 0.0f;
153   float min = 0.0f;
154   size_t i;
155   for (i = 0; i < diverse_data->num_points; ++i) {
156     // v = v1 - v_bias;
157     vecSub(vec_bias_removed,
158            &diverse_data->diverse_data[i * THREE_AXIS_DATA_DIM],
159            vec_bias,
160            THREE_AXIS_DATA_DIM);
161 
162     // norm = ||v||
163     norm_results = vecNorm(vec_bias_removed, THREE_AXIS_DATA_DIM);
164 
165     // Accumulate for mean and VAR.
166     acc_norm += norm_results;
167     acc_norm_square += norm_results * norm_results ;
168 
169     if (i == 0) {
170       min = norm_results;
171       max = norm_results;
172     }
173     // Finding min
174     if (norm_results < min) {
175       min = norm_results;
176     }
177 
178     // Finding max.
179     if (norm_results > max) {
180       max = norm_results;
181     }
182     // can leave the function if max-min is violated
183     // no need to continue.
184     if ((max - min) > diverse_data->max_min_threshold) {
185       return false;
186     }
187   }
188   float inv = 1.0f / diverse_data->num_points;
189   float var = (acc_norm_square - (acc_norm * acc_norm) * inv) * inv;
190 
191   // Debug Message.
192 #ifdef DIVERSE_DEBUG_ENABLE
193   diverse_data->diversity_dbg.diversity_count++;
194   diverse_data->diversity_dbg.var_log = var;
195   diverse_data->diversity_dbg.mean_log = acc_norm * inv;
196   diverse_data->diversity_dbg.max_log = max;
197   diverse_data->diversity_dbg.min_log = min;
198   memcpy(&diverse_data->diversity_dbg.diverse_data_log,
199          &diverse_data->diverse_data,
200          sizeof(diverse_data->diversity_dbg.diverse_data_log));
201 #endif
202   return (var < diverse_data->var_threshold);
203 }
204 
diversityCheckerLocalFieldUpdate(struct DiversityChecker * diverse_data,float local_field)205 void diversityCheckerLocalFieldUpdate(struct DiversityChecker* diverse_data,
206                                       float local_field) {
207   if (local_field > 0) {
208     // Updating threshold based on the local field information.
209     diverse_data->threshold = diverse_data->threshold_tuning_param_sq *
210         (local_field * local_field);
211 
212     // Updating max distance based on the local field information.
213     diverse_data->max_distance = diverse_data->max_distance_tuning_param_sq *
214         (local_field * local_field);
215   }
216 }
217