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.gyroscope;
17  
18  import com.irurueta.algebra.Matrix;
19  import com.irurueta.navigation.LockedException;
20  import com.irurueta.navigation.NotReadyException;
21  import com.irurueta.navigation.inertial.calibration.CalibrationException;
22  import com.irurueta.navigation.inertial.calibration.StandardDeviationFrameBodyKinematics;
23  import com.irurueta.numerical.robust.MSACRobustEstimator;
24  import com.irurueta.numerical.robust.MSACRobustEstimatorListener;
25  import com.irurueta.numerical.robust.RobustEstimator;
26  import com.irurueta.numerical.robust.RobustEstimatorException;
27  import com.irurueta.numerical.robust.RobustEstimatorMethod;
28  import com.irurueta.units.AngularSpeed;
29  
30  import java.util.List;
31  
32  /**
33   * Robustly estimates gyroscope cross couplings and scaling factors
34   * along with G-dependent cross biases introduced on the gyroscope by the
35   * specific forces sensed by the accelerometer using an MSAC algorithm to discard
36   * outliers.
37   * This estimator assumes that biases are known.
38   * <p>
39   * To use this calibrator at least 6 measurements at different known frames must
40   * be provided. In other words, accelerometer and gyroscope (i.e. body kinematics)
41   * samples must be obtained at 6 different positions, orientations and velocities
42   * (although typically velocities are always zero).
43   * <p>
44   * Measured gyroscope angular rates is assumed to follow the model shown below:
45   * <pre>
46   *     Ωmeas = bg + (I + Mg) * Ωtrue + Gg * ftrue + w
47   * </pre>
48   * Where:
49   * - Ωmeas is the measured gyroscope angular rates. This is a 3x1 vector.
50   * - bg is the gyroscope bias. Ideally, on a perfect gyroscope, this should be a
51   * 3x1 zero vector.
52   * - I is the 3x3 identity matrix.
53   * - Mg is the 3x3 matrix containing cross-couplings and scaling factors. Ideally, on
54   * a perfect gyroscope, this should be a 3x3 zero matrix.
55   * - Ωtrue is ground-truth gyroscope angular rates.
56   * - Gg is the G-dependent cross biases introduced by the specific forces sensed
57   * by the accelerometer. Ideally, on a perfect gyroscope, this should be a 3x3
58   * zero matrix.
59   * - ftrue is ground-truth specific force. This is a 3x1 vector.
60   * - w is measurement noise. This is a 3x1 vector.
61   */
62  public class MSACRobustKnownBiasAndFrameGyroscopeCalibrator extends RobustKnownBiasAndFrameGyroscopeCalibrator {
63      /**
64       * Constant defining default threshold to determine whether samples are inliers or not.
65       */
66      public static final double DEFAULT_THRESHOLD = 1e-2;
67  
68      /**
69       * Minimum value that can be set as threshold.
70       * Threshold must be strictly greater than 0.0.
71       */
72      public static final double MIN_THRESHOLD = 0.0;
73  
74      /**
75       * Threshold to determine whether samples are inliers or not when testing possible solutions.
76       * The threshold refers to the amount of error on distance between estimated position and
77       * distances provided for each sample.
78       */
79      private double threshold = DEFAULT_THRESHOLD;
80  
81      /**
82       * Constructor.
83       */
84      public MSACRobustKnownBiasAndFrameGyroscopeCalibrator() {
85          super();
86      }
87  
88      /**
89       * Constructor.
90       *
91       * @param listener listener to be notified of events such as when estimation
92       *                 starts, ends or its progress significantly changes.
93       */
94      public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
95              final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
96          super(listener);
97      }
98  
99      /**
100      * Constructor.
101      *
102      * @param measurements list of body kinematics measurements with standard
103      *                     deviations taken at different frames (positions, orientations
104      *                     and velocities).
105      */
106     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
107             final List<StandardDeviationFrameBodyKinematics> measurements) {
108         super(measurements);
109     }
110 
111     /**
112      * Constructor.
113      *
114      * @param measurements list of body kinematics measurements with standard
115      *                     deviations taken at different frames (positions, orientations
116      *                     and velocities).
117      * @param listener     listener to handle events raised by this calibrator.
118      */
119     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
120             final List<StandardDeviationFrameBodyKinematics> measurements,
121             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
122         super(measurements, listener);
123     }
124 
125     /**
126      * Constructor.
127      *
128      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
129      *                       accelerometer and gyroscope.
130      */
131     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final boolean commonAxisUsed) {
132         super(commonAxisUsed);
133     }
134 
135     /**
136      * Constructor.
137      *
138      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
139      *                       accelerometer and gyroscope.
140      * @param listener       listener to handle events raised by this calibrator.
141      */
142     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
143             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
144         super(commonAxisUsed, listener);
145     }
146 
147     /**
148      * Constructor.
149      *
150      * @param measurements   list of body kinematics measurements with standard
151      *                       deviations taken at different frames (positions, orientations
152      *                       and velocities).
153      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
154      *                       accelerometer and gyroscope.
155      */
156     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
157             final List<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed) {
158         super(measurements, commonAxisUsed);
159     }
160 
161     /**
162      * Constructor.
163      *
164      * @param measurements   list of body kinematics measurements with standard
165      *                       deviations taken at different frames (positions, orientations
166      *                       and velocities).
167      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
168      *                       accelerometer and gyroscope.
169      * @param listener       listener to handle events raised by this calibrator.
170      */
171     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
172             final List<StandardDeviationFrameBodyKinematics> measurements,
173             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
174         super(measurements, commonAxisUsed, listener);
175     }
176 
177     /**
178      * Constructor.
179      *
180      * @param biasX known x coordinate of gyroscope bias expressed in radians per
181      *              second (rad/s).
182      * @param biasY known y coordinate of gyroscope bias expressed in radians per
183      *              second (rad/s).
184      * @param biasZ known z coordinate of gyroscope bias expressed in radians per
185      *              second (rad/s).
186      */
187     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final double biasX, final double biasY, final double biasZ) {
188         super(biasX, biasY, biasZ);
189     }
190 
191     /**
192      * Constructor.
193      *
194      * @param biasX    known x coordinate of gyroscope bias expressed in radians per
195      *                 second (rad/s).
196      * @param biasY    known y coordinate of gyroscope bias expressed in radians per
197      *                 second (rad/s).
198      * @param biasZ    known z coordinate of gyroscope bias expressed in radians per
199      *                 second (rad/s).
200      * @param listener listener to be notified of events such as when estimation
201      *                 starts, ends or its progress significantly changes.
202      */
203     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
204             final double biasX, final double biasY, final double biasZ,
205             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
206         super(biasX, biasY, biasZ, listener);
207     }
208 
209     /**
210      * Constructor.
211      *
212      * @param measurements list of body kinematics measurements with standard
213      *                     deviations taken at different frames (positions, orientations
214      *                     and velocities).
215      * @param biasX        known x coordinate of gyroscope bias expressed in radians per
216      *                     second (rad/s).
217      * @param biasY        known y coordinate of gyroscope bias expressed in radians per
218      *                     second (rad/s).
219      * @param biasZ        known z coordinate of gyroscope bias expressed in radians per
220      *                     second (rad/s).
221      */
222     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
223             final List<StandardDeviationFrameBodyKinematics> measurements,
224             final double biasX, final double biasY, final double biasZ) {
225         super(measurements, biasX, biasY, biasZ);
226     }
227 
228     /**
229      * Constructor.
230      *
231      * @param measurements list of body kinematics measurements with standard
232      *                     deviations taken at different frames (positions, orientations
233      *                     and velocities).
234      * @param biasX        known x coordinate of gyroscope bias expressed in radians per
235      *                     second (rad/s).
236      * @param biasY        known y coordinate of gyroscope bias expressed in radians per
237      *                     second (rad/s).
238      * @param biasZ        known z coordinate of gyroscope bias expressed in radians per
239      *                     second (rad/s).
240      * @param listener     listener to handle events raised by this calibrator.
241      */
242     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
243             final List<StandardDeviationFrameBodyKinematics> measurements,
244             final double biasX, final double biasY, final double biasZ,
245             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
246         super(measurements, biasX, biasY, biasZ, listener);
247     }
248 
249     /**
250      * Constructor.
251      *
252      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
253      *                       second (rad/s).
254      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
255      *                       second (rad/s).
256      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
257      *                       second (rad/s).
258      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
259      *                       accelerometer and gyroscope.
260      */
261     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
262             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed) {
263         super(biasX, biasY, biasZ, commonAxisUsed);
264     }
265 
266     /**
267      * Constructor.
268      *
269      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
270      *                       second (rad/s).
271      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
272      *                       second (rad/s).
273      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
274      *                       second (rad/s).
275      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
276      *                       accelerometer and gyroscope.
277      * @param listener       listener to handle events raised by this calibrator.
278      */
279     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
280             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed,
281             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
282         super(biasX, biasY, biasZ, commonAxisUsed, listener);
283     }
284 
285     /**
286      * Constructor.
287      *
288      * @param measurements   list of body kinematics measurements with standard
289      *                       deviations taken at different frames (positions, orientations
290      *                       and velocities).
291      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
292      *                       second (rad/s).
293      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
294      *                       second (rad/s).
295      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
296      *                       second (rad/s).
297      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
298      *                       accelerometer and gyroscope.
299      */
300     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
301             final List<StandardDeviationFrameBodyKinematics> measurements,
302             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed) {
303         super(measurements, biasX, biasY, biasZ, commonAxisUsed);
304     }
305 
306     /**
307      * Constructor.
308      *
309      * @param measurements   list of body kinematics measurements with standard
310      *                       deviations taken at different frames (positions, orientations
311      *                       and velocities).
312      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
313      *                       second (rad/s).
314      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
315      *                       second (rad/s).
316      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
317      *                       second (rad/s).
318      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
319      *                       accelerometer and gyroscope.
320      * @param listener       listener to handle events raised by this calibrator.
321      */
322     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
323             final List<StandardDeviationFrameBodyKinematics> measurements,
324             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed,
325             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
326         super(measurements, biasX, biasY, biasZ, commonAxisUsed, listener);
327     }
328 
329     /**
330      * Constructor.
331      *
332      * @param biasX known x coordinate of gyroscope bias.
333      * @param biasY known y coordinate of gyroscope bias.
334      * @param biasZ known z coordinate of gyroscope bias.
335      */
336     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
337             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ) {
338         super(biasX, biasY, biasZ);
339     }
340 
341     /**
342      * Constructor.
343      *
344      * @param biasX    known x coordinate of gyroscope bias.
345      * @param biasY    known y coordinate of gyroscope bias.
346      * @param biasZ    known z coordinate of gyroscope bias.
347      * @param listener listener to be notified of events such as when estimation
348      *                 starts, ends or its progress significantly changes.
349      */
350     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
351             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
352             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
353         super(biasX, biasY, biasZ, listener);
354     }
355 
356     /**
357      * Constructor.
358      *
359      * @param measurements list of body kinematics measurements with standard
360      *                     deviations taken at different frames (positions, orientations
361      *                     and velocities).
362      * @param biasX        known x coordinate of gyroscope bias.
363      * @param biasY        known y coordinate of gyroscope bias.
364      * @param biasZ        known z coordinate of gyroscope bias.
365      */
366     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
367             final List<StandardDeviationFrameBodyKinematics> measurements,
368             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ) {
369         super(measurements, biasX, biasY, biasZ);
370     }
371 
372     /**
373      * Constructor.
374      *
375      * @param measurements list of body kinematics measurements with standard
376      *                     deviations taken at different frames (positions, orientations
377      *                     and velocities).
378      * @param biasX        known x coordinate of gyroscope bias.
379      * @param biasY        known y coordinate of gyroscope bias.
380      * @param biasZ        known z coordinate of gyroscope bias.
381      * @param listener     listener to handle events raised by this calibrator.
382      */
383     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
384             final List<StandardDeviationFrameBodyKinematics> measurements,
385             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
386             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
387         super(measurements, biasX, biasY, biasZ, listener);
388     }
389 
390     /**
391      * Constructor.
392      *
393      * @param biasX          known x coordinate of gyroscope bias.
394      * @param biasY          known y coordinate of gyroscope bias.
395      * @param biasZ          known z coordinate of gyroscope bias.
396      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
397      *                       accelerometer and gyroscope.
398      */
399     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
400             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
401             final boolean commonAxisUsed) {
402         super(biasX, biasY, biasZ, commonAxisUsed);
403     }
404 
405     /**
406      * Constructor.
407      *
408      * @param biasX          known x coordinate of gyroscope bias.
409      * @param biasY          known y coordinate of gyroscope bias.
410      * @param biasZ          known z coordinate of gyroscope bias.
411      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
412      *                       accelerometer and gyroscope.
413      * @param listener       listener to handle events raised by this calibrator.
414      */
415     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
416             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ, final boolean commonAxisUsed,
417             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
418         super(biasX, biasY, biasZ, commonAxisUsed, listener);
419     }
420 
421     /**
422      * Constructor.
423      *
424      * @param measurements   list of body kinematics measurements with standard
425      *                       deviations taken at different frames (positions, orientations
426      *                       and velocities).
427      * @param biasX          known x coordinate of gyroscope bias.
428      * @param biasY          known y coordinate of gyroscope bias.
429      * @param biasZ          known z coordinate of gyroscope bias.
430      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
431      *                       accelerometer and gyroscope.
432      */
433     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
434             final List<StandardDeviationFrameBodyKinematics> measurements,
435             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
436             final boolean commonAxisUsed) {
437         super(measurements, biasX, biasY, biasZ, commonAxisUsed);
438     }
439 
440     /**
441      * Constructor.
442      *
443      * @param measurements   list of body kinematics measurements with standard
444      *                       deviations taken at different frames (positions, orientations
445      *                       and velocities).
446      * @param biasX          known x coordinate of gyroscope bias.
447      * @param biasY          known y coordinate of gyroscope bias.
448      * @param biasZ          known z coordinate of gyroscope bias.
449      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
450      *                       accelerometer and gyroscope.
451      * @param listener       listener to handle events raised by this calibrator.
452      */
453     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
454             final List<StandardDeviationFrameBodyKinematics> measurements,
455             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ, final boolean commonAxisUsed,
456             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
457         super(measurements, biasX, biasY, biasZ, commonAxisUsed, listener);
458     }
459 
460     /**
461      * Constructor.
462      *
463      * @param bias known gyroscope bias.
464      * @throws IllegalArgumentException if provided array does not have length 3.
465      */
466     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final double[] bias) {
467         super(bias);
468     }
469 
470     /**
471      * Constructor.
472      *
473      * @param bias     known gyroscope bias.
474      * @param listener listener to be notified of events such as when estimation
475      *                 starts, ends or its progress significantly changes.
476      * @throws IllegalArgumentException if provided array does not have length 3.
477      */
478     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
479             final double[] bias, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
480         super(bias, listener);
481     }
482 
483     /**
484      * Constructor.
485      *
486      * @param measurements list of body kinematics measurements with standard
487      *                     deviations taken at different frames (positions, orientations
488      *                     and velocities).
489      * @param bias         known gyroscope bias.
490      * @throws IllegalArgumentException if provided array does not have length 3.
491      */
492     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
493             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias) {
494         super(measurements, bias);
495     }
496 
497     /**
498      * Constructor.
499      *
500      * @param measurements list of body kinematics measurements with standard
501      *                     deviations taken at different frames (positions, orientations
502      *                     and velocities).
503      * @param bias         known gyroscope bias.
504      * @param listener     listener to handle events raised by this calibrator.
505      * @throws IllegalArgumentException if provided array does not have length 3.
506      */
507     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
508             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
509             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
510         super(measurements, bias, listener);
511     }
512 
513     /**
514      * Constructor.
515      *
516      * @param bias           known gyroscope bias.
517      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
518      *                       accelerometer and gyroscope.
519      * @throws IllegalArgumentException if provided array does not have length 3.
520      */
521     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final double[] bias, final boolean commonAxisUsed) {
522         super(bias, commonAxisUsed);
523     }
524 
525     /**
526      * Constructor.
527      *
528      * @param bias           known gyroscope bias.
529      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
530      *                       accelerometer and gyroscope.
531      * @param listener       listener to handle events raised by this calibrator.
532      * @throws IllegalArgumentException if provided array does not have length 3.
533      */
534     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
535             final double[] bias, final boolean commonAxisUsed,
536             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
537         super(bias, commonAxisUsed, listener);
538     }
539 
540     /**
541      * Constructor.
542      *
543      * @param measurements   list of body kinematics measurements with standard
544      *                       deviations taken at different frames (positions, orientations
545      *                       and velocities).
546      * @param bias           known gyroscope bias.
547      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
548      *                       accelerometer and gyroscope.
549      * @throws IllegalArgumentException if provided array does not have length 3.
550      */
551     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
552             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
553             final boolean commonAxisUsed) {
554         super(measurements, bias, commonAxisUsed);
555     }
556 
557     /**
558      * Constructor.
559      *
560      * @param measurements   list of body kinematics measurements with standard
561      *                       deviations taken at different frames (positions, orientations
562      *                       and velocities).
563      * @param bias           known gyroscope bias.
564      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
565      *                       accelerometer and gyroscope.
566      * @param listener       listener to handle events raised by this calibrator.
567      * @throws IllegalArgumentException if provided array does not have length 3.
568      */
569     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
570             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
571             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
572         super(measurements, bias, commonAxisUsed, listener);
573     }
574 
575     /**
576      * Constructor.
577      *
578      * @param bias known gyroscope bias.
579      * @throws IllegalArgumentException if provided matrix is not 3x1.
580      */
581     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final Matrix bias) {
582         super(bias);
583     }
584 
585     /**
586      * Constructor.
587      *
588      * @param bias     known gyroscope bias.
589      * @param listener listener to be notified of events such as when estimation
590      *                 starts, ends or its progress significantly changes.
591      * @throws IllegalArgumentException if provided matrix is not 3x1.
592      */
593     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
594             final Matrix bias, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
595         super(bias, listener);
596     }
597 
598     /**
599      * Constructor.
600      *
601      * @param measurements list of body kinematics measurements with standard
602      *                     deviations taken at different frames (positions, orientations
603      *                     and velocities).
604      * @param bias         known gyroscope bias.
605      * @throws IllegalArgumentException if provided matrix is not 3x1.
606      */
607     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
608             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias) {
609         super(measurements, bias);
610     }
611 
612     /**
613      * Constructor.
614      *
615      * @param measurements list of body kinematics measurements with standard
616      *                     deviations taken at different frames (positions, orientations
617      *                     and velocities).
618      * @param bias         known gyroscope bias.
619      * @param listener     listener to handle events raised by this calibrator.
620      * @throws IllegalArgumentException if provided matrix is not 3x1.
621      */
622     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
623             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
624             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
625         super(measurements, bias, listener);
626     }
627 
628     /**
629      * Constructor.
630      *
631      * @param bias           known gyroscope bias.
632      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
633      *                       accelerometer and gyroscope.
634      * @throws IllegalArgumentException if provided matrix is not 3x1.
635      */
636     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(final Matrix bias, final boolean commonAxisUsed) {
637         super(bias, commonAxisUsed);
638     }
639 
640     /**
641      * Constructor.
642      *
643      * @param bias           known gyroscope bias.
644      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
645      *                       accelerometer and gyroscope.
646      * @param listener       listener to handle events raised by this calibrator.
647      * @throws IllegalArgumentException if provided matrix is not 3x1.
648      */
649     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
650             final Matrix bias, final boolean commonAxisUsed,
651             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
652         super(bias, commonAxisUsed, listener);
653     }
654 
655     /**
656      * Constructor.
657      *
658      * @param measurements   list of body kinematics measurements with standard
659      *                       deviations taken at different frames (positions, orientations
660      *                       and velocities).
661      * @param bias           known gyroscope bias.
662      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
663      *                       accelerometer and gyroscope.
664      * @throws IllegalArgumentException if provided matrix is not 3x1.
665      */
666     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
667             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
668             final boolean commonAxisUsed) {
669         super(measurements, bias, commonAxisUsed);
670     }
671 
672     /**
673      * Constructor.
674      *
675      * @param measurements   list of body kinematics measurements with standard
676      *                       deviations taken at different frames (positions, orientations
677      *                       and velocities).
678      * @param bias           known gyroscope bias.
679      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
680      *                       accelerometer and gyroscope.
681      * @param listener       listener to handle events raised by this calibrator.
682      * @throws IllegalArgumentException if provided matrix is not 3x1.
683      */
684     public MSACRobustKnownBiasAndFrameGyroscopeCalibrator(
685             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
686             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
687         super(measurements, bias, commonAxisUsed, listener);
688     }
689 
690     /**
691      * Gets threshold to determine whether samples are inliers or not when testing possible solutions.
692      * The threshold refers to the amount of error on norm between measured angular rates and the
693      * ones generated with estimated calibration parameters provided for each sample.
694      *
695      * @return threshold to determine whether samples are inliers or not.
696      */
697     public double getThreshold() {
698         return threshold;
699     }
700 
701     /**
702      * Sets threshold to determine whether samples are inliers or not when testing possible solutions.
703      * The threshold refers to the amount of error on norm between measured angular rates and the
704      * ones generated with estimated calibration parameters provided for each sample.
705      *
706      * @param threshold threshold to determine whether samples are inliers or not.
707      * @throws IllegalArgumentException if provided value is equal or less than zero.
708      * @throws LockedException          if calibrator is currently running.
709      */
710     public void setThreshold(final double threshold) throws LockedException {
711         if (running) {
712             throw new LockedException();
713         }
714         if (threshold <= MIN_THRESHOLD) {
715             throw new IllegalArgumentException();
716         }
717         this.threshold = threshold;
718     }
719 
720     /**
721      * Estimates gyroscope calibration parameters containing bias, scale factors
722      * cross-coupling errors and g-dependant cross biases.
723      *
724      * @throws LockedException      if calibrator is currently running.
725      * @throws NotReadyException    if calibrator is not ready.
726      * @throws CalibrationException if estimation fails for numerical reasons.
727      */
728     @SuppressWarnings("DuplicatedCode")
729     @Override
730     public void calibrate() throws LockedException, NotReadyException, CalibrationException {
731         if (running) {
732             throw new LockedException();
733         }
734         if (!isReady()) {
735             throw new NotReadyException();
736         }
737 
738         final var innerEstimator = new MSACRobustEstimator<>(new MSACRobustEstimatorListener<PreliminaryResult>() {
739             @Override
740             public double getThreshold() {
741                 return threshold;
742             }
743 
744             @Override
745             public int getTotalSamples() {
746                 return measurements.size();
747             }
748 
749             @Override
750             public int getSubsetSize() {
751                 return preliminarySubsetSize;
752             }
753 
754             @Override
755             public void estimatePreliminarSolutions(
756                     final int[] samplesIndices, final List<PreliminaryResult> solutions) {
757                 computePreliminarySolutions(samplesIndices, solutions);
758             }
759 
760             @Override
761             public double computeResidual(final PreliminaryResult currentEstimation, final int i) {
762                 return computeError(measurements.get(i), currentEstimation);
763             }
764 
765             @Override
766             public boolean isReady() {
767                 return MSACRobustKnownBiasAndFrameGyroscopeCalibrator.super.isReady();
768             }
769 
770             @Override
771             public void onEstimateStart(final RobustEstimator<PreliminaryResult> estimator) {
772                 // no action needed
773             }
774 
775             @Override
776             public void onEstimateEnd(final RobustEstimator<PreliminaryResult> estimator) {
777                 // no action needed
778             }
779 
780             @Override
781             public void onEstimateNextIteration(
782                     final RobustEstimator<PreliminaryResult> estimator, final int iteration) {
783                 if (listener != null) {
784                     listener.onCalibrateNextIteration(
785                             MSACRobustKnownBiasAndFrameGyroscopeCalibrator.this, iteration);
786                 }
787             }
788 
789             @Override
790             public void onEstimateProgressChange(
791                     final RobustEstimator<PreliminaryResult> estimator, final float progress) {
792                 if (listener != null) {
793                     listener.onCalibrateProgressChange(
794                             MSACRobustKnownBiasAndFrameGyroscopeCalibrator.this, progress);
795                 }
796             }
797         });
798 
799         try {
800             running = true;
801 
802             if (listener != null) {
803                 listener.onCalibrateStart(this);
804             }
805 
806             inliersData = null;
807             innerEstimator.setConfidence(confidence);
808             innerEstimator.setMaxIterations(maxIterations);
809             innerEstimator.setProgressDelta(progressDelta);
810             final var preliminaryResult = innerEstimator.estimate();
811             inliersData = innerEstimator.getInliersData();
812 
813             attemptRefine(preliminaryResult);
814 
815             if (listener != null) {
816                 listener.onCalibrateEnd(this);
817             }
818 
819         } catch (final com.irurueta.numerical.LockedException e) {
820             throw new LockedException(e);
821         } catch (final com.irurueta.numerical.NotReadyException e) {
822             throw new NotReadyException(e);
823         } catch (final RobustEstimatorException e) {
824             throw new CalibrationException(e);
825         } finally {
826             running = false;
827         }
828     }
829 
830     /**
831      * Returns method being used for robust estimation.
832      *
833      * @return method being used for robust estimation.
834      */
835     @Override
836     public RobustEstimatorMethod getMethod() {
837         return RobustEstimatorMethod.MSAC;
838     }
839 
840     /**
841      * Indicates whether this calibrator requires quality scores for each
842      * measurement/sequence or not.
843      *
844      * @return true if quality scores are required, false otherwise.
845      */
846     @Override
847     public boolean isQualityScoresRequired() {
848         return false;
849     }
850 }