View Javadoc
1   /*
2    * Copyright (C) 2020 Alberto Irurueta Carro (alberto@irurueta.com)
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  package com.irurueta.navigation.inertial.calibration.accelerometer;
17  
18  import com.irurueta.algebra.AlgebraException;
19  import com.irurueta.algebra.Matrix;
20  import com.irurueta.algebra.Utils;
21  import com.irurueta.algebra.WrongSizeException;
22  import com.irurueta.navigation.LockedException;
23  import com.irurueta.navigation.NotReadyException;
24  import com.irurueta.navigation.frames.ECEFPosition;
25  import com.irurueta.navigation.frames.ECEFVelocity;
26  import com.irurueta.navigation.frames.NEDPosition;
27  import com.irurueta.navigation.frames.NEDVelocity;
28  import com.irurueta.navigation.frames.converters.ECEFtoNEDPositionVelocityConverter;
29  import com.irurueta.navigation.frames.converters.NEDtoECEFPositionVelocityConverter;
30  import com.irurueta.navigation.inertial.BodyKinematics;
31  import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanInitializerConfig;
32  import com.irurueta.navigation.inertial.INSTightlyCoupledKalmanInitializerConfig;
33  import com.irurueta.navigation.inertial.calibration.AccelerationTriad;
34  import com.irurueta.navigation.inertial.calibration.AccelerometerBiasUncertaintySource;
35  import com.irurueta.navigation.inertial.calibration.AccelerometerCalibrationSource;
36  import com.irurueta.navigation.inertial.calibration.CalibrationException;
37  import com.irurueta.navigation.inertial.calibration.StandardDeviationBodyKinematics;
38  import com.irurueta.navigation.inertial.estimators.ECEFGravityEstimator;
39  import com.irurueta.numerical.robust.InliersData;
40  import com.irurueta.numerical.robust.RobustEstimatorMethod;
41  import com.irurueta.units.Acceleration;
42  import com.irurueta.units.AccelerationConverter;
43  import com.irurueta.units.AccelerationUnit;
44  
45  import java.util.ArrayList;
46  import java.util.List;
47  
48  /**
49   * This is an abstract class to robustly estimate accelerometer biases,
50   * cross couplings and scaling factors.
51   * <p>
52   * To use this calibrator at least 10 measurements taken at a single known position must
53   * be taken at 10 different unknown orientations and zero velocity when common z-axis
54   * is assumed, otherwise at least 13 measurements are required.
55   * <p>
56   * Measured specific force is assumed to follow the model shown below:
57   * <pre>
58   *     fmeas = ba + (I + Ma) * ftrue + w
59   * </pre>
60   * Where:
61   * - fmeas is the measured specific force. This is a 3x1 vector.
62   * - ba is accelerometer bias. Ideally, on a perfect accelerometer, this should be a
63   * 3x1 zero vector.
64   * - I is the 3x3 identity matrix.
65   * - Ma is the 3x3 matrix containing cross-couplings and scaling factors. Ideally, on
66   * a perfect accelerometer, this should be a 3x3 zero matrix.
67   * - ftrue is ground-truth specific force.
68   * - w is measurement noise.
69   */
70  public abstract class RobustKnownPositionAccelerometerCalibrator implements
71          AccelerometerNonLinearCalibrator, UnknownBiasNonLinearAccelerometerCalibrator, AccelerometerCalibrationSource,
72          AccelerometerBiasUncertaintySource, OrderedStandardDeviationBodyKinematicsAccelerometerCalibrator,
73          QualityScoredAccelerometerCalibrator {
74      /**
75       * Indicates whether by default a common z-axis is assumed for both the accelerometer
76       * and gyroscope.
77       */
78      public static final boolean DEFAULT_USE_COMMON_Z_AXIS = false;
79  
80      /**
81       * Required minimum number of measurements when common z-axis is assumed.
82       */
83      public static final int MINIMUM_MEASUREMENTS_COMMON_Z_AXIS =
84              BaseGravityNormAccelerometerCalibrator.MINIMUM_MEASUREMENTS_COMMON_Z_AXIS;
85  
86      /**
87       * Required minimum number of measurements for the general case.
88       */
89      public static final int MINIMUM_MEASUREMENTS_GENERAL =
90              BaseGravityNormAccelerometerCalibrator.MINIMUM_MEASUREMENTS_GENERAL;
91  
92      /**
93       * Default robust estimator method when none is provided.
94       */
95      public static final RobustEstimatorMethod DEFAULT_ROBUST_METHOD = RobustEstimatorMethod.LMEDS;
96  
97      /**
98       * Indicates that result is refined by default.
99       */
100     public static final boolean DEFAULT_REFINE_RESULT = true;
101 
102     /**
103      * Indicates that covariance is kept by default after refining result.
104      */
105     public static final boolean DEFAULT_KEEP_COVARIANCE = true;
106 
107     /**
108      * Default amount of progress variation before notifying a change in estimation progress.
109      * By default this is set to 5%.
110      */
111     public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
112 
113     /**
114      * Minimum allowed value for progress delta.
115      */
116     public static final float MIN_PROGRESS_DELTA = 0.0f;
117 
118     /**
119      * Maximum allowed value for progress delta.
120      */
121     public static final float MAX_PROGRESS_DELTA = 1.0f;
122 
123     /**
124      * Constant defining default confidence of the estimated result, which is
125      * 99%. This means that with a probability of 99% estimation will be
126      * accurate because chosen sub-samples will be inliers.
127      */
128     public static final double DEFAULT_CONFIDENCE = 0.99;
129 
130     /**
131      * Default maximum allowed number of iterations.
132      */
133     public static final int DEFAULT_MAX_ITERATIONS = 5000;
134 
135     /**
136      * Minimum allowed confidence value.
137      */
138     public static final double MIN_CONFIDENCE = 0.0;
139 
140     /**
141      * Maximum allowed confidence value.
142      */
143     public static final double MAX_CONFIDENCE = 1.0;
144 
145     /**
146      * Minimum allowed number of iterations.
147      */
148     public static final int MIN_ITERATIONS = 1;
149 
150     /**
151      * Contains a list of body kinematics measurements taken at a
152      * given position with different unknown orientations and containing the
153      * standard deviations of accelerometer and gyroscope measurements.
154      */
155     protected List<StandardDeviationBodyKinematics> measurements;
156 
157     /**
158      * Listener to be notified of events such as when calibration starts, ends or its
159      * progress significantly changes.
160      */
161     protected RobustKnownPositionAccelerometerCalibratorListener listener;
162 
163     /**
164      * Indicates whether calibrator is running.
165      */
166     protected boolean running;
167 
168     /**
169      * Amount of progress variation before notifying a progress change during calibration.
170      */
171     protected float progressDelta = DEFAULT_PROGRESS_DELTA;
172 
173     /**
174      * Amount of confidence expressed as a value between 0.0 and 1.0 (which is equivalent
175      * to 100%). The amount of confidence indicates the probability that the estimated
176      * result is correct. Usually this value will be close to 1.0, but not exactly 1.0.
177      */
178     protected double confidence = DEFAULT_CONFIDENCE;
179 
180     /**
181      * Maximum allowed number of iterations. When the maximum number of iterations is
182      * exceeded, result will not be available, however an approximate result will be
183      * available for retrieval.
184      */
185     protected int maxIterations = DEFAULT_MAX_ITERATIONS;
186 
187     /**
188      * Data related to inliers found after calibration.
189      */
190     protected InliersData inliersData;
191 
192     /**
193      * Indicates whether result must be refined using a non linear calibrator over
194      * found inliers.
195      * If true, inliers will be computed and kept in any implementation regardless of the
196      * settings.
197      */
198     protected boolean refineResult = DEFAULT_REFINE_RESULT;
199 
200     /**
201      * Size of subsets to be checked during robust estimation.
202      */
203     protected int preliminarySubsetSize = MINIMUM_MEASUREMENTS_GENERAL;
204 
205     /**
206      * This flag indicates whether z-axis is assumed to be common for accelerometer
207      * and gyroscope.
208      * When enabled, this eliminates 3 variables from Ma matrix.
209      */
210     private boolean commonAxisUsed = DEFAULT_USE_COMMON_Z_AXIS;
211 
212     /**
213      * Initial x-coordinate of accelerometer bias to be used to find a solution.
214      * This is expressed in meters per squared second (m/s^2).
215      */
216     private double initialBiasX;
217 
218     /**
219      * Initial y-coordinate of accelerometer bias to be used to find a solution.
220      * This is expressed in meters per squared second (m/s^2).
221      */
222     private double initialBiasY;
223 
224     /**
225      * Initial z-coordinate of accelerometer bias to be used to find a solution.
226      * This is expressed in meters per squared second (m/s^2).
227      */
228     private double initialBiasZ;
229 
230     /**
231      * Initial x scaling factor.
232      */
233     private double initialSx;
234 
235     /**
236      * Initial y scaling factor.
237      */
238     private double initialSy;
239 
240     /**
241      * Initial z scaling factor.
242      */
243     private double initialSz;
244 
245     /**
246      * Initial x-y cross coupling error.
247      */
248     private double initialMxy;
249 
250     /**
251      * Initial x-z cross coupling error.
252      */
253     private double initialMxz;
254 
255     /**
256      * Initial y-x cross coupling error.
257      */
258     private double initialMyx;
259 
260     /**
261      * Initial y-z cross coupling error.
262      */
263     private double initialMyz;
264 
265     /**
266      * Initial z-x cross coupling error.
267      */
268     private double initialMzx;
269 
270     /**
271      * Initial z-y cross coupling error.
272      */
273     private double initialMzy;
274 
275     /**
276      * Position where body kinematics measures have been taken.
277      */
278     private ECEFPosition position;
279 
280     /**
281      * Estimated accelerometer biases for each IMU axis expressed in meter per squared
282      * second (m/s^2).
283      */
284     private double[] estimatedBiases;
285 
286     /**
287      * Estimated accelerometer scale factors and cross coupling errors.
288      * This is the product of matrix Ta containing cross coupling errors and Ka
289      * containing scaling factors.
290      * So tat:
291      * <pre>
292      *     Ma = [sx    mxy  mxz] = Ta*Ka
293      *          [myx   sy   myz]
294      *          [mzx   mzy  sz ]
295      * </pre>
296      * Where:
297      * <pre>
298      *     Ka = [sx 0   0 ]
299      *          [0  sy  0 ]
300      *          [0  0   sz]
301      * </pre>
302      * and
303      * <pre>
304      *     Ta = [1          -alphaXy    alphaXz ]
305      *          [alphaYx    1           -alphaYz]
306      *          [-alphaZx   alphaZy     1       ]
307      * </pre>
308      * Hence:
309      * <pre>
310      *     Ma = [sx    mxy  mxz] = Ta*Ka =  [sx             -sy * alphaXy   sz * alphaXz ]
311      *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
312      *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
313      * </pre>
314      * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
315      * are considered to be zero if the accelerometer z-axis is assumed to be the same
316      * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Ma matrix
317      * becomes upper diagonal:
318      * <pre>
319      *     Ma = [sx    mxy  mxz]
320      *          [0     sy   myz]
321      *          [0     0    sz ]
322      * </pre>
323      * Values of this matrix are unit-less.
324      */
325     private Matrix estimatedMa;
326 
327     /**
328      * Indicates whether covariance must be kept after refining result.
329      * This setting is only taken into account if result is refined.
330      */
331     private boolean keepCovariance = DEFAULT_KEEP_COVARIANCE;
332 
333     /**
334      * Estimated covariance of estimated position.
335      * This is only available when result has been refined and covariance is kept.
336      */
337     private Matrix estimatedCovariance;
338 
339     /**
340      * Estimated chi square value.
341      */
342     private double estimatedChiSq;
343 
344     /**
345      * Estimated mean square error respect to provided measurements.
346      */
347     private double estimatedMse;
348 
349     /**
350      * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
351      * minus the number of estimated parameters.
352      */
353     private int estimatedChiSqDegreesOfFreedom;
354 
355     /**
356      * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
357      * freedom. Ideally this value should be close to 1.0.
358      */
359     private double estimatedReducedChiSq;
360 
361     /**
362      * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
363      * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
364      * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
365      */
366     private double estimatedP;
367 
368     /**
369      * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
370      * the better the fit that has been estimated.
371      */
372     private double estimatedQ;
373 
374     /**
375      * Inner calibrator to compute calibration for each subset of data or during
376      * final refining.
377      */
378     private final KnownPositionAccelerometerCalibrator innerCalibrator = new KnownPositionAccelerometerCalibrator();
379 
380     /**
381      * Contains gravity norm for current position to be reused during calibration.
382      */
383     protected double gravityNorm;
384 
385     /**
386      * Contains 3x3 identify to be reused.
387      */
388     protected Matrix identity;
389 
390     /**
391      * Contains 3x3 temporary matrix.
392      */
393     protected Matrix tmp1;
394 
395     /**
396      * Contains 3x3 temporary matrix.
397      */
398     protected Matrix tmp2;
399 
400     /**
401      * Contains 3x1 temporary matrix.
402      */
403     protected Matrix tmp3;
404 
405     /**
406      * Contains 3x1 temporary matrix.
407      */
408     protected Matrix tmp4;
409 
410     /**
411      * Constructor.
412      */
413     protected RobustKnownPositionAccelerometerCalibrator() {
414     }
415 
416     /**
417      * Constructor.
418      *
419      * @param listener listener to be notified of events such as when estimation
420      *                 starts, ends or its progress significantly changes.
421      */
422     protected RobustKnownPositionAccelerometerCalibrator(
423             final RobustKnownPositionAccelerometerCalibratorListener listener) {
424         this.listener = listener;
425     }
426 
427     /**
428      * Constructor.
429      *
430      * @param measurements collection of body kinematics measurements with standard
431      *                     deviations taken at the same position with zero velocity
432      *                     and unknown different orientations.
433      */
434     protected RobustKnownPositionAccelerometerCalibrator(final List<StandardDeviationBodyKinematics> measurements) {
435         this.measurements = measurements;
436     }
437 
438 
439     /**
440      * Constructor.
441      *
442      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
443      *                       accelerometer and gyroscope.
444      */
445     protected RobustKnownPositionAccelerometerCalibrator(final boolean commonAxisUsed) {
446         this.commonAxisUsed = commonAxisUsed;
447     }
448 
449     /**
450      * Constructor.
451      *
452      * @param initialBias initial accelerometer bias to be used to find a solution.
453      *                    This must have length 3 and is expressed in meters per
454      *                    squared second (m/s^2).
455      * @throws IllegalArgumentException if provided bias array does not have length 3.
456      */
457     protected RobustKnownPositionAccelerometerCalibrator(final double[] initialBias) {
458         try {
459             setInitialBias(initialBias);
460         } catch (final LockedException ignore) {
461             // never happens
462         }
463     }
464 
465     /**
466      * Constructor.
467      *
468      * @param initialBias initial bias to find a solution.
469      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
470      */
471     protected RobustKnownPositionAccelerometerCalibrator(final Matrix initialBias) {
472         try {
473             setInitialBias(initialBias);
474         } catch (final LockedException ignore) {
475             // never happens
476         }
477     }
478 
479     /**
480      * Constructor.
481      *
482      * @param initialBias initial bias to find a solution.
483      * @param initialMa   initial scale factors and cross coupling errors matrix.
484      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
485      *                                  scaling and coupling error matrix is not 3x3.
486      */
487     protected RobustKnownPositionAccelerometerCalibrator(final Matrix initialBias, final Matrix initialMa) {
488         this(initialBias);
489         try {
490             setInitialMa(initialMa);
491         } catch (final LockedException ignore) {
492             // never happens
493         }
494     }
495 
496     /**
497      * Constructor.
498      *
499      * @param position position where body kinematics measures have been taken.
500      */
501     protected RobustKnownPositionAccelerometerCalibrator(final ECEFPosition position) {
502         this.position = position;
503     }
504 
505     /**
506      * Constructor.
507      *
508      * @param position     position where body kinematics measures have been taken.
509      * @param measurements list of body kinematics measurements taken at a given position with
510      *                     different unknown orientations and containing the standard deviations
511      *                     of accelerometer and gyroscope measurements.
512      */
513     protected RobustKnownPositionAccelerometerCalibrator(
514             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements) {
515         this(measurements);
516         this.position = position;
517     }
518 
519     /**
520      * Constructor.
521      *
522      * @param position     position where body kinematics measures have been taken.
523      * @param measurements list of body kinematics measurements taken at a given position with
524      *                     different unknown orientations and containing the standard deviations
525      *                     of accelerometer and gyroscope measurements.
526      * @param listener     listener to be notified of events such as when estimation
527      *                     starts, ends or its progress significantly changes.
528      */
529     protected RobustKnownPositionAccelerometerCalibrator(
530             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
531             final RobustKnownPositionAccelerometerCalibratorListener listener) {
532         this(measurements);
533         this.position = position;
534         this.listener = listener;
535     }
536 
537     /**
538      * Constructor.
539      *
540      * @param position       position where body kinematics measures have been taken.
541      * @param measurements   list of body kinematics measurements taken at a given position with
542      *                       different unknown orientations and containing the standard deviations
543      *                       of accelerometer and gyroscope measurements.
544      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
545      *                       accelerometer and gyroscope.
546      */
547     protected RobustKnownPositionAccelerometerCalibrator(
548             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
549             final boolean commonAxisUsed) {
550         this(measurements);
551         this.position = position;
552         this.commonAxisUsed = commonAxisUsed;
553     }
554 
555     /**
556      * Constructor.
557      *
558      * @param position       position where body kinematics measures have been taken.
559      * @param measurements   list of body kinematics measurements taken at a given position with
560      *                       different unknown orientations and containing the standard deviations
561      *                       of accelerometer and gyroscope measurements.
562      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
563      *                       accelerometer and gyroscope.
564      * @param listener       listener to be notified of events such as when estimation
565      *                       starts, ends or its progress significantly changes.
566      */
567     protected RobustKnownPositionAccelerometerCalibrator(
568             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
569             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener) {
570         this(position, measurements, commonAxisUsed);
571         this.listener = listener;
572     }
573 
574     /**
575      * Constructor.
576      *
577      * @param position     position where body kinematics measures have been taken.
578      * @param measurements collection of body kinematics measurements with standard
579      *                     deviations taken at the same position with zero velocity
580      *                     and unknown different orientations.
581      * @param initialBias  initial accelerometer bias to be used to find a solution.
582      *                     This must have length 3 and is expressed in meters per
583      *                     squared second (m/s^2).
584      * @throws IllegalArgumentException if provided bias array does not have length 3.
585      */
586     protected RobustKnownPositionAccelerometerCalibrator(
587             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
588             final double[] initialBias) {
589         this(initialBias);
590         this.position = position;
591         this.measurements = measurements;
592     }
593 
594     /**
595      * Constructor.
596      *
597      * @param position     position where body kinematics measures have been taken.
598      * @param measurements collection of body kinematics measurements with standard
599      *                     deviations taken at the same position with zero velocity
600      *                     and unknown different orientations.
601      * @param initialBias  initial accelerometer bias to be used to find a solution.
602      *                     This must have length 3 and is expressed in meters per
603      *                     squared second (m/s^2).
604      * @param listener     listener to handle events raised by this calibrator.
605      * @throws IllegalArgumentException if provided bias array does not have length 3.
606      */
607     protected RobustKnownPositionAccelerometerCalibrator(
608             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
609             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
610         this(position, measurements, initialBias);
611         this.listener = listener;
612     }
613 
614     /**
615      * Constructor.
616      *
617      * @param position       position where body kinematics measures have been taken.
618      * @param measurements   collection of body kinematics measurements with standard
619      *                       deviations taken at the same position with zero velocity
620      *                       and unknown different orientations.
621      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
622      *                       accelerometer and gyroscope.
623      * @param initialBias    initial accelerometer bias to be used to find a solution.
624      *                       This must have length 3 and is expressed in meters per
625      *                       squared second (m/s^2).
626      * @throws IllegalArgumentException if provided bias array does not have length 3.
627      */
628     protected RobustKnownPositionAccelerometerCalibrator(
629             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
630             final boolean commonAxisUsed, final double[] initialBias) {
631         this(position, measurements, initialBias);
632         this.commonAxisUsed = commonAxisUsed;
633     }
634 
635     /**
636      * Constructor.
637      *
638      * @param position       position where body kinematics measures have been taken.
639      * @param measurements   collection of body kinematics measurements with standard
640      *                       deviations taken at the same position with zero velocity
641      *                       and unknown different orientations.
642      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
643      *                       accelerometer and gyroscope.
644      * @param initialBias    initial accelerometer bias to be used to find a solution.
645      *                       This must have length 3 and is expressed in meters per
646      *                       squared second (m/s^2).
647      * @param listener       listener to handle events raised by this calibrator.
648      * @throws IllegalArgumentException if provided bias array does not have length 3.
649      */
650     protected RobustKnownPositionAccelerometerCalibrator(
651             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
652             final boolean commonAxisUsed, final double[] initialBias,
653             final RobustKnownPositionAccelerometerCalibratorListener listener) {
654         this(position, measurements, commonAxisUsed, initialBias);
655         this.listener = listener;
656     }
657 
658     /**
659      * Constructor.
660      *
661      * @param position     position where body kinematics measures have been taken.
662      * @param measurements collection of body kinematics measurements with standard
663      *                     deviations taken at the same position with zero velocity
664      *                     and unknown different orientations.
665      * @param initialBias  initial bias to find a solution.
666      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
667      */
668     protected RobustKnownPositionAccelerometerCalibrator(
669             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
670             final Matrix initialBias) {
671         this(initialBias);
672         this.position = position;
673         this.measurements = measurements;
674     }
675 
676     /**
677      * Constructor.
678      *
679      * @param position     position where body kinematics measures have been taken.
680      * @param measurements collection of body kinematics measurements with standard
681      *                     deviations taken at the same position with zero velocity
682      *                     and unknown different orientations.
683      * @param initialBias  initial bias to find a solution.
684      * @param listener     listener to handle events raised by this calibrator.
685      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
686      */
687     protected RobustKnownPositionAccelerometerCalibrator(
688             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
689             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
690         this(position, measurements, initialBias);
691         this.listener = listener;
692     }
693 
694     /**
695      * Constructor.
696      *
697      * @param position       position where body kinematics measures have been taken.
698      * @param measurements   collection of body kinematics measurements with standard
699      *                       deviations taken at the same position with zero velocity
700      *                       and unknown different orientations.
701      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
702      *                       accelerometer and gyroscope.
703      * @param initialBias    initial bias to find a solution.
704      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
705      */
706     protected RobustKnownPositionAccelerometerCalibrator(
707             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
708             final boolean commonAxisUsed, final Matrix initialBias) {
709         this(position, measurements, initialBias);
710         this.commonAxisUsed = commonAxisUsed;
711     }
712 
713     /**
714      * Constructor.
715      *
716      * @param position       position where body kinematics measures have been taken.
717      * @param measurements   collection of body kinematics measurements with standard
718      *                       deviations taken at the same position with zero velocity
719      *                       and unknown different orientations.
720      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
721      *                       accelerometer and gyroscope.
722      * @param initialBias    initial bias to find a solution.
723      * @param listener       listener to handle events raised by this calibrator.
724      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
725      */
726     protected RobustKnownPositionAccelerometerCalibrator(
727             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
728             final boolean commonAxisUsed, final Matrix initialBias,
729             final RobustKnownPositionAccelerometerCalibratorListener listener) {
730         this(position, measurements, commonAxisUsed, initialBias);
731         this.listener = listener;
732     }
733 
734     /**
735      * Constructor.
736      *
737      * @param position     position where body kinematics measures have been taken.
738      * @param measurements collection of body kinematics measurements with standard
739      *                     deviations taken at the same position with zero velocity
740      *                     and unknown different orientations.
741      * @param initialBias  initial bias to find a solution.
742      * @param initialMa    initial scale factors and cross coupling errors matrix.
743      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
744      *                                  scaling and coupling error matrix is not 3x3.
745      */
746     protected RobustKnownPositionAccelerometerCalibrator(
747             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
748             final Matrix initialBias, final Matrix initialMa) {
749         this(initialBias, initialMa);
750         this.position = position;
751         this.measurements = measurements;
752     }
753 
754     /**
755      * Constructor.
756      *
757      * @param position     position where body kinematics measures have been taken.
758      * @param measurements collection of body kinematics measurements with standard
759      *                     deviations taken at the same position with zero velocity
760      *                     and unknown different orientations.
761      * @param initialBias  initial bias to find a solution.
762      * @param initialMa    initial scale factors and cross coupling errors matrix.
763      * @param listener     listener to handle events raised by this calibrator.
764      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
765      *                                  scaling and coupling error matrix is not 3x3.
766      */
767     protected RobustKnownPositionAccelerometerCalibrator(
768             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
769             final Matrix initialBias, final Matrix initialMa,
770             final RobustKnownPositionAccelerometerCalibratorListener listener) {
771         this(position, measurements, initialBias, initialMa);
772         this.listener = listener;
773     }
774 
775     /**
776      * Constructor.
777      *
778      * @param position       position where body kinematics measures have been taken.
779      * @param measurements   collection of body kinematics measurements with standard
780      *                       deviations taken at the same position with zero velocity
781      *                       and unknown different orientations.
782      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
783      *                       accelerometer and gyroscope.
784      * @param initialBias    initial bias to find a solution.
785      * @param initialMa      initial scale factors and cross coupling errors matrix.
786      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
787      *                                  scaling and coupling error matrix is not 3x3.
788      */
789     protected RobustKnownPositionAccelerometerCalibrator(
790             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
791             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
792         this(position, measurements, initialBias, initialMa);
793         this.commonAxisUsed = commonAxisUsed;
794     }
795 
796     /**
797      * Constructor.
798      *
799      * @param position       position where body kinematics measures have been taken.
800      * @param measurements   collection of body kinematics measurements with standard
801      *                       deviations taken at the same position with zero velocity
802      *                       and unknown different orientations.
803      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
804      *                       accelerometer and gyroscope.
805      * @param initialBias    initial bias to find a solution.
806      * @param initialMa      initial scale factors and cross coupling errors matrix.
807      * @param listener       listener to handle events raised by this calibrator.
808      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
809      *                                  scaling and coupling error matrix is not 3x3.
810      */
811     protected RobustKnownPositionAccelerometerCalibrator(
812             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
813             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
814             final RobustKnownPositionAccelerometerCalibratorListener listener) {
815         this(position, measurements, commonAxisUsed, initialBias, initialMa);
816         this.listener = listener;
817     }
818 
819     /**
820      * Constructor.
821      *
822      * @param position position where body kinematics measures have been taken.
823      */
824     protected RobustKnownPositionAccelerometerCalibrator(final NEDPosition position) {
825         this.position = convertPosition(position);
826     }
827 
828     /**
829      * Constructor.
830      *
831      * @param position     position where body kinematics measures have been taken.
832      * @param measurements list of body kinematics measurements taken at a given position with
833      *                     different unknown orientations and containing the standard deviations
834      *                     of accelerometer and gyroscope measurements.
835      */
836     protected RobustKnownPositionAccelerometerCalibrator(
837             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements) {
838         this(convertPosition(position), measurements);
839     }
840 
841     /**
842      * Constructor.
843      *
844      * @param position     position where body kinematics measures have been taken.
845      * @param measurements list of body kinematics measurements taken at a given position with
846      *                     different unknown orientations and containing the standard deviations
847      *                     of accelerometer and gyroscope measurements.
848      * @param listener     listener to be notified of events such as when estimation
849      *                     starts, ends or its progress significantly changes.
850      */
851     protected RobustKnownPositionAccelerometerCalibrator(
852             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
853             final RobustKnownPositionAccelerometerCalibratorListener listener) {
854         this(convertPosition(position), measurements, listener);
855     }
856 
857     /**
858      * Constructor.
859      *
860      * @param position       position where body kinematics measures have been taken.
861      * @param measurements   list of body kinematics measurements taken at a given position with
862      *                       different unknown orientations and containing the standard deviations
863      *                       of accelerometer and gyroscope measurements.
864      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
865      *                       accelerometer and gyroscope.
866      */
867     protected RobustKnownPositionAccelerometerCalibrator(
868             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
869             final boolean commonAxisUsed) {
870         this(convertPosition(position), measurements, commonAxisUsed);
871     }
872 
873     /**
874      * Constructor.
875      *
876      * @param position       position where body kinematics measures have been taken.
877      * @param measurements   list of body kinematics measurements taken at a given position with
878      *                       different unknown orientations and containing the standard deviations
879      *                       of accelerometer and gyroscope measurements.
880      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
881      *                       accelerometer and gyroscope.
882      * @param listener       listener to be notified of events such as when estimation
883      *                       starts, ends or its progress significantly changes.
884      */
885     protected RobustKnownPositionAccelerometerCalibrator(
886             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
887             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener) {
888         this(convertPosition(position), measurements, commonAxisUsed, listener);
889     }
890 
891     /**
892      * Constructor.
893      *
894      * @param position     position where body kinematics measures have been taken.
895      * @param measurements collection of body kinematics measurements with standard
896      *                     deviations taken at the same position with zero velocity
897      *                     and unknown different orientations.
898      * @param initialBias  initial accelerometer bias to be used to find a solution.
899      *                     This must have length 3 and is expressed in meters per
900      *                     squared second (m/s^2).
901      * @throws IllegalArgumentException if provided bias array does not have length 3.
902      */
903     protected RobustKnownPositionAccelerometerCalibrator(
904             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
905             final double[] initialBias) {
906         this(convertPosition(position), measurements, initialBias);
907     }
908 
909     /**
910      * Constructor.
911      *
912      * @param position     position where body kinematics measures have been taken.
913      * @param measurements collection of body kinematics measurements with standard
914      *                     deviations taken at the same position with zero velocity
915      *                     and unknown different orientations.
916      * @param initialBias  initial accelerometer bias to be used to find a solution.
917      *                     This must have length 3 and is expressed in meters per
918      *                     squared second (m/s^2).
919      * @param listener     listener to handle events raised by this calibrator.
920      * @throws IllegalArgumentException if provided bias array does not have length 3.
921      */
922     protected RobustKnownPositionAccelerometerCalibrator(
923             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
924             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
925         this(convertPosition(position), measurements, initialBias, listener);
926     }
927 
928     /**
929      * Constructor.
930      *
931      * @param position       position where body kinematics measures have been taken.
932      * @param measurements   collection of body kinematics measurements with standard
933      *                       deviations taken at the same position with zero velocity
934      *                       and unknown different orientations.
935      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
936      *                       accelerometer and gyroscope.
937      * @param initialBias    initial accelerometer bias to be used to find a solution.
938      *                       This must have length 3 and is expressed in meters per
939      *                       squared second (m/s^2).
940      * @throws IllegalArgumentException if provided bias array does not have length 3.
941      */
942     protected RobustKnownPositionAccelerometerCalibrator(
943             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
944             final boolean commonAxisUsed, final double[] initialBias) {
945         this(convertPosition(position), measurements, commonAxisUsed, initialBias);
946     }
947 
948     /**
949      * Constructor.
950      *
951      * @param position       position where body kinematics measures have been taken.
952      * @param measurements   collection of body kinematics measurements with standard
953      *                       deviations taken at the same position with zero velocity
954      *                       and unknown different orientations.
955      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
956      *                       accelerometer and gyroscope.
957      * @param initialBias    initial accelerometer bias to be used to find a solution.
958      *                       This must have length 3 and is expressed in meters per
959      *                       squared second (m/s^2).
960      * @param listener       listener to handle events raised by this calibrator.
961      * @throws IllegalArgumentException if provided bias array does not have length 3.
962      */
963     protected RobustKnownPositionAccelerometerCalibrator(
964             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
965             final boolean commonAxisUsed, final double[] initialBias,
966             final RobustKnownPositionAccelerometerCalibratorListener listener) {
967         this(convertPosition(position), measurements, commonAxisUsed, initialBias, listener);
968     }
969 
970     /**
971      * Constructor.
972      *
973      * @param position     position where body kinematics measures have been taken.
974      * @param measurements collection of body kinematics measurements with standard
975      *                     deviations taken at the same position with zero velocity
976      *                     and unknown different orientations.
977      * @param initialBias  initial bias to find a solution.
978      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
979      */
980     protected RobustKnownPositionAccelerometerCalibrator(
981             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
982             final Matrix initialBias) {
983         this(convertPosition(position), measurements, initialBias);
984     }
985 
986     /**
987      * Constructor.
988      *
989      * @param position     position where body kinematics measures have been taken.
990      * @param measurements collection of body kinematics measurements with standard
991      *                     deviations taken at the same position with zero velocity
992      *                     and unknown different orientations.
993      * @param initialBias  initial bias to find a solution.
994      * @param listener     listener to handle events raised by this calibrator.
995      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
996      */
997     protected RobustKnownPositionAccelerometerCalibrator(
998             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
999             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
1000         this(convertPosition(position), measurements, initialBias, listener);
1001     }
1002 
1003     /**
1004      * Constructor.
1005      *
1006      * @param position       position where body kinematics measures have been taken.
1007      * @param measurements   collection of body kinematics measurements with standard
1008      *                       deviations taken at the same position with zero velocity
1009      *                       and unknown different orientations.
1010      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1011      *                       accelerometer and gyroscope.
1012      * @param initialBias    initial bias to find a solution.
1013      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1014      */
1015     protected RobustKnownPositionAccelerometerCalibrator(
1016             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1017             final boolean commonAxisUsed, final Matrix initialBias) {
1018         this(convertPosition(position), measurements, commonAxisUsed, initialBias);
1019     }
1020 
1021     /**
1022      * Constructor.
1023      *
1024      * @param position       position where body kinematics measures have been taken.
1025      * @param measurements   collection of body kinematics measurements with standard
1026      *                       deviations taken at the same position with zero velocity
1027      *                       and unknown different orientations.
1028      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1029      *                       accelerometer and gyroscope.
1030      * @param initialBias    initial bias to find a solution.
1031      * @param listener       listener to handle events raised by this calibrator.
1032      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1033      */
1034     protected RobustKnownPositionAccelerometerCalibrator(
1035             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1036             final boolean commonAxisUsed, final Matrix initialBias,
1037             final RobustKnownPositionAccelerometerCalibratorListener listener) {
1038         this(convertPosition(position), measurements, commonAxisUsed, initialBias, listener);
1039     }
1040 
1041     /**
1042      * Constructor.
1043      *
1044      * @param position     position where body kinematics measures have been taken.
1045      * @param measurements collection of body kinematics measurements with standard
1046      *                     deviations taken at the same position with zero velocity
1047      *                     and unknown different orientations.
1048      * @param initialBias  initial bias to find a solution.
1049      * @param initialMa    initial scale factors and cross coupling errors matrix.
1050      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1051      *                                  scaling and coupling error matrix is not 3x3.
1052      */
1053     protected RobustKnownPositionAccelerometerCalibrator(
1054             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1055             final Matrix initialBias, final Matrix initialMa) {
1056         this(convertPosition(position), measurements, initialBias, initialMa);
1057     }
1058 
1059     /**
1060      * Constructor.
1061      *
1062      * @param position     position where body kinematics measures have been taken.
1063      * @param measurements collection of body kinematics measurements with standard
1064      *                     deviations taken at the same position with zero velocity
1065      *                     and unknown different orientations.
1066      * @param initialBias  initial bias to find a solution.
1067      * @param initialMa    initial scale factors and cross coupling errors matrix.
1068      * @param listener     listener to handle events raised by this calibrator.
1069      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1070      *                                  scaling and coupling error matrix is not 3x3.
1071      */
1072     protected RobustKnownPositionAccelerometerCalibrator(
1073             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1074             final Matrix initialBias, final Matrix initialMa,
1075             final RobustKnownPositionAccelerometerCalibratorListener listener) {
1076         this(convertPosition(position), measurements, initialBias, initialMa, listener);
1077     }
1078 
1079     /**
1080      * Constructor.
1081      *
1082      * @param position       position where body kinematics measures have been taken.
1083      * @param measurements   collection of body kinematics measurements with standard
1084      *                       deviations taken at the same position with zero velocity
1085      *                       and unknown different orientations.
1086      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1087      *                       accelerometer and gyroscope.
1088      * @param initialBias    initial bias to find a solution.
1089      * @param initialMa      initial scale factors and cross coupling errors matrix.
1090      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1091      *                                  scaling and coupling error matrix is not 3x3.
1092      */
1093     protected RobustKnownPositionAccelerometerCalibrator(
1094             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1095             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
1096         this(convertPosition(position), measurements, commonAxisUsed, initialBias, initialMa);
1097     }
1098 
1099     /**
1100      * Constructor.
1101      *
1102      * @param position       position where body kinematics measures have been taken.
1103      * @param measurements   collection of body kinematics measurements with standard
1104      *                       deviations taken at the same position with zero velocity
1105      *                       and unknown different orientations.
1106      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1107      *                       accelerometer and gyroscope.
1108      * @param initialBias    initial bias to find a solution.
1109      * @param initialMa      initial scale factors and cross coupling errors matrix.
1110      * @param listener       listener to handle events raised by this calibrator.
1111      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1112      *                                  scaling and coupling error matrix is not 3x3.
1113      */
1114     protected RobustKnownPositionAccelerometerCalibrator(
1115             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
1116             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
1117             final RobustKnownPositionAccelerometerCalibratorListener listener) {
1118         this(convertPosition(position), measurements, commonAxisUsed, initialBias, initialMa, listener);
1119     }
1120 
1121     /**
1122      * Gets initial x-coordinate of accelerometer bias to be used to find a solutions.
1123      * This is expressed in meters per squared second (m/s^2) and only taken into
1124      * account if non-linear preliminary solutions are used.
1125      *
1126      * @return initial x-coordinate of accelerometer bias.
1127      */
1128     @Override
1129     public double getInitialBiasX() {
1130         return initialBiasX;
1131     }
1132 
1133     /**
1134      * Sets initial x-coordinate of accelerometer bias to be used to find a solution.
1135      * This is expressed in meters per squared second (m/s^2) and only taken into
1136      * account if non-linear preliminary solutions are used.
1137      *
1138      * @param initialBiasX initial x-coordinate of accelerometer bias.
1139      * @throws LockedException if calibrator is currently running.
1140      */
1141     @Override
1142     public void setInitialBiasX(final double initialBiasX) throws LockedException {
1143         if (running) {
1144             throw new LockedException();
1145         }
1146         this.initialBiasX = initialBiasX;
1147     }
1148 
1149     /**
1150      * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
1151      * This is expressed in meters per squared second (m/s^2) and only taken into
1152      * account if non-linear preliminary solutions are used.
1153      *
1154      * @return initial y-coordinate of accelerometer bias.
1155      */
1156     @Override
1157     public double getInitialBiasY() {
1158         return initialBiasY;
1159     }
1160 
1161     /**
1162      * Sets initial y-coordinate of accelerometer bias to be used to find a solution.
1163      * This is expressed in meters per squared second (m/s^2) and only taken into
1164      * account if non-linear preliminary solutions are used.
1165      *
1166      * @param initialBiasY initial y-coordinate of accelerometer bias.
1167      * @throws LockedException if calibrator is currently running.
1168      */
1169     @Override
1170     public void setInitialBiasY(final double initialBiasY) throws LockedException {
1171         if (running) {
1172             throw new LockedException();
1173         }
1174         this.initialBiasY = initialBiasY;
1175     }
1176 
1177     /**
1178      * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
1179      * This is expressed in meters per squared second (m/s^2) and only taken into
1180      * account if non-linear preliminary solutions are used.
1181      *
1182      * @return initial z-coordinate of accelerometer bias.
1183      */
1184     @Override
1185     public double getInitialBiasZ() {
1186         return initialBiasZ;
1187     }
1188 
1189     /**
1190      * Sets initial z-coordinate of accelerometer bias to be used to find a solution.
1191      * This is expressed in meters per squared second (m/s^2) and only taken into
1192      * account if non-linear preliminary solutions are used.
1193      *
1194      * @param initialBiasZ initial z-coordinate of accelerometer bias.
1195      * @throws LockedException if calibrator is currently running.
1196      */
1197     @Override
1198     public void setInitialBiasZ(final double initialBiasZ) throws LockedException {
1199         if (running) {
1200             throw new LockedException();
1201         }
1202         this.initialBiasZ = initialBiasZ;
1203     }
1204 
1205     /**
1206      * Gets initial x-coordinate of accelerometer bias to be used to find a solution.
1207      * This is only taken into account if non-linear preliminary solutions are used.
1208      *
1209      * @return initial x-coordinate of accelerometer bias.
1210      */
1211     @Override
1212     public Acceleration getInitialBiasXAsAcceleration() {
1213         return new Acceleration(initialBiasX, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1214     }
1215 
1216     /**
1217      * Gets initial x-coordinate of accelerometer bias to be used to find a solution.
1218      * This is only taken into account if non-linear preliminary solutions are used.
1219      *
1220      * @param result instance where result data will be stored.
1221      */
1222     @Override
1223     public void getInitialBiasXAsAcceleration(final Acceleration result) {
1224         result.setValue(initialBiasX);
1225         result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1226     }
1227 
1228     /**
1229      * Sets initial x-coordinate of accelerometer bias to be used to find a solution.
1230      * This is only taken into account if non-linear preliminary solutions are used.
1231      *
1232      * @param initialBiasX initial x-coordinate of accelerometer bias.
1233      * @throws LockedException if calibrator is currently running.
1234      */
1235     @Override
1236     public void setInitialBiasX(final Acceleration initialBiasX) throws LockedException {
1237         if (running) {
1238             throw new LockedException();
1239         }
1240         this.initialBiasX = convertAcceleration(initialBiasX);
1241     }
1242 
1243     /**
1244      * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
1245      * This is only taken into account if non-linear preliminary solutions are used.
1246      *
1247      * @return initial y-coordinate of accelerometer bias.
1248      */
1249     @Override
1250     public Acceleration getInitialBiasYAsAcceleration() {
1251         return new Acceleration(initialBiasY, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1252     }
1253 
1254     /**
1255      * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
1256      * This is only taken into account if non-linear preliminary solutions are used.
1257      *
1258      * @param result instance where result data will be stored.
1259      */
1260     @Override
1261     public void getInitialBiasYAsAcceleration(final Acceleration result) {
1262         result.setValue(initialBiasY);
1263         result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1264     }
1265 
1266     /**
1267      * Sets initial y-coordinate of accelerometer bias to be used to find a solution.
1268      * This is only taken into account if non-linear preliminary solutions are used.
1269      *
1270      * @param initialBiasY initial y-coordinate of accelerometer bias.
1271      * @throws LockedException if calibrator is currently running.
1272      */
1273     @Override
1274     public void setInitialBiasY(final Acceleration initialBiasY) throws LockedException {
1275         if (running) {
1276             throw new LockedException();
1277         }
1278         this.initialBiasY = convertAcceleration(initialBiasY);
1279     }
1280 
1281     /**
1282      * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
1283      * This is only taken into account if non-linear preliminary solutions are used.
1284      *
1285      * @return initial z-coordinate of accelerometer bias.
1286      */
1287     @Override
1288     public Acceleration getInitialBiasZAsAcceleration() {
1289         return new Acceleration(initialBiasZ, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1290     }
1291 
1292     /**
1293      * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
1294      * This is only taken into account if non-linear preliminary solutions are used.
1295      *
1296      * @param result instance where result data will be stored.
1297      */
1298     @Override
1299     public void getInitialBiasZAsAcceleration(final Acceleration result) {
1300         result.setValue(initialBiasZ);
1301         result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1302     }
1303 
1304     /**
1305      * Sets initial z-coordinate of accelerometer bias to be used to find a solution.
1306      * This is only taken into account if non-linear preliminary solutions are used.
1307      *
1308      * @param initialBiasZ initial z-coordinate of accelerometer bias.
1309      * @throws LockedException if calibrator is currently running.
1310      */
1311     @Override
1312     public void setInitialBiasZ(final Acceleration initialBiasZ) throws LockedException {
1313         if (running) {
1314             throw new LockedException();
1315         }
1316         this.initialBiasZ = convertAcceleration(initialBiasZ);
1317     }
1318 
1319     /**
1320      * Sets initial bias coordinates of accelerometer used to find a solution
1321      * expressed in meters per squared second (m/s^2).
1322      * This is only taken into account if non-linear preliminary solutions are used.
1323      *
1324      * @param initialBiasX initial x-coordinate of accelerometer bias.
1325      * @param initialBiasY initial y-coordinate of accelerometer bias.
1326      * @param initialBiasZ initial z-coordinate of accelerometer bias.
1327      * @throws LockedException if calibrator is currently running.
1328      */
1329     @Override
1330     public void setInitialBias(
1331             final double initialBiasX, final double initialBiasY, final double initialBiasZ) throws LockedException {
1332         if (running) {
1333             throw new LockedException();
1334         }
1335         this.initialBiasX = initialBiasX;
1336         this.initialBiasY = initialBiasY;
1337         this.initialBiasZ = initialBiasZ;
1338     }
1339 
1340     /**
1341      * Sets initial bias coordinates of accelerometer used to find a solution.
1342      * This is only taken into account if non-linear preliminary solutions are used.
1343      *
1344      * @param initialBiasX initial x-coordinate of accelerometer bias.
1345      * @param initialBiasY initial y-coordinate of accelerometer bias.
1346      * @param initialBiasZ initial z-coordinate of accelerometer bias.
1347      * @throws LockedException if calibrator is currently running.
1348      */
1349     @Override
1350     public void setInitialBias(
1351             final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ)
1352             throws LockedException {
1353         if (running) {
1354             throw new LockedException();
1355         }
1356         this.initialBiasX = convertAcceleration(initialBiasX);
1357         this.initialBiasY = convertAcceleration(initialBiasY);
1358         this.initialBiasZ = convertAcceleration(initialBiasZ);
1359     }
1360 
1361     /**
1362      * Gets initial bias coordinates of accelerometer used to find a solution.
1363      *
1364      * @return initial bias coordinates.
1365      */
1366     @Override
1367     public AccelerationTriad getInitialBiasAsTriad() {
1368         return new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
1369                 initialBiasX, initialBiasY, initialBiasZ);
1370     }
1371 
1372     /**
1373      * Gets initial bias coordinates of accelerometer used to find a solution.
1374      *
1375      * @param result instance where result will be stored.
1376      */
1377     @Override
1378     public void getInitialBiasAsTriad(final AccelerationTriad result) {
1379         result.setValueCoordinatesAndUnit(initialBiasX, initialBiasY, initialBiasZ,
1380                 AccelerationUnit.METERS_PER_SQUARED_SECOND);
1381     }
1382 
1383     /**
1384      * Sets initial bias coordinates of accelerometer used to find a solution.
1385      *
1386      * @param initialBias initial bias coordinates to be set.
1387      */
1388     @Override
1389     public void setInitialBias(final AccelerationTriad initialBias) {
1390         initialBiasX = convertAcceleration(initialBias.getValueX(), initialBias.getUnit());
1391         initialBiasY = convertAcceleration(initialBias.getValueY(), initialBias.getUnit());
1392         initialBiasZ = convertAcceleration(initialBias.getValueZ(), initialBias.getUnit());
1393     }
1394 
1395     /**
1396      * Gets initial x scaling factor.
1397      * This is only taken into account if non-linear preliminary solutions are used.
1398      *
1399      * @return initial x scaling factor.
1400      */
1401     @Override
1402     public double getInitialSx() {
1403         return initialSx;
1404     }
1405 
1406     /**
1407      * Sets initial x scaling factor.
1408      * This is only taken into account if non-linear preliminary solutions are used.
1409      *
1410      * @param initialSx initial x scaling factor.
1411      * @throws LockedException if calibrator is currently running.
1412      */
1413     @Override
1414     public void setInitialSx(final double initialSx) throws LockedException {
1415         if (running) {
1416             throw new LockedException();
1417         }
1418         this.initialSx = initialSx;
1419     }
1420 
1421     /**
1422      * Gets initial y scaling factor.
1423      * This is only taken into account if non-linear preliminary solutions are used.
1424      *
1425      * @return initial y scaling factor.
1426      */
1427     @Override
1428     public double getInitialSy() {
1429         return initialSy;
1430     }
1431 
1432     /**
1433      * Sets initial y scaling factor.
1434      * This is only taken into account if non-linear preliminary solutions are used.
1435      *
1436      * @param initialSy initial y scaling factor.
1437      * @throws LockedException if calibrator is currently running.
1438      */
1439     @Override
1440     public void setInitialSy(final double initialSy) throws LockedException {
1441         if (running) {
1442             throw new LockedException();
1443         }
1444         this.initialSy = initialSy;
1445     }
1446 
1447     /**
1448      * Gets initial z scaling factor.
1449      * This is only taken into account if non-linear preliminary solutions are used.
1450      *
1451      * @return initial z scaling factor.
1452      */
1453     @Override
1454     public double getInitialSz() {
1455         return initialSz;
1456     }
1457 
1458     /**
1459      * Sets initial z scaling factor.
1460      * This is only taken into account if non-linear preliminary solutions are used.
1461      *
1462      * @param initialSz initial z scaling factor.
1463      * @throws LockedException if calibrator is currently running.
1464      */
1465     @Override
1466     public void setInitialSz(final double initialSz) throws LockedException {
1467         if (running) {
1468             throw new LockedException();
1469         }
1470         this.initialSz = initialSz;
1471     }
1472 
1473     /**
1474      * Gets initial x-y cross coupling error.
1475      * This is only taken into account if non-linear preliminary solutions are used.
1476      *
1477      * @return initial x-y cross coupling error.
1478      */
1479     @Override
1480     public double getInitialMxy() {
1481         return initialMxy;
1482     }
1483 
1484     /**
1485      * Sets initial x-y cross coupling error.
1486      * This is only taken into account if non-linear preliminary solutions are used.
1487      *
1488      * @param initialMxy initial x-y cross coupling error.
1489      * @throws LockedException if calibrator is currently running.
1490      */
1491     @Override
1492     public void setInitialMxy(final double initialMxy) throws LockedException {
1493         if (running) {
1494             throw new LockedException();
1495         }
1496         this.initialMxy = initialMxy;
1497     }
1498 
1499     /**
1500      * Gets initial x-z cross coupling error.
1501      * This is only taken into account if non-linear preliminary solutions are used.
1502      *
1503      * @return initial x-z cross coupling error.
1504      */
1505     @Override
1506     public double getInitialMxz() {
1507         return initialMxz;
1508     }
1509 
1510     /**
1511      * Sets initial x-z cross coupling error.
1512      * This is only taken into account if non-linear preliminary solutions are used.
1513      *
1514      * @param initialMxz initial x-z cross coupling error.
1515      * @throws LockedException if calibrator is currently running.
1516      */
1517     @Override
1518     public void setInitialMxz(final double initialMxz) throws LockedException {
1519         if (running) {
1520             throw new LockedException();
1521         }
1522         this.initialMxz = initialMxz;
1523     }
1524 
1525     /**
1526      * Gets initial y-x cross coupling error.
1527      * This is only taken into account if non-linear preliminary solutions are used.
1528      *
1529      * @return initial y-x cross coupling error.
1530      */
1531     @Override
1532     public double getInitialMyx() {
1533         return initialMyx;
1534     }
1535 
1536     /**
1537      * Sets initial y-x cross coupling error.
1538      * This is only taken into account if non-linear preliminary solutions are used.
1539      *
1540      * @param initialMyx initial y-x cross coupling error.
1541      * @throws LockedException if calibrator is currently running.
1542      */
1543     @Override
1544     public void setInitialMyx(final double initialMyx) throws LockedException {
1545         if (running) {
1546             throw new LockedException();
1547         }
1548         this.initialMyx = initialMyx;
1549     }
1550 
1551     /**
1552      * Gets initial y-z cross coupling error.
1553      * This is only taken into account if non-linear preliminary solutions are used.
1554      *
1555      * @return initial y-z cross coupling error.
1556      */
1557     @Override
1558     public double getInitialMyz() {
1559         return initialMyz;
1560     }
1561 
1562     /**
1563      * Sets initial y-z cross coupling error.
1564      * This is only taken into account if non-linear preliminary solutions are used.
1565      *
1566      * @param initialMyz initial y-z cross coupling error.
1567      * @throws LockedException if calibrator is currently running.
1568      */
1569     @Override
1570     public void setInitialMyz(final double initialMyz) throws LockedException {
1571         if (running) {
1572             throw new LockedException();
1573         }
1574         this.initialMyz = initialMyz;
1575     }
1576 
1577     /**
1578      * Gets initial z-x cross coupling error.
1579      * This is only taken into account if non-linear preliminary solutions are used.
1580      *
1581      * @return initial z-x cross coupling error.
1582      */
1583     @Override
1584     public double getInitialMzx() {
1585         return initialMzx;
1586     }
1587 
1588     /**
1589      * Sets initial z-x cross coupling error.
1590      * This is only taken into account if non-linear preliminary solutions are used.
1591      *
1592      * @param initialMzx initial z-x cross coupling error.
1593      * @throws LockedException if calibrator is currently running.
1594      */
1595     @Override
1596     public void setInitialMzx(final double initialMzx) throws LockedException {
1597         if (running) {
1598             throw new LockedException();
1599         }
1600         this.initialMzx = initialMzx;
1601     }
1602 
1603     /**
1604      * Gets initial z-y cross coupling error.
1605      * This is only taken into account if non-linear preliminary solutions are used.
1606      *
1607      * @return initial z-y cross coupling error.
1608      */
1609     @Override
1610     public double getInitialMzy() {
1611         return initialMzy;
1612     }
1613 
1614     /**
1615      * Sets initial z-y cross coupling error.
1616      * This is only taken into account if non-linear preliminary solutions are used.
1617      *
1618      * @param initialMzy initial z-y cross coupling error.
1619      * @throws LockedException if calibrator is currently running.
1620      */
1621     @Override
1622     public void setInitialMzy(final double initialMzy) throws LockedException {
1623         if (running) {
1624             throw new LockedException();
1625         }
1626         this.initialMzy = initialMzy;
1627     }
1628 
1629     /**
1630      * Sets initial scaling factors.
1631      * This is only taken into account if non-linear preliminary solutions are used.
1632      *
1633      * @param initialSx initial x scaling factor.
1634      * @param initialSy initial y scaling factor.
1635      * @param initialSz initial z scaling factor.
1636      * @throws LockedException if calibrator is currently running.
1637      */
1638     @Override
1639     public void setInitialScalingFactors(
1640             final double initialSx, final double initialSy, final double initialSz) throws LockedException {
1641         if (running) {
1642             throw new LockedException();
1643         }
1644         this.initialSx = initialSx;
1645         this.initialSy = initialSy;
1646         this.initialSz = initialSz;
1647     }
1648 
1649     /**
1650      * Sets initial cross coupling errors.
1651      * This is only taken into account if non-linear preliminary solutions are used.
1652      *
1653      * @param initialMxy initial x-y cross coupling error.
1654      * @param initialMxz initial x-z cross coupling error.
1655      * @param initialMyx initial y-x cross coupling error.
1656      * @param initialMyz initial y-z cross coupling error.
1657      * @param initialMzx initial z-x cross coupling error.
1658      * @param initialMzy initial z-y cross coupling error.
1659      * @throws LockedException if calibrator is currently running.
1660      */
1661     @Override
1662     public void setInitialCrossCouplingErrors(
1663             final double initialMxy, final double initialMxz, final double initialMyx,
1664             final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
1665         if (running) {
1666             throw new LockedException();
1667         }
1668         this.initialMxy = initialMxy;
1669         this.initialMxz = initialMxz;
1670         this.initialMyx = initialMyx;
1671         this.initialMyz = initialMyz;
1672         this.initialMzx = initialMzx;
1673         this.initialMzy = initialMzy;
1674     }
1675 
1676     /**
1677      * Sets initial scaling factors and cross coupling errors.
1678      * This is only taken into account if non-linear preliminary solutions are used.
1679      *
1680      * @param initialSx  initial x scaling factor.
1681      * @param initialSy  initial y scaling factor.
1682      * @param initialSz  initial z scaling factor.
1683      * @param initialMxy initial x-y cross coupling error.
1684      * @param initialMxz initial x-z cross coupling error.
1685      * @param initialMyx initial y-x cross coupling error.
1686      * @param initialMyz initial y-z cross coupling error.
1687      * @param initialMzx initial z-x cross coupling error.
1688      * @param initialMzy initial z-y cross coupling error.
1689      * @throws LockedException if calibrator is currently running.
1690      */
1691     @Override
1692     public void setInitialScalingFactorsAndCrossCouplingErrors(
1693             final double initialSx, final double initialSy, final double initialSz,
1694             final double initialMxy, final double initialMxz, final double initialMyx,
1695             final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
1696         if (running) {
1697             throw new LockedException();
1698         }
1699         setInitialScalingFactors(initialSx, initialSy, initialSz);
1700         setInitialCrossCouplingErrors(initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1701     }
1702 
1703     /**
1704      * Gets initial bias to be used to find a solution as an array.
1705      * Array values are expressed in meters per squared second (m/s^2).
1706      * This is only taken into account if non-linear preliminary solutions are used.
1707      *
1708      * @return array containing coordinates of initial bias.
1709      */
1710     @Override
1711     public double[] getInitialBias() {
1712         final var result = new double[BodyKinematics.COMPONENTS];
1713         getInitialBias(result);
1714         return result;
1715     }
1716 
1717     /**
1718      * Gets initial bias to be used to find a solution as an array.
1719      * Array values are expressed in meters per squared second (m/s^2).
1720      * This is only taken into account if non-linear preliminary solutions are used.
1721      *
1722      * @param result instance where result data will be copied to.
1723      * @throws IllegalArgumentException if provided array does not have length 3.
1724      */
1725     @Override
1726     public void getInitialBias(final double[] result) {
1727         if (result.length != BodyKinematics.COMPONENTS) {
1728             throw new IllegalArgumentException();
1729         }
1730         result[0] = initialBiasX;
1731         result[1] = initialBiasY;
1732         result[2] = initialBiasZ;
1733     }
1734 
1735     /**
1736      * Sets initial bias to be used to find a solution as an array.
1737      * Array values are expressed in meters per squared second (m/s^2).
1738      * This is only taken into account if non-linear preliminary solutions are used.
1739      *
1740      * @param initialBias initial bias to find a solution.
1741      * @throws LockedException          if calibrator is currently running.
1742      * @throws IllegalArgumentException if provided array does not have length 3.
1743      */
1744     @Override
1745     public void setInitialBias(final double[] initialBias) throws LockedException {
1746         if (running) {
1747             throw new LockedException();
1748         }
1749 
1750         if (initialBias.length != BodyKinematics.COMPONENTS) {
1751             throw new IllegalArgumentException();
1752         }
1753         initialBiasX = initialBias[0];
1754         initialBiasY = initialBias[1];
1755         initialBiasZ = initialBias[2];
1756     }
1757 
1758     /**
1759      * Gets initial bias to be used to find a solution as a column matrix.
1760      * This is only taken into account if non-linear preliminary solutions are used.
1761      * Values are expressed in meters per squared second (m/s^2).
1762      *
1763      * @return initial bias to be used to find a solution as a column matrix.
1764      */
1765     @Override
1766     public Matrix getInitialBiasAsMatrix() {
1767         Matrix result;
1768         try {
1769             result = new Matrix(BodyKinematics.COMPONENTS, 1);
1770             getInitialBiasAsMatrix(result);
1771         } catch (final WrongSizeException ignore) {
1772             // never happens
1773             result = null;
1774         }
1775         return result;
1776     }
1777 
1778     /**
1779      * Gets initial bias to be used to find a solution as a column matrix.
1780      * This is only taken into account if non-linear preliminary solutions are used.
1781      * Values are expressed in meters per squared second (m/s^2).
1782      *
1783      * @param result instance where result data will be copied to.
1784      * @throws IllegalArgumentException if provided matrix is not 3x1.
1785      */
1786     @Override
1787     public void getInitialBiasAsMatrix(final Matrix result) {
1788         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1789             throw new IllegalArgumentException();
1790         }
1791         result.setElementAtIndex(0, initialBiasX);
1792         result.setElementAtIndex(1, initialBiasY);
1793         result.setElementAtIndex(2, initialBiasZ);
1794     }
1795 
1796     /**
1797      * Sets initial bias to be used to find a solution as an array.
1798      * This is only taken into account if non-linear preliminary solutions are used.
1799      * Values are expressed in meters per squared second (m/s^2).
1800      *
1801      * @param initialBias initial bias to find a solution.
1802      * @throws LockedException          if calibrator is currently running.
1803      * @throws IllegalArgumentException if provided matrix is not 3x1.
1804      */
1805     @Override
1806     public void setInitialBias(final Matrix initialBias) throws LockedException {
1807         if (running) {
1808             throw new LockedException();
1809         }
1810         if (initialBias.getRows() != BodyKinematics.COMPONENTS || initialBias.getColumns() != 1) {
1811             throw new IllegalArgumentException();
1812         }
1813 
1814         initialBiasX = initialBias.getElementAtIndex(0);
1815         initialBiasY = initialBias.getElementAtIndex(1);
1816         initialBiasZ = initialBias.getElementAtIndex(2);
1817     }
1818 
1819     /**
1820      * Gets initial scale factors and cross coupling errors matrix.
1821      * This is only taken into account if non-linear preliminary solutions are used.
1822      *
1823      * @return initial scale factors and cross coupling errors matrix.
1824      */
1825     @Override
1826     public Matrix getInitialMa() {
1827         Matrix result;
1828         try {
1829             result = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
1830             getInitialMa(result);
1831         } catch (final WrongSizeException ignore) {
1832             // never happens
1833             result = null;
1834         }
1835         return result;
1836     }
1837 
1838     /**
1839      * Gets initial scale factors and cross coupling errors matrix.
1840      * This is only taken into account if non-linear preliminary solutions are used.
1841      *
1842      * @param result instance where data will be stored.
1843      * @throws IllegalArgumentException if provided matrix is not 3x3.
1844      */
1845     @Override
1846     public void getInitialMa(final Matrix result) {
1847         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
1848             throw new IllegalArgumentException();
1849         }
1850         result.setElementAtIndex(0, initialSx);
1851         result.setElementAtIndex(1, initialMyx);
1852         result.setElementAtIndex(2, initialMzx);
1853 
1854         result.setElementAtIndex(3, initialMxy);
1855         result.setElementAtIndex(4, initialSy);
1856         result.setElementAtIndex(5, initialMzy);
1857 
1858         result.setElementAtIndex(6, initialMxz);
1859         result.setElementAtIndex(7, initialMyz);
1860         result.setElementAtIndex(8, initialSz);
1861     }
1862 
1863     /**
1864      * Sets initial scale factors and cross coupling errors matrix.
1865      * This is only taken into account if non-linear preliminary solutions are used.
1866      *
1867      * @param initialMa initial scale factors and cross coupling errors matrix.
1868      * @throws IllegalArgumentException if provided matrix is not 3x3.
1869      * @throws LockedException          if calibrator is currently running.
1870      */
1871     @Override
1872     public void setInitialMa(final Matrix initialMa) throws LockedException {
1873         if (running) {
1874             throw new LockedException();
1875         }
1876         if (initialMa.getRows() != BodyKinematics.COMPONENTS || initialMa.getColumns() != BodyKinematics.COMPONENTS) {
1877             throw new IllegalArgumentException();
1878         }
1879 
1880         initialSx = initialMa.getElementAtIndex(0);
1881         initialMyx = initialMa.getElementAtIndex(1);
1882         initialMzx = initialMa.getElementAtIndex(2);
1883 
1884         initialMxy = initialMa.getElementAtIndex(3);
1885         initialSy = initialMa.getElementAtIndex(4);
1886         initialMzy = initialMa.getElementAtIndex(5);
1887 
1888         initialMxz = initialMa.getElementAtIndex(6);
1889         initialMyz = initialMa.getElementAtIndex(7);
1890         initialSz = initialMa.getElementAtIndex(8);
1891     }
1892 
1893     /**
1894      * Gets position where body kinematics measures have been taken expressed in
1895      * ECEF coordinates.
1896      *
1897      * @return position where body kinematics measures have been taken.
1898      */
1899     public ECEFPosition getEcefPosition() {
1900         return position;
1901     }
1902 
1903     /**
1904      * Gets position where body kinematics measures have been taken expressed in
1905      * ECEF coordinates.
1906      *
1907      * @param position position where body kinematics measures have been taken.
1908      * @throws LockedException if calibrator is currently running.
1909      */
1910     public void setPosition(final ECEFPosition position) throws LockedException {
1911         if (running) {
1912             throw new LockedException();
1913         }
1914 
1915         this.position = position;
1916     }
1917 
1918     /**
1919      * Gets position where body kinematics measures have been taken expressed in
1920      * NED coordinates.
1921      *
1922      * @return position where body kinematics measures have been taken or null if
1923      * not available.
1924      */
1925     public NEDPosition getNedPosition() {
1926         final var result = new NEDPosition();
1927         return getNedPosition(result) ? result : null;
1928     }
1929 
1930     /**
1931      * Gets position where body kinematics measures have been taken expressed in
1932      * NED coordinates.
1933      *
1934      * @param result instance where result will be stored.
1935      * @return true if NED position could be computed, false otherwise.
1936      */
1937     public boolean getNedPosition(final NEDPosition result) {
1938         if (position != null) {
1939             final var velocity = new NEDVelocity();
1940             ECEFtoNEDPositionVelocityConverter.convertECEFtoNED(
1941                     position.getX(), position.getY(), position.getZ(),
1942                     0.0, 0.0, 0.0, result, velocity);
1943             return true;
1944         } else {
1945             return false;
1946         }
1947     }
1948 
1949     /**
1950      * Sets position where body kinematics measures have been taken expressed in
1951      * NED coordinates.
1952      *
1953      * @param position position where body kinematics measures have been taken.
1954      * @throws LockedException if calibrator is currently running.
1955      */
1956     public void setPosition(final NEDPosition position) throws LockedException {
1957         if (running) {
1958             throw new LockedException();
1959         }
1960 
1961         this.position = convertPosition(position);
1962     }
1963 
1964     /**
1965      * Gets a list of body kinematics measurements taken at a
1966      * given position with different unknown orientations and containing the
1967      * standard deviations of accelerometer and gyroscope measurements.
1968      *
1969      * @return list of body kinematics measurements.
1970      */
1971     @Override
1972     public List<StandardDeviationBodyKinematics> getMeasurements() {
1973         return measurements;
1974     }
1975 
1976     /**
1977      * Sets a list of body kinematics measurements taken at a
1978      * given position with different unknown orientations and containing the
1979      * standard deviations of accelerometer and gyroscope measurements.
1980      *
1981      * @param measurements list of body kinematics measurements.
1982      * @throws LockedException if calibrator is currently running.
1983      */
1984     @Override
1985     public void setMeasurements(final List<StandardDeviationBodyKinematics> measurements) throws LockedException {
1986         if (running) {
1987             throw new LockedException();
1988         }
1989         this.measurements = measurements;
1990     }
1991 
1992     /**
1993      * Indicates the type of measurement used by this calibrator.
1994      *
1995      * @return type of measurement used by this calibrator.
1996      */
1997     @Override
1998     public AccelerometerCalibratorMeasurementType getMeasurementType() {
1999         return AccelerometerCalibratorMeasurementType.STANDARD_DEVIATION_BODY_KINEMATICS;
2000     }
2001 
2002     /**
2003      * Indicates whether this calibrator requires ordered measurements in a
2004      * list or not.
2005      *
2006      * @return true if measurements must be ordered, false otherwise.
2007      */
2008     @Override
2009     public boolean isOrderedMeasurementsRequired() {
2010         return true;
2011     }
2012 
2013     /**
2014      * Indicates whether z-axis is assumed to be common for accelerometer and
2015      * gyroscope.
2016      * When enabled, this eliminates 3 variables from Ma matrix.
2017      *
2018      * @return true if z-axis is assumed to be common for accelerometer and gyroscope,
2019      * false otherwise.
2020      */
2021     @Override
2022     public boolean isCommonAxisUsed() {
2023         return commonAxisUsed;
2024     }
2025 
2026     /**
2027      * Specifies whether z-axis is assumed to be common for accelerometer and
2028      * gyroscope.
2029      * When enabled, this eliminates 3 variables from Ma matrix.
2030      *
2031      * @param commonAxisUsed true if z-axis is assumed to be common for accelerometer
2032      *                       and gyroscope, false otherwise.
2033      * @throws LockedException if calibrator is currently running.
2034      */
2035     @Override
2036     public void setCommonAxisUsed(final boolean commonAxisUsed) throws LockedException {
2037         if (running) {
2038             throw new LockedException();
2039         }
2040 
2041         this.commonAxisUsed = commonAxisUsed;
2042     }
2043 
2044     /**
2045      * Gets listener to handle events raised by this estimator.
2046      *
2047      * @return listener to handle events raised by this estimator.
2048      */
2049     public RobustKnownPositionAccelerometerCalibratorListener getListener() {
2050         return listener;
2051     }
2052 
2053     /**
2054      * Sets listener to handle events raised by this estimator.
2055      *
2056      * @param listener listener to handle events raised by this estimator.
2057      * @throws LockedException if calibrator is currently running.
2058      */
2059     public void setListener(final RobustKnownPositionAccelerometerCalibratorListener listener) throws LockedException {
2060         if (running) {
2061             throw new LockedException();
2062         }
2063 
2064         this.listener = listener;
2065     }
2066 
2067     /**
2068      * Gets minimum number of required measurements.
2069      *
2070      * @return minimum number of required measurements.
2071      */
2072     @Override
2073     public int getMinimumRequiredMeasurements() {
2074         return commonAxisUsed ? MINIMUM_MEASUREMENTS_COMMON_Z_AXIS : MINIMUM_MEASUREMENTS_GENERAL;
2075     }
2076 
2077     /**
2078      * Indicates whether calibrator is ready to start.
2079      *
2080      * @return true if calibrator is ready, false otherwise.
2081      */
2082     @Override
2083     public boolean isReady() {
2084         return measurements != null && measurements.size() >= getMinimumRequiredMeasurements() && position != null;
2085     }
2086 
2087     /**
2088      * Indicates whether calibrator is currently running or not.
2089      *
2090      * @return true if calibrator is running, false otherwise.
2091      */
2092     @Override
2093     public boolean isRunning() {
2094         return running;
2095     }
2096 
2097     /**
2098      * Returns amount of progress variation before notifying a progress change during
2099      * calibration.
2100      *
2101      * @return amount of progress variation before notifying a progress change during
2102      * calibration.
2103      */
2104     public float getProgressDelta() {
2105         return progressDelta;
2106     }
2107 
2108     /**
2109      * Sets amount of progress variation before notifying a progress change during
2110      * calibration.
2111      *
2112      * @param progressDelta amount of progress variation before notifying a progress
2113      *                      change during calibration.
2114      * @throws IllegalArgumentException if progress delta is less than zero or greater than 1.
2115      * @throws LockedException          if calibrator is currently running.
2116      */
2117     public void setProgressDelta(final float progressDelta) throws LockedException {
2118         if (running) {
2119             throw new LockedException();
2120         }
2121         if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
2122             throw new IllegalArgumentException();
2123         }
2124         this.progressDelta = progressDelta;
2125     }
2126 
2127     /**
2128      * Returns amount of confidence expressed as a value between 0.0 and 1.0
2129      * (which is equivalent to 100%). The amount of confidence indicates the probability
2130      * that the estimated result is correct. Usually this value will be close to 1.0, but
2131      * not exactly 1.0.
2132      *
2133      * @return amount of confidence as a value between 0.0 and 1.0.
2134      */
2135     public double getConfidence() {
2136         return confidence;
2137     }
2138 
2139     /**
2140      * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which is
2141      * equivalent to 100%). The amount of confidence indicates the probability that
2142      * the estimated result is correct. Usually this value will be close to 1.0, but
2143      * not exactly 1.0.
2144      *
2145      * @param confidence confidence to be set as a value between 0.0 and 1.0.
2146      * @throws IllegalArgumentException if provided value is not between 0.0 and 1.0.
2147      * @throws LockedException          if calibrator is currently running.
2148      */
2149     public void setConfidence(final double confidence) throws LockedException {
2150         if (running) {
2151             throw new LockedException();
2152         }
2153         if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
2154             throw new IllegalArgumentException();
2155         }
2156         this.confidence = confidence;
2157     }
2158 
2159     /**
2160      * Returns maximum allowed number of iterations. If maximum allowed number of
2161      * iterations is achieved without converging to a result when calling calibrate(),
2162      * a RobustEstimatorException will be raised.
2163      *
2164      * @return maximum allowed number of iterations.
2165      */
2166     public int getMaxIterations() {
2167         return maxIterations;
2168     }
2169 
2170     /**
2171      * Sets maximum allowed number of iterations. When the maximum number of iterations
2172      * is exceeded, result will not be available, however an approximate result will be
2173      * available for retrieval.
2174      *
2175      * @param maxIterations maximum allowed number of iterations to be set.
2176      * @throws IllegalArgumentException if provided value is less than 1.
2177      * @throws LockedException          if calibrator is currently running.
2178      */
2179     public void setMaxIterations(final int maxIterations) throws LockedException {
2180         if (running) {
2181             throw new LockedException();
2182         }
2183         if (maxIterations < MIN_ITERATIONS) {
2184             throw new IllegalArgumentException();
2185         }
2186         this.maxIterations = maxIterations;
2187     }
2188 
2189     /**
2190      * Gets data related to inliers found after estimation.
2191      *
2192      * @return data related to inliers found after estimation.
2193      */
2194     public InliersData getInliersData() {
2195         return inliersData;
2196     }
2197 
2198     /**
2199      * Indicates whether result must be refined using a non-linear solver over found inliers.
2200      *
2201      * @return true to refine result, false to simply use result found by robust estimator
2202      * without further refining.
2203      */
2204     public boolean isResultRefined() {
2205         return refineResult;
2206     }
2207 
2208     /**
2209      * Specifies whether result must be refined using a non-linear solver over found inliers.
2210      *
2211      * @param refineResult true to refine result, false to simply use result found by robust
2212      *                     estimator without further refining.
2213      * @throws LockedException if calibrator is currently running.
2214      */
2215     public void setResultRefined(final boolean refineResult) throws LockedException {
2216         if (running) {
2217             throw new LockedException();
2218         }
2219         this.refineResult = refineResult;
2220     }
2221 
2222     /**
2223      * Indicates whether covariance must be kept after refining result.
2224      * This setting is only taken into account if result is refined.
2225      *
2226      * @return true if covariance must be kept after refining result, false otherwise.
2227      */
2228     public boolean isCovarianceKept() {
2229         return keepCovariance;
2230     }
2231 
2232     /**
2233      * Specifies whether covariance must be kept after refining result.
2234      * This setting is only taken into account if result is refined.
2235      *
2236      * @param keepCovariance true if covariance must be kept after refining result,
2237      *                       false otherwise.
2238      * @throws LockedException if calibrator is currently running.
2239      */
2240     public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
2241         if (running) {
2242             throw new LockedException();
2243         }
2244         this.keepCovariance = keepCovariance;
2245     }
2246 
2247     /**
2248      * Returns quality scores corresponding to each measurement.
2249      * The larger the score value the better the quality of the sample.
2250      * This implementation always returns null.
2251      * Subclasses using quality scores must implement proper behavior.
2252      *
2253      * @return quality scores corresponding to each sample.
2254      */
2255     @Override
2256     public double[] getQualityScores() {
2257         return null;
2258     }
2259 
2260     /**
2261      * Sets quality scores corresponding to each measurement.
2262      * The larger the score value the better the quality of the sample.
2263      * This implementation makes no action.
2264      * Subclasses using quality scores must implement proper behaviour.
2265      *
2266      * @param qualityScores quality scores corresponding to each pair of
2267      *                      matched points.
2268      * @throws IllegalArgumentException if provided quality scores length
2269      *                                  is smaller than minimum required samples.
2270      * @throws LockedException          if calibrator is currently running.
2271      */
2272     @Override
2273     public void setQualityScores(final double[] qualityScores) throws LockedException {
2274     }
2275 
2276     /**
2277      * Gets array containing x,y,z components of estimated accelerometer biases
2278      * expressed in meters per squared second (m/s^2).
2279      *
2280      * @return array containing x,y,z components of estimated accelerometer biases.
2281      */
2282     @Override
2283     public double[] getEstimatedBiases() {
2284         return estimatedBiases;
2285     }
2286 
2287     /**
2288      * Gets array containing x,y,z components of estimated accelerometer biases
2289      * expressed in meters per squared second (m/s^2).
2290      *
2291      * @param result instance where estimated accelerometer biases will be stored.
2292      * @return true if result instance was updated, false otherwise (when estimation
2293      * is not yet available).
2294      */
2295     @Override
2296     public boolean getEstimatedBiases(final double[] result) {
2297         if (estimatedBiases != null) {
2298             System.arraycopy(estimatedBiases, 0, result, 0, estimatedBiases.length);
2299             return true;
2300         } else {
2301             return false;
2302         }
2303     }
2304 
2305     /**
2306      * Gets column matrix containing x,y,z components of estimated accelerometer biases
2307      * expressed in meters per squared second (m/s^2).
2308      *
2309      * @return column matrix containing x,y,z components of estimated accelerometer
2310      * biases
2311      */
2312     @Override
2313     public Matrix getEstimatedBiasesAsMatrix() {
2314         return estimatedBiases != null ? Matrix.newFromArray(estimatedBiases) : null;
2315     }
2316 
2317     /**
2318      * Gets column matrix containing x,y,z components of estimated accelerometer biases
2319      * expressed in meters per squared second (m/s^2).
2320      *
2321      * @param result instance where result data will be stored.
2322      * @return true if result was updated, false otherwise.
2323      * @throws WrongSizeException if provided result instance has invalid size.
2324      */
2325     @Override
2326     public boolean getEstimatedBiasesAsMatrix(final Matrix result) throws WrongSizeException {
2327         if (estimatedBiases != null) {
2328             result.fromArray(estimatedBiases);
2329             return true;
2330         } else {
2331             return false;
2332         }
2333     }
2334 
2335     /**
2336      * Gets x coordinate of estimated accelerometer bias expressed in meters per
2337      * squared second (m/s^2).
2338      *
2339      * @return x coordinate of estimated accelerometer bias or null if not available.
2340      */
2341     @Override
2342     public Double getEstimatedBiasFx() {
2343         return estimatedBiases != null ? estimatedBiases[0] : null;
2344     }
2345 
2346     /**
2347      * Gets y coordinate of estimated accelerometer bias expressed in meters per
2348      * squared second (m/s^2).
2349      *
2350      * @return y coordinate of estimated accelerometer bias or null if not available.
2351      */
2352     @Override
2353     public Double getEstimatedBiasFy() {
2354         return estimatedBiases != null ? estimatedBiases[1] : null;
2355     }
2356 
2357     /**
2358      * Gets z coordinate of estimated accelerometer bias expressed in meters per
2359      * squared second (m/s^2).
2360      *
2361      * @return z coordinate of estimated accelerometer bias or null if not available.
2362      */
2363     @Override
2364     public Double getEstimatedBiasFz() {
2365         return estimatedBiases != null ? estimatedBiases[2] : null;
2366     }
2367 
2368     /**
2369      * Gets x coordinate of estimated accelerometer bias.
2370      *
2371      * @return x coordinate of estimated accelerometer bias or null if not available.
2372      */
2373     @Override
2374     public Acceleration getEstimatedBiasFxAsAcceleration() {
2375         return estimatedBiases != null
2376                 ? new Acceleration(estimatedBiases[0], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
2377     }
2378 
2379     /**
2380      * Gets x coordinate of estimated accelerometer bias.
2381      *
2382      * @param result instance where result will be stored.
2383      * @return true if result was updated, false if estimation is not available.
2384      */
2385     @Override
2386     public boolean getEstimatedBiasFxAsAcceleration(final Acceleration result) {
2387         if (estimatedBiases != null) {
2388             result.setValue(estimatedBiases[0]);
2389             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2390             return true;
2391         } else {
2392             return false;
2393         }
2394     }
2395 
2396     /**
2397      * Gets y coordinate of estimated accelerometer bias.
2398      *
2399      * @return y coordinate of estimated accelerometer bias or null if not available.
2400      */
2401     @Override
2402     public Acceleration getEstimatedBiasFyAsAcceleration() {
2403         return estimatedBiases != null
2404                 ? new Acceleration(estimatedBiases[1], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
2405     }
2406 
2407     /**
2408      * Gets y coordinate of estimated accelerometer bias.
2409      *
2410      * @param result instance where result will be stored.
2411      * @return true if result was updated, false if estimation is not available.
2412      */
2413     @Override
2414     public boolean getEstimatedBiasFyAsAcceleration(final Acceleration result) {
2415         if (estimatedBiases != null) {
2416             result.setValue(estimatedBiases[1]);
2417             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2418             return true;
2419         } else {
2420             return false;
2421         }
2422     }
2423 
2424     /**
2425      * Gets z coordinate of estimated accelerometer bias.
2426      *
2427      * @return z coordinate of estimated accelerometer bias or null if not available.
2428      */
2429     @Override
2430     public Acceleration getEstimatedBiasFzAsAcceleration() {
2431         return estimatedBiases != null
2432                 ? new Acceleration(estimatedBiases[2], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
2433     }
2434 
2435     /**
2436      * Gets z coordinate of estimated accelerometer bias.
2437      *
2438      * @param result instance where result will be stored.
2439      * @return true if result was updated, false if estimation is not available.
2440      */
2441     @Override
2442     public boolean getEstimatedBiasFzAsAcceleration(final Acceleration result) {
2443         if (estimatedBiases != null) {
2444             result.setValue(estimatedBiases[2]);
2445             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2446             return true;
2447         } else {
2448             return false;
2449         }
2450     }
2451 
2452     /**
2453      * Gets estimated accelerometer bias.
2454      *
2455      * @return estimated accelerometer bias or null if not available.
2456      */
2457     @Override
2458     public AccelerationTriad getEstimatedBiasAsTriad() {
2459         return estimatedBiases != null
2460                 ? new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
2461                 estimatedBiases[0], estimatedBiases[1], estimatedBiases[2])
2462                 : null;
2463     }
2464 
2465     /**
2466      * Gets estimated accelerometer bias.
2467      *
2468      * @param result instance where result will be stored.
2469      * @return true if estimated accelerometer bias is available and result was
2470      * modified, false otherwise.
2471      */
2472     @Override
2473     public boolean getEstimatedBiasAsTriad(final AccelerationTriad result) {
2474         if (estimatedBiases != null) {
2475             result.setValueCoordinatesAndUnit(estimatedBiases[0], estimatedBiases[1], estimatedBiases[2],
2476                     AccelerationUnit.METERS_PER_SQUARED_SECOND);
2477             return true;
2478         } else {
2479             return false;
2480         }
2481     }
2482 
2483     /**
2484      * Gets estimated accelerometer scale factors and ross coupling errors.
2485      * This is the product of matrix Ta containing cross coupling errors and Ka
2486      * containing scaling factors.
2487      * So tat:
2488      * <pre>
2489      *     Ma = [sx    mxy  mxz] = Ta*Ka
2490      *          [myx   sy   myz]
2491      *          [mzx   mzy  sz ]
2492      * </pre>
2493      * Where:
2494      * <pre>
2495      *     Ka = [sx 0   0 ]
2496      *          [0  sy  0 ]
2497      *          [0  0   sz]
2498      * </pre>
2499      * and
2500      * <pre>
2501      *     Ta = [1          -alphaXy    alphaXz ]
2502      *          [alphaYx    1           -alphaYz]
2503      *          [-alphaZx   alphaZy     1       ]
2504      * </pre>
2505      * Hence:
2506      * <pre>
2507      *     Ma = [sx    mxy  mxz] = Ta*Ka =  [sx             -sy * alphaXy   sz * alphaXz ]
2508      *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
2509      *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
2510      * </pre>
2511      * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
2512      * are considered to be zero if the accelerometer z-axis is assumed to be the same
2513      * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Ma matrix
2514      * becomes upper diagonal:
2515      * <pre>
2516      *     Ma = [sx    mxy  mxz]
2517      *          [0     sy   myz]
2518      *          [0     0    sz ]
2519      * </pre>
2520      * Values of this matrix are unit-less.
2521      *
2522      * @return estimated accelerometer scale factors and cross coupling errors, or null
2523      * if not available.
2524      */
2525     @Override
2526     public Matrix getEstimatedMa() {
2527         return estimatedMa;
2528     }
2529 
2530     /**
2531      * Gets estimated x-axis scale factor.
2532      *
2533      * @return estimated x-axis scale factor or null if not available.
2534      */
2535     @Override
2536     public Double getEstimatedSx() {
2537         return estimatedMa != null ? estimatedMa.getElementAt(0, 0) : null;
2538     }
2539 
2540     /**
2541      * Gets estimated y-axis scale factor.
2542      *
2543      * @return estimated y-axis scale factor or null if not available.
2544      */
2545     @Override
2546     public Double getEstimatedSy() {
2547         return estimatedMa != null ? estimatedMa.getElementAt(1, 1) : null;
2548     }
2549 
2550     /**
2551      * Gets estimated z-axis scale factor.
2552      *
2553      * @return estimated z-axis scale factor or null if not available.
2554      */
2555     @Override
2556     public Double getEstimatedSz() {
2557         return estimatedMa != null ? estimatedMa.getElementAt(2, 2) : null;
2558     }
2559 
2560     /**
2561      * Gets estimated x-y cross-coupling error.
2562      *
2563      * @return estimated x-y cross-coupling error or null if not available.
2564      */
2565     @Override
2566     public Double getEstimatedMxy() {
2567         return estimatedMa != null ? estimatedMa.getElementAt(0, 1) : null;
2568     }
2569 
2570     /**
2571      * Gets estimated x-z cross-coupling error.
2572      *
2573      * @return estimated x-z cross-coupling error or null if not available.
2574      */
2575     @Override
2576     public Double getEstimatedMxz() {
2577         return estimatedMa != null ? estimatedMa.getElementAt(0, 2) : null;
2578     }
2579 
2580     /**
2581      * Gets estimated y-x cross-coupling error.
2582      *
2583      * @return estimated y-x cross-coupling error or null if not available.
2584      */
2585     @Override
2586     public Double getEstimatedMyx() {
2587         return estimatedMa != null ? estimatedMa.getElementAt(1, 0) : null;
2588     }
2589 
2590     /**
2591      * Gets estimated y-z cross-coupling error.
2592      *
2593      * @return estimated y-z cross-coupling error or null if not available.
2594      */
2595     @Override
2596     public Double getEstimatedMyz() {
2597         return estimatedMa != null ? estimatedMa.getElementAt(1, 2) : null;
2598     }
2599 
2600     /**
2601      * Gets estimated z-x cross-coupling error.
2602      *
2603      * @return estimated z-x cross-coupling error or null if not available.
2604      */
2605     @Override
2606     public Double getEstimatedMzx() {
2607         return estimatedMa != null ? estimatedMa.getElementAt(2, 0) : null;
2608     }
2609 
2610     /**
2611      * Gets estimated z-y cross-coupling error.
2612      *
2613      * @return estimated z-y cross-coupling error or null if not available.
2614      */
2615     @Override
2616     public Double getEstimatedMzy() {
2617         return estimatedMa != null ? estimatedMa.getElementAt(2, 1) : null;
2618     }
2619 
2620     /**
2621      * Gets estimated chi square value.
2622      *
2623      * @return estimated chi square value.
2624      */
2625     @Override
2626     public double getEstimatedChiSq() {
2627         return estimatedChiSq;
2628     }
2629 
2630     /**
2631      * Gets estimated chi square degrees of freedom. Degrees of freedom is equal to the number of sampled data minus the
2632      * number of estimated parameters.
2633      *
2634      * @return estimated degrees of freedom of chi square value
2635      */
2636     @Override
2637     public int getEstimatedChiSqDegreesOfFreedom() {
2638         return estimatedChiSqDegreesOfFreedom;
2639     }
2640 
2641     /**
2642      * Gets estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
2643      * freedom. Ideally this value should be close to 1.0, indicating that fit is optimal.
2644      * A value larger than 1.0 indicates that fit is not good or noise has been underestimated, and a value smaller than
2645      * 1.0 indicates that there is overfitting or noise has been overestimated.
2646      *
2647      * @return estimated reduced chi square value
2648      */
2649     @Override
2650     public double getEstimatedReducedChiSq() {
2651         return estimatedReducedChiSq;
2652     }
2653 
2654     /**
2655      * Gets estimated mean square error respect to provided measurements.
2656      *
2657      * @return estimated mean square error respect to provided measurements.
2658      */
2659     @Override
2660     public double getEstimatedMse() {
2661         return estimatedMse;
2662     }
2663 
2664     /**
2665      * Gets estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The
2666      * smaller the found chi square value is, the better the fit of the estimated parameters to the actual parameter.
2667      * Thus, the smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
2668      *
2669      * @return estimated probability of finding a smaller chi square value.
2670      */
2671     @Override
2672     public double getEstimatedP() {
2673         return estimatedP;
2674     }
2675 
2676     /**
2677      * Gets estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value
2678      * is, the better the fit that has been estimated.
2679      *
2680      * @return estimated measure of quality of estimated fit.
2681      */
2682     @Override
2683     public double getEstimatedQ() {
2684         return estimatedQ;
2685     }
2686 
2687     /**
2688      * Gets estimated covariance matrix for estimated calibration solution.
2689      * Diagonal elements of the matrix contains variance for the following
2690      * parameters (following indicated order): bx, by, bz, sx, sy, sz,
2691      * mxy, mxz, myx, myz, mzx, mzy.
2692      * This is only available when result has been refined and covariance
2693      * is kept.
2694      *
2695      * @return estimated covariance matrix for estimated position.
2696      */
2697     @Override
2698     public Matrix getEstimatedCovariance() {
2699         return estimatedCovariance;
2700     }
2701 
2702     /**
2703      * Gets variance of estimated x coordinate of accelerometer bias expressed in (m^2/s^4).
2704      *
2705      * @return variance of estimated x coordinate of accelerometer bias or null if not available.
2706      */
2707     public Double getEstimatedBiasFxVariance() {
2708         return estimatedCovariance != null ? estimatedCovariance.getElementAt(0, 0) : null;
2709     }
2710 
2711     /**
2712      * Gets standard deviation of estimated x coordinate of accelerometer bias expressed in
2713      * meters per squared second (m/s^2).
2714      *
2715      * @return standard deviation of estimated x coordinate of accelerometer bias or null if not
2716      * available.
2717      */
2718     public Double getEstimatedBiasFxStandardDeviation() {
2719         final var variance = getEstimatedBiasFxVariance();
2720         return variance != null ? Math.sqrt(variance) : null;
2721     }
2722 
2723     /**
2724      * Gets standard deviation of estimated x coordinate of accelerometer bias.
2725      *
2726      * @return standard deviation of estimated x coordinate of accelerometer bias or null if not
2727      * available.
2728      */
2729     public Acceleration getEstimatedBiasFxStandardDeviationAsAcceleration() {
2730         return estimatedCovariance != null
2731                 ? new Acceleration(getEstimatedBiasFxStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
2732                 : null;
2733     }
2734 
2735     /**
2736      * Gets standard deviation of estimated x coordinate of accelerometer bias.
2737      *
2738      * @param result instance where result will be stored.
2739      * @return true if standard deviation of estimated x coordinate of accelerometer bias is available,
2740      * false otherwise.
2741      */
2742     public boolean getEstimatedBiasFxStandardDeviationAsAcceleration(final Acceleration result) {
2743         if (estimatedCovariance != null) {
2744             result.setValue(getEstimatedBiasFxStandardDeviation());
2745             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2746             return true;
2747         } else {
2748             return false;
2749         }
2750     }
2751 
2752     /**
2753      * Gets variance of estimated y coordinate of accelerometer bias expressed in (m^2/s^4).
2754      *
2755      * @return variance of estimated y coordinate of accelerometer bias or null if not available.
2756      */
2757     public Double getEstimatedBiasFyVariance() {
2758         return estimatedCovariance != null ? estimatedCovariance.getElementAt(1, 1) : null;
2759     }
2760 
2761     /**
2762      * Gets standard deviation of estimated y coordinate of accelerometer bias expressed in
2763      * meters per squared second (m/s^2).
2764      *
2765      * @return standard deviation of estimated y coordinate of accelerometer bias or null if not
2766      * available.
2767      */
2768     public Double getEstimatedBiasFyStandardDeviation() {
2769         final var variance = getEstimatedBiasFyVariance();
2770         return variance != null ? Math.sqrt(variance) : null;
2771     }
2772 
2773     /**
2774      * Gets standard deviation of estimated y coordinate of accelerometer bias.
2775      *
2776      * @return standard deviation of estimated y coordinate of accelerometer bias or null if not
2777      * available.
2778      */
2779     public Acceleration getEstimatedBiasFyStandardDeviationAsAcceleration() {
2780         return estimatedCovariance != null
2781                 ? new Acceleration(getEstimatedBiasFyStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
2782                 : null;
2783     }
2784 
2785     /**
2786      * Gets standard deviation of estimated y coordinate of accelerometer bias.
2787      *
2788      * @param result instance where result will be stored.
2789      * @return true if standard deviation of estimated y coordinate of accelerometer bias is available,
2790      * false otherwise.
2791      */
2792     public boolean getEstimatedBiasFyStandardDeviationAsAcceleration(final Acceleration result) {
2793         if (estimatedCovariance != null) {
2794             result.setValue(getEstimatedBiasFyStandardDeviation());
2795             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2796             return true;
2797         } else {
2798             return false;
2799         }
2800     }
2801 
2802     /**
2803      * Gets variance of estimated z coordinate of accelerometer bias expressed in (m^2/s^4).
2804      *
2805      * @return variance of estimated z coordinate of accelerometer bias or null if not available.
2806      */
2807     public Double getEstimatedBiasFzVariance() {
2808         return estimatedCovariance != null ? estimatedCovariance.getElementAt(2, 2) : null;
2809     }
2810 
2811     /**
2812      * Gets standard deviation of estimated z coordinate of accelerometer bias expressed in
2813      * meters per squared second (m/s^2).
2814      *
2815      * @return standard deviation of estimated z coordinate of accelerometer bias or null if not
2816      * available.
2817      */
2818     public Double getEstimatedBiasFzStandardDeviation() {
2819         final var variance = getEstimatedBiasFzVariance();
2820         return variance != null ? Math.sqrt(variance) : null;
2821     }
2822 
2823     /**
2824      * Gets standard deviation of estimated z coordinate of accelerometer bias.
2825      *
2826      * @return standard deviation of estimated z coordinate of accelerometer bias or null if not
2827      * available.
2828      */
2829     public Acceleration getEstimatedBiasFzStandardDeviationAsAcceleration() {
2830         return estimatedCovariance != null
2831                 ? new Acceleration(getEstimatedBiasFzStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
2832                 : null;
2833     }
2834 
2835     /**
2836      * Gets standard deviation of estimated z coordinate of accelerometer bias.
2837      *
2838      * @param result instance where result will be stored.
2839      * @return true if standard deviation of estimated z coordinate of accelerometer bias is available,
2840      * false otherwise.
2841      */
2842     public boolean getEstimatedBiasFzStandardDeviationAsAcceleration(final Acceleration result) {
2843         if (estimatedCovariance != null) {
2844             result.setValue(getEstimatedBiasFzStandardDeviation());
2845             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2846             return true;
2847         } else {
2848             return false;
2849         }
2850     }
2851 
2852     /**
2853      * Gets standard deviation of estimated accelerometer bias coordinates.
2854      *
2855      * @return standard deviation of estimated accelerometer bias coordinates.
2856      */
2857     public AccelerationTriad getEstimatedBiasStandardDeviation() {
2858         return estimatedCovariance != null
2859                 ? new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
2860                 getEstimatedBiasFxStandardDeviation(),
2861                 getEstimatedBiasFyStandardDeviation(),
2862                 getEstimatedBiasFzStandardDeviation())
2863                 : null;
2864     }
2865 
2866     /**
2867      * Gets standard deviation of estimated accelerometer bias coordinates.
2868      *
2869      * @param result instance where result will be stored.
2870      * @return true if standard deviation of accelerometer bias was available, false
2871      * otherwise.
2872      */
2873     public boolean getEstimatedBiasStandardDeviation(final AccelerationTriad result) {
2874         if (estimatedCovariance != null) {
2875             result.setValueCoordinatesAndUnit(
2876                     getEstimatedBiasFxStandardDeviation(),
2877                     getEstimatedBiasFyStandardDeviation(),
2878                     getEstimatedBiasFzStandardDeviation(),
2879                     AccelerationUnit.METERS_PER_SQUARED_SECOND);
2880             return true;
2881         } else {
2882             return false;
2883         }
2884     }
2885 
2886     /**
2887      * Gets average of estimated standard deviation of accelerometer bias coordinates expressed
2888      * in meters per squared second (m/s^2).
2889      *
2890      * @return average of estimated standard deviation of accelerometer bias coordinates or null
2891      * if not available.
2892      */
2893     public Double getEstimatedBiasStandardDeviationAverage() {
2894         return estimatedCovariance != null
2895                 ? (getEstimatedBiasFxStandardDeviation() + getEstimatedBiasFyStandardDeviation()
2896                 + getEstimatedBiasFzStandardDeviation()) / 3.0
2897                 : null;
2898     }
2899 
2900     /**
2901      * Gets average of estimated standard deviation of accelerometer bias coordinates.
2902      *
2903      * @return average of estimated standard deviation of accelerometer bias coordinates or null.
2904      */
2905     public Acceleration getEstimatedBiasStandardDeviationAverageAsAcceleration() {
2906         return estimatedCovariance != null
2907                 ? new Acceleration(getEstimatedBiasStandardDeviationAverage(),
2908                 AccelerationUnit.METERS_PER_SQUARED_SECOND)
2909                 : null;
2910     }
2911 
2912     /**
2913      * Gets average of estimated standard deviation of accelerometer bias coordinates.
2914      *
2915      * @param result instance where result will be stored.
2916      * @return true if average of estimated standard deviation of accelerometer bias is available,
2917      * false otherwise.
2918      */
2919     public boolean getEstimatedBiasStandardDeviationAverageAsAcceleration(final Acceleration result) {
2920         if (estimatedCovariance != null) {
2921             result.setValue(getEstimatedBiasStandardDeviationAverage());
2922             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2923             return true;
2924         } else {
2925             return false;
2926         }
2927     }
2928 
2929     /**
2930      * Gets norm of estimated standard deviation of accelerometer bias expressed in
2931      * meters per squared second (m/s^2).
2932      * This can be used as the initial accelerometer bias uncertainty for
2933      * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
2934      *
2935      * @return norm of estimated standard deviation of accelerometer bias or null
2936      * if not available.
2937      */
2938     @Override
2939     public Double getEstimatedBiasStandardDeviationNorm() {
2940         return estimatedCovariance != null
2941                 ? Math.sqrt(getEstimatedBiasFxVariance() + getEstimatedBiasFyVariance() + getEstimatedBiasFzVariance())
2942                 : null;
2943     }
2944 
2945     /**
2946      * Gets norm of estimated standard deviation of accelerometer bias.
2947      * This can be used as the initial accelerometer bias uncertainty for
2948      * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
2949      *
2950      * @return norm of estimated standard deviation of accelerometer bias or null
2951      * if not available.
2952      */
2953     public Acceleration getEstimatedBiasStandardDeviationNormAsAcceleration() {
2954         return estimatedCovariance != null
2955                 ? new Acceleration(getEstimatedBiasStandardDeviationNorm(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
2956                 : null;
2957     }
2958 
2959     /**
2960      * Gets norm of estimated standard deviation of accelerometer bias coordinates.
2961      * This can be used as the initial accelerometer bias uncertainty for
2962      * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
2963      *
2964      * @param result instance where result will be stored.
2965      * @return true if norm of estimated standard deviation of accelerometer bias is
2966      * available, false otherwise.
2967      */
2968     public boolean getEstimatedBiasStandardDeviationNormAsAcceleration(final Acceleration result) {
2969         if (estimatedCovariance != null) {
2970             result.setValue(getEstimatedBiasStandardDeviationNorm());
2971             result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2972             return true;
2973         } else {
2974             return false;
2975         }
2976     }
2977 
2978     /**
2979      * Gets size of subsets to be checked during robust estimation.
2980      * This has to be at least {@link #getMinimumRequiredMeasurements()}.
2981      *
2982      * @return size of subsets to be checked during robust estimation.
2983      */
2984     public int getPreliminarySubsetSize() {
2985         return preliminarySubsetSize;
2986     }
2987 
2988     /**
2989      * Sets size of subsets to be checked during robust estimation.
2990      * This has to be at least {@link #getMinimumRequiredMeasurements()}.
2991      *
2992      * @param preliminarySubsetSize size of subsets to be checked during robust estimation.
2993      * @throws LockedException          if calibrator is currently running.
2994      * @throws IllegalArgumentException if provided value is less than {@link #getMinimumRequiredMeasurements()}.
2995      */
2996     public void setPreliminarySubsetSize(final int preliminarySubsetSize) throws LockedException {
2997         if (running) {
2998             throw new LockedException();
2999         }
3000         if (preliminarySubsetSize < getMinimumRequiredMeasurements()) {
3001             throw new IllegalArgumentException();
3002         }
3003 
3004         this.preliminarySubsetSize = preliminarySubsetSize;
3005     }
3006 
3007     /**
3008      * Returns method being used for robust estimation.
3009      *
3010      * @return method being used for robust estimation.
3011      */
3012     public abstract RobustEstimatorMethod getMethod();
3013 
3014     /**
3015      * Creates a robust accelerometer calibrator.
3016      *
3017      * @param method robust estimator method.
3018      * @return a robust accelerometer calibrator.
3019      */
3020     public static RobustKnownPositionAccelerometerCalibrator create(final RobustEstimatorMethod method) {
3021         return switch (method) {
3022             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator();
3023             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator();
3024             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator();
3025             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator();
3026             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator();
3027         };
3028     }
3029 
3030     /**
3031      * Creates a robust accelerometer calibrator.
3032      *
3033      * @param listener listener to be notified of events such as when estimation
3034      *                 starts, ends or its progress significantly changes.
3035      * @param method   robust estimator method.
3036      * @return a robust accelerometer calibrator.
3037      */
3038     public static RobustKnownPositionAccelerometerCalibrator create(
3039             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3040         return switch (method) {
3041             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(listener);
3042             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(listener);
3043             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(listener);
3044             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(listener);
3045             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(listener);
3046         };
3047     }
3048 
3049     /**
3050      * Creates a robust accelerometer calibrator.
3051      *
3052      * @param measurements list of body kinematics measurements taken at a given position with
3053      *                     different unknown orientations and containing the standard deviations
3054      *                     of accelerometer and gyroscope measurements.
3055      * @param method       robust estimator method.
3056      * @return a robust accelerometer calibrator.
3057      */
3058     public static RobustKnownPositionAccelerometerCalibrator create(
3059             final List<StandardDeviationBodyKinematics> measurements, final RobustEstimatorMethod method) {
3060         return switch (method) {
3061             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(measurements);
3062             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(measurements);
3063             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(measurements);
3064             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(measurements);
3065             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(measurements);
3066         };
3067     }
3068 
3069     /**
3070      * Creates a robust accelerometer calibrator.
3071      *
3072      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3073      *                       accelerometer and gyroscope.
3074      * @param method         robust estimator method.
3075      * @return a robust accelerometer calibrator.
3076      */
3077     public static RobustKnownPositionAccelerometerCalibrator create(
3078             final boolean commonAxisUsed, final RobustEstimatorMethod method) {
3079         return switch (method) {
3080             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(commonAxisUsed);
3081             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(commonAxisUsed);
3082             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(commonAxisUsed);
3083             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(commonAxisUsed);
3084             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(commonAxisUsed);
3085         };
3086     }
3087 
3088     /**
3089      * Creates a robust accelerometer calibrator.
3090      *
3091      * @param initialBias initial accelerometer bias to be used to find a solution.
3092      *                    This must have length 3 and is expressed in meters per
3093      *                    squared second (m/s^2).
3094      * @param method      robust estimator method.
3095      * @return a robust accelerometer calibrator.
3096      * @throws IllegalArgumentException if provided bias array does not have length 3.
3097      */
3098     public static RobustKnownPositionAccelerometerCalibrator create(
3099             final double[] initialBias, final RobustEstimatorMethod method) {
3100         return switch (method) {
3101             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3102             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(initialBias);
3103             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3104             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3105             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(initialBias);
3106         };
3107     }
3108 
3109     /**
3110      * Creates a robust accelerometer calibrator.
3111      *
3112      * @param initialBias initial bias to find a solution.
3113      * @param method      robust estimator method.
3114      * @return a robust accelerometer calibrator.
3115      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3116      */
3117     public static RobustKnownPositionAccelerometerCalibrator create(
3118             final Matrix initialBias, final RobustEstimatorMethod method) {
3119         return switch (method) {
3120             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3121             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(initialBias);
3122             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3123             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(initialBias);
3124             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(initialBias);
3125         };
3126     }
3127 
3128     /**
3129      * Creates a robust accelerometer calibrator.
3130      *
3131      * @param initialBias initial bias to find a solution.
3132      * @param initialMa   initial scale factors and cross coupling errors matrix.
3133      * @param method      robust estimator method.
3134      * @return a robust accelerometer calibrator.
3135      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
3136      *                                  scaling and coupling error matrix is not 3x3.
3137      */
3138     public static RobustKnownPositionAccelerometerCalibrator create(
3139             final Matrix initialBias, final Matrix initialMa, final RobustEstimatorMethod method) {
3140         return switch (method) {
3141             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(initialBias, initialMa);
3142             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(initialBias, initialMa);
3143             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(initialBias, initialMa);
3144             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(initialBias, initialMa);
3145             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(initialBias, initialMa);
3146         };
3147     }
3148 
3149     /**
3150      * Creates a robust accelerometer calibrator.
3151      *
3152      * @param position position where body kinematics measures have been taken.
3153      * @param method   robust estimator method.
3154      * @return a robust accelerometer calibrator.
3155      */
3156     public static RobustKnownPositionAccelerometerCalibrator create(
3157             final ECEFPosition position, final RobustEstimatorMethod method) {
3158         return switch (method) {
3159             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position);
3160             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position);
3161             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position);
3162             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position);
3163             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position);
3164         };
3165     }
3166 
3167     /**
3168      * Creates a robust accelerometer calibrator.
3169      *
3170      * @param position     position where body kinematics measures have been taken.
3171      * @param measurements list of body kinematics measurements taken at a given position with
3172      *                     different unknown orientations and containing the standard deviations
3173      *                     of accelerometer and gyroscope measurements.
3174      * @param method       robust estimator method.
3175      * @return a robust accelerometer calibrator.
3176      */
3177     public static RobustKnownPositionAccelerometerCalibrator create(
3178             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3179             final RobustEstimatorMethod method) {
3180         return switch (method) {
3181             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3182             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
3183             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3184             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3185             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
3186         };
3187     }
3188 
3189     /**
3190      * Creates a robust accelerometer calibrator.
3191      *
3192      * @param position     position where body kinematics measures have been taken.
3193      * @param measurements list of body kinematics measurements taken at a given position with
3194      *                     different unknown orientations and containing the standard deviations
3195      *                     of accelerometer and gyroscope measurements.
3196      * @param listener     listener to be notified of events such as when estimation
3197      *                     starts, ends or its progress significantly changes.
3198      * @param method       robust estimator method.
3199      * @return a robust accelerometer calibrator.
3200      */
3201     public static RobustKnownPositionAccelerometerCalibrator create(
3202             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3203             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3204         return switch (method) {
3205             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3206             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3207             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3208             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3209             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3210         };
3211     }
3212 
3213     /**
3214      * Creates a robust accelerometer calibrator.
3215      *
3216      * @param position       position where body kinematics measures have been taken.
3217      * @param measurements   list of body kinematics measurements taken at a given position with
3218      *                       different unknown orientations and containing the standard deviations
3219      *                       of accelerometer and gyroscope measurements.
3220      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3221      *                       accelerometer and gyroscope.
3222      * @param method         robust estimator method.
3223      * @return a robust accelerometer calibrator.
3224      */
3225     public static RobustKnownPositionAccelerometerCalibrator create(
3226             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3227             final boolean commonAxisUsed, final RobustEstimatorMethod method) {
3228         return switch (method) {
3229             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3230                     position, measurements, commonAxisUsed);
3231             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3232                     position, measurements, commonAxisUsed);
3233             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3234                     position, measurements, commonAxisUsed);
3235             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3236                     position, measurements, commonAxisUsed);
3237             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3238                     position, measurements, commonAxisUsed);
3239         };
3240     }
3241 
3242     /**
3243      * Creates a robust accelerometer calibrator.
3244      *
3245      * @param position       position where body kinematics measures have been taken.
3246      * @param measurements   list of body kinematics measurements taken at a given position with
3247      *                       different unknown orientations and containing the standard deviations
3248      *                       of accelerometer and gyroscope measurements.
3249      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3250      *                       accelerometer and gyroscope.
3251      * @param listener       listener to be notified of events such as when estimation
3252      *                       starts, ends or its progress significantly changes.
3253      * @param method         robust estimator method.
3254      * @return a robust accelerometer calibrator.
3255      */
3256     public static RobustKnownPositionAccelerometerCalibrator create(
3257             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3258             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener,
3259             final RobustEstimatorMethod method) {
3260         return switch (method) {
3261             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3262                     position, measurements, commonAxisUsed, listener);
3263             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3264                     position, measurements, commonAxisUsed, listener);
3265             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3266                     position, measurements, commonAxisUsed, listener);
3267             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3268                     position, measurements, commonAxisUsed, listener);
3269             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3270                     position, measurements, commonAxisUsed, listener);
3271         };
3272     }
3273 
3274     /**
3275      * Creates a robust accelerometer calibrator.
3276      *
3277      * @param position     position where body kinematics measures have been taken.
3278      * @param measurements collection of body kinematics measurements with standard
3279      *                     deviations taken at the same position with zero velocity
3280      *                     and unknown different orientations.
3281      * @param initialBias  initial accelerometer bias to be used to find a solution.
3282      *                     This must have length 3 and is expressed in meters per
3283      *                     squared second (m/s^2).
3284      * @param method       robust estimator method.
3285      * @return a robust accelerometer calibrator.
3286      * @throws IllegalArgumentException if provided bias array does not have length 3.
3287      */
3288     public static RobustKnownPositionAccelerometerCalibrator create(
3289             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3290             final double[] initialBias, final RobustEstimatorMethod method) {
3291         return switch (method) {
3292             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3293             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3294             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3295             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3296             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3297         };
3298     }
3299 
3300     /**
3301      * Creates a robust accelerometer calibrator.
3302      *
3303      * @param position     position where body kinematics measures have been taken.
3304      * @param measurements collection of body kinematics measurements with standard
3305      *                     deviations taken at the same position with zero velocity
3306      *                     and unknown different orientations.
3307      * @param initialBias  initial accelerometer bias to be used to find a solution.
3308      *                     This must have length 3 and is expressed in meters per
3309      *                     squared second (m/s^2).
3310      * @param listener     listener to handle events raised by this calibrator.
3311      * @param method       robust estimator method.
3312      * @return a robust accelerometer calibrator.
3313      * @throws IllegalArgumentException if provided bias array does not have length 3.
3314      */
3315     public static RobustKnownPositionAccelerometerCalibrator create(
3316             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3317             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
3318             final RobustEstimatorMethod method) {
3319         return switch (method) {
3320             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3321                     measurements, initialBias, listener);
3322             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3323                     measurements, initialBias, listener);
3324             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3325                     measurements, initialBias, listener);
3326             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3327                     measurements, initialBias, listener);
3328             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3329                     measurements, initialBias, listener);
3330         };
3331     }
3332 
3333     /**
3334      * Creates a robust accelerometer calibrator.
3335      *
3336      * @param position       position where body kinematics measures have been taken.
3337      * @param measurements   collection of body kinematics measurements with standard
3338      *                       deviations taken at the same position with zero velocity
3339      *                       and unknown different orientations.
3340      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3341      *                       accelerometer and gyroscope.
3342      * @param initialBias    initial accelerometer bias to be used to find a solution.
3343      *                       This must have length 3 and is expressed in meters per
3344      *                       squared second (m/s^2).
3345      * @param method         robust estimator method.
3346      * @return a robust accelerometer calibrator.
3347      * @throws IllegalArgumentException if provided bias array does not have length 3.
3348      */
3349     public static RobustKnownPositionAccelerometerCalibrator create(
3350             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3351             final boolean commonAxisUsed, final double[] initialBias, final RobustEstimatorMethod method) {
3352         return switch (method) {
3353             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3354                     measurements, commonAxisUsed, initialBias);
3355             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3356                     measurements, commonAxisUsed, initialBias);
3357             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3358                     measurements, commonAxisUsed, initialBias);
3359             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3360                     measurements, commonAxisUsed, initialBias);
3361             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3362                     measurements, commonAxisUsed, initialBias);
3363         };
3364     }
3365 
3366     /**
3367      * Creates a robust accelerometer calibrator.
3368      *
3369      * @param position       position where body kinematics measures have been taken.
3370      * @param measurements   collection of body kinematics measurements with standard
3371      *                       deviations taken at the same position with zero velocity
3372      *                       and unknown different orientations.
3373      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3374      *                       accelerometer and gyroscope.
3375      * @param initialBias    initial accelerometer bias to be used to find a solution.
3376      *                       This must have length 3 and is expressed in meters per
3377      *                       squared second (m/s^2).
3378      * @param listener       listener to handle events raised by this calibrator.
3379      * @param method         robust estimator method.
3380      * @return a robust accelerometer calibrator.
3381      * @throws IllegalArgumentException if provided bias array does not have length 3.
3382      */
3383     public static RobustKnownPositionAccelerometerCalibrator create(
3384             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3385             final boolean commonAxisUsed, final double[] initialBias,
3386             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3387         return switch (method) {
3388             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3389                     measurements, commonAxisUsed, initialBias, listener);
3390             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3391                     measurements, commonAxisUsed, initialBias, listener);
3392             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3393                     measurements, commonAxisUsed, initialBias, listener);
3394             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3395                     measurements, commonAxisUsed, initialBias, listener);
3396             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3397                     measurements, commonAxisUsed, initialBias, listener);
3398         };
3399     }
3400 
3401     /**
3402      * Creates a robust accelerometer calibrator.
3403      *
3404      * @param position     position where body kinematics measures have been taken.
3405      * @param measurements collection of body kinematics measurements with standard
3406      *                     deviations taken at the same position with zero velocity
3407      *                     and unknown different orientations.
3408      * @param initialBias  initial bias to find a solution.
3409      * @param method       robust estimator method.
3410      * @return a robust accelerometer calibrator.
3411      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3412      */
3413     public static RobustKnownPositionAccelerometerCalibrator create(
3414             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3415             final Matrix initialBias, final RobustEstimatorMethod method) {
3416         return switch (method) {
3417             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3418             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3419             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3420             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3421             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3422         };
3423     }
3424 
3425     /**
3426      * Creates a robust accelerometer calibrator.
3427      *
3428      * @param position     position where body kinematics measures have been taken.
3429      * @param measurements collection of body kinematics measurements with standard
3430      *                     deviations taken at the same position with zero velocity
3431      *                     and unknown different orientations.
3432      * @param initialBias  initial bias to find a solution.
3433      * @param listener     listener to handle events raised by this calibrator.
3434      * @param method       robust estimator method.
3435      * @return a robust accelerometer calibrator.
3436      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3437      */
3438     public static RobustKnownPositionAccelerometerCalibrator create(
3439             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3440             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
3441             final RobustEstimatorMethod method) {
3442         return switch (method) {
3443             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3444                     position, measurements, initialBias, listener);
3445             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3446                     position, measurements, initialBias, listener);
3447             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3448                     position, measurements, initialBias, listener);
3449             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3450                     position, measurements, initialBias, listener);
3451             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3452                     position, measurements, initialBias, listener);
3453         };
3454     }
3455 
3456     /**
3457      * Creates a robust accelerometer calibrator.
3458      *
3459      * @param position       position where body kinematics measures have been taken.
3460      * @param measurements   collection of body kinematics measurements with standard
3461      *                       deviations taken at the same position with zero velocity
3462      *                       and unknown different orientations.
3463      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3464      *                       accelerometer and gyroscope.
3465      * @param initialBias    initial bias to find a solution.
3466      * @param method         robust estimator method.
3467      * @return a robust accelerometer calibrator.
3468      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3469      */
3470     public static RobustKnownPositionAccelerometerCalibrator create(
3471             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3472             final boolean commonAxisUsed, final Matrix initialBias, final RobustEstimatorMethod method) {
3473         return switch (method) {
3474             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3475                     position, measurements, commonAxisUsed, initialBias);
3476             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3477                     position, measurements, commonAxisUsed, initialBias);
3478             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3479                     position, measurements, commonAxisUsed, initialBias);
3480             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3481                     position, measurements, commonAxisUsed, initialBias);
3482             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3483                     position, measurements, commonAxisUsed, initialBias);
3484         };
3485     }
3486 
3487     /**
3488      * Creates a robust accelerometer calibrator.
3489      *
3490      * @param position       position where body kinematics measures have been taken.
3491      * @param measurements   collection of body kinematics measurements with standard
3492      *                       deviations taken at the same position with zero velocity
3493      *                       and unknown different orientations.
3494      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3495      *                       accelerometer and gyroscope.
3496      * @param initialBias    initial bias to find a solution.
3497      * @param listener       listener to handle events raised by this calibrator.
3498      * @param method         robust estimator method.
3499      * @return a robust accelerometer calibrator.
3500      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3501      */
3502     public static RobustKnownPositionAccelerometerCalibrator create(
3503             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3504             final boolean commonAxisUsed, final Matrix initialBias,
3505             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3506         return switch (method) {
3507             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3508                     position, measurements, commonAxisUsed, initialBias, listener);
3509             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3510                     position, measurements, commonAxisUsed, initialBias, listener);
3511             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3512                     position, measurements, commonAxisUsed, initialBias, listener);
3513             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3514                     position, measurements, commonAxisUsed, initialBias, listener);
3515             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3516                     position, measurements, commonAxisUsed, initialBias, listener);
3517         };
3518     }
3519 
3520     /**
3521      * Creates a robust accelerometer calibrator.
3522      *
3523      * @param position     position where body kinematics measures have been taken.
3524      * @param measurements collection of body kinematics measurements with standard
3525      *                     deviations taken at the same position with zero velocity
3526      *                     and unknown different orientations.
3527      * @param initialBias  initial bias to find a solution.
3528      * @param initialMa    initial scale factors and cross coupling errors matrix.
3529      * @param method       robust estimator method.
3530      * @return a robust accelerometer calibrator.
3531      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
3532      *                                  scaling and coupling error matrix is not 3x3.
3533      */
3534     public static RobustKnownPositionAccelerometerCalibrator create(
3535             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3536             final Matrix initialBias, final Matrix initialMa, final RobustEstimatorMethod method) {
3537         return switch (method) {
3538             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3539                     position, measurements, initialBias, initialMa);
3540             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3541                     position, measurements, initialBias, initialMa);
3542             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3543                     position, measurements, initialBias, initialMa);
3544             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3545                     position, measurements, initialBias, initialMa);
3546             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3547                     position, measurements, initialBias, initialMa);
3548         };
3549     }
3550 
3551     /**
3552      * Creates a robust accelerometer calibrator.
3553      *
3554      * @param position     position where body kinematics measures have been taken.
3555      * @param measurements collection of body kinematics measurements with standard
3556      *                     deviations taken at the same position with zero velocity
3557      *                     and unknown different orientations.
3558      * @param initialBias  initial bias to find a solution.
3559      * @param initialMa    initial scale factors and cross coupling errors matrix.
3560      * @param listener     listener to handle events raised by this calibrator.
3561      * @param method       robust estimator method.
3562      * @return a robust accelerometer calibrator.
3563      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
3564      *                                  scaling and coupling error matrix is not 3x3.
3565      */
3566     public static RobustKnownPositionAccelerometerCalibrator create(
3567             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3568             final Matrix initialBias, final Matrix initialMa,
3569             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3570         return switch (method) {
3571             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3572                     position, measurements, initialBias, initialMa, listener);
3573             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3574                     position, measurements, initialBias, initialMa, listener);
3575             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3576                     position, measurements, initialBias, initialMa, listener);
3577             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3578                     position, measurements, initialBias, initialMa, listener);
3579             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3580                     position, measurements, initialBias, initialMa, listener);
3581         };
3582     }
3583 
3584     /**
3585      * Creates a robust accelerometer calibrator.
3586      *
3587      * @param position       position where body kinematics measures have been taken.
3588      * @param measurements   collection of body kinematics measurements with standard
3589      *                       deviations taken at the same position with zero velocity
3590      *                       and unknown different orientations.
3591      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3592      *                       accelerometer and gyroscope.
3593      * @param initialBias    initial bias to find a solution.
3594      * @param initialMa      initial scale factors and cross coupling errors matrix.
3595      * @param method         robust estimator method.
3596      * @return a robust accelerometer calibrator.
3597      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
3598      *                                  scaling and coupling error matrix is not 3x3.
3599      */
3600     public static RobustKnownPositionAccelerometerCalibrator create(
3601             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3602             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
3603             final RobustEstimatorMethod method) {
3604         return switch (method) {
3605             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3606                     position, measurements, commonAxisUsed, initialBias, initialMa);
3607             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3608                     position, measurements, commonAxisUsed, initialBias, initialMa);
3609             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3610                     position, measurements, commonAxisUsed, initialBias, initialMa);
3611             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3612                     position, measurements, commonAxisUsed, initialBias, initialMa);
3613             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3614                     position, measurements, commonAxisUsed, initialBias, initialMa);
3615         };
3616     }
3617 
3618     /**
3619      * Creates a robust accelerometer calibrator.
3620      *
3621      * @param position       position where body kinematics measures have been taken.
3622      * @param measurements   collection of body kinematics measurements with standard
3623      *                       deviations taken at the same position with zero velocity
3624      *                       and unknown different orientations.
3625      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3626      *                       accelerometer and gyroscope.
3627      * @param initialBias    initial bias to find a solution.
3628      * @param initialMa      initial scale factors and cross coupling errors matrix.
3629      * @param listener       listener to handle events raised by this calibrator.
3630      * @param method         robust estimator method.
3631      * @return a robust accelerometer calibrator.
3632      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
3633      *                                  scaling and coupling error matrix is not 3x3.
3634      */
3635     public static RobustKnownPositionAccelerometerCalibrator create(
3636             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
3637             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
3638             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3639         return switch (method) {
3640             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3641                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
3642             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3643                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
3644             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3645                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
3646             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3647                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
3648             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3649                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
3650         };
3651     }
3652 
3653     /**
3654      * Creates a robust accelerometer calibrator.
3655      *
3656      * @param position position where body kinematics measures have been taken.
3657      * @param method   robust estimator method.
3658      * @return a robust accelerometer calibrator.
3659      */
3660     public static RobustKnownPositionAccelerometerCalibrator create(
3661             final NEDPosition position, final RobustEstimatorMethod method) {
3662         return switch (method) {
3663             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position);
3664             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position);
3665             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position);
3666             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position);
3667             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position);
3668         };
3669     }
3670 
3671     /**
3672      * Creates a robust accelerometer calibrator.
3673      *
3674      * @param position     position where body kinematics measures have been taken.
3675      * @param measurements list of body kinematics measurements taken at a given position with
3676      *                     different unknown orientations and containing the standard deviations
3677      *                     of accelerometer and gyroscope measurements.
3678      * @param method       robust estimator method.
3679      * @return a robust accelerometer calibrator.
3680      */
3681     public static RobustKnownPositionAccelerometerCalibrator create(
3682             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3683             final RobustEstimatorMethod method) {
3684         return switch (method) {
3685             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3686             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
3687             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3688             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
3689             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
3690         };
3691     }
3692 
3693     /**
3694      * Creates a robust accelerometer calibrator.
3695      *
3696      * @param position     position where body kinematics measures have been taken.
3697      * @param measurements list of body kinematics measurements taken at a given position with
3698      *                     different unknown orientations and containing the standard deviations
3699      *                     of accelerometer and gyroscope measurements.
3700      * @param listener     listener to be notified of events such as when estimation
3701      *                     starts, ends or its progress significantly changes.
3702      * @param method       robust estimator method.
3703      * @return a robust accelerometer calibrator.
3704      */
3705     public static RobustKnownPositionAccelerometerCalibrator create(
3706             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3707             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3708         return switch (method) {
3709             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3710             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3711             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3712             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3713             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
3714         };
3715     }
3716 
3717     /**
3718      * Creates a robust accelerometer calibrator.
3719      *
3720      * @param position       position where body kinematics measures have been taken.
3721      * @param measurements   list of body kinematics measurements taken at a given position with
3722      *                       different unknown orientations and containing the standard deviations
3723      *                       of accelerometer and gyroscope measurements.
3724      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3725      *                       accelerometer and gyroscope.
3726      * @param method         robust estimator method.
3727      * @return a robust accelerometer calibrator.
3728      */
3729     public static RobustKnownPositionAccelerometerCalibrator create(
3730             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3731             final boolean commonAxisUsed, final RobustEstimatorMethod method) {
3732         return switch (method) {
3733             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3734                     position, measurements, commonAxisUsed);
3735             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3736                     position, measurements, commonAxisUsed);
3737             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3738                     position, measurements, commonAxisUsed);
3739             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3740                     position, measurements, commonAxisUsed);
3741             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3742                     position, measurements, commonAxisUsed);
3743         };
3744     }
3745 
3746     /**
3747      * Creates a robust accelerometer calibrator.
3748      *
3749      * @param position       position where body kinematics measures have been taken.
3750      * @param measurements   list of body kinematics measurements taken at a given position with
3751      *                       different unknown orientations and containing the standard deviations
3752      *                       of accelerometer and gyroscope measurements.
3753      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3754      *                       accelerometer and gyroscope.
3755      * @param listener       listener to be notified of events such as when estimation
3756      *                       starts, ends or its progress significantly changes.
3757      * @param method         robust estimator method.
3758      * @return a robust accelerometer calibrator.
3759      */
3760     public static RobustKnownPositionAccelerometerCalibrator create(
3761             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3762             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener,
3763             final RobustEstimatorMethod method) {
3764         return switch (method) {
3765             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3766                     position, measurements, commonAxisUsed, listener);
3767             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3768                     position, measurements, commonAxisUsed, listener);
3769             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3770                     position, measurements, commonAxisUsed, listener);
3771             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3772                     position, measurements, commonAxisUsed, listener);
3773             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3774                     position, measurements, commonAxisUsed, listener);
3775         };
3776     }
3777 
3778     /**
3779      * Creates a robust accelerometer calibrator.
3780      *
3781      * @param position     position where body kinematics measures have been taken.
3782      * @param measurements collection of body kinematics measurements with standard
3783      *                     deviations taken at the same position with zero velocity
3784      *                     and unknown different orientations.
3785      * @param initialBias  initial accelerometer bias to be used to find a solution.
3786      *                     This must have length 3 and is expressed in meters per
3787      *                     squared second (m/s^2).
3788      * @param method       robust estimator method.
3789      * @return a robust accelerometer calibrator.
3790      * @throws IllegalArgumentException if provided bias array does not have length 3.
3791      */
3792     public static RobustKnownPositionAccelerometerCalibrator create(
3793             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3794             final double[] initialBias, final RobustEstimatorMethod method) {
3795         return switch (method) {
3796             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3797             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3798             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3799             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3800             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3801         };
3802     }
3803 
3804     /**
3805      * Creates a robust accelerometer calibrator.
3806      *
3807      * @param position     position where body kinematics measures have been taken.
3808      * @param measurements collection of body kinematics measurements with standard
3809      *                     deviations taken at the same position with zero velocity
3810      *                     and unknown different orientations.
3811      * @param initialBias  initial accelerometer bias to be used to find a solution.
3812      *                     This must have length 3 and is expressed in meters per
3813      *                     squared second (m/s^2).
3814      * @param listener     listener to handle events raised by this calibrator.
3815      * @param method       robust estimator method.
3816      * @return a robust accelerometer calibrator.
3817      * @throws IllegalArgumentException if provided bias array does not have length 3.
3818      */
3819     public static RobustKnownPositionAccelerometerCalibrator create(
3820             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3821             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
3822             final RobustEstimatorMethod method) {
3823         return switch (method) {
3824             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3825                     measurements, initialBias, listener);
3826             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3827                     measurements, initialBias, listener);
3828             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3829                     measurements, initialBias, listener);
3830             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3831                     measurements, initialBias, listener);
3832             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3833                     measurements, initialBias, listener);
3834         };
3835     }
3836 
3837     /**
3838      * Creates a robust accelerometer calibrator.
3839      *
3840      * @param position       position where body kinematics measures have been taken.
3841      * @param measurements   collection of body kinematics measurements with standard
3842      *                       deviations taken at the same position with zero velocity
3843      *                       and unknown different orientations.
3844      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3845      *                       accelerometer and gyroscope.
3846      * @param initialBias    initial accelerometer bias to be used to find a solution.
3847      *                       This must have length 3 and is expressed in meters per
3848      *                       squared second (m/s^2).
3849      * @param method         robust estimator method.
3850      * @return a robust accelerometer calibrator.
3851      * @throws IllegalArgumentException if provided bias array does not have length 3.
3852      */
3853     public static RobustKnownPositionAccelerometerCalibrator create(
3854             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3855             final boolean commonAxisUsed, final double[] initialBias, final RobustEstimatorMethod method) {
3856         return switch (method) {
3857             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3858                     measurements, commonAxisUsed, initialBias);
3859             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3860                     measurements, commonAxisUsed, initialBias);
3861             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3862                     measurements, commonAxisUsed, initialBias);
3863             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3864                     measurements, commonAxisUsed, initialBias);
3865             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3866                     measurements, commonAxisUsed, initialBias);
3867         };
3868     }
3869 
3870     /**
3871      * Creates a robust accelerometer calibrator.
3872      *
3873      * @param position       position where body kinematics measures have been taken.
3874      * @param measurements   collection of body kinematics measurements with standard
3875      *                       deviations taken at the same position with zero velocity
3876      *                       and unknown different orientations.
3877      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3878      *                       accelerometer and gyroscope.
3879      * @param initialBias    initial accelerometer bias to be used to find a solution.
3880      *                       This must have length 3 and is expressed in meters per
3881      *                       squared second (m/s^2).
3882      * @param listener       listener to handle events raised by this calibrator.
3883      * @param method         robust estimator method.
3884      * @return a robust accelerometer calibrator.
3885      * @throws IllegalArgumentException if provided bias array does not have length 3.
3886      */
3887     public static RobustKnownPositionAccelerometerCalibrator create(
3888             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3889             final boolean commonAxisUsed, final double[] initialBias,
3890             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
3891         return switch (method) {
3892             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position,
3893                     measurements, commonAxisUsed, initialBias, listener);
3894             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position,
3895                     measurements, commonAxisUsed, initialBias, listener);
3896             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position,
3897                     measurements, commonAxisUsed, initialBias, listener);
3898             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position,
3899                     measurements, commonAxisUsed, initialBias, listener);
3900             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position,
3901                     measurements, commonAxisUsed, initialBias, listener);
3902         };
3903     }
3904 
3905     /**
3906      * Creates a robust accelerometer calibrator.
3907      *
3908      * @param position     position where body kinematics measures have been taken.
3909      * @param measurements collection of body kinematics measurements with standard
3910      *                     deviations taken at the same position with zero velocity
3911      *                     and unknown different orientations.
3912      * @param initialBias  initial bias to find a solution.
3913      * @param method       robust estimator method.
3914      * @return a robust accelerometer calibrator.
3915      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3916      */
3917     public static RobustKnownPositionAccelerometerCalibrator create(
3918             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3919             final Matrix initialBias, final RobustEstimatorMethod method) {
3920         return switch (method) {
3921             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3922             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3923             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3924             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3925             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
3926         };
3927     }
3928 
3929     /**
3930      * Creates a robust accelerometer calibrator.
3931      *
3932      * @param position     position where body kinematics measures have been taken.
3933      * @param measurements collection of body kinematics measurements with standard
3934      *                     deviations taken at the same position with zero velocity
3935      *                     and unknown different orientations.
3936      * @param initialBias  initial bias to find a solution.
3937      * @param listener     listener to handle events raised by this calibrator.
3938      * @param method       robust estimator method.
3939      * @return a robust accelerometer calibrator.
3940      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3941      */
3942     public static RobustKnownPositionAccelerometerCalibrator create(
3943             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3944             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
3945             final RobustEstimatorMethod method) {
3946         return switch (method) {
3947             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3948                     position, measurements, initialBias, listener);
3949             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3950                     position, measurements, initialBias, listener);
3951             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3952                     position, measurements, initialBias, listener);
3953             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3954                     position, measurements, initialBias, listener);
3955             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3956                     position, measurements, initialBias, listener);
3957         };
3958     }
3959 
3960     /**
3961      * Creates a robust accelerometer calibrator.
3962      *
3963      * @param position       position where body kinematics measures have been taken.
3964      * @param measurements   collection of body kinematics measurements with standard
3965      *                       deviations taken at the same position with zero velocity
3966      *                       and unknown different orientations.
3967      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3968      *                       accelerometer and gyroscope.
3969      * @param initialBias    initial bias to find a solution.
3970      * @param method         robust estimator method.
3971      * @return a robust accelerometer calibrator.
3972      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
3973      */
3974     public static RobustKnownPositionAccelerometerCalibrator create(
3975             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
3976             final boolean commonAxisUsed, final Matrix initialBias, final RobustEstimatorMethod method) {
3977         return switch (method) {
3978             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
3979                     position, measurements, commonAxisUsed, initialBias);
3980             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
3981                     position, measurements, commonAxisUsed, initialBias);
3982             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
3983                     position, measurements, commonAxisUsed, initialBias);
3984             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
3985                     position, measurements, commonAxisUsed, initialBias);
3986             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
3987                     position, measurements, commonAxisUsed, initialBias);
3988         };
3989     }
3990 
3991     /**
3992      * Creates a robust accelerometer calibrator.
3993      *
3994      * @param position       position where body kinematics measures have been taken.
3995      * @param measurements   collection of body kinematics measurements with standard
3996      *                       deviations taken at the same position with zero velocity
3997      *                       and unknown different orientations.
3998      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
3999      *                       accelerometer and gyroscope.
4000      * @param initialBias    initial bias to find a solution.
4001      * @param listener       listener to handle events raised by this calibrator.
4002      * @param method         robust estimator method.
4003      * @return a robust accelerometer calibrator.
4004      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
4005      */
4006     public static RobustKnownPositionAccelerometerCalibrator create(
4007             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
4008             final boolean commonAxisUsed, final Matrix initialBias,
4009             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4010         return switch (method) {
4011             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4012                     position, measurements, commonAxisUsed, initialBias, listener);
4013             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4014                     position, measurements, commonAxisUsed, initialBias, listener);
4015             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4016                     position, measurements, commonAxisUsed, initialBias, listener);
4017             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4018                     position, measurements, commonAxisUsed, initialBias, listener);
4019             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4020                     position, measurements, commonAxisUsed, initialBias, listener);
4021         };
4022     }
4023 
4024     /**
4025      * Creates a robust accelerometer calibrator.
4026      *
4027      * @param position     position where body kinematics measures have been taken.
4028      * @param measurements collection of body kinematics measurements with standard
4029      *                     deviations taken at the same position with zero velocity
4030      *                     and unknown different orientations.
4031      * @param initialBias  initial bias to find a solution.
4032      * @param initialMa    initial scale factors and cross coupling errors matrix.
4033      * @param method       robust estimator method.
4034      * @return a robust accelerometer calibrator.
4035      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4036      *                                  scaling and coupling error matrix is not 3x3.
4037      */
4038     public static RobustKnownPositionAccelerometerCalibrator create(
4039             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
4040             final Matrix initialBias, final Matrix initialMa, final RobustEstimatorMethod method) {
4041         return switch (method) {
4042             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4043                     position, measurements, initialBias, initialMa);
4044             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4045                     position, measurements, initialBias, initialMa);
4046             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4047                     position, measurements, initialBias, initialMa);
4048             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4049                     position, measurements, initialBias, initialMa);
4050             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4051                     position, measurements, initialBias, initialMa);
4052         };
4053     }
4054 
4055     /**
4056      * Creates a robust accelerometer calibrator.
4057      *
4058      * @param position     position where body kinematics measures have been taken.
4059      * @param measurements collection of body kinematics measurements with standard
4060      *                     deviations taken at the same position with zero velocity
4061      *                     and unknown different orientations.
4062      * @param initialBias  initial bias to find a solution.
4063      * @param initialMa    initial scale factors and cross coupling errors matrix.
4064      * @param listener     listener to handle events raised by this calibrator.
4065      * @param method       robust estimator method.
4066      * @return a robust accelerometer calibrator.
4067      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4068      *                                  scaling and coupling error matrix is not 3x3.
4069      */
4070     public static RobustKnownPositionAccelerometerCalibrator create(
4071             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
4072             final Matrix initialBias, final Matrix initialMa,
4073             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4074         return switch (method) {
4075             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4076                     position, measurements, initialBias, initialMa, listener);
4077             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4078                     position, measurements, initialBias, initialMa, listener);
4079             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4080                     position, measurements, initialBias, initialMa, listener);
4081             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4082                     position, measurements, initialBias, initialMa, listener);
4083             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4084                     position, measurements, initialBias, initialMa, listener);
4085         };
4086     }
4087 
4088     /**
4089      * Creates a robust accelerometer calibrator.
4090      *
4091      * @param position       position where body kinematics measures have been taken.
4092      * @param measurements   collection of body kinematics measurements with standard
4093      *                       deviations taken at the same position with zero velocity
4094      *                       and unknown different orientations.
4095      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4096      *                       accelerometer and gyroscope.
4097      * @param initialBias    initial bias to find a solution.
4098      * @param initialMa      initial scale factors and cross coupling errors matrix.
4099      * @param method         robust estimator method.
4100      * @return a robust accelerometer calibrator.
4101      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4102      *                                  scaling and coupling error matrix is not 3x3.
4103      */
4104     public static RobustKnownPositionAccelerometerCalibrator create(
4105             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
4106             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
4107             final RobustEstimatorMethod method) {
4108         return switch (method) {
4109             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4110                     position, measurements, commonAxisUsed, initialBias, initialMa);
4111             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4112                     position, measurements, commonAxisUsed, initialBias, initialMa);
4113             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4114                     position, measurements, commonAxisUsed, initialBias, initialMa);
4115             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4116                     position, measurements, commonAxisUsed, initialBias, initialMa);
4117             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4118                     position, measurements, commonAxisUsed, initialBias, initialMa);
4119         };
4120     }
4121 
4122     /**
4123      * Creates a robust accelerometer calibrator.
4124      *
4125      * @param position       position where body kinematics measures have been taken.
4126      * @param measurements   collection of body kinematics measurements with standard
4127      *                       deviations taken at the same position with zero velocity
4128      *                       and unknown different orientations.
4129      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4130      *                       accelerometer and gyroscope.
4131      * @param initialBias    initial bias to find a solution.
4132      * @param initialMa      initial scale factors and cross coupling errors matrix.
4133      * @param listener       listener to handle events raised by this calibrator.
4134      * @param method         robust estimator method.
4135      * @return a robust accelerometer calibrator.
4136      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4137      *                                  scaling and coupling error matrix is not 3x3.
4138      */
4139     public static RobustKnownPositionAccelerometerCalibrator create(
4140             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
4141             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
4142             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4143         return switch (method) {
4144             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4145                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4146             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4147                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4148             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4149                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4150             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4151                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4152             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4153                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4154         };
4155     }
4156 
4157     /**
4158      * Creates a robust accelerometer calibrator.
4159      *
4160      * @param qualityScores quality scores corresponding to each provided
4161      *                      measurement. The larger the score value the better
4162      *                      the quality of the sample.
4163      * @param position      position where body kinematics measures have been taken.
4164      * @param measurements  list of body kinematics measurements taken at a given position with
4165      *                      different unknown orientations and containing the standard deviations
4166      *                      of accelerometer and gyroscope measurements.
4167      * @param method        robust estimator method.
4168      * @return a robust accelerometer calibrator.
4169      * @throws IllegalArgumentException if provided quality scores length
4170      *                                  is smaller than 13 samples.
4171      */
4172     public static RobustKnownPositionAccelerometerCalibrator create(
4173             final double[] qualityScores, final ECEFPosition position,
4174             final List<StandardDeviationBodyKinematics> measurements, final RobustEstimatorMethod method) {
4175         return switch (method) {
4176             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
4177             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
4178             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
4179             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(qualityScores, position, measurements);
4180             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(qualityScores, position, measurements);
4181         };
4182     }
4183 
4184     /**
4185      * Creates a robust accelerometer calibrator.
4186      *
4187      * @param qualityScores quality scores corresponding to each provided
4188      *                      measurement. The larger the score value the better
4189      *                      the quality of the sample.
4190      * @param position      position where body kinematics measures have been taken.
4191      * @param measurements  list of body kinematics measurements taken at a given position with
4192      *                      different unknown orientations and containing the standard deviations
4193      *                      of accelerometer and gyroscope measurements.
4194      * @param listener      listener to be notified of events such as when estimation
4195      *                      starts, ends or its progress significantly changes.
4196      * @param method        robust estimator method.
4197      * @return a robust accelerometer calibrator.
4198      * @throws IllegalArgumentException if provided quality scores length
4199      *                                  is smaller than 13 samples.
4200      */
4201     public static RobustKnownPositionAccelerometerCalibrator create(
4202             final double[] qualityScores, final ECEFPosition position,
4203             final List<StandardDeviationBodyKinematics> measurements,
4204             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4205         return switch (method) {
4206             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4207             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4208             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4209             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4210                     qualityScores, position, measurements, listener);
4211             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4212                     qualityScores, position, measurements, listener);
4213         };
4214     }
4215 
4216     /**
4217      * Creates a robust accelerometer calibrator.
4218      *
4219      * @param qualityScores  quality scores corresponding to each provided
4220      *                       measurement. The larger the score value the better
4221      *                       the quality of the sample.
4222      * @param position       position where body kinematics measures have been taken.
4223      * @param measurements   list of body kinematics measurements taken at a given position with
4224      *                       different unknown orientations and containing the standard deviations
4225      *                       of accelerometer and gyroscope measurements.
4226      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4227      *                       accelerometer and gyroscope. If true 10 samples are
4228      *                       required, otherwise 13.
4229      * @param method         robust estimator method.
4230      * @return a robust accelerometer calibrator.
4231      * @throws IllegalArgumentException if provided quality scores length
4232      *                                  is smaller than the minimum number of
4233      *                                  required samples (10 or 13).
4234      */
4235     public static RobustKnownPositionAccelerometerCalibrator create(
4236             final double[] qualityScores, final ECEFPosition position,
4237             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4238             final RobustEstimatorMethod method) {
4239         return switch (method) {
4240             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4241             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4242             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4243             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4244                     qualityScores, position, measurements, commonAxisUsed);
4245             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4246                     qualityScores, position, measurements, commonAxisUsed);
4247         };
4248     }
4249 
4250     /**
4251      * Creates a robust accelerometer calibrator.
4252      *
4253      * @param qualityScores  quality scores corresponding to each provided
4254      *                       measurement. The larger the score value the better
4255      *                       the quality of the sample.
4256      * @param position       position where body kinematics measures have been taken.
4257      * @param measurements   list of body kinematics measurements taken at a given position with
4258      *                       different unknown orientations and containing the standard deviations
4259      *                       of accelerometer and gyroscope measurements.
4260      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4261      *                       accelerometer and gyroscope. If true 10 samples are
4262      *                       required, otherwise 13.
4263      * @param listener       listener to be notified of events such as when estimation
4264      *                       starts, ends or its progress significantly changes.
4265      * @param method         robust estimator method.
4266      * @return a robust accelerometer calibrator.
4267      * @throws IllegalArgumentException if provided quality scores length
4268      *                                  is smaller than the minimum number of
4269      *                                  required samples (10 or 13).
4270      */
4271     public static RobustKnownPositionAccelerometerCalibrator create(
4272             final double[] qualityScores, final ECEFPosition position,
4273             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4274             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4275         return switch (method) {
4276             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4277                     position, measurements, commonAxisUsed, listener);
4278             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4279                     position, measurements, commonAxisUsed, listener);
4280             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4281                     position, measurements, commonAxisUsed, listener);
4282             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4283                     qualityScores, position, measurements, commonAxisUsed, listener);
4284             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4285                     qualityScores, position, measurements, commonAxisUsed, listener);
4286         };
4287     }
4288 
4289     /**
4290      * Creates a robust accelerometer calibrator.
4291      *
4292      * @param qualityScores quality scores corresponding to each provided
4293      *                      measurement. The larger the score value the better
4294      *                      the quality of the sample.
4295      * @param position      position where body kinematics measures have been taken.
4296      * @param measurements  collection of body kinematics measurements with standard
4297      *                      deviations taken at the same position with zero velocity
4298      *                      and unknown different orientations.
4299      * @param initialBias   initial accelerometer bias to be used to find a solution.
4300      *                      This must have length 3 and is expressed in meters per
4301      *                      squared second (m/s^2).
4302      * @param method        robust estimator method.
4303      * @return a robust accelerometer calibrator.
4304      * @throws IllegalArgumentException if provided bias array does not have length 3
4305      *                                  or quality scores array is smaller than 13
4306      *                                  samples.
4307      */
4308     public static RobustKnownPositionAccelerometerCalibrator create(
4309             final double[] qualityScores, final ECEFPosition position,
4310             final List<StandardDeviationBodyKinematics> measurements, final double[] initialBias,
4311             final RobustEstimatorMethod method) {
4312         return switch (method) {
4313             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4314             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4315             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4316             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4317                     qualityScores, position, measurements, initialBias);
4318             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4319                     qualityScores, position, measurements, initialBias);
4320         };
4321     }
4322 
4323     /**
4324      * Creates a robust accelerometer calibrator
4325      *
4326      * @param qualityScores quality scores corresponding to each provided
4327      *                      measurement. The larger the score value the better
4328      *                      the quality of the sample.
4329      * @param position      position where body kinematics measures have been taken.
4330      * @param measurements  collection of body kinematics measurements with standard
4331      *                      deviations taken at the same position with zero velocity
4332      *                      and unknown different orientations.
4333      * @param initialBias   initial accelerometer bias to be used to find a solution.
4334      *                      This must have length 3 and is expressed in meters per
4335      *                      squared second (m/s^2).
4336      * @param listener      listener to handle events raised by this calibrator.
4337      * @param method        robust estimator method.
4338      * @return a robust accelerometer calibrator.
4339      * @throws IllegalArgumentException if provided bias array does not have length 3
4340      *                                  or if quality scores array is smaller than 13
4341      *                                  samples.
4342      */
4343     public static RobustKnownPositionAccelerometerCalibrator create(
4344             final double[] qualityScores, final ECEFPosition position,
4345             final List<StandardDeviationBodyKinematics> measurements, final double[] initialBias,
4346             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4347         return switch (method) {
4348             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4349                     position, measurements, initialBias, listener);
4350             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4351                     position, measurements, initialBias, listener);
4352             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4353                     position, measurements, initialBias, listener);
4354             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4355                     qualityScores, position, measurements, initialBias, listener);
4356             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4357                     qualityScores, position, measurements, initialBias, listener);
4358         };
4359     }
4360 
4361     /**
4362      * Creates a robust accelerometer calibrator.
4363      *
4364      * @param qualityScores  quality scores corresponding to each provided
4365      *                       measurement. The larger the score value the better
4366      *                       the quality of the sample.
4367      * @param position       position where body kinematics measures have been taken.
4368      * @param measurements   collection of body kinematics measurements with standard
4369      *                       deviations taken at the same position with zero velocity
4370      *                       and unknown different orientations.
4371      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4372      *                       accelerometer and gyroscope.
4373      * @param initialBias    initial accelerometer bias to be used to find a solution.
4374      *                       This must have length 3 and is expressed in meters per
4375      *                       squared second (m/s^2).
4376      * @param method         robust estimator method.
4377      * @return a robust accelerometer calibrator.
4378      * @throws IllegalArgumentException if provided bias array does not have length 3
4379      *                                  or if provided quality scores length is
4380      *                                  smaller than the minimum number of required
4381      *                                  samples (10 or 13).
4382      */
4383     public static RobustKnownPositionAccelerometerCalibrator create(
4384             final double[] qualityScores, final ECEFPosition position,
4385             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4386             final double[] initialBias, final RobustEstimatorMethod method) {
4387         return switch (method) {
4388             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4389                     position, measurements, commonAxisUsed, initialBias);
4390             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4391                     position, measurements, commonAxisUsed, initialBias);
4392             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4393                     position, measurements, commonAxisUsed, initialBias);
4394             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4395                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4396             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4397                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4398         };
4399     }
4400 
4401     /**
4402      * Creates a robust accelerometer calibrator.
4403      *
4404      * @param qualityScores  quality scores corresponding to each provided
4405      *                       measurement. The larger the score value the better
4406      *                       the quality of the sample.
4407      * @param position       position where body kinematics measures have been taken.
4408      * @param measurements   collection of body kinematics measurements with standard
4409      *                       deviations taken at the same position with zero velocity
4410      *                       and unknown different orientations.
4411      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4412      *                       accelerometer and gyroscope.
4413      * @param initialBias    initial accelerometer bias to be used to find a solution.
4414      *                       This must have length 3 and is expressed in meters per
4415      *                       squared second (m/s^2).
4416      * @param listener       listener to handle events raised by this calibrator.
4417      * @param method         robust estimator method.
4418      * @return a robust accelerometer calibrator.
4419      * @throws IllegalArgumentException if provided bias array does not have length 3
4420      *                                  or if provided quality scores length is
4421      *                                  smaller than the minimum number of required
4422      *                                  samples (10 or 13).
4423      */
4424     public static RobustKnownPositionAccelerometerCalibrator create(
4425             final double[] qualityScores, final ECEFPosition position,
4426             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4427             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
4428             final RobustEstimatorMethod method) {
4429         return switch (method) {
4430             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4431                     position, measurements, commonAxisUsed, initialBias, listener);
4432             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4433                     position, measurements, commonAxisUsed, initialBias, listener);
4434             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4435                     position, measurements, commonAxisUsed, initialBias, listener);
4436             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4437                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
4438             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4439                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
4440         };
4441     }
4442 
4443     /**
4444      * Creates a robust accelerometer calibrator.
4445      *
4446      * @param qualityScores quality scores corresponding to each provided
4447      *                      measurement. The larger the score value the better
4448      *                      the quality of the sample.
4449      * @param position      position where body kinematics measures have been taken.
4450      * @param measurements  collection of body kinematics measurements with standard
4451      *                      deviations taken at the same position with zero velocity
4452      *                      and unknown different orientations.
4453      * @param initialBias   initial bias to find a solution.
4454      * @param method        robust estimator method.
4455      * @return a robust accelerometer calibrator.
4456      * @throws IllegalArgumentException if provided bias matrix is not 3x1 or if
4457      *                                  quality scores array is smaller than 13
4458      *                                  samples.
4459      */
4460     public static RobustKnownPositionAccelerometerCalibrator create(
4461             final double[] qualityScores, final ECEFPosition position,
4462             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias,
4463             final RobustEstimatorMethod method) {
4464         return switch (method) {
4465             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4466                     position, measurements, initialBias);
4467             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4468                     position, measurements, initialBias);
4469             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4470                     position, measurements, initialBias);
4471             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4472                     qualityScores, position, measurements, initialBias);
4473             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4474                     qualityScores, position, measurements, initialBias);
4475         };
4476     }
4477 
4478     /**
4479      * Creates a robust accelerometer calibrator.
4480      *
4481      * @param qualityScores quality scores corresponding to each provided
4482      *                      measurement. The larger the score value the better
4483      *                      the quality of the sample.
4484      * @param position      position where body kinematics measures have been taken.
4485      * @param measurements  collection of body kinematics measurements with standard
4486      *                      deviations taken at the same position with zero velocity
4487      *                      and unknown different orientations.
4488      * @param initialBias   initial bias to find a solution.
4489      * @param listener      listener to handle events raised by this calibrator.
4490      * @param method        robust estimator method.
4491      * @return a robust accelerometer calibrator.
4492      * @throws IllegalArgumentException if provided bias matrix is not 3x1 or if
4493      *                                  quality scores array is smaller than 13
4494      *                                  samples.
4495      */
4496     public static RobustKnownPositionAccelerometerCalibrator create(
4497             final double[] qualityScores, final ECEFPosition position,
4498             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias,
4499             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4500         return switch (method) {
4501             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4502                     position, measurements, initialBias, listener);
4503             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4504                     position, measurements, initialBias, listener);
4505             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4506                     position, measurements, initialBias, listener);
4507             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4508                     qualityScores, position, measurements, initialBias, listener);
4509             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4510                     qualityScores, position, measurements, initialBias, listener);
4511         };
4512     }
4513 
4514     /**
4515      * Creates a robust accelerometer calibrator.
4516      *
4517      * @param qualityScores  quality scores corresponding to each provided
4518      *                       measurement. The larger the score value the better
4519      *                       the quality of the sample.
4520      * @param position       position where body kinematics measures have been taken.
4521      * @param measurements   collection of body kinematics measurements with standard
4522      *                       deviations taken at the same position with zero velocity
4523      *                       and unknown different orientations.
4524      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4525      *                       accelerometer and gyroscope.
4526      * @param initialBias    initial bias to find a solution.
4527      * @param method         robust estimator method.
4528      * @return a robust accelerometer calibrator.
4529      * @throws IllegalArgumentException if provided bias matrix is not 3x1
4530      *                                  or if provided quality scores length is
4531      *                                  smaller than the minimum number of required
4532      *                                  samples (10 or 13).
4533      */
4534     public static RobustKnownPositionAccelerometerCalibrator create(
4535             final double[] qualityScores, final ECEFPosition position,
4536             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4537             final Matrix initialBias, final RobustEstimatorMethod method) {
4538         return switch (method) {
4539             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4540                     position, measurements, commonAxisUsed, initialBias);
4541             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4542                     position, measurements, commonAxisUsed, initialBias);
4543             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4544                     position, measurements, commonAxisUsed, initialBias);
4545             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4546                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4547             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4548                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4549         };
4550     }
4551 
4552     /**
4553      * Creates a robust accelerometer calibrator.
4554      *
4555      * @param qualityScores  quality scores corresponding to each provided
4556      *                       measurement. The larger the score value the better
4557      *                       the quality of the sample.
4558      * @param position       position where body kinematics measures have been taken.
4559      * @param measurements   collection of body kinematics measurements with standard
4560      *                       deviations taken at the same position with zero velocity
4561      *                       and unknown different orientations.
4562      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4563      *                       accelerometer and gyroscope.
4564      * @param initialBias    initial bias to find a solution.
4565      * @param listener       listener to handle events raised by this calibrator.
4566      * @param method         robust estimator method.
4567      * @return a robust accelerometer calibrator.
4568      * @throws IllegalArgumentException if provided bias matrix is not 3x1
4569      *                                  or if provided quality scores length is
4570      *                                  smaller than the minimum number of required
4571      *                                  samples (10 or 13).
4572      */
4573     public static RobustKnownPositionAccelerometerCalibrator create(
4574             final double[] qualityScores, final ECEFPosition position,
4575             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4576             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
4577             final RobustEstimatorMethod method) {
4578         return switch (method) {
4579             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4580                     position, measurements, commonAxisUsed, initialBias, listener);
4581             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4582                     position, measurements, commonAxisUsed, initialBias, listener);
4583             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4584                     position, measurements, commonAxisUsed, initialBias, listener);
4585             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4586                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
4587             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4588                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
4589         };
4590     }
4591 
4592     /**
4593      * Creates a robust accelerometer calibrator.
4594      *
4595      * @param qualityScores quality scores corresponding to each provided
4596      *                      measurement. The larger the score value the better
4597      *                      the quality of the sample.
4598      * @param position      position where body kinematics measures have been taken.
4599      * @param measurements  collection of body kinematics measurements with standard
4600      *                      deviations taken at the same position with zero velocity
4601      *                      and unknown different orientations.
4602      * @param initialBias   initial bias to find a solution.
4603      * @param initialMa     initial scale factors and cross coupling errors matrix.
4604      * @param method        robust estimator method.
4605      * @return a robust accelerometer calibrator.
4606      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4607      *                                  scaling and coupling error matrix is not 3x3
4608      *                                  or if quality scores array is smaller than 13
4609      *                                  samples.
4610      */
4611     public static RobustKnownPositionAccelerometerCalibrator create(
4612             final double[] qualityScores, final ECEFPosition position,
4613             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias, final Matrix initialMa,
4614             final RobustEstimatorMethod method) {
4615         return switch (method) {
4616             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4617                     position, measurements, initialBias, initialMa);
4618             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4619                     position, measurements, initialBias, initialMa);
4620             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4621                     position, measurements, initialBias, initialMa);
4622             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4623                     qualityScores, position, measurements, initialBias, initialMa);
4624             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4625                     qualityScores, position, measurements, initialBias, initialMa);
4626         };
4627     }
4628 
4629     /**
4630      * Creates a robust accelerometer calibrator.
4631      *
4632      * @param qualityScores quality scores corresponding to each provided
4633      *                      measurement. The larger the score value the better
4634      *                      the quality of the sample.
4635      * @param position      position where body kinematics measures have been taken.
4636      * @param measurements  collection of body kinematics measurements with standard
4637      *                      deviations taken at the same position with zero velocity
4638      *                      and unknown different orientations.
4639      * @param initialBias   initial bias to find a solution.
4640      * @param initialMa     initial scale factors and cross coupling errors matrix.
4641      * @param listener      listener to handle events raised by this calibrator.
4642      * @param method        robust estimator method.
4643      * @return a robust accelerometer calibrator.
4644      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4645      *                                  scaling and coupling error matrix is not 3x3
4646      *                                  or if quality scores array is smaller than 13
4647      *                                  samples.
4648      */
4649     public static RobustKnownPositionAccelerometerCalibrator create(
4650             final double[] qualityScores, final ECEFPosition position,
4651             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias, final Matrix initialMa,
4652             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4653         return switch (method) {
4654             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4655                     position, measurements, initialBias, initialMa, listener);
4656             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4657                     position, measurements, initialBias, initialMa, listener);
4658             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4659                     position, measurements, initialBias, initialMa, listener);
4660             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4661                     qualityScores, position, measurements, initialBias, initialMa, listener);
4662             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4663                     qualityScores, position, measurements, initialBias, initialMa, listener);
4664         };
4665     }
4666 
4667     /**
4668      * Creates a robust accelerometer calibrator.
4669      *
4670      * @param qualityScores  quality scores corresponding to each provided
4671      *                       measurement. The larger the score value the better
4672      *                       the quality of the sample.
4673      * @param position       position where body kinematics measures have been taken.
4674      * @param measurements   collection of body kinematics measurements with standard
4675      *                       deviations taken at the same position with zero velocity
4676      *                       and unknown different orientations.
4677      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4678      *                       accelerometer and gyroscope.
4679      * @param initialBias    initial bias to find a solution.
4680      * @param initialMa      initial scale factors and cross coupling errors matrix.
4681      * @param method         robust estimator method.
4682      * @return a robust accelerometer calibrator.
4683      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4684      *                                  scaling and coupling error matrix is not 3x3
4685      *                                  or if provided quality scores length is
4686      *                                  smaller than the minimum number of required
4687      *                                  samples (10 or 13).
4688      */
4689     public static RobustKnownPositionAccelerometerCalibrator create(
4690             final double[] qualityScores, final ECEFPosition position,
4691             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4692             final Matrix initialBias, final Matrix initialMa, final RobustEstimatorMethod method) {
4693         return switch (method) {
4694             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4695                     position, measurements, commonAxisUsed, initialBias, initialMa);
4696             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4697                     position, measurements, commonAxisUsed, initialBias, initialMa);
4698             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4699                     position, measurements, commonAxisUsed, initialBias, initialMa);
4700             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4701                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa);
4702             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4703                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa);
4704         };
4705     }
4706 
4707     /**
4708      * Creates a robust accelerometer calibrator.
4709      *
4710      * @param qualityScores  quality scores corresponding to each provided
4711      *                       measurement. The larger the score value the better
4712      *                       the quality of the sample.
4713      * @param position       position where body kinematics measures have been taken.
4714      * @param measurements   collection of body kinematics measurements with standard
4715      *                       deviations taken at the same position with zero velocity
4716      *                       and unknown different orientations.
4717      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4718      *                       accelerometer and gyroscope.
4719      * @param initialBias    initial bias to find a solution.
4720      * @param initialMa      initial scale factors and cross coupling errors matrix.
4721      * @param listener       listener to handle events raised by this calibrator.
4722      * @param method         robust estimator method.
4723      * @return a robust accelerometer calibrator.
4724      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
4725      *                                  scaling and coupling error matrix is not 3x3
4726      *                                  or if provided quality scores length is
4727      *                                  smaller than the minimum number of required
4728      *                                  samples (10 or 13).
4729      */
4730     public static RobustKnownPositionAccelerometerCalibrator create(
4731             final double[] qualityScores, final ECEFPosition position,
4732             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4733             final Matrix initialBias, final Matrix initialMa,
4734             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4735         return switch (method) {
4736             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4737                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4738             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4739                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4740             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4741                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4742             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4743                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4744             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4745                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa, listener);
4746         };
4747     }
4748 
4749     /**
4750      * Creates a robust accelerometer calibrator.
4751      *
4752      * @param qualityScores quality scores corresponding to each provided
4753      *                      measurement. The larger the score value the better
4754      *                      the quality of the sample.
4755      * @param position      position where body kinematics measures have been taken.
4756      * @param measurements  list of body kinematics measurements taken at a given position with
4757      *                      different unknown orientations and containing the standard deviations
4758      *                      of accelerometer and gyroscope measurements.
4759      * @param method        robust estimator method.
4760      * @return a robust accelerometer calibrator.
4761      * @throws IllegalArgumentException if provided quality scores length
4762      *                                  is smaller than 13 samples.
4763      */
4764     public static RobustKnownPositionAccelerometerCalibrator create(
4765             final double[] qualityScores, final NEDPosition position,
4766             final List<StandardDeviationBodyKinematics> measurements, final RobustEstimatorMethod method) {
4767         return switch (method) {
4768             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
4769             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements);
4770             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements);
4771             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(qualityScores, position, measurements);
4772             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(qualityScores, position, measurements);
4773         };
4774     }
4775 
4776     /**
4777      * Creates a robust accelerometer calibrator.
4778      *
4779      * @param qualityScores quality scores corresponding to each provided
4780      *                      measurement. The larger the score value the better
4781      *                      the quality of the sample.
4782      * @param position      position where body kinematics measures have been taken.
4783      * @param measurements  list of body kinematics measurements taken at a given position with
4784      *                      different unknown orientations and containing the standard deviations
4785      *                      of accelerometer and gyroscope measurements.
4786      * @param listener      listener to be notified of events such as when estimation
4787      *                      starts, ends or its progress significantly changes.
4788      * @param method        robust estimator method.
4789      * @return a robust accelerometer calibrator.
4790      * @throws IllegalArgumentException if provided quality scores length
4791      *                                  is smaller than 13 samples.
4792      */
4793     public static RobustKnownPositionAccelerometerCalibrator create(
4794             final double[] qualityScores, final NEDPosition position,
4795             final List<StandardDeviationBodyKinematics> measurements,
4796             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4797         return switch (method) {
4798             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4799             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4800             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, listener);
4801             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4802                     qualityScores, position, measurements, listener);
4803             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4804                     qualityScores, position, measurements, listener);
4805         };
4806     }
4807 
4808     /**
4809      * Creates a robust accelerometer calibrator.
4810      *
4811      * @param qualityScores  quality scores corresponding to each provided
4812      *                       measurement. The larger the score value the better
4813      *                       the quality of the sample.
4814      * @param position       position where body kinematics measures have been taken.
4815      * @param measurements   list of body kinematics measurements taken at a given position with
4816      *                       different unknown orientations and containing the standard deviations
4817      *                       of accelerometer and gyroscope measurements.
4818      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4819      *                       accelerometer and gyroscope. If true 10 samples are
4820      *                       required, otherwise 13.
4821      * @param method         robust estimator method.
4822      * @return a robust accelerometer calibrator.
4823      * @throws IllegalArgumentException if provided quality scores length
4824      *                                  is smaller than the minimum number of
4825      *                                  required samples (10 or 13).
4826      */
4827     public static RobustKnownPositionAccelerometerCalibrator create(
4828             final double[] qualityScores, final NEDPosition position,
4829             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4830             final RobustEstimatorMethod method) {
4831         return switch (method) {
4832             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4833             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4834             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, commonAxisUsed);
4835             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4836                     qualityScores, position, measurements, commonAxisUsed);
4837             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4838                     qualityScores, position, measurements, commonAxisUsed);
4839         };
4840     }
4841 
4842     /**
4843      * Creates a robust accelerometer calibrator.
4844      *
4845      * @param qualityScores  quality scores corresponding to each provided
4846      *                       measurement. The larger the score value the better
4847      *                       the quality of the sample.
4848      * @param position       position where body kinematics measures have been taken.
4849      * @param measurements   list of body kinematics measurements taken at a given position with
4850      *                       different unknown orientations and containing the standard deviations
4851      *                       of accelerometer and gyroscope measurements.
4852      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4853      *                       accelerometer and gyroscope. If true 10 samples are
4854      *                       required, otherwise 13.
4855      * @param listener       listener to be notified of events such as when estimation
4856      *                       starts, ends or its progress significantly changes.
4857      * @param method         robust estimator method.
4858      * @return a robust accelerometer calibrator.
4859      * @throws IllegalArgumentException if provided quality scores length
4860      *                                  is smaller than the minimum number of
4861      *                                  required samples (10 or 13).
4862      */
4863     public static RobustKnownPositionAccelerometerCalibrator create(
4864             final double[] qualityScores, final NEDPosition position,
4865             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4866             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4867         return switch (method) {
4868             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4869                     position, measurements, commonAxisUsed, listener);
4870             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4871                     position, measurements, commonAxisUsed, listener);
4872             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4873                     position, measurements, commonAxisUsed, listener);
4874             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4875                     qualityScores, position, measurements, commonAxisUsed, listener);
4876             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4877                     qualityScores, position, measurements, commonAxisUsed, listener);
4878         };
4879     }
4880 
4881     /**
4882      * Creates a robust accelerometer calibrator.
4883      *
4884      * @param qualityScores quality scores corresponding to each provided
4885      *                      measurement. The larger the score value the better
4886      *                      the quality of the sample.
4887      * @param position      position where body kinematics measures have been taken.
4888      * @param measurements  collection of body kinematics measurements with standard
4889      *                      deviations taken at the same position with zero velocity
4890      *                      and unknown different orientations.
4891      * @param initialBias   initial accelerometer bias to be used to find a solution.
4892      *                      This must have length 3 and is expressed in meters per
4893      *                      squared second (m/s^2).
4894      * @param method        robust estimator method.
4895      * @return a robust accelerometer calibrator.
4896      * @throws IllegalArgumentException if provided bias array does not have length 3
4897      *                                  or quality scores array is smaller than 13
4898      *                                  samples.
4899      */
4900     public static RobustKnownPositionAccelerometerCalibrator create(
4901             final double[] qualityScores, final NEDPosition position,
4902             final List<StandardDeviationBodyKinematics> measurements, final double[] initialBias,
4903             final RobustEstimatorMethod method) {
4904         return switch (method) {
4905             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4906             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4907             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
4908             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4909                     qualityScores, position, measurements, initialBias);
4910             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4911                     qualityScores, position, measurements, initialBias);
4912         };
4913     }
4914 
4915     /**
4916      * Creates a robust accelerometer calibrator.
4917      *
4918      * @param qualityScores quality scores corresponding to each provided
4919      *                      measurement. The larger the score value the better
4920      *                      the quality of the sample.
4921      * @param position      position where body kinematics measures have been taken.
4922      * @param measurements  collection of body kinematics measurements with standard
4923      *                      deviations taken at the same position with zero velocity
4924      *                      and unknown different orientations.
4925      * @param initialBias   initial accelerometer bias to be used to find a solution.
4926      *                      This must have length 3 and is expressed in meters per
4927      *                      squared second (m/s^2).
4928      * @param listener      listener to handle events raised by this calibrator.
4929      * @param method        robust estimator method.
4930      * @return a robust accelerometer calibrator.
4931      * @throws IllegalArgumentException if provided bias array does not have length 3
4932      *                                  or if quality scores array is smaller than 13
4933      *                                  samples.
4934      */
4935     public static RobustKnownPositionAccelerometerCalibrator create(
4936             final double[] qualityScores, final NEDPosition position,
4937             final List<StandardDeviationBodyKinematics> measurements, final double[] initialBias,
4938             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
4939         return switch (method) {
4940             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4941                     position, measurements, initialBias, listener);
4942             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4943                     position, measurements, initialBias, listener);
4944             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4945                     position, measurements, initialBias, listener);
4946             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4947                     qualityScores, position, measurements, initialBias, listener);
4948             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4949                     qualityScores, position, measurements, initialBias, listener);
4950         };
4951     }
4952 
4953     /**
4954      * Creates a robust accelerometer calibrator.
4955      *
4956      * @param qualityScores  quality scores corresponding to each provided
4957      *                       measurement. The larger the score value the better
4958      *                       the quality of the sample.
4959      * @param position       position where body kinematics measures have been taken.
4960      * @param measurements   collection of body kinematics measurements with standard
4961      *                       deviations taken at the same position with zero velocity
4962      *                       and unknown different orientations.
4963      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
4964      *                       accelerometer and gyroscope.
4965      * @param initialBias    initial accelerometer bias to be used to find a solution.
4966      *                       This must have length 3 and is expressed in meters per
4967      *                       squared second (m/s^2).
4968      * @param method         robust estimator method.
4969      * @return a robust accelerometer calibrator.
4970      * @throws IllegalArgumentException if provided bias array does not have length 3
4971      *                                  or if provided quality scores length is
4972      *                                  smaller than the minimum number of required
4973      *                                  samples (10 or 13).
4974      */
4975     public static RobustKnownPositionAccelerometerCalibrator create(
4976             final double[] qualityScores, final NEDPosition position,
4977             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
4978             final double[] initialBias, final RobustEstimatorMethod method) {
4979         return switch (method) {
4980             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
4981                     position, measurements, commonAxisUsed, initialBias);
4982             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
4983                     position, measurements, commonAxisUsed, initialBias);
4984             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
4985                     position, measurements, commonAxisUsed, initialBias);
4986             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
4987                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4988             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
4989                     qualityScores, position, measurements, commonAxisUsed, initialBias);
4990         };
4991     }
4992 
4993     /**
4994      * Creates a robust accelerometer calibrator.
4995      *
4996      * @param qualityScores  quality scores corresponding to each provided
4997      *                       measurement. The larger the score value the better
4998      *                       the quality of the sample.
4999      * @param position       position where body kinematics measures have been taken.
5000      * @param measurements   collection of body kinematics measurements with standard
5001      *                       deviations taken at the same position with zero velocity
5002      *                       and unknown different orientations.
5003      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5004      *                       accelerometer and gyroscope.
5005      * @param initialBias    initial accelerometer bias to be used to find a solution.
5006      *                       This must have length 3 and is expressed in meters per
5007      *                       squared second (m/s^2).
5008      * @param listener       listener to handle events raised by this calibrator.
5009      * @param method         robust estimator method.
5010      * @return a robust accelerometer calibrator.
5011      * @throws IllegalArgumentException if provided bias array does not have length 3
5012      *                                  or if provided quality scores length is
5013      *                                  smaller than the minimum number of required
5014      *                                  samples (10 or 13).
5015      */
5016     public static RobustKnownPositionAccelerometerCalibrator create(
5017             final double[] qualityScores, final NEDPosition position,
5018             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
5019             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
5020             final RobustEstimatorMethod method) {
5021         return switch (method) {
5022             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5023                     position, measurements, commonAxisUsed, initialBias, listener);
5024             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5025                     position, measurements, commonAxisUsed, initialBias, listener);
5026             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5027                     position, measurements, commonAxisUsed, initialBias, listener);
5028             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5029                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
5030             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5031                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
5032         };
5033     }
5034 
5035     /**
5036      * Creates a robust accelerometer calibrator.
5037      *
5038      * @param qualityScores quality scores corresponding to each provided
5039      *                      measurement. The larger the score value the better
5040      *                      the quality of the sample.
5041      * @param position      position where body kinematics measures have been taken.
5042      * @param measurements  collection of body kinematics measurements with standard
5043      *                      deviations taken at the same position with zero velocity
5044      *                      and unknown different orientations.
5045      * @param initialBias   initial bias to find a solution.
5046      * @param method        robust estimator method.
5047      * @return a robust accelerometer calibrator.
5048      * @throws IllegalArgumentException if provided bias matrix is not 3x1 or if
5049      *                                  quality scores array is smaller than 13
5050      *                                  samples.
5051      */
5052     public static RobustKnownPositionAccelerometerCalibrator create(
5053             final double[] qualityScores, final NEDPosition position,
5054             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias,
5055             final RobustEstimatorMethod method) {
5056         return switch (method) {
5057             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
5058             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
5059             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(position, measurements, initialBias);
5060             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5061                     qualityScores, position, measurements, initialBias);
5062             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5063                     qualityScores, position, measurements, initialBias);
5064         };
5065     }
5066 
5067     /**
5068      * Creates a robust accelerometer calibrator.
5069      *
5070      * @param qualityScores quality scores corresponding to each provided
5071      *                      measurement. The larger the score value the better
5072      *                      the quality of the sample.
5073      * @param position      position where body kinematics measures have been taken.
5074      * @param measurements  collection of body kinematics measurements with standard
5075      *                      deviations taken at the same position with zero velocity
5076      *                      and unknown different orientations.
5077      * @param initialBias   initial bias to find a solution.
5078      * @param listener      listener to handle events raised by this calibrator.
5079      * @param method        robust estimator method.
5080      * @return a robust accelerometer calibrator.
5081      * @throws IllegalArgumentException if provided bias matrix is not 3x1 or if
5082      *                                  quality scores array is smaller than 13
5083      *                                  samples.
5084      */
5085     public static RobustKnownPositionAccelerometerCalibrator create(
5086             final double[] qualityScores, final NEDPosition position,
5087             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias,
5088             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
5089         return switch (method) {
5090             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5091                     position, measurements, initialBias, listener);
5092             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5093                     position, measurements, initialBias, listener);
5094             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5095                     position, measurements, initialBias, listener);
5096             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5097                     qualityScores, position, measurements, initialBias, listener);
5098             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5099                     qualityScores, position, measurements, initialBias, listener);
5100         };
5101     }
5102 
5103     /**
5104      * Creates a robust accelerometer calibrator.
5105      *
5106      * @param qualityScores  quality scores corresponding to each provided
5107      *                       measurement. The larger the score value the better
5108      *                       the quality of the sample.
5109      * @param position       position where body kinematics measures have been taken.
5110      * @param measurements   collection of body kinematics measurements with standard
5111      *                       deviations taken at the same position with zero velocity
5112      *                       and unknown different orientations.
5113      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5114      *                       accelerometer and gyroscope.
5115      * @param initialBias    initial bias to find a solution.
5116      * @param method         robust estimator method.
5117      * @return a robust accelerometer calibrator.
5118      * @throws IllegalArgumentException if provided bias matrix is not 3x1
5119      *                                  or if provided quality scores length is
5120      *                                  smaller than the minimum number of required
5121      *                                  samples (10 or 13).
5122      */
5123     public static RobustKnownPositionAccelerometerCalibrator create(
5124             final double[] qualityScores, final NEDPosition position,
5125             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
5126             final Matrix initialBias, final RobustEstimatorMethod method) {
5127         return switch (method) {
5128             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5129                     position, measurements, commonAxisUsed, initialBias);
5130             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5131                     position, measurements, commonAxisUsed, initialBias);
5132             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5133                     position, measurements, commonAxisUsed, initialBias);
5134             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5135                     qualityScores, position, measurements, commonAxisUsed, initialBias);
5136             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5137                     qualityScores, position, measurements, commonAxisUsed, initialBias);
5138         };
5139     }
5140 
5141     /**
5142      * Creates a robust accelerometer calibrator.
5143      *
5144      * @param qualityScores  quality scores corresponding to each provided
5145      *                       measurement. The larger the score value the better
5146      *                       the quality of the sample.
5147      * @param position       position where body kinematics measures have been taken.
5148      * @param measurements   collection of body kinematics measurements with standard
5149      *                       deviations taken at the same position with zero velocity
5150      *                       and unknown different orientations.
5151      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5152      *                       accelerometer and gyroscope.
5153      * @param initialBias    initial bias to find a solution.
5154      * @param listener       listener to handle events raised by this calibrator.
5155      * @param method         robust estimator method.
5156      * @return a robust accelerometer calibrator.
5157      * @throws IllegalArgumentException if provided bias matrix is not 3x1
5158      *                                  or if provided quality scores length is
5159      *                                  smaller than the minimum number of required
5160      *                                  samples (10 or 13).
5161      */
5162     public static RobustKnownPositionAccelerometerCalibrator create(
5163             final double[] qualityScores, final NEDPosition position,
5164             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
5165             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener,
5166             final RobustEstimatorMethod method) {
5167         return switch (method) {
5168             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5169                     position, measurements, commonAxisUsed, initialBias, listener);
5170             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5171                     position, measurements, commonAxisUsed, initialBias, listener);
5172             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5173                     position, measurements, commonAxisUsed, initialBias, listener);
5174             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5175                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
5176             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5177                     qualityScores, position, measurements, commonAxisUsed, initialBias, listener);
5178         };
5179     }
5180 
5181     /**
5182      * Creates a robust accelerometer calibrator.
5183      *
5184      * @param qualityScores quality scores corresponding to each provided
5185      *                      measurement. The larger the score value the better
5186      *                      the quality of the sample.
5187      * @param position      position where body kinematics measures have been taken.
5188      * @param measurements  collection of body kinematics measurements with standard
5189      *                      deviations taken at the same position with zero velocity
5190      *                      and unknown different orientations.
5191      * @param initialBias   initial bias to find a solution.
5192      * @param initialMa     initial scale factors and cross coupling errors matrix.
5193      * @param method        robust estimator method.
5194      * @return a robust accelerometer calibrator.
5195      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5196      *                                  scaling and coupling error matrix is not 3x3
5197      *                                  or if quality scores array is smaller than 13
5198      *                                  samples.
5199      */
5200     public static RobustKnownPositionAccelerometerCalibrator create(
5201             final double[] qualityScores, final NEDPosition position,
5202             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias, final Matrix initialMa,
5203             final RobustEstimatorMethod method) {
5204         return switch (method) {
5205             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5206                     position, measurements, initialBias, initialMa);
5207             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5208                     position, measurements, initialBias, initialMa);
5209             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5210                     position, measurements, initialBias, initialMa);
5211             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5212                     qualityScores, position, measurements, initialBias, initialMa);
5213             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5214                     qualityScores, position, measurements, initialBias, initialMa);
5215         };
5216     }
5217 
5218     /**
5219      * Creates a robust accelerometer calibrator.
5220      *
5221      * @param qualityScores quality scores corresponding to each provided
5222      *                      measurement. The larger the score value the better
5223      *                      the quality of the sample.
5224      * @param position      position where body kinematics measures have been taken.
5225      * @param measurements  collection of body kinematics measurements with standard
5226      *                      deviations taken at the same position with zero velocity
5227      *                      and unknown different orientations.
5228      * @param initialBias   initial bias to find a solution.
5229      * @param initialMa     initial scale factors and cross coupling errors matrix.
5230      * @param listener      listener to handle events raised by this calibrator.
5231      * @param method        robust estimator method.
5232      * @return a robust accelerometer calibrator.
5233      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5234      *                                  scaling and coupling error matrix is not 3x3
5235      *                                  or if quality scores array is smaller than 13
5236      *                                  samples.
5237      */
5238     public static RobustKnownPositionAccelerometerCalibrator create(
5239             final double[] qualityScores, final NEDPosition position,
5240             final List<StandardDeviationBodyKinematics> measurements, final Matrix initialBias, final Matrix initialMa,
5241             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
5242         return switch (method) {
5243             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5244                     position, measurements, initialBias, initialMa, listener);
5245             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5246                     position, measurements, initialBias, initialMa, listener);
5247             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5248                     position, measurements, initialBias, initialMa, listener);
5249             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5250                     qualityScores, position, measurements, initialBias, initialMa, listener);
5251             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5252                     qualityScores, position, measurements, initialBias, initialMa, listener);
5253         };
5254     }
5255 
5256     /**
5257      * Creates a robust accelerometer calibrator.
5258      *
5259      * @param qualityScores  quality scores corresponding to each provided
5260      *                       measurement. The larger the score value the better
5261      *                       the quality of the sample.
5262      * @param position       position where body kinematics measures have been taken.
5263      * @param measurements   collection of body kinematics measurements with standard
5264      *                       deviations taken at the same position with zero velocity
5265      *                       and unknown different orientations.
5266      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5267      *                       accelerometer and gyroscope.
5268      * @param initialBias    initial bias to find a solution.
5269      * @param initialMa      initial scale factors and cross coupling errors matrix.
5270      * @param method         robust estimator method.
5271      * @return a robust accelerometer calibrator.
5272      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5273      *                                  scaling and coupling error matrix is not 3x3
5274      *                                  or if provided quality scores length is
5275      *                                  smaller than the minimum number of required
5276      *                                  samples (10 or 13).
5277      */
5278     public static RobustKnownPositionAccelerometerCalibrator create(
5279             final double[] qualityScores, final NEDPosition position,
5280             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
5281             final Matrix initialBias, final Matrix initialMa, final RobustEstimatorMethod method) {
5282         return switch (method) {
5283             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5284                     position, measurements, commonAxisUsed, initialBias, initialMa);
5285             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5286                     position, measurements, commonAxisUsed, initialBias, initialMa);
5287             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5288                     position, measurements, commonAxisUsed, initialBias, initialMa);
5289             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5290                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa);
5291             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5292                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa);
5293         };
5294     }
5295 
5296     /**
5297      * Creates a robust accelerometer calibrator.
5298      *
5299      * @param qualityScores  quality scores corresponding to each provided
5300      *                       measurement. The larger the score value the better
5301      *                       the quality of the sample.
5302      * @param position       position where body kinematics measures have been taken.
5303      * @param measurements   collection of body kinematics measurements with standard
5304      *                       deviations taken at the same position with zero velocity
5305      *                       and unknown different orientations.
5306      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5307      *                       accelerometer and gyroscope.
5308      * @param initialBias    initial bias to find a solution.
5309      * @param initialMa      initial scale factors and cross coupling errors matrix.
5310      * @param listener       listener to handle events raised by this calibrator.
5311      * @param method         robust estimator method.
5312      * @return a robust accelerometer calibrator.
5313      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5314      *                                  scaling and coupling error matrix is not 3x3
5315      *                                  or if provided quality scores length is
5316      *                                  smaller than the minimum number of required
5317      *                                  samples (10 or 13).
5318      */
5319     public static RobustKnownPositionAccelerometerCalibrator create(
5320             final double[] qualityScores, final NEDPosition position,
5321             final List<StandardDeviationBodyKinematics> measurements, final boolean commonAxisUsed,
5322             final Matrix initialBias, final Matrix initialMa,
5323             final RobustKnownPositionAccelerometerCalibratorListener listener, final RobustEstimatorMethod method) {
5324         return switch (method) {
5325             case RANSAC -> new RANSACRobustKnownPositionAccelerometerCalibrator(
5326                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
5327             case LMEDS -> new LMedSRobustKnownPositionAccelerometerCalibrator(
5328                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
5329             case MSAC -> new MSACRobustKnownPositionAccelerometerCalibrator(
5330                     position, measurements, commonAxisUsed, initialBias, initialMa, listener);
5331             case PROSAC -> new PROSACRobustKnownPositionAccelerometerCalibrator(
5332                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa, listener);
5333             default -> new PROMedSRobustKnownPositionAccelerometerCalibrator(
5334                     qualityScores, position, measurements, commonAxisUsed, initialBias, initialMa, listener);
5335         };
5336     }
5337 
5338     /**
5339      * Creates a robust accelerometer calibrator using default robust method.
5340      *
5341      * @return a robust accelerometer calibrator.
5342      */
5343     public static RobustKnownPositionAccelerometerCalibrator create() {
5344         return create(DEFAULT_ROBUST_METHOD);
5345     }
5346 
5347     /**
5348      * Creates a robust accelerometer calibrator using default robust method.
5349      *
5350      * @param listener listener to be notified of events such as when estimation
5351      *                 starts, ends or its progress significantly changes.
5352      * @return a robust accelerometer calibrator.
5353      */
5354     public static RobustKnownPositionAccelerometerCalibrator create(
5355             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5356         return create(listener, DEFAULT_ROBUST_METHOD);
5357     }
5358 
5359     /**
5360      * Creates a robust accelerometer calibrator using default robust method.
5361      *
5362      * @param measurements list of body kinematics measurements taken at a given position with
5363      *                     different unknown orientations and containing the standard deviations
5364      *                     of accelerometer and gyroscope measurements.
5365      * @return a robust accelerometer calibrator.
5366      */
5367     public static RobustKnownPositionAccelerometerCalibrator create(
5368             final List<StandardDeviationBodyKinematics> measurements) {
5369         return create(measurements, DEFAULT_ROBUST_METHOD);
5370     }
5371 
5372     /**
5373      * Creates a robust accelerometer calibrator using default robust method.
5374      *
5375      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5376      *                       accelerometer and gyroscope.
5377      * @return a robust accelerometer calibrator.
5378      */
5379     public static RobustKnownPositionAccelerometerCalibrator create(final boolean commonAxisUsed) {
5380         return create(commonAxisUsed, DEFAULT_ROBUST_METHOD);
5381     }
5382 
5383     /**
5384      * Creates a robust accelerometer calibrator using default robust method.
5385      *
5386      * @param initialBias initial accelerometer bias to be used to find a solution.
5387      *                    This must have length 3 and is expressed in meters per
5388      *                    squared second (m/s^2).
5389      * @return a robust accelerometer calibrator.
5390      * @throws IllegalArgumentException if provided bias array does not have length 3.
5391      */
5392     public static RobustKnownPositionAccelerometerCalibrator create(final double[] initialBias) {
5393         return create(initialBias, DEFAULT_ROBUST_METHOD);
5394     }
5395 
5396     /**
5397      * Creates a robust accelerometer calibrator using default robust method.
5398      *
5399      * @param initialBias initial bias to find a solution.
5400      * @return a robust accelerometer calibrator.
5401      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5402      */
5403     public static RobustKnownPositionAccelerometerCalibrator create(final Matrix initialBias) {
5404         return create(initialBias, DEFAULT_ROBUST_METHOD);
5405     }
5406 
5407     /**
5408      * Creates a robust accelerometer calibrator using default robust method.
5409      *
5410      * @param initialBias initial bias to find a solution.
5411      * @param initialMa   initial scale factors and cross coupling errors matrix.
5412      * @return a robust accelerometer calibrator.
5413      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5414      *                                  scaling and coupling error matrix is not 3x3.
5415      */
5416     public static RobustKnownPositionAccelerometerCalibrator create(final Matrix initialBias, final Matrix initialMa) {
5417         return create(initialBias, initialMa, DEFAULT_ROBUST_METHOD);
5418     }
5419 
5420     /**
5421      * Creates a robust accelerometer calibrator using default robust method.
5422      *
5423      * @param position position where body kinematics measures have been taken.
5424      * @return a robust accelerometer calibrator.
5425      */
5426     public static RobustKnownPositionAccelerometerCalibrator create(final ECEFPosition position) {
5427         return create(position, DEFAULT_ROBUST_METHOD);
5428     }
5429 
5430     /**
5431      * Creates a robust accelerometer calibrator using default robust method.
5432      *
5433      * @param position     position where body kinematics measures have been taken.
5434      * @param measurements list of body kinematics measurements taken at a given position with
5435      *                     different unknown orientations and containing the standard deviations
5436      *                     of accelerometer and gyroscope measurements.
5437      * @return a robust accelerometer calibrator.
5438      */
5439     public static RobustKnownPositionAccelerometerCalibrator create(
5440             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements) {
5441         return create(position, measurements, DEFAULT_ROBUST_METHOD);
5442     }
5443 
5444     /**
5445      * Creates a robust accelerometer calibrator using default robust method.
5446      *
5447      * @param position     position where body kinematics measures have been taken.
5448      * @param measurements list of body kinematics measurements taken at a given position with
5449      *                     different unknown orientations and containing the standard deviations
5450      *                     of accelerometer and gyroscope measurements.
5451      * @param listener     listener to be notified of events such as when estimation
5452      *                     starts, ends or its progress significantly changes.
5453      * @return a robust accelerometer calibrator.
5454      */
5455     public static RobustKnownPositionAccelerometerCalibrator create(
5456             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5457             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5458         return create(position, measurements, listener, DEFAULT_ROBUST_METHOD);
5459     }
5460 
5461     /**
5462      * Creates a robust accelerometer calibrator using default robust method.
5463      *
5464      * @param position       position where body kinematics measures have been taken.
5465      * @param measurements   list of body kinematics measurements taken at a given position with
5466      *                       different unknown orientations and containing the standard deviations
5467      *                       of accelerometer and gyroscope measurements.
5468      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5469      *                       accelerometer and gyroscope.
5470      * @return a robust accelerometer calibrator.
5471      */
5472     public static RobustKnownPositionAccelerometerCalibrator create(
5473             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5474             final boolean commonAxisUsed) {
5475         return create(position, measurements, commonAxisUsed, DEFAULT_ROBUST_METHOD);
5476     }
5477 
5478     /**
5479      * Creates a robust accelerometer calibrator using default robust method.
5480      *
5481      * @param position       position where body kinematics measures have been taken.
5482      * @param measurements   list of body kinematics measurements taken at a given position with
5483      *                       different unknown orientations and containing the standard deviations
5484      *                       of accelerometer and gyroscope measurements.
5485      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5486      *                       accelerometer and gyroscope.
5487      * @param listener       listener to be notified of events such as when estimation
5488      *                       starts, ends or its progress significantly changes.
5489      * @return a robust accelerometer calibrator.
5490      */
5491     public static RobustKnownPositionAccelerometerCalibrator create(
5492             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5493             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5494         return create(position, measurements, commonAxisUsed, listener, DEFAULT_ROBUST_METHOD);
5495     }
5496 
5497     /**
5498      * Creates a robust accelerometer calibrator using default robust method.
5499      *
5500      * @param position     position where body kinematics measures have been taken.
5501      * @param measurements collection of body kinematics measurements with standard
5502      *                     deviations taken at the same position with zero velocity
5503      *                     and unknown different orientations.
5504      * @param initialBias  initial accelerometer bias to be used to find a solution.
5505      *                     This must have length 3 and is expressed in meters per
5506      *                     squared second (m/s^2).
5507      * @return a robust accelerometer calibrator.
5508      * @throws IllegalArgumentException if provided bias array does not have length 3.
5509      */
5510     public static RobustKnownPositionAccelerometerCalibrator create(
5511             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5512             final double[] initialBias) {
5513         return create(position, measurements, initialBias, DEFAULT_ROBUST_METHOD);
5514     }
5515 
5516     /**
5517      * Creates a robust accelerometer calibrator using default robust method.
5518      *
5519      * @param position     position where body kinematics measures have been taken.
5520      * @param measurements collection of body kinematics measurements with standard
5521      *                     deviations taken at the same position with zero velocity
5522      *                     and unknown different orientations.
5523      * @param initialBias  initial accelerometer bias to be used to find a solution.
5524      *                     This must have length 3 and is expressed in meters per
5525      *                     squared second (m/s^2).
5526      * @param listener     listener to handle events raised by this calibrator.
5527      * @return a robust accelerometer calibrator.
5528      * @throws IllegalArgumentException if provided bias array does not have length 3.
5529      */
5530     public static RobustKnownPositionAccelerometerCalibrator create(
5531             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5532             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5533         return create(position, measurements, initialBias, listener, DEFAULT_ROBUST_METHOD);
5534     }
5535 
5536     /**
5537      * Creates a robust accelerometer calibrator using default robust method.
5538      *
5539      * @param position       position where body kinematics measures have been taken.
5540      * @param measurements   collection of body kinematics measurements with standard
5541      *                       deviations taken at the same position with zero velocity
5542      *                       and unknown different orientations.
5543      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5544      *                       accelerometer and gyroscope.
5545      * @param initialBias    initial accelerometer bias to be used to find a solution.
5546      *                       This must have length 3 and is expressed in meters per
5547      *                       squared second (m/s^2).
5548      * @return a robust accelerometer calibrator.
5549      * @throws IllegalArgumentException if provided bias array does not have length 3.
5550      */
5551     public static RobustKnownPositionAccelerometerCalibrator create(
5552             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5553             final boolean commonAxisUsed, final double[] initialBias) {
5554         return create(position, measurements, commonAxisUsed, initialBias, DEFAULT_ROBUST_METHOD);
5555     }
5556 
5557     /**
5558      * Creates a robust accelerometer calibrator using default robust method.
5559      *
5560      * @param position       position where body kinematics measures have been taken.
5561      * @param measurements   collection of body kinematics measurements with standard
5562      *                       deviations taken at the same position with zero velocity
5563      *                       and unknown different orientations.
5564      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5565      *                       accelerometer and gyroscope.
5566      * @param initialBias    initial accelerometer bias to be used to find a solution.
5567      *                       This must have length 3 and is expressed in meters per
5568      *                       squared second (m/s^2).
5569      * @param listener       listener to handle events raised by this calibrator.
5570      * @return a robust accelerometer calibrator.
5571      * @throws IllegalArgumentException if provided bias array does not have length 3.
5572      */
5573     public static RobustKnownPositionAccelerometerCalibrator create(
5574             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5575             final boolean commonAxisUsed, final double[] initialBias,
5576             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5577         return create(position, measurements, commonAxisUsed, initialBias, listener, DEFAULT_ROBUST_METHOD);
5578     }
5579 
5580     /**
5581      * Creates a robust accelerometer calibrator using default robust method.
5582      *
5583      * @param position     position where body kinematics measures have been taken.
5584      * @param measurements collection of body kinematics measurements with standard
5585      *                     deviations taken at the same position with zero velocity
5586      *                     and unknown different orientations.
5587      * @param initialBias  initial bias to find a solution.
5588      * @return a robust accelerometer calibrator.
5589      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5590      */
5591     public static RobustKnownPositionAccelerometerCalibrator create(
5592             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5593             final Matrix initialBias) {
5594         return create(position, measurements, initialBias, DEFAULT_ROBUST_METHOD);
5595     }
5596 
5597     /**
5598      * Creates a robust accelerometer calibrator using default robust method.
5599      *
5600      * @param position     position where body kinematics measures have been taken.
5601      * @param measurements collection of body kinematics measurements with standard
5602      *                     deviations taken at the same position with zero velocity
5603      *                     and unknown different orientations.
5604      * @param initialBias  initial bias to find a solution.
5605      * @param listener     listener to handle events raised by this calibrator.
5606      * @return a robust accelerometer calibrator.
5607      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5608      */
5609     public static RobustKnownPositionAccelerometerCalibrator create(
5610             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5611             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5612         return create(position, measurements, initialBias, listener, DEFAULT_ROBUST_METHOD);
5613     }
5614 
5615     /**
5616      * Creates a robust accelerometer calibrator using default robust method.
5617      *
5618      * @param position       position where body kinematics measures have been taken.
5619      * @param measurements   collection of body kinematics measurements with standard
5620      *                       deviations taken at the same position with zero velocity
5621      *                       and unknown different orientations.
5622      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5623      *                       accelerometer and gyroscope.
5624      * @param initialBias    initial bias to find a solution.
5625      * @return a robust accelerometer calibrator.
5626      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5627      */
5628     public static RobustKnownPositionAccelerometerCalibrator create(
5629             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5630             final boolean commonAxisUsed, final Matrix initialBias) {
5631         return create(position, measurements, commonAxisUsed, initialBias, DEFAULT_ROBUST_METHOD);
5632     }
5633 
5634     /**
5635      * Creates a robust accelerometer calibrator using default robust method.
5636      *
5637      * @param position       position where body kinematics measures have been taken.
5638      * @param measurements   collection of body kinematics measurements with standard
5639      *                       deviations taken at the same position with zero velocity
5640      *                       and unknown different orientations.
5641      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5642      *                       accelerometer and gyroscope.
5643      * @param initialBias    initial bias to find a solution.
5644      * @param listener       listener to handle events raised by this calibrator.
5645      * @return a robust accelerometer calibrator.
5646      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5647      */
5648     public static RobustKnownPositionAccelerometerCalibrator create(
5649             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5650             final boolean commonAxisUsed, final Matrix initialBias,
5651             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5652         return create(position, measurements, commonAxisUsed, initialBias, listener, DEFAULT_ROBUST_METHOD);
5653     }
5654 
5655     /**
5656      * Creates a robust accelerometer calibrator using default robust method.
5657      *
5658      * @param position     position where body kinematics measures have been taken.
5659      * @param measurements collection of body kinematics measurements with standard
5660      *                     deviations taken at the same position with zero velocity
5661      *                     and unknown different orientations.
5662      * @param initialBias  initial bias to find a solution.
5663      * @param initialMa    initial scale factors and cross coupling errors matrix.
5664      * @return a robust accelerometer calibrator.
5665      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5666      *                                  scaling and coupling error matrix is not 3x3.
5667      */
5668     public static RobustKnownPositionAccelerometerCalibrator create(
5669             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5670             final Matrix initialBias, final Matrix initialMa) {
5671         return create(position, measurements, initialBias, initialMa, DEFAULT_ROBUST_METHOD);
5672     }
5673 
5674     /**
5675      * Creates a robust accelerometer calibrator using default robust method.
5676      *
5677      * @param position     position where body kinematics measures have been taken.
5678      * @param measurements collection of body kinematics measurements with standard
5679      *                     deviations taken at the same position with zero velocity
5680      *                     and unknown different orientations.
5681      * @param initialBias  initial bias to find a solution.
5682      * @param initialMa    initial scale factors and cross coupling errors matrix.
5683      * @param listener     listener to handle events raised by this calibrator.
5684      * @return a robust accelerometer calibrator.
5685      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5686      *                                  scaling and coupling error matrix is not 3x3.
5687      */
5688     public static RobustKnownPositionAccelerometerCalibrator create(
5689             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5690             final Matrix initialBias, final Matrix initialMa,
5691             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5692         return create(position, measurements, initialBias, initialMa, listener, DEFAULT_ROBUST_METHOD);
5693     }
5694 
5695     /**
5696      * Creates a robust accelerometer calibrator using default robust method.
5697      *
5698      * @param position       position where body kinematics measures have been taken.
5699      * @param measurements   collection of body kinematics measurements with standard
5700      *                       deviations taken at the same position with zero velocity
5701      *                       and unknown different orientations.
5702      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5703      *                       accelerometer and gyroscope.
5704      * @param initialBias    initial bias to find a solution.
5705      * @param initialMa      initial scale factors and cross coupling errors matrix.
5706      * @return a robust accelerometer calibrator.
5707      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5708      *                                  scaling and coupling error matrix is not 3x3.
5709      */
5710     public static RobustKnownPositionAccelerometerCalibrator create(
5711             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5712             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
5713         return create(position, measurements, commonAxisUsed, initialBias, initialMa, DEFAULT_ROBUST_METHOD);
5714     }
5715 
5716     /**
5717      * Creates a robust accelerometer calibrator using default robust method.
5718      *
5719      * @param position       position where body kinematics measures have been taken.
5720      * @param measurements   collection of body kinematics measurements with standard
5721      *                       deviations taken at the same position with zero velocity
5722      *                       and unknown different orientations.
5723      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5724      *                       accelerometer and gyroscope.
5725      * @param initialBias    initial bias to find a solution.
5726      * @param initialMa      initial scale factors and cross coupling errors matrix.
5727      * @param listener       listener to handle events raised by this calibrator.
5728      * @return a robust accelerometer calibrator.
5729      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5730      *                                  scaling and coupling error matrix is not 3x3.
5731      */
5732     public static RobustKnownPositionAccelerometerCalibrator create(
5733             final ECEFPosition position, final List<StandardDeviationBodyKinematics> measurements,
5734             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
5735             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5736         return create(position, measurements, commonAxisUsed, initialBias, initialMa, listener, DEFAULT_ROBUST_METHOD);
5737     }
5738 
5739     /**
5740      * Creates a robust accelerometer calibrator using default robust method.
5741      *
5742      * @param position position where body kinematics measures have been taken.
5743      * @return a robust accelerometer calibrator.
5744      */
5745     public static RobustKnownPositionAccelerometerCalibrator create(final NEDPosition position) {
5746         return create(position, DEFAULT_ROBUST_METHOD);
5747     }
5748 
5749     /**
5750      * Creates a robust accelerometer calibrator using default robust method.
5751      *
5752      * @param position     position where body kinematics measures have been taken.
5753      * @param measurements list of body kinematics measurements taken at a given position with
5754      *                     different unknown orientations and containing the standard deviations
5755      *                     of accelerometer and gyroscope measurements.
5756      * @return a robust accelerometer calibrator.
5757      */
5758     public static RobustKnownPositionAccelerometerCalibrator create(
5759             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements) {
5760         return create(position, measurements, DEFAULT_ROBUST_METHOD);
5761     }
5762 
5763     /**
5764      * Creates a robust accelerometer calibrator using default robust method.
5765      *
5766      * @param position     position where body kinematics measures have been taken.
5767      * @param measurements list of body kinematics measurements taken at a given position with
5768      *                     different unknown orientations and containing the standard deviations
5769      *                     of accelerometer and gyroscope measurements.
5770      * @param listener     listener to be notified of events such as when estimation
5771      *                     starts, ends or its progress significantly changes.
5772      * @return a robust accelerometer calibrator.
5773      */
5774     public static RobustKnownPositionAccelerometerCalibrator create(
5775             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5776             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5777         return create(position, measurements, listener, DEFAULT_ROBUST_METHOD);
5778     }
5779 
5780     /**
5781      * Creates a robust accelerometer calibrator using default robust method.
5782      *
5783      * @param position       position where body kinematics measures have been taken.
5784      * @param measurements   list of body kinematics measurements taken at a given position with
5785      *                       different unknown orientations and containing the standard deviations
5786      *                       of accelerometer and gyroscope measurements.
5787      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5788      *                       accelerometer and gyroscope.
5789      * @return a robust accelerometer calibrator.
5790      */
5791     public static RobustKnownPositionAccelerometerCalibrator create(
5792             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5793             final boolean commonAxisUsed) {
5794         return create(position, measurements, commonAxisUsed, DEFAULT_ROBUST_METHOD);
5795     }
5796 
5797     /**
5798      * Creates a robust accelerometer calibrator using default robust method.
5799      *
5800      * @param position       position where body kinematics measures have been taken.
5801      * @param measurements   list of body kinematics measurements taken at a given position with
5802      *                       different unknown orientations and containing the standard deviations
5803      *                       of accelerometer and gyroscope measurements.
5804      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5805      *                       accelerometer and gyroscope.
5806      * @param listener       listener to be notified of events such as when estimation
5807      *                       starts, ends or its progress significantly changes.
5808      * @return a robust accelerometer calibrator.
5809      */
5810     public static RobustKnownPositionAccelerometerCalibrator create(
5811             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5812             final boolean commonAxisUsed, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5813         return create(position, measurements, commonAxisUsed, listener, DEFAULT_ROBUST_METHOD);
5814     }
5815 
5816 
5817     /**
5818      * Creates a robust accelerometer calibrator using default robust method.
5819      *
5820      * @param position     position where body kinematics measures have been taken.
5821      * @param measurements collection of body kinematics measurements with standard
5822      *                     deviations taken at the same position with zero velocity
5823      *                     and unknown different orientations.
5824      * @param initialBias  initial accelerometer bias to be used to find a solution.
5825      *                     This must have length 3 and is expressed in meters per
5826      *                     squared second (m/s^2).
5827      * @return a robust accelerometer calibrator.
5828      * @throws IllegalArgumentException if provided bias array does not have length 3.
5829      */
5830     public static RobustKnownPositionAccelerometerCalibrator create(
5831             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5832             final double[] initialBias) {
5833         return create(position, measurements, initialBias, DEFAULT_ROBUST_METHOD);
5834     }
5835 
5836     /**
5837      * Creates a robust accelerometer calibrator using default robust method.
5838      *
5839      * @param position     position where body kinematics measures have been taken.
5840      * @param measurements collection of body kinematics measurements with standard
5841      *                     deviations taken at the same position with zero velocity
5842      *                     and unknown different orientations.
5843      * @param initialBias  initial accelerometer bias to be used to find a solution.
5844      *                     This must have length 3 and is expressed in meters per
5845      *                     squared second (m/s^2).
5846      * @param listener     listener to handle events raised by this calibrator.
5847      * @return a robust accelerometer calibrator.
5848      * @throws IllegalArgumentException if provided bias array does not have length 3.
5849      */
5850     public static RobustKnownPositionAccelerometerCalibrator create(
5851             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5852             final double[] initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5853         return create(position, measurements, initialBias, listener, DEFAULT_ROBUST_METHOD);
5854     }
5855 
5856     /**
5857      * Creates a robust accelerometer calibrator using default robust method.
5858      *
5859      * @param position       position where body kinematics measures have been taken.
5860      * @param measurements   collection of body kinematics measurements with standard
5861      *                       deviations taken at the same position with zero velocity
5862      *                       and unknown different orientations.
5863      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5864      *                       accelerometer and gyroscope.
5865      * @param initialBias    initial accelerometer bias to be used to find a solution.
5866      *                       This must have length 3 and is expressed in meters per
5867      *                       squared second (m/s^2).
5868      * @return a robust accelerometer calibrator.
5869      * @throws IllegalArgumentException if provided bias array does not have length 3.
5870      */
5871     public static RobustKnownPositionAccelerometerCalibrator create(
5872             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5873             final boolean commonAxisUsed, final double[] initialBias) {
5874         return create(position, measurements, commonAxisUsed, initialBias, DEFAULT_ROBUST_METHOD);
5875     }
5876 
5877     /**
5878      * Creates a robust accelerometer calibrator using default robust method.
5879      *
5880      * @param position       position where body kinematics measures have been taken.
5881      * @param measurements   collection of body kinematics measurements with standard
5882      *                       deviations taken at the same position with zero velocity
5883      *                       and unknown different orientations.
5884      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5885      *                       accelerometer and gyroscope.
5886      * @param initialBias    initial accelerometer bias to be used to find a solution.
5887      *                       This must have length 3 and is expressed in meters per
5888      *                       squared second (m/s^2).
5889      * @param listener       listener to handle events raised by this calibrator.
5890      * @return a robust accelerometer calibrator.
5891      * @throws IllegalArgumentException if provided bias array does not have length 3.
5892      */
5893     public static RobustKnownPositionAccelerometerCalibrator create(
5894             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5895             final boolean commonAxisUsed, final double[] initialBias,
5896             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5897         return create(position, measurements, commonAxisUsed, initialBias, listener, DEFAULT_ROBUST_METHOD);
5898     }
5899 
5900     /**
5901      * Creates a robust accelerometer calibrator using default robust method.
5902      *
5903      * @param position     position where body kinematics measures have been taken.
5904      * @param measurements collection of body kinematics measurements with standard
5905      *                     deviations taken at the same position with zero velocity
5906      *                     and unknown different orientations.
5907      * @param initialBias  initial bias to find a solution.
5908      * @return a robust accelerometer calibrator.
5909      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5910      */
5911     public static RobustKnownPositionAccelerometerCalibrator create(
5912             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5913             final Matrix initialBias) {
5914         return create(position, measurements, initialBias, DEFAULT_ROBUST_METHOD);
5915     }
5916 
5917     /**
5918      * Creates a robust accelerometer calibrator using default robust method.
5919      *
5920      * @param position     position where body kinematics measures have been taken.
5921      * @param measurements collection of body kinematics measurements with standard
5922      *                     deviations taken at the same position with zero velocity
5923      *                     and unknown different orientations.
5924      * @param initialBias  initial bias to find a solution.
5925      * @param listener     listener to handle events raised by this calibrator.
5926      * @return a robust accelerometer calibrator.
5927      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5928      */
5929     public static RobustKnownPositionAccelerometerCalibrator create(
5930             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5931             final Matrix initialBias, final RobustKnownPositionAccelerometerCalibratorListener listener) {
5932         return create(position, measurements, initialBias, listener, DEFAULT_ROBUST_METHOD);
5933     }
5934 
5935     /**
5936      * Creates a robust accelerometer calibrator using default robust method.
5937      *
5938      * @param position       position where body kinematics measures have been taken.
5939      * @param measurements   collection of body kinematics measurements with standard
5940      *                       deviations taken at the same position with zero velocity
5941      *                       and unknown different orientations.
5942      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5943      *                       accelerometer and gyroscope.
5944      * @param initialBias    initial bias to find a solution.
5945      * @return a robust accelerometer calibrator.
5946      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5947      */
5948     public static RobustKnownPositionAccelerometerCalibrator create(
5949             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5950             final boolean commonAxisUsed, final Matrix initialBias) {
5951         return create(position, measurements, commonAxisUsed, initialBias, DEFAULT_ROBUST_METHOD);
5952     }
5953 
5954     /**
5955      * Creates a robust accelerometer calibrator using default robust method.
5956      *
5957      * @param position       position where body kinematics measures have been taken.
5958      * @param measurements   collection of body kinematics measurements with standard
5959      *                       deviations taken at the same position with zero velocity
5960      *                       and unknown different orientations.
5961      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
5962      *                       accelerometer and gyroscope.
5963      * @param initialBias    initial bias to find a solution.
5964      * @param listener       listener to handle events raised by this calibrator.
5965      * @return a robust accelerometer calibrator.
5966      * @throws IllegalArgumentException if provided bias matrix is not 3x1.
5967      */
5968     public static RobustKnownPositionAccelerometerCalibrator create(
5969             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5970             final boolean commonAxisUsed, final Matrix initialBias,
5971             final RobustKnownPositionAccelerometerCalibratorListener listener) {
5972         return create(position, measurements, commonAxisUsed, initialBias, listener, DEFAULT_ROBUST_METHOD);
5973     }
5974 
5975     /**
5976      * Creates a robust accelerometer calibrator using default robust method.
5977      *
5978      * @param position     position where body kinematics measures have been taken.
5979      * @param measurements collection of body kinematics measurements with standard
5980      *                     deviations taken at the same position with zero velocity
5981      *                     and unknown different orientations.
5982      * @param initialBias  initial bias to find a solution.
5983      * @param initialMa    initial scale factors and cross coupling errors matrix.
5984      * @return a robust accelerometer calibrator.
5985      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
5986      *                                  scaling and coupling error matrix is not 3x3.
5987      */
5988     public static RobustKnownPositionAccelerometerCalibrator create(
5989             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
5990             final Matrix initialBias, final Matrix initialMa) {
5991         return create(position, measurements, initialBias, initialMa, DEFAULT_ROBUST_METHOD);
5992     }
5993 
5994     /**
5995      * Creates a robust accelerometer calibrator using default robust method.
5996      *
5997      * @param position     position where body kinematics measures have been taken.
5998      * @param measurements collection of body kinematics measurements with standard
5999      *                     deviations taken at the same position with zero velocity
6000      *                     and unknown different orientations.
6001      * @param initialBias  initial bias to find a solution.
6002      * @param initialMa    initial scale factors and cross coupling errors matrix.
6003      * @param listener     listener to handle events raised by this calibrator.
6004      * @return a robust accelerometer calibrator.
6005      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
6006      *                                  scaling and coupling error matrix is not 3x3.
6007      */
6008     public static RobustKnownPositionAccelerometerCalibrator create(
6009             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
6010             final Matrix initialBias, final Matrix initialMa,
6011             final RobustKnownPositionAccelerometerCalibratorListener listener) {
6012         return create(position, measurements, initialBias, initialMa, listener, DEFAULT_ROBUST_METHOD);
6013     }
6014 
6015     /**
6016      * Creates a robust accelerometer calibrator using default robust method.
6017      *
6018      * @param position       position where body kinematics measures have been taken.
6019      * @param measurements   collection of body kinematics measurements with standard
6020      *                       deviations taken at the same position with zero velocity
6021      *                       and unknown different orientations.
6022      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
6023      *                       accelerometer and gyroscope.
6024      * @param initialBias    initial bias to find a solution.
6025      * @param initialMa      initial scale factors and cross coupling errors matrix.
6026      * @return a robust accelerometer calibrator.
6027      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
6028      *                                  scaling and coupling error matrix is not 3x3.
6029      */
6030     public static RobustKnownPositionAccelerometerCalibrator create(
6031             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
6032             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
6033         return create(position, measurements, commonAxisUsed, initialBias, initialMa, DEFAULT_ROBUST_METHOD);
6034     }
6035 
6036     /**
6037      * Creates a robust accelerometer calibrator using default robust method.
6038      *
6039      * @param position       position where body kinematics measures have been taken.
6040      * @param measurements   collection of body kinematics measurements with standard
6041      *                       deviations taken at the same position with zero velocity
6042      *                       and unknown different orientations.
6043      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
6044      *                       accelerometer and gyroscope.
6045      * @param initialBias    initial bias to find a solution.
6046      * @param initialMa      initial scale factors and cross coupling errors matrix.
6047      * @param listener       listener to handle events raised by this calibrator.
6048      * @return a robust accelerometer calibrator.
6049      * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
6050      *                                  scaling and coupling error matrix is not 3x3.
6051      */
6052     public static RobustKnownPositionAccelerometerCalibrator create(
6053             final NEDPosition position, final List<StandardDeviationBodyKinematics> measurements,
6054             final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
6055             final RobustKnownPositionAccelerometerCalibratorListener listener) {
6056         return create(position, measurements, commonAxisUsed, initialBias, initialMa, listener, DEFAULT_ROBUST_METHOD);
6057     }
6058 
6059     /**
6060      * Computes error of preliminary result respect a given measurement for current gravity norm.
6061      *
6062      * @param measurement       a measurement.
6063      * @param preliminaryResult a preliminary result.
6064      * @return computed error.
6065      */
6066     protected double computeError(
6067             final StandardDeviationBodyKinematics measurement, final PreliminaryResult preliminaryResult) {
6068 
6069         try {
6070             // We know that measured specific force is:
6071             // fmeas = ba + (I + Ma) * ftrue
6072 
6073             // fmeas - ba = (I + Ma) * ftrue
6074 
6075             // ftrue = (I + Ma)^-1 * (fmeas - ba)
6076 
6077             // We know that ||ftrue|| should be equal to the gravity value at current Earth
6078             // position
6079             // ||ftrue|| = g ~ 9.81 m/s^2
6080 
6081             final var estBiases = preliminaryResult.estimatedBiases;
6082             final var estMa = preliminaryResult.estimatedMa;
6083 
6084             if (identity == null) {
6085                 identity = Matrix.identity(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
6086             }
6087 
6088             if (tmp1 == null) {
6089                 tmp1 = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
6090             }
6091 
6092             if (tmp2 == null) {
6093                 tmp2 = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
6094             }
6095 
6096             if (tmp3 == null) {
6097                 tmp3 = new Matrix(BodyKinematics.COMPONENTS, 1);
6098             }
6099 
6100             if (tmp4 == null) {
6101                 tmp4 = new Matrix(BodyKinematics.COMPONENTS, 1);
6102             }
6103 
6104             identity.add(estMa, tmp1);
6105 
6106             Utils.inverse(tmp1, tmp2);
6107 
6108             final var kinematics = measurement.getKinematics();
6109             final var fmeasX = kinematics.getFx();
6110             final var fmeasY = kinematics.getFy();
6111             final var fmeasZ = kinematics.getFz();
6112 
6113             final var bx = estBiases[0];
6114             final var by = estBiases[1];
6115             final var bz = estBiases[2];
6116 
6117             tmp3.setElementAtIndex(0, fmeasX - bx);
6118             tmp3.setElementAtIndex(1, fmeasY - by);
6119             tmp3.setElementAtIndex(2, fmeasZ - bz);
6120 
6121             tmp2.multiply(tmp3, tmp4);
6122 
6123             final var norm = Utils.normF(tmp4);
6124             final var diff = gravityNorm - norm;
6125 
6126             return diff * diff;
6127 
6128         } catch (final AlgebraException e) {
6129             return Double.MAX_VALUE;
6130         }
6131     }
6132 
6133     /**
6134      * Computes a preliminary solution for a subset of samples picked by a robust estimator.
6135      *
6136      * @param samplesIndices indices of samples picked by the robust estimator.
6137      * @param solutions      list where estimated preliminary solution will be stored.
6138      */
6139     protected void computePreliminarySolutions(final int[] samplesIndices, final List<PreliminaryResult> solutions) {
6140 
6141         final var meas = new ArrayList<StandardDeviationBodyKinematics>();
6142 
6143         for (final var samplesIndex : samplesIndices) {
6144             meas.add(this.measurements.get(samplesIndex));
6145         }
6146 
6147         try {
6148             final var result = new PreliminaryResult();
6149             result.estimatedBiases = getInitialBias();
6150             result.estimatedMa = getInitialMa();
6151 
6152             innerCalibrator.setInitialBias(result.estimatedBiases);
6153             innerCalibrator.setInitialMa(result.estimatedMa);
6154             innerCalibrator.setCommonAxisUsed(commonAxisUsed);
6155             innerCalibrator.setPosition(position);
6156             innerCalibrator.setMeasurements(meas);
6157             innerCalibrator.calibrate();
6158 
6159             innerCalibrator.getEstimatedBiases(result.estimatedBiases);
6160             result.estimatedMa = innerCalibrator.getEstimatedMa();
6161 
6162             if (keepCovariance) {
6163                 result.covariance = innerCalibrator.getEstimatedCovariance();
6164             } else {
6165                 result.covariance = null;
6166             }
6167 
6168             result.estimatedMse = innerCalibrator.getEstimatedMse();
6169             result.estimatedChiSq = innerCalibrator.getEstimatedChiSq();
6170             result.estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
6171             result.estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
6172             result.estimatedP = innerCalibrator.getEstimatedP();
6173             result.estimatedQ = innerCalibrator.getEstimatedQ();
6174 
6175             solutions.add(result);
6176 
6177         } catch (final LockedException | CalibrationException | NotReadyException e) {
6178             solutions.clear();
6179         }
6180     }
6181 
6182     /**
6183      * Attempts to refine calibration parameters if refinement is requested.
6184      * This method returns a refined solution or provided input if refinement is not
6185      * requested or has failed.
6186      * If refinement is enabled and it is requested to keep covariance, this method
6187      * will also keep covariance of refined position.
6188      *
6189      * @param preliminaryResult a preliminary result.
6190      */
6191     protected void attemptRefine(final PreliminaryResult preliminaryResult) {
6192         if (refineResult && inliersData != null) {
6193             final var inliers = inliersData.getInliers();
6194             final var nSamples = measurements.size();
6195 
6196             final var inlierMeasurements = new ArrayList<StandardDeviationBodyKinematics>();
6197             for (var i = 0; i < nSamples; i++) {
6198                 if (inliers.get(i)) {
6199                     // sample is inlier
6200                     inlierMeasurements.add(measurements.get(i));
6201                 }
6202             }
6203 
6204             try {
6205                 innerCalibrator.setInitialBias(preliminaryResult.estimatedBiases);
6206                 innerCalibrator.setInitialMa(preliminaryResult.estimatedMa);
6207                 innerCalibrator.setCommonAxisUsed(commonAxisUsed);
6208                 innerCalibrator.setPosition(position);
6209                 innerCalibrator.setMeasurements(inlierMeasurements);
6210                 innerCalibrator.calibrate();
6211 
6212                 estimatedBiases = innerCalibrator.getEstimatedBiases();
6213                 estimatedMa = innerCalibrator.getEstimatedMa();
6214                 estimatedMse = innerCalibrator.getEstimatedMse();
6215                 estimatedChiSq = innerCalibrator.getEstimatedChiSq();
6216                 estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
6217                 estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
6218                 estimatedP = innerCalibrator.getEstimatedP();
6219                 estimatedQ = innerCalibrator.getEstimatedQ();
6220 
6221                 if (keepCovariance) {
6222                     estimatedCovariance = innerCalibrator.getEstimatedCovariance();
6223                 } else {
6224                     estimatedCovariance = null;
6225                 }
6226             } catch (final LockedException | CalibrationException | NotReadyException e) {
6227                 estimatedCovariance = preliminaryResult.covariance;
6228                 estimatedBiases = preliminaryResult.estimatedBiases;
6229                 estimatedMa = preliminaryResult.estimatedMa;
6230                 estimatedMse = preliminaryResult.estimatedMse;
6231                 estimatedChiSq = preliminaryResult.estimatedChiSq;
6232                 estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
6233                 estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
6234                 estimatedP = preliminaryResult.estimatedP;
6235                 estimatedQ = preliminaryResult.estimatedQ;
6236             }
6237         } else {
6238             estimatedCovariance = preliminaryResult.covariance;
6239             estimatedBiases = preliminaryResult.estimatedBiases;
6240             estimatedMa = preliminaryResult.estimatedMa;
6241             estimatedMse = preliminaryResult.estimatedMse;
6242             estimatedChiSq = preliminaryResult.estimatedChiSq;
6243             estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
6244             estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
6245             estimatedP = preliminaryResult.estimatedP;
6246             estimatedQ = preliminaryResult.estimatedQ;
6247         }
6248     }
6249 
6250     /**
6251      * Computes gravity norm for current position.
6252      *
6253      * @return gravity norm for current position expressed in meters per squared second.
6254      */
6255     protected double computeGravityNorm() {
6256         final var gravity = ECEFGravityEstimator.estimateGravityAndReturnNew(
6257                 position.getX(), position.getY(), position.getZ());
6258         return gravity.getNorm();
6259     }
6260 
6261     /**
6262      * Converts provided NED position expressed in terms of latitude, longitude and height respect
6263      * mean Earth surface, to position expressed in ECEF coordinates.
6264      *
6265      * @param position NED position to be converted.
6266      * @return converted position expressed in ECEF coordinates.
6267      */
6268     private static ECEFPosition convertPosition(final NEDPosition position) {
6269         final var velocity = new ECEFVelocity();
6270         final var result = new ECEFPosition();
6271         NEDtoECEFPositionVelocityConverter.convertNEDtoECEF(
6272                 position.getLatitude(), position.getLongitude(), position.getHeight(),
6273                 0.0, 0.0, 0.0, result, velocity);
6274         return result;
6275     }
6276 
6277     /**
6278      * Converts acceleration value and unit to meters per squared second.
6279      *
6280      * @param value acceleration value.
6281      * @param unit  unit of acceleration value.
6282      * @return converted value.
6283      */
6284     private static double convertAcceleration(final double value, final AccelerationUnit unit) {
6285         return AccelerationConverter.convert(value, unit, AccelerationUnit.METERS_PER_SQUARED_SECOND);
6286     }
6287 
6288     /**
6289      * Converts acceleration instance to meters per squared second.
6290      *
6291      * @param acceleration acceleration instance to be converted.
6292      * @return converted value.
6293      */
6294     private static double convertAcceleration(final Acceleration acceleration) {
6295         return convertAcceleration(acceleration.getValue().doubleValue(), acceleration.getUnit());
6296     }
6297 
6298     /**
6299      * Internal class containing estimated preliminary result.
6300      */
6301     protected static class PreliminaryResult {
6302         /**
6303          * Estimated accelerometer biases for each IMU axis expressed in meter per squared
6304          * second (m/s^2).
6305          */
6306         private double[] estimatedBiases;
6307 
6308         /**
6309          * Estimated accelerometer scale factors and cross coupling errors.
6310          * This is the product of matrix Ta containing cross coupling errors and Ka
6311          * containing scaling factors.
6312          * So tat:
6313          * <pre>
6314          *     Ma = [sx    mxy  mxz] = Ta*Ka
6315          *          [myx   sy   myz]
6316          *          [mzx   mzy  sz ]
6317          * </pre>
6318          * Where:
6319          * <pre>
6320          *     Ka = [sx 0   0 ]
6321          *          [0  sy  0 ]
6322          *          [0  0   sz]
6323          * </pre>
6324          * and
6325          * <pre>
6326          *     Ta = [1          -alphaXy    alphaXz ]
6327          *          [alphaYx    1           -alphaYz]
6328          *          [-alphaZx   alphaZy     1       ]
6329          * </pre>
6330          * Hence:
6331          * <pre>
6332          *     Ma = [sx    mxy  mxz] = Ta*Ka =  [sx             -sy * alphaXy   sz * alphaXz ]
6333          *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
6334          *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
6335          * </pre>
6336          * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
6337          * are considered to be zero if the accelerometer z-axis is assumed to be the same
6338          * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Ma matrix
6339          * becomes upper diagonal:
6340          * <pre>
6341          *     Ma = [sx    mxy  mxz]
6342          *          [0     sy   myz]
6343          *          [0     0    sz ]
6344          * </pre>
6345          * Values of this matrix are unit-less.
6346          */
6347         private Matrix estimatedMa;
6348 
6349         /**
6350          * Estimated covariance matrix.
6351          */
6352         private Matrix covariance;
6353 
6354         /**
6355          * Estimated MSE (Mean Square Error).
6356          */
6357         private double estimatedMse;
6358 
6359         /**
6360          * Estimated chi square value.
6361          */
6362         private double estimatedChiSq;
6363 
6364         /**
6365          * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
6366          * minus the number of estimated parameters.
6367          */
6368         private int estimatedChiSqDegreesOfFreedom;
6369 
6370         /**
6371          * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
6372          * freedom. Ideally this value should be close to 1.0.
6373          */
6374         private double estimatedReducedChiSq;
6375 
6376         /**
6377          * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
6378          * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
6379          * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
6380          */
6381         private double estimatedP;
6382 
6383         /**
6384          * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
6385          * the better the fit that has been estimated.
6386          */
6387         private double estimatedQ;
6388     }
6389 }