View Javadoc
1   /*
2    * Copyright (C) 2022 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.magnetometer;
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.BodyMagneticFluxDensity;
26  import com.irurueta.navigation.inertial.calibration.CalibrationException;
27  import com.irurueta.navigation.inertial.calibration.MagneticFluxDensityTriad;
28  import com.irurueta.navigation.inertial.calibration.StandardDeviationBodyMagneticFluxDensity;
29  import com.irurueta.numerical.robust.InliersData;
30  import com.irurueta.numerical.robust.RobustEstimatorMethod;
31  import com.irurueta.units.MagneticFluxDensity;
32  import com.irurueta.units.MagneticFluxDensityConverter;
33  import com.irurueta.units.MagneticFluxDensityUnit;
34  
35  import java.util.ArrayList;
36  import java.util.List;
37  
38  /**
39   * This is an abstract class to robustly estimate magnetometer hard-iron
40   * biases, cross couplings and scaling factors.
41   * <p>
42   * To use this calibrator at least 10 measurements taken at a single unknown
43   * position and instant must be taken at 10 different unknown orientations
44   * when common z-axis is assumed, otherwise at least 13
45   * measurements are required.
46   * <p>
47   * Measured magnetic flux density is assumed to follow the model shown below:
48   * <pre>
49   *     mBmeas = bm + (I + Mm) * mBtrue + w
50   * </pre>
51   * Where:
52   * - mBmeas is the measured magnetic flux density. This is a 3x1 vector.
53   * - bm is magnetometer hard-iron bias. Ideally, on a perfect magnetometer,
54   * this should be a 3x1 zero vector.
55   * - I is the 3x3 identity matrix.
56   * - Mm is the 3x3 soft-iron matrix containing cross-couplings and scaling
57   * factors. Ideally, on a perfect magnetometer, this should be a 3x3 zero
58   * matrix.
59   * - mBtrue is ground-truth magnetic flux density. This is a 3x1 vector.
60   * - w is measurement noise. This is a 3x1 vector.
61   * Notice that this calibrator assumes that all measurements are taken in
62   * a short span of time where Earth magnetic field can be assumed to be
63   * constant at provided location and instant.
64   */
65  public abstract class RobustKnownMagneticFluxDensityNormMagnetometerCalibrator implements
66          MagnetometerNonLinearCalibrator, UnknownHardIronNonLinearMagnetometerCalibrator,
67          OrderedStandardDeviationBodyMagneticFluxDensityMagnetometerCalibrator, QualityScoredMagnetometerCalibrator {
68  
69      /**
70       * Indicates whether by default a common z-axis is assumed for the accelerometer,
71       * gyroscope and magnetometer.
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              BaseMagneticFluxDensityNormMagnetometerCalibrator.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              BaseMagneticFluxDensityNormMagnetometerCalibrator.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 magnetic flux density measurements taken
147      * at a given position with different unknown orientations and containing the
148      * standard deviation of magnetometer measurements.
149      */
150     protected List<StandardDeviationBodyMagneticFluxDensity> 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 RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener;
157 
158     /**
159      * Indicates whether estimator 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 inlier 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      * gyroscope and magnetometer.
203      * When enabled, this eliminates 3 variables from soft-iron (Mm) matrix.
204      */
205     private boolean commonAxisUsed = DEFAULT_USE_COMMON_Z_AXIS;
206 
207     /**
208      * Estimated magnetometer hard-iron biases for each magnetometer axis
209      * expressed in Teslas (T).
210      */
211     private double[] estimatedHardIron;
212 
213     /**
214      * Estimated magnetometer soft-iron matrix containing scale factors
215      * and cross coupling errors.
216      * This is the product of matrix Tm containing cross coupling errors and Km
217      * containing scaling factors.
218      * So tat:
219      * <pre>
220      *     Mm = [sx    mxy  mxz] = Tm*Km
221      *          [myx   sy   myz]
222      *          [mzx   mzy  sz ]
223      * </pre>
224      * Where:
225      * <pre>
226      *     Km = [sx 0   0 ]
227      *          [0  sy  0 ]
228      *          [0  0   sz]
229      * </pre>
230      * and
231      * <pre>
232      *     Tm = [1          -alphaXy    alphaXz ]
233      *          [alphaYx    1           -alphaYz]
234      *          [-alphaZx   alphaZy     1       ]
235      * </pre>
236      * Hence:
237      * <pre>
238      *     Mm = [sx    mxy  mxz] = Tm*Km =  [sx             -sy * alphaXy   sz * alphaXz ]
239      *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
240      *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
241      * </pre>
242      * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
243      * are considered to be zero if the accelerometer z-axis is assumed to be the same
244      * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mm matrix
245      * becomes upper diagonal:
246      * <pre>
247      *     Mm = [sx    mxy  mxz]
248      *          [0     sy   myz]
249      *          [0     0    sz ]
250      * </pre>
251      * Values of this matrix are unit-less.
252      */
253     private Matrix estimatedMm;
254 
255     /**
256      * Indicates whether covariance must be kept after refining result.
257      * This setting is only taken into account if result is refined.
258      */
259     private boolean keepCovariance = DEFAULT_KEEP_COVARIANCE;
260 
261     /**
262      * Estimated covariance matrix for estimated parameters.
263      */
264     private Matrix estimatedCovariance;
265 
266     /**
267      * Estimated chi square value.
268      */
269     private double estimatedChiSq;
270 
271     /**
272      * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
273      * minus the number of estimated parameters.
274      */
275     private int estimatedChiSqDegreesOfFreedom;
276 
277     /**
278      * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
279      * freedom. Ideally this value should be close to 1.0.
280      */
281     private double estimatedReducedChiSq;
282 
283     /**
284      * Estimated mean square error respect to provided measurements.
285      */
286     private double estimatedMse;
287 
288     /**
289      * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
290      * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
291      * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
292      */
293     private double estimatedP;
294 
295     /**
296      * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
297      * the better the fit that has been estimated.
298      */
299     private double estimatedQ;
300 
301     /**
302      * Initial x-coordinate of hard-iron bias to be used to find a solution.
303      * This is expressed in Teslas (T).
304      */
305     private double initialHardIronX;
306 
307     /**
308      * Initial y-coordinate of hard-iron bias to be used to find a solution.
309      * This is expressed in Teslas (T).
310      */
311     private double initialHardIronY;
312 
313     /**
314      * Initial z-coordinate of hard-iron bias to be used to find a solution.
315      * This is expressed in Teslas (T).
316      */
317     private double initialHardIronZ;
318 
319     /**
320      * Initial x scaling factor.
321      */
322     private double initialSx;
323 
324     /**
325      * Initial y scaling factor.
326      */
327     private double initialSy;
328 
329     /**
330      * Initial z scaling factor.
331      */
332     private double initialSz;
333 
334     /**
335      * Initial x-y cross coupling error.
336      */
337     private double initialMxy;
338 
339     /**
340      * Initial x-z cross coupling error.
341      */
342     private double initialMxz;
343 
344     /**
345      * Initial y-x cross coupling error.
346      */
347     private double initialMyx;
348 
349     /**
350      * Initial y-z cross coupling error.
351      */
352     private double initialMyz;
353 
354     /**
355      * Initial z-x cross coupling error.
356      */
357     private double initialMzx;
358 
359     /**
360      * Initial z-y cross coupling error.
361      */
362     private double initialMzy;
363 
364     /**
365      * Ground truth magnetic flux density norm to be expected at location where measurements have been made,
366      * expressed in Teslas (T).
367      */
368     protected Double groundTruthMagneticFluxDensityNorm;
369 
370     /**
371      * Inner calibrator to compute calibration for each subset of data or during
372      * final refining.
373      */
374     private final KnownMagneticFluxDensityNormMagnetometerCalibrator innerCalibrator =
375             new KnownMagneticFluxDensityNormMagnetometerCalibrator();
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 RobustKnownMagneticFluxDensityNormMagnetometerCalibrator() {
406     }
407 
408     /**
409      * Constructor.
410      *
411      * @param listener listener to handle events raised by this calibrator.
412      */
413     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
414             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
415         this.listener = listener;
416     }
417 
418     /**
419      * Constructor.
420      *
421      * @param measurements list of body magnetic flux density
422      *                     measurements with standard deviation of
423      *                     magnetometer measurements taken at the same
424      *                     position with zero velocity and unknown different
425      *                     orientations.
426      */
427     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
428             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
429         this.measurements = measurements;
430     }
431 
432     /**
433      * Constructor.
434      *
435      * @param commonAxisUsed indicates whether z-axis is assumed to be common
436      *                       for the accelerometer, gyroscope and magnetometer.
437      */
438     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(final boolean commonAxisUsed) {
439         this.commonAxisUsed = commonAxisUsed;
440     }
441 
442     /**
443      * Constructor.
444      *
445      * @param initialHardIron initial hard-iron to find a solution.
446      * @throws IllegalArgumentException if provided hard-iron array does
447      *                                  not have length 3.
448      */
449     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(final double[] initialHardIron) {
450         try {
451             setInitialHardIron(initialHardIron);
452         } catch (final LockedException ignore) {
453             // never happens
454         }
455     }
456 
457     /**
458      * Constructor.
459      *
460      * @param initialHardIron initial hard-iron to find a solution.
461      * @throws IllegalArgumentException if provided hard-iron matrix is not
462      *                                  3x1.
463      */
464     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(final Matrix initialHardIron) {
465         try {
466             setInitialHardIron(initialHardIron);
467         } catch (final LockedException ignore) {
468             // never happens
469         }
470     }
471 
472     /**
473      * Constructor.
474      *
475      * @param initialHardIron initial hard-iron to find a solution.
476      * @param initialMm       initial soft-iron matrix containing scale factors
477      *                        and cross coupling errors.
478      * @throws IllegalArgumentException if provided hard-iron matrix is not
479      *                                  3x1 or if soft-iron matrix is not
480      *                                  3x3.
481      */
482     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
483             final Matrix initialHardIron, final Matrix initialMm) {
484         this(initialHardIron);
485         try {
486             setInitialMm(initialMm);
487         } catch (final LockedException ignore) {
488             // never happens
489         }
490     }
491 
492     /**
493      * Constructor.
494      *
495      * @param measurements list of body magnetic flux density
496      *                     measurements with standard deviation of
497      *                     magnetometer measurements taken at the same
498      *                     position with zero velocity and unknown different
499      *                     orientations.
500      * @param listener     listener to handle events raised by this calibrator.
501      */
502     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
503             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
504             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
505         this.measurements = measurements;
506         this.listener = listener;
507     }
508 
509     /**
510      * Constructor.
511      *
512      * @param measurements   collection of body magnetic flux density
513      *                       measurements with standard deviation of
514      *                       magnetometer measurements taken at the same
515      *                       position with zero velocity and unknown different
516      *                       orientations.
517      * @param commonAxisUsed indicates whether z-axis is assumed to be common
518      *                       for the accelerometer, gyroscope and magnetometer.
519      */
520     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
521             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
522         this.measurements = measurements;
523         this.commonAxisUsed = commonAxisUsed;
524     }
525 
526     /**
527      * Constructor.
528      *
529      * @param measurements   collection of body magnetic flux density
530      *                       measurements with standard deviation of
531      *                       magnetometer measurements taken at the same
532      *                       position with zero velocity and unknown different
533      *                       orientations.
534      * @param commonAxisUsed indicates whether z-axis is assumed to be common
535      *                       for the accelerometer, gyroscope and magnetometer.
536      * @param listener       listener to handle events raised by this calibrator.
537      */
538     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
539             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
540             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
541         this(measurements, commonAxisUsed);
542         this.listener = listener;
543     }
544 
545     /**
546      * Constructor.
547      *
548      * @param measurements    collection of body magnetic flux density
549      *                        measurements with standard deviation of
550      *                        magnetometer measurements taken at the same
551      *                        position with zero velocity and unknown different
552      *                        orientations.
553      * @param initialHardIron initial hard-iron to find a solution.
554      * @throws IllegalArgumentException if provided hard-iron array does
555      *                                  not have length 3.
556      */
557     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
558             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron) {
559         this(initialHardIron);
560         this.measurements = measurements;
561     }
562 
563     /**
564      * Constructor.
565      *
566      * @param measurements    collection of body magnetic flux density
567      *                        measurements with standard deviation of
568      *                        magnetometer measurements taken at the same
569      *                        position with zero velocity and unknown different
570      *                        orientations.
571      * @param initialHardIron initial hard-iron to find a solution.
572      * @param listener        listener to handle events raised by this calibrator.
573      * @throws IllegalArgumentException if provided hard-iron array does
574      *                                  not have length 3.
575      */
576     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
577             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
578             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
579         this(measurements, initialHardIron);
580         this.listener = listener;
581     }
582 
583     /**
584      * Constructor.
585      *
586      * @param measurements    collection of body magnetic flux density
587      *                        measurements with standard deviation of
588      *                        magnetometer measurements taken at the same
589      *                        position with zero velocity and unknown different
590      *                        orientations.
591      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
592      *                        for the accelerometer, gyroscope and magnetometer.
593      * @param initialHardIron initial hard-iron to find a solution.
594      * @throws IllegalArgumentException if provided hard-iron array does
595      *                                  not have length 3.
596      */
597     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
598             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
599             final double[] initialHardIron) {
600         this(measurements, initialHardIron);
601         this.commonAxisUsed = commonAxisUsed;
602     }
603 
604     /**
605      * Constructor.
606      *
607      * @param measurements    collection of body magnetic flux density
608      *                        measurements with standard deviation of
609      *                        magnetometer measurements taken at the same
610      *                        position with zero velocity and unknown different
611      *                        orientations.
612      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
613      *                        for the accelerometer, gyroscope and magnetometer.
614      * @param initialHardIron initial hard-iron to find a solution.
615      * @param listener        listener to handle events raised by this calibrator.
616      * @throws IllegalArgumentException if provided hard-iron array does
617      *                                  not have length 3.
618      */
619     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
620             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
621             final double[] initialHardIron,
622             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
623         this(measurements, commonAxisUsed, initialHardIron);
624         this.listener = listener;
625     }
626 
627     /**
628      * Constructor.
629      *
630      * @param measurements    collection of body magnetic flux density
631      *                        measurements with standard deviation of
632      *                        magnetometer measurements taken at the same
633      *                        position with zero velocity and unknown different
634      *                        orientations.
635      * @param initialHardIron initial hard-iron to find a solution.
636      * @throws IllegalArgumentException if provided hard-iron matrix is not
637      *                                  3x1.
638      */
639     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
640             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron) {
641         this(initialHardIron);
642         this.measurements = measurements;
643     }
644 
645     /**
646      * Constructor.
647      *
648      * @param measurements    collection of body magnetic flux density
649      *                        measurements with standard deviation of
650      *                        magnetometer measurements taken at the same
651      *                        position with zero velocity and unknown different
652      *                        orientations.
653      * @param initialHardIron initial hard-iron to find a solution.
654      * @param listener        listener to handle events raised by this calibrator.
655      * @throws IllegalArgumentException if provided hard-iron matrix is not
656      *                                  3x1.
657      */
658     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
659             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
660             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
661         this(measurements, initialHardIron);
662         this.listener = listener;
663     }
664 
665     /**
666      * Constructor.
667      *
668      * @param measurements    collection of body magnetic flux density
669      *                        measurements with standard deviation of
670      *                        magnetometer measurements taken at the same
671      *                        position with zero velocity and unknown different
672      *                        orientations.
673      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
674      *                        for the accelerometer, gyroscope and magnetometer.
675      * @param initialHardIron initial hard-iron to find a solution.
676      * @throws IllegalArgumentException if provided hard-iron matrix is not
677      *                                  3x1.
678      */
679     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
680             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
681             final Matrix initialHardIron) {
682         this(measurements, initialHardIron);
683         this.commonAxisUsed = commonAxisUsed;
684     }
685 
686     /**
687      * Constructor.
688      *
689      * @param measurements    collection of body magnetic flux density
690      *                        measurements with standard deviation of
691      *                        magnetometer measurements taken at the same
692      *                        position with zero velocity and unknown different
693      *                        orientations.
694      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
695      *                        for the accelerometer, gyroscope and magnetometer.
696      * @param initialHardIron initial hard-iron to find a solution.
697      * @param listener        listener to handle events raised by this calibrator.
698      * @throws IllegalArgumentException if provided hard-iron matrix is not
699      *                                  3x1.
700      */
701     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
702             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
703             final Matrix initialHardIron,
704             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
705         this(measurements, commonAxisUsed, initialHardIron);
706         this.listener = listener;
707     }
708 
709     /**
710      * Constructor.
711      *
712      * @param measurements    collection of body magnetic flux density
713      *                        measurements with standard deviation of
714      *                        magnetometer measurements taken at the same
715      *                        position with zero velocity and unknown different
716      *                        orientations.
717      * @param initialHardIron initial hard-iron to find a solution.
718      * @param initialMm       initial soft-iron matrix containing scale factors
719      *                        and cross coupling errors.
720      * @throws IllegalArgumentException if provided hard-iron matrix is not
721      *                                  3x1 or if soft-iron matrix is not
722      *                                  3x3.
723      */
724     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
725             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
726             final Matrix initialMm) {
727         this(initialHardIron, initialMm);
728         this.measurements = measurements;
729     }
730 
731     /**
732      * Constructor.
733      *
734      * @param measurements    collection of body magnetic flux density
735      *                        measurements with standard deviation of
736      *                        magnetometer measurements taken at the same
737      *                        position with zero velocity and unknown different
738      *                        orientations.
739      * @param initialHardIron initial hard-iron to find a solution.
740      * @param initialMm       initial soft-iron matrix containing scale factors
741      *                        and cross coupling errors.
742      * @param listener        listener to handle events raised by this calibrator.
743      * @throws IllegalArgumentException if provided hard-iron matrix is not
744      *                                  3x1 or if soft-iron matrix is not
745      *                                  3x3.
746      */
747     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
748             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
749             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
750         this(measurements, initialHardIron, initialMm);
751         this.listener = listener;
752     }
753 
754     /**
755      * Constructor.
756      *
757      * @param measurements    collection of body magnetic flux density
758      *                        measurements with standard deviation of
759      *                        magnetometer measurements taken at the same
760      *                        position with zero velocity and unknown different
761      *                        orientations.
762      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
763      *                        for the accelerometer, gyroscope and magnetometer.
764      * @param initialHardIron initial hard-iron to find a solution.
765      * @param initialMm       initial soft-iron matrix containing scale factors
766      *                        and cross coupling errors.
767      * @throws IllegalArgumentException if provided hard-iron matrix is not
768      *                                  3x1 or if soft-iron matrix is not
769      *                                  3x3.
770      */
771     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
772             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
773             final Matrix initialHardIron, final Matrix initialMm) {
774         this(measurements, initialHardIron, initialMm);
775         this.commonAxisUsed = commonAxisUsed;
776     }
777 
778     /**
779      * Constructor.
780      *
781      * @param measurements    collection of body magnetic flux density
782      *                        measurements with standard deviation of
783      *                        magnetometer measurements taken at the same
784      *                        position with zero velocity and unknown different
785      *                        orientations.
786      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
787      *                        for the accelerometer, gyroscope and magnetometer.
788      * @param initialHardIron initial hard-iron to find a solution.
789      * @param initialMm       initial soft-iron matrix containing scale factors
790      *                        and cross coupling errors.
791      * @param listener        listener to handle events raised by this calibrator.
792      * @throws IllegalArgumentException if provided hard-iron matrix is not
793      *                                  3x1 or if soft-iron matrix is not
794      *                                  3x3.
795      */
796     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
797             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
798             final Matrix initialHardIron, final Matrix initialMm,
799             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
800         this(measurements, commonAxisUsed, initialHardIron, initialMm);
801         this.listener = listener;
802     }
803 
804     /**
805      * Constructor.
806      *
807      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
808      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
809      */
810     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
811             final Double groundTruthMagneticFluxDensityNorm) {
812         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
813     }
814 
815     /**
816      * Constructor.
817      *
818      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
819      * @param listener                           listener to handle events raised by this calibrator.
820      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
821      */
822     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
823             final Double groundTruthMagneticFluxDensityNorm,
824             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
825         this(groundTruthMagneticFluxDensityNorm);
826         this.listener = listener;
827     }
828 
829     /**
830      * Constructor.
831      *
832      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
833      * @param measurements                       collection of body magnetic flux density
834      *                                           measurements with standard deviation of
835      *                                           magnetometer measurements taken at the same
836      *                                           position with zero velocity and unknown different
837      *                                           orientations.
838      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
839      */
840     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
841             final Double groundTruthMagneticFluxDensityNorm,
842             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
843         this(groundTruthMagneticFluxDensityNorm);
844         this.measurements = measurements;
845     }
846 
847     /**
848      * Constructor.
849      *
850      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
851      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
852      *                                           for the accelerometer, gyroscope and magnetometer.
853      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
854      */
855     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
856             final Double groundTruthMagneticFluxDensityNorm, final boolean commonAxisUsed) {
857         this(groundTruthMagneticFluxDensityNorm);
858         this.commonAxisUsed = commonAxisUsed;
859     }
860 
861     /**
862      * Constructor.
863      *
864      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
865      * @param initialHardIron                    initial hard-iron to find a solution.
866      * @throws IllegalArgumentException if provided magnetic flux norm value is
867      *                                  negative, or if provided hard-iron array does
868      *                                  not have length 3.
869      */
870     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
871             final Double groundTruthMagneticFluxDensityNorm, final double[] initialHardIron) {
872         this(initialHardIron);
873         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
874     }
875 
876     /**
877      * Constructor.
878      *
879      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
880      * @param initialHardIron                    initial hard-iron to find a solution.
881      * @throws IllegalArgumentException if provided magnetic flux norm value is
882      *                                  negative, or if provided hard-iron matrix is not
883      *                                  3x1.
884      */
885     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
886             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron) {
887         this(initialHardIron);
888         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
889     }
890 
891     /**
892      * Constructor.
893      *
894      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
895      * @param initialHardIron                    initial hard-iron to find a solution.
896      * @param initialMm                          initial soft-iron matrix containing scale factors
897      *                                           and cross coupling errors.
898      * @throws IllegalArgumentException if provided magnetic flux norm value is
899      *                                  negative, or if provided hard-iron matrix is not
900      *                                  3x1 or if soft-iron matrix is not
901      *                                  3x3.
902      */
903     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
904             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron, final Matrix initialMm) {
905         this(initialHardIron, initialMm);
906         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
907     }
908 
909     /**
910      * Constructor.
911      *
912      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
913      * @param measurements                       collection of body magnetic flux density
914      *                                           measurements with standard deviation of
915      *                                           magnetometer measurements taken at the same
916      *                                           position with zero velocity and unknown different
917      *                                           orientations.
918      * @param listener                           listener to handle events raised by this calibrator.
919      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
920      */
921     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
922             final Double groundTruthMagneticFluxDensityNorm,
923             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
924             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
925         this(groundTruthMagneticFluxDensityNorm, measurements);
926         this.listener = listener;
927     }
928 
929     /**
930      * Constructor.
931      *
932      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
933      * @param measurements                       collection of body magnetic flux density
934      *                                           measurements with standard deviation of
935      *                                           magnetometer measurements taken at the same
936      *                                           position with zero velocity and unknown different
937      *                                           orientations.
938      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
939      *                                           for the accelerometer, gyroscope and magnetometer.
940      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
941      */
942     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
943             final Double groundTruthMagneticFluxDensityNorm,
944             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
945         this(groundTruthMagneticFluxDensityNorm, measurements);
946         this.commonAxisUsed = commonAxisUsed;
947     }
948 
949     /**
950      * Constructor.
951      *
952      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
953      * @param measurements                       collection of body magnetic flux density
954      *                                           measurements with standard deviation of
955      *                                           magnetometer measurements taken at the same
956      *                                           position with zero velocity and unknown different
957      *                                           orientations.
958      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
959      *                                           for the accelerometer, gyroscope and magnetometer.
960      * @param listener                           listener to handle events raised by this calibrator.
961      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
962      */
963     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
964             final Double groundTruthMagneticFluxDensityNorm,
965             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
966             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
967         this(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
968         this.listener = listener;
969     }
970 
971     /**
972      * Constructor.
973      *
974      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
975      * @param measurements                       collection of body magnetic flux density
976      *                                           measurements with standard deviation of
977      *                                           magnetometer measurements taken at the same
978      *                                           position with zero velocity and unknown different
979      *                                           orientations.
980      * @param initialHardIron                    initial hard-iron to find a solution.
981      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
982      *                                  or if provided hard-iron array does not have length 3.
983      */
984     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
985             final Double groundTruthMagneticFluxDensityNorm,
986             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron) {
987         this(measurements, initialHardIron);
988         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
989     }
990 
991     /**
992      * Constructor.
993      *
994      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
995      * @param measurements                       collection of body magnetic flux density
996      *                                           measurements with standard deviation of
997      *                                           magnetometer measurements taken at the same
998      *                                           position with zero velocity and unknown different
999      *                                           orientations.
1000      * @param initialHardIron                    initial hard-iron to find a solution.
1001      * @param listener                           listener to handle events raised by this calibrator.
1002      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1003      *                                  or if provided hard-iron array does not have length 3.
1004      */
1005     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1006             final Double groundTruthMagneticFluxDensityNorm,
1007             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
1008             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1009         this(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
1010         this.listener = listener;
1011     }
1012 
1013     /**
1014      * Constructor.
1015      *
1016      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1017      * @param measurements                       collection of body magnetic flux density
1018      *                                           measurements with standard deviation of
1019      *                                           magnetometer measurements taken at the same
1020      *                                           position with zero velocity and unknown different
1021      *                                           orientations.
1022      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1023      *                                           for the accelerometer, gyroscope and magnetometer.
1024      * @param initialHardIron                    initial hard-iron to find a solution.
1025      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1026      *                                  or if provided hard-iron array does not have length 3.
1027      */
1028     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1029             final Double groundTruthMagneticFluxDensityNorm,
1030             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1031             final double[] initialHardIron) {
1032         this(measurements, commonAxisUsed, initialHardIron);
1033         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1034     }
1035 
1036     /**
1037      * Constructor.
1038      *
1039      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1040      * @param measurements                       collection of body magnetic flux density
1041      *                                           measurements with standard deviation of
1042      *                                           magnetometer measurements taken at the same
1043      *                                           position with zero velocity and unknown different
1044      *                                           orientations.
1045      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1046      *                                           for the accelerometer, gyroscope and magnetometer.
1047      * @param initialHardIron                    initial hard-iron to find a solution.
1048      * @param listener                           listener to handle events raised by this calibrator.
1049      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1050      *                                  or if provided hard-iron array does not have length 3.
1051      */
1052     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1053             final Double groundTruthMagneticFluxDensityNorm,
1054             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1055             final double[] initialHardIron,
1056             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1057         this(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
1058         this.listener = listener;
1059     }
1060 
1061     /**
1062      * Constructor.
1063      *
1064      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1065      * @param measurements                       collection of body magnetic flux density
1066      *                                           measurements with standard deviation of
1067      *                                           magnetometer measurements taken at the same
1068      *                                           position with zero velocity and unknown different
1069      *                                           orientations.
1070      * @param initialHardIron                    initial hard-iron to find a solution.
1071      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1072      *                                  or if provided hard-iron matrix is not 3x1.
1073      */
1074     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1075             final Double groundTruthMagneticFluxDensityNorm,
1076             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron) {
1077         this(measurements, initialHardIron);
1078         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1079     }
1080 
1081     /**
1082      * Constructor.
1083      *
1084      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1085      * @param measurements                       collection of body magnetic flux density
1086      *                                           measurements with standard deviation of
1087      *                                           magnetometer measurements taken at the same
1088      *                                           position with zero velocity and unknown different
1089      *                                           orientations.
1090      * @param initialHardIron                    initial hard-iron to find a solution.
1091      * @param listener                           listener to handle events raised by this calibrator.
1092      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1093      *                                  or if provided hard-iron matrix is not 3x1.
1094      */
1095     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1096             final Double groundTruthMagneticFluxDensityNorm,
1097             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
1098             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1099         this(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
1100         this.listener = listener;
1101     }
1102 
1103     /**
1104      * Constructor.
1105      *
1106      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1107      * @param measurements                       collection of body magnetic flux density
1108      *                                           measurements with standard deviation of
1109      *                                           magnetometer measurements taken at the same
1110      *                                           position with zero velocity and unknown different
1111      *                                           orientations.
1112      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1113      *                                           for the accelerometer, gyroscope and magnetometer.
1114      * @param initialHardIron                    initial hard-iron to find a solution.
1115      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1116      *                                  or if provided hard-iron matrix is not 3x1.
1117      */
1118     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1119             final Double groundTruthMagneticFluxDensityNorm,
1120             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1121             final Matrix initialHardIron) {
1122         this(measurements, commonAxisUsed, initialHardIron);
1123         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1124     }
1125 
1126     /**
1127      * Constructor.
1128      *
1129      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1130      * @param measurements                       collection of body magnetic flux density
1131      *                                           measurements with standard deviation of
1132      *                                           magnetometer measurements taken at the same
1133      *                                           position with zero velocity and unknown different
1134      *                                           orientations.
1135      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1136      *                                           for the accelerometer, gyroscope and magnetometer.
1137      * @param initialHardIron                    initial hard-iron to find a solution.
1138      * @param listener                           listener to handle events raised by this calibrator.
1139      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1140      *                                  or if provided hard-iron matrix is not 3x1.
1141      */
1142     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1143             final Double groundTruthMagneticFluxDensityNorm,
1144             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1145             final Matrix initialHardIron,
1146             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1147         this(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
1148         this.listener = listener;
1149     }
1150 
1151     /**
1152      * Constructor.
1153      *
1154      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1155      * @param measurements                       collection of body magnetic flux density
1156      *                                           measurements with standard deviation of
1157      *                                           magnetometer measurements taken at the same
1158      *                                           position with zero velocity and unknown different
1159      *                                           orientations.
1160      * @param initialHardIron                    initial hard-iron to find a solution.
1161      * @param initialMm                          initial soft-iron matrix containing scale factors
1162      *                                           and cross coupling errors.
1163      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1164      *                                  or if provided hard-iron matrix is not 3x1 or if
1165      *                                  soft-iron matrix is not 3x3.
1166      */
1167     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1168             final Double groundTruthMagneticFluxDensityNorm,
1169             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
1170             final Matrix initialMm) {
1171         this(measurements, initialHardIron, initialMm);
1172         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1173     }
1174 
1175     /**
1176      * Constructor.
1177      *
1178      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1179      * @param measurements                       collection of body magnetic flux density
1180      *                                           measurements with standard deviation of
1181      *                                           magnetometer measurements taken at the same
1182      *                                           position with zero velocity and unknown different
1183      *                                           orientations.
1184      * @param initialHardIron                    initial hard-iron to find a solution.
1185      * @param initialMm                          initial soft-iron matrix containing scale factors
1186      *                                           and cross coupling errors.
1187      * @param listener                           listener to handle events raised by this calibrator.
1188      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1189      *                                  or if provided hard-iron matrix is not 3x1 or if
1190      *                                  soft-iron matrix is not 3x3.
1191      */
1192     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1193             final Double groundTruthMagneticFluxDensityNorm,
1194             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
1195             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1196         this(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
1197         this.listener = listener;
1198     }
1199 
1200     /**
1201      * Constructor.
1202      *
1203      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1204      * @param measurements                       collection of body magnetic flux density
1205      *                                           measurements with standard deviation of
1206      *                                           magnetometer measurements taken at the same
1207      *                                           position with zero velocity and unknown different
1208      *                                           orientations.
1209      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1210      *                                           for the accelerometer, gyroscope and magnetometer.
1211      * @param initialHardIron                    initial hard-iron to find a solution.
1212      * @param initialMm                          initial soft-iron matrix containing scale factors
1213      *                                           and cross coupling errors.
1214      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1215      *                                  or if provided hard-iron matrix is not 3x1
1216      *                                  or if soft-iron matrix is not 3x3.
1217      */
1218     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1219             final Double groundTruthMagneticFluxDensityNorm,
1220             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1221             final Matrix initialHardIron, final Matrix initialMm) {
1222         this(measurements, commonAxisUsed, initialHardIron, initialMm);
1223         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1224     }
1225 
1226     /**
1227      * Constructor.
1228      *
1229      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1230      * @param measurements                       collection of body magnetic flux density
1231      *                                           measurements with standard deviation of
1232      *                                           magnetometer measurements taken at the same
1233      *                                           position with zero velocity and unknown different
1234      *                                           orientations.
1235      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1236      *                                           for the accelerometer, gyroscope and magnetometer.
1237      * @param initialHardIron                    initial hard-iron to find a solution.
1238      * @param initialMm                          initial soft-iron matrix containing scale factors
1239      *                                           and cross coupling errors.
1240      * @param listener                           listener to handle events raised by this calibrator.
1241      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1242      *                                  or if provided hard-iron matrix is not 3x1
1243      *                                  or if soft-iron matrix is not 3x3.
1244      */
1245     protected RobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
1246             final Double groundTruthMagneticFluxDensityNorm,
1247             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1248             final Matrix initialHardIron, final Matrix initialMm,
1249             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1250         this(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
1251         this.listener = listener;
1252     }
1253 
1254     /**
1255      * Gets ground truth magnetic flux density norm to be expected at location where measurements have been made,
1256      * expressed in Teslas (T).
1257      *
1258      * @return ground truth magnetic flux density or null.
1259      */
1260     public Double getGroundTruthMagneticFluxDensityNorm() {
1261         return groundTruthMagneticFluxDensityNorm;
1262     }
1263 
1264     /**
1265      * Gets ground truth magnetic flux density norm to be expected at location where measurements have been made.
1266      *
1267      * @return ground truth magnetic flux density or null.
1268      */
1269     public MagneticFluxDensity getGroundTruthMagneticFluxDensityNormAsMagneticFluxDensity() {
1270         return groundTruthMagneticFluxDensityNorm != null
1271                 ? new MagneticFluxDensity(groundTruthMagneticFluxDensityNorm, MagneticFluxDensityUnit.TESLA) : null;
1272     }
1273 
1274     /**
1275      * Gets ground truth magnetic flux density norm to be expected at location where measurements have been made.
1276      *
1277      * @param result instance where result will be stored.
1278      * @return true if ground truth magnetic flux density norm has been defined, false if it is not available yet.
1279      */
1280     public boolean getGroundTruthMagneticFluxDensityNormAsMagneticFluxDensity(final MagneticFluxDensity result) {
1281         if (groundTruthMagneticFluxDensityNorm != null) {
1282             result.setValue(groundTruthMagneticFluxDensityNorm);
1283             result.setUnit(MagneticFluxDensityUnit.TESLA);
1284             return true;
1285         } else {
1286             return false;
1287         }
1288     }
1289 
1290     /**
1291      * Sets ground truth magnetic flux density norm to be expected at location where
1292      * measurements have been made, expressed in Teslas (T).
1293      *
1294      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm or null if undefined.
1295      * @throws IllegalArgumentException if provided value is negative.
1296      * @throws LockedException          if calibrator is currently running.
1297      */
1298     public void setGroundTruthMagneticFluxDensityNorm(final Double groundTruthMagneticFluxDensityNorm)
1299             throws LockedException {
1300         if (isRunning()) {
1301             throw new LockedException();
1302         }
1303 
1304         internalSetGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
1305     }
1306 
1307     /**
1308      * Sets ground truth magnetic flux density norm to be expected at location where
1309      * measurements have been made.
1310      *
1311      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm or null if undefined.
1312      * @throws IllegalArgumentException if provided value is negative.
1313      * @throws LockedException          if calibrator is currently running.
1314      */
1315     public void setGroundTruthMagneticFluxDensityNorm(final MagneticFluxDensity groundTruthMagneticFluxDensityNorm)
1316             throws LockedException {
1317         if (isRunning()) {
1318             throw new LockedException();
1319         }
1320         if (groundTruthMagneticFluxDensityNorm != null) {
1321             internalSetGroundTruthMagneticFluxDensityNorm(MagneticFluxDensityConverter.convert(
1322                     groundTruthMagneticFluxDensityNorm.getValue().doubleValue(),
1323                     groundTruthMagneticFluxDensityNorm.getUnit(), MagneticFluxDensityUnit.TESLA));
1324         } else {
1325             internalSetGroundTruthMagneticFluxDensityNorm(null);
1326         }
1327     }
1328 
1329     /**
1330      * Gets initial x-coordinate of magnetometer hard-iron bias to be used
1331      * to find a solution.
1332      * This is expressed in Teslas (T).
1333      *
1334      * @return initial x-coordinate of magnetometer hard-iron bias.
1335      */
1336     @Override
1337     public double getInitialHardIronX() {
1338         return initialHardIronX;
1339     }
1340 
1341     /**
1342      * Sets initial x-coordinate of magnetometer hard-iron bias to be used
1343      * to find a solution.
1344      * This is expressed in Teslas (T).
1345      *
1346      * @param initialHardIronX initial x-coordinate of magnetometer
1347      *                         hard-iron bias.
1348      * @throws LockedException if calibrator is currently running.
1349      */
1350     @Override
1351     public void setInitialHardIronX(final double initialHardIronX) throws LockedException {
1352         if (running) {
1353             throw new LockedException();
1354         }
1355         this.initialHardIronX = initialHardIronX;
1356     }
1357 
1358     /**
1359      * Gets initial y-coordinate of magnetometer hard-iron bias to be used
1360      * to find a solution.
1361      * This is expressed in Teslas (T).
1362      *
1363      * @return initial y-coordinate of magnetometer hard-iron bias.
1364      */
1365     @Override
1366     public double getInitialHardIronY() {
1367         return initialHardIronY;
1368     }
1369 
1370     /**
1371      * Sets initial y-coordinate of magnetometer hard-iron bias to be used
1372      * to find a solution.
1373      * This is expressed in Teslas (T).
1374      *
1375      * @param initialHardIronY initial y-coordinate of magnetometer
1376      *                         hard-iron bias.
1377      * @throws LockedException if calibrator is currently running.
1378      */
1379     @Override
1380     public void setInitialHardIronY(final double initialHardIronY) throws LockedException {
1381         if (running) {
1382             throw new LockedException();
1383         }
1384         this.initialHardIronY = initialHardIronY;
1385     }
1386 
1387     /**
1388      * Gets initial z-coordinate of magnetometer hard-iron bias to be used
1389      * to find a solution.
1390      * This is expressed in Teslas (T).
1391      *
1392      * @return initial z-coordinate of magnetometer hard-iron bias.
1393      */
1394     @Override
1395     public double getInitialHardIronZ() {
1396         return initialHardIronZ;
1397     }
1398 
1399     /**
1400      * Sets initial z-coordinate of magnetometer hard-iron bias to be used
1401      * to find a solution.
1402      * This is expressed in meters Teslas (T).
1403      *
1404      * @param initialHardIronZ initial z-coordinate of magnetometer
1405      *                         hard-iron bias.
1406      * @throws LockedException if calibrator is currently running.
1407      */
1408     @Override
1409     public void setInitialHardIronZ(final double initialHardIronZ) throws LockedException {
1410         if (running) {
1411             throw new LockedException();
1412         }
1413         this.initialHardIronZ = initialHardIronZ;
1414     }
1415 
1416     /**
1417      * Gets initial x-coordinate of magnetometer hard iron bias to be used
1418      * to find a solution.
1419      *
1420      * @return initial x-coordinate of magnetometer hard-iron bias.
1421      */
1422     @Override
1423     public MagneticFluxDensity getInitialHardIronXAsMagneticFluxDensity() {
1424         return new MagneticFluxDensity(initialHardIronX, MagneticFluxDensityUnit.TESLA);
1425     }
1426 
1427     /**
1428      * Gets initial x-coordinate of magnetometer hard iron bias to be used
1429      * to find a solution.
1430      *
1431      * @param result instance where result will be stored.
1432      */
1433     @Override
1434     public void getInitialHardIronXAsMagneticFluxDensity(final MagneticFluxDensity result) {
1435         result.setValue(initialHardIronX);
1436         result.setUnit(MagneticFluxDensityUnit.TESLA);
1437     }
1438 
1439     /**
1440      * Sets initial x-coordinate of magnetometer hard iron bias to be used
1441      * to find a solution.
1442      *
1443      * @param initialHardIronX initial x-coordinate of magnetometer bias.
1444      * @throws LockedException if calibrator is currently running.
1445      */
1446     @Override
1447     public void setInitialHardIronX(final MagneticFluxDensity initialHardIronX) throws LockedException {
1448         if (running) {
1449             throw new LockedException();
1450         }
1451         this.initialHardIronX = convertMagneticFluxDensity(initialHardIronX);
1452     }
1453 
1454     /**
1455      * Gets initial y-coordinate of magnetometer hard iron bias to be used
1456      * to find a solution.
1457      *
1458      * @return initial y-coordinate of magnetometer hard-iron bias.
1459      */
1460     @Override
1461     public MagneticFluxDensity getInitialHardIronYAsMagneticFluxDensity() {
1462         return new MagneticFluxDensity(initialHardIronY, MagneticFluxDensityUnit.TESLA);
1463     }
1464 
1465     /**
1466      * Gets initial y-coordinate of magnetometer hard iron bias to be used
1467      * to find a solution.
1468      *
1469      * @param result instance where result will be stored.
1470      */
1471     @Override
1472     public void getInitialHardIronYAsMagneticFluxDensity(final MagneticFluxDensity result) {
1473         result.setValue(initialHardIronY);
1474         result.setUnit(MagneticFluxDensityUnit.TESLA);
1475     }
1476 
1477     /**
1478      * Sets initial y-coordinate of magnetometer hard iron bias to be used
1479      * to find a solution.
1480      *
1481      * @param initialHardIronY initial y-coordinate of magnetometer bias.
1482      * @throws LockedException if calibrator is currently running.
1483      */
1484     @Override
1485     public void setInitialHardIronY(final MagneticFluxDensity initialHardIronY) throws LockedException {
1486         if (running) {
1487             throw new LockedException();
1488         }
1489         this.initialHardIronY = convertMagneticFluxDensity(initialHardIronY);
1490     }
1491 
1492     /**
1493      * Gets initial z-coordinate of magnetometer hard iron bias to be used
1494      * to find a solution.
1495      *
1496      * @return initial z-coordinate of magnetometer hard-iron bias.
1497      */
1498     @Override
1499     public MagneticFluxDensity getInitialHardIronZAsMagneticFluxDensity() {
1500         return new MagneticFluxDensity(initialHardIronZ, MagneticFluxDensityUnit.TESLA);
1501     }
1502 
1503     /**
1504      * Gets initial z-coordinate of magnetometer hard iron bias to be used
1505      * to find a solution.
1506      *
1507      * @param result instance where result will be stored.
1508      */
1509     @Override
1510     public void getInitialHardIronZAsMagneticFluxDensity(final MagneticFluxDensity result) {
1511         result.setValue(initialHardIronZ);
1512         result.setUnit(MagneticFluxDensityUnit.TESLA);
1513     }
1514 
1515     /**
1516      * Sets initial z-coordinate of magnetometer hard iron bias to be used
1517      * to find a solution.
1518      *
1519      * @param initialHardIronZ initial z-coordinate of magnetometer bias.
1520      * @throws LockedException if calibrator is currently running.
1521      */
1522     @Override
1523     public void setInitialHardIronZ(final MagneticFluxDensity initialHardIronZ) throws LockedException {
1524         if (running) {
1525             throw new LockedException();
1526         }
1527         this.initialHardIronZ = convertMagneticFluxDensity(initialHardIronZ);
1528     }
1529 
1530     /**
1531      * Sets initial hard-iron bias coordinates of magnetometer used to find
1532      * a solution expressed in Teslas (T).
1533      *
1534      * @param initialHardIronX initial x-coordinate of magnetometer
1535      *                         hard-iron bias.
1536      * @param initialHardIronY initial y-coordinate of magnetometer
1537      *                         hard-iron bias.
1538      * @param initialHardIronZ initial z-coordinate of magnetometer
1539      *                         hard-iron bias.
1540      * @throws LockedException if calibrator is currently running.
1541      */
1542     @Override
1543     public void setInitialHardIron(
1544             final double initialHardIronX, final double initialHardIronY, final double initialHardIronZ)
1545             throws LockedException {
1546         if (running) {
1547             throw new LockedException();
1548         }
1549         this.initialHardIronX = initialHardIronX;
1550         this.initialHardIronY = initialHardIronY;
1551         this.initialHardIronZ = initialHardIronZ;
1552     }
1553 
1554     /**
1555      * Sets initial hard iron coordinates of magnetometer used to find a solution.
1556      *
1557      * @param initialHardIronX initial x-coordinate of magnetometer bias.
1558      * @param initialHardIronY initial y-coordinate of magnetometer bias.
1559      * @param initialHardIronZ initial z-coordinate of magnetometer bias.
1560      * @throws LockedException if calibrator is currently running.
1561      */
1562     @Override
1563     public void setInitialHardIron(
1564             final MagneticFluxDensity initialHardIronX, final MagneticFluxDensity initialHardIronY,
1565             final MagneticFluxDensity initialHardIronZ) throws LockedException {
1566         if (running) {
1567             throw new LockedException();
1568         }
1569 
1570         this.initialHardIronX = convertMagneticFluxDensity(initialHardIronX);
1571         this.initialHardIronY = convertMagneticFluxDensity(initialHardIronY);
1572         this.initialHardIronZ = convertMagneticFluxDensity(initialHardIronZ);
1573     }
1574 
1575     /**
1576      * Gets initial hard-iron used to find a solution.
1577      *
1578      * @return initial hard-iron.
1579      */
1580     @Override
1581     public MagneticFluxDensityTriad getInitialHardIronAsTriad() {
1582         return new MagneticFluxDensityTriad(MagneticFluxDensityUnit.TESLA,
1583                 initialHardIronX, initialHardIronY, initialHardIronZ);
1584     }
1585 
1586     /**
1587      * Gets initial hard-iron used to find a solution.
1588      *
1589      * @param result instance where result will be stored.
1590      */
1591     @Override
1592     public void getInitialHardIronAsTriad(final MagneticFluxDensityTriad result) {
1593         result.setValueCoordinatesAndUnit(initialHardIronX, initialHardIronY, initialHardIronZ,
1594                 MagneticFluxDensityUnit.TESLA);
1595     }
1596 
1597     /**
1598      * Sets initial hard-iron used to find a solution.
1599      *
1600      * @param initialHardIron initial hard-iron to be set.
1601      * @throws LockedException if calibrator is currently running.
1602      */
1603     @Override
1604     public void setInitialHardIron(final MagneticFluxDensityTriad initialHardIron) throws LockedException {
1605         if (running) {
1606             throw new LockedException();
1607         }
1608 
1609         initialHardIronX = convertMagneticFluxDensity(initialHardIron.getValueX(), initialHardIron.getUnit());
1610         initialHardIronY = convertMagneticFluxDensity(initialHardIron.getValueY(), initialHardIron.getUnit());
1611         initialHardIronZ = convertMagneticFluxDensity(initialHardIron.getValueZ(), initialHardIron.getUnit());
1612     }
1613 
1614     /**
1615      * Gets initial x scaling factor.
1616      *
1617      * @return initial x scaling factor.
1618      */
1619     @Override
1620     public double getInitialSx() {
1621         return initialSx;
1622     }
1623 
1624     /**
1625      * Sets initial x scaling factor.
1626      *
1627      * @param initialSx initial x scaling factor.
1628      * @throws LockedException if calibrator is currently running.
1629      */
1630     @Override
1631     public void setInitialSx(final double initialSx) throws LockedException {
1632         if (running) {
1633             throw new LockedException();
1634         }
1635         this.initialSx = initialSx;
1636     }
1637 
1638     /**
1639      * Gets initial y scaling factor.
1640      *
1641      * @return initial y scaling factor.
1642      */
1643     @Override
1644     public double getInitialSy() {
1645         return initialSy;
1646     }
1647 
1648     /**
1649      * Sets initial y scaling factor.
1650      *
1651      * @param initialSy initial y scaling factor.
1652      * @throws LockedException if calibrator is currently running.
1653      */
1654     @Override
1655     public void setInitialSy(final double initialSy) throws LockedException {
1656         if (running) {
1657             throw new LockedException();
1658         }
1659         this.initialSy = initialSy;
1660     }
1661 
1662     /**
1663      * Gets initial z scaling factor.
1664      *
1665      * @return initial z scaling factor.
1666      */
1667     @Override
1668     public double getInitialSz() {
1669         return initialSz;
1670     }
1671 
1672     /**
1673      * Sets initial z scaling factor.
1674      *
1675      * @param initialSz initial z scaling factor.
1676      * @throws LockedException if calibrator is currently running.
1677      */
1678     @Override
1679     public void setInitialSz(final double initialSz) throws LockedException {
1680         if (running) {
1681             throw new LockedException();
1682         }
1683         this.initialSz = initialSz;
1684     }
1685 
1686     /**
1687      * Gets initial x-y cross coupling error.
1688      *
1689      * @return initial x-y cross coupling error.
1690      */
1691     @Override
1692     public double getInitialMxy() {
1693         return initialMxy;
1694     }
1695 
1696     /**
1697      * Sets initial x-y cross coupling error.
1698      *
1699      * @param initialMxy initial x-y cross coupling error.
1700      * @throws LockedException if calibrator is currently running.
1701      */
1702     @Override
1703     public void setInitialMxy(final double initialMxy) throws LockedException {
1704         if (running) {
1705             throw new LockedException();
1706         }
1707         this.initialMxy = initialMxy;
1708     }
1709 
1710     /**
1711      * Gets initial x-z cross coupling error.
1712      *
1713      * @return initial x-z cross coupling error.
1714      */
1715     @Override
1716     public double getInitialMxz() {
1717         return initialMxz;
1718     }
1719 
1720     /**
1721      * Sets initial x-z cross coupling error.
1722      *
1723      * @param initialMxz initial x-z cross coupling error.
1724      * @throws LockedException if calibrator is currently running.
1725      */
1726     @Override
1727     public void setInitialMxz(final double initialMxz) throws LockedException {
1728         if (running) {
1729             throw new LockedException();
1730         }
1731         this.initialMxz = initialMxz;
1732     }
1733 
1734     /**
1735      * Gets initial y-x cross coupling error.
1736      *
1737      * @return initial y-x cross coupling error.
1738      */
1739     @Override
1740     public double getInitialMyx() {
1741         return initialMyx;
1742     }
1743 
1744     /**
1745      * Sets initial y-x cross coupling error.
1746      *
1747      * @param initialMyx initial y-x cross coupling error.
1748      * @throws LockedException if calibrator is currently running.
1749      */
1750     @Override
1751     public void setInitialMyx(final double initialMyx) throws LockedException {
1752         if (running) {
1753             throw new LockedException();
1754         }
1755         this.initialMyx = initialMyx;
1756     }
1757 
1758     /**
1759      * Gets initial y-z cross coupling error.
1760      *
1761      * @return initial y-z cross coupling error.
1762      */
1763     @Override
1764     public double getInitialMyz() {
1765         return initialMyz;
1766     }
1767 
1768     /**
1769      * Sets initial y-z cross coupling error.
1770      *
1771      * @param initialMyz initial y-z cross coupling error.
1772      * @throws LockedException if calibrator is currently running.
1773      */
1774     @Override
1775     public void setInitialMyz(final double initialMyz) throws LockedException {
1776         if (running) {
1777             throw new LockedException();
1778         }
1779         this.initialMyz = initialMyz;
1780     }
1781 
1782     /**
1783      * Gets initial z-x cross coupling error.
1784      *
1785      * @return initial z-x cross coupling error.
1786      */
1787     @Override
1788     public double getInitialMzx() {
1789         return initialMzx;
1790     }
1791 
1792     /**
1793      * Sets initial z-x cross coupling error.
1794      *
1795      * @param initialMzx initial z-x cross coupling error.
1796      * @throws LockedException if calibrator is currently running.
1797      */
1798     @Override
1799     public void setInitialMzx(final double initialMzx) throws LockedException {
1800         if (running) {
1801             throw new LockedException();
1802         }
1803         this.initialMzx = initialMzx;
1804     }
1805 
1806     /**
1807      * Gets initial z-y cross coupling error.
1808      *
1809      * @return initial z-y cross coupling error.
1810      */
1811     @Override
1812     public double getInitialMzy() {
1813         return initialMzy;
1814     }
1815 
1816     /**
1817      * Sets initial z-y cross coupling error.
1818      *
1819      * @param initialMzy initial z-y cross coupling error.
1820      * @throws LockedException if calibrator is currently running.
1821      */
1822     @Override
1823     public void setInitialMzy(final double initialMzy) throws LockedException {
1824         if (running) {
1825             throw new LockedException();
1826         }
1827         this.initialMzy = initialMzy;
1828     }
1829 
1830     /**
1831      * Sets initial scaling factors.
1832      *
1833      * @param initialSx initial x scaling factor.
1834      * @param initialSy initial y scaling factor.
1835      * @param initialSz initial z scaling factor.
1836      * @throws LockedException if calibrator is currently running.
1837      */
1838     @Override
1839     public void setInitialScalingFactors(final double initialSx, final double initialSy, final double initialSz)
1840             throws LockedException {
1841         if (running) {
1842             throw new LockedException();
1843         }
1844         this.initialSx = initialSx;
1845         this.initialSy = initialSy;
1846         this.initialSz = initialSz;
1847     }
1848 
1849     /**
1850      * Sets initial cross coupling errors.
1851      *
1852      * @param initialMxy initial x-y cross coupling error.
1853      * @param initialMxz initial x-z cross coupling error.
1854      * @param initialMyx initial y-x cross coupling error.
1855      * @param initialMyz initial y-z cross coupling error.
1856      * @param initialMzx initial z-x cross coupling error.
1857      * @param initialMzy initial z-y cross coupling error.
1858      * @throws LockedException if calibrator is currently running.
1859      */
1860     @Override
1861     public void setInitialCrossCouplingErrors(
1862             final double initialMxy, final double initialMxz, final double initialMyx,
1863             final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
1864         if (running) {
1865             throw new LockedException();
1866         }
1867         this.initialMxy = initialMxy;
1868         this.initialMxz = initialMxz;
1869         this.initialMyx = initialMyx;
1870         this.initialMyz = initialMyz;
1871         this.initialMzx = initialMzx;
1872         this.initialMzy = initialMzy;
1873     }
1874 
1875     /**
1876      * Sets initial scaling factors and cross coupling errors.
1877      *
1878      * @param initialSx  initial x scaling factor.
1879      * @param initialSy  initial y scaling factor.
1880      * @param initialSz  initial z scaling factor.
1881      * @param initialMxy initial x-y cross coupling error.
1882      * @param initialMxz initial x-z cross coupling error.
1883      * @param initialMyx initial y-x cross coupling error.
1884      * @param initialMyz initial y-z cross coupling error.
1885      * @param initialMzx initial z-x cross coupling error.
1886      * @param initialMzy initial z-y cross coupling error.
1887      * @throws LockedException if calibrator is currently running.
1888      */
1889     @Override
1890     public void setInitialScalingFactorsAndCrossCouplingErrors(
1891             final double initialSx, final double initialSy, final double initialSz,
1892             final double initialMxy, final double initialMxz, final double initialMyx,
1893             final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
1894         if (running) {
1895             throw new LockedException();
1896         }
1897         setInitialScalingFactors(initialSx, initialSy, initialSz);
1898         setInitialCrossCouplingErrors(initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1899     }
1900 
1901     /**
1902      * Gets initial hard-iron bias to be used to find a solution as an array.
1903      * Array values are expressed in Teslas (T).
1904      *
1905      * @return array containing coordinates of initial bias.
1906      */
1907     @Override
1908     public double[] getInitialHardIron() {
1909         final var result = new double[BodyMagneticFluxDensity.COMPONENTS];
1910         getInitialHardIron(result);
1911         return result;
1912     }
1913 
1914     /**
1915      * Gets initial hard-iron  bias to be used to find a solution as an array.
1916      * Array values are expressed in Teslas (T).
1917      *
1918      * @param result instance where result data will be copied to.
1919      * @throws IllegalArgumentException if provided array does not have
1920      *                                  length 3.
1921      */
1922     @Override
1923     public void getInitialHardIron(final double[] result) {
1924         if (result.length != BodyMagneticFluxDensity.COMPONENTS) {
1925             throw new IllegalArgumentException();
1926         }
1927         result[0] = initialHardIronX;
1928         result[1] = initialHardIronY;
1929         result[2] = initialHardIronZ;
1930     }
1931 
1932     /**
1933      * Sets initial hard-iron bias to be used to find a solution as an array.
1934      * Array values are expressed in Teslas (T).
1935      *
1936      * @param initialHardIron initial hard-iron to find a solution.
1937      * @throws LockedException          if calibrator is currently running.
1938      * @throws IllegalArgumentException if provided array does not have length 3.
1939      */
1940     @Override
1941     public void setInitialHardIron(final double[] initialHardIron) throws LockedException {
1942         if (running) {
1943             throw new LockedException();
1944         }
1945 
1946         if (initialHardIron.length != BodyMagneticFluxDensity.COMPONENTS) {
1947             throw new IllegalArgumentException();
1948         }
1949         initialHardIronX = initialHardIron[0];
1950         initialHardIronY = initialHardIron[1];
1951         initialHardIronZ = initialHardIron[2];
1952     }
1953 
1954     /**
1955      * Gets initial hard-iron bias to be used to find a solution as a
1956      * column matrix.
1957      * Values are expressed in Teslas (T).
1958      *
1959      * @return initial hard-iron bias to be used to find a solution as a
1960      * column matrix.
1961      */
1962     @Override
1963     public Matrix getInitialHardIronAsMatrix() {
1964         Matrix result;
1965         try {
1966             result = new Matrix(BodyMagneticFluxDensity.COMPONENTS, 1);
1967             getInitialHardIronAsMatrix(result);
1968         } catch (final WrongSizeException ignore) {
1969             // never happens
1970             result = null;
1971         }
1972         return result;
1973     }
1974 
1975     /**
1976      * Gets initial hard-iron bias to be used to find a solution as a
1977      * column matrix.
1978      * Values are expressed in Teslas (T).
1979      *
1980      * @param result instance where result data will be copied to.
1981      * @throws IllegalArgumentException if provided matrix is not 3x1.
1982      */
1983     @Override
1984     public void getInitialHardIronAsMatrix(final Matrix result) {
1985         if (result.getRows() != BodyMagneticFluxDensity.COMPONENTS || result.getColumns() != 1) {
1986             throw new IllegalArgumentException();
1987         }
1988         result.setElementAtIndex(0, initialHardIronX);
1989         result.setElementAtIndex(1, initialHardIronY);
1990         result.setElementAtIndex(2, initialHardIronZ);
1991     }
1992 
1993     /**
1994      * Sets initial hard-iron bias to be used to find a solution as a column
1995      * matrix with values expressed in Teslas (T).
1996      *
1997      * @param initialHardIron initial hard-iron bias to find a solution.
1998      * @throws LockedException          if calibrator is currently running.
1999      * @throws IllegalArgumentException if provided matrix is not 3x1.
2000      */
2001     @Override
2002     public void setInitialHardIron(final Matrix initialHardIron) throws LockedException {
2003         if (running) {
2004             throw new LockedException();
2005         }
2006         if (initialHardIron.getRows() != BodyMagneticFluxDensity.COMPONENTS || initialHardIron.getColumns() != 1) {
2007             throw new IllegalArgumentException();
2008         }
2009 
2010         initialHardIronX = initialHardIron.getElementAtIndex(0);
2011         initialHardIronY = initialHardIron.getElementAtIndex(1);
2012         initialHardIronZ = initialHardIron.getElementAtIndex(2);
2013     }
2014 
2015     /**
2016      * Gets initial scale factors and cross coupling errors matrix.
2017      *
2018      * @return initial scale factors and cross coupling errors matrix.
2019      */
2020     @Override
2021     public Matrix getInitialMm() {
2022         Matrix result;
2023         try {
2024             result = new Matrix(BodyMagneticFluxDensity.COMPONENTS, BodyMagneticFluxDensity.COMPONENTS);
2025             getInitialMm(result);
2026         } catch (final WrongSizeException ignore) {
2027             // never happens
2028             result = null;
2029         }
2030         return result;
2031     }
2032 
2033     /**
2034      * Gets initial scale factors and cross coupling errors matrix.
2035      *
2036      * @param result instance where data will be stored.
2037      * @throws IllegalArgumentException if provided matrix is not 3x3.
2038      */
2039     @Override
2040     public void getInitialMm(final Matrix result) {
2041         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
2042             throw new IllegalArgumentException();
2043         }
2044         result.setElementAtIndex(0, initialSx);
2045         result.setElementAtIndex(1, initialMyx);
2046         result.setElementAtIndex(2, initialMzx);
2047 
2048         result.setElementAtIndex(3, initialMxy);
2049         result.setElementAtIndex(4, initialSy);
2050         result.setElementAtIndex(5, initialMzy);
2051 
2052         result.setElementAtIndex(6, initialMxz);
2053         result.setElementAtIndex(7, initialMyz);
2054         result.setElementAtIndex(8, initialSz);
2055     }
2056 
2057     /**
2058      * Sets initial scale factors and cross coupling errors matrix.
2059      *
2060      * @param initialMm initial scale factors and cross coupling errors matrix.
2061      * @throws IllegalArgumentException if provided matrix is not 3x3.
2062      * @throws LockedException          if calibrator is currently running.
2063      */
2064     @Override
2065     public void setInitialMm(final Matrix initialMm) throws LockedException {
2066         if (running) {
2067             throw new LockedException();
2068         }
2069         if (initialMm.getRows() != BodyKinematics.COMPONENTS || initialMm.getColumns() != BodyKinematics.COMPONENTS) {
2070             throw new IllegalArgumentException();
2071         }
2072 
2073         initialSx = initialMm.getElementAtIndex(0);
2074         initialMyx = initialMm.getElementAtIndex(1);
2075         initialMzx = initialMm.getElementAtIndex(2);
2076 
2077         initialMxy = initialMm.getElementAtIndex(3);
2078         initialSy = initialMm.getElementAtIndex(4);
2079         initialMzy = initialMm.getElementAtIndex(5);
2080 
2081         initialMxz = initialMm.getElementAtIndex(6);
2082         initialMyz = initialMm.getElementAtIndex(7);
2083         initialSz = initialMm.getElementAtIndex(8);
2084     }
2085 
2086     /**
2087      * Gets collection of body magnetic flux density measurements taken
2088      * at a given position with different unknown orientations and containing the
2089      * standard deviation of magnetometer measurements.
2090      *
2091      * @return collection of body magnetic flux density measurements at
2092      * a known position and timestamp with unknown orientations.
2093      */
2094     @Override
2095     public List<StandardDeviationBodyMagneticFluxDensity> getMeasurements() {
2096         return measurements;
2097     }
2098 
2099     /**
2100      * Sets collection of body magnetic flux density measurements taken
2101      * at a given position with different unknown orientations and containing the
2102      * standard deviation of magnetometer measurements.
2103      *
2104      * @param measurements collection of body magnetic flux density
2105      *                     measurements at a known position and timestamp
2106      *                     with unknown orientations.
2107      * @throws LockedException if calibrator is currently running.
2108      */
2109     @Override
2110     public void setMeasurements(final List<StandardDeviationBodyMagneticFluxDensity> measurements)
2111             throws LockedException {
2112         if (running) {
2113             throw new LockedException();
2114         }
2115         this.measurements = measurements;
2116     }
2117 
2118     /**
2119      * Indicates the type of measurement used by this calibrator.
2120      *
2121      * @return type of measurement used by this calibrator.
2122      */
2123     @Override
2124     public MagnetometerCalibratorMeasurementType getMeasurementType() {
2125         return MagnetometerCalibratorMeasurementType.STANDARD_DEVIATION_BODY_MAGNETIC_FLUX_DENSITY;
2126     }
2127 
2128     /**
2129      * Indicates whether this calibrator requires ordered measurements in a
2130      * list or not.
2131      *
2132      * @return true if measurements must be ordered, false otherwise.
2133      */
2134     @Override
2135     public boolean isOrderedMeasurementsRequired() {
2136         return true;
2137     }
2138 
2139     /**
2140      * Indicates whether z-axis is assumed to be common for accelerometer,
2141      * gyroscope and magnetometer.
2142      * When enabled, this eliminates 3 variables from Mm (soft-iron) matrix.
2143      *
2144      * @return true if z-axis is assumed to be common for accelerometer,
2145      * gyroscope and magnetometer, false otherwise.
2146      */
2147     @Override
2148     public boolean isCommonAxisUsed() {
2149         return commonAxisUsed;
2150     }
2151 
2152     /**
2153      * Specifies whether z-axis is assumed to be common for accelerometer and
2154      * gyroscope.
2155      * When enabled, this eliminates 3 variables from Mm matrix.
2156      *
2157      * @param commonAxisUsed true if z-axis is assumed to be common for
2158      *                       accelerometer, gyroscope and magnetometer, false
2159      *                       otherwise.
2160      * @throws LockedException if estimator is currently running.
2161      */
2162     @Override
2163     public void setCommonAxisUsed(final boolean commonAxisUsed) throws LockedException {
2164         if (running) {
2165             throw new LockedException();
2166         }
2167 
2168         this.commonAxisUsed = commonAxisUsed;
2169     }
2170 
2171     /**
2172      * Gets listener to handle events raised by this calibrator.
2173      *
2174      * @return listener to handle events raised by this calibrator.
2175      */
2176     public RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener getListener() {
2177         return listener;
2178     }
2179 
2180     /**
2181      * Sets listener to handle events raised by this calibrator.
2182      *
2183      * @param listener listener to handle events raised by this calibrator.
2184      * @throws LockedException if calibrator is currently running.
2185      */
2186     public void setListener(final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener)
2187             throws LockedException {
2188         if (running) {
2189             throw new LockedException();
2190         }
2191 
2192         this.listener = listener;
2193     }
2194 
2195     /**
2196      * Gets minimum number of required measurements.
2197      *
2198      * @return minimum number of required measurements.
2199      */
2200     @Override
2201     public int getMinimumRequiredMeasurements() {
2202         return commonAxisUsed ? MINIMUM_MEASUREMENTS_COMMON_Z_AXIS : MINIMUM_MEASUREMENTS_GENERAL;
2203     }
2204 
2205     /**
2206      * Indicates whether calibrator is ready to start the estimator.
2207      *
2208      * @return true if calibrator is ready, false otherwise.
2209      */
2210     @Override
2211     public boolean isReady() {
2212         return measurements != null
2213                 && measurements.size() >= getMinimumRequiredMeasurements()
2214                 && groundTruthMagneticFluxDensityNorm != null;
2215     }
2216 
2217     /**
2218      * Indicates whether calibrator is currently running or no.
2219      *
2220      * @return true if calibrator is running, false otherwise.
2221      */
2222     @Override
2223     public boolean isRunning() {
2224         return running;
2225     }
2226 
2227     /**
2228      * Returns amount of progress variation before notifying a progress change during
2229      * calibration.
2230      *
2231      * @return amount of progress variation before notifying a progress change during
2232      * calibration.
2233      */
2234     public float getProgressDelta() {
2235         return progressDelta;
2236     }
2237 
2238     /**
2239      * Sets amount of progress variation before notifying a progress change during
2240      * calibration.
2241      *
2242      * @param progressDelta amount of progress variation before notifying a progress
2243      *                      change during calibration.
2244      * @throws IllegalArgumentException if progress delta is less than zero or greater than 1.
2245      * @throws LockedException          if calibrator is currently running.
2246      */
2247     public void setProgressDelta(final float progressDelta) throws LockedException {
2248         if (running) {
2249             throw new LockedException();
2250         }
2251         if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
2252             throw new IllegalArgumentException();
2253         }
2254         this.progressDelta = progressDelta;
2255     }
2256 
2257     /**
2258      * Returns amount of confidence expressed as a value between 0.0 and 1.0
2259      * (which is equivalent to 100%). The amount of confidence indicates the probability
2260      * that the estimated result is correct. Usually this value will be close to 1.0, but
2261      * not exactly 1.0.
2262      *
2263      * @return amount of confidence as a value between 0.0 and 1.0.
2264      */
2265     public double getConfidence() {
2266         return confidence;
2267     }
2268 
2269     /**
2270      * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which is
2271      * equivalent to 100%). The amount of confidence indicates the probability that
2272      * the estimated result is correct. Usually this value will be close to 1.0, but
2273      * not exactly 1.0.
2274      *
2275      * @param confidence confidence to be set as a value between 0.0 and 1.0.
2276      * @throws IllegalArgumentException if provided value is not between 0.0 and 1.0.
2277      * @throws LockedException          if calibrator is currently running.
2278      */
2279     public void setConfidence(final double confidence) throws LockedException {
2280         if (running) {
2281             throw new LockedException();
2282         }
2283         if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
2284             throw new IllegalArgumentException();
2285         }
2286         this.confidence = confidence;
2287     }
2288 
2289     /**
2290      * Returns maximum allowed number of iterations. If maximum allowed number of
2291      * iterations is achieved without converging to a result when calling calibrate(),
2292      * a RobustEstimatorException will be raised.
2293      *
2294      * @return maximum allowed number of iterations.
2295      */
2296     public int getMaxIterations() {
2297         return maxIterations;
2298     }
2299 
2300     /**
2301      * Sets maximum allowed number of iterations. When the maximum number of iterations
2302      * is exceeded, result will not be available, however an approximate result will be
2303      * available for retrieval.
2304      *
2305      * @param maxIterations maximum allowed number of iterations to be set.
2306      * @throws IllegalArgumentException if provided value is less than 1.
2307      * @throws LockedException          if calibrator is currently running.
2308      */
2309     public void setMaxIterations(final int maxIterations) throws LockedException {
2310         if (running) {
2311             throw new LockedException();
2312         }
2313         if (maxIterations < MIN_ITERATIONS) {
2314             throw new IllegalArgumentException();
2315         }
2316         this.maxIterations = maxIterations;
2317     }
2318 
2319     /**
2320      * Gets data related to inliers found after estimation.
2321      *
2322      * @return data related to inliers found after estimation.
2323      */
2324     public InliersData getInliersData() {
2325         return inliersData;
2326     }
2327 
2328     /**
2329      * Indicates whether result must be refined using a non-linear solver over found inliers.
2330      *
2331      * @return true to refine result, false to simply use result found by robust estimator
2332      * without further refining.
2333      */
2334     public boolean isResultRefined() {
2335         return refineResult;
2336     }
2337 
2338     /**
2339      * Specifies whether result must be refined using a non-linear solver over found inliers.
2340      *
2341      * @param refineResult true to refine result, false to simply use result found by robust
2342      *                     estimator without further refining.
2343      * @throws LockedException if calibrator is currently running.
2344      */
2345     public void setResultRefined(final boolean refineResult) throws LockedException {
2346         if (running) {
2347             throw new LockedException();
2348         }
2349         this.refineResult = refineResult;
2350     }
2351 
2352     /**
2353      * Indicates whether covariance must be kept after refining result.
2354      * This setting is only taken into account if result is refined.
2355      *
2356      * @return true if covariance must be kept after refining result, false otherwise.
2357      */
2358     public boolean isCovarianceKept() {
2359         return keepCovariance;
2360     }
2361 
2362     /**
2363      * Specifies whether covariance must be kept after refining result.
2364      * This setting is only taken into account if result is refined.
2365      *
2366      * @param keepCovariance true if covariance must be kept after refining result,
2367      *                       false otherwise.
2368      * @throws LockedException if calibrator is currently running.
2369      */
2370     public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
2371         if (running) {
2372             throw new LockedException();
2373         }
2374         this.keepCovariance = keepCovariance;
2375     }
2376 
2377     /**
2378      * Returns quality scores corresponding to each measurement.
2379      * The larger the score value the better the quality of the sample.
2380      * This implementation always returns null.
2381      * Subclasses using quality scores must implement proper behavior.
2382      *
2383      * @return quality scores corresponding to each sample.
2384      */
2385     @Override
2386     public double[] getQualityScores() {
2387         return null;
2388     }
2389 
2390     /**
2391      * Sets quality scores corresponding to each measurement.
2392      * The larger the score value the better the quality of the sample.
2393      * This implementation makes no action.
2394      * Subclasses using quality scores must implement proper behaviour.
2395      *
2396      * @param qualityScores quality scores corresponding to each pair of
2397      *                      matched points.
2398      * @throws IllegalArgumentException if provided quality scores length
2399      *                                  is smaller than minimum required samples.
2400      * @throws LockedException          if calibrator is currently running.
2401      */
2402     @Override
2403     public void setQualityScores(final double[] qualityScores) throws LockedException {
2404     }
2405 
2406     /**
2407      * Gets array containing x,y,z components of estimated magnetometer
2408      * hard-iron biases expressed in Teslas (T).
2409      *
2410      * @return array containing x,y,z components of estimated magnetometer
2411      * hard-iron biases.
2412      */
2413     @Override
2414     public double[] getEstimatedHardIron() {
2415         return estimatedHardIron;
2416     }
2417 
2418     /**
2419      * Gets array containing x,y,z components of estimated magnetometer
2420      * hard-iron biases expressed in Teslas (T).
2421      *
2422      * @param result instance where estimated magnetometer biases will be
2423      *               stored.
2424      * @return true if result instance was updated, false otherwise (when
2425      * estimation is not yet available).
2426      */
2427     @Override
2428     public boolean getEstimatedHardIron(final double[] result) {
2429         if (estimatedHardIron != null) {
2430             System.arraycopy(estimatedHardIron, 0, result, 0, estimatedHardIron.length);
2431             return true;
2432         } else {
2433             return false;
2434         }
2435     }
2436 
2437     /**
2438      * Gets column matrix containing x,y,z components of estimated
2439      * magnetometer hard-iron biases expressed in Teslas (T).
2440      *
2441      * @return column matrix containing x,y,z components of estimated
2442      * magnetometer hard-iron biases.
2443      */
2444     @Override
2445     public Matrix getEstimatedHardIronAsMatrix() {
2446         return estimatedHardIron != null ? Matrix.newFromArray(estimatedHardIron) : null;
2447     }
2448 
2449     /**
2450      * Gets column matrix containing x,y,z components of estimated
2451      * magnetometer hard-iron biases expressed in Teslas (T).
2452      *
2453      * @param result instance where result data will be stored.
2454      * @return true if result was updated, false otherwise.
2455      * @throws WrongSizeException if provided result instance has invalid size.
2456      */
2457     @Override
2458     public boolean getEstimatedHardIronAsMatrix(final Matrix result) throws WrongSizeException {
2459         if (estimatedHardIron != null) {
2460             result.fromArray(estimatedHardIron);
2461             return true;
2462         } else {
2463             return false;
2464         }
2465     }
2466 
2467     /**
2468      * Gets x coordinate of estimated magnetometer bias expressed in
2469      * Teslas (T).
2470      *
2471      * @return x coordinate of estimated magnetometer bias or null if not
2472      * available.
2473      */
2474     @Override
2475     public Double getEstimatedHardIronX() {
2476         return estimatedHardIron != null ? estimatedHardIron[0] : null;
2477     }
2478 
2479     /**
2480      * Gets y coordinate of estimated magnetometer bias expressed in
2481      * Teslas (T).
2482      *
2483      * @return y coordinate of estimated magnetometer bias or null if not
2484      * available.
2485      */
2486     @Override
2487     public Double getEstimatedHardIronY() {
2488         return estimatedHardIron != null ? estimatedHardIron[1] : null;
2489     }
2490 
2491     /**
2492      * Gets z coordinate of estimated magnetometer bias expressed in
2493      * Teslas (T).
2494      *
2495      * @return z coordinate of estimated magnetometer bias or null if not
2496      * available.
2497      */
2498     @Override
2499     public Double getEstimatedHardIronZ() {
2500         return estimatedHardIron != null ? estimatedHardIron[2] : null;
2501     }
2502 
2503     /**
2504      * Gets x coordinate of estimated magnetometer bias.
2505      *
2506      * @return x coordinate of estimated magnetometer bias.
2507      */
2508     @Override
2509     public MagneticFluxDensity getEstimatedHardIronXAsMagneticFluxDensity() {
2510         return estimatedHardIron != null
2511                 ? new MagneticFluxDensity(estimatedHardIron[0], MagneticFluxDensityUnit.TESLA) : null;
2512     }
2513 
2514     /**
2515      * Gets x coordinate of estimated magnetometer bias.
2516      *
2517      * @param result instance where result will be stored.
2518      * @return true if estimated magnetometer bias is available, false otherwise.
2519      */
2520     @Override
2521     public boolean getEstimatedHardIronXAsMagneticFluxDensity(final MagneticFluxDensity result) {
2522         if (estimatedHardIron != null) {
2523             result.setValue(estimatedHardIron[0]);
2524             result.setUnit(MagneticFluxDensityUnit.TESLA);
2525             return true;
2526         } else {
2527             return false;
2528         }
2529     }
2530 
2531     /**
2532      * Gets y coordinate of estimated magnetometer bias.
2533      *
2534      * @return y coordinate of estimated magnetometer bias.
2535      */
2536     @Override
2537     public MagneticFluxDensity getEstimatedHardIronYAsMagneticFluxDensity() {
2538         return estimatedHardIron != null
2539                 ? new MagneticFluxDensity(estimatedHardIron[1], MagneticFluxDensityUnit.TESLA) : null;
2540     }
2541 
2542     /**
2543      * Gets y coordinate of estimated magnetometer bias.
2544      *
2545      * @param result instance where result will be stored.
2546      * @return true if estimated magnetometer bias is available, false otherwise.
2547      */
2548     @Override
2549     public boolean getEstimatedHardIronYAsMagneticFluxDensity(final MagneticFluxDensity result) {
2550         if (estimatedHardIron != null) {
2551             result.setValue(estimatedHardIron[1]);
2552             result.setUnit(MagneticFluxDensityUnit.TESLA);
2553             return true;
2554         } else {
2555             return false;
2556         }
2557     }
2558 
2559     /**
2560      * Gets z coordinate of estimated magnetometer bias.
2561      *
2562      * @return z coordinate of estimated magnetometer bias.
2563      */
2564     @Override
2565     public MagneticFluxDensity getEstimatedHardIronZAsMagneticFluxDensity() {
2566         return estimatedHardIron != null
2567                 ? new MagneticFluxDensity(estimatedHardIron[2], MagneticFluxDensityUnit.TESLA) : null;
2568     }
2569 
2570     /**
2571      * Gets z coordinate of estimated magnetometer bias.
2572      *
2573      * @param result instance where result will be stored.
2574      * @return true if estimated magnetometer bias is available, false otherwise.
2575      */
2576     @Override
2577     public boolean getEstimatedHardIronZAsMagneticFluxDensity(final MagneticFluxDensity result) {
2578         if (estimatedHardIron != null) {
2579             result.setValue(estimatedHardIron[2]);
2580             result.setUnit(MagneticFluxDensityUnit.TESLA);
2581             return true;
2582         } else {
2583             return false;
2584         }
2585     }
2586 
2587     /**
2588      * Gets estimated magnetometer bias.
2589      *
2590      * @return estimated magnetometer bias or null if not available.
2591      */
2592     @Override
2593     public MagneticFluxDensityTriad getEstimatedHardIronAsTriad() {
2594         return estimatedHardIron != null
2595                 ? new MagneticFluxDensityTriad(MagneticFluxDensityUnit.TESLA,
2596                 estimatedHardIron[0], estimatedHardIron[1], estimatedHardIron[2])
2597                 : null;
2598     }
2599 
2600     /**
2601      * Gets estimated magnetometer bias.
2602      *
2603      * @param result instance where result will be stored.
2604      * @return true if estimated magnetometer bias is available and result was
2605      * modified, false otherwise.
2606      */
2607     @Override
2608     public boolean getEstimatedHardIronAsTriad(final MagneticFluxDensityTriad result) {
2609         if (estimatedHardIron != null) {
2610             result.setValueCoordinatesAndUnit(estimatedHardIron[0], estimatedHardIron[1], estimatedHardIron[2],
2611                     MagneticFluxDensityUnit.TESLA);
2612             return true;
2613         } else {
2614             return false;
2615         }
2616     }
2617 
2618     /**
2619      * Gets estimated magnetometer soft-iron matrix containing scale factors
2620      * and cross coupling errors.
2621      * This is the product of matrix Tm containing cross coupling errors and Km
2622      * containing scaling factors.
2623      * So tat:
2624      * <pre>
2625      *     Mm = [sx    mxy  mxz] = Tm*Km
2626      *          [myx   sy   myz]
2627      *          [mzx   mzy  sz ]
2628      * </pre>
2629      * Where:
2630      * <pre>
2631      *     Km = [sx 0   0 ]
2632      *          [0  sy  0 ]
2633      *          [0  0   sz]
2634      * </pre>
2635      * and
2636      * <pre>
2637      *     Tm = [1          -alphaXy    alphaXz ]
2638      *          [alphaYx    1           -alphaYz]
2639      *          [-alphaZx   alphaZy     1       ]
2640      * </pre>
2641      * Hence:
2642      * <pre>
2643      *     Mm = [sx    mxy  mxz] = Tm*Km =  [sx             -sy * alphaXy   sz * alphaXz ]
2644      *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
2645      *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
2646      * </pre>
2647      * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
2648      * are considered to be zero if the accelerometer z-axis is assumed to be the same
2649      * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mm matrix
2650      * becomes upper diagonal:
2651      * <pre>
2652      *     Mm = [sx    mxy  mxz]
2653      *          [0     sy   myz]
2654      *          [0     0    sz ]
2655      * </pre>
2656      * Values of this matrix are unit-less.
2657      *
2658      * @return estimated magnetometer soft-iron scale factors and cross coupling errors,
2659      * or null if not available.
2660      */
2661     @Override
2662     public Matrix getEstimatedMm() {
2663         return estimatedMm;
2664     }
2665 
2666     /**
2667      * Gets estimated x-axis scale factor.
2668      *
2669      * @return estimated x-axis scale factor or null if not available.
2670      */
2671     @Override
2672     public Double getEstimatedSx() {
2673         return estimatedMm != null ? estimatedMm.getElementAt(0, 0) : null;
2674     }
2675 
2676     /**
2677      * Gets estimated y-axis scale factor.
2678      *
2679      * @return estimated y-axis scale factor or null if not available.
2680      */
2681     @Override
2682     public Double getEstimatedSy() {
2683         return estimatedMm != null ? estimatedMm.getElementAt(1, 1) : null;
2684     }
2685 
2686     /**
2687      * Gets estimated z-axis scale factor.
2688      *
2689      * @return estimated z-axis scale factor or null if not available.
2690      */
2691     @Override
2692     public Double getEstimatedSz() {
2693         return estimatedMm != null ? estimatedMm.getElementAt(2, 2) : null;
2694     }
2695 
2696     /**
2697      * Gets estimated x-y cross-coupling error.
2698      *
2699      * @return estimated x-y cross-coupling error or null if not available.
2700      */
2701     @Override
2702     public Double getEstimatedMxy() {
2703         return estimatedMm != null ? estimatedMm.getElementAt(0, 1) : null;
2704     }
2705 
2706     /**
2707      * Gets estimated x-z cross-coupling error.
2708      *
2709      * @return estimated x-z cross-coupling error or null if not available.
2710      */
2711     @Override
2712     public Double getEstimatedMxz() {
2713         return estimatedMm != null ? estimatedMm.getElementAt(0, 2) : null;
2714     }
2715 
2716     /**
2717      * Gets estimated y-x cross-coupling error.
2718      *
2719      * @return estimated y-x cross-coupling error or null if not available.
2720      */
2721     @Override
2722     public Double getEstimatedMyx() {
2723         return estimatedMm != null ? estimatedMm.getElementAt(1, 0) : null;
2724     }
2725 
2726     /**
2727      * Gets estimated y-z cross-coupling error.
2728      *
2729      * @return estimated y-z cross-coupling error or null if not available.
2730      */
2731     @Override
2732     public Double getEstimatedMyz() {
2733         return estimatedMm != null ? estimatedMm.getElementAt(1, 2) : null;
2734     }
2735 
2736     /**
2737      * Gets estimated z-x cross-coupling error.
2738      *
2739      * @return estimated z-x cross-coupling error or null if not available.
2740      */
2741     @Override
2742     public Double getEstimatedMzx() {
2743         return estimatedMm != null ? estimatedMm.getElementAt(2, 0) : null;
2744     }
2745 
2746     /**
2747      * Gets estimated z-y cross-coupling error.
2748      *
2749      * @return estimated z-y cross-coupling error or null if not available.
2750      */
2751     @Override
2752     public Double getEstimatedMzy() {
2753         return estimatedMm != null ? estimatedMm.getElementAt(2, 1) : null;
2754     }
2755 
2756     /**
2757      * Gets estimated chi square value.
2758      *
2759      * @return estimated chi square value.
2760      */
2761     @Override
2762     public double getEstimatedChiSq() {
2763         return estimatedChiSq;
2764     }
2765 
2766     /**
2767      * Gets estimated chi square degrees of freedom. Degrees of freedom is equal to the number of sampled data minus the
2768      * number of estimated parameters.
2769      *
2770      * @return estimated degrees of freedom of chi square value
2771      */
2772     @Override
2773     public int getEstimatedChiSqDegreesOfFreedom() {
2774         return estimatedChiSqDegreesOfFreedom;
2775     }
2776 
2777     /**
2778      * Gets estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
2779      * freedom. Ideally this value should be close to 1.0, indicating that fit is optimal.
2780      * A value larger than 1.0 indicates that fit is not good or noise has been underestimated, and a value smaller than
2781      * 1.0 indicates that there is overfitting or noise has been overestimated.
2782      *
2783      * @return estimated reduced chi square value
2784      */
2785     @Override
2786     public double getEstimatedReducedChiSq() {
2787         return estimatedReducedChiSq;
2788     }
2789 
2790     /**
2791      * Gets estimated mean square error respect to provided measurements.
2792      *
2793      * @return estimated mean square error respect to provided measurements.
2794      */
2795     @Override
2796     public double getEstimatedMse() {
2797         return estimatedMse;
2798     }
2799 
2800     /**
2801      * Gets estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The
2802      * smaller the found chi square value is, the better the fit of the estimated parameters to the actual parameter.
2803      * Thus, the smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
2804      *
2805      * @return estimated probability of finding a smaller chi square value.
2806      */
2807     @Override
2808     public double getEstimatedP() {
2809         return estimatedP;
2810     }
2811 
2812     /**
2813      * Gets estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value
2814      * is, the better the fit that has been estimated.
2815      *
2816      * @return estimated measure of quality of estimated fit.
2817      */
2818     @Override
2819     public double getEstimatedQ() {
2820         return estimatedQ;
2821     }
2822 
2823     /**
2824      * Gets estimated covariance matrix for estimated calibration parameters.
2825      * Diagonal elements of the matrix contains variance for the following
2826      * parameters (following indicated order): bx, by, bz, sx, sy, sz,
2827      * mxy, mxz, myx, myz, mzx, mzy.
2828      *
2829      * @return estimated covariance matrix for estimated calibration parameters.
2830      */
2831     @Override
2832     public Matrix getEstimatedCovariance() {
2833         return estimatedCovariance;
2834     }
2835 
2836     /**
2837      * Gets variance of estimated x coordinate of magnetometer bias expressed in
2838      * squared Teslas (T^2).
2839      *
2840      * @return variance of estimated x coordinate of magnetometer bias or null if
2841      * not available.
2842      */
2843     public Double getEstimatedHardIronXVariance() {
2844         return estimatedCovariance != null ? estimatedCovariance.getElementAt(0, 0) : null;
2845     }
2846 
2847     /**
2848      * Gets standard deviation of estimated x coordinate of magnetometer bias
2849      * expressed in Teslas (T).
2850      *
2851      * @return standard deviation of estimated x coordinate of magnetometer bias
2852      * or null if not available.
2853      */
2854     public Double getEstimatedHardIronXStandardDeviation() {
2855         final var variance = getEstimatedHardIronXVariance();
2856         return variance != null ? Math.sqrt(variance) : null;
2857     }
2858 
2859     /**
2860      * Gets standard deviation of estimated x coordinate of magnetometer bias.
2861      *
2862      * @return standard deviation of estimated x coordinate of magnetometer bias
2863      * or null if not available.
2864      */
2865     public MagneticFluxDensity getEstimatedHardIronXStandardDeviationAsMagneticFluxDensity() {
2866         return estimatedCovariance != null
2867                 ? new MagneticFluxDensity(getEstimatedHardIronXStandardDeviation(), MagneticFluxDensityUnit.TESLA)
2868                 : null;
2869     }
2870 
2871     /**
2872      * Gets standard deviation of estimated x coordinate of magnetometer bias.
2873      *
2874      * @param result instance where result will be stored.
2875      * @return true if standard deviation of estimated x coordinate of
2876      * magnetometer bias is available, false otherwise.
2877      */
2878     public boolean getEstimatedHardIronXStandardDeviationAsMagneticFluxDensity(final MagneticFluxDensity result) {
2879         if (estimatedCovariance != null) {
2880             result.setValue(getEstimatedHardIronXStandardDeviation());
2881             result.setUnit(MagneticFluxDensityUnit.TESLA);
2882             return true;
2883         } else {
2884             return false;
2885         }
2886     }
2887 
2888     /**
2889      * Gets variance of estimated y coordinate of magnetometer bias expressed in
2890      * squared Teslas (T^2).
2891      *
2892      * @return variance of estimated y coordinate of magnetometer bias or null if
2893      * not available.
2894      */
2895     public Double getEstimatedHardIronYVariance() {
2896         return estimatedCovariance != null ? estimatedCovariance.getElementAt(1, 1) : null;
2897     }
2898 
2899     /**
2900      * Gets standard deviation of estimated y coordinate of magnetometer bias
2901      * expressed in Teslas (T).
2902      *
2903      * @return standard deviation of estimated y coordinate of magnetometer bias
2904      * or null if not available.
2905      */
2906     public Double getEstimatedHardIronYStandardDeviation() {
2907         final var variance = getEstimatedHardIronYVariance();
2908         return variance != null ? Math.sqrt(variance) : null;
2909     }
2910 
2911     /**
2912      * Gets standard deviation of estimated y coordinate of magnetometer bias.
2913      *
2914      * @return standard deviation of estimated y coordinate of magnetometer bias
2915      * or null if not available.
2916      */
2917     public MagneticFluxDensity getEstimatedHardIronYStandardDeviationAsMagneticFluxDensity() {
2918         return estimatedCovariance != null
2919                 ? new MagneticFluxDensity(getEstimatedHardIronYStandardDeviation(), MagneticFluxDensityUnit.TESLA)
2920                 : null;
2921     }
2922 
2923     /**
2924      * Gets standard deviation of estimated y coordinate of magnetometer bias.
2925      *
2926      * @param result instance where result will be stored.
2927      * @return true if standard deviation of estimated y coordinate of
2928      * magnetometer bias is available, false otherwise.
2929      */
2930     public boolean getEstimatedHardIronYStandardDeviationAsMagneticFluxDensity(final MagneticFluxDensity result) {
2931         if (estimatedCovariance != null) {
2932             result.setValue(getEstimatedHardIronYStandardDeviation());
2933             result.setUnit(MagneticFluxDensityUnit.TESLA);
2934             return true;
2935         } else {
2936             return false;
2937         }
2938     }
2939 
2940     /**
2941      * Gets variance of estimated z coordinate of magnetometer bias expressed in
2942      * squared Teslas (T^2).
2943      *
2944      * @return variance of estimated z coordinate of magnetometer bias or null if
2945      * not available.
2946      */
2947     public Double getEstimatedHardIronZVariance() {
2948         return estimatedCovariance != null ? estimatedCovariance.getElementAt(2, 2) : null;
2949     }
2950 
2951     /**
2952      * Gets standard deviation of estimated z coordinate of magnetometer bias
2953      * expressed in Teslas (T).
2954      *
2955      * @return standard deviation of estimated z coordinate of magnetometer bias
2956      * or null if not available.
2957      */
2958     public Double getEstimatedHardIronZStandardDeviation() {
2959         final var variance = getEstimatedHardIronZVariance();
2960         return variance != null ? Math.sqrt(variance) : null;
2961     }
2962 
2963     /**
2964      * Gets standard deviation of estimated z coordinate of magnetometer bias.
2965      *
2966      * @return standard deviation of estimated z coordinate of magnetometer bias
2967      * or null if not available.
2968      */
2969     public MagneticFluxDensity getEstimatedHardIronZStandardDeviationAsMagneticFluxDensity() {
2970         return estimatedCovariance != null
2971                 ? new MagneticFluxDensity(getEstimatedHardIronZStandardDeviation(), MagneticFluxDensityUnit.TESLA)
2972                 : null;
2973     }
2974 
2975     /**
2976      * Gets standard deviation of estimated z coordinate of magnetometer bias.
2977      *
2978      * @param result instance where result will be stored.
2979      * @return true if standard deviation of estimated z coordinate of
2980      * magnetometer bias is available, false otherwise.
2981      */
2982     public boolean getEstimatedHardIronZStandardDeviationAsMagneticFluxDensity(final MagneticFluxDensity result) {
2983         if (estimatedCovariance != null) {
2984             result.setValue(getEstimatedHardIronZStandardDeviation());
2985             result.setUnit(MagneticFluxDensityUnit.TESLA);
2986             return true;
2987         } else {
2988             return false;
2989         }
2990     }
2991 
2992     /**
2993      * Gets standard deviation of estimated magnetometer bias coordinates.
2994      *
2995      * @return standard deviation of estimated magnetometer bias coordinates.
2996      */
2997     public MagneticFluxDensityTriad getEstimatedHardIronStandardDeviation() {
2998         return estimatedCovariance != null
2999                 ? new MagneticFluxDensityTriad(MagneticFluxDensityUnit.TESLA,
3000                 getEstimatedHardIronXStandardDeviation(),
3001                 getEstimatedHardIronYStandardDeviation(),
3002                 getEstimatedHardIronZStandardDeviation())
3003                 : null;
3004     }
3005 
3006     /**
3007      * Gets standard deviation of estimated magnetometer bias coordinates.
3008      *
3009      * @param result instance where result will be stored.
3010      * @return true if standard deviation of magnetometer bias was available,
3011      * false otherwise.
3012      */
3013     public boolean getEstimatedHardIronStandardDeviation(final MagneticFluxDensityTriad result) {
3014         if (estimatedCovariance != null) {
3015             result.setValueCoordinatesAndUnit(
3016                     getEstimatedHardIronXStandardDeviation(),
3017                     getEstimatedHardIronYStandardDeviation(),
3018                     getEstimatedHardIronZStandardDeviation(),
3019                     MagneticFluxDensityUnit.TESLA);
3020             return true;
3021         } else {
3022             return false;
3023         }
3024     }
3025 
3026     /**
3027      * Gets average of estimated standard deviation of magnetometer bias coordinates
3028      * expressed in Teslas (T).
3029      *
3030      * @return average of estimated standard deviation of magnetometer bias coordinates,
3031      * or null if not available.
3032      */
3033     public Double getEstimatedHardIronStandardDeviationAverage() {
3034         return estimatedCovariance != null
3035                 ? (getEstimatedHardIronXStandardDeviation() + getEstimatedHardIronYStandardDeviation()
3036                 + getEstimatedHardIronZStandardDeviation()) / 3.0
3037                 : null;
3038     }
3039 
3040     /**
3041      * Gets average of estimated standard deviation of magnetometer bias coordinates.
3042      *
3043      * @return average of estimated standard deviation of magnetometer bias coordinates,
3044      * or null if not available.
3045      */
3046     public MagneticFluxDensity getEstimatedHardIronStandardDeviationAverageAsMagneticFluxDensity() {
3047         return estimatedCovariance != null
3048                 ? new MagneticFluxDensity(getEstimatedHardIronStandardDeviationAverage(), MagneticFluxDensityUnit.TESLA)
3049                 : null;
3050     }
3051 
3052     /**
3053      * Gets average of estimated standard deviation of magnetometer bias coordinates.
3054      *
3055      * @param result instance where result will be stored.
3056      * @return true if average of estimated standard deviation of magnetometer bias is available,
3057      * false otherwise.
3058      */
3059     public boolean getEstimatedHardIronStandardDeviationAverageAsMagneticFluxDensity(final MagneticFluxDensity result) {
3060         if (estimatedCovariance != null) {
3061             result.setValue(getEstimatedHardIronStandardDeviationAverage());
3062             result.setUnit(MagneticFluxDensityUnit.TESLA);
3063             return true;
3064         } else {
3065             return false;
3066         }
3067     }
3068 
3069     /**
3070      * Gets norm of estimated standard deviation of magnetometer bias expressed in
3071      * Teslas (T).
3072      *
3073      * @return norm of estimated standard deviation of magnetometer bias or null
3074      * if not available.
3075      */
3076     public Double getEstimatedHardIronStandardDeviationNorm() {
3077         return estimatedCovariance != null
3078                 ? Math.sqrt(getEstimatedHardIronXVariance() + getEstimatedHardIronYVariance()
3079                 + getEstimatedHardIronZVariance())
3080                 : null;
3081     }
3082 
3083     /**
3084      * Gets norm of estimated standard deviation of magnetometer bias.
3085      *
3086      * @return norm of estimated standard deviation of magnetometer bias or null
3087      * if not available.
3088      */
3089     public MagneticFluxDensity getEstimatedHardIronStandardDeviationNormAsMagneticFluxDensity() {
3090         return estimatedCovariance != null
3091                 ? new MagneticFluxDensity(getEstimatedHardIronStandardDeviationNorm(), MagneticFluxDensityUnit.TESLA)
3092                 : null;
3093     }
3094 
3095     /**
3096      * Gets norm of estimated standard deviation of magnetometer bias.
3097      *
3098      * @param result instance where result will be stored.
3099      * @return true if norm of estimated standard deviation of magnetometer bias
3100      * is available, false otherwise.
3101      */
3102     public boolean getEstimatedHardIronStandardDeviationNormAsMagneticFluxDensity(final MagneticFluxDensity result) {
3103         if (estimatedCovariance != null) {
3104             result.setValue(getEstimatedHardIronStandardDeviationNorm());
3105             result.setUnit(MagneticFluxDensityUnit.TESLA);
3106             return true;
3107         } else {
3108             return false;
3109         }
3110     }
3111 
3112     /**
3113      * Gets size of subsets to be checked during robust estimation.
3114      * This has to be at least {@link #MINIMUM_MEASUREMENTS_COMMON_Z_AXIS}.
3115      *
3116      * @return size of subsets to be checked during robust estimation.
3117      */
3118     public int getPreliminarySubsetSize() {
3119         return preliminarySubsetSize;
3120     }
3121 
3122     /**
3123      * Sets size of subsets to be checked during robust estimation.
3124      * This has to be at least {@link #MINIMUM_MEASUREMENTS_COMMON_Z_AXIS}.
3125      *
3126      * @param preliminarySubsetSize size of subsets to be checked during robust estimation.
3127      * @throws LockedException          if calibrator is currently running.
3128      * @throws IllegalArgumentException if provided value is less than {@link #MINIMUM_MEASUREMENTS_COMMON_Z_AXIS}.
3129      */
3130     public void setPreliminarySubsetSize(final int preliminarySubsetSize) throws LockedException {
3131         if (running) {
3132             throw new LockedException();
3133         }
3134         if (preliminarySubsetSize < MINIMUM_MEASUREMENTS_COMMON_Z_AXIS) {
3135             throw new IllegalArgumentException();
3136         }
3137 
3138         this.preliminarySubsetSize = preliminarySubsetSize;
3139     }
3140 
3141     /**
3142      * Returns method being used for robust estimation.
3143      *
3144      * @return method being used for robust estimation.
3145      */
3146     public abstract RobustEstimatorMethod getMethod();
3147 
3148     /**
3149      * Creates a robust magnetometer calibrator.
3150      *
3151      * @param method robust estimator method.
3152      * @return a robust magnetometer calibrator.
3153      */
3154     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(final RobustEstimatorMethod method) {
3155         return switch (method) {
3156             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator();
3157             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator();
3158             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator();
3159             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator();
3160             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator();
3161         };
3162     }
3163 
3164     /**
3165      * Creates a robust magnetometer calibrator.
3166      *
3167      * @param listener listener to handle events raised by this calibrator.
3168      * @param method   robust estimator method.
3169      * @return a robust magnetometer calibrator.
3170      */
3171     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3172             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3173             final RobustEstimatorMethod method) {
3174         return switch (method) {
3175             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(listener);
3176             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(listener);
3177             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(listener);
3178             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(listener);
3179             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(listener);
3180         };
3181     }
3182 
3183     /**
3184      * Creates a robust magnetometer calibrator.
3185      *
3186      * @param measurements list of body magnetic flux density
3187      *                     measurements with standard deviation of
3188      *                     magnetometer measurements taken at the same
3189      *                     position with zero velocity and unknown different
3190      *                     orientations.
3191      * @param method       robust estimator method.
3192      * @return a robust magnetometer calibrator.
3193      */
3194     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3195             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final RobustEstimatorMethod method) {
3196         return switch (method) {
3197             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
3198             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
3199             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
3200             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
3201             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
3202         };
3203     }
3204 
3205     /**
3206      * Creates a robust magnetometer calibrator.
3207      *
3208      * @param commonAxisUsed indicates whether z-axis is assumed to be common
3209      *                       for the accelerometer, gyroscope and magnetometer.
3210      * @param method         robust estimator method.
3211      * @return a robust magnetometer calibrator.
3212      */
3213     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3214             final boolean commonAxisUsed, final RobustEstimatorMethod method) {
3215         return switch (method) {
3216             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
3217             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
3218             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
3219             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
3220             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
3221         };
3222     }
3223 
3224     /**
3225      * Creates a robust magnetometer calibrator.
3226      *
3227      * @param initialHardIron initial hard-iron to find a solution.
3228      * @param method          robust estimator method.
3229      * @return a robust magnetometer calibrator.
3230      * @throws IllegalArgumentException if provided hard-iron array does
3231      *                                  not have length 3.
3232      */
3233     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3234             final double[] initialHardIron, final RobustEstimatorMethod method) {
3235         return switch (method) {
3236             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3237             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3238             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3239             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3240             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3241         };
3242     }
3243 
3244     /**
3245      * Creates a robust magnetometer calibrator.
3246      *
3247      * @param initialHardIron initial hard-iron to find a solution.
3248      * @param method          robust estimator method.
3249      * @return a robust magnetometer calibrator.
3250      * @throws IllegalArgumentException if provided hard-iron matrix is not
3251      *                                  3x1.
3252      */
3253     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3254             final Matrix initialHardIron, final RobustEstimatorMethod method) {
3255         return switch (method) {
3256             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3257             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3258             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3259             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3260             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
3261         };
3262     }
3263 
3264     /**
3265      * Creates a robust magnetometer calibrator.
3266      *
3267      * @param initialHardIron initial hard-iron to find a solution.
3268      * @param initialMm       initial soft-iron matrix containing scale factors
3269      *                        and cross coupling errors.
3270      * @param method          robust estimator method.
3271      * @return a robust magnetometer calibrator.
3272      * @throws IllegalArgumentException if provided hard-iron matrix is not
3273      *                                  3x1 or if soft-iron matrix is not
3274      *                                  3x3.
3275      */
3276     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3277             final Matrix initialHardIron, final Matrix initialMm, final RobustEstimatorMethod method) {
3278         return switch (method) {
3279             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3280                     initialHardIron, initialMm);
3281             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3282                     initialHardIron, initialMm);
3283             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3284                     initialHardIron, initialMm);
3285             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3286                     initialHardIron, initialMm);
3287             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3288                     initialHardIron, initialMm);
3289         };
3290     }
3291 
3292     /**
3293      * Creates a robust magnetometer calibrator.
3294      *
3295      * @param measurements list of body magnetic flux density
3296      *                     measurements with standard deviation of
3297      *                     magnetometer measurements taken at the same
3298      *                     position with zero velocity and unknown different
3299      *                     orientations.
3300      * @param listener     listener to handle events raised by this calibrator.
3301      * @param method       robust estimator method.
3302      * @return a robust magnetometer calibrator.
3303      */
3304     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3305             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
3306             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3307             final RobustEstimatorMethod method) {
3308         return switch (method) {
3309             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
3310             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
3311             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
3312             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
3313             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
3314         };
3315     }
3316 
3317     /**
3318      * Creates a robust magnetometer calibrator.
3319      *
3320      * @param measurements   collection of body magnetic flux density
3321      *                       measurements with standard deviation of
3322      *                       magnetometer measurements taken at the same
3323      *                       position with zero velocity and unknown different
3324      *                       orientations.
3325      * @param commonAxisUsed indicates whether z-axis is assumed to be common
3326      *                       for the accelerometer, gyroscope and magnetometer.
3327      * @param method         robust estimator method.
3328      * @return a robust magnetometer calibrator.
3329      */
3330     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3331             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3332             final RobustEstimatorMethod method) {
3333         return switch (method) {
3334             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3335                     measurements, commonAxisUsed);
3336             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3337                     measurements, commonAxisUsed);
3338             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3339                     measurements, commonAxisUsed);
3340             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3341                     measurements, commonAxisUsed);
3342             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3343                     measurements, commonAxisUsed);
3344         };
3345     }
3346 
3347     /**
3348      * Creates a robust magnetometer calibrator.
3349      *
3350      * @param measurements   collection of body magnetic flux density
3351      *                       measurements with standard deviation of
3352      *                       magnetometer measurements taken at the same
3353      *                       position with zero velocity and unknown different
3354      *                       orientations.
3355      * @param commonAxisUsed indicates whether z-axis is assumed to be common
3356      *                       for the accelerometer, gyroscope and magnetometer.
3357      * @param listener       listener to handle events raised by this calibrator.
3358      * @param method         robust estimator method.
3359      * @return a robust magnetometer calibrator.
3360      */
3361     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3362             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3363             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3364             final RobustEstimatorMethod method) {
3365         return switch (method) {
3366             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3367                     measurements, commonAxisUsed, listener);
3368             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3369                     measurements, commonAxisUsed, listener);
3370             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3371                     measurements, commonAxisUsed, listener);
3372             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3373                     measurements, commonAxisUsed, listener);
3374             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3375                     measurements, commonAxisUsed, listener);
3376         };
3377     }
3378 
3379     /**
3380      * Creates a robust magnetometer calibrator.
3381      *
3382      * @param measurements    collection of body magnetic flux density
3383      *                        measurements with standard deviation of
3384      *                        magnetometer measurements taken at the same
3385      *                        position with zero velocity and unknown different
3386      *                        orientations.
3387      * @param initialHardIron initial hard-iron to find a solution.
3388      * @param method          robust estimator method.
3389      * @return a robust magnetometer calibrator.
3390      * @throws IllegalArgumentException if provided hard-iron array does
3391      *                                  not have length 3.
3392      */
3393     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3394             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
3395             final RobustEstimatorMethod method) {
3396         return switch (method) {
3397             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3398                     measurements, initialHardIron);
3399             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3400                     measurements, initialHardIron);
3401             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3402                     measurements, initialHardIron);
3403             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3404                     measurements, initialHardIron);
3405             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3406                     measurements, initialHardIron);
3407         };
3408     }
3409 
3410     /**
3411      * Creates a robust magnetometer calibrator.
3412      *
3413      * @param measurements    collection of body magnetic flux density
3414      *                        measurements with standard deviation of
3415      *                        magnetometer measurements taken at the same
3416      *                        position with zero velocity and unknown different
3417      *                        orientations.
3418      * @param initialHardIron initial hard-iron to find a solution.
3419      * @param listener        listener to handle events raised by this calibrator.
3420      * @param method          robust estimator method.
3421      * @return a robust magnetometer calibrator.
3422      * @throws IllegalArgumentException if provided hard-iron array does
3423      *                                  not have length 3.
3424      */
3425     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3426             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
3427             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3428             final RobustEstimatorMethod method) {
3429         return switch (method) {
3430             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3431                     measurements, initialHardIron, listener);
3432             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3433                     measurements, initialHardIron, listener);
3434             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3435                     measurements, initialHardIron, listener);
3436             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3437                     measurements, initialHardIron, listener);
3438             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3439                     measurements, initialHardIron, listener);
3440         };
3441     }
3442 
3443     /**
3444      * Creates a robust magnetometer calibrator.
3445      *
3446      * @param measurements    collection of body magnetic flux density
3447      *                        measurements with standard deviation of
3448      *                        magnetometer measurements taken at the same
3449      *                        position with zero velocity and unknown different
3450      *                        orientations.
3451      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3452      *                        for the accelerometer, gyroscope and magnetometer.
3453      * @param initialHardIron initial hard-iron to find a solution.
3454      * @param method          robust estimator method.
3455      * @return a robust magnetometer calibrator.
3456      * @throws IllegalArgumentException if provided hard-iron array does
3457      *                                  not have length 3.
3458      */
3459     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3460             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
3461             final boolean commonAxisUsed, final double[] initialHardIron, final RobustEstimatorMethod method) {
3462         return switch (method) {
3463             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3464                     measurements, commonAxisUsed, initialHardIron);
3465             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3466                     measurements, commonAxisUsed, initialHardIron);
3467             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3468                     measurements, commonAxisUsed, initialHardIron);
3469             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3470                     measurements, commonAxisUsed, initialHardIron);
3471             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3472                     measurements, commonAxisUsed, initialHardIron);
3473         };
3474     }
3475 
3476     /**
3477      * Creates a robust magnetometer calibrator.
3478      *
3479      * @param measurements    collection of body magnetic flux density
3480      *                        measurements with standard deviation of
3481      *                        magnetometer measurements taken at the same
3482      *                        position with zero velocity and unknown different
3483      *                        orientations.
3484      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3485      *                        for the accelerometer, gyroscope and magnetometer.
3486      * @param initialHardIron initial hard-iron to find a solution.
3487      * @param listener        listener to handle events raised by this calibrator.
3488      * @param method          robust estimator method.
3489      * @return a robust magnetometer calibrator.
3490      */
3491     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3492             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3493             final double[] initialHardIron,
3494             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3495             final RobustEstimatorMethod method) {
3496         return switch (method) {
3497             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3498                     measurements, commonAxisUsed, initialHardIron, listener);
3499             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3500                     measurements, commonAxisUsed, initialHardIron, listener);
3501             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3502                     measurements, commonAxisUsed, initialHardIron, listener);
3503             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3504                     measurements, commonAxisUsed, initialHardIron, listener);
3505             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3506                     measurements, commonAxisUsed, initialHardIron, listener);
3507         };
3508     }
3509 
3510     /**
3511      * Creates a robust magnetometer calibrator.
3512      *
3513      * @param measurements    collection of body magnetic flux density
3514      *                        measurements with standard deviation of
3515      *                        magnetometer measurements taken at the same
3516      *                        position with zero velocity and unknown different
3517      *                        orientations.
3518      * @param initialHardIron initial hard-iron to find a solution.
3519      * @param method          robust estimator method.
3520      * @return a robust magnetometer calibrator.
3521      * @throws IllegalArgumentException if provided hard-iron matrix is not
3522      *                                  3x1.
3523      */
3524     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3525             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
3526             final RobustEstimatorMethod method) {
3527         return switch (method) {
3528             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3529                     measurements, initialHardIron);
3530             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3531                     measurements, initialHardIron);
3532             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3533                     measurements, initialHardIron);
3534             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3535                     measurements, initialHardIron);
3536             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3537                     measurements, initialHardIron);
3538         };
3539     }
3540 
3541     /**
3542      * Creates a robust magnetometer calibrator.
3543      *
3544      * @param measurements    collection of body magnetic flux density
3545      *                        measurements with standard deviation of
3546      *                        magnetometer measurements taken at the same
3547      *                        position with zero velocity and unknown different
3548      *                        orientations.
3549      * @param initialHardIron initial hard-iron to find a solution.
3550      * @param listener        listener to handle events raised by this calibrator.
3551      * @param method          robust estimator method.
3552      * @return a robust magnetometer calibrator.
3553      * @throws IllegalArgumentException if provided hard-iron matrix is not
3554      *                                  3x1.
3555      */
3556     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3557             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
3558             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3559             final RobustEstimatorMethod method) {
3560         return switch (method) {
3561             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3562                     measurements, initialHardIron, listener);
3563             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3564                     measurements, initialHardIron, listener);
3565             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3566                     measurements, initialHardIron, listener);
3567             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3568                     measurements, initialHardIron, listener);
3569             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3570                     measurements, initialHardIron, listener);
3571         };
3572     }
3573 
3574     /**
3575      * Creates a robust magnetometer calibrator.
3576      *
3577      * @param measurements    collection of body magnetic flux density
3578      *                        measurements with standard deviation of
3579      *                        magnetometer measurements taken at the same
3580      *                        position with zero velocity and unknown different
3581      *                        orientations.
3582      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3583      *                        for the accelerometer, gyroscope and magnetometer.
3584      * @param initialHardIron initial hard-iron to find a solution.
3585      * @param method          robust estimator method.
3586      * @return a robust magnetometer calibrator.
3587      * @throws IllegalArgumentException if provided hard-iron matrix is not
3588      *                                  3x1.
3589      */
3590     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3591             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3592             final Matrix initialHardIron, final RobustEstimatorMethod method) {
3593         return switch (method) {
3594             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3595                     measurements, commonAxisUsed, initialHardIron);
3596             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3597                     measurements, commonAxisUsed, initialHardIron);
3598             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3599                     measurements, commonAxisUsed, initialHardIron);
3600             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3601                     measurements, commonAxisUsed, initialHardIron);
3602             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3603                     measurements, commonAxisUsed, initialHardIron);
3604         };
3605     }
3606 
3607     /**
3608      * Creates a robust magnetometer calibrator.
3609      *
3610      * @param measurements    collection of body magnetic flux density
3611      *                        measurements with standard deviation of
3612      *                        magnetometer measurements taken at the same
3613      *                        position with zero velocity and unknown different
3614      *                        orientations.
3615      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3616      *                        for the accelerometer, gyroscope and magnetometer.
3617      * @param initialHardIron initial hard-iron to find a solution.
3618      * @param listener        listener to handle events raised by this calibrator.
3619      * @param method          robust estimator method.
3620      * @return a robust magnetometer calibrator.
3621      * @throws IllegalArgumentException if provided hard-iron matrix is not
3622      *                                  3x1.
3623      */
3624     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3625             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3626             final Matrix initialHardIron,
3627             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3628             final RobustEstimatorMethod method) {
3629         return switch (method) {
3630             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3631                     measurements, commonAxisUsed, initialHardIron, listener);
3632             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3633                     measurements, commonAxisUsed, initialHardIron, listener);
3634             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3635                     measurements, commonAxisUsed, initialHardIron, listener);
3636             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3637                     measurements, commonAxisUsed, initialHardIron, listener);
3638             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3639                     measurements, commonAxisUsed, initialHardIron, listener);
3640         };
3641     }
3642 
3643     /**
3644      * Creates a robust magnetometer calibrator.
3645      *
3646      * @param measurements    collection of body magnetic flux density
3647      *                        measurements with standard deviation of
3648      *                        magnetometer measurements taken at the same
3649      *                        position with zero velocity and unknown different
3650      *                        orientations.
3651      * @param initialHardIron initial hard-iron to find a solution.
3652      * @param initialMm       initial soft-iron matrix containing scale factors
3653      *                        and cross coupling errors.
3654      * @param method          robust estimator method.
3655      * @return a robust magnetometer calibrator.
3656      * @throws IllegalArgumentException if provided hard-iron matrix is not
3657      *                                  3x1 or if soft-iron matrix is not
3658      *                                  3x3.
3659      */
3660     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3661             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
3662             final Matrix initialMm, final RobustEstimatorMethod method) {
3663         return switch (method) {
3664             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3665                     measurements, initialHardIron, initialMm);
3666             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3667                     measurements, initialHardIron, initialMm);
3668             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3669                     measurements, initialHardIron, initialMm);
3670             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3671                     measurements, initialHardIron, initialMm);
3672             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3673                     measurements, initialHardIron, initialMm);
3674         };
3675     }
3676 
3677     /**
3678      * Creates a robust magnetometer calibrator.
3679      *
3680      * @param measurements    collection of body magnetic flux density
3681      *                        measurements with standard deviation of
3682      *                        magnetometer measurements taken at the same
3683      *                        position with zero velocity and unknown different
3684      *                        orientations.
3685      * @param initialHardIron initial hard-iron to find a solution.
3686      * @param initialMm       initial soft-iron matrix containing scale factors
3687      *                        and cross coupling errors.
3688      * @param listener        listener to handle events raised by this calibrator.
3689      * @param method          robust estimator method.
3690      * @return a robust magnetometer calibrator.
3691      * @throws IllegalArgumentException if provided hard-iron matrix is not
3692      *                                  3x1 or if soft-iron matrix is not
3693      *                                  3x3.
3694      */
3695     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3696             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
3697             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3698             final RobustEstimatorMethod method) {
3699         return switch (method) {
3700             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3701                     measurements, initialHardIron, initialMm, listener);
3702             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3703                     measurements, initialHardIron, initialMm, listener);
3704             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3705                     measurements, initialHardIron, initialMm, listener);
3706             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3707                     measurements, initialHardIron, initialMm, listener);
3708             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3709                     measurements, initialHardIron, initialMm, listener);
3710         };
3711     }
3712 
3713     /**
3714      * Creates a robust magnetometer calibrator.
3715      *
3716      * @param measurements    collection of body magnetic flux density
3717      *                        measurements with standard deviation of
3718      *                        magnetometer measurements taken at the same
3719      *                        position with zero velocity and unknown different
3720      *                        orientations.
3721      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3722      *                        for the accelerometer, gyroscope and magnetometer.
3723      * @param initialHardIron initial hard-iron to find a solution.
3724      * @param initialMm       initial soft-iron matrix containing scale factors
3725      *                        and cross coupling errors.
3726      * @param method          robust estimator method.
3727      * @return a robust magnetometer calibrator.
3728      * @throws IllegalArgumentException if provided hard-iron matrix is not
3729      *                                  3x1 or if soft-iron matrix is not
3730      *                                  3x3.
3731      */
3732     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3733             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3734             final Matrix initialHardIron, final Matrix initialMm, final RobustEstimatorMethod method) {
3735         return switch (method) {
3736             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3737                     measurements, commonAxisUsed, initialHardIron, initialMm);
3738             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3739                     measurements, commonAxisUsed, initialHardIron, initialMm);
3740             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3741                     measurements, commonAxisUsed, initialHardIron, initialMm);
3742             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3743                     measurements, commonAxisUsed, initialHardIron, initialMm);
3744             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3745                     measurements, commonAxisUsed, initialHardIron, initialMm);
3746         };
3747     }
3748 
3749     /**
3750      * Creates a robust magnetometer calibrator.
3751      *
3752      * @param measurements    collection of body magnetic flux density
3753      *                        measurements with standard deviation of
3754      *                        magnetometer measurements taken at the same
3755      *                        position with zero velocity and unknown different
3756      *                        orientations.
3757      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
3758      *                        for the accelerometer, gyroscope and magnetometer.
3759      * @param initialHardIron initial hard-iron to find a solution.
3760      * @param initialMm       initial soft-iron matrix containing scale factors
3761      *                        and cross coupling errors.
3762      * @param listener        listener to handle events raised by this calibrator.
3763      * @param method          robust estimator method.
3764      * @return a robust magnetometer calibrator.
3765      * @throws IllegalArgumentException if provided hard-iron matrix is not
3766      *                                  3x1 or if soft-iron matrix is not
3767      *                                  3x3.
3768      */
3769     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3770             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
3771             final Matrix initialHardIron, final Matrix initialMm,
3772             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3773             final RobustEstimatorMethod method) {
3774         return switch (method) {
3775             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3776                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
3777             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3778                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
3779             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3780                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
3781             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3782                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
3783             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3784                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
3785         };
3786     }
3787 
3788     /**
3789      * Creates a robust magnetometer calibrator.
3790      *
3791      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3792      * @param method                             robust estimator method.
3793      * @return a robust magnetometer calibrator.
3794      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
3795      */
3796     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3797             final Double groundTruthMagneticFluxDensityNorm, final RobustEstimatorMethod method) {
3798         return switch (method) {
3799             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3800                     groundTruthMagneticFluxDensityNorm);
3801             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3802                     groundTruthMagneticFluxDensityNorm);
3803             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3804                     groundTruthMagneticFluxDensityNorm);
3805             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3806                     groundTruthMagneticFluxDensityNorm);
3807             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3808                     groundTruthMagneticFluxDensityNorm);
3809         };
3810     }
3811 
3812     /**
3813      * Creates a robust magnetometer calibrator.
3814      *
3815      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3816      * @param listener                           listener to handle events raised by this calibrator.
3817      * @param method                             robust estimator method.
3818      * @return a robust magnetometer calibrator.
3819      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
3820      */
3821     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3822             final Double groundTruthMagneticFluxDensityNorm,
3823             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
3824             final RobustEstimatorMethod method) {
3825         return switch (method) {
3826             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3827                     groundTruthMagneticFluxDensityNorm, listener);
3828             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3829                     groundTruthMagneticFluxDensityNorm, listener);
3830             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3831                     groundTruthMagneticFluxDensityNorm, listener);
3832             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3833                     groundTruthMagneticFluxDensityNorm, listener);
3834             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3835                     groundTruthMagneticFluxDensityNorm, listener);
3836         };
3837     }
3838 
3839     /**
3840      * Creates a robust magnetometer calibrator.
3841      *
3842      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3843      * @param measurements                       collection of body magnetic flux density
3844      *                                           measurements with standard deviation of
3845      *                                           magnetometer measurements taken at the same
3846      *                                           position with zero velocity and unknown different
3847      *                                           orientations.
3848      * @param method                             robust estimator method.
3849      * @return a robust magnetometer calibrator.
3850      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
3851      */
3852     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3853             final Double groundTruthMagneticFluxDensityNorm,
3854             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
3855             final RobustEstimatorMethod method) {
3856         return switch (method) {
3857             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3858                     groundTruthMagneticFluxDensityNorm, measurements);
3859             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3860                     groundTruthMagneticFluxDensityNorm, measurements);
3861             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3862                     groundTruthMagneticFluxDensityNorm, measurements);
3863             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3864                     groundTruthMagneticFluxDensityNorm, measurements);
3865             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3866                     groundTruthMagneticFluxDensityNorm, measurements);
3867         };
3868     }
3869 
3870     /**
3871      * Creates a robust magnetometer calibrator.
3872      *
3873      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3874      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
3875      *                                           for the accelerometer, gyroscope and magnetometer.
3876      * @param method                             robust estimator method.
3877      * @return a robust magnetometer calibrator.
3878      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
3879      */
3880     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3881             final Double groundTruthMagneticFluxDensityNorm, final boolean commonAxisUsed,
3882             final RobustEstimatorMethod method) {
3883         return switch (method) {
3884             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3885                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
3886             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3887                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
3888             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3889                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
3890             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3891                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
3892             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3893                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
3894         };
3895     }
3896 
3897     /**
3898      * Creates a robust magnetometer calibrator.
3899      *
3900      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3901      * @param initialHardIron                    initial hard-iron to find a solution.
3902      * @param method                             robust estimator method.
3903      * @return a robust magnetometer calibrator.
3904      * @throws IllegalArgumentException if provided magnetic flux norm value is
3905      *                                  negative, or if provided hard-iron array does
3906      *                                  not have length 3.
3907      */
3908     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3909             final Double groundTruthMagneticFluxDensityNorm, final double[] initialHardIron,
3910             final RobustEstimatorMethod method) {
3911         return switch (method) {
3912             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3913                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3914             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3915                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3916             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3917                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3918             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3919                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3920             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3921                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3922         };
3923     }
3924 
3925     /**
3926      * Creates a robust magnetometer calibrator.
3927      *
3928      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3929      * @param initialHardIron                    initial hard-iron to find a solution.
3930      * @param method                             robust estimator method.
3931      * @return a robust magnetometer calibrator.
3932      * @throws IllegalArgumentException if provided magnetic flux norm value is
3933      *                                  negative, or if provided hard-iron matrix is not
3934      *                                  3x1.
3935      */
3936     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3937             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron,
3938             final RobustEstimatorMethod method) {
3939         return switch (method) {
3940             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3941                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3942             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3943                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3944             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3945                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3946             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3947                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3948             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3949                     groundTruthMagneticFluxDensityNorm, initialHardIron);
3950         };
3951     }
3952 
3953     /**
3954      * Creates a robust magnetometer calibrator.
3955      *
3956      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3957      * @param initialHardIron                    initial hard-iron to find a solution.
3958      * @param initialMm                          initial soft-iron matrix containing scale factors
3959      *                                           and cross coupling errors.
3960      * @param method                             robust estimator method.
3961      * @return a robust magnetometer calibrator.
3962      * @throws IllegalArgumentException if provided magnetic flux norm value is
3963      *                                  negative, or if provided hard-iron matrix is not
3964      *                                  3x1 or if soft-iron matrix is not
3965      *                                  3x3.
3966      */
3967     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3968             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron, final Matrix initialMm,
3969             final RobustEstimatorMethod method) {
3970         return switch (method) {
3971             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3972                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
3973             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3974                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
3975             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3976                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
3977             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3978                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
3979             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
3980                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
3981         };
3982     }
3983 
3984     /**
3985      * Creates a robust magnetometer calibrator.
3986      *
3987      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
3988      * @param measurements                       collection of body magnetic flux density
3989      *                                           measurements with standard deviation of
3990      *                                           magnetometer measurements taken at the same
3991      *                                           position with zero velocity and unknown different
3992      *                                           orientations.
3993      * @param listener                           listener to handle events raised by this calibrator.
3994      * @param method                             robust estimator method.
3995      * @return a robust magnetometer calibrator.
3996      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
3997      */
3998     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
3999             final Double groundTruthMagneticFluxDensityNorm,
4000             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4001             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4002             final RobustEstimatorMethod method) {
4003         return switch (method) {
4004             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4005                     groundTruthMagneticFluxDensityNorm, measurements, listener);
4006             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4007                     groundTruthMagneticFluxDensityNorm, measurements, listener);
4008             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4009                     groundTruthMagneticFluxDensityNorm, measurements, listener);
4010             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4011                     groundTruthMagneticFluxDensityNorm, measurements, listener);
4012             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4013                     groundTruthMagneticFluxDensityNorm, measurements, listener);
4014         };
4015     }
4016 
4017     /**
4018      * Creates a robust magnetometer calibrator.
4019      *
4020      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4021      * @param measurements                       collection of body magnetic flux density
4022      *                                           measurements with standard deviation of
4023      *                                           magnetometer measurements taken at the same
4024      *                                           position with zero velocity and unknown different
4025      *                                           orientations.
4026      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4027      *                                           for the accelerometer, gyroscope and magnetometer.
4028      * @param method                             robust estimator method.
4029      * @return a robust magnetometer calibrator.
4030      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
4031      */
4032     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4033             final Double groundTruthMagneticFluxDensityNorm,
4034             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4035             final RobustEstimatorMethod method) {
4036         return switch (method) {
4037             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4038                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
4039             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4040                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
4041             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4042                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
4043             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4044                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
4045             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4046                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
4047         };
4048     }
4049 
4050     /**
4051      * Creates a robust magnetometer calibrator.
4052      *
4053      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4054      * @param measurements                       collection of body magnetic flux density
4055      *                                           measurements with standard deviation of
4056      *                                           magnetometer measurements taken at the same
4057      *                                           position with zero velocity and unknown different
4058      *                                           orientations.
4059      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4060      *                                           for the accelerometer, gyroscope and magnetometer.
4061      * @param listener                           listener to handle events raised by this calibrator.
4062      * @param method                             robust estimator method.
4063      * @return a robust magnetometer calibrator.
4064      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
4065      */
4066     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4067             final Double groundTruthMagneticFluxDensityNorm,
4068             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4069             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4070             final RobustEstimatorMethod method) {
4071         return switch (method) {
4072             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4073                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
4074             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4075                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
4076             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4077                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
4078             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4079                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
4080             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4081                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
4082         };
4083     }
4084 
4085     /**
4086      * Creates a robust magnetometer calibrator.
4087      *
4088      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4089      * @param measurements                       collection of body magnetic flux density
4090      *                                           measurements with standard deviation of
4091      *                                           magnetometer measurements taken at the same
4092      *                                           position with zero velocity and unknown different
4093      *                                           orientations.
4094      * @param initialHardIron                    initial hard-iron to find a solution.
4095      * @param method                             robust estimator method.
4096      * @return a robust magnetometer calibrator.
4097      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4098      *                                  or if provided hard-iron array does not have length 3.
4099      */
4100     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4101             final Double groundTruthMagneticFluxDensityNorm,
4102             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
4103             final RobustEstimatorMethod method) {
4104         return switch (method) {
4105             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4106                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4107             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4108                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4109             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4110                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4111             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4112                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4113             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4114                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4115         };
4116     }
4117 
4118     /**
4119      * Creates a robust magnetometer calibrator.
4120      *
4121      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4122      * @param measurements                       collection of body magnetic flux density
4123      *                                           measurements with standard deviation of
4124      *                                           magnetometer measurements taken at the same
4125      *                                           position with zero velocity and unknown different
4126      *                                           orientations.
4127      * @param initialHardIron                    initial hard-iron 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 magnetometer calibrator.
4131      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4132      *                                  or if provided hard-iron array does not have length 3.
4133      */
4134     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4135             final Double groundTruthMagneticFluxDensityNorm,
4136             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
4137             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4138             final RobustEstimatorMethod method) {
4139         return switch (method) {
4140             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4141                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4142             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4143                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4144             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4145                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4146             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4147                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4148             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4149                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4150         };
4151     }
4152 
4153     /**
4154      * Creates a robust magnetometer calibrator.
4155      *
4156      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4157      * @param measurements                       collection of body magnetic flux density
4158      *                                           measurements with standard deviation of
4159      *                                           magnetometer measurements taken at the same
4160      *                                           position with zero velocity and unknown different
4161      *                                           orientations.
4162      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4163      *                                           for the accelerometer, gyroscope and magnetometer.
4164      * @param initialHardIron                    initial hard-iron to find a solution.
4165      * @param method                             robust estimator method.
4166      * @return a robust magnetometer calibrator.
4167      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4168      *                                  or if provided hard-iron array does not have length 3.
4169      */
4170     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4171             final Double groundTruthMagneticFluxDensityNorm,
4172             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4173             final double[] initialHardIron, final RobustEstimatorMethod method) {
4174         return switch (method) {
4175             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4176                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4177             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4178                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4179             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4180                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4181             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4182                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4183             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4184                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4185         };
4186     }
4187 
4188     /**
4189      * Creates a robust magnetometer calibrator.
4190      *
4191      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4192      * @param measurements                       collection of body magnetic flux density
4193      *                                           measurements with standard deviation of
4194      *                                           magnetometer measurements taken at the same
4195      *                                           position with zero velocity and unknown different
4196      *                                           orientations.
4197      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4198      *                                           for the accelerometer, gyroscope and magnetometer.
4199      * @param initialHardIron                    initial hard-iron to find a solution.
4200      * @param listener                           listener to handle events raised by this calibrator.
4201      * @param method                             robust estimator method.
4202      * @return a robust magnetometer calibrator.
4203      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4204      *                                  or if provided hard-iron array does not have length 3.
4205      */
4206     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4207             final Double groundTruthMagneticFluxDensityNorm,
4208             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4209             final double[] initialHardIron,
4210             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4211             final RobustEstimatorMethod method) {
4212         return switch (method) {
4213             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4214                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4215             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4216                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4217             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4218                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4219             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4220                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4221             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4222                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4223         };
4224     }
4225 
4226     /**
4227      * Creates a robust magnetometer calibrator.
4228      *
4229      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4230      * @param measurements                       collection of body magnetic flux density
4231      *                                           measurements with standard deviation of
4232      *                                           magnetometer measurements taken at the same
4233      *                                           position with zero velocity and unknown different
4234      *                                           orientations.
4235      * @param initialHardIron                    initial hard-iron to find a solution.
4236      * @param method                             robust estimator method.
4237      * @return a robust magnetometer calibrator.
4238      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4239      *                                  or if provided hard-iron matrix is not 3x1.
4240      */
4241     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4242             final Double groundTruthMagneticFluxDensityNorm,
4243             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
4244             final RobustEstimatorMethod method) {
4245         return switch (method) {
4246             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4247                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4248             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4249                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4250             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4251                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4252             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4253                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4254             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4255                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
4256         };
4257     }
4258 
4259     /**
4260      * Creates a robust magnetometer calibrator.
4261      *
4262      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4263      * @param measurements                       collection of body magnetic flux density
4264      *                                           measurements with standard deviation of
4265      *                                           magnetometer measurements taken at the same
4266      *                                           position with zero velocity and unknown different
4267      *                                           orientations.
4268      * @param initialHardIron                    initial hard-iron to find a solution.
4269      * @param listener                           listener to handle events raised by this calibrator.
4270      * @param method                             robust estimator method.
4271      * @return a robust magnetometer calibrator.
4272      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4273      *                                  or if provided hard-iron matrix is not 3x1.
4274      */
4275     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4276             final Double groundTruthMagneticFluxDensityNorm,
4277             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
4278             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4279             final RobustEstimatorMethod method) {
4280         return switch (method) {
4281             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4282                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4283             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4284                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4285             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4286                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4287             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4288                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4289             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4290                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
4291         };
4292     }
4293 
4294     /**
4295      * Creates a robust magnetometer calibrator.
4296      *
4297      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4298      * @param measurements                       collection of body magnetic flux density
4299      *                                           measurements with standard deviation of
4300      *                                           magnetometer measurements taken at the same
4301      *                                           position with zero velocity and unknown different
4302      *                                           orientations.
4303      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4304      *                                           for the accelerometer, gyroscope and magnetometer.
4305      * @param initialHardIron                    initial hard-iron to find a solution.
4306      * @param method                             robust estimator method.
4307      * @return a robust magnetometer calibrator.
4308      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4309      *                                  or if provided hard-iron matrix is not 3x1.
4310      */
4311     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4312             final Double groundTruthMagneticFluxDensityNorm,
4313             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4314             final Matrix initialHardIron, final RobustEstimatorMethod method) {
4315         return switch (method) {
4316             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4317                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4318             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4319                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4320             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4321                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4322             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4323                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4324             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4325                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
4326         };
4327     }
4328 
4329     /**
4330      * Creates a robust magnetometer calibrator.
4331      *
4332      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4333      * @param measurements                       collection of body magnetic flux density
4334      *                                           measurements with standard deviation of
4335      *                                           magnetometer measurements taken at the same
4336      *                                           position with zero velocity and unknown different
4337      *                                           orientations.
4338      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4339      *                                           for the accelerometer, gyroscope and magnetometer.
4340      * @param initialHardIron                    initial hard-iron to find a solution.
4341      * @param listener                           listener to handle events raised by this calibrator.
4342      * @param method robust estimator method.
4343      * @return a robust magnetometer calibrator.
4344      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4345      *                                  or if provided hard-iron matrix is not 3x1.
4346      */
4347     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4348             final Double groundTruthMagneticFluxDensityNorm,
4349             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4350             final Matrix initialHardIron,
4351             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4352             final RobustEstimatorMethod method) {
4353         return switch (method) {
4354             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4355                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4356             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4357                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4358             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4359                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4360             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4361                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4362             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4363                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
4364         };
4365     }
4366 
4367     /**
4368      * Creates a robust magnetometer calibrator.
4369      *
4370      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4371      * @param measurements                       collection of body magnetic flux density
4372      *                                           measurements with standard deviation of
4373      *                                           magnetometer measurements taken at the same
4374      *                                           position with zero velocity and unknown different
4375      *                                           orientations.
4376      * @param initialHardIron                    initial hard-iron to find a solution.
4377      * @param initialMm                          initial soft-iron matrix containing scale factors
4378      *                                           and cross coupling errors.
4379      * @param method robust estimator method.
4380      * @return a robust magnetometer calibrator.
4381      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4382      *                                  or if provided hard-iron matrix is not 3x1 or if
4383      *                                  soft-iron matrix is not 3x3.
4384      */
4385     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4386             final Double groundTruthMagneticFluxDensityNorm,
4387             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
4388             final Matrix initialMm, final RobustEstimatorMethod method) {
4389         return switch (method) {
4390             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4391                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
4392             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4393                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
4394             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4395                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
4396             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4397                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
4398             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4399                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
4400         };
4401     }
4402 
4403     /**
4404      * Creates a robust magnetometer calibrator.
4405      *
4406      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4407      * @param measurements                       collection of body magnetic flux density
4408      *                                           measurements with standard deviation of
4409      *                                           magnetometer measurements taken at the same
4410      *                                           position with zero velocity and unknown different
4411      *                                           orientations.
4412      * @param initialHardIron                    initial hard-iron to find a solution.
4413      * @param initialMm                          initial soft-iron matrix containing scale factors
4414      *                                           and cross coupling errors.
4415      * @param listener                           listener to handle events raised by this calibrator.
4416      * @param method robust estimator method.
4417      * @return a robust magnetometer calibrator.
4418      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4419      *                                  or if provided hard-iron matrix is not 3x1 or if
4420      *                                  soft-iron matrix is not 3x3.
4421      */
4422     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4423             final Double groundTruthMagneticFluxDensityNorm,
4424             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
4425             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4426             final RobustEstimatorMethod method) {
4427         return switch (method) {
4428             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4429                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
4430             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4431                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
4432             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4433                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
4434             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4435                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
4436             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4437                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
4438         };
4439     }
4440 
4441     /**
4442      * Creates a robust magnetometer calibrator.
4443      *
4444      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4445      * @param measurements                       collection of body magnetic flux density
4446      *                                           measurements with standard deviation of
4447      *                                           magnetometer measurements taken at the same
4448      *                                           position with zero velocity and unknown different
4449      *                                           orientations.
4450      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4451      *                                           for the accelerometer, gyroscope and magnetometer.
4452      * @param initialHardIron                    initial hard-iron to find a solution.
4453      * @param initialMm                          initial soft-iron matrix containing scale factors
4454      *                                           and cross coupling errors.
4455      * @param method robust estimator method.
4456      * @return a robust magnetometer calibrator.
4457      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4458      *                                  or if provided hard-iron matrix is not 3x1
4459      *                                  or if soft-iron matrix is not 3x3.
4460      */
4461     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4462             final Double groundTruthMagneticFluxDensityNorm,
4463             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4464             final Matrix initialHardIron, final Matrix initialMm, final RobustEstimatorMethod method) {
4465         return switch (method) {
4466             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4467                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
4468             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4469                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
4470             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4471                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
4472             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4473                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
4474             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4475                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
4476         };
4477     }
4478 
4479     /**
4480      * Creates a robust magnetometer calibrator.
4481      *
4482      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
4483      * @param measurements                       collection of body magnetic flux density
4484      *                                           measurements with standard deviation of
4485      *                                           magnetometer measurements taken at the same
4486      *                                           position with zero velocity and unknown different
4487      *                                           orientations.
4488      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
4489      *                                           for the accelerometer, gyroscope and magnetometer.
4490      * @param initialHardIron                    initial hard-iron to find a solution.
4491      * @param initialMm                          initial soft-iron matrix containing scale factors
4492      *                                           and cross coupling errors.
4493      * @param listener                           listener to handle events raised by this calibrator.
4494      * @param method robust estimator method.
4495      * @return a robust magnetometer calibrator.
4496      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
4497      *                                  or if provided hard-iron matrix is not 3x1
4498      *                                  or if soft-iron matrix is not 3x3.
4499      */
4500     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4501             final Double groundTruthMagneticFluxDensityNorm,
4502             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
4503             final Matrix initialHardIron, final Matrix initialMm,
4504             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4505             final RobustEstimatorMethod method) {
4506         return switch (method) {
4507             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4508                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
4509                     listener);
4510             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4511                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
4512                     listener);
4513             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4514                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
4515                     listener);
4516             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4517                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
4518                     listener);
4519             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4520                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
4521                     listener);
4522         };
4523     }
4524 
4525     /**
4526      * Creates a robust magnetometer calibrator.
4527      *
4528      * @param qualityScores quality scores corresponding to each provided
4529      *                      measurement. The larger the score value the better
4530      *                      the quality of the sample.
4531      * @param measurements  list of body magnetic flux density
4532      *                      measurements with standard deviation of
4533      *                      magnetometer measurements taken at the same
4534      *                      position with zero velocity and unknown different
4535      *                      orientations.
4536      * @param method robust estimator method.
4537      * @return a robust magnetometer calibrator.
4538      * @throws IllegalArgumentException if provided quality scores length
4539      *                                  is smaller than 10 samples.
4540      */
4541     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4542             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4543             final RobustEstimatorMethod method) {
4544         return switch (method) {
4545             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
4546             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
4547             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements);
4548             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores,
4549                     measurements);
4550             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores, measurements);
4551         };
4552     }
4553 
4554     /**
4555      * Creates a robust magnetometer calibrator.
4556      *
4557      * @param qualityScores  quality scores corresponding to each provided
4558      *                       measurement. The larger the score value the better
4559      *                       the quality of the sample.
4560      * @param commonAxisUsed indicates whether z-axis is assumed to be common
4561      *                       for the accelerometer, gyroscope and magnetometer.
4562      * @param method robust estimator method.
4563      * @return a robust magnetometer calibrator.
4564      * @throws IllegalArgumentException if provided quality scores length
4565      *                                  is smaller than 10 samples.
4566      */
4567     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4568             final double[] qualityScores, final boolean commonAxisUsed, final RobustEstimatorMethod method) {
4569         return switch (method) {
4570             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
4571             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
4572             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(commonAxisUsed);
4573             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4574                     qualityScores, commonAxisUsed);
4575             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4576                     qualityScores, commonAxisUsed);
4577         };
4578     }
4579 
4580     /**
4581      * Creates a robust magnetometer calibrator.
4582      *
4583      * @param qualityScores   quality scores corresponding to each provided
4584      *                        measurement. The larger the score value the better
4585      *                        the quality of the sample.
4586      * @param initialHardIron initial hard-iron to find a solution.
4587      * @param method robust estimator method.
4588      * @return a robust magnetometer calibrator.
4589      * @throws IllegalArgumentException if provided hard-iron array does
4590      *                                  not have length 3 or if provided
4591      *                                  quality scores length is smaller
4592      *                                  than 10 samples.
4593      */
4594     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4595             final double[] qualityScores, final double[] initialHardIron, final RobustEstimatorMethod method) {
4596         return switch (method) {
4597             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4598             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4599             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4600             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores,
4601                     initialHardIron);
4602             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores,
4603                     initialHardIron);
4604         };
4605     }
4606 
4607     /**
4608      * Creates a robust magnetometer calibrator.
4609      *
4610      * @param qualityScores   quality scores corresponding to each provided
4611      *                        measurement. The larger the score value the better
4612      *                        the quality of the sample.
4613      * @param initialHardIron initial hard-iron to find a solution.
4614      * @param method robust estimator method.
4615      * @return a robust magnetometer calibrator.
4616      * @throws IllegalArgumentException if provided hard-iron matrix is not
4617      *                                  3x1 or if provided quality scores
4618      *                                  length is smaller than 10 samples.
4619      */
4620     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4621             final double[] qualityScores, final Matrix initialHardIron, final RobustEstimatorMethod method) {
4622         return switch (method) {
4623             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4624             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4625             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(initialHardIron);
4626             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores,
4627                     initialHardIron);
4628             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(qualityScores,
4629                     initialHardIron);
4630         };
4631     }
4632 
4633     /**
4634      * Creates a robust magnetometer calibrator.
4635      *
4636      * @param qualityScores   quality scores corresponding to each provided
4637      *                        measurement. The larger the score value the better
4638      *                        the quality of the sample.
4639      * @param initialHardIron initial hard-iron to find a solution.
4640      * @param initialMm       initial soft-iron matrix containing scale factors
4641      *                        and cross coupling errors.
4642      * @param method robust estimator method.
4643      * @return a robust magnetometer calibrator.
4644      * @throws IllegalArgumentException if provided hard-iron matrix is not
4645      *                                  3x1 or if soft-iron matrix is not
4646      *                                  3x3 or if provided quality scores
4647      *                                  length is smaller than 10 samples.
4648      */
4649     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4650             final double[] qualityScores, final Matrix initialHardIron, final Matrix initialMm,
4651             final RobustEstimatorMethod method) {
4652         return switch (method) {
4653             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4654                     initialHardIron, initialMm);
4655             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4656                     initialHardIron, initialMm);
4657             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4658                     initialHardIron, initialMm);
4659             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4660                     qualityScores, initialHardIron, initialMm);
4661             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4662                     qualityScores, initialHardIron, initialMm);
4663         };
4664     }
4665 
4666     /**
4667      * Creates a robust magnetometer calibrator.
4668      *
4669      * @param qualityScores quality scores corresponding to each provided
4670      *                      measurement. The larger the score value the better
4671      *                      the quality of the sample.
4672      * @param measurements  list of body magnetic flux density
4673      *                      measurements with standard deviation of
4674      *                      magnetometer measurements taken at the same
4675      *                      position with zero velocity and unknown different
4676      *                      orientations.
4677      * @param listener      listener to handle events raised by this calibrator.
4678      * @param method robust estimator method.
4679      * @return a robust magnetometer calibrator.
4680      * @throws IllegalArgumentException if provided quality scores length
4681      *                                  is smaller than 10 samples.
4682      */
4683     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4684             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4685             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4686             final RobustEstimatorMethod method) {
4687         return switch (method) {
4688             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
4689             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
4690             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(measurements, listener);
4691             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4692                     qualityScores, measurements, listener);
4693             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4694                     qualityScores, measurements, listener);
4695         };
4696     }
4697 
4698     /**
4699      * Creates a robust magnetometer calibrator.
4700      *
4701      * @param qualityScores  quality scores corresponding to each provided
4702      *                       measurement. The larger the score value the better
4703      *                       the quality of the sample.
4704      * @param measurements   collection of body magnetic flux density
4705      *                       measurements with standard deviation of
4706      *                       magnetometer measurements taken at the same
4707      *                       position with zero velocity and unknown different
4708      *                       orientations.
4709      * @param commonAxisUsed indicates whether z-axis is assumed to be common
4710      *                       for the accelerometer, gyroscope and magnetometer.
4711      * @param method robust estimator method.
4712      * @return a robust magnetometer calibrator.
4713      * @throws IllegalArgumentException if provided quality scores length
4714      *                                  is smaller than 10 samples.
4715      */
4716     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4717             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4718             final boolean commonAxisUsed, final RobustEstimatorMethod method) {
4719         return switch (method) {
4720             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4721                     measurements, commonAxisUsed);
4722             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4723                     measurements, commonAxisUsed);
4724             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4725                     measurements, commonAxisUsed);
4726             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4727                     qualityScores, measurements, commonAxisUsed);
4728             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4729                     qualityScores, measurements, commonAxisUsed);
4730         };
4731     }
4732 
4733     /**
4734      * Creates a robust magnetometer calibrator.
4735      *
4736      * @param qualityScores  quality scores corresponding to each provided
4737      *                       measurement. The larger the score value the better
4738      *                       the quality of the sample.
4739      * @param measurements   collection of body magnetic flux density
4740      *                       measurements with standard deviation of
4741      *                       magnetometer measurements taken at the same
4742      *                       position with zero velocity and unknown different
4743      *                       orientations.
4744      * @param commonAxisUsed indicates whether z-axis is assumed to be common
4745      *                       for the accelerometer, gyroscope and magnetometer.
4746      * @param listener       listener to handle events raised by this calibrator.
4747      * @param method robust estimator method.
4748      * @return a robust magnetometer calibrator.
4749      * @throws IllegalArgumentException if provided quality scores length
4750      *                                  is smaller than 10 samples.
4751      */
4752     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4753             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4754             final boolean commonAxisUsed,
4755             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4756             final RobustEstimatorMethod method) {
4757         return switch (method) {
4758             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4759                     measurements, commonAxisUsed, listener);
4760             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4761                     measurements, commonAxisUsed, listener);
4762             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4763                     measurements, commonAxisUsed, listener);
4764             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4765                     qualityScores, measurements, commonAxisUsed, listener);
4766             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4767                     qualityScores, measurements, commonAxisUsed, listener);
4768         };
4769     }
4770 
4771     /**
4772      * Creates a robust magnetometer calibrator.
4773      *
4774      * @param qualityScores   quality scores corresponding to each provided
4775      *                        measurement. The larger the score value the better
4776      *                        the quality of the sample.
4777      * @param measurements    collection of body magnetic flux density
4778      *                        measurements with standard deviation of
4779      *                        magnetometer measurements taken at the same
4780      *                        position with zero velocity and unknown different
4781      *                        orientations.
4782      * @param initialHardIron initial hard-iron to find a solution.
4783      * @param method robust estimator method.
4784      * @return a robust magnetometer calibrator.
4785      * @throws IllegalArgumentException if provided hard-iron array does
4786      *                                  not have length 3 or if provided quality
4787      *                                  scores length is smaller than 10 samples.
4788      */
4789     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4790             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4791             final double[] initialHardIron, final RobustEstimatorMethod method) {
4792         return switch (method) {
4793             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4794                     measurements, initialHardIron);
4795             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4796                     measurements, initialHardIron);
4797             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4798                     measurements, initialHardIron);
4799             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4800                     qualityScores, measurements, initialHardIron);
4801             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4802                     qualityScores, measurements, initialHardIron);
4803         };
4804     }
4805 
4806     /**
4807      * Creates a robust magnetometer calibrator.
4808      *
4809      * @param qualityScores   quality scores corresponding to each provided
4810      *                        measurement. The larger the score value the better
4811      *                        the quality of the sample.
4812      * @param measurements    collection of body magnetic flux density
4813      *                        measurements with standard deviation of
4814      *                        magnetometer measurements taken at the same
4815      *                        position with zero velocity and unknown different
4816      *                        orientations.
4817      * @param initialHardIron initial hard-iron to find a solution.
4818      * @param listener        listener to handle events raised by this calibrator.
4819      * @param method robust estimator method.
4820      * @return a robust magnetometer calibrator.
4821      * @throws IllegalArgumentException if provided hard-iron array does
4822      *                                  not have length 3 or if provided quality
4823      *                                  scores length is smaller than 10 samples.
4824      */
4825     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4826             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4827             final double[] initialHardIron,
4828             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4829             final RobustEstimatorMethod method) {
4830         return switch (method) {
4831             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4832                     measurements, initialHardIron, listener);
4833             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4834                     measurements, initialHardIron, listener);
4835             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4836                     measurements, initialHardIron, listener);
4837             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4838                     qualityScores, measurements, initialHardIron, listener);
4839             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4840                     qualityScores, measurements, initialHardIron, listener);
4841         };
4842     }
4843 
4844     /**
4845      * Creates a robust magnetometer calibrator.
4846      *
4847      * @param qualityScores   quality scores corresponding to each provided
4848      *                        measurement. The larger the score value the better
4849      *                        the quality of the sample.
4850      * @param measurements    collection of body magnetic flux density
4851      *                        measurements with standard deviation of
4852      *                        magnetometer measurements taken at the same
4853      *                        position with zero velocity and unknown different
4854      *                        orientations.
4855      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
4856      *                        for the accelerometer, gyroscope and magnetometer.
4857      * @param initialHardIron initial hard-iron to find a solution.
4858      * @param method robust estimator method.
4859      * @return a robust magnetometer calibrator.
4860      * @throws IllegalArgumentException if provided hard-iron array does
4861      *                                  not have length 3 or if provided quality
4862      *                                  scores length is smaller than 10 samples.
4863      */
4864     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4865             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4866             final boolean commonAxisUsed, final double[] initialHardIron, final RobustEstimatorMethod method) {
4867         return switch (method) {
4868             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4869                     measurements, commonAxisUsed, initialHardIron);
4870             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4871                     measurements, commonAxisUsed, initialHardIron);
4872             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4873                     measurements, commonAxisUsed, initialHardIron);
4874             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4875                     qualityScores, measurements, commonAxisUsed, initialHardIron);
4876             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4877                     qualityScores, measurements, commonAxisUsed, initialHardIron);
4878         };
4879     }
4880 
4881     /**
4882      * Creates a robust magnetometer calibrator.
4883      *
4884      * @param qualityScores   quality scores corresponding to each provided
4885      *                        measurement. The larger the score value the better
4886      *                        the quality of the sample.
4887      * @param measurements    collection of body magnetic flux density
4888      *                        measurements with standard deviation of
4889      *                        magnetometer measurements taken at the same
4890      *                        position with zero velocity and unknown different
4891      *                        orientations.
4892      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
4893      *                        for the accelerometer, gyroscope and magnetometer.
4894      * @param initialHardIron initial hard-iron to find a solution.
4895      * @param listener        listener to handle events raised by this calibrator.
4896      * @param method robust estimator method.
4897      * @return a robust magnetometer calibrator.
4898      * @throws IllegalArgumentException if provided hard-iron array does
4899      *                                  not have length 3 or if provided quality
4900      *                                  scores length is smaller than 10 samples.
4901      */
4902     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4903             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4904             final boolean commonAxisUsed, final double[] initialHardIron,
4905             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4906             final RobustEstimatorMethod method) {
4907         return switch (method) {
4908             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4909                     measurements, commonAxisUsed, initialHardIron, listener);
4910             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4911                     measurements, commonAxisUsed, initialHardIron, listener);
4912             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4913                     measurements, commonAxisUsed, initialHardIron, listener);
4914             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4915                     qualityScores, measurements, commonAxisUsed, initialHardIron, listener);
4916             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4917                     qualityScores, measurements, commonAxisUsed, initialHardIron, listener);
4918         };
4919     }
4920 
4921     /**
4922      * Creates a robust magnetometer calibrator.
4923      *
4924      * @param qualityScores   quality scores corresponding to each provided
4925      *                        measurement. The larger the score value the better
4926      *                        the quality of the sample.
4927      * @param measurements    collection of body magnetic flux density
4928      *                        measurements with standard deviation of
4929      *                        magnetometer measurements taken at the same
4930      *                        position with zero velocity and unknown different
4931      *                        orientations.
4932      * @param initialHardIron initial hard-iron to find a solution.
4933      * @param method robust estimator method.
4934      * @return a robust magnetometer calibrator.
4935      * @throws IllegalArgumentException if provided hard-iron matrix is not
4936      *                                  3x1 or if provided quality scores length
4937      *                                  is smaller than 10 samples.
4938      */
4939     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4940             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4941             final Matrix initialHardIron, final RobustEstimatorMethod method) {
4942         return switch (method) {
4943             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4944                     measurements, initialHardIron);
4945             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4946                     measurements, initialHardIron);
4947             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4948                     measurements, initialHardIron);
4949             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4950                     qualityScores, measurements, initialHardIron);
4951             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4952                     qualityScores, measurements, initialHardIron);
4953         };
4954     }
4955 
4956     /**
4957      * Creates a robust magnetometer calibrator.
4958      *
4959      * @param qualityScores   quality scores corresponding to each provided
4960      *                        measurement. The larger the score value the better
4961      *                        the quality of the sample.
4962      * @param measurements    collection of body magnetic flux density
4963      *                        measurements with standard deviation of
4964      *                        magnetometer measurements taken at the same
4965      *                        position with zero velocity and unknown different
4966      *                        orientations.
4967      * @param initialHardIron initial hard-iron to find a solution.
4968      * @param listener        listener to handle events raised by this calibrator.
4969      * @param method robust estimator method.
4970      * @return a robust magnetometer calibrator.
4971      * @throws IllegalArgumentException if provided hard-iron matrix is not
4972      *                                  3x1 or if provided quality scores length
4973      *                                  is smaller than 10 samples.
4974      */
4975     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
4976             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
4977             final Matrix initialHardIron,
4978             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
4979             final RobustEstimatorMethod method) {
4980         return switch (method) {
4981             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4982                     measurements, initialHardIron, listener);
4983             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4984                     measurements, initialHardIron, listener);
4985             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4986                     measurements, initialHardIron, listener);
4987             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4988                     qualityScores, measurements, initialHardIron, listener);
4989             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
4990                     qualityScores, measurements, initialHardIron, listener);
4991         };
4992     }
4993 
4994     /**
4995      * Creates a robust magnetometer calibrator.
4996      *
4997      * @param qualityScores   quality scores corresponding to each provided
4998      *                        measurement. The larger the score value the better
4999      *                        the quality of the sample.
5000      * @param measurements    collection of body magnetic flux density
5001      *                        measurements with standard deviation of
5002      *                        magnetometer measurements taken at the same
5003      *                        position with zero velocity and unknown different
5004      *                        orientations.
5005      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
5006      *                        for the accelerometer, gyroscope and magnetometer.
5007      * @param initialHardIron initial hard-iron to find a solution.
5008      * @param method robust estimator method.
5009      * @return a robust magnetometer calibrator.
5010      * @throws IllegalArgumentException if provided hard-iron matrix is not
5011      *                                  3x1 or if provided quality scores length
5012      *                                  is smaller than 10 samples.
5013      */
5014     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5015             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5016             final boolean commonAxisUsed, final Matrix initialHardIron, final RobustEstimatorMethod method) {
5017         return switch (method) {
5018             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5019                     measurements, commonAxisUsed, initialHardIron);
5020             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5021                     measurements, commonAxisUsed, initialHardIron);
5022             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5023                     measurements, commonAxisUsed, initialHardIron);
5024             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5025                     qualityScores, measurements, commonAxisUsed, initialHardIron);
5026             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5027                     qualityScores, measurements, commonAxisUsed, initialHardIron);
5028         };
5029     }
5030 
5031     /**
5032      * Creates a robust magnetometer calibrator.
5033      *
5034      * @param qualityScores   quality scores corresponding to each provided
5035      *                        measurement. The larger the score value the better
5036      *                        the quality of the sample.
5037      * @param measurements    collection of body magnetic flux density
5038      *                        measurements with standard deviation of
5039      *                        magnetometer measurements taken at the same
5040      *                        position with zero velocity and unknown different
5041      *                        orientations.
5042      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
5043      *                        for the accelerometer, gyroscope and magnetometer.
5044      * @param initialHardIron initial hard-iron to find a solution.
5045      * @param listener        listener to handle events raised by this calibrator.
5046      * @param method robust estimator method.
5047      * @return a robust magnetometer calibrator.
5048      * @throws IllegalArgumentException if provided hard-iron matrix is not
5049      *                                  3x1 or if provided quality scores length
5050      *                                  is smaller than 10 samples.
5051      */
5052     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5053             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5054             final boolean commonAxisUsed, final Matrix initialHardIron,
5055             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5056             final RobustEstimatorMethod method) {
5057         return switch (method) {
5058             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5059                     measurements, commonAxisUsed, initialHardIron, listener);
5060             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5061                     measurements, commonAxisUsed, initialHardIron, listener);
5062             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5063                     measurements, commonAxisUsed, initialHardIron, listener);
5064             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5065                     qualityScores, measurements, commonAxisUsed, initialHardIron, listener);
5066             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5067                     qualityScores, measurements, commonAxisUsed, initialHardIron, listener);
5068         };
5069     }
5070 
5071     /**
5072      * Creates a robust magnetometer calibrator.
5073      *
5074      * @param qualityScores   quality scores corresponding to each provided
5075      *                        measurement. The larger the score value the better
5076      *                        the quality of the sample.*
5077      * @param measurements    collection of body magnetic flux density
5078      *                        measurements with standard deviation of
5079      *                        magnetometer measurements taken at the same
5080      *                        position with zero velocity and unknown different
5081      *                        orientations.
5082      * @param initialHardIron initial hard-iron to find a solution.
5083      * @param initialMm       initial soft-iron matrix containing scale factors
5084      *                        and cross coupling errors.
5085      * @param method robust estimator method.
5086      * @return a robust magnetometer calibrator.
5087      * @throws IllegalArgumentException if provided hard-iron matrix is not
5088      *                                  3x1 or if soft-iron matrix is not
5089      *                                  3x3 or if provided quality scores length
5090      *                                  is smaller than 10 samples.
5091      */
5092     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5093             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5094             final Matrix initialHardIron, final Matrix initialMm, final RobustEstimatorMethod method) {
5095         return switch (method) {
5096             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5097                     measurements, initialHardIron, initialMm);
5098             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5099                     measurements, initialHardIron, initialMm);
5100             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5101                     measurements, initialHardIron, initialMm);
5102             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5103                     qualityScores, measurements, initialHardIron, initialMm);
5104             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5105                     qualityScores, measurements, initialHardIron, initialMm);
5106         };
5107     }
5108 
5109     /**
5110      * Creates a robust magnetometer calibrator.
5111      *
5112      * @param qualityScores   quality scores corresponding to each provided
5113      *                        measurement. The larger the score value the better
5114      *                        the quality of the sample.
5115      * @param measurements    collection of body magnetic flux density
5116      *                        measurements with standard deviation of
5117      *                        magnetometer measurements taken at the same
5118      *                        position with zero velocity and unknown different
5119      *                        orientations.
5120      * @param initialHardIron initial hard-iron to find a solution.
5121      * @param initialMm       initial soft-iron matrix containing scale factors
5122      *                        and cross coupling errors.
5123      * @param listener        listener to handle events raised by this calibrator.
5124      * @param method robust estimator method.
5125      * @return a robust magnetometer calibrator.
5126      * @throws IllegalArgumentException if provided hard-iron matrix is not
5127      *                                  3x1 or if soft-iron matrix is not
5128      *                                  3x3 or if provided quality scores length
5129      *                                  is smaller than 10 samples.
5130      */
5131     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5132             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5133             final Matrix initialHardIron, final Matrix initialMm,
5134             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5135             final RobustEstimatorMethod method) {
5136         return switch (method) {
5137             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5138                     measurements, initialHardIron, initialMm, listener);
5139             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5140                     measurements, initialHardIron, initialMm, listener);
5141             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5142                     measurements, initialHardIron, initialMm, listener);
5143             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5144                     qualityScores, measurements, initialHardIron, initialMm, listener);
5145             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5146                     qualityScores, measurements, initialHardIron, initialMm, listener);
5147         };
5148     }
5149 
5150     /**
5151      * Creates a robust magnetometer calibrator.
5152      *
5153      * @param qualityScores   quality scores corresponding to each provided
5154      *                        measurement. The larger the score value the better
5155      *                        the quality of the sample.
5156      * @param measurements    collection of body magnetic flux density
5157      *                        measurements with standard deviation of
5158      *                        magnetometer measurements taken at the same
5159      *                        position with zero velocity and unknown different
5160      *                        orientations.
5161      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
5162      *                        for the accelerometer, gyroscope and magnetometer.
5163      * @param initialHardIron initial hard-iron to find a solution.
5164      * @param initialMm       initial soft-iron matrix containing scale factors
5165      *                        and cross coupling errors.
5166      * @param method robust estimator method.
5167      * @return a robust magnetometer calibrator.
5168      * @throws IllegalArgumentException if provided hard-iron matrix is not
5169      *                                  3x1 or if soft-iron matrix is not
5170      *                                  3x3 or if provided quality scores length
5171      *                                  is smaller than 10 samples.
5172      */
5173     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5174             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5175             final boolean commonAxisUsed, final Matrix initialHardIron, final Matrix initialMm,
5176             final RobustEstimatorMethod method) {
5177         return switch (method) {
5178             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5179                     measurements, commonAxisUsed, initialHardIron, initialMm);
5180             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5181                     measurements, commonAxisUsed, initialHardIron, initialMm);
5182             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5183                     measurements, commonAxisUsed, initialHardIron, initialMm);
5184             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5185                     qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm);
5186             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5187                     qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm);
5188         };
5189     }
5190 
5191     /**
5192      * Creates a robust magnetometer calibrator.
5193      *
5194      * @param qualityScores   quality scores corresponding to each provided
5195      *                        measurement. The larger the score value the better
5196      *                        the quality of the sample.
5197      * @param measurements    collection of body magnetic flux density
5198      *                        measurements with standard deviation of
5199      *                        magnetometer measurements taken at the same
5200      *                        position with zero velocity and unknown different
5201      *                        orientations.
5202      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
5203      *                        for the accelerometer, gyroscope and magnetometer.
5204      * @param initialHardIron initial hard-iron to find a solution.
5205      * @param initialMm       initial soft-iron matrix containing scale factors
5206      *                        and cross coupling errors.
5207      * @param listener        listener to handle events raised by this calibrator.
5208      * @param method robust estimator method.
5209      * @return a robust magnetometer calibrator.
5210      * @throws IllegalArgumentException if provided hard-iron matrix is not
5211      *                                  3x1 or if soft-iron matrix is not
5212      *                                  3x3 or if provided quality scores length
5213      *                                  is smaller than 10 samples.
5214      */
5215     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5216             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5217             final boolean commonAxisUsed, final Matrix initialHardIron, final Matrix initialMm,
5218             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5219             final RobustEstimatorMethod method) {
5220         return switch (method) {
5221             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5222                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
5223             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5224                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
5225             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5226                     measurements, commonAxisUsed, initialHardIron, initialMm, listener);
5227             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5228                     qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm, listener);
5229             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5230                     qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm, listener);
5231         };
5232     }
5233 
5234     /**
5235      * Creates a robust magnetometer calibrator.
5236      *
5237      * @param qualityScores                      quality scores corresponding to each provided
5238      *                                           measurement. The larger the score value the better
5239      *                                           the quality of the sample.
5240      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5241      * @param method robust estimator method.
5242      * @return a robust magnetometer calibrator.
5243      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5244      *                                  or if provided quality scores length is smaller
5245      *                                  than 10 samples.
5246      */
5247     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5248             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5249             final RobustEstimatorMethod method) {
5250         return switch (method) {
5251             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5252                     groundTruthMagneticFluxDensityNorm);
5253             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5254                     groundTruthMagneticFluxDensityNorm);
5255             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5256                     groundTruthMagneticFluxDensityNorm);
5257             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5258                     qualityScores, groundTruthMagneticFluxDensityNorm);
5259             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5260                     qualityScores, groundTruthMagneticFluxDensityNorm);
5261         };
5262     }
5263 
5264     /**
5265      * Creates a robust magnetometer calibrator.
5266      *
5267      * @param qualityScores                      quality scores corresponding to each provided
5268      *                                           measurement. The larger the score value the better
5269      *                                           the quality of the sample.
5270      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5271      * @param listener                           listener to handle events raised by this calibrator.
5272      * @param method robust estimator method.
5273      * @return a robust magnetometer calibrator.
5274      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5275      *                                  or if provided quality scores length is smaller
5276      *                                  than 10 samples.
5277      */
5278     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5279             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5280             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5281             final RobustEstimatorMethod method) {
5282         return switch (method) {
5283             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5284                     groundTruthMagneticFluxDensityNorm, listener);
5285             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5286                     groundTruthMagneticFluxDensityNorm, listener);
5287             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5288                     groundTruthMagneticFluxDensityNorm, listener);
5289             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5290                     qualityScores, groundTruthMagneticFluxDensityNorm, listener);
5291             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5292                     qualityScores, groundTruthMagneticFluxDensityNorm, listener);
5293         };
5294     }
5295 
5296     /**
5297      * Creates a robust magnetometer calibrator.
5298      *
5299      * @param qualityScores                      quality scores corresponding to each provided
5300      *                                           measurement. The larger the score value the better
5301      *                                           the quality of the sample.
5302      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5303      * @param measurements                       collection of body magnetic flux density
5304      *                                           measurements with standard deviation of
5305      *                                           magnetometer measurements taken at the same
5306      *                                           position with zero velocity and unknown different
5307      *                                           orientations.
5308      * @param method robust estimator method.
5309      * @return a robust magnetometer calibrator.
5310      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5311      *                                  or if provided quality scores length is smaller
5312      *                                  than 10 samples.
5313      */
5314     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5315             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5316             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5317             final RobustEstimatorMethod method) {
5318         return switch (method) {
5319             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5320                     groundTruthMagneticFluxDensityNorm, measurements);
5321             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5322                     groundTruthMagneticFluxDensityNorm, measurements);
5323             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5324                     groundTruthMagneticFluxDensityNorm, measurements);
5325             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5326                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements);
5327             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5328                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements);
5329         };
5330     }
5331 
5332     /**
5333      * Creates a robust magnetometer calibrator.
5334      *
5335      * @param qualityScores                      quality scores corresponding to each provided
5336      *                                           measurement. The larger the score value the better
5337      *                                           the quality of the sample.
5338      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5339      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5340      *                                           for the accelerometer, gyroscope and magnetometer.
5341      * @param method robust estimator method.
5342      * @return a robust magnetometer calibrator.
5343      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5344      *                                  or if provided quality scores length is smaller
5345      *                                  than 10 samples.
5346      */
5347     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5348             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final boolean commonAxisUsed,
5349             final RobustEstimatorMethod method) {
5350         return switch (method) {
5351             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5352                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
5353             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5354                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
5355             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5356                     groundTruthMagneticFluxDensityNorm, commonAxisUsed);
5357             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5358                     qualityScores, groundTruthMagneticFluxDensityNorm, commonAxisUsed);
5359             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5360                     qualityScores, groundTruthMagneticFluxDensityNorm, commonAxisUsed);
5361         };
5362     }
5363 
5364     /**
5365      * Creates a robust magnetometer calibrator.
5366      *
5367      * @param qualityScores                      quality scores corresponding to each provided
5368      *                                           measurement. The larger the score value the better
5369      *                                           the quality of the sample.
5370      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5371      * @param initialHardIron                    initial hard-iron to find a solution.
5372      * @param method robust estimator method.
5373      * @return a robust magnetometer calibrator.
5374      * @throws IllegalArgumentException if provided magnetic flux norm value is
5375      *                                  negative, or if provided hard-iron array does
5376      *                                  not have length 3, or if provided quality scores
5377      *                                  length is smaller than 10 samples.
5378      */
5379     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5380             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5381             final double[] initialHardIron, final RobustEstimatorMethod method) {
5382         return switch (method) {
5383             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5384                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5385             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5386                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5387             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5388                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5389             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5390                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron);
5391             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5392                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron);
5393         };
5394     }
5395 
5396     /**
5397      * Creates a robust magnetometer calibrator.
5398      *
5399      * @param qualityScores                      quality scores corresponding to each provided
5400      *                                           measurement. The larger the score value the better
5401      *                                           the quality of the sample.
5402      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5403      * @param initialHardIron                    initial hard-iron to find a solution.
5404      * @param method robust estimator method.
5405      * @return a robust magnetometer calibrator.
5406      * @throws IllegalArgumentException if provided magnetic flux norm value is
5407      *                                  negative, or if provided hard-iron matrix is not
5408      *                                  3x1, or if provided quality scores length
5409      *                                  is smaller than 10 samples.
5410      */
5411     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5412             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5413             final Matrix initialHardIron, final RobustEstimatorMethod method) {
5414         return switch (method) {
5415             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5416                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5417             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5418                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5419             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5420                     groundTruthMagneticFluxDensityNorm, initialHardIron);
5421             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5422                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron);
5423             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5424                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron);
5425         };
5426     }
5427 
5428     /**
5429      * Creates a robust magnetometer calibrator.
5430      *
5431      * @param qualityScores                      quality scores corresponding to each provided
5432      *                                           measurement. The larger the score value the better
5433      *                                           the quality of the sample.
5434      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5435      * @param initialHardIron                    initial hard-iron to find a solution.
5436      * @param initialMm                          initial soft-iron matrix containing scale factors
5437      *                                           and cross coupling errors.
5438      * @param method robust estimator method.
5439      * @return a robust magnetometer calibrator.
5440      * @throws IllegalArgumentException if provided magnetic flux norm value is
5441      *                                  negative, or if provided hard-iron matrix is not
5442      *                                  3x1 or if soft-iron matrix is not
5443      *                                  3x3 or if provided quality scores length
5444      *                                  is smaller than 10 samples.
5445      */
5446     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5447             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron,
5448             final Matrix initialMm, final RobustEstimatorMethod method) {
5449         return switch (method) {
5450             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5451                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
5452             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5453                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
5454             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5455                     groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
5456             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5457                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
5458             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5459                     qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm);
5460         };
5461     }
5462 
5463     /**
5464      * Creates a robust magnetometer calibrator.
5465      *
5466      * @param qualityScores                      quality scores corresponding to each provided
5467      *                                           measurement. The larger the score value the better
5468      *                                           the quality of the sample.
5469      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5470      * @param measurements                       collection of body magnetic flux density
5471      *                                           measurements with standard deviation of
5472      *                                           magnetometer measurements taken at the same
5473      *                                           position with zero velocity and unknown different
5474      *                                           orientations.
5475      * @param listener                           listener to handle events raised by this calibrator.
5476      * @param method robust estimator method.
5477      * @return a robust magnetometer calibrator.
5478      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5479      *                                  or if provided quality scores length is
5480      *                                  smaller than 10 samples.
5481      */
5482     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5483             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5484             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
5485             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5486             final RobustEstimatorMethod method) {
5487         return switch (method) {
5488             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5489                     groundTruthMagneticFluxDensityNorm, measurements, listener);
5490             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5491                     groundTruthMagneticFluxDensityNorm, measurements, listener);
5492             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5493                     groundTruthMagneticFluxDensityNorm, measurements, listener);
5494             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5495                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, listener);
5496             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5497                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, listener);
5498         };
5499     }
5500 
5501     /**
5502      * Creates a robust magnetometer calibrator.
5503      *
5504      * @param qualityScores                      quality scores corresponding to each provided
5505      *                                           measurement. The larger the score value the better
5506      *                                           the quality of the sample.
5507      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5508      * @param measurements                       collection of body magnetic flux density
5509      *                                           measurements with standard deviation of
5510      *                                           magnetometer measurements taken at the same
5511      *                                           position with zero velocity and unknown different
5512      *                                           orientations.
5513      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5514      *                                           for the accelerometer, gyroscope and magnetometer.
5515      * @param method robust estimator method.
5516      * @return a robust magnetometer calibrator.
5517      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5518      *                                  or if provided quality scores length is smaller
5519      *                                  than 10 samples.
5520      */
5521     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5522             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5523             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5524             final RobustEstimatorMethod method) {
5525         return switch (method) {
5526             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5527                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
5528             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5529                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
5530             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5531                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
5532             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5533                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
5534             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5535                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
5536         };
5537     }
5538 
5539     /**
5540      * Creates a robust magnetometer calibrator.
5541      *
5542      * @param qualityScores                      quality scores corresponding to each provided
5543      *                                           measurement. The larger the score value the better
5544      *                                           the quality of the sample.
5545      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5546      * @param measurements                       collection of body magnetic flux density
5547      *                                           measurements with standard deviation of
5548      *                                           magnetometer measurements taken at the same
5549      *                                           position with zero velocity and unknown different
5550      *                                           orientations.
5551      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5552      *                                           for the accelerometer, gyroscope and magnetometer.
5553      * @param listener                           listener to handle events raised by this calibrator.
5554      * @param method robust estimator method.
5555      * @return a robust magnetometer calibrator.
5556      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
5557      *                                  or if provided quality scores length is smaller
5558      *                                  than 10 samples.
5559      */
5560     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5561             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5562             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5563             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5564             final RobustEstimatorMethod method) {
5565         return switch (method) {
5566             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5567                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
5568             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5569                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
5570             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5571                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
5572             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5573                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
5574             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5575                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
5576         };
5577     }
5578 
5579     /**
5580      * Creates a robust magnetometer calibrator.
5581      *
5582      * @param qualityScores                      quality scores corresponding to each provided
5583      *                                           measurement. The larger the score value the better
5584      *                                           the quality of the sample.
5585      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5586      * @param measurements                       collection of body magnetic flux density
5587      *                                           measurements with standard deviation of
5588      *                                           magnetometer measurements taken at the same
5589      *                                           position with zero velocity and unknown different
5590      *                                           orientations.
5591      * @param initialHardIron                    initial hard-iron to find a solution.
5592      * @param method robust estimator method.
5593      * @return a robust magnetometer calibrator.
5594      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5595      *                                  or if provided hard-iron array does not have length 3,
5596      *                                  or if provided quality scores length is smaller
5597      *                                  than 10 samples.
5598      */
5599     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5600             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5601             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
5602             final RobustEstimatorMethod method) {
5603         return switch (method) {
5604             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5605                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5606             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5607                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5608             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5609                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5610             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5611                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5612             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5613                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5614         };
5615     }
5616 
5617     /**
5618      * Creates a robust magnetometer calibrator.
5619      *
5620      * @param qualityScores                      quality scores corresponding to each provided
5621      *                                           measurement. The larger the score value the better
5622      *                                           the quality of the sample.
5623      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5624      * @param measurements                       collection of body magnetic flux density
5625      *                                           measurements with standard deviation of
5626      *                                           magnetometer measurements taken at the same
5627      *                                           position with zero velocity and unknown different
5628      *                                           orientations.
5629      * @param initialHardIron                    initial hard-iron to find a solution.
5630      * @param listener                           listener to handle events raised by this calibrator.
5631      * @param method robust estimator method.
5632      * @return a robust magnetometer calibrator.
5633      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5634      *                                  or if provided hard-iron array does not have length 3,
5635      *                                  or if provided quality scores length is smaller
5636      *                                  than 10 samples.
5637      */
5638     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5639             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5640             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
5641             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5642             final RobustEstimatorMethod method) {
5643         return switch (method) {
5644             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5645                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5646             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5647                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5648             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5649                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5650             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5651                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5652             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5653                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5654         };
5655     }
5656 
5657     /**
5658      * Creates a robust magnetometer calibrator.
5659      *
5660      * @param qualityScores                      quality scores corresponding to each provided
5661      *                                           measurement. The larger the score value the better
5662      *                                           the quality of the sample.
5663      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5664      * @param measurements                       collection of body magnetic flux density
5665      *                                           measurements with standard deviation of
5666      *                                           magnetometer measurements taken at the same
5667      *                                           position with zero velocity and unknown different
5668      *                                           orientations.
5669      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5670      *                                           for the accelerometer, gyroscope and magnetometer.
5671      * @param initialHardIron                    initial hard-iron to find a solution.
5672      * @param method robust estimator method.
5673      * @return a robust magnetometer calibrator.
5674      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5675      *                                  or if provided hard-iron array does not have length 3,
5676      *                                  or if provided quality scores length is smaller
5677      *                                  than 10 samples.
5678      */
5679     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5680             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5681             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5682             final double[] initialHardIron, final RobustEstimatorMethod method) {
5683         return switch (method) {
5684             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5685                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5686             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5687                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5688             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5689                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5690             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5691                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5692             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5693                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5694         };
5695     }
5696 
5697     /**
5698      * Creates a robust magnetometer calibrator.
5699      *
5700      * @param qualityScores                      quality scores corresponding to each provided
5701      *                                           measurement. The larger the score value the better
5702      *                                           the quality of the sample.
5703      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5704      * @param measurements                       collection of body magnetic flux density
5705      *                                           measurements with standard deviation of
5706      *                                           magnetometer measurements taken at the same
5707      *                                           position with zero velocity and unknown different
5708      *                                           orientations.
5709      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5710      *                                           for the accelerometer, gyroscope and magnetometer.
5711      * @param initialHardIron                    initial hard-iron to find a solution.
5712      * @param listener                           listener to handle events raised by this calibrator.
5713      * @param method robust estimator method.
5714      * @return a robust magnetometer calibrator.
5715      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5716      *                                  or if provided hard-iron array does not have length 3,
5717      *                                  or if provided quality scores length is smaller
5718      *                                  than 10 samples.
5719      */
5720     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5721             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5722             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5723             final double[] initialHardIron,
5724             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5725             final RobustEstimatorMethod method) {
5726         return switch (method) {
5727             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5728                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5729             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5730                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5731             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5732                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5733             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5734                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
5735                     listener);
5736             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5737                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
5738                     listener);
5739         };
5740     }
5741 
5742     /**
5743      * Creates a robust magnetometer calibrator.
5744      *
5745      * @param qualityScores                      quality scores corresponding to each provided
5746      *                                           measurement. The larger the score value the better
5747      *                                           the quality of the sample.
5748      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5749      * @param measurements                       collection of body magnetic flux density
5750      *                                           measurements with standard deviation of
5751      *                                           magnetometer measurements taken at the same
5752      *                                           position with zero velocity and unknown different
5753      *                                           orientations.
5754      * @param initialHardIron                    initial hard-iron to find a solution.
5755      * @param method robust estimator method.
5756      * @return a robust magnetometer calibrator.
5757      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5758      *                                  or if provided hard-iron matrix is not 3x1,
5759      *                                  or if provided quality scores length is smaller
5760      *                                  than 10 samples.
5761      */
5762     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5763             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5764             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
5765             final RobustEstimatorMethod method) {
5766         return switch (method) {
5767             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5768                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5769             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5770                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5771             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5772                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5773             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5774                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5775             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5776                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron);
5777         };
5778     }
5779 
5780     /**
5781      * Creates a robust magnetometer calibrator.
5782      *
5783      * @param qualityScores                      quality scores corresponding to each provided
5784      *                                           measurement. The larger the score value the better
5785      *                                           the quality of the sample.
5786      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5787      * @param measurements                       collection of body magnetic flux density
5788      *                                           measurements with standard deviation of
5789      *                                           magnetometer measurements taken at the same
5790      *                                           position with zero velocity and unknown different
5791      *                                           orientations.
5792      * @param initialHardIron                    initial hard-iron to find a solution.
5793      * @param listener                           listener to handle events raised by this calibrator.
5794      * @param method robust estimator method.
5795      * @return a robust magnetometer calibrator.
5796      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5797      *                                  or if provided hard-iron matrix is not 3x1,
5798      *                                  or if provided quality scores length is smaller
5799      *                                  than 10 samples.
5800      */
5801     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5802             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5803             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
5804             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5805             final RobustEstimatorMethod method) {
5806         return switch (method) {
5807             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5808                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5809             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5810                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5811             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5812                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5813             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5814                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5815             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5816                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener);
5817         };
5818     }
5819 
5820     /**
5821      * Creates a robust magnetometer calibrator.
5822      *
5823      * @param qualityScores                      quality scores corresponding to each provided
5824      *                                           measurement. The larger the score value the better
5825      *                                           the quality of the sample.
5826      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5827      * @param measurements                       collection of body magnetic flux density
5828      *                                           measurements with standard deviation of
5829      *                                           magnetometer measurements taken at the same
5830      *                                           position with zero velocity and unknown different
5831      *                                           orientations.
5832      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5833      *                                           for the accelerometer, gyroscope and magnetometer.
5834      * @param initialHardIron                    initial hard-iron to find a solution.
5835      * @param method robust estimator method.
5836      * @return a robust magnetometer calibrator.
5837      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5838      *                                  or if provided hard-iron matrix is not 3x1,
5839      *                                  or if provided quality scores length is smaller
5840      *                                  than 10 samples.
5841      */
5842     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5843             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5844             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5845             final Matrix initialHardIron, final RobustEstimatorMethod method) {
5846         return switch (method) {
5847             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5848                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5849             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5850                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5851             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5852                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5853             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5854                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5855             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5856                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron);
5857         };
5858     }
5859 
5860     /**
5861      * Creates a robust magnetometer calibrator.
5862      *
5863      * @param qualityScores                      quality scores corresponding to each provided
5864      *                                           measurement. The larger the score value the better
5865      *                                           the quality of the sample.
5866      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5867      * @param measurements                       collection of body magnetic flux density
5868      *                                           measurements with standard deviation of
5869      *                                           magnetometer measurements taken at the same
5870      *                                           position with zero velocity and unknown different
5871      *                                           orientations.
5872      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
5873      *                                           for the accelerometer, gyroscope and magnetometer.
5874      * @param initialHardIron                    initial hard-iron to find a solution.
5875      * @param listener                           listener to handle events raised by this calibrator.
5876      * @param method robust estimator method.
5877      * @return a robust magnetometer calibrator.
5878      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5879      *                                  or if provided hard-iron matrix is not 3x1,
5880      *                                  or if provided quality scores length is smaller
5881      *                                  than 10 samples.
5882      */
5883     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5884             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5885             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
5886             final Matrix initialHardIron,
5887             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5888             final RobustEstimatorMethod method) {
5889         return switch (method) {
5890             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5891                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5892             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5893                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5894             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5895                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener);
5896             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5897                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
5898                     listener);
5899             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5900                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
5901                     listener);
5902         };
5903     }
5904 
5905     /**
5906      * Creates a robust magnetometer calibrator.
5907      *
5908      * @param qualityScores                      quality scores corresponding to each provided
5909      *                                           measurement. The larger the score value the better
5910      *                                           the quality of the sample.
5911      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5912      * @param measurements                       collection of body magnetic flux density
5913      *                                           measurements with standard deviation of
5914      *                                           magnetometer measurements taken at the same
5915      *                                           position with zero velocity and unknown different
5916      *                                           orientations.
5917      * @param initialHardIron                    initial hard-iron to find a solution.
5918      * @param initialMm                          initial soft-iron matrix containing scale factors
5919      *                                           and cross coupling errors.
5920      * @param method robust estimator method.
5921      * @return a robust magnetometer calibrator.
5922      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5923      *                                  or if provided hard-iron matrix is not 3x1 or if
5924      *                                  soft-iron matrix is not 3x3, or if provided
5925      *                                  quality scores length is smaller than 10 samples.
5926      */
5927     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5928             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5929             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
5930             final Matrix initialMm, final RobustEstimatorMethod method) {
5931         return switch (method) {
5932             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5933                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
5934             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5935                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
5936             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5937                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
5938             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5939                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
5940             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5941                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm);
5942         };
5943     }
5944 
5945     /**
5946      * Creates a robust magnetometer calibrator.
5947      *
5948      * @param qualityScores                      quality scores corresponding to each provided
5949      *                                           measurement. The larger the score value the better
5950      *                                           the quality of the sample.
5951      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5952      * @param measurements                       collection of body magnetic flux density
5953      *                                           measurements with standard deviation of
5954      *                                           magnetometer measurements taken at the same
5955      *                                           position with zero velocity and unknown different
5956      *                                           orientations.
5957      * @param initialHardIron                    initial hard-iron to find a solution.
5958      * @param initialMm                          initial soft-iron matrix containing scale factors
5959      *                                           and cross coupling errors.
5960      * @param listener                           listener to handle events raised by this calibrator.
5961      * @param method robust estimator method.
5962      * @return a robust magnetometer calibrator.
5963      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
5964      *                                  or if provided hard-iron matrix is not 3x1 or if
5965      *                                  soft-iron matrix is not 3x3, or if provided
5966      *                                  quality scores length is smaller than 10 samples.
5967      */
5968     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
5969             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
5970             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
5971             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
5972             final RobustEstimatorMethod method) {
5973         return switch (method) {
5974             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5975                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
5976             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5977                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
5978             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5979                     groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener);
5980             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5981                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm,
5982                     listener);
5983             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
5984                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm,
5985                     listener);
5986         };
5987     }
5988 
5989     /**
5990      * Creates a robust magnetometer calibrator.
5991      *
5992      * @param qualityScores                      quality scores corresponding to each provided
5993      *                                           measurement. The larger the score value the better
5994      *                                           the quality of the sample.
5995      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
5996      * @param measurements                       collection of body magnetic flux density
5997      *                                           measurements with standard deviation of
5998      *                                           magnetometer measurements taken at the same
5999      *                                           position with zero velocity and unknown different
6000      *                                           orientations.
6001      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6002      *                                           for the accelerometer, gyroscope and magnetometer.
6003      * @param initialHardIron                    initial hard-iron to find a solution.
6004      * @param initialMm                          initial soft-iron matrix containing scale factors
6005      *                                           and cross coupling errors.
6006      * @param method robust estimator method.
6007      * @return a robust magnetometer calibrator.
6008      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6009      *                                  or if provided hard-iron matrix is not 3x1
6010      *                                  or if soft-iron matrix is not 3x3, or if
6011      *                                  provided quality scores length is smaller
6012      *                                  than 10 samples.
6013      */
6014     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6015             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
6016             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6017             final Matrix initialHardIron, final Matrix initialMm, final RobustEstimatorMethod method) {
6018         return switch (method) {
6019             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6020                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
6021             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6022                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
6023             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6024                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm);
6025             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6026                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6027                     initialMm);
6028             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6029                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6030                     initialMm);
6031         };
6032     }
6033 
6034     /**
6035      * Creates a robust magnetometer calibrator.
6036      *
6037      * @param qualityScores                      quality scores corresponding to each provided
6038      *                                           measurement. The larger the score value the better
6039      *                                           the quality of the sample.
6040      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6041      * @param measurements                       collection of body magnetic flux density
6042      *                                           measurements with standard deviation of
6043      *                                           magnetometer measurements taken at the same
6044      *                                           position with zero velocity and unknown different
6045      *                                           orientations.
6046      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6047      *                                           for the accelerometer, gyroscope and magnetometer.
6048      * @param initialHardIron                    initial hard-iron to find a solution.
6049      * @param initialMm                          initial soft-iron matrix containing scale factors
6050      *                                           and cross coupling errors.
6051      * @param listener                           listener to handle events raised by this calibrator.
6052      * @param method robust estimator method.
6053      * @return a robust magnetometer calibrator.
6054      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6055      *                                  or if provided hard-iron matrix is not 3x1
6056      *                                  or if soft-iron matrix is not 3x3, or if
6057      *                                  provided quality scores length is smaller
6058      *                                  than 10 samples.
6059      */
6060     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6061             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
6062             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6063             final Matrix initialHardIron, final Matrix initialMm,
6064             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener,
6065             final RobustEstimatorMethod method) {
6066         return switch (method) {
6067             case RANSAC -> new RANSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6068                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
6069                     listener);
6070             case LMEDS -> new LMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6071                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
6072                     listener);
6073             case MSAC -> new MSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6074                     groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
6075                     listener);
6076             case PROSAC -> new PROSACRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6077                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6078                     initialMm, listener);
6079             default -> new PROMedSRobustKnownMagneticFluxDensityNormMagnetometerCalibrator(
6080                     qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6081                     initialMm, listener);
6082         };
6083     }
6084 
6085     /**
6086      * Creates a robust magnetometer calibrator with default robust method.
6087      *
6088      * @return a robust magnetometer calibrator.
6089      */
6090     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create() {
6091         return create(DEFAULT_ROBUST_METHOD);
6092     }
6093 
6094     /**
6095      * Creates a robust magnetometer calibrator with default robust method.
6096      *
6097      * @param listener listener to handle events raised by this calibrator.
6098      * @return a robust magnetometer calibrator.
6099      */
6100     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6101             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6102         return create(listener, DEFAULT_ROBUST_METHOD);
6103     }
6104 
6105     /**
6106      * Creates a robust magnetometer calibrator with default robust method.
6107      *
6108      * @param measurements list of body magnetic flux density
6109      *                     measurements with standard deviation of
6110      *                     magnetometer measurements taken at the same
6111      *                     position with zero velocity and unknown different
6112      *                     orientations.
6113      * @return a robust magnetometer calibrator.
6114      */
6115     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6116             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
6117         return create(measurements, DEFAULT_ROBUST_METHOD);
6118     }
6119 
6120     /**
6121      * Creates a robust magnetometer calibrator with default robust method.
6122      *
6123      * @param commonAxisUsed indicates whether z-axis is assumed to be common
6124      *                       for the accelerometer, gyroscope and magnetometer.
6125      * @return a robust magnetometer calibrator.
6126      */
6127     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(final boolean commonAxisUsed) {
6128         return create(commonAxisUsed, DEFAULT_ROBUST_METHOD);
6129     }
6130 
6131     /**
6132      * Creates a robust magnetometer calibrator with default robust method.
6133      *
6134      * @param initialHardIron initial hard-iron to find a solution.
6135      * @return a robust magnetometer calibrator.
6136      * @throws IllegalArgumentException if provided hard-iron array does
6137      *                                  not have length 3.
6138      */
6139     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(final double[] initialHardIron) {
6140         return create(initialHardIron, DEFAULT_ROBUST_METHOD);
6141     }
6142 
6143     /**
6144      * Creates a robust magnetometer calibrator with default robust method.
6145      *
6146      * @param initialHardIron initial hard-iron to find a solution.
6147      * @return a robust magnetometer calibrator.
6148      * @throws IllegalArgumentException if provided hard-iron matrix is not
6149      *                                  3x1.
6150      */
6151     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(final Matrix initialHardIron) {
6152         return create(initialHardIron, DEFAULT_ROBUST_METHOD);
6153     }
6154 
6155     /**
6156      * Creates a robust magnetometer calibrator with default robust method.
6157      *
6158      * @param initialHardIron initial hard-iron to find a solution.
6159      * @param initialMm       initial soft-iron matrix containing scale factors
6160      *                        and cross coupling errors.
6161      * @return a robust magnetometer calibrator.
6162      * @throws IllegalArgumentException if provided hard-iron matrix is not
6163      *                                  3x1 or if soft-iron matrix is not
6164      *                                  3x3.
6165      */
6166     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6167             final Matrix initialHardIron, final Matrix initialMm) {
6168         return create(initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
6169     }
6170 
6171     /**
6172      * Creates a robust magnetometer calibrator with default robust method.
6173      *
6174      * @param measurements list of body magnetic flux density
6175      *                     measurements with standard deviation of
6176      *                     magnetometer measurements taken at the same
6177      *                     position with zero velocity and unknown different
6178      *                     orientations.
6179      * @param listener     listener to handle events raised by this calibrator.
6180      * @return a robust magnetometer calibrator.
6181      */
6182     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6183             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
6184             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6185         return create(measurements, listener, DEFAULT_ROBUST_METHOD);
6186     }
6187 
6188     /**
6189      * Creates a robust magnetometer calibrator with default robust method.
6190      *
6191      * @param measurements   collection of body magnetic flux density
6192      *                       measurements with standard deviation of
6193      *                       magnetometer measurements taken at the same
6194      *                       position with zero velocity and unknown different
6195      *                       orientations.
6196      * @param commonAxisUsed indicates whether z-axis is assumed to be common
6197      *                       for the accelerometer, gyroscope and magnetometer.
6198      * @return a robust magnetometer calibrator.
6199      */
6200     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6201             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
6202         return create(measurements, commonAxisUsed, DEFAULT_ROBUST_METHOD);
6203     }
6204 
6205     /**
6206      * Creates a robust magnetometer calibrator with default robust method.
6207      *
6208      * @param measurements   collection of body magnetic flux density
6209      *                       measurements with standard deviation of
6210      *                       magnetometer measurements taken at the same
6211      *                       position with zero velocity and unknown different
6212      *                       orientations.
6213      * @param commonAxisUsed indicates whether z-axis is assumed to be common
6214      *                       for the accelerometer, gyroscope and magnetometer.
6215      * @param listener       listener to handle events raised by this calibrator.
6216      * @return a robust magnetometer calibrator.
6217      */
6218     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6219             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6220             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6221         return create(measurements, commonAxisUsed, listener, DEFAULT_ROBUST_METHOD);
6222     }
6223 
6224     /**
6225      * Creates a robust magnetometer calibrator with default robust method.
6226      *
6227      * @param measurements    collection of body magnetic flux density
6228      *                        measurements with standard deviation of
6229      *                        magnetometer measurements taken at the same
6230      *                        position with zero velocity and unknown different
6231      *                        orientations.
6232      * @param initialHardIron initial hard-iron to find a solution.
6233      * @return a robust magnetometer calibrator.
6234      * @throws IllegalArgumentException if provided hard-iron array does
6235      *                                  not have length 3.
6236      */
6237     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6238             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron) {
6239         return create(measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
6240     }
6241 
6242     /**
6243      * Creates a robust magnetometer calibrator with default robust method.
6244      *
6245      * @param measurements    collection of body magnetic flux density
6246      *                        measurements with standard deviation of
6247      *                        magnetometer measurements taken at the same
6248      *                        position with zero velocity and unknown different
6249      *                        orientations.
6250      * @param initialHardIron initial hard-iron to find a solution.
6251      * @param listener        listener to handle events raised by this calibrator.
6252      * @return a robust magnetometer calibrator.
6253      * @throws IllegalArgumentException if provided hard-iron array does
6254      *                                  not have length 3.
6255      */
6256     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6257             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
6258             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6259         return create(measurements, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
6260     }
6261 
6262     /**
6263      * Creates a robust magnetometer calibrator with default robust method.
6264      *
6265      * @param measurements    collection of body magnetic flux density
6266      *                        measurements with standard deviation of
6267      *                        magnetometer measurements taken at the same
6268      *                        position with zero velocity and unknown different
6269      *                        orientations.
6270      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6271      *                        for the accelerometer, gyroscope and magnetometer.
6272      * @param initialHardIron initial hard-iron to find a solution.
6273      * @return a robust magnetometer calibrator.
6274      * @throws IllegalArgumentException if provided hard-iron array does
6275      *                                  not have length 3.
6276      */
6277     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6278             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6279             final double[] initialHardIron) {
6280         return create(measurements, commonAxisUsed, initialHardIron, DEFAULT_ROBUST_METHOD);
6281     }
6282 
6283     /**
6284      * Creates a robust magnetometer calibrator with default robust method.
6285      *
6286      * @param measurements    collection of body magnetic flux density
6287      *                        measurements with standard deviation of
6288      *                        magnetometer measurements taken at the same
6289      *                        position with zero velocity and unknown different
6290      *                        orientations.
6291      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6292      *                        for the accelerometer, gyroscope and magnetometer.
6293      * @param initialHardIron initial hard-iron to find a solution.
6294      * @param listener        listener to handle events raised by this calibrator.
6295      * @return a robust magnetometer calibrator.
6296      */
6297     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6298             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6299             final double[] initialHardIron,
6300             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6301         return create(measurements, commonAxisUsed, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
6302     }
6303 
6304     /**
6305      * Creates a robust magnetometer calibrator with default robust method.
6306      *
6307      * @param measurements    collection of body magnetic flux density
6308      *                        measurements with standard deviation of
6309      *                        magnetometer measurements taken at the same
6310      *                        position with zero velocity and unknown different
6311      *                        orientations.
6312      * @param initialHardIron initial hard-iron to find a solution.
6313      * @return a robust magnetometer calibrator.
6314      * @throws IllegalArgumentException if provided hard-iron matrix is not
6315      *                                  3x1.
6316      */
6317     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6318             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron) {
6319         return create(measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
6320     }
6321 
6322     /**
6323      * Creates a robust magnetometer calibrator with default robust method.
6324      *
6325      * @param measurements    collection of body magnetic flux density
6326      *                        measurements with standard deviation of
6327      *                        magnetometer measurements taken at the same
6328      *                        position with zero velocity and unknown different
6329      *                        orientations.
6330      * @param initialHardIron initial hard-iron to find a solution.
6331      * @param listener        listener to handle events raised by this calibrator.
6332      * @return a robust magnetometer calibrator.
6333      * @throws IllegalArgumentException if provided hard-iron matrix is not
6334      *                                  3x1.
6335      */
6336     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6337             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6338             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6339         return create(measurements, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
6340     }
6341 
6342     /**
6343      * Creates a robust magnetometer calibrator with default robust method.
6344      *
6345      * @param measurements    collection of body magnetic flux density
6346      *                        measurements with standard deviation of
6347      *                        magnetometer measurements taken at the same
6348      *                        position with zero velocity and unknown different
6349      *                        orientations.
6350      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6351      *                        for the accelerometer, gyroscope and magnetometer.
6352      * @param initialHardIron initial hard-iron to find a solution.
6353      * @return a robust magnetometer calibrator.
6354      * @throws IllegalArgumentException if provided hard-iron matrix is not
6355      *                                  3x1.
6356      */
6357     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6358             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6359             final Matrix initialHardIron) {
6360         return create(measurements, commonAxisUsed, initialHardIron, DEFAULT_ROBUST_METHOD);
6361     }
6362 
6363     /**
6364      * Creates a robust magnetometer calibrator with default robust method.
6365      *
6366      * @param measurements    collection of body magnetic flux density
6367      *                        measurements with standard deviation of
6368      *                        magnetometer measurements taken at the same
6369      *                        position with zero velocity and unknown different
6370      *                        orientations.
6371      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6372      *                        for the accelerometer, gyroscope and magnetometer.
6373      * @param initialHardIron initial hard-iron to find a solution.
6374      * @param listener        listener to handle events raised by this calibrator.
6375      * @return a robust magnetometer calibrator.
6376      * @throws IllegalArgumentException if provided hard-iron matrix is not
6377      *                                  3x1.
6378      */
6379     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6380             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6381             final Matrix initialHardIron,
6382             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6383         return create(measurements, commonAxisUsed, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
6384     }
6385 
6386     /**
6387      * Creates a robust magnetometer calibrator with default robust method.
6388      *
6389      * @param measurements    collection of body magnetic flux density
6390      *                        measurements with standard deviation of
6391      *                        magnetometer measurements taken at the same
6392      *                        position with zero velocity and unknown different
6393      *                        orientations.
6394      * @param initialHardIron initial hard-iron to find a solution.
6395      * @param initialMm       initial soft-iron matrix containing scale factors
6396      *                        and cross coupling errors.
6397      * @return a robust magnetometer calibrator.
6398      * @throws IllegalArgumentException if provided hard-iron matrix is not
6399      *                                  3x1 or if soft-iron matrix is not
6400      *                                  3x3.
6401      */
6402     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6403             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6404             final Matrix initialMm) {
6405         return create(measurements, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
6406     }
6407 
6408     /**
6409      * Creates a robust magnetometer calibrator with default robust method.
6410      *
6411      * @param measurements    collection of body magnetic flux density
6412      *                        measurements with standard deviation of
6413      *                        magnetometer measurements taken at the same
6414      *                        position with zero velocity and unknown different
6415      *                        orientations.
6416      * @param initialHardIron initial hard-iron to find a solution.
6417      * @param initialMm       initial soft-iron matrix containing scale factors
6418      *                        and cross coupling errors.
6419      * @param listener        listener to handle events raised by this calibrator.
6420      * @return a robust magnetometer calibrator.
6421      * @throws IllegalArgumentException if provided hard-iron matrix is not
6422      *                                  3x1 or if soft-iron matrix is not
6423      *                                  3x3.
6424      */
6425     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6426             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6427             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6428         return create(measurements, initialHardIron, initialMm, listener, DEFAULT_ROBUST_METHOD);
6429     }
6430 
6431     /**
6432      * Creates a robust magnetometer calibrator with default robust method.
6433      *
6434      * @param measurements    collection of body magnetic flux density
6435      *                        measurements with standard deviation of
6436      *                        magnetometer measurements taken at the same
6437      *                        position with zero velocity and unknown different
6438      *                        orientations.
6439      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6440      *                        for the accelerometer, gyroscope and magnetometer.
6441      * @param initialHardIron initial hard-iron to find a solution.
6442      * @param initialMm       initial soft-iron matrix containing scale factors
6443      *                        and cross coupling errors.
6444      * @return a robust magnetometer calibrator.
6445      * @throws IllegalArgumentException if provided hard-iron matrix is not
6446      *                                  3x1 or if soft-iron matrix is not
6447      *                                  3x3.
6448      */
6449     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6450             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6451             final Matrix initialHardIron, final Matrix initialMm) {
6452         return create(measurements, commonAxisUsed, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
6453     }
6454 
6455     /**
6456      * Creates a robust magnetometer calibrator with default robust method.
6457      *
6458      * @param measurements    collection of body magnetic flux density
6459      *                        measurements with standard deviation of
6460      *                        magnetometer measurements taken at the same
6461      *                        position with zero velocity and unknown different
6462      *                        orientations.
6463      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
6464      *                        for the accelerometer, gyroscope and magnetometer.
6465      * @param initialHardIron initial hard-iron to find a solution.
6466      * @param initialMm       initial soft-iron matrix containing scale factors
6467      *                        and cross coupling errors.
6468      * @param listener        listener to handle events raised by this calibrator.
6469      * @return a robust magnetometer calibrator.
6470      * @throws IllegalArgumentException if provided hard-iron matrix is not
6471      *                                  3x1 or if soft-iron matrix is not
6472      *                                  3x3.
6473      */
6474     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6475             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
6476             final boolean commonAxisUsed, final Matrix initialHardIron, final Matrix initialMm,
6477             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6478         return create(measurements, commonAxisUsed, initialHardIron, initialMm, listener, DEFAULT_ROBUST_METHOD);
6479     }
6480 
6481     /**
6482      * Creates a robust magnetometer calibrator with default robust method.
6483      *
6484      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6485      * @return a robust magnetometer calibrator.
6486      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6487      */
6488     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6489             final Double groundTruthMagneticFluxDensityNorm) {
6490         return create(groundTruthMagneticFluxDensityNorm, DEFAULT_ROBUST_METHOD);
6491     }
6492 
6493     /**
6494      * Creates a robust magnetometer calibrator with default robust method.
6495      *
6496      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6497      * @param listener                           listener to handle events raised by this calibrator.
6498      * @return a robust magnetometer calibrator.
6499      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6500      */
6501     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6502             final Double groundTruthMagneticFluxDensityNorm,
6503             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6504         return create(groundTruthMagneticFluxDensityNorm, listener, DEFAULT_ROBUST_METHOD);
6505     }
6506 
6507     /**
6508      * Creates a robust magnetometer calibrator with default robust method.
6509      *
6510      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6511      * @param measurements                       collection of body magnetic flux density
6512      *                                           measurements with standard deviation of
6513      *                                           magnetometer measurements taken at the same
6514      *                                           position with zero velocity and unknown different
6515      *                                           orientations.
6516      * @return a robust magnetometer calibrator.
6517      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6518      */
6519     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6520             final Double groundTruthMagneticFluxDensityNorm,
6521             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
6522         return create(groundTruthMagneticFluxDensityNorm, measurements, DEFAULT_ROBUST_METHOD);
6523     }
6524 
6525     /**
6526      * Creates a robust magnetometer calibrator with default robust method.
6527      *
6528      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6529      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6530      *                                           for the accelerometer, gyroscope and magnetometer.
6531      * @return a robust magnetometer calibrator.
6532      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6533      */
6534     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6535             final Double groundTruthMagneticFluxDensityNorm, final boolean commonAxisUsed) {
6536         return create(groundTruthMagneticFluxDensityNorm, commonAxisUsed, DEFAULT_ROBUST_METHOD);
6537     }
6538 
6539     /**
6540      * Creates a robust magnetometer calibrator with default robust method.
6541      *
6542      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6543      * @param initialHardIron                    initial hard-iron to find a solution.
6544      * @return a robust magnetometer calibrator.
6545      * @throws IllegalArgumentException if provided magnetic flux norm value is
6546      *                                  negative, or if provided hard-iron array does
6547      *                                  not have length 3.
6548      */
6549     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6550             final Double groundTruthMagneticFluxDensityNorm, final double[] initialHardIron) {
6551         return create(groundTruthMagneticFluxDensityNorm, initialHardIron, DEFAULT_ROBUST_METHOD);
6552     }
6553 
6554     /**
6555      * Creates a robust magnetometer calibrator with default robust method.
6556      *
6557      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6558      * @param initialHardIron                    initial hard-iron to find a solution.
6559      * @return a robust magnetometer calibrator.
6560      * @throws IllegalArgumentException if provided magnetic flux norm value is
6561      *                                  negative, or if provided hard-iron matrix is not
6562      *                                  3x1.
6563      */
6564     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6565             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron) {
6566         return create(groundTruthMagneticFluxDensityNorm, initialHardIron, DEFAULT_ROBUST_METHOD);
6567     }
6568 
6569     /**
6570      * Creates a robust magnetometer calibrator with default robust method.
6571      *
6572      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6573      * @param initialHardIron                    initial hard-iron to find a solution.
6574      * @param initialMm                          initial soft-iron matrix containing scale factors
6575      *                                           and cross coupling errors.
6576      * @return a robust magnetometer calibrator.
6577      * @throws IllegalArgumentException if provided magnetic flux norm value is
6578      *                                  negative, or if provided hard-iron matrix is not
6579      *                                  3x1 or if soft-iron matrix is not
6580      *                                  3x3.
6581      */
6582     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6583             final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron, final Matrix initialMm) {
6584         return create(groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
6585     }
6586 
6587     /**
6588      * Creates a robust magnetometer calibrator with default robust method.
6589      *
6590      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6591      * @param measurements                       collection of body magnetic flux density
6592      *                                           measurements with standard deviation of
6593      *                                           magnetometer measurements taken at the same
6594      *                                           position with zero velocity and unknown different
6595      *                                           orientations.
6596      * @param listener                           listener to handle events raised by this calibrator.
6597      * @return a robust magnetometer calibrator.
6598      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6599      */
6600     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6601             final Double groundTruthMagneticFluxDensityNorm,
6602             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
6603             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6604         return create(groundTruthMagneticFluxDensityNorm, measurements, listener, DEFAULT_ROBUST_METHOD);
6605     }
6606 
6607     /**
6608      * Creates a robust magnetometer calibrator with default robust method.
6609      *
6610      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6611      * @param measurements                       collection of body magnetic flux density
6612      *                                           measurements with standard deviation of
6613      *                                           magnetometer measurements taken at the same
6614      *                                           position with zero velocity and unknown different
6615      *                                           orientations.
6616      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6617      *                                           for the accelerometer, gyroscope and magnetometer.
6618      * @return a robust magnetometer calibrator.
6619      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6620      */
6621     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6622             final Double groundTruthMagneticFluxDensityNorm,
6623             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
6624         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, DEFAULT_ROBUST_METHOD);
6625     }
6626 
6627     /**
6628      * Creates a robust magnetometer calibrator with default robust method.
6629      *
6630      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6631      * @param measurements                       collection of body magnetic flux density
6632      *                                           measurements with standard deviation of
6633      *                                           magnetometer measurements taken at the same
6634      *                                           position with zero velocity and unknown different
6635      *                                           orientations.
6636      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6637      *                                           for the accelerometer, gyroscope and magnetometer.
6638      * @param listener                           listener to handle events raised by this calibrator.
6639      * @return a robust magnetometer calibrator.
6640      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
6641      */
6642     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6643             final Double groundTruthMagneticFluxDensityNorm,
6644             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6645             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6646         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener,
6647                 DEFAULT_ROBUST_METHOD);
6648     }
6649 
6650     /**
6651      * Creates a robust magnetometer calibrator with default robust method.
6652      *
6653      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6654      * @param measurements                       collection of body magnetic flux density
6655      *                                           measurements with standard deviation of
6656      *                                           magnetometer measurements taken at the same
6657      *                                           position with zero velocity and unknown different
6658      *                                           orientations.
6659      * @param initialHardIron                    initial hard-iron to find a solution.
6660      * @return a robust magnetometer calibrator.
6661      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6662      *                                  or if provided hard-iron array does not have length 3.
6663      */
6664     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6665             final Double groundTruthMagneticFluxDensityNorm,
6666             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron) {
6667         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
6668     }
6669 
6670     /**
6671      * Creates a robust magnetometer calibrator with default robust method.
6672      *
6673      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6674      * @param measurements                       collection of body magnetic flux density
6675      *                                           measurements with standard deviation of
6676      *                                           magnetometer measurements taken at the same
6677      *                                           position with zero velocity and unknown different
6678      *                                           orientations.
6679      * @param initialHardIron                    initial hard-iron to find a solution.
6680      * @param listener                           listener to handle events raised by this calibrator.
6681      * @return a robust magnetometer calibrator.
6682      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6683      *                                  or if provided hard-iron array does not have length 3.
6684      */
6685     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6686             final Double groundTruthMagneticFluxDensityNorm,
6687             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
6688             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6689         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener,
6690                 DEFAULT_ROBUST_METHOD);
6691     }
6692 
6693     /**
6694      * Creates a robust magnetometer calibrator with default robust method.
6695      *
6696      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6697      * @param measurements                       collection of body magnetic flux density
6698      *                                           measurements with standard deviation of
6699      *                                           magnetometer measurements taken at the same
6700      *                                           position with zero velocity and unknown different
6701      *                                           orientations.
6702      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6703      *                                           for the accelerometer, gyroscope and magnetometer.
6704      * @param initialHardIron                    initial hard-iron to find a solution.
6705      * @return a robust magnetometer calibrator.
6706      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6707      *                                  or if provided hard-iron array does not have length 3.
6708      */
6709     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6710             final Double groundTruthMagneticFluxDensityNorm,
6711             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6712             final double[] initialHardIron) {
6713         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6714                 DEFAULT_ROBUST_METHOD);
6715     }
6716 
6717     /**
6718      * Creates a robust magnetometer calibrator with default robust method.
6719      *
6720      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6721      * @param measurements                       collection of body magnetic flux density
6722      *                                           measurements with standard deviation of
6723      *                                           magnetometer measurements taken at the same
6724      *                                           position with zero velocity and unknown different
6725      *                                           orientations.
6726      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6727      *                                           for the accelerometer, gyroscope and magnetometer.
6728      * @param initialHardIron                    initial hard-iron to find a solution.
6729      * @param listener                           listener to handle events raised by this calibrator.
6730      * @return a robust magnetometer calibrator.
6731      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6732      *                                  or if provided hard-iron array does not have length 3.
6733      */
6734     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6735             final Double groundTruthMagneticFluxDensityNorm,
6736             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6737             final double[] initialHardIron,
6738             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6739         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener,
6740                 DEFAULT_ROBUST_METHOD);
6741     }
6742 
6743     /**
6744      * Creates a robust magnetometer calibrator with default robust method.
6745      *
6746      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6747      * @param measurements                       collection of body magnetic flux density
6748      *                                           measurements with standard deviation of
6749      *                                           magnetometer measurements taken at the same
6750      *                                           position with zero velocity and unknown different
6751      *                                           orientations.
6752      * @param initialHardIron                    initial hard-iron to find a solution.
6753      * @return a robust magnetometer calibrator.
6754      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6755      *                                  or if provided hard-iron matrix is not 3x1.
6756      */
6757     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6758             final Double groundTruthMagneticFluxDensityNorm,
6759             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron) {
6760         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
6761     }
6762 
6763     /**
6764      * Creates a robust magnetometer calibrator with default robust method.
6765      *
6766      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6767      * @param measurements                       collection of body magnetic flux density
6768      *                                           measurements with standard deviation of
6769      *                                           magnetometer measurements taken at the same
6770      *                                           position with zero velocity and unknown different
6771      *                                           orientations.
6772      * @param initialHardIron                    initial hard-iron to find a solution.
6773      * @param listener                           listener to handle events raised by this calibrator.
6774      * @return a robust magnetometer calibrator.
6775      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6776      *                                  or if provided hard-iron matrix is not 3x1.
6777      */
6778     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6779             final Double groundTruthMagneticFluxDensityNorm,
6780             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6781             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6782         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener,
6783                 DEFAULT_ROBUST_METHOD);
6784     }
6785 
6786     /**
6787      * Creates a robust magnetometer calibrator with default robust method.
6788      *
6789      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6790      * @param measurements                       collection of body magnetic flux density
6791      *                                           measurements with standard deviation of
6792      *                                           magnetometer measurements taken at the same
6793      *                                           position with zero velocity and unknown different
6794      *                                           orientations.
6795      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6796      *                                           for the accelerometer, gyroscope and magnetometer.
6797      * @param initialHardIron                    initial hard-iron to find a solution.
6798      * @return a robust magnetometer calibrator.
6799      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6800      *                                  or if provided hard-iron matrix is not 3x1.
6801      */
6802     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6803             final Double groundTruthMagneticFluxDensityNorm,
6804             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6805             final Matrix initialHardIron) {
6806         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
6807                 DEFAULT_ROBUST_METHOD);
6808     }
6809 
6810     /**
6811      * Creates a robust magnetometer calibrator with default robust method.
6812      *
6813      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6814      * @param measurements                       collection of body magnetic flux density
6815      *                                           measurements with standard deviation of
6816      *                                           magnetometer measurements taken at the same
6817      *                                           position with zero velocity and unknown different
6818      *                                           orientations.
6819      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6820      *                                           for the accelerometer, gyroscope and magnetometer.
6821      * @param initialHardIron                    initial hard-iron to find a solution.
6822      * @param listener                           listener to handle events raised by this calibrator.
6823      * @return a robust magnetometer calibrator.
6824      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6825      *                                  or if provided hard-iron matrix is not 3x1.
6826      */
6827     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6828             final Double groundTruthMagneticFluxDensityNorm,
6829             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6830             final Matrix initialHardIron,
6831             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6832         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, listener,
6833                 DEFAULT_ROBUST_METHOD);
6834     }
6835 
6836     /**
6837      * Creates a robust magnetometer calibrator with default robust method.
6838      *
6839      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6840      * @param measurements                       collection of body magnetic flux density
6841      *                                           measurements with standard deviation of
6842      *                                           magnetometer measurements taken at the same
6843      *                                           position with zero velocity and unknown different
6844      *                                           orientations.
6845      * @param initialHardIron                    initial hard-iron to find a solution.
6846      * @param initialMm                          initial soft-iron matrix containing scale factors
6847      *                                           and cross coupling errors.
6848      * @return a robust magnetometer calibrator.
6849      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6850      *                                  or if provided hard-iron matrix is not 3x1 or if
6851      *                                  soft-iron matrix is not 3x3.
6852      */
6853     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6854             final Double groundTruthMagneticFluxDensityNorm,
6855             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6856             final Matrix initialMm) {
6857         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm,
6858                 DEFAULT_ROBUST_METHOD);
6859     }
6860 
6861     /**
6862      * Creates a robust magnetometer calibrator with default robust method.
6863      *
6864      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6865      * @param measurements                       collection of body magnetic flux density
6866      *                                           measurements with standard deviation of
6867      *                                           magnetometer measurements taken at the same
6868      *                                           position with zero velocity and unknown different
6869      *                                           orientations.
6870      * @param initialHardIron                    initial hard-iron to find a solution.
6871      * @param initialMm                          initial soft-iron matrix containing scale factors
6872      *                                           and cross coupling errors.
6873      * @param listener                           listener to handle events raised by this calibrator.
6874      * @return a robust magnetometer calibrator.
6875      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6876      *                                  or if provided hard-iron matrix is not 3x1 or if
6877      *                                  soft-iron matrix is not 3x3.
6878      */
6879     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6880             final Double groundTruthMagneticFluxDensityNorm,
6881             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
6882             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6883         return create(groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm, listener,
6884                 DEFAULT_ROBUST_METHOD);
6885     }
6886 
6887     /**
6888      * Creates a robust magnetometer calibrator with default robust method.
6889      *
6890      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6891      * @param measurements                       collection of body magnetic flux density
6892      *                                           measurements with standard deviation of
6893      *                                           magnetometer measurements taken at the same
6894      *                                           position with zero velocity and unknown different
6895      *                                           orientations.
6896      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6897      *                                           for the accelerometer, gyroscope and magnetometer.
6898      * @param initialHardIron                    initial hard-iron to find a solution.
6899      * @param initialMm                          initial soft-iron matrix containing scale factors
6900      *                                           and cross coupling errors.
6901      * @return a robust magnetometer calibrator.
6902      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6903      *                                  or if provided hard-iron matrix is not 3x1
6904      *                                  or if soft-iron matrix is not 3x3.
6905      */
6906     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6907             final Double groundTruthMagneticFluxDensityNorm,
6908             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6909             final Matrix initialHardIron, final Matrix initialMm) {
6910         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
6911                 DEFAULT_ROBUST_METHOD);
6912     }
6913 
6914     /**
6915      * Creates a robust magnetometer calibrator with default robust method.
6916      *
6917      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
6918      * @param measurements                       collection of body magnetic flux density
6919      *                                           measurements with standard deviation of
6920      *                                           magnetometer measurements taken at the same
6921      *                                           position with zero velocity and unknown different
6922      *                                           orientations.
6923      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
6924      *                                           for the accelerometer, gyroscope and magnetometer.
6925      * @param initialHardIron                    initial hard-iron to find a solution.
6926      * @param initialMm                          initial soft-iron matrix containing scale factors
6927      *                                           and cross coupling errors.
6928      * @param listener                           listener to handle events raised by this calibrator.
6929      * @return a robust magnetometer calibrator.
6930      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
6931      *                                  or if provided hard-iron matrix is not 3x1
6932      *                                  or if soft-iron matrix is not 3x3.
6933      */
6934     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6935             final Double groundTruthMagneticFluxDensityNorm,
6936             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
6937             final Matrix initialHardIron, final Matrix initialMm,
6938             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
6939         return create(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron, initialMm,
6940                 listener, DEFAULT_ROBUST_METHOD);
6941     }
6942 
6943     /**
6944      * Creates a robust magnetometer calibrator with default robust method.
6945      *
6946      * @param qualityScores quality scores corresponding to each provided
6947      *                      measurement. The larger the score value the better
6948      *                      the quality of the sample.
6949      * @param measurements  list of body magnetic flux density
6950      *                      measurements with standard deviation of
6951      *                      magnetometer measurements taken at the same
6952      *                      position with zero velocity and unknown different
6953      *                      orientations.
6954      * @return a robust magnetometer calibrator.
6955      * @throws IllegalArgumentException if provided quality scores length
6956      *                                  is smaller than 10 samples.
6957      */
6958     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6959             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
6960         return create(qualityScores, measurements, DEFAULT_ROBUST_METHOD);
6961     }
6962 
6963     /**
6964      * Creates a robust magnetometer calibrator with default robust method.
6965      *
6966      * @param qualityScores  quality scores corresponding to each provided
6967      *                       measurement. The larger the score value the better
6968      *                       the quality of the sample.
6969      * @param commonAxisUsed indicates whether z-axis is assumed to be common
6970      *                       for the accelerometer, gyroscope and magnetometer.
6971      * @return a robust magnetometer calibrator.
6972      * @throws IllegalArgumentException if provided quality scores length
6973      *                                  is smaller than 10 samples.
6974      */
6975     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6976             final double[] qualityScores, final boolean commonAxisUsed) {
6977         return create(qualityScores, commonAxisUsed, DEFAULT_ROBUST_METHOD);
6978     }
6979 
6980     /**
6981      * Creates a robust magnetometer calibrator with default robust method.
6982      *
6983      * @param qualityScores   quality scores corresponding to each provided
6984      *                        measurement. The larger the score value the better
6985      *                        the quality of the sample.
6986      * @param initialHardIron initial hard-iron to find a solution.
6987      * @return a robust magnetometer calibrator.
6988      * @throws IllegalArgumentException if provided hard-iron array does
6989      *                                  not have length 3 or if provided
6990      *                                  quality scores length is smaller
6991      *                                  than 10 samples.
6992      */
6993     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
6994             final double[] qualityScores, final double[] initialHardIron) {
6995         return create(qualityScores, initialHardIron, DEFAULT_ROBUST_METHOD);
6996     }
6997 
6998     /**
6999      * Creates a robust magnetometer calibrator with default robust method.
7000      *
7001      * @param qualityScores   quality scores corresponding to each provided
7002      *                        measurement. The larger the score value the better
7003      *                        the quality of the sample.
7004      * @param initialHardIron initial hard-iron to find a solution.
7005      * @return a robust magnetometer calibrator.
7006      * @throws IllegalArgumentException if provided hard-iron matrix is not
7007      *                                  3x1 or if provided quality scores
7008      *                                  length is smaller than 10 samples.
7009      */
7010     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7011             final double[] qualityScores, final Matrix initialHardIron) {
7012         return create(qualityScores, initialHardIron, DEFAULT_ROBUST_METHOD);
7013     }
7014 
7015     /**
7016      * Creates a robust magnetometer calibrator with default robust method.
7017      *
7018      * @param qualityScores   quality scores corresponding to each provided
7019      *                        measurement. The larger the score value the better
7020      *                        the quality of the sample.
7021      * @param initialHardIron initial hard-iron to find a solution.
7022      * @param initialMm       initial soft-iron matrix containing scale factors
7023      *                        and cross coupling errors.
7024      * @return a robust magnetometer calibrator.
7025      * @throws IllegalArgumentException if provided hard-iron matrix is not
7026      *                                  3x1 or if soft-iron matrix is not
7027      *                                  3x3 or if provided quality scores
7028      *                                  length is smaller than 10 samples.
7029      */
7030     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7031             final double[] qualityScores, final Matrix initialHardIron, final Matrix initialMm) {
7032         return create(qualityScores, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
7033     }
7034 
7035     /**
7036      * Creates a robust magnetometer calibrator with default robust method.
7037      *
7038      * @param qualityScores quality scores corresponding to each provided
7039      *                      measurement. The larger the score value the better
7040      *                      the quality of the sample.
7041      * @param measurements  list of body magnetic flux density
7042      *                      measurements with standard deviation of
7043      *                      magnetometer measurements taken at the same
7044      *                      position with zero velocity and unknown different
7045      *                      orientations.
7046      * @param listener      listener to handle events raised by this calibrator.
7047      * @return a robust magnetometer calibrator.
7048      * @throws IllegalArgumentException if provided quality scores length
7049      *                                  is smaller than 10 samples.
7050      */
7051     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7052             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7053             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7054         return create(qualityScores, measurements, listener, DEFAULT_ROBUST_METHOD);
7055     }
7056 
7057     /**
7058      * Creates a robust magnetometer calibrator with default robust method.
7059      *
7060      * @param qualityScores  quality scores corresponding to each provided
7061      *                       measurement. The larger the score value the better
7062      *                       the quality of the sample.
7063      * @param measurements   collection of body magnetic flux density
7064      *                       measurements with standard deviation of
7065      *                       magnetometer measurements taken at the same
7066      *                       position with zero velocity and unknown different
7067      *                       orientations.
7068      * @param commonAxisUsed indicates whether z-axis is assumed to be common
7069      *                       for the accelerometer, gyroscope and magnetometer.
7070      * @return a robust magnetometer calibrator.
7071      * @throws IllegalArgumentException if provided quality scores length
7072      *                                  is smaller than 10 samples.
7073      */
7074     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7075             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7076             final boolean commonAxisUsed) {
7077         return create(qualityScores, measurements, commonAxisUsed, DEFAULT_ROBUST_METHOD);
7078     }
7079 
7080     /**
7081      * Creates a robust magnetometer calibrator with default robust method.
7082      *
7083      * @param qualityScores  quality scores corresponding to each provided
7084      *                       measurement. The larger the score value the better
7085      *                       the quality of the sample.
7086      * @param measurements   collection of body magnetic flux density
7087      *                       measurements with standard deviation of
7088      *                       magnetometer measurements taken at the same
7089      *                       position with zero velocity and unknown different
7090      *                       orientations.
7091      * @param commonAxisUsed indicates whether z-axis is assumed to be common
7092      *                       for the accelerometer, gyroscope and magnetometer.
7093      * @param listener       listener to handle events raised by this calibrator.
7094      * @return a robust magnetometer calibrator.
7095      * @throws IllegalArgumentException if provided quality scores length
7096      *                                  is smaller than 10 samples.
7097      */
7098     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7099             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7100             final boolean commonAxisUsed,
7101             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7102         return create(qualityScores, measurements, commonAxisUsed, listener, DEFAULT_ROBUST_METHOD);
7103     }
7104 
7105     /**
7106      * Creates a robust magnetometer calibrator with default robust method.
7107      *
7108      * @param qualityScores   quality scores corresponding to each provided
7109      *                        measurement. The larger the score value the better
7110      *                        the quality of the sample.
7111      * @param measurements    collection of body magnetic flux density
7112      *                        measurements with standard deviation of
7113      *                        magnetometer measurements taken at the same
7114      *                        position with zero velocity and unknown different
7115      *                        orientations.
7116      * @param initialHardIron initial hard-iron to find a solution.
7117      * @return a robust magnetometer calibrator.
7118      * @throws IllegalArgumentException if provided hard-iron array does
7119      *                                  not have length 3 or if provided quality
7120      *                                  scores length is smaller than 10 samples.
7121      */
7122     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7123             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7124             final double[] initialHardIron) {
7125         return create(qualityScores, measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
7126     }
7127 
7128     /**
7129      * Creates a robust magnetometer calibrator with default robust method.
7130      *
7131      * @param qualityScores   quality scores corresponding to each provided
7132      *                        measurement. The larger the score value the better
7133      *                        the quality of the sample.
7134      * @param measurements    collection of body magnetic flux density
7135      *                        measurements with standard deviation of
7136      *                        magnetometer measurements taken at the same
7137      *                        position with zero velocity and unknown different
7138      *                        orientations.
7139      * @param initialHardIron initial hard-iron to find a solution.
7140      * @param listener        listener to handle events raised by this calibrator.
7141      * @return a robust magnetometer calibrator.
7142      * @throws IllegalArgumentException if provided hard-iron array does
7143      *                                  not have length 3 or if provided quality
7144      *                                  scores length is smaller than 10 samples.
7145      */
7146     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7147             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7148             final double[] initialHardIron,
7149             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7150         return create(qualityScores, measurements, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
7151     }
7152 
7153     /**
7154      * Creates a robust magnetometer calibrator with default robust method.
7155      *
7156      * @param qualityScores   quality scores corresponding to each provided
7157      *                        measurement. The larger the score value the better
7158      *                        the quality of the sample.
7159      * @param measurements    collection of body magnetic flux density
7160      *                        measurements with standard deviation of
7161      *                        magnetometer measurements taken at the same
7162      *                        position with zero velocity and unknown different
7163      *                        orientations.
7164      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7165      *                        for the accelerometer, gyroscope and magnetometer.
7166      * @param initialHardIron initial hard-iron to find a solution.
7167      * @return a robust magnetometer calibrator.
7168      * @throws IllegalArgumentException if provided hard-iron array does
7169      *                                  not have length 3 or if provided quality
7170      *                                  scores length is smaller than 10 samples.
7171      */
7172     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7173             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7174             final boolean commonAxisUsed, final double[] initialHardIron) {
7175         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, DEFAULT_ROBUST_METHOD);
7176     }
7177 
7178     /**
7179      * Creates a robust magnetometer calibrator with default robust method.
7180      *
7181      * @param qualityScores   quality scores corresponding to each provided
7182      *                        measurement. The larger the score value the better
7183      *                        the quality of the sample.
7184      * @param measurements    collection of body magnetic flux density
7185      *                        measurements with standard deviation of
7186      *                        magnetometer measurements taken at the same
7187      *                        position with zero velocity and unknown different
7188      *                        orientations.
7189      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7190      *                        for the accelerometer, gyroscope and magnetometer.
7191      * @param initialHardIron initial hard-iron to find a solution.
7192      * @param listener        listener to handle events raised by this calibrator.
7193      * @return a robust magnetometer calibrator.
7194      * @throws IllegalArgumentException if provided hard-iron array does
7195      *                                  not have length 3 or if provided quality
7196      *                                  scores length is smaller than 10 samples.
7197      */
7198     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7199             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7200             final boolean commonAxisUsed, final double[] initialHardIron,
7201             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7202         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
7203     }
7204 
7205     /**
7206      * Creates a robust magnetometer calibrator with default robust method.
7207      *
7208      * @param qualityScores   quality scores corresponding to each provided
7209      *                        measurement. The larger the score value the better
7210      *                        the quality of the sample.
7211      * @param measurements    collection of body magnetic flux density
7212      *                        measurements with standard deviation of
7213      *                        magnetometer measurements taken at the same
7214      *                        position with zero velocity and unknown different
7215      *                        orientations.
7216      * @param initialHardIron initial hard-iron to find a solution.
7217      * @return a robust magnetometer calibrator.
7218      * @throws IllegalArgumentException if provided hard-iron matrix is not
7219      *                                  3x1 or if provided quality scores length
7220      *                                  is smaller than 10 samples.
7221      */
7222     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7223             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7224             final Matrix initialHardIron) {
7225         return create(qualityScores, measurements, initialHardIron, DEFAULT_ROBUST_METHOD);
7226     }
7227 
7228     /**
7229      * Creates a robust magnetometer calibrator with default robust method.
7230      *
7231      * @param qualityScores   quality scores corresponding to each provided
7232      *                        measurement. The larger the score value the better
7233      *                        the quality of the sample.
7234      * @param measurements    collection of body magnetic flux density
7235      *                        measurements with standard deviation of
7236      *                        magnetometer measurements taken at the same
7237      *                        position with zero velocity and unknown different
7238      *                        orientations.
7239      * @param initialHardIron initial hard-iron to find a solution.
7240      * @param listener        listener to handle events raised by this calibrator.
7241      * @return a robust magnetometer calibrator.
7242      * @throws IllegalArgumentException if provided hard-iron matrix is not
7243      *                                  3x1 or if provided quality scores length
7244      *                                  is smaller than 10 samples.
7245      */
7246     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7247             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7248             final Matrix initialHardIron,
7249             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7250         return create(qualityScores, measurements, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
7251     }
7252 
7253     /**
7254      * Creates a robust magnetometer calibrator with default robust method.
7255      *
7256      * @param qualityScores   quality scores corresponding to each provided
7257      *                        measurement. The larger the score value the better
7258      *                        the quality of the sample.
7259      * @param measurements    collection of body magnetic flux density
7260      *                        measurements with standard deviation of
7261      *                        magnetometer measurements taken at the same
7262      *                        position with zero velocity and unknown different
7263      *                        orientations.
7264      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7265      *                        for the accelerometer, gyroscope and magnetometer.
7266      * @param initialHardIron initial hard-iron to find a solution.
7267      * @return a robust magnetometer calibrator.
7268      * @throws IllegalArgumentException if provided hard-iron matrix is not
7269      *                                  3x1 or if provided quality scores length
7270      *                                  is smaller than 10 samples.
7271      */
7272     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7273             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7274             final boolean commonAxisUsed, final Matrix initialHardIron) {
7275         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, DEFAULT_ROBUST_METHOD);
7276     }
7277 
7278     /**
7279      * Creates a robust magnetometer calibrator with default robust method.
7280      *
7281      * @param qualityScores   quality scores corresponding to each provided
7282      *                        measurement. The larger the score value the better
7283      *                        the quality of the sample.
7284      * @param measurements    collection of body magnetic flux density
7285      *                        measurements with standard deviation of
7286      *                        magnetometer measurements taken at the same
7287      *                        position with zero velocity and unknown different
7288      *                        orientations.
7289      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7290      *                        for the accelerometer, gyroscope and magnetometer.
7291      * @param initialHardIron initial hard-iron to find a solution.
7292      * @param listener        listener to handle events raised by this calibrator.
7293      * @return a robust magnetometer calibrator.
7294      * @throws IllegalArgumentException if provided hard-iron matrix is not
7295      *                                  3x1 or if provided quality scores length
7296      *                                  is smaller than 10 samples.
7297      */
7298     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7299             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7300             final boolean commonAxisUsed, final Matrix initialHardIron,
7301             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7302         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, listener, DEFAULT_ROBUST_METHOD);
7303     }
7304 
7305     /**
7306      * Creates a robust magnetometer calibrator with default robust method.
7307      *
7308      * @param qualityScores   quality scores corresponding to each provided
7309      *                        measurement. The larger the score value the better
7310      *                        the quality of the sample.*
7311      * @param measurements    collection of body magnetic flux density
7312      *                        measurements with standard deviation of
7313      *                        magnetometer measurements taken at the same
7314      *                        position with zero velocity and unknown different
7315      *                        orientations.
7316      * @param initialHardIron initial hard-iron to find a solution.
7317      * @param initialMm       initial soft-iron matrix containing scale factors
7318      *                        and cross coupling errors.
7319      * @return a robust magnetometer calibrator.
7320      * @throws IllegalArgumentException if provided hard-iron matrix is not
7321      *                                  3x1 or if soft-iron matrix is not
7322      *                                  3x3 or if provided quality scores length
7323      *                                  is smaller than 10 samples.
7324      */
7325     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7326             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7327             final Matrix initialHardIron, final Matrix initialMm) {
7328         return create(qualityScores, measurements, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
7329     }
7330 
7331     /**
7332      * Creates a robust magnetometer calibrator with default robust method.
7333      *
7334      * @param qualityScores   quality scores corresponding to each provided
7335      *                        measurement. The larger the score value the better
7336      *                        the quality of the sample.
7337      * @param measurements    collection of body magnetic flux density
7338      *                        measurements with standard deviation of
7339      *                        magnetometer measurements taken at the same
7340      *                        position with zero velocity and unknown different
7341      *                        orientations.
7342      * @param initialHardIron initial hard-iron to find a solution.
7343      * @param initialMm       initial soft-iron matrix containing scale factors
7344      *                        and cross coupling errors.
7345      * @param listener        listener to handle events raised by this calibrator.
7346      * @return a robust magnetometer calibrator.
7347      * @throws IllegalArgumentException if provided hard-iron matrix is not
7348      *                                  3x1 or if soft-iron matrix is not
7349      *                                  3x3 or if provided quality scores length
7350      *                                  is smaller than 10 samples.
7351      */
7352     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7353             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7354             final Matrix initialHardIron, final Matrix initialMm,
7355             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7356         return create(qualityScores, measurements, initialHardIron, initialMm, listener, DEFAULT_ROBUST_METHOD);
7357     }
7358 
7359     /**
7360      * Creates a robust magnetometer calibrator with default robust method.
7361      *
7362      * @param qualityScores   quality scores corresponding to each provided
7363      *                        measurement. The larger the score value the better
7364      *                        the quality of the sample.
7365      * @param measurements    collection of body magnetic flux density
7366      *                        measurements with standard deviation of
7367      *                        magnetometer measurements taken at the same
7368      *                        position with zero velocity and unknown different
7369      *                        orientations.
7370      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7371      *                        for the accelerometer, gyroscope and magnetometer.
7372      * @param initialHardIron initial hard-iron to find a solution.
7373      * @param initialMm       initial soft-iron matrix containing scale factors
7374      *                        and cross coupling errors.
7375      * @return a robust magnetometer calibrator.
7376      * @throws IllegalArgumentException if provided hard-iron matrix is not
7377      *                                  3x1 or if soft-iron matrix is not
7378      *                                  3x3 or if provided quality scores length
7379      *                                  is smaller than 10 samples.
7380      */
7381     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7382             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7383             final boolean commonAxisUsed, final Matrix initialHardIron, final Matrix initialMm) {
7384         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm, DEFAULT_ROBUST_METHOD);
7385     }
7386 
7387     /**
7388      * Creates a robust magnetometer calibrator with default robust method.
7389      *
7390      * @param qualityScores   quality scores corresponding to each provided
7391      *                        measurement. The larger the score value the better
7392      *                        the quality of the sample.
7393      * @param measurements    collection of body magnetic flux density
7394      *                        measurements with standard deviation of
7395      *                        magnetometer measurements taken at the same
7396      *                        position with zero velocity and unknown different
7397      *                        orientations.
7398      * @param commonAxisUsed  indicates whether z-axis is assumed to be common
7399      *                        for the accelerometer, gyroscope and magnetometer.
7400      * @param initialHardIron initial hard-iron to find a solution.
7401      * @param initialMm       initial soft-iron matrix containing scale factors
7402      *                        and cross coupling errors.
7403      * @param listener        listener to handle events raised by this calibrator.
7404      * @return a robust magnetometer calibrator.
7405      * @throws IllegalArgumentException if provided hard-iron matrix is not
7406      *                                  3x1 or if soft-iron matrix is not
7407      *                                  3x3 or if provided quality scores length
7408      *                                  is smaller than 10 samples.
7409      */
7410     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7411             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7412             final boolean commonAxisUsed, final Matrix initialHardIron, final Matrix initialMm,
7413             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7414         return create(qualityScores, measurements, commonAxisUsed, initialHardIron, initialMm, listener,
7415                 DEFAULT_ROBUST_METHOD);
7416     }
7417 
7418     /**
7419      * Creates a robust magnetometer calibrator with default robust method.
7420      *
7421      * @param qualityScores                      quality scores corresponding to each provided
7422      *                                           measurement. The larger the score value the better
7423      *                                           the quality of the sample.
7424      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7425      * @return a robust magnetometer calibrator.
7426      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7427      *                                  or if provided quality scores length is smaller
7428      *                                  than 10 samples.
7429      */
7430     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7431             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm) {
7432         return create(qualityScores, groundTruthMagneticFluxDensityNorm, DEFAULT_ROBUST_METHOD);
7433     }
7434 
7435     /**
7436      * Creates a robust magnetometer calibrator with default robust method.
7437      *
7438      * @param qualityScores                      quality scores corresponding to each provided
7439      *                                           measurement. The larger the score value the better
7440      *                                           the quality of the sample.
7441      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7442      * @param listener                           listener to handle events raised by this calibrator.
7443      * @return a robust magnetometer calibrator.
7444      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7445      *                                  or if provided quality scores length is smaller
7446      *                                  than 10 samples.
7447      */
7448     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7449             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7450             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7451         return create(qualityScores, groundTruthMagneticFluxDensityNorm, listener, DEFAULT_ROBUST_METHOD);
7452     }
7453 
7454     /**
7455      * Creates a robust magnetometer calibrator with default robust method.
7456      *
7457      * @param qualityScores                      quality scores corresponding to each provided
7458      *                                           measurement. The larger the score value the better
7459      *                                           the quality of the sample.
7460      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7461      * @param measurements                       collection of body magnetic flux density
7462      *                                           measurements with standard deviation of
7463      *                                           magnetometer measurements taken at the same
7464      *                                           position with zero velocity and unknown different
7465      *                                           orientations.
7466      * @return a robust magnetometer calibrator.
7467      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7468      *                                  or if provided quality scores length is smaller
7469      *                                  than 10 samples.
7470      */
7471     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7472             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7473             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
7474         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, DEFAULT_ROBUST_METHOD);
7475     }
7476 
7477     /**
7478      * Creates a robust magnetometer calibrator with default robust method.
7479      *
7480      * @param qualityScores                      quality scores corresponding to each provided
7481      *                                           measurement. The larger the score value the better
7482      *                                           the quality of the sample.
7483      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7484      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7485      *                                           for the accelerometer, gyroscope and magnetometer.
7486      * @return a robust magnetometer calibrator.
7487      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7488      *                                  or if provided quality scores length is smaller
7489      *                                  than 10 samples.
7490      */
7491     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7492             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7493             final boolean commonAxisUsed) {
7494         return create(qualityScores, groundTruthMagneticFluxDensityNorm, commonAxisUsed, DEFAULT_ROBUST_METHOD);
7495     }
7496 
7497     /**
7498      * Creates a robust magnetometer calibrator with default robust method.
7499      *
7500      * @param qualityScores                      quality scores corresponding to each provided
7501      *                                           measurement. The larger the score value the better
7502      *                                           the quality of the sample.
7503      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7504      * @param initialHardIron                    initial hard-iron to find a solution.
7505      * @return a robust magnetometer calibrator.
7506      * @throws IllegalArgumentException if provided magnetic flux norm value is
7507      *                                  negative, or if provided hard-iron array does
7508      *                                  not have length 3, or if provided quality scores
7509      *                                  length is smaller than 10 samples.
7510      */
7511     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7512             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7513             final double[] initialHardIron) {
7514         return create(qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron, DEFAULT_ROBUST_METHOD);
7515     }
7516 
7517     /**
7518      * Creates a robust magnetometer calibrator with default robust method.
7519      *
7520      * @param qualityScores                      quality scores corresponding to each provided
7521      *                                           measurement. The larger the score value the better
7522      *                                           the quality of the sample.
7523      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7524      * @param initialHardIron                    initial hard-iron to find a solution.
7525      * @return a robust magnetometer calibrator.
7526      * @throws IllegalArgumentException if provided magnetic flux norm value is
7527      *                                  negative, or if provided hard-iron matrix is not
7528      *                                  3x1, or if provided quality scores length
7529      *                                  is smaller than 10 samples.
7530      */
7531     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7532             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7533             final Matrix initialHardIron) {
7534         return create(qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron, DEFAULT_ROBUST_METHOD);
7535     }
7536 
7537     /**
7538      * Creates a robust magnetometer calibrator with default robust method.
7539      *
7540      * @param qualityScores                      quality scores corresponding to each provided
7541      *                                           measurement. The larger the score value the better
7542      *                                           the quality of the sample.
7543      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7544      * @param initialHardIron                    initial hard-iron to find a solution.
7545      * @param initialMm                          initial soft-iron matrix containing scale factors
7546      *                                           and cross coupling errors.
7547      * @return a robust magnetometer calibrator.
7548      * @throws IllegalArgumentException if provided magnetic flux norm value is
7549      *                                  negative, or if provided hard-iron matrix is not
7550      *                                  3x1 or if soft-iron matrix is not
7551      *                                  3x3 or if provided quality scores length
7552      *                                  is smaller than 10 samples.
7553      */
7554     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7555             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final Matrix initialHardIron,
7556             final Matrix initialMm) {
7557         return create(qualityScores, groundTruthMagneticFluxDensityNorm, initialHardIron, initialMm,
7558                 DEFAULT_ROBUST_METHOD);
7559     }
7560 
7561     /**
7562      * Creates a robust magnetometer calibrator with default robust method.
7563      *
7564      * @param qualityScores                      quality scores corresponding to each provided
7565      *                                           measurement. The larger the score value the better
7566      *                                           the quality of the sample.
7567      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7568      * @param measurements                       collection of body magnetic flux density
7569      *                                           measurements with standard deviation of
7570      *                                           magnetometer measurements taken at the same
7571      *                                           position with zero velocity and unknown different
7572      *                                           orientations.
7573      * @param listener                           listener to handle events raised by this calibrator.
7574      * @return a robust magnetometer calibrator.
7575      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7576      *                                  or if provided quality scores length is
7577      *                                  smaller than 10 samples.
7578      */
7579     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7580             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7581             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
7582             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7583         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, listener, DEFAULT_ROBUST_METHOD);
7584     }
7585 
7586     /**
7587      * Creates a robust magnetometer calibrator with default robust method.
7588      *
7589      * @param qualityScores                      quality scores corresponding to each provided
7590      *                                           measurement. The larger the score value the better
7591      *                                           the quality of the sample.
7592      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7593      * @param measurements                       collection of body magnetic flux density
7594      *                                           measurements with standard deviation of
7595      *                                           magnetometer measurements taken at the same
7596      *                                           position with zero velocity and unknown different
7597      *                                           orientations.
7598      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7599      *                                           for the accelerometer, gyroscope and magnetometer.
7600      * @return a robust magnetometer calibrator.
7601      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7602      *                                  or if provided quality scores length is smaller
7603      *                                  than 10 samples.
7604      */
7605     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7606             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7607             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
7608         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed,
7609                 DEFAULT_ROBUST_METHOD);
7610     }
7611 
7612     /**
7613      * Creates a robust magnetometer calibrator with default robust method.
7614      *
7615      * @param qualityScores                      quality scores corresponding to each provided
7616      *                                           measurement. The larger the score value the better
7617      *                                           the quality of the sample.
7618      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7619      * @param measurements                       collection of body magnetic flux density
7620      *                                           measurements with standard deviation of
7621      *                                           magnetometer measurements taken at the same
7622      *                                           position with zero velocity and unknown different
7623      *                                           orientations.
7624      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7625      *                                           for the accelerometer, gyroscope and magnetometer.
7626      * @param listener                           listener to handle events raised by this calibrator.
7627      * @return a robust magnetometer calibrator.
7628      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
7629      *                                  or if provided quality scores length is smaller
7630      *                                  than 10 samples.
7631      */
7632     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7633             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7634             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7635             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7636         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener,
7637                 DEFAULT_ROBUST_METHOD);
7638     }
7639 
7640     /**
7641      * Creates a robust magnetometer calibrator with default robust method.
7642      *
7643      * @param qualityScores                      quality scores corresponding to each provided
7644      *                                           measurement. The larger the score value the better
7645      *                                           the quality of the sample.
7646      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7647      * @param measurements                       collection of body magnetic flux density
7648      *                                           measurements with standard deviation of
7649      *                                           magnetometer measurements taken at the same
7650      *                                           position with zero velocity and unknown different
7651      *                                           orientations.
7652      * @param initialHardIron                    initial hard-iron to find a solution.
7653      * @return a robust magnetometer calibrator.
7654      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7655      *                                  or if provided hard-iron array does not have length 3,
7656      *                                  or if provided quality scores length is smaller
7657      *                                  than 10 samples.
7658      */
7659     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7660             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7661             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron) {
7662         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron,
7663                 DEFAULT_ROBUST_METHOD);
7664     }
7665 
7666     /**
7667      * Creates a robust magnetometer calibrator with default robust method.
7668      *
7669      * @param qualityScores                      quality scores corresponding to each provided
7670      *                                           measurement. The larger the score value the better
7671      *                                           the quality of the sample.
7672      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7673      * @param measurements                       collection of body magnetic flux density
7674      *                                           measurements with standard deviation of
7675      *                                           magnetometer measurements taken at the same
7676      *                                           position with zero velocity and unknown different
7677      *                                           orientations.
7678      * @param initialHardIron                    initial hard-iron to find a solution.
7679      * @param listener                           listener to handle events raised by this calibrator.
7680      * @return a robust magnetometer calibrator.
7681      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7682      *                                  or if provided hard-iron array does not have length 3,
7683      *                                  or if provided quality scores length is smaller
7684      *                                  than 10 samples.
7685      */
7686     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7687             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7688             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] initialHardIron,
7689             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7690         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener,
7691                 DEFAULT_ROBUST_METHOD);
7692     }
7693 
7694     /**
7695      * Creates a robust magnetometer calibrator with default robust method.
7696      *
7697      * @param qualityScores                      quality scores corresponding to each provided
7698      *                                           measurement. The larger the score value the better
7699      *                                           the quality of the sample.
7700      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7701      * @param measurements                       collection of body magnetic flux density
7702      *                                           measurements with standard deviation of
7703      *                                           magnetometer measurements taken at the same
7704      *                                           position with zero velocity and unknown different
7705      *                                           orientations.
7706      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7707      *                                           for the accelerometer, gyroscope and magnetometer.
7708      * @param initialHardIron                    initial hard-iron to find a solution.
7709      * @return a robust magnetometer calibrator.
7710      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7711      *                                  or if provided hard-iron array does not have length 3,
7712      *                                  or if provided quality scores length is smaller
7713      *                                  than 10 samples.
7714      */
7715     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7716             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7717             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7718             final double[] initialHardIron) {
7719         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7720                 DEFAULT_ROBUST_METHOD);
7721     }
7722 
7723     /**
7724      * Creates a robust magnetometer calibrator with default robust method.
7725      *
7726      * @param qualityScores                      quality scores corresponding to each provided
7727      *                                           measurement. The larger the score value the better
7728      *                                           the quality of the sample.
7729      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7730      * @param measurements                       collection of body magnetic flux density
7731      *                                           measurements with standard deviation of
7732      *                                           magnetometer measurements taken at the same
7733      *                                           position with zero velocity and unknown different
7734      *                                           orientations.
7735      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7736      *                                           for the accelerometer, gyroscope and magnetometer.
7737      * @param initialHardIron                    initial hard-iron to find a solution.
7738      * @param listener                           listener to handle events raised by this calibrator.
7739      * @return a robust magnetometer calibrator.
7740      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7741      *                                  or if provided hard-iron array does not have length 3,
7742      *                                  or if provided quality scores length is smaller
7743      *                                  than 10 samples.
7744      */
7745     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7746             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7747             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7748             final double[] initialHardIron,
7749             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7750         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7751                 listener, DEFAULT_ROBUST_METHOD);
7752     }
7753 
7754     /**
7755      * Creates a robust magnetometer calibrator with default robust method.
7756      *
7757      * @param qualityScores                      quality scores corresponding to each provided
7758      *                                           measurement. The larger the score value the better
7759      *                                           the quality of the sample.
7760      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7761      * @param measurements                       collection of body magnetic flux density
7762      *                                           measurements with standard deviation of
7763      *                                           magnetometer measurements taken at the same
7764      *                                           position with zero velocity and unknown different
7765      *                                           orientations.
7766      * @param initialHardIron                    initial hard-iron to find a solution.
7767      * @return a robust magnetometer calibrator.
7768      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7769      *                                  or if provided hard-iron matrix is not 3x1,
7770      *                                  or if provided quality scores length is smaller
7771      *                                  than 10 samples.
7772      */
7773     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7774             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7775             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron) {
7776         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron,
7777                 DEFAULT_ROBUST_METHOD);
7778     }
7779 
7780     /**
7781      * Creates a robust magnetometer calibrator with default robust method.
7782      *
7783      * @param qualityScores                      quality scores corresponding to each provided
7784      *                                           measurement. The larger the score value the better
7785      *                                           the quality of the sample.
7786      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7787      * @param measurements                       collection of body magnetic flux density
7788      *                                           measurements with standard deviation of
7789      *                                           magnetometer measurements taken at the same
7790      *                                           position with zero velocity and unknown different
7791      *                                           orientations.
7792      * @param initialHardIron                    initial hard-iron to find a solution.
7793      * @param listener                           listener to handle events raised by this calibrator.
7794      * @return a robust magnetometer calibrator.
7795      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7796      *                                  or if provided hard-iron matrix is not 3x1,
7797      *                                  or if provided quality scores length is smaller
7798      *                                  than 10 samples.
7799      */
7800     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7801             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7802             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
7803             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7804         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, listener,
7805                 DEFAULT_ROBUST_METHOD);
7806     }
7807 
7808     /**
7809      * Creates a robust magnetometer calibrator with default robust method.
7810      *
7811      * @param qualityScores                      quality scores corresponding to each provided
7812      *                                           measurement. The larger the score value the better
7813      *                                           the quality of the sample.
7814      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7815      * @param measurements                       collection of body magnetic flux density
7816      *                                           measurements with standard deviation of
7817      *                                           magnetometer measurements taken at the same
7818      *                                           position with zero velocity and unknown different
7819      *                                           orientations.
7820      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7821      *                                           for the accelerometer, gyroscope and magnetometer.
7822      * @param initialHardIron                    initial hard-iron to find a solution.
7823      * @return a robust magnetometer calibrator.
7824      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7825      *                                  or if provided hard-iron matrix is not 3x1,
7826      *                                  or if provided quality scores length is smaller
7827      *                                  than 10 samples.
7828      */
7829     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7830             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7831             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7832             final Matrix initialHardIron) {
7833         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7834                 DEFAULT_ROBUST_METHOD);
7835     }
7836 
7837     /**
7838      * Creates a robust magnetometer calibrator with default robust method.
7839      *
7840      * @param qualityScores                      quality scores corresponding to each provided
7841      *                                           measurement. The larger the score value the better
7842      *                                           the quality of the sample.
7843      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7844      * @param measurements                       collection of body magnetic flux density
7845      *                                           measurements with standard deviation of
7846      *                                           magnetometer measurements taken at the same
7847      *                                           position with zero velocity and unknown different
7848      *                                           orientations.
7849      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7850      *                                           for the accelerometer, gyroscope and magnetometer.
7851      * @param initialHardIron                    initial hard-iron to find a solution.
7852      * @param listener                           listener to handle events raised by this calibrator.
7853      * @return a robust magnetometer calibrator.
7854      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7855      *                                  or if provided hard-iron matrix is not 3x1,
7856      *                                  or if provided quality scores length is smaller
7857      *                                  than 10 samples.
7858      */
7859     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7860             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7861             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7862             final Matrix initialHardIron,
7863             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7864         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7865                 listener, DEFAULT_ROBUST_METHOD);
7866     }
7867 
7868     /**
7869      * Creates a robust magnetometer calibrator with default robust method.
7870      *
7871      * @param qualityScores                      quality scores corresponding to each provided
7872      *                                           measurement. The larger the score value the better
7873      *                                           the quality of the sample.
7874      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7875      * @param measurements                       collection of body magnetic flux density
7876      *                                           measurements with standard deviation of
7877      *                                           magnetometer measurements taken at the same
7878      *                                           position with zero velocity and unknown different
7879      *                                           orientations.
7880      * @param initialHardIron                    initial hard-iron to find a solution.
7881      * @param initialMm                          initial soft-iron matrix containing scale factors
7882      *                                           and cross coupling errors.
7883      * @return a robust magnetometer calibrator.
7884      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7885      *                                  or if provided hard-iron matrix is not 3x1 or if
7886      *                                  soft-iron matrix is not 3x3, or if provided
7887      *                                  quality scores length is smaller than 10 samples.
7888      */
7889     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7890             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7891             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
7892             final Matrix initialMm) {
7893         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm,
7894                 DEFAULT_ROBUST_METHOD);
7895     }
7896 
7897     /**
7898      * Creates a robust magnetometer calibrator with default robust method.
7899      *
7900      * @param qualityScores                      quality scores corresponding to each provided
7901      *                                           measurement. The larger the score value the better
7902      *                                           the quality of the sample.
7903      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7904      * @param measurements                       collection of body magnetic flux density
7905      *                                           measurements with standard deviation of
7906      *                                           magnetometer measurements taken at the same
7907      *                                           position with zero velocity and unknown different
7908      *                                           orientations.
7909      * @param initialHardIron                    initial hard-iron to find a solution.
7910      * @param initialMm                          initial soft-iron matrix containing scale factors
7911      *                                           and cross coupling errors.
7912      * @param listener                           listener to handle events raised by this calibrator.
7913      * @return a robust magnetometer calibrator.
7914      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7915      *                                  or if provided hard-iron matrix is not 3x1 or if
7916      *                                  soft-iron matrix is not 3x3, or if provided
7917      *                                  quality scores length is smaller than 10 samples.
7918      */
7919     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7920             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7921             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix initialHardIron,
7922             final Matrix initialMm, final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7923         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, initialHardIron, initialMm,
7924                 listener, DEFAULT_ROBUST_METHOD);
7925     }
7926 
7927     /**
7928      * Creates a robust magnetometer calibrator with default robust method.
7929      *
7930      * @param qualityScores                      quality scores corresponding to each provided
7931      *                                           measurement. The larger the score value the better
7932      *                                           the quality of the sample.
7933      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7934      * @param measurements                       collection of body magnetic flux density
7935      *                                           measurements with standard deviation of
7936      *                                           magnetometer measurements taken at the same
7937      *                                           position with zero velocity and unknown different
7938      *                                           orientations.
7939      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7940      *                                           for the accelerometer, gyroscope and magnetometer.
7941      * @param initialHardIron                    initial hard-iron to find a solution.
7942      * @param initialMm                          initial soft-iron matrix containing scale factors
7943      *                                           and cross coupling errors.
7944      * @return a robust magnetometer calibrator.
7945      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7946      *                                  or if provided hard-iron matrix is not 3x1
7947      *                                  or if soft-iron matrix is not 3x3, or if
7948      *                                  provided quality scores length is smaller
7949      *                                  than 10 samples.
7950      */
7951     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7952             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7953             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7954             final Matrix initialHardIron, final Matrix initialMm) {
7955         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7956                 initialMm, DEFAULT_ROBUST_METHOD);
7957     }
7958 
7959     /**
7960      * Creates a robust magnetometer calibrator with default robust method.
7961      *
7962      * @param qualityScores                      quality scores corresponding to each provided
7963      *                                           measurement. The larger the score value the better
7964      *                                           the quality of the sample.
7965      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
7966      * @param measurements                       collection of body magnetic flux density
7967      *                                           measurements with standard deviation of
7968      *                                           magnetometer measurements taken at the same
7969      *                                           position with zero velocity and unknown different
7970      *                                           orientations.
7971      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
7972      *                                           for the accelerometer, gyroscope and magnetometer.
7973      * @param initialHardIron                    initial hard-iron to find a solution.
7974      * @param initialMm                          initial soft-iron matrix containing scale factors
7975      *                                           and cross coupling errors.
7976      * @param listener                           listener to handle events raised by this calibrator.
7977      * @return a robust magnetometer calibrator.
7978      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
7979      *                                  or if provided hard-iron matrix is not 3x1
7980      *                                  or if soft-iron matrix is not 3x3, or if
7981      *                                  provided quality scores length is smaller
7982      *                                  than 10 samples.
7983      */
7984     public static RobustKnownMagneticFluxDensityNormMagnetometerCalibrator create(
7985             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
7986             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
7987             final Matrix initialHardIron, final Matrix initialMm,
7988             final RobustKnownMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
7989         return create(qualityScores, groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, initialHardIron,
7990                 initialMm, listener, DEFAULT_ROBUST_METHOD);
7991     }
7992 
7993     /**
7994      * Computes error of a preliminary result respect a given measurement.
7995      *
7996      * @param measurement       a measurement.
7997      * @param preliminaryResult a preliminary result.
7998      * @return computed error.
7999      */
8000     protected double computeError(
8001             final StandardDeviationBodyMagneticFluxDensity measurement, final PreliminaryResult preliminaryResult) {
8002 
8003         try {
8004             // The magnetometer model is:
8005             // mBmeas = bm + (I + Mm) * mBtrue
8006 
8007             // mBmeas - bm = (I + Mm) * mBtrue
8008 
8009             // mBtrue = (I + Mm)^-1 * (mBmeas - ba)
8010 
8011             // We know that ||mBtrue||should be equal to the magnitude of the
8012             // Earth magnetic field at provided location
8013 
8014             final var estimatedBiases = preliminaryResult.estimatedHardIron;
8015             final var estMm = preliminaryResult.estimatedMm;
8016 
8017             if (identity == null) {
8018                 identity = Matrix.identity(BodyMagneticFluxDensity.COMPONENTS, BodyMagneticFluxDensity.COMPONENTS);
8019             }
8020 
8021             if (tmp1 == null) {
8022                 tmp1 = new Matrix(BodyMagneticFluxDensity.COMPONENTS, BodyMagneticFluxDensity.COMPONENTS);
8023             }
8024 
8025             if (tmp2 == null) {
8026                 tmp2 = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
8027             }
8028 
8029             if (tmp3 == null) {
8030                 tmp3 = new Matrix(BodyKinematics.COMPONENTS, 1);
8031             }
8032 
8033             if (tmp4 == null) {
8034                 tmp4 = new Matrix(BodyKinematics.COMPONENTS, 1);
8035             }
8036 
8037             identity.add(estMm, tmp1);
8038 
8039             Utils.inverse(tmp1, tmp2);
8040 
8041             final var measuredMagneticFluxDensity = measurement.getMagneticFluxDensity();
8042             final var bMeasX = measuredMagneticFluxDensity.getBx();
8043             final var bMeasY = measuredMagneticFluxDensity.getBy();
8044             final var bMeasZ = measuredMagneticFluxDensity.getBz();
8045 
8046             final var bx = estimatedBiases[0];
8047             final var by = estimatedBiases[1];
8048             final var bz = estimatedBiases[2];
8049 
8050             tmp3.setElementAtIndex(0, bMeasX - bx);
8051             tmp3.setElementAtIndex(1, bMeasY - by);
8052             tmp3.setElementAtIndex(2, bMeasZ - bz);
8053 
8054             tmp2.multiply(tmp3, tmp4);
8055 
8056             final var norm = Utils.normF(tmp4);
8057             final var diff = groundTruthMagneticFluxDensityNorm - norm;
8058 
8059             return diff * diff;
8060 
8061         } catch (final AlgebraException e) {
8062             return Double.MAX_VALUE;
8063         }
8064     }
8065 
8066     /**
8067      * Computes a preliminary solution for a subset of samples picked by a robust estimator.
8068      *
8069      * @param samplesIndices indices of samples picked by the robust estimator.
8070      * @param solutions      list where estimated preliminary solution will be stored.
8071      */
8072     protected void computePreliminarySolutions(final int[] samplesIndices, final List<PreliminaryResult> solutions) {
8073 
8074         final var meas = new ArrayList<StandardDeviationBodyMagneticFluxDensity>();
8075 
8076         for (final var samplesIndex : samplesIndices) {
8077             meas.add(this.measurements.get(samplesIndex));
8078         }
8079 
8080         try {
8081             final var result = new PreliminaryResult();
8082             result.estimatedHardIron = getInitialHardIron();
8083             result.estimatedMm = getInitialMm();
8084 
8085             innerCalibrator.setInitialHardIron(result.estimatedHardIron);
8086             innerCalibrator.setInitialMm(result.estimatedMm);
8087             innerCalibrator.setCommonAxisUsed(commonAxisUsed);
8088             innerCalibrator.setGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
8089             innerCalibrator.setMeasurements(meas);
8090             innerCalibrator.calibrate();
8091 
8092             innerCalibrator.getEstimatedHardIron(result.estimatedHardIron);
8093             result.estimatedMm = innerCalibrator.getEstimatedMm();
8094 
8095             if (keepCovariance) {
8096                 result.covariance = innerCalibrator.getEstimatedCovariance();
8097             } else {
8098                 result.covariance = null;
8099             }
8100 
8101             result.estimatedMse = innerCalibrator.getEstimatedMse();
8102             result.estimatedChiSq = innerCalibrator.getEstimatedChiSq();
8103             result.estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
8104             result.estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
8105             result.estimatedP = innerCalibrator.getEstimatedP();
8106             result.estimatedQ = innerCalibrator.getEstimatedQ();
8107 
8108             solutions.add(result);
8109 
8110         } catch (final LockedException | CalibrationException | NotReadyException e) {
8111             solutions.clear();
8112         }
8113     }
8114 
8115     /**
8116      * Attempts to refine calibration parameters if refinement is requested.
8117      * This method returns a refined solution or provided input if refinement is not
8118      * requested or has failed.
8119      * If refinement is enabled and it is requested to keep covariance, this method
8120      * will also keep covariance of refined position.
8121      *
8122      * @param preliminaryResult a preliminary result.
8123      */
8124     protected void attemptRefine(final PreliminaryResult preliminaryResult) {
8125         if (refineResult && inliersData != null) {
8126             final var inliers = inliersData.getInliers();
8127             final var nSamples = measurements.size();
8128 
8129             final var inlierMeasurements = new ArrayList<StandardDeviationBodyMagneticFluxDensity>();
8130             for (var i = 0; i < nSamples; i++) {
8131                 if (inliers.get(i)) {
8132                     // sample is inlier
8133                     inlierMeasurements.add(measurements.get(i));
8134                 }
8135             }
8136 
8137             try {
8138                 innerCalibrator.setInitialHardIron(preliminaryResult.estimatedHardIron);
8139                 innerCalibrator.setInitialMm(preliminaryResult.estimatedMm);
8140                 innerCalibrator.setCommonAxisUsed(commonAxisUsed);
8141                 innerCalibrator.setGroundTruthMagneticFluxDensityNorm(groundTruthMagneticFluxDensityNorm);
8142                 innerCalibrator.setMeasurements(inlierMeasurements);
8143                 innerCalibrator.calibrate();
8144 
8145                 estimatedHardIron = innerCalibrator.getEstimatedHardIron();
8146                 estimatedMm = innerCalibrator.getEstimatedMm();
8147 
8148                 if (keepCovariance) {
8149                     estimatedCovariance = innerCalibrator.getEstimatedCovariance();
8150                 } else {
8151                     estimatedCovariance = null;
8152                 }
8153 
8154                 estimatedMse = innerCalibrator.getEstimatedMse();
8155                 estimatedChiSq = innerCalibrator.getEstimatedChiSq();
8156                 estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
8157                 estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
8158                 estimatedP = innerCalibrator.getEstimatedP();
8159                 estimatedQ = innerCalibrator.getEstimatedQ();
8160 
8161             } catch (final LockedException | CalibrationException | NotReadyException e) {
8162                 estimatedCovariance = preliminaryResult.covariance;
8163                 estimatedHardIron = preliminaryResult.estimatedHardIron;
8164                 estimatedMm = preliminaryResult.estimatedMm;
8165                 estimatedMse = preliminaryResult.estimatedMse;
8166                 estimatedChiSq = preliminaryResult.estimatedChiSq;
8167                 estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
8168                 estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
8169                 estimatedP = preliminaryResult.estimatedP;
8170                 estimatedQ = preliminaryResult.estimatedQ;
8171             }
8172         } else {
8173             estimatedCovariance = preliminaryResult.covariance;
8174             estimatedHardIron = preliminaryResult.estimatedHardIron;
8175             estimatedMm = preliminaryResult.estimatedMm;
8176             estimatedMse = preliminaryResult.estimatedMse;
8177             estimatedChiSq = preliminaryResult.estimatedChiSq;
8178             estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
8179             estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
8180             estimatedP = preliminaryResult.estimatedP;
8181             estimatedQ = preliminaryResult.estimatedQ;
8182         }
8183     }
8184 
8185     /**
8186      * Internally sets ground truth magnetic flux density norm to be expected at location where
8187      * measurements have been made, expressed in Teslas (T).
8188      *
8189      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm or null if undefined.
8190      * @throws IllegalArgumentException if provided value is negative.
8191      */
8192     private void internalSetGroundTruthMagneticFluxDensityNorm(final Double groundTruthMagneticFluxDensityNorm) {
8193         if (groundTruthMagneticFluxDensityNorm != null && groundTruthMagneticFluxDensityNorm < 0.0) {
8194             throw new IllegalArgumentException();
8195         }
8196         this.groundTruthMagneticFluxDensityNorm = groundTruthMagneticFluxDensityNorm;
8197     }
8198 
8199     /**
8200      * Converts magnetic flux density value and unit to Teslas.
8201      *
8202      * @param value magnetic flux density value.
8203      * @param unit  unit of magnetic flux density value.
8204      * @return converted value.
8205      */
8206     private static double convertMagneticFluxDensity(final double value, final MagneticFluxDensityUnit unit) {
8207         return MagneticFluxDensityConverter.convert(value, unit, MagneticFluxDensityUnit.TESLA);
8208     }
8209 
8210     /**
8211      * Converts magnetic flux density instance to Teslas.
8212      *
8213      * @param magneticFluxDensity magnetic flux density instance to be converted.
8214      * @return converted value.
8215      */
8216     private static double convertMagneticFluxDensity(final MagneticFluxDensity magneticFluxDensity) {
8217         return convertMagneticFluxDensity(magneticFluxDensity.getValue().doubleValue(), magneticFluxDensity.getUnit());
8218     }
8219 
8220     /**
8221      * Internal class containing estimated preliminary result.
8222      */
8223     protected static class PreliminaryResult {
8224         /**
8225          * Estimated magnetometer hard-iron biases for each magnetometer axis
8226          * expressed in Teslas (T).
8227          */
8228         private double[] estimatedHardIron;
8229 
8230         /**
8231          * Estimated magnetometer soft-iron matrix containing scale factors
8232          * and cross coupling errors.
8233          * This is the product of matrix Tm containing cross coupling errors and Km
8234          * containing scaling factors.
8235          * So tat:
8236          * <pre>
8237          *     Mm = [sx    mxy  mxz] = Tm*Km
8238          *          [myx   sy   myz]
8239          *          [mzx   mzy  sz ]
8240          * </pre>
8241          * Where:
8242          * <pre>
8243          *     Km = [sx 0   0 ]
8244          *          [0  sy  0 ]
8245          *          [0  0   sz]
8246          * </pre>
8247          * and
8248          * <pre>
8249          *     Tm = [1          -alphaXy    alphaXz ]
8250          *          [alphaYx    1           -alphaYz]
8251          *          [-alphaZx   alphaZy     1       ]
8252          * </pre>
8253          * Hence:
8254          * <pre>
8255          *     Mm = [sx    mxy  mxz] = Tm*Km =  [sx             -sy * alphaXy   sz * alphaXz ]
8256          *          [myx   sy   myz]            [sx * alphaYx   sy              -sz * alphaYz]
8257          *          [mzx   mzy  sz ]            [-sx * alphaZx  sy * alphaZy    sz           ]
8258          * </pre>
8259          * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
8260          * are considered to be zero if the accelerometer z-axis is assumed to be the same
8261          * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mm matrix
8262          * becomes upper diagonal:
8263          * <pre>
8264          *     Mm = [sx    mxy  mxz]
8265          *          [0     sy   myz]
8266          *          [0     0    sz ]
8267          * </pre>
8268          * Values of this matrix are unit-less.
8269          */
8270         private Matrix estimatedMm;
8271 
8272         /**
8273          * Covariance matrix.
8274          */
8275         private Matrix covariance;
8276 
8277         /**
8278          * Estimated Mean Squared Error (MSE).
8279          */
8280         private double estimatedMse;
8281 
8282         /**
8283          * Estimated chi square value.
8284          */
8285         private double estimatedChiSq;
8286 
8287         /**
8288          * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
8289          * minus the number of estimated parameters.
8290          */
8291         private int estimatedChiSqDegreesOfFreedom;
8292 
8293         /**
8294          * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
8295          * freedom. Ideally this value should be close to 1.0.
8296          */
8297         private double estimatedReducedChiSq;
8298 
8299         /**
8300          * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
8301          * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
8302          * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
8303          */
8304         private double estimatedP;
8305 
8306         /**
8307          * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
8308          * the better the fit that has been estimated.
8309          */
8310         private double estimatedQ;
8311     }
8312 }