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