Ellipsoid Fit Implementation
This script aims to implement the ellipsoid fit method proposed in [1] to develop a method for magnetic compass calibration. As the algebraic analysis presented in section (IV) of the paper is not enough for the direct implementation, we will take the algebraic analysis further for the straightforward Python implementation.
[1] Liu, Y. X., Li, X. S., Zhang, X. J., & Feng, Y. B. (2014). Novel calibration algorithm for a three-axis strapdown magnetometer. Sensors, 14(5), 8485-8504.
Magnetic Calibration method
The measurement of a magnetic compass can be modeled as:
Where \(b\) is a constant offset that shifts the output of the sensors, and \(M\) accounts for the the sensitivity of the individual axes of the sensor, the non-orthogonality and misalignment of the axes, and the sum of soft-iron errors fixed to the body frame, which serves to scale the sensor's output.
When the magnetic compass remains stationary and only changes direction, the magnitude of the true magnetic field \(||h^b||\) remains constant, and the locus of the true magnetic field measured \(h^b\) is a sphere. Meanwhile, the locus of the disturbed magnetic field measured \(h_m^b\) is an ellipsoid, and it can be expressed as follows:
Where \(A = G^TG\), \(G = M^{-1}\), and \(\tilde{n} = 2(h_m^b-b)^TG^TGn + n^TG^TGn\). We can see that this is the expression of an ellipsoid in terms of \(h_m^b\). In other words, the measurements \((h_m^b)\) with errors are constrained to lie on an ellipsoid. Thus, the calibration of the magnetic compass is to seek ellipsoid-fitting methods to solve the coefficients of \(G\) and \(b\).
Since an ellipsoid is a kind of concoid, the ellipsoid equation can be expressed as a general equation of a concoid in the 3-D space as follows:
Where \(a = \begin{bmatrix} a && b && c && d && e && j && p && q && r && s\end{bmatrix}^T\). Moreover, the problem of fitting an ellipsoid into N data points \(h_m^b\) can be solved by minimizing the sum of squares of the algebraic distance:
We define the design matrix (we will use the notation \(h_j^i\) to denote the i-th sample of \(h_{mj}^b\)), where the i-th row is:
An additional property of the design matrix is that (S^TS) is symmetric:
Now, the minimization problem can be presented as:
In order to avoid the trivial solution \(a = \mathbb{O}_{10}\), and recognizing that any multiple of a solution \(a\) represents the same concoid, the parameter vector \(a\) is constrained in someway. In order that the surface is fitted to be an ellipsoid in 3D, the parameters \(a\) must insure the matrix \(A\) to be either positive or negative definite, the equivalent constrained condition is:
The imposition of this inequality constraint is difficult in general; in this case, we have the freedom to arbitrarily scale the parameters, so we may simply incorporate the scaling into the constraint and impose the equality constraint \(\(4ac - b^2 = 1\)\), which can be expressed in the matrix form of \(a^TCa = 1\), as:
Notice that as \(C\) is a block matrix, \(C_1 = C_1^T\), and all the other blocks are zeros:
With this additional constraint, the optimization problem is:
Using the Lagrange method:
Differentiating with respect to \(a\) we find:
To solve this system, we can rewrite the matrix \(S^TS\) as a block matrix:
Furthermore, Using the definition that \(S^TS\) is symmetric, then: \(X_{21} = X_{12}^T\):
We can also define: \(a_1 = \begin{bmatrix} a && b && c\end{bmatrix}^T\) and \(a_2 = \begin{bmatrix} d && e && j && p && q && r && s\end{bmatrix}^T\), such that: \(a = \begin{bmatrix} a_1 && a_2\end{bmatrix}^T\). Now, we can rewrite the system as:
Considering that \(C_2, C_3, C_4\) are zero matrices, the first equation that we can get from this is:
The second equation is:
If the data is not coplanar, the \(X_{22}\) will be non-singular:
Replacing this term in the first equation, and considering that \(C_1\) is non-singular as \(det(C_1) = 4\):
It is proven that exactly one eigenvalue of the last system is positive. Let \(u_1\) be the eigenvector associated with the only positive eigenvalue of the general system, then we can get the full solution: \(u = \begin{bmatrix} u_1 && u_2\end{bmatrix}^T\). In the case that the matrix \((X_{11} - X_{12}X_{22}^{-1}X_{12}^T)\) is singular, the corresponding \(u_1\) can be replaced with the eigenvector associated with the largest eigenvalue.
With the previously defined equations, we are able to determine the values of: \(a = \begin{bmatrix} a && b && c && d && e && j && p && q && r && s\end{bmatrix}^T\), and with those values we need to recover the soft-iron and hard-iron, \(M\) and \(b\), respectively. By definition:
Soft-Iron
And we also defined that: \(G^TG = A\), with \(G = M^{-1}\). However, there are uncountable matrices \(G\) which can satisfy \(G^TG = A\). Thus, we select the x-axis of the sensors as the x-axis of the magnetic compass; thus we can obtain the unique \(G\) by singular value decomposition.
As A is a symmetric matrix, then: \(A^T = A \; \rightarrow \; G^TG = GG^T\).
If we do the singular value decomposition of A:
Then, as \(A\) is a symmetric matrix, then: \(U = V\), therefore:
Then:
Hard-Iron
From the magnetic field magnitude we found that:
The first term of that equation is related to the quadratic terms, while the second term is related to the linear terms:
From the general equation of a concoid in the 3-D space, the linear terms are:
Therefore, we have the system:
MAGYC - Benchmark Methods - Ellipsoid Fit
This module contains ellipsoid fit appraches for magnetometer calibration.
Functions:
Name | Description |
---|---|
ellipsoid_fit |
Standard ellipsoid fit method. |
ellipsoid_fit_fang |
Ellipsoid fit method by Fang et al. |
ellipsoid_fit(magnetic_field)
The ellipsoid fit method is based on the fact that the error model of a magnetic compass is an ellipsoid, and a constraint least-squares method is adopted to estimate the parameters of an ellipsoid by rotating the magnetic compass in various random orientations.
For further details about the implementation, refer to Aleksandr Bazhin Github repository, where he ports to python [matlab's ellipsoid fit].(http://www.mathworks.com/matlabcentral/fileexchange/24693-ellipsoid-fit)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
magnetic_field |
ndarray or list
|
Magnetic field measurements in a 3xN or Nx3 numpy array or list. |
required |
Returns:
Name | Type | Description |
---|---|---|
hard_iron |
ndarray
|
Hard iron bias. |
soft_iron |
ndarray
|
Soft iron matrix. |
calibrated_magnetic_field |
ndarray
|
Calibrated magnetic field measurements. |
Raises:
Type | Description |
---|---|
TypeError
|
If the input is not a numpy array or a list. |
ValueError
|
If the input is not a 3xN or Nx3 numpy array. |
Source code in magyc/benchmark_methods/ellipsoidfit.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
ellipsoid_fit_fang(magnetic_field)
The ellipsoid fit method is based on the fact that the error model of a magnetic compass is an ellipsoid, and a constraint least-squares method is adopted to estimate the parameters of an ellipsoid by rotating the magnetic compass in various random orientations.
For further details about the implementation, refer to section (III) in J. Fang, H. Sun, J. Cao, X. Zhang, and Y. Tao, “A novel calibration method of magnetic compass based on ellipsoid fitting,” IEEE Transactions on Instrumentation and Measurement, vol. 60, no. 6, pp. 2053--2061, 2011.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
magnetic_field |
ndarray or list
|
Magnetic field measurements in a 3xN or Nx3 numpy array or list. |
required |
Returns:
Name | Type | Description |
---|---|---|
hard_iron |
ndarray
|
Hard iron bias. |
soft_iron |
ndarray
|
Soft iron matrix. |
calibrated_magnetic_field |
ndarray
|
Calibrated magnetic field measurements. |
Raises:
Type | Description |
---|---|
TypeError
|
If the input is not a numpy array or a list. |
ValueError
|
If the input is not a 3xN or Nx3 numpy array. |
RuntimeWarning
|
If no positive eigenvalues are found. |
Source code in magyc/benchmark_methods/ellipsoidfit.py
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
|