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.Matrix;
19  import com.irurueta.navigation.LockedException;
20  import com.irurueta.navigation.NotReadyException;
21  import com.irurueta.navigation.inertial.calibration.CalibrationException;
22  import com.irurueta.navigation.inertial.calibration.StandardDeviationBodyMagneticFluxDensity;
23  import com.irurueta.numerical.robust.PROMedSRobustEstimator;
24  import com.irurueta.numerical.robust.PROMedSRobustEstimatorListener;
25  import com.irurueta.numerical.robust.RobustEstimator;
26  import com.irurueta.numerical.robust.RobustEstimatorException;
27  import com.irurueta.numerical.robust.RobustEstimatorMethod;
28  
29  import java.util.List;
30  
31  /**
32   * Robustly estimates magnetometer cross couplings and scaling factors using
33   * PROMedS algorithm.
34   * <p>
35   * To use this calibrator at least 7 measurements with known magnetic field norm at
36   * an unknown position and instant must be taken at 7 different unknown orientations
37   * when common z-axis is assumed, otherwise at least 10
38   * measurements are required.
39   * <p>
40   * Measured magnetic flux density is assumed to follow the model shown below:
41   * <pre>
42   *     mBmeas = bm + (I + Mm) * mBtrue + w
43   * </pre>
44   * Where:
45   * - mBmeas is the measured magnetic flux density. This is a 3x1 vector.
46   * - bm is magnetometer hard-iron bias. Ideally, on a perfect magnetometer,
47   * this should be a 3x1 zero vector.
48   * - I is the 3x3 identity matrix.
49   * - Mm is the 3x3 soft-iron matrix containing cross-couplings and scaling
50   * factors. Ideally, on a perfect magnetometer, this should be a 3x3 zero
51   * matrix.
52   * - mBtrue is ground-truth magnetic flux density. This is a 3x1 vector.
53   * - w is measurement noise. This is a 3x1 vector.
54   * Notice that this calibrator assumes that all measurements are taken in
55   * a short span of time, where Earth magnetic field can be assumed to be
56   * constant at provided location and instant.
57   */
58  public class PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator extends
59          RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator {
60  
61      /**
62       * Default value to be used for stop threshold. Stop threshold can be used to
63       * avoid keeping the algorithm unnecessarily iterating in case that best
64       * estimated threshold using median of residuals is not small enough. Once a
65       * solution is found that generates a threshold below this value, the
66       * algorithm will stop.
67       * The stop threshold can be used to prevent the LMedS algorithm iterating
68       * too many times in cases where samples have a very similar accuracy.
69       * For instance, in cases where proportion of outliers is very small (close
70       * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
71       * iterate for a long time trying to find the best solution when indeed
72       * there is no need to do that if a reasonable threshold has already been
73       * reached.
74       * Because of this behaviour the stop threshold can be set to a value much
75       * lower than the one typically used in RANSAC, and yet the algorithm could
76       * still produce even smaller thresholds in estimated results.
77       */
78      public static final double DEFAULT_STOP_THRESHOLD = 1e-9;
79  
80      /**
81       * Minimum allowed stop threshold value.
82       */
83      public static final double MIN_STOP_THRESHOLD = 0.0;
84  
85      /**
86       * Threshold to be used to keep the algorithm iterating in case that best
87       * estimated threshold using median of residuals is not small enough. Once
88       * a solution is found that generates a threshold below this value, the
89       * algorithm will stop.
90       * The stop threshold can be used to prevent the LMedS algorithm iterating
91       * too many times in cases where samples have a very similar accuracy.
92       * For instance, in cases where proportion of outliers is very small (close
93       * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
94       * iterate for a long time trying to find the best solution when indeed
95       * there is no need to do that if a reasonable threshold has already been
96       * reached.
97       * Because of this behaviour the stop threshold can be set to a value much
98       * lower than the one typically used in RANSAC, and yet the algorithm could
99       * still produce even smaller thresholds in estimated results.
100      */
101     private double stopThreshold = DEFAULT_STOP_THRESHOLD;
102 
103     /**
104      * Quality scores corresponding to each provided sample.
105      * The larger the score value the better the quality of the sample.
106      */
107     private double[] qualityScores;
108 
109     /**
110      * Constructor.
111      */
112     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator() {
113         super();
114     }
115 
116     /**
117      * Constructor.
118      *
119      * @param listener listener to handle events raised by this calibrator.
120      */
121     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
122             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
123         super(listener);
124     }
125 
126     /**
127      * Constructor.
128      *
129      * @param measurements list of body magnetic flux density
130      *                     measurements with standard deviation of
131      *                     magnetometer measurements taken at the same
132      *                     position with zero velocity and unknown different
133      *                     orientations.
134      */
135     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
136             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
137         super(measurements);
138     }
139 
140     /**
141      * Constructor.
142      *
143      * @param commonAxisUsed indicates whether z-axis is assumed to be common
144      *                       for the accelerometer, gyroscope and magnetometer.
145      */
146     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(final boolean commonAxisUsed) {
147         super(commonAxisUsed);
148     }
149 
150     /**
151      * Constructor.
152      *
153      * @param hardIron known hard-iron.
154      * @throws IllegalArgumentException if provided hard-iron array does
155      *                                  not have length 3.
156      */
157     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(final double[] hardIron) {
158         super(hardIron);
159     }
160 
161     /**
162      * Constructor.
163      *
164      * @param hardIron known hard-iron.
165      * @throws IllegalArgumentException if provided hard-iron matrix is not
166      *                                  3x1.
167      */
168     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(final Matrix hardIron) {
169         super(hardIron);
170     }
171 
172     /**
173      * Constructor.
174      *
175      * @param hardIron  known hard-iron.
176      * @param initialMm initial soft-iron matrix containing scale factors
177      *                  and cross coupling errors.
178      * @throws IllegalArgumentException if provided hard-iron matrix is not
179      *                                  3x1 or if soft-iron matrix is not
180      *                                  3x3.
181      */
182     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
183             final Matrix hardIron, final Matrix initialMm) {
184         super(hardIron, initialMm);
185     }
186 
187     /**
188      * Constructor.
189      *
190      * @param measurements list of body magnetic flux density
191      *                     measurements with standard deviation of
192      *                     magnetometer measurements taken at the same
193      *                     position with zero velocity and unknown different
194      *                     orientations.
195      * @param listener     listener to handle events raised by this calibrator.
196      */
197     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
198             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
199             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
200         super(measurements, listener);
201     }
202 
203     /**
204      * Constructor.
205      *
206      * @param measurements   collection of body magnetic flux density
207      *                       measurements with standard deviation of
208      *                       magnetometer measurements taken at the same
209      *                       position with zero velocity and unknown different
210      *                       orientations.
211      * @param commonAxisUsed indicates whether z-axis is assumed to be common
212      *                       for the accelerometer, gyroscope and magnetometer.
213      */
214     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
215             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
216         super(measurements, commonAxisUsed);
217     }
218 
219     /**
220      * Constructor.
221      *
222      * @param measurements   collection of body magnetic flux density
223      *                       measurements with standard deviation of
224      *                       magnetometer measurements taken at the same
225      *                       position with zero velocity and unknown different
226      *                       orientations.
227      * @param commonAxisUsed indicates whether z-axis is assumed to be common
228      *                       for the accelerometer, gyroscope and magnetometer.
229      * @param listener       listener to handle events raised by this calibrator.
230      */
231     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
232             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
233             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
234         super(measurements, commonAxisUsed, listener);
235     }
236 
237     /**
238      * Constructor.
239      *
240      * @param measurements collection of body magnetic flux density
241      *                     measurements with standard deviation of
242      *                     magnetometer measurements taken at the same
243      *                     position with zero velocity and unknown different
244      *                     orientations.
245      * @param hardIron     known hard-iron.
246      * @throws IllegalArgumentException if provided hard-iron array does
247      *                                  not have length 3.
248      */
249     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
250             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron) {
251         super(measurements, hardIron);
252     }
253 
254     /**
255      * Constructor.
256      *
257      * @param measurements collection of body magnetic flux density
258      *                     measurements with standard deviation of
259      *                     magnetometer measurements taken at the same
260      *                     position with zero velocity and unknown different
261      *                     orientations.
262      * @param hardIron     known hard-iron.
263      * @param listener     listener to handle events raised by this calibrator.
264      * @throws IllegalArgumentException if provided hard-iron array does
265      *                                  not have length 3.
266      */
267     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
268             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron,
269             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
270         super(measurements, hardIron, listener);
271     }
272 
273     /**
274      * Constructor.
275      *
276      * @param measurements   collection of body magnetic flux density
277      *                       measurements with standard deviation of
278      *                       magnetometer measurements taken at the same
279      *                       position with zero velocity and unknown different
280      *                       orientations.
281      * @param commonAxisUsed indicates whether z-axis is assumed to be common
282      *                       for the accelerometer, gyroscope and magnetometer.
283      * @param hardIron       known hard-iron.
284      * @throws IllegalArgumentException if provided hard-iron array does
285      *                                  not have length 3.
286      */
287     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
288             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
289             final double[] hardIron) {
290         super(measurements, commonAxisUsed, hardIron);
291     }
292 
293     /**
294      * Constructor.
295      *
296      * @param measurements   collection of body magnetic flux density
297      *                       measurements with standard deviation of
298      *                       magnetometer measurements taken at the same
299      *                       position with zero velocity and unknown different
300      *                       orientations.
301      * @param commonAxisUsed indicates whether z-axis is assumed to be common
302      *                       for the accelerometer, gyroscope and magnetometer.
303      * @param hardIron       known hard-iron.
304      * @param listener       listener to handle events raised by this calibrator.
305      * @throws IllegalArgumentException if provided hard-iron array does
306      *                                  not have length 3.
307      */
308     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
309             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
310             final double[] hardIron,
311             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
312         super(measurements, commonAxisUsed, hardIron, listener);
313     }
314 
315     /**
316      * Constructor.
317      *
318      * @param measurements collection of body magnetic flux density
319      *                     measurements with standard deviation of
320      *                     magnetometer measurements taken at the same
321      *                     position with zero velocity and unknown different
322      *                     orientations.
323      * @param hardIron     known hard-iron.
324      * @throws IllegalArgumentException if provided hard-iron matrix is not
325      *                                  3x1.
326      */
327     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
328             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron) {
329         super(measurements, hardIron);
330     }
331 
332     /**
333      * Constructor.
334      *
335      * @param measurements collection of body magnetic flux density
336      *                     measurements with standard deviation of
337      *                     magnetometer measurements taken at the same
338      *                     position with zero velocity and unknown different
339      *                     orientations.
340      * @param hardIron     known hard-iron to find a solution.
341      * @param listener     listener to handle events raised by this calibrator.
342      * @throws IllegalArgumentException if provided hard-iron matrix is not
343      *                                  3x1.
344      */
345     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
346             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
347             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
348         super(measurements, hardIron, listener);
349     }
350 
351     /**
352      * Constructor.
353      *
354      * @param measurements   collection of body magnetic flux density
355      *                       measurements with standard deviation of
356      *                       magnetometer measurements taken at the same
357      *                       position with zero velocity and unknown different
358      *                       orientations.
359      * @param commonAxisUsed indicates whether z-axis is assumed to be common
360      *                       for the accelerometer, gyroscope and magnetometer.
361      * @param hardIron       known hard-iron.
362      * @throws IllegalArgumentException if provided hard-iron matrix is not
363      *                                  3x1.
364      */
365     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
366             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
367             final Matrix hardIron) {
368         super(measurements, commonAxisUsed, hardIron);
369     }
370 
371     /**
372      * Constructor.
373      *
374      * @param measurements   collection of body magnetic flux density
375      *                       measurements with standard deviation of
376      *                       magnetometer measurements taken at the same
377      *                       position with zero velocity and unknown different
378      *                       orientations.
379      * @param commonAxisUsed indicates whether z-axis is assumed to be common
380      *                       for the accelerometer, gyroscope and magnetometer.
381      * @param hardIron       known hard-iron.
382      * @param listener       listener to handle events raised by this calibrator.
383      * @throws IllegalArgumentException if provided hard-iron matrix is not
384      *                                  3x1.
385      */
386     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
387             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
388             final Matrix hardIron,
389             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
390         super(measurements, commonAxisUsed, hardIron, listener);
391     }
392 
393     /**
394      * Constructor.
395      *
396      * @param measurements collection of body magnetic flux density
397      *                     measurements with standard deviation of
398      *                     magnetometer measurements taken at the same
399      *                     position with zero velocity and unknown different
400      *                     orientations.
401      * @param hardIron     known hard-iron.
402      * @param initialMm    initial soft-iron matrix containing scale factors
403      *                     and cross coupling errors.
404      * @throws IllegalArgumentException if provided hard-iron matrix is not
405      *                                  3x1 or if soft-iron matrix is not
406      *                                  3x3.
407      */
408     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
409             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
410             final Matrix initialMm) {
411         super(measurements, hardIron, initialMm);
412     }
413 
414     /**
415      * Constructor.
416      *
417      * @param measurements collection of body magnetic flux density
418      *                     measurements with standard deviation of
419      *                     magnetometer measurements taken at the same
420      *                     position with zero velocity and unknown different
421      *                     orientations.
422      * @param hardIron     known hard-iron.
423      * @param initialMm    initial soft-iron matrix containing scale factors
424      *                     and cross coupling errors.
425      * @param listener     listener to handle events raised by this calibrator.
426      * @throws IllegalArgumentException if provided hard-iron matrix is not
427      *                                  3x1 or if soft-iron matrix is not
428      *                                  3x3.
429      */
430     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
431             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
432             final Matrix initialMm,
433             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
434         super(measurements, hardIron, initialMm, listener);
435     }
436 
437     /**
438      * Constructor.
439      *
440      * @param measurements   collection of body magnetic flux density
441      *                       measurements with standard deviation of
442      *                       magnetometer measurements taken at the same
443      *                       position with zero velocity and unknown different
444      *                       orientations.
445      * @param commonAxisUsed indicates whether z-axis is assumed to be common
446      *                       for the accelerometer, gyroscope and magnetometer.
447      * @param hardIron       known hard-iron.
448      * @param initialMm      initial soft-iron matrix containing scale factors
449      *                       and cross coupling errors.
450      * @throws IllegalArgumentException if provided hard-iron matrix is not
451      *                                  3x1 or if soft-iron matrix is not
452      *                                  3x3.
453      */
454     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
455             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
456             final Matrix hardIron, final Matrix initialMm) {
457         super(measurements, commonAxisUsed, hardIron, initialMm);
458     }
459 
460     /**
461      * Constructor.
462      *
463      * @param measurements   collection of body magnetic flux density
464      *                       measurements with standard deviation of
465      *                       magnetometer measurements taken at the same
466      *                       position with zero velocity and unknown different
467      *                       orientations.
468      * @param commonAxisUsed indicates whether z-axis is assumed to be common
469      *                       for the accelerometer, gyroscope and magnetometer.
470      * @param hardIron       known hard-iron.
471      * @param initialMm      initial soft-iron matrix containing scale factors
472      *                       and cross coupling errors.
473      * @param listener       listener to handle events raised by this calibrator.
474      * @throws IllegalArgumentException if provided hard-iron matrix is not
475      *                                  3x1 or if soft-iron matrix is not
476      *                                  3x3.
477      */
478     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
479             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
480             final Matrix hardIron, final Matrix initialMm,
481             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
482         super(measurements, commonAxisUsed, hardIron, initialMm, listener);
483     }
484 
485     /**
486      * Constructor.
487      *
488      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
489      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
490      */
491     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
492             final Double groundTruthMagneticFluxDensityNorm) {
493         super(groundTruthMagneticFluxDensityNorm);
494     }
495 
496     /**
497      * Constructor.
498      *
499      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
500      * @param listener                           listener to handle events raised by this calibrator.
501      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
502      */
503     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
504             final Double groundTruthMagneticFluxDensityNorm,
505             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
506         super(groundTruthMagneticFluxDensityNorm, listener);
507     }
508 
509     /**
510      * Constructor.
511      *
512      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
513      * @param measurements                       collection of body magnetic flux density
514      *                                           measurements with standard deviation of
515      *                                           magnetometer measurements taken at the same
516      *                                           position with zero velocity and unknown different
517      *                                           orientations.
518      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
519      */
520     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
521             final Double groundTruthMagneticFluxDensityNorm,
522             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
523         super(groundTruthMagneticFluxDensityNorm, measurements);
524     }
525 
526     /**
527      * Constructor.
528      *
529      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
530      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
531      *                                           for the accelerometer, gyroscope and magnetometer.
532      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
533      */
534     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
535             final Double groundTruthMagneticFluxDensityNorm, final boolean commonAxisUsed) {
536         super(groundTruthMagneticFluxDensityNorm, commonAxisUsed);
537     }
538 
539     /**
540      * Constructor.
541      *
542      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
543      * @param hardIron                           known hard-iron.
544      * @throws IllegalArgumentException if provided magnetic flux norm value is
545      *                                  negative, or if provided hard-iron array does
546      *                                  not have length 3.
547      */
548     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
549             final Double groundTruthMagneticFluxDensityNorm, final double[] hardIron) {
550         super(groundTruthMagneticFluxDensityNorm, hardIron);
551     }
552 
553     /**
554      * Constructor.
555      *
556      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
557      * @param hardIron                           known hard-iron.
558      * @throws IllegalArgumentException if provided magnetic flux norm value is
559      *                                  negative, or if provided hard-iron matrix is not
560      *                                  3x1.
561      */
562     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
563             final Double groundTruthMagneticFluxDensityNorm, final Matrix hardIron) {
564         super(groundTruthMagneticFluxDensityNorm, hardIron);
565     }
566 
567     /**
568      * Constructor.
569      *
570      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
571      * @param hardIron                           known hard-iron.
572      * @param initialMm                          initial soft-iron matrix containing scale factors
573      *                                           and cross coupling errors.
574      * @throws IllegalArgumentException if provided magnetic flux norm value is
575      *                                  negative, or if provided hard-iron matrix is not
576      *                                  3x1 or if soft-iron matrix is not
577      *                                  3x3.
578      */
579     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
580             final Double groundTruthMagneticFluxDensityNorm, final Matrix hardIron, final Matrix initialMm) {
581         super(groundTruthMagneticFluxDensityNorm, hardIron, initialMm);
582     }
583 
584     /**
585      * Constructor.
586      *
587      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
588      * @param measurements                       collection of body magnetic flux density
589      *                                           measurements with standard deviation of
590      *                                           magnetometer measurements taken at the same
591      *                                           position with zero velocity and unknown different
592      *                                           orientations.
593      * @param listener                           listener to handle events raised by this calibrator.
594      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
595      */
596     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
597             final Double groundTruthMagneticFluxDensityNorm,
598             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
599             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
600         super(groundTruthMagneticFluxDensityNorm, measurements, listener);
601     }
602 
603     /**
604      * Constructor.
605      *
606      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
607      * @param measurements                       collection of body magnetic flux density
608      *                                           measurements with standard deviation of
609      *                                           magnetometer measurements taken at the same
610      *                                           position with zero velocity and unknown different
611      *                                           orientations.
612      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
613      *                                           for the accelerometer, gyroscope and magnetometer.
614      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
615      */
616     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
617             final Double groundTruthMagneticFluxDensityNorm,
618             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
619         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
620     }
621 
622     /**
623      * Constructor.
624      *
625      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
626      * @param measurements                       collection of body magnetic flux density
627      *                                           measurements with standard deviation of
628      *                                           magnetometer measurements taken at the same
629      *                                           position with zero velocity and unknown different
630      *                                           orientations.
631      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
632      *                                           for the accelerometer, gyroscope and magnetometer.
633      * @param listener                           listener to handle events raised by this calibrator.
634      * @throws IllegalArgumentException if provided magnetic flux norm value is negative.
635      */
636     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
637             final Double groundTruthMagneticFluxDensityNorm,
638             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
639             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
640         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
641     }
642 
643     /**
644      * Constructor.
645      *
646      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
647      * @param measurements                       collection of body magnetic flux density
648      *                                           measurements with standard deviation of
649      *                                           magnetometer measurements taken at the same
650      *                                           position with zero velocity and unknown different
651      *                                           orientations.
652      * @param hardIron                           known hard-iron.
653      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
654      *                                  or if provided hard-iron array does not have length 3.
655      */
656     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
657             final Double groundTruthMagneticFluxDensityNorm,
658             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron) {
659         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron);
660     }
661 
662     /**
663      * Constructor.
664      *
665      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
666      * @param measurements                       collection of body magnetic flux density
667      *                                           measurements with standard deviation of
668      *                                           magnetometer measurements taken at the same
669      *                                           position with zero velocity and unknown different
670      *                                           orientations.
671      * @param hardIron                           known hard-iron.
672      * @param listener                           listener to handle events raised by this calibrator.
673      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
674      *                                  or if provided hard-iron array does not have length 3.
675      */
676     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
677             final Double groundTruthMagneticFluxDensityNorm,
678             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron,
679             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
680         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, listener);
681     }
682 
683     /**
684      * Constructor.
685      *
686      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
687      * @param measurements                       collection of body magnetic flux density
688      *                                           measurements with standard deviation of
689      *                                           magnetometer measurements taken at the same
690      *                                           position with zero velocity and unknown different
691      *                                           orientations.
692      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
693      *                                           for the accelerometer, gyroscope and magnetometer.
694      * @param hardIron                           known hard-iron.
695      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
696      *                                  or if provided hard-iron array does not have length 3.
697      */
698     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
699             final Double groundTruthMagneticFluxDensityNorm,
700             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
701             final double[] hardIron) {
702         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron);
703     }
704 
705     /**
706      * Constructor.
707      *
708      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
709      * @param measurements                       collection of body magnetic flux density
710      *                                           measurements with standard deviation of
711      *                                           magnetometer measurements taken at the same
712      *                                           position with zero velocity and unknown different
713      *                                           orientations.
714      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
715      *                                           for the accelerometer, gyroscope and magnetometer.
716      * @param hardIron                           known hard-iron.
717      * @param listener                           listener to handle events raised by this calibrator.
718      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
719      *                                  or if provided hard-iron array does not have length 3.
720      */
721     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
722             final Double groundTruthMagneticFluxDensityNorm,
723             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
724             final double[] hardIron,
725             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
726         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, listener);
727     }
728 
729     /**
730      * Constructor.
731      *
732      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
733      * @param measurements                       collection of body magnetic flux density
734      *                                           measurements with standard deviation of
735      *                                           magnetometer measurements taken at the same
736      *                                           position with zero velocity and unknown different
737      *                                           orientations.
738      * @param hardIron                           known hard-iron.
739      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
740      *                                  or if provided hard-iron matrix is not 3x1.
741      */
742     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
743             final Double groundTruthMagneticFluxDensityNorm,
744             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron) {
745         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron);
746     }
747 
748     /**
749      * Constructor.
750      *
751      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
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 hardIron                           known hard-iron.
758      * @param listener                           listener to handle events raised by this calibrator.
759      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
760      *                                  or if provided hard-iron matrix is not 3x1.
761      */
762     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
763             final Double groundTruthMagneticFluxDensityNorm,
764             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
765             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
766         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, listener);
767     }
768 
769     /**
770      * Constructor.
771      *
772      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
773      * @param measurements                       collection of body magnetic flux density
774      *                                           measurements with standard deviation of
775      *                                           magnetometer measurements taken at the same
776      *                                           position with zero velocity and unknown different
777      *                                           orientations.
778      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
779      *                                           for the accelerometer, gyroscope and magnetometer.
780      * @param hardIron                           known hard-iron.
781      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
782      *                                  or if provided hard-iron matrix is not 3x1.
783      */
784     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
785             final Double groundTruthMagneticFluxDensityNorm,
786             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
787             final Matrix hardIron) {
788         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron);
789     }
790 
791     /**
792      * Constructor.
793      *
794      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
795      * @param measurements                       collection of body magnetic flux density
796      *                                           measurements with standard deviation of
797      *                                           magnetometer measurements taken at the same
798      *                                           position with zero velocity and unknown different
799      *                                           orientations.
800      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
801      *                                           for the accelerometer, gyroscope and magnetometer.
802      * @param hardIron                           known hard-iron.
803      * @param listener                           listener to handle events raised by this calibrator.
804      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
805      *                                  or if provided hard-iron matrix is not 3x1.
806      */
807     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
808             final Double groundTruthMagneticFluxDensityNorm,
809             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
810             final Matrix hardIron,
811             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
812         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, listener);
813     }
814 
815     /**
816      * Constructor.
817      *
818      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
819      * @param measurements                       collection of body magnetic flux density
820      *                                           measurements with standard deviation of
821      *                                           magnetometer measurements taken at the same
822      *                                           position with zero velocity and unknown different
823      *                                           orientations.
824      * @param hardIron                           known hard-iron.
825      * @param initialMm                          initial soft-iron matrix containing scale factors
826      *                                           and cross coupling errors.
827      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
828      *                                  or if provided hard-iron matrix is not 3x1 or if
829      *                                  soft-iron matrix is not 3x3.
830      */
831     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
832             final Double groundTruthMagneticFluxDensityNorm,
833             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
834             final Matrix initialMm) {
835         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, initialMm);
836     }
837 
838     /**
839      * Constructor.
840      *
841      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
842      * @param measurements                       collection of body magnetic flux density
843      *                                           measurements with standard deviation of
844      *                                           magnetometer measurements taken at the same
845      *                                           position with zero velocity and unknown different
846      *                                           orientations.
847      * @param hardIron                           known hard-iron.
848      * @param initialMm                          initial soft-iron matrix containing scale factors
849      *                                           and cross coupling errors.
850      * @param listener                           listener to handle events raised by this calibrator.
851      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
852      *                                  or if provided hard-iron matrix is not 3x1 or if
853      *                                  soft-iron matrix is not 3x3.
854      */
855     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
856             final Double groundTruthMagneticFluxDensityNorm,
857             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
858             final Matrix initialMm,
859             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
860         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, initialMm, listener);
861     }
862 
863     /**
864      * Constructor.
865      *
866      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
867      * @param measurements                       collection of body magnetic flux density
868      *                                           measurements with standard deviation of
869      *                                           magnetometer measurements taken at the same
870      *                                           position with zero velocity and unknown different
871      *                                           orientations.
872      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
873      *                                           for the accelerometer, gyroscope and magnetometer.
874      * @param hardIron                           known hard-iron.
875      * @param initialMm                          initial soft-iron matrix containing scale factors
876      *                                           and cross coupling errors.
877      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
878      *                                  or if provided hard-iron matrix is not 3x1
879      *                                  or if soft-iron matrix is not 3x3.
880      */
881     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
882             final Double groundTruthMagneticFluxDensityNorm,
883             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
884             final Matrix hardIron, final Matrix initialMm) {
885         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, initialMm);
886     }
887 
888     /**
889      * Constructor.
890      *
891      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
892      * @param measurements                       collection of body magnetic flux density
893      *                                           measurements with standard deviation of
894      *                                           magnetometer measurements taken at the same
895      *                                           position with zero velocity and unknown different
896      *                                           orientations.
897      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
898      *                                           for the accelerometer, gyroscope and magnetometer.
899      * @param hardIron                           known hard-iron.
900      * @param initialMm                          initial soft-iron matrix containing scale factors
901      *                                           and cross coupling errors.
902      * @param listener                           listener to handle events raised by this calibrator.
903      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
904      *                                  or if provided hard-iron matrix is not 3x1
905      *                                  or if soft-iron matrix is not 3x3.
906      */
907     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
908             final Double groundTruthMagneticFluxDensityNorm,
909             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
910             final Matrix hardIron, final Matrix initialMm,
911             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
912         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, initialMm, listener);
913     }
914 
915     /**
916      * Constructor.
917      *
918      * @param qualityScores quality scores corresponding to each provided
919      *                      measurement. The larger the score value the better
920      *                      the quality of the sample.
921      * @param measurements  list of body magnetic flux density
922      *                      measurements with standard deviation of
923      *                      magnetometer measurements taken at the same
924      *                      position with zero velocity and unknown different
925      *                      orientations.
926      * @throws IllegalArgumentException if provided quality scores length
927      *                                  is smaller than 10 samples.
928      */
929     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
930             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
931         super(measurements);
932         internalSetQualityScores(qualityScores);
933     }
934 
935     /**
936      * Constructor.
937      *
938      * @param qualityScores  quality scores corresponding to each provided
939      *                       measurement. The larger the score value the better
940      *                       the quality of the sample.
941      * @param commonAxisUsed indicates whether z-axis is assumed to be common
942      *                       for the accelerometer, gyroscope and magnetometer.
943      * @throws IllegalArgumentException if provided quality scores length
944      *                                  is smaller than 10 samples.
945      */
946     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
947             final double[] qualityScores, final boolean commonAxisUsed) {
948         super(commonAxisUsed);
949         internalSetQualityScores(qualityScores);
950     }
951 
952     /**
953      * Constructor.
954      *
955      * @param qualityScores quality scores corresponding to each provided
956      *                      measurement. The larger the score value the better
957      *                      the quality of the sample.
958      * @param hardIron      known hard-iron.
959      * @throws IllegalArgumentException if provided hard-iron array does
960      *                                  not have length 3 or if provided
961      *                                  quality scores length is smaller
962      *                                  than 10 samples.
963      */
964     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
965             final double[] qualityScores, final double[] hardIron) {
966         super(hardIron);
967         internalSetQualityScores(qualityScores);
968     }
969 
970     /**
971      * Constructor.
972      *
973      * @param qualityScores quality scores corresponding to each provided
974      *                      measurement. The larger the score value the better
975      *                      the quality of the sample.
976      * @param hardIron      known hard-iron.
977      * @throws IllegalArgumentException if provided hard-iron matrix is not
978      *                                  3x1 or if provided quality scores
979      *                                  length is smaller than 10 samples.
980      */
981     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
982             final double[] qualityScores, final Matrix hardIron) {
983         super(hardIron);
984         internalSetQualityScores(qualityScores);
985     }
986 
987     /**
988      * Constructor.
989      *
990      * @param qualityScores quality scores corresponding to each provided
991      *                      measurement. The larger the score value the better
992      *                      the quality of the sample.
993      * @param hardIron      known hard-iron.
994      * @param initialMm     initial soft-iron matrix containing scale factors
995      *                      and cross coupling errors.
996      * @throws IllegalArgumentException if provided hard-iron matrix is not
997      *                                  3x1 or if soft-iron matrix is not
998      *                                  3x3 or if provided quality scores
999      *                                  length is smaller than 10 samples.
1000      */
1001     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1002             final double[] qualityScores, final Matrix hardIron, final Matrix initialMm) {
1003         super(hardIron, initialMm);
1004         internalSetQualityScores(qualityScores);
1005     }
1006 
1007     /**
1008      * Constructor.
1009      *
1010      * @param qualityScores quality scores corresponding to each provided
1011      *                      measurement. The larger the score value the better
1012      *                      the quality of the sample.
1013      * @param measurements  list of body magnetic flux density
1014      *                      measurements with standard deviation of
1015      *                      magnetometer measurements taken at the same
1016      *                      position with zero velocity and unknown different
1017      *                      orientations.
1018      * @param listener      listener to handle events raised by this calibrator.
1019      * @throws IllegalArgumentException if provided quality scores length
1020      *                                  is smaller than 10 samples.
1021      */
1022     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1023             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1024             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1025         super(measurements, listener);
1026         internalSetQualityScores(qualityScores);
1027     }
1028 
1029     /**
1030      * Constructor.
1031      *
1032      * @param qualityScores  quality scores corresponding to each provided
1033      *                       measurement. The larger the score value the better
1034      *                       the quality of the sample.
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      * @throws IllegalArgumentException if provided quality scores length
1043      *                                  is smaller than 10 samples.
1044      */
1045     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1046             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1047             final boolean commonAxisUsed) {
1048         super(measurements, commonAxisUsed);
1049         internalSetQualityScores(qualityScores);
1050     }
1051 
1052     /**
1053      * Constructor.
1054      *
1055      * @param qualityScores  quality scores corresponding to each provided
1056      *                       measurement. The larger the score value the better
1057      *                       the quality of the sample.
1058      * @param measurements   collection of body magnetic flux density
1059      *                       measurements with standard deviation of
1060      *                       magnetometer measurements taken at the same
1061      *                       position with zero velocity and unknown different
1062      *                       orientations.
1063      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1064      *                       for the accelerometer, gyroscope and magnetometer.
1065      * @param listener       listener to handle events raised by this calibrator.
1066      * @throws IllegalArgumentException if provided quality scores length
1067      *                                  is smaller than 10 samples.
1068      */
1069     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1070             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1071             final boolean commonAxisUsed,
1072             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1073         super(measurements, commonAxisUsed, listener);
1074         internalSetQualityScores(qualityScores);
1075     }
1076 
1077     /**
1078      * Constructor.
1079      *
1080      * @param qualityScores quality scores corresponding to each provided
1081      *                      measurement. The larger the score value the better
1082      *                      the quality of the sample.
1083      * @param measurements  collection of body magnetic flux density
1084      *                      measurements with standard deviation of
1085      *                      magnetometer measurements taken at the same
1086      *                      position with zero velocity and unknown different
1087      *                      orientations.
1088      * @param hardIron      known hard-iron.
1089      * @throws IllegalArgumentException if provided hard-iron array does
1090      *                                  not have length 3 or if provided quality
1091      *                                  scores length is smaller than 10 samples.
1092      */
1093     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1094             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1095             final double[] hardIron) {
1096         super(measurements, hardIron);
1097         internalSetQualityScores(qualityScores);
1098     }
1099 
1100     /**
1101      * Constructor.
1102      *
1103      * @param qualityScores quality scores corresponding to each provided
1104      *                      measurement. The larger the score value the better
1105      *                      the quality of the sample.
1106      * @param measurements  collection of body magnetic flux density
1107      *                      measurements with standard deviation of
1108      *                      magnetometer measurements taken at the same
1109      *                      position with zero velocity and unknown different
1110      *                      orientations.
1111      * @param hardIron      known hard-iron.
1112      * @param listener      listener to handle events raised by this calibrator.
1113      * @throws IllegalArgumentException if provided hard-iron array does
1114      *                                  not have length 3 or if provided quality
1115      *                                  scores length is smaller than 10 samples.
1116      */
1117     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1118             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1119             final double[] hardIron,
1120             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1121         super(measurements, hardIron, listener);
1122         internalSetQualityScores(qualityScores);
1123     }
1124 
1125     /**
1126      * Constructor.
1127      *
1128      * @param qualityScores  quality scores corresponding to each provided
1129      *                       measurement. The larger the score value the better
1130      *                       the quality of the sample.
1131      * @param measurements   collection of body magnetic flux density
1132      *                       measurements with standard deviation of
1133      *                       magnetometer measurements taken at the same
1134      *                       position with zero velocity and unknown different
1135      *                       orientations.
1136      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1137      *                       for the accelerometer, gyroscope and magnetometer.
1138      * @param hardIron       known hard-iron.
1139      * @throws IllegalArgumentException if provided hard-iron array does
1140      *                                  not have length 3 or if provided quality
1141      *                                  scores length is smaller than 10 samples.
1142      */
1143     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1144             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1145             final boolean commonAxisUsed, final double[] hardIron) {
1146         super(measurements, commonAxisUsed, hardIron);
1147         internalSetQualityScores(qualityScores);
1148     }
1149 
1150     /**
1151      * Constructor.
1152      *
1153      * @param qualityScores  quality scores corresponding to each provided
1154      *                       measurement. The larger the score value the better
1155      *                       the quality of the sample.
1156      * @param measurements   collection of body magnetic flux density
1157      *                       measurements with standard deviation of
1158      *                       magnetometer measurements taken at the same
1159      *                       position with zero velocity and unknown different
1160      *                       orientations.
1161      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1162      *                       for the accelerometer, gyroscope and magnetometer.
1163      * @param hardIron       known hard-iron.
1164      * @param listener       listener to handle events raised by this calibrator.
1165      * @throws IllegalArgumentException if provided hard-iron array does
1166      *                                  not have length 3 or if provided quality
1167      *                                  scores length is smaller than 10 samples.
1168      */
1169     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1170             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1171             final boolean commonAxisUsed, final double[] hardIron,
1172             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1173         super(measurements, commonAxisUsed, hardIron, listener);
1174         internalSetQualityScores(qualityScores);
1175     }
1176 
1177     /**
1178      * Constructor.
1179      *
1180      * @param qualityScores quality scores corresponding to each provided
1181      *                      measurement. The larger the score value the better
1182      *                      the quality of the sample.
1183      * @param measurements  collection of body magnetic flux density
1184      *                      measurements with standard deviation of
1185      *                      magnetometer measurements taken at the same
1186      *                      position with zero velocity and unknown different
1187      *                      orientations.
1188      * @param hardIron      known hard-iron.
1189      * @throws IllegalArgumentException if provided hard-iron matrix is not
1190      *                                  3x1 or if provided quality scores length
1191      *                                  is smaller than 10 samples.
1192      */
1193     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1194             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1195             final Matrix hardIron) {
1196         super(measurements, hardIron);
1197         internalSetQualityScores(qualityScores);
1198     }
1199 
1200     /**
1201      * Constructor.
1202      *
1203      * @param qualityScores quality scores corresponding to each provided
1204      *                      measurement. The larger the score value the better
1205      *                      the quality of the sample.
1206      * @param measurements  collection of body magnetic flux density
1207      *                      measurements with standard deviation of
1208      *                      magnetometer measurements taken at the same
1209      *                      position with zero velocity and unknown different
1210      *                      orientations.
1211      * @param hardIron      known hard-iron.
1212      * @param listener      listener to handle events raised by this calibrator.
1213      * @throws IllegalArgumentException if provided hard-iron matrix is not
1214      *                                  3x1 or if provided quality scores length
1215      *                                  is smaller than 10 samples.
1216      */
1217     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1218             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1219             final Matrix hardIron,
1220             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1221         super(measurements, hardIron, listener);
1222         internalSetQualityScores(qualityScores);
1223     }
1224 
1225     /**
1226      * Constructor.
1227      *
1228      * @param qualityScores  quality scores corresponding to each provided
1229      *                       measurement. The larger the score value the better
1230      *                       the quality of the sample.
1231      * @param measurements   collection of body magnetic flux density
1232      *                       measurements with standard deviation of
1233      *                       magnetometer measurements taken at the same
1234      *                       position with zero velocity and unknown different
1235      *                       orientations.
1236      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1237      *                       for the accelerometer, gyroscope and magnetometer.
1238      * @param hardIron       known hard-iron.
1239      * @throws IllegalArgumentException if provided hard-iron matrix is not
1240      *                                  3x1 or if provided quality scores length
1241      *                                  is smaller than 10 samples.
1242      */
1243     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1244             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1245             final boolean commonAxisUsed, final Matrix hardIron) {
1246         super(measurements, commonAxisUsed, hardIron);
1247         internalSetQualityScores(qualityScores);
1248     }
1249 
1250     /**
1251      * Constructor.
1252      *
1253      * @param qualityScores  quality scores corresponding to each provided
1254      *                       measurement. The larger the score value the better
1255      *                       the quality of the sample.
1256      * @param measurements   collection of body magnetic flux density
1257      *                       measurements with standard deviation of
1258      *                       magnetometer measurements taken at the same
1259      *                       position with zero velocity and unknown different
1260      *                       orientations.
1261      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1262      *                       for the accelerometer, gyroscope and magnetometer.
1263      * @param hardIron       known hard-iron.
1264      * @param listener       listener to handle events raised by this calibrator.
1265      * @throws IllegalArgumentException if provided hard-iron matrix is not
1266      *                                  3x1 or if provided quality scores length
1267      *                                  is smaller than 10 samples.
1268      */
1269     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1270             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1271             final boolean commonAxisUsed, final Matrix hardIron,
1272             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1273         super(measurements, commonAxisUsed, hardIron, listener);
1274         internalSetQualityScores(qualityScores);
1275     }
1276 
1277     /**
1278      * Constructor.
1279      *
1280      * @param qualityScores quality scores corresponding to each provided
1281      *                      measurement. The larger the score value the better
1282      *                      the quality of the sample.*
1283      * @param measurements  collection of body magnetic flux density
1284      *                      measurements with standard deviation of
1285      *                      magnetometer measurements taken at the same
1286      *                      position with zero velocity and unknown different
1287      *                      orientations.
1288      * @param hardIron      known hard-iron.
1289      * @param initialMm     initial soft-iron matrix containing scale factors
1290      *                      and cross coupling errors.
1291      * @throws IllegalArgumentException if provided hard-iron matrix is not
1292      *                                  3x1 or if soft-iron matrix is not
1293      *                                  3x3 or if provided quality scores length
1294      *                                  is smaller than 10 samples.
1295      */
1296     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1297             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1298             final Matrix hardIron, final Matrix initialMm) {
1299         super(measurements, hardIron, initialMm);
1300         internalSetQualityScores(qualityScores);
1301     }
1302 
1303     /**
1304      * Constructor.
1305      *
1306      * @param qualityScores quality scores corresponding to each provided
1307      *                      measurement. The larger the score value the better
1308      *                      the quality of the sample.
1309      * @param measurements  collection of body magnetic flux density
1310      *                      measurements with standard deviation of
1311      *                      magnetometer measurements taken at the same
1312      *                      position with zero velocity and unknown different
1313      *                      orientations.
1314      * @param hardIron      known hard-iron.
1315      * @param initialMm     initial soft-iron matrix containing scale factors
1316      *                      and cross coupling errors.
1317      * @param listener      listener to handle events raised by this calibrator.
1318      * @throws IllegalArgumentException if provided hard-iron matrix is not
1319      *                                  3x1 or if soft-iron matrix is not
1320      *                                  3x3 or if provided quality scores length
1321      *                                  is smaller than 10 samples.
1322      */
1323     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1324             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1325             final Matrix hardIron, final Matrix initialMm,
1326             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1327         super(measurements, hardIron, initialMm, listener);
1328         internalSetQualityScores(qualityScores);
1329     }
1330 
1331     /**
1332      * Constructor.
1333      *
1334      * @param qualityScores  quality scores corresponding to each provided
1335      *                       measurement. The larger the score value the better
1336      *                       the quality of the sample.
1337      * @param measurements   collection of body magnetic flux density
1338      *                       measurements with standard deviation of
1339      *                       magnetometer measurements taken at the same
1340      *                       position with zero velocity and unknown different
1341      *                       orientations.
1342      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1343      *                       for the accelerometer, gyroscope and magnetometer.
1344      * @param hardIron       known hard-iron.
1345      * @param initialMm      initial soft-iron matrix containing scale factors
1346      *                       and cross coupling errors.
1347      * @throws IllegalArgumentException if provided hard-iron matrix is not
1348      *                                  3x1 or if soft-iron matrix is not
1349      *                                  3x3 or if provided quality scores length
1350      *                                  is smaller than 10 samples.
1351      */
1352     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1353             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1354             final boolean commonAxisUsed, final Matrix hardIron, final Matrix initialMm) {
1355         super(measurements, commonAxisUsed, hardIron, initialMm);
1356         internalSetQualityScores(qualityScores);
1357     }
1358 
1359     /**
1360      * Constructor.
1361      *
1362      * @param qualityScores  quality scores corresponding to each provided
1363      *                       measurement. The larger the score value the better
1364      *                       the quality of the sample.
1365      * @param measurements   collection of body magnetic flux density
1366      *                       measurements with standard deviation of
1367      *                       magnetometer measurements taken at the same
1368      *                       position with zero velocity and unknown different
1369      *                       orientations.
1370      * @param commonAxisUsed indicates whether z-axis is assumed to be common
1371      *                       for the accelerometer, gyroscope and magnetometer.
1372      * @param hardIron       known hard-iron.
1373      * @param initialMm      initial soft-iron matrix containing scale factors
1374      *                       and cross coupling errors.
1375      * @param listener       listener to handle events raised by this calibrator.
1376      * @throws IllegalArgumentException if provided hard-iron matrix is not
1377      *                                  3x1 or if soft-iron matrix is not
1378      *                                  3x3 or if provided quality scores length
1379      *                                  is smaller than 10 samples.
1380      */
1381     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1382             final double[] qualityScores, final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1383             final boolean commonAxisUsed, final Matrix hardIron, final Matrix initialMm,
1384             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1385         super(measurements, commonAxisUsed, hardIron, initialMm, listener);
1386         internalSetQualityScores(qualityScores);
1387     }
1388 
1389     /**
1390      * Constructor.
1391      *
1392      * @param qualityScores                      quality scores corresponding to each provided
1393      *                                           measurement. The larger the score value the better
1394      *                                           the quality of the sample.
1395      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1396      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1397      *                                  or if provided quality scores length is smaller
1398      *                                  than 10 samples.
1399      */
1400     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1401             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm) {
1402         super(groundTruthMagneticFluxDensityNorm);
1403         internalSetQualityScores(qualityScores);
1404     }
1405 
1406     /**
1407      * Constructor.
1408      *
1409      * @param qualityScores                      quality scores corresponding to each provided
1410      *                                           measurement. The larger the score value the better
1411      *                                           the quality of the sample.
1412      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1413      * @param listener                           listener to handle events raised by this calibrator.
1414      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1415      *                                  or if provided quality scores length is smaller
1416      *                                  than 10 samples.
1417      */
1418     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1419             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1420             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1421         super(groundTruthMagneticFluxDensityNorm, listener);
1422         internalSetQualityScores(qualityScores);
1423     }
1424 
1425     /**
1426      * Constructor.
1427      *
1428      * @param qualityScores                      quality scores corresponding to each provided
1429      *                                           measurement. The larger the score value the better
1430      *                                           the quality of the sample.
1431      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1432      * @param measurements                       collection of body magnetic flux density
1433      *                                           measurements with standard deviation of
1434      *                                           magnetometer measurements taken at the same
1435      *                                           position with zero velocity and unknown different
1436      *                                           orientations.
1437      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1438      *                                  or if provided quality scores length is smaller
1439      *                                  than 10 samples.
1440      */
1441     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1442             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1443             final List<StandardDeviationBodyMagneticFluxDensity> measurements) {
1444         super(groundTruthMagneticFluxDensityNorm, measurements);
1445         internalSetQualityScores(qualityScores);
1446     }
1447 
1448     /**
1449      * Constructor.
1450      *
1451      * @param qualityScores                      quality scores corresponding to each provided
1452      *                                           measurement. The larger the score value the better
1453      *                                           the quality of the sample.
1454      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1455      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1456      *                                           for the accelerometer, gyroscope and magnetometer.
1457      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1458      *                                  or if provided quality scores length is smaller
1459      *                                  than 10 samples.
1460      */
1461     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1462             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1463             final boolean commonAxisUsed) {
1464         super(groundTruthMagneticFluxDensityNorm, commonAxisUsed);
1465         internalSetQualityScores(qualityScores);
1466     }
1467 
1468     /**
1469      * Constructor.
1470      *
1471      * @param qualityScores                      quality scores corresponding to each provided
1472      *                                           measurement. The larger the score value the better
1473      *                                           the quality of the sample.
1474      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1475      * @param hardIron                           known hard-iron.
1476      * @throws IllegalArgumentException if provided magnetic flux norm value is
1477      *                                  negative, or if provided hard-iron array does
1478      *                                  not have length 3, or if provided quality scores
1479      *                                  length is smaller than 10 samples.
1480      */
1481     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1482             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final double[] hardIron) {
1483         super(groundTruthMagneticFluxDensityNorm, hardIron);
1484         internalSetQualityScores(qualityScores);
1485     }
1486 
1487     /**
1488      * Constructor.
1489      *
1490      * @param qualityScores                      quality scores corresponding to each provided
1491      *                                           measurement. The larger the score value the better
1492      *                                           the quality of the sample.
1493      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1494      * @param hardIron                           known hard-iron.
1495      * @throws IllegalArgumentException if provided magnetic flux norm value is
1496      *                                  negative, or if provided hard-iron matrix is not
1497      *                                  3x1, or if provided quality scores length
1498      *                                  is smaller than 10 samples.
1499      */
1500     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1501             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final Matrix hardIron) {
1502         super(groundTruthMagneticFluxDensityNorm, hardIron);
1503         internalSetQualityScores(qualityScores);
1504     }
1505 
1506     /**
1507      * Constructor.
1508      *
1509      * @param qualityScores                      quality scores corresponding to each provided
1510      *                                           measurement. The larger the score value the better
1511      *                                           the quality of the sample.
1512      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1513      * @param hardIron                           known hard-iron.
1514      * @param initialMm                          initial soft-iron matrix containing scale factors
1515      *                                           and cross coupling errors.
1516      * @throws IllegalArgumentException if provided magnetic flux norm value is
1517      *                                  negative, or if provided hard-iron matrix is not
1518      *                                  3x1 or if soft-iron matrix is not
1519      *                                  3x3 or if provided quality scores length
1520      *                                  is smaller than 10 samples.
1521      */
1522     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1523             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm, final Matrix hardIron,
1524             final Matrix initialMm) {
1525         super(groundTruthMagneticFluxDensityNorm, hardIron, initialMm);
1526         internalSetQualityScores(qualityScores);
1527     }
1528 
1529     /**
1530      * Constructor.
1531      *
1532      * @param qualityScores                      quality scores corresponding to each provided
1533      *                                           measurement. The larger the score value the better
1534      *                                           the quality of the sample.
1535      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1536      * @param measurements                       collection of body magnetic flux density
1537      *                                           measurements with standard deviation of
1538      *                                           magnetometer measurements taken at the same
1539      *                                           position with zero velocity and unknown different
1540      *                                           orientations.
1541      * @param listener                           listener to handle events raised by this calibrator.
1542      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1543      *                                  or if provided quality scores length is
1544      *                                  smaller than 10 samples.
1545      */
1546     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1547             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1548             final List<StandardDeviationBodyMagneticFluxDensity> measurements,
1549             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1550         super(groundTruthMagneticFluxDensityNorm, measurements, listener);
1551         internalSetQualityScores(qualityScores);
1552     }
1553 
1554     /**
1555      * Constructor.
1556      *
1557      * @param qualityScores                      quality scores corresponding to each provided
1558      *                                           measurement. The larger the score value the better
1559      *                                           the quality of the sample.
1560      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1561      * @param measurements                       collection of body magnetic flux density
1562      *                                           measurements with standard deviation of
1563      *                                           magnetometer measurements taken at the same
1564      *                                           position with zero velocity and unknown different
1565      *                                           orientations.
1566      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1567      *                                           for the accelerometer, gyroscope and magnetometer.
1568      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1569      *                                  or if provided quality scores length is smaller
1570      *                                  than 10 samples.
1571      */
1572     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1573             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1574             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed) {
1575         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed);
1576         internalSetQualityScores(qualityScores);
1577     }
1578 
1579     /**
1580      * Constructor.
1581      *
1582      * @param qualityScores                      quality scores corresponding to each provided
1583      *                                           measurement. The larger the score value the better
1584      *                                           the quality of the sample.
1585      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1586      * @param measurements                       collection of body magnetic flux density
1587      *                                           measurements with standard deviation of
1588      *                                           magnetometer measurements taken at the same
1589      *                                           position with zero velocity and unknown different
1590      *                                           orientations.
1591      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1592      *                                           for the accelerometer, gyroscope and magnetometer.
1593      * @param listener                           listener to handle events raised by this calibrator.
1594      * @throws IllegalArgumentException if provided magnetic flux norm value is negative
1595      *                                  or if provided quality scores length is smaller
1596      *                                  than 10 samples.
1597      */
1598     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1599             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1600             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1601             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1602         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, listener);
1603         internalSetQualityScores(qualityScores);
1604     }
1605 
1606     /**
1607      * Constructor.
1608      *
1609      * @param qualityScores                      quality scores corresponding to each provided
1610      *                                           measurement. The larger the score value the better
1611      *                                           the quality of the sample.
1612      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1613      * @param measurements                       collection of body magnetic flux density
1614      *                                           measurements with standard deviation of
1615      *                                           magnetometer measurements taken at the same
1616      *                                           position with zero velocity and unknown different
1617      *                                           orientations.
1618      * @param hardIron                           known hard-iron.
1619      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1620      *                                  or if provided hard-iron array does not have length 3,
1621      *                                  or if provided quality scores length is smaller
1622      *                                  than 10 samples.
1623      */
1624     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1625             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1626             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron) {
1627         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron);
1628         internalSetQualityScores(qualityScores);
1629     }
1630 
1631     /**
1632      * Constructor.
1633      *
1634      * @param qualityScores                      quality scores corresponding to each provided
1635      *                                           measurement. The larger the score value the better
1636      *                                           the quality of the sample.
1637      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1638      * @param measurements                       collection of body magnetic flux density
1639      *                                           measurements with standard deviation of
1640      *                                           magnetometer measurements taken at the same
1641      *                                           position with zero velocity and unknown different
1642      *                                           orientations.
1643      * @param hardIron                           known hard-iron.
1644      * @param listener                           listener to handle events raised by this calibrator.
1645      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1646      *                                  or if provided hard-iron array does not have length 3,
1647      *                                  or if provided quality scores length is smaller
1648      *                                  than 10 samples.
1649      */
1650     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1651             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1652             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final double[] hardIron,
1653             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1654         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, listener);
1655         internalSetQualityScores(qualityScores);
1656     }
1657 
1658     /**
1659      * Constructor.
1660      *
1661      * @param qualityScores                      quality scores corresponding to each provided
1662      *                                           measurement. The larger the score value the better
1663      *                                           the quality of the sample.
1664      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1665      * @param measurements                       collection of body magnetic flux density
1666      *                                           measurements with standard deviation of
1667      *                                           magnetometer measurements taken at the same
1668      *                                           position with zero velocity and unknown different
1669      *                                           orientations.
1670      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1671      *                                           for the accelerometer, gyroscope and magnetometer.
1672      * @param hardIron                           known hard-iron.
1673      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1674      *                                  or if provided hard-iron array does not have length 3,
1675      *                                  or if provided quality scores length is smaller
1676      *                                  than 10 samples.
1677      */
1678     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1679             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1680             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1681             final double[] hardIron) {
1682         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron);
1683         internalSetQualityScores(qualityScores);
1684     }
1685 
1686     /**
1687      * Constructor.
1688      *
1689      * @param qualityScores                      quality scores corresponding to each provided
1690      *                                           measurement. The larger the score value the better
1691      *                                           the quality of the sample.
1692      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1693      * @param measurements                       collection of body magnetic flux density
1694      *                                           measurements with standard deviation of
1695      *                                           magnetometer measurements taken at the same
1696      *                                           position with zero velocity and unknown different
1697      *                                           orientations.
1698      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1699      *                                           for the accelerometer, gyroscope and magnetometer.
1700      * @param hardIron                           known hard-iron.
1701      * @param listener                           listener to handle events raised by this calibrator.
1702      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1703      *                                  or if provided hard-iron array does not have length 3,
1704      *                                  or if provided quality scores length is smaller
1705      *                                  than 10 samples.
1706      */
1707     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1708             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1709             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1710             final double[] hardIron,
1711             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1712         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, listener);
1713         internalSetQualityScores(qualityScores);
1714     }
1715 
1716     /**
1717      * Constructor.
1718      *
1719      * @param qualityScores                      quality scores corresponding to each provided
1720      *                                           measurement. The larger the score value the better
1721      *                                           the quality of the sample.
1722      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1723      * @param measurements                       collection of body magnetic flux density
1724      *                                           measurements with standard deviation of
1725      *                                           magnetometer measurements taken at the same
1726      *                                           position with zero velocity and unknown different
1727      *                                           orientations.
1728      * @param hardIron                           known hard-iron.
1729      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1730      *                                  or if provided hard-iron matrix is not 3x1,
1731      *                                  or if provided quality scores length is smaller
1732      *                                  than 10 samples.
1733      */
1734     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1735             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1736             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron) {
1737         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron);
1738         internalSetQualityScores(qualityScores);
1739     }
1740 
1741     /**
1742      * Constructor.
1743      *
1744      * @param qualityScores                      quality scores corresponding to each provided
1745      *                                           measurement. The larger the score value the better
1746      *                                           the quality of the sample.
1747      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1748      * @param measurements                       collection of body magnetic flux density
1749      *                                           measurements with standard deviation of
1750      *                                           magnetometer measurements taken at the same
1751      *                                           position with zero velocity and unknown different
1752      *                                           orientations.
1753      * @param hardIron                           known hard-iron.
1754      * @param listener                           listener to handle events raised by this calibrator.
1755      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1756      *                                  or if provided hard-iron matrix is not 3x1,
1757      *                                  or if provided quality scores length is smaller
1758      *                                  than 10 samples.
1759      */
1760     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1761             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1762             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
1763             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1764         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, listener);
1765         internalSetQualityScores(qualityScores);
1766     }
1767 
1768     /**
1769      * Constructor.
1770      *
1771      * @param qualityScores                      quality scores corresponding to each provided
1772      *                                           measurement. The larger the score value the better
1773      *                                           the quality of the sample.
1774      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1775      * @param measurements                       collection of body magnetic flux density
1776      *                                           measurements with standard deviation of
1777      *                                           magnetometer measurements taken at the same
1778      *                                           position with zero velocity and unknown different
1779      *                                           orientations.
1780      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1781      *                                           for the accelerometer, gyroscope and magnetometer.
1782      * @param hardIron                           known hard-iron.
1783      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1784      *                                  or if provided hard-iron matrix is not 3x1,
1785      *                                  or if provided quality scores length is smaller
1786      *                                  than 10 samples.
1787      */
1788     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1789             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1790             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1791             final Matrix hardIron) {
1792         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron);
1793         internalSetQualityScores(qualityScores);
1794     }
1795 
1796     /**
1797      * Constructor.
1798      *
1799      * @param qualityScores                      quality scores corresponding to each provided
1800      *                                           measurement. The larger the score value the better
1801      *                                           the quality of the sample.
1802      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1803      * @param measurements                       collection of body magnetic flux density
1804      *                                           measurements with standard deviation of
1805      *                                           magnetometer measurements taken at the same
1806      *                                           position with zero velocity and unknown different
1807      *                                           orientations.
1808      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1809      *                                           for the accelerometer, gyroscope and magnetometer.
1810      * @param hardIron                           known hard-iron.
1811      * @param listener                           listener to handle events raised by this calibrator.
1812      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1813      *                                  or if provided hard-iron matrix is not 3x1,
1814      *                                  or if provided quality scores length is smaller
1815      *                                  than 10 samples.
1816      */
1817     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1818             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1819             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1820             final Matrix hardIron,
1821             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1822         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, listener);
1823         internalSetQualityScores(qualityScores);
1824     }
1825 
1826     /**
1827      * Constructor.
1828      *
1829      * @param qualityScores                      quality scores corresponding to each provided
1830      *                                           measurement. The larger the score value the better
1831      *                                           the quality of the sample.
1832      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1833      * @param measurements                       collection of body magnetic flux density
1834      *                                           measurements with standard deviation of
1835      *                                           magnetometer measurements taken at the same
1836      *                                           position with zero velocity and unknown different
1837      *                                           orientations.
1838      * @param hardIron                           known hard-iron.
1839      * @param initialMm                          initial soft-iron matrix containing scale factors
1840      *                                           and cross coupling errors.
1841      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1842      *                                  or if provided hard-iron matrix is not 3x1 or if
1843      *                                  soft-iron matrix is not 3x3, or if provided
1844      *                                  quality scores length is smaller than 10 samples.
1845      */
1846     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1847             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1848             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
1849             final Matrix initialMm) {
1850         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, initialMm);
1851         internalSetQualityScores(qualityScores);
1852     }
1853 
1854     /**
1855      * Constructor.
1856      *
1857      * @param qualityScores                      quality scores corresponding to each provided
1858      *                                           measurement. The larger the score value the better
1859      *                                           the quality of the sample.
1860      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1861      * @param measurements                       collection of body magnetic flux density
1862      *                                           measurements with standard deviation of
1863      *                                           magnetometer measurements taken at the same
1864      *                                           position with zero velocity and unknown different
1865      *                                           orientations.
1866      * @param hardIron                           known hard-iron.
1867      * @param initialMm                          initial soft-iron matrix containing scale factors
1868      *                                           and cross coupling errors.
1869      * @param listener                           listener to handle events raised by this calibrator.
1870      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1871      *                                  or if provided hard-iron matrix is not 3x1 or if
1872      *                                  soft-iron matrix is not 3x3, or if provided
1873      *                                  quality scores length is smaller than 10 samples.
1874      */
1875     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1876             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1877             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final Matrix hardIron,
1878             final Matrix initialMm,
1879             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1880         super(groundTruthMagneticFluxDensityNorm, measurements, hardIron, initialMm, listener);
1881         internalSetQualityScores(qualityScores);
1882     }
1883 
1884     /**
1885      * Constructor.
1886      *
1887      * @param qualityScores                      quality scores corresponding to each provided
1888      *                                           measurement. The larger the score value the better
1889      *                                           the quality of the sample.
1890      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1891      * @param measurements                       collection of body magnetic flux density
1892      *                                           measurements with standard deviation of
1893      *                                           magnetometer measurements taken at the same
1894      *                                           position with zero velocity and unknown different
1895      *                                           orientations.
1896      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1897      *                                           for the accelerometer, gyroscope and magnetometer.
1898      * @param hardIron                           known hard-iron.
1899      * @param initialMm                          initial soft-iron matrix containing scale factors
1900      *                                           and cross coupling errors.
1901      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1902      *                                  or if provided hard-iron matrix is not 3x1
1903      *                                  or if soft-iron matrix is not 3x3, or if
1904      *                                  provided quality scores length is smaller
1905      *                                  than 10 samples.
1906      */
1907     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1908             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1909             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1910             final Matrix hardIron, final Matrix initialMm) {
1911         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, initialMm);
1912         internalSetQualityScores(qualityScores);
1913     }
1914 
1915     /**
1916      * Constructor.
1917      *
1918      * @param qualityScores                      quality scores corresponding to each provided
1919      *                                           measurement. The larger the score value the better
1920      *                                           the quality of the sample.
1921      * @param groundTruthMagneticFluxDensityNorm ground truth magnetic flux density norm expressed in Teslas (T).
1922      * @param measurements                       collection of body magnetic flux density
1923      *                                           measurements with standard deviation of
1924      *                                           magnetometer measurements taken at the same
1925      *                                           position with zero velocity and unknown different
1926      *                                           orientations.
1927      * @param commonAxisUsed                     indicates whether z-axis is assumed to be common
1928      *                                           for the accelerometer, gyroscope and magnetometer.
1929      * @param hardIron                           known hard-iron.
1930      * @param initialMm                          initial soft-iron matrix containing scale factors
1931      *                                           and cross coupling errors.
1932      * @param listener                           listener to handle events raised by this calibrator.
1933      * @throws IllegalArgumentException if provided magnetic flux norm value is negative,
1934      *                                  or if provided hard-iron matrix is not 3x1
1935      *                                  or if soft-iron matrix is not 3x3, or if
1936      *                                  provided quality scores length is smaller
1937      *                                  than 10 samples.
1938      */
1939     public PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator(
1940             final double[] qualityScores, final Double groundTruthMagneticFluxDensityNorm,
1941             final List<StandardDeviationBodyMagneticFluxDensity> measurements, final boolean commonAxisUsed,
1942             final Matrix hardIron, final Matrix initialMm,
1943             final RobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibratorListener listener) {
1944         super(groundTruthMagneticFluxDensityNorm, measurements, commonAxisUsed, hardIron, initialMm, listener);
1945         internalSetQualityScores(qualityScores);
1946     }
1947 
1948 
1949     /**
1950      * Returns threshold to be used to keep the algorithm iterating in case that
1951      * best estimated threshold using median of residuals is not small enough.
1952      * Once a solution is found that generates a threshold below this value, the
1953      * algorithm will stop.
1954      * The stop threshold can be used to prevent the LMedS algorithm to iterate
1955      * too many times in cases where samples have a very similar accuracy.
1956      * For instance, in cases where proportion of outliers is very small (close
1957      * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
1958      * iterate for a long time trying to find the best solution when indeed
1959      * there is no need to do that if a reasonable threshold has already been
1960      * reached.
1961      * Because of this behaviour the stop threshold can be set to a value much
1962      * lower than the one typically used in RANSAC, and yet the algorithm could
1963      * still produce even smaller thresholds in estimated results.
1964      *
1965      * @return stop threshold to stop the algorithm prematurely when a certain
1966      * accuracy has been reached.
1967      */
1968     public double getStopThreshold() {
1969         return stopThreshold;
1970     }
1971 
1972     /**
1973      * Sets threshold to be used to keep the algorithm iterating in case that
1974      * best estimated threshold using median of residuals is not small enough.
1975      * Once a solution is found that generates a threshold below this value,
1976      * the algorithm will stop.
1977      * The stop threshold can be used to prevent the LMedS algorithm to iterate
1978      * too many times in cases where samples have a very similar accuracy.
1979      * For instance, in cases where proportion of outliers is very small (close
1980      * to 0%), and samples are very accurate (i.e. 1e-6), the algorithm would
1981      * iterate for a long time trying to find the best solution when indeed
1982      * there is no need to do that if a reasonable threshold has already been
1983      * reached.
1984      * Because of this behaviour the stop threshold can be set to a value much
1985      * lower than the one typically used in RANSAC, and yet the algorithm could
1986      * still produce even smaller thresholds in estimated results.
1987      *
1988      * @param stopThreshold stop threshold to stop the algorithm prematurely
1989      *                      when a certain accuracy has been reached.
1990      * @throws IllegalArgumentException if provided value is zero or negative.
1991      * @throws LockedException          if calibrator is currently running.
1992      */
1993     public void setStopThreshold(final double stopThreshold) throws LockedException {
1994         if (running) {
1995             throw new LockedException();
1996         }
1997         if (stopThreshold <= MIN_STOP_THRESHOLD) {
1998             throw new IllegalArgumentException();
1999         }
2000 
2001         this.stopThreshold = stopThreshold;
2002     }
2003 
2004     /**
2005      * Returns quality scores corresponding to each provided sample.
2006      * The larger the score value the better the quality of the sample.
2007      *
2008      * @return quality scores corresponding to each sample.
2009      */
2010     @Override
2011     public double[] getQualityScores() {
2012         return qualityScores;
2013     }
2014 
2015     /**
2016      * Sets quality scores corresponding to each provided sample.
2017      * The larger the score value the better the quality of the sample.
2018      *
2019      * @param qualityScores quality scores corresponding to each sample.
2020      * @throws IllegalArgumentException if provided quality scores length
2021      *                                  is smaller than minimum required samples.
2022      * @throws LockedException          if calibrator is currently running.
2023      */
2024     @Override
2025     public void setQualityScores(final double[] qualityScores) throws LockedException {
2026         if (running) {
2027             throw new LockedException();
2028         }
2029         internalSetQualityScores(qualityScores);
2030     }
2031 
2032     /**
2033      * Indicates whether calibrator is ready to find a solution.
2034      *
2035      * @return true if calibrator is ready, false otherwise.
2036      */
2037     @Override
2038     public boolean isReady() {
2039         return super.isReady() && qualityScores != null && qualityScores.length == measurements.size();
2040     }
2041 
2042     /**
2043      * Estimates magnetometer calibration parameters containing hard-iron
2044      * bias and soft-iron scale factors and cross-coupling errors.
2045      *
2046      * @throws LockedException      if calibrator is currently running.
2047      * @throws NotReadyException    if calibrator is not ready.
2048      * @throws CalibrationException if estimation fails for numerical reasons.
2049      */
2050     @SuppressWarnings("DuplicatedCode")
2051     @Override
2052     public void calibrate() throws LockedException, NotReadyException, CalibrationException {
2053         if (running) {
2054             throw new LockedException();
2055         }
2056         if (!isReady()) {
2057             throw new NotReadyException();
2058         }
2059 
2060         final var innerEstimator = new PROMedSRobustEstimator<>(
2061                 new PROMedSRobustEstimatorListener<PreliminaryResult>() {
2062                     @Override
2063                     public double[] getQualityScores() {
2064                         return qualityScores;
2065                     }
2066 
2067                     @Override
2068                     public double getThreshold() {
2069                         return stopThreshold;
2070                     }
2071 
2072                     @Override
2073                     public int getTotalSamples() {
2074                         return measurements.size();
2075                     }
2076 
2077                     @Override
2078                     public int getSubsetSize() {
2079                         return preliminarySubsetSize;
2080                     }
2081 
2082                     @Override
2083                     public void estimatePreliminarSolutions(
2084                             final int[] samplesIndices, final List<PreliminaryResult> solutions) {
2085                         computePreliminarySolutions(samplesIndices, solutions);
2086                     }
2087 
2088                     @Override
2089                     public double computeResidual(final PreliminaryResult currentEstimation, final int i) {
2090                         return computeError(measurements.get(i), currentEstimation);
2091                     }
2092 
2093                     @Override
2094                     public boolean isReady() {
2095                         return PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator.this.isReady();
2096                     }
2097 
2098                     @Override
2099                     public void onEstimateStart(final RobustEstimator<PreliminaryResult> estimator) {
2100                         // no action needed
2101                     }
2102 
2103                     @Override
2104                     public void onEstimateEnd(final RobustEstimator<PreliminaryResult> estimator) {
2105                         // no action needed
2106                     }
2107 
2108                     @Override
2109                     public void onEstimateNextIteration(
2110                             final RobustEstimator<PreliminaryResult> estimator, final int iteration) {
2111                         if (listener != null) {
2112                             listener.onCalibrateNextIteration(
2113                                     PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator.this,
2114                                     iteration);
2115                         }
2116                     }
2117 
2118                     @Override
2119                     public void onEstimateProgressChange(
2120                             final RobustEstimator<PreliminaryResult> estimator, final float progress) {
2121                         if (listener != null) {
2122                             listener.onCalibrateProgressChange(
2123                                     PROMedSRobustKnownHardIronMagneticFluxDensityNormMagnetometerCalibrator.this,
2124                                     progress);
2125                         }
2126                     }
2127                 });
2128 
2129         try {
2130             running = true;
2131 
2132             if (listener != null) {
2133                 listener.onCalibrateStart(this);
2134             }
2135 
2136             inliersData = null;
2137 
2138             innerEstimator.setUseInlierThresholds(true);
2139             innerEstimator.setConfidence(confidence);
2140             innerEstimator.setMaxIterations(maxIterations);
2141             innerEstimator.setProgressDelta(progressDelta);
2142             final var preliminaryResult = innerEstimator.estimate();
2143             inliersData = innerEstimator.getInliersData();
2144 
2145             attemptRefine(preliminaryResult);
2146 
2147             if (listener != null) {
2148                 listener.onCalibrateEnd(this);
2149             }
2150 
2151         } catch (final com.irurueta.numerical.LockedException e) {
2152             throw new LockedException(e);
2153         } catch (final com.irurueta.numerical.NotReadyException e) {
2154             throw new NotReadyException(e);
2155         } catch (final RobustEstimatorException e) {
2156             throw new CalibrationException(e);
2157         } finally {
2158             running = false;
2159         }
2160     }
2161 
2162     /**
2163      * Returns method being used for robust estimation.
2164      *
2165      * @return method being used for robust estimation.
2166      */
2167     @Override
2168     public RobustEstimatorMethod getMethod() {
2169         return RobustEstimatorMethod.PROMEDS;
2170     }
2171 
2172     /**
2173      * Indicates whether this calibrator requires quality scores for each
2174      * measurement or not.
2175      *
2176      * @return true if quality scores are required, false otherwise.
2177      */
2178     @Override
2179     public boolean isQualityScoresRequired() {
2180         return true;
2181     }
2182 
2183     /**
2184      * Sets quality scores corresponding to each provided sample.
2185      * This method is used internally and does not check whether instance is
2186      * locked or not.
2187      *
2188      * @param qualityScores quality scores to be set.
2189      * @throws IllegalArgumentException if provided quality scores length
2190      *                                  is smaller than 4 samples.
2191      */
2192     private void internalSetQualityScores(final double[] qualityScores) {
2193         if (qualityScores == null || qualityScores.length < MINIMUM_MEASUREMENTS_COMMON_Z_AXIS) {
2194             throw new IllegalArgumentException();
2195         }
2196 
2197         this.qualityScores = qualityScores;
2198     }
2199 }