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