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