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