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