summaryrefslogtreecommitdiff
path: root/firmware/os/algos/calibration/common/sphere_fit_calibration.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/os/algos/calibration/common/sphere_fit_calibration.h')
-rw-r--r--firmware/os/algos/calibration/common/sphere_fit_calibration.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/firmware/os/algos/calibration/common/sphere_fit_calibration.h b/firmware/os/algos/calibration/common/sphere_fit_calibration.h
new file mode 100644
index 00000000..e49f225a
--- /dev/null
+++ b/firmware/os/algos/calibration/common/sphere_fit_calibration.h
@@ -0,0 +1,143 @@
+/*
+ * 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 module contains an algorithm for performing a sphere fit calibration.
+ * A sphere fit calibration solves the following non-linear least squares
+ * problem:
+ *
+ * arg min || ||M(x - b)|| - exp_norm ||
+ * M,b
+ *
+ * where:
+ * x is a 3xN matrix containing N 3-dimensional uncalibrated data points,
+ * M is a 3x3 lower diagonal scaling matrix
+ * b is a 3x1 offset vector.
+ * exp_norm is the expected norm of an individual calibration data point.
+ * M and b are solved such that the norm of the calibrated data (M(x - b)) is
+ * near exp_norm.
+ *
+ * This module uses a Levenberg-Marquardt nonlinear least squares solver to find
+ * M and b. M is assumed to be a lower diagonal, consisting of 6 parameters.
+ *
+ */
+#ifndef LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_COMMON_SPHERE_FIT_CALIBRATION_H_
+#define LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_COMMON_SPHERE_FIT_CALIBRATION_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "calibration/common/calibration_data.h"
+#include "common/math/levenberg_marquardt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MIN_NUM_SPHERE_FIT_POINTS (14)
+
+// Enum defining the meaning of the state parameters. The 9-parameter
+// sphere fit calibration computes a lower-diagonal scaling matrix (M) and
+// an offset such that:
+// x_corrected = M * (x_impaired - offset)
+enum SphereFitParams {
+ eParamScaleMatrix11 = 0,
+ eParamScaleMatrix21,
+ eParamScaleMatrix22,
+ eParamScaleMatrix31,
+ eParamScaleMatrix32,
+ eParamScaleMatrix33,
+ eParamOffset1,
+ eParamOffset2,
+ eParamOffset3,
+ SF_STATE_DIM
+};
+
+// Structure containing the data to be used for the sphere fit calibration.
+struct SphereFitData {
+ // Data for fit (assumed to be a matrix of size num_fit_points x SF_DATA_DIM)
+ const float *fit_data;
+
+ // Pointer to standard deviations of the fit data, used to weight individual
+ // data points. Assumed to point to a matrix of dimensions
+ // num_fit_points x THREE_AXIS_DIM.
+ // If NULL, data will all be used with equal weighting in the fit.
+ const float *fit_data_std;
+
+ // Number of fit points.
+ size_t num_fit_points;
+
+ // Expected data norm.
+ float expected_norm;
+};
+
+// Structure for a sphere fit calibration, including a non-linear least squares
+// solver and the latest state estimate.
+struct SphereFitCal {
+ // Levenberg-Marquardt solver.
+ struct LmSolver lm_solver;
+
+ // Minimum number of points for computing a calibration.
+ size_t min_points_for_cal;
+
+ // State estimate.
+ float x[SF_STATE_DIM];
+ uint64_t estimate_time_nanos;
+
+ // Initial state for solver.
+ float x0[SF_STATE_DIM];
+};
+
+// Initialize sphere fit calibration structure with solver and fit params.
+void sphereFitInit(struct SphereFitCal *sphere_cal,
+ const struct LmParams *lm_params,
+ const size_t min_num_points_for_cal);
+
+// Clears state estimate and initial state.
+void sphereFitReset(struct SphereFitCal *sphere_cal);
+
+// Sets data pointer for single solve of the Levenberg-Marquardt solver.
+// Must be called before calling sphereFitRunCal().
+void sphereFitSetSolverData(struct SphereFitCal *sphere_cal,
+ struct LmData *lm_data);
+
+// Sends in a set of calibration data and attempts to run calibration.
+// Returns true if a calibration was successfully triggered with this data.
+bool sphereFitRunCal(struct SphereFitCal *sphere_cal,
+ const struct SphereFitData *data,
+ uint64_t timestamp_nanos);
+
+// Set an initial condition for the bias state.
+void sphereFitSetInitialBias(struct SphereFitCal *sphere_cal,
+ const float initial_bias[THREE_AXIS_DIM]);
+
+// Returns the latest calibration data in a ThreeAxisCalData structure.
+void sphereFitGetLatestCal(const struct SphereFitCal *sphere_cal,
+ struct ThreeAxisCalData *cal_data);
+
+///////////////// TEST UTILITIES ///////////////////////////////////////////
+// The following functions are exposed in the header for testing only.
+
+// The ResidualAndJacobianFunction for sphere calibration in the
+// Levenberg-Marquardt solver.
+void sphereFitResidAndJacobianFunc(const float *state, const void *f_data,
+ float *residual, float *jacobian);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LOCATION_LBS_CONTEXTHUB_NANOAPPS_CALIBRATION_COMMON_SPHERE_FIT_CALIBRATION_H_