| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| /* |
| * This function implements a diversity checker and stores diverse vectors into |
| * a memory. We assume that the data is located on a sphere, and we use the |
| * norm of the difference of two vectors to decide if the vectors are diverse |
| * enough: |
| * |
| * k = norm( v1 - v2 )^2 < Threshold |
| * |
| * Hence when k < Threshold the data is not stored, because the vectors are too |
| * similar. We store diverse vectors in memory and all new incoming vectors |
| * are checked against the already stored data points. |
| * |
| * Furthermore we also check if k > max_distance, since that data is most likely |
| * not located on a sphere anymore and indicates a disturbance. Finally we give |
| * a "data is full" flag to indicate once the memory is full. |
| * The diverse data can be used to improve sphere fit calibrations, ensuring |
| * that the sphere is populated enough resulting in better fits. |
| * |
| * Memory is stored in an array initialized to length of |
| * [THREE_AXIS_DATA_DIM * NUM_DIVERSE_VECTORS], this has been done to be |
| * compatible with the full sphere fit algorithm. |
| * |
| * Notice, this function stops to check if data is diverse, once the memory is |
| * full. This has been done in order to save processing power. |
| */ |
| |
| #ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_DIVERSITY_CHECKER_DIVERSITY_CHECKER_H_ |
| #define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_DIVERSITY_CHECKER_DIVERSITY_CHECKER_H_ |
| |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #if defined(MAG_CAL_DEBUG_ENABLE) && !defined(DIVERSE_DEBUG_ENABLE) |
| // Ensures that diversity messaging is set when mag_cal debugging is enabled. |
| #define DIVERSE_DEBUG_ENABLE |
| #endif // MAG_CAL_DEBUG_ENABLE && !DIVERSE_DEBUG_ENABLE |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #define THREE_AXIS_DATA_DIM (3) // data is three-dimensional. |
| #define NUM_DIVERSE_VECTORS (30) // Storing 30 data points. |
| |
| // Debug Messages |
| #ifdef DIVERSE_DEBUG_ENABLE |
| struct DiversityDbg { |
| uint32_t diversity_count; |
| float var_log; |
| float mean_log; |
| float max_log; |
| float min_log; |
| float diverse_data_log[THREE_AXIS_DATA_DIM * NUM_DIVERSE_VECTORS]; |
| size_t new_trigger; |
| }; |
| #endif |
| |
| // DiversityChecker parameters container. |
| struct DiversityCheckerParameters { |
| float var_threshold; |
| float max_min_threshold; |
| float local_field; |
| float threshold_tuning_param; |
| float max_distance_tuning_param; |
| size_t min_num_diverse_vectors; |
| size_t max_num_max_distance; |
| }; |
| |
| // Main data struct. |
| struct DiversityChecker { |
| // Data memory. |
| float diverse_data[THREE_AXIS_DATA_DIM * NUM_DIVERSE_VECTORS]; |
| |
| // Number of data points in the memory. |
| size_t num_points; |
| |
| // Number of data points that violated the max_distance condition. |
| size_t num_max_dist_violations; |
| |
| // Threshold value that is used to check k against. |
| float threshold; |
| |
| // Threshold tuning parameter used to calculate threshold (k_algo): |
| // threshold = threshold_tuning_param_sq * (local_field)^2. |
| float threshold_tuning_param_sq; |
| |
| // Maximum distance value. |
| float max_distance; |
| |
| // Max Distance tuning parameter: |
| // max_distance = max_distance_tuning_param_sq * (local_field)^2. |
| float max_distance_tuning_param_sq; |
| |
| // Data full bit. |
| bool data_full; |
| |
| // Setup variables for NormQuality check. |
| size_t min_num_diverse_vectors; |
| size_t max_num_max_distance; |
| float var_threshold; |
| float max_min_threshold; |
| |
| // Debug Messages |
| #ifdef DIVERSE_DEBUG_ENABLE |
| struct DiversityDbg diversity_dbg; |
| #endif |
| }; |
| |
| // Initialization of the function/struct, input parameters struct consists of: |
| // min_num_diverse_vectors -> sets the gate for a minimum number of data points |
| // in the memory |
| // max_num_max_distance -> sets the value for a max distance violation number |
| // gate. |
| // var_threshold -> is a threshold value for a Norm variance gate. |
| // max_min_threshold -> is a value for a gate that rejects Norm variations |
| // that are larger than this number. |
| // local_field -> is the assumed local_field (radius of the sphere). |
| // threshold_tuning_param -> threshold tuning parameter used to calculate |
| // threshold (k_algo). |
| // max_distance_tuning_param -> Max distance tuning parameter used to calculate |
| // max_distance. |
| void diversityCheckerInit(struct DiversityChecker* diverse_data, |
| const struct DiversityCheckerParameters* parameters); |
| |
| // Resetting the memory and the counters, leaves threshold and max_distance |
| // as well as the setup variables for NormQuality check untouched. |
| void diversityCheckerReset(struct DiversityChecker* diverse_data); |
| |
| // Checks if data point (x, y, z) is diverse against the diverse_data set. |
| // Returns true when the input point is diverse. |
| // Returns false when a maximum distance check is violated. |
| bool diversityCheckerFindNearestPoint(struct DiversityChecker* diverse_data, |
| float x, float y, float z); |
| |
| // Main function. Tests the data (x,y,z) against the memory if diverse and |
| // stores it, if so. |
| void diversityCheckerUpdate(struct DiversityChecker* diverse_data, float x, |
| float y, float z); |
| |
| // Removing a constant bias from the diverse_data and check if the norm is |
| // within a defined bound: |
| // implemented 4 gates |
| // -> needs a minimum number of data points in the memory |
| // (controlled by min_num_divers_vectors). |
| // -> will return false if maximum number of max_distance is reached |
| // (controlled by max_num_max_distance). |
| // -> norm must be within a var window. |
| // -> norm must be within a MAX/MIN window. |
| // Returned value will only be true if all 4 gates are passed. |
| bool diversityCheckerNormQuality(struct DiversityChecker* diverse_data, |
| float x_bias, float y_bias, float z_bias); |
| |
| // This function updates the threshold value and max distance value based on the |
| // local field. This ensures a local field independent operation of the |
| // diversity checker. |
| // |
| // threshold = (threshold_tuning_param * local_field)^2 |
| // max_distance = (max_distance_tuning_param * local_field)^2 |
| void diversityCheckerLocalFieldUpdate(struct DiversityChecker* diverse_data, |
| float local_field); |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_DIVERSITY_CHECKER_DIVERSITY_CHECKER_H_ |