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