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.RANSACRobustEstimator;
24  import com.irurueta.numerical.robust.RANSACRobustEstimatorListener;
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 a RANSAC 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 RANSACRobustKnownBiasAndFrameGyroscopeCalibrator 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       * Indicates that by default inliers will only be computed but not kept.
76       */
77      public static final boolean DEFAULT_COMPUTE_AND_KEEP_INLIERS = false;
78  
79      /**
80       * Indicates that by default residuals will only be computed but not kept.
81       */
82      public static final boolean DEFAULT_COMPUTE_AND_KEEP_RESIDUALS = false;
83  
84      /**
85       * Threshold to determine whether samples are inliers or not when testing possible solutions.
86       * The threshold refers to the amount of error on distance between estimated position and
87       * distances provided for each sample.
88       */
89      private double threshold = DEFAULT_THRESHOLD;
90  
91      /**
92       * Indicates whether inliers must be computed and kept.
93       */
94      private boolean computeAndKeepInliers = DEFAULT_COMPUTE_AND_KEEP_INLIERS;
95  
96      /**
97       * Indicates whether residuals must be computed and kept.
98       */
99      private boolean computeAndKeepResiduals = DEFAULT_COMPUTE_AND_KEEP_RESIDUALS;
100 
101     /**
102      * Constructor.
103      */
104     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator() {
105         super();
106     }
107 
108     /**
109      * Constructor.
110      *
111      * @param listener listener to be notified of events such as when estimation
112      *                 starts, ends or its progress significantly changes.
113      */
114     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
115             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
116         super(listener);
117     }
118 
119     /**
120      * Constructor.
121      *
122      * @param measurements list of body kinematics measurements with standard
123      *                     deviations taken at different frames (positions, orientations
124      *                     and velocities).
125      */
126     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
127             final List<StandardDeviationFrameBodyKinematics> measurements) {
128         super(measurements);
129     }
130 
131     /**
132      * Constructor.
133      *
134      * @param measurements list of body kinematics measurements with standard
135      *                     deviations taken at different frames (positions, orientations
136      *                     and velocities).
137      * @param listener     listener to handle events raised by this calibrator.
138      */
139     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
140             final List<StandardDeviationFrameBodyKinematics> measurements,
141             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
142         super(measurements, listener);
143     }
144 
145     /**
146      * Constructor.
147      *
148      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
149      *                       accelerometer and gyroscope.
150      */
151     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(final boolean commonAxisUsed) {
152         super(commonAxisUsed);
153     }
154 
155     /**
156      * Constructor.
157      *
158      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
159      *                       accelerometer and gyroscope.
160      * @param listener       listener to handle events raised by this calibrator.
161      */
162     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
163             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
164         super(commonAxisUsed, listener);
165     }
166 
167     /**
168      * Constructor.
169      *
170      * @param measurements   list of body kinematics measurements with standard
171      *                       deviations taken at different frames (positions, orientations
172      *                       and velocities).
173      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
174      *                       accelerometer and gyroscope.
175      */
176     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
177             final List<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed) {
178         super(measurements, commonAxisUsed);
179     }
180 
181     /**
182      * Constructor.
183      *
184      * @param measurements   list of body kinematics measurements with standard
185      *                       deviations taken at different frames (positions, orientations
186      *                       and velocities).
187      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
188      *                       accelerometer and gyroscope.
189      * @param listener       listener to handle events raised by this calibrator.
190      */
191     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
192             final List<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
193             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
194         super(measurements, commonAxisUsed, listener);
195     }
196 
197     /**
198      * Constructor.
199      *
200      * @param biasX known x coordinate of gyroscope bias expressed in radians per
201      *              second (rad/s).
202      * @param biasY known y coordinate of gyroscope bias expressed in radians per
203      *              second (rad/s).
204      * @param biasZ known z coordinate of gyroscope bias expressed in radians per
205      *              second (rad/s).
206      */
207     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
208             final double biasX, final double biasY, final double biasZ) {
209         super(biasX, biasY, biasZ);
210     }
211 
212     /**
213      * Constructor.
214      *
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      * @param listener listener to be notified of events such as when estimation
222      *                 starts, ends or its progress significantly changes.
223      */
224     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
225             final double biasX, final double biasY, final double biasZ,
226             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
227         super(biasX, biasY, biasZ, listener);
228     }
229 
230     /**
231      * Constructor.
232      *
233      * @param measurements list of body kinematics measurements with standard
234      *                     deviations taken at different frames (positions, orientations
235      *                     and velocities).
236      * @param biasX        known x coordinate of gyroscope bias expressed in radians per
237      *                     second (rad/s).
238      * @param biasY        known y coordinate of gyroscope bias expressed in radians per
239      *                     second (rad/s).
240      * @param biasZ        known z coordinate of gyroscope bias expressed in radians per
241      *                     second (rad/s).
242      */
243     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
244             final List<StandardDeviationFrameBodyKinematics> measurements,
245             final double biasX, final double biasY, final double biasZ) {
246         super(measurements, biasX, biasY, biasZ);
247     }
248 
249     /**
250      * Constructor.
251      *
252      * @param measurements list of body kinematics measurements with standard
253      *                     deviations taken at different frames (positions, orientations
254      *                     and velocities).
255      * @param biasX        known x coordinate of gyroscope bias expressed in radians per
256      *                     second (rad/s).
257      * @param biasY        known y coordinate of gyroscope bias expressed in radians per
258      *                     second (rad/s).
259      * @param biasZ        known z coordinate of gyroscope bias expressed in radians per
260      *                     second (rad/s).
261      * @param listener     listener to handle events raised by this calibrator.
262      */
263     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
264             final List<StandardDeviationFrameBodyKinematics> measurements,
265             final double biasX, final double biasY, final double biasZ,
266             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
267         super(measurements, biasX, biasY, biasZ, listener);
268     }
269 
270     /**
271      * Constructor.
272      *
273      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
274      *                       second (rad/s).
275      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
276      *                       second (rad/s).
277      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
278      *                       second (rad/s).
279      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
280      *                       accelerometer and gyroscope.
281      */
282     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
283             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed) {
284         super(biasX, biasY, biasZ, commonAxisUsed);
285     }
286 
287     /**
288      * Constructor.
289      *
290      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
291      *                       second (rad/s).
292      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
293      *                       second (rad/s).
294      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
295      *                       second (rad/s).
296      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
297      *                       accelerometer and gyroscope.
298      * @param listener       listener to handle events raised by this calibrator.
299      */
300     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
301             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed,
302             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
303         super(biasX, biasY, biasZ, commonAxisUsed, listener);
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      */
321     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
322             final List<StandardDeviationFrameBodyKinematics> measurements,
323             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed) {
324         super(measurements, biasX, biasY, biasZ, commonAxisUsed);
325     }
326 
327     /**
328      * Constructor.
329      *
330      * @param measurements   list of body kinematics measurements with standard
331      *                       deviations taken at different frames (positions, orientations
332      *                       and velocities).
333      * @param biasX          known x coordinate of gyroscope bias expressed in radians per
334      *                       second (rad/s).
335      * @param biasY          known y coordinate of gyroscope bias expressed in radians per
336      *                       second (rad/s).
337      * @param biasZ          known z coordinate of gyroscope bias expressed in radians per
338      *                       second (rad/s).
339      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
340      *                       accelerometer and gyroscope.
341      * @param listener       listener to handle events raised by this calibrator.
342      */
343     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
344             final List<StandardDeviationFrameBodyKinematics> measurements,
345             final double biasX, final double biasY, final double biasZ, final boolean commonAxisUsed,
346             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
347         super(measurements, biasX, biasY, biasZ, commonAxisUsed, listener);
348     }
349 
350     /**
351      * Constructor.
352      *
353      * @param biasX known x coordinate of gyroscope bias.
354      * @param biasY known y coordinate of gyroscope bias.
355      * @param biasZ known z coordinate of gyroscope bias.
356      */
357     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
358             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ) {
359         super(biasX, biasY, biasZ);
360     }
361 
362     /**
363      * Constructor.
364      *
365      * @param biasX    known x coordinate of gyroscope bias.
366      * @param biasY    known y coordinate of gyroscope bias.
367      * @param biasZ    known z coordinate of gyroscope bias.
368      * @param listener listener to be notified of events such as when estimation
369      *                 starts, ends or its progress significantly changes.
370      */
371     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
372             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
373             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
374         super(biasX, biasY, biasZ, listener);
375     }
376 
377     /**
378      * Constructor.
379      *
380      * @param measurements list of body kinematics measurements with standard
381      *                     deviations taken at different frames (positions, orientations
382      *                     and velocities).
383      * @param biasX        known x coordinate of gyroscope bias.
384      * @param biasY        known y coordinate of gyroscope bias.
385      * @param biasZ        known z coordinate of gyroscope bias.
386      */
387     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
388             final List<StandardDeviationFrameBodyKinematics> measurements,
389             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ) {
390         super(measurements, biasX, biasY, biasZ);
391     }
392 
393     /**
394      * Constructor.
395      *
396      * @param measurements list of body kinematics measurements with standard
397      *                     deviations taken at different frames (positions, orientations
398      *                     and velocities).
399      * @param biasX        known x coordinate of gyroscope bias.
400      * @param biasY        known y coordinate of gyroscope bias.
401      * @param biasZ        known z coordinate of gyroscope bias.
402      * @param listener     listener to handle events raised by this calibrator.
403      */
404     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
405             final List<StandardDeviationFrameBodyKinematics> measurements,
406             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
407             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
408         super(measurements, biasX, biasY, biasZ, listener);
409     }
410 
411     /**
412      * Constructor.
413      *
414      * @param biasX          known x coordinate of gyroscope bias.
415      * @param biasY          known y coordinate of gyroscope bias.
416      * @param biasZ          known z coordinate of gyroscope bias.
417      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
418      *                       accelerometer and gyroscope.
419      */
420     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
421             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
422             final boolean commonAxisUsed) {
423         super(biasX, biasY, biasZ, commonAxisUsed);
424     }
425 
426     /**
427      * Constructor.
428      *
429      * @param biasX          known x coordinate of gyroscope bias.
430      * @param biasY          known y coordinate of gyroscope bias.
431      * @param biasZ          known z coordinate of gyroscope bias.
432      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
433      *                       accelerometer and gyroscope.
434      * @param listener       listener to handle events raised by this calibrator.
435      */
436     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
437             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
438             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
439         super(biasX, biasY, biasZ, commonAxisUsed, listener);
440     }
441 
442     /**
443      * Constructor.
444      *
445      * @param measurements   list of body kinematics measurements with standard
446      *                       deviations taken at different frames (positions, orientations
447      *                       and velocities).
448      * @param biasX          known x coordinate of gyroscope bias.
449      * @param biasY          known y coordinate of gyroscope bias.
450      * @param biasZ          known z coordinate of gyroscope bias.
451      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
452      *                       accelerometer and gyroscope.
453      */
454     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
455             final List<StandardDeviationFrameBodyKinematics> measurements,
456             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
457             final boolean commonAxisUsed) {
458         super(measurements, biasX, biasY, biasZ, commonAxisUsed);
459     }
460 
461     /**
462      * Constructor.
463      *
464      * @param measurements   list of body kinematics measurements with standard
465      *                       deviations taken at different frames (positions, orientations
466      *                       and velocities).
467      * @param biasX          known x coordinate of gyroscope bias.
468      * @param biasY          known y coordinate of gyroscope bias.
469      * @param biasZ          known z coordinate of gyroscope bias.
470      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
471      *                       accelerometer and gyroscope.
472      * @param listener       listener to handle events raised by this calibrator.
473      */
474     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
475             final List<StandardDeviationFrameBodyKinematics> measurements,
476             final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ,
477             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
478         super(measurements, biasX, biasY, biasZ, commonAxisUsed, listener);
479     }
480 
481     /**
482      * Constructor.
483      *
484      * @param bias known gyroscope bias.
485      * @throws IllegalArgumentException if provided array does not have length 3.
486      */
487     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(final double[] bias) {
488         super(bias);
489     }
490 
491     /**
492      * Constructor.
493      *
494      * @param bias     known gyroscope bias.
495      * @param listener listener to be notified of events such as when estimation
496      *                 starts, ends or its progress significantly changes.
497      * @throws IllegalArgumentException if provided array does not have length 3.
498      */
499     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
500             final double[] bias, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
501         super(bias, listener);
502     }
503 
504     /**
505      * Constructor.
506      *
507      * @param measurements list of body kinematics measurements with standard
508      *                     deviations taken at different frames (positions, orientations
509      *                     and velocities).
510      * @param bias         known gyroscope bias.
511      * @throws IllegalArgumentException if provided array does not have length 3.
512      */
513     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
514             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias) {
515         super(measurements, bias);
516     }
517 
518     /**
519      * Constructor.
520      *
521      * @param measurements list of body kinematics measurements with standard
522      *                     deviations taken at different frames (positions, orientations
523      *                     and velocities).
524      * @param bias         known gyroscope bias.
525      * @param listener     listener to handle events raised by this calibrator.
526      * @throws IllegalArgumentException if provided array does not have length 3.
527      */
528     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
529             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
530             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
531         super(measurements, bias, listener);
532     }
533 
534     /**
535      * Constructor.
536      *
537      * @param bias           known gyroscope bias.
538      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
539      *                       accelerometer and gyroscope.
540      * @throws IllegalArgumentException if provided array does not have length 3.
541      */
542     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(final double[] bias, final boolean commonAxisUsed) {
543         super(bias, commonAxisUsed);
544     }
545 
546     /**
547      * Constructor.
548      *
549      * @param bias           known gyroscope bias.
550      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
551      *                       accelerometer and gyroscope.
552      * @param listener       listener to handle events raised by this calibrator.
553      * @throws IllegalArgumentException if provided array does not have length 3.
554      */
555     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
556             final double[] bias, final boolean commonAxisUsed,
557             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
558         super(bias, commonAxisUsed, listener);
559     }
560 
561     /**
562      * Constructor.
563      *
564      * @param measurements   list of body kinematics measurements with standard
565      *                       deviations taken at different frames (positions, orientations
566      *                       and velocities).
567      * @param bias           known gyroscope bias.
568      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
569      *                       accelerometer and gyroscope.
570      * @throws IllegalArgumentException if provided array does not have length 3.
571      */
572     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
573             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
574             final boolean commonAxisUsed) {
575         super(measurements, bias, commonAxisUsed);
576     }
577 
578     /**
579      * Constructor.
580      *
581      * @param measurements   list of body kinematics measurements with standard
582      *                       deviations taken at different frames (positions, orientations
583      *                       and velocities).
584      * @param bias           known gyroscope bias.
585      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
586      *                       accelerometer and gyroscope.
587      * @param listener       listener to handle events raised by this calibrator.
588      * @throws IllegalArgumentException if provided array does not have length 3.
589      */
590     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
591             final List<StandardDeviationFrameBodyKinematics> measurements, final double[] bias,
592             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
593         super(measurements, bias, commonAxisUsed, listener);
594     }
595 
596     /**
597      * Constructor.
598      *
599      * @param bias known gyroscope bias.
600      * @throws IllegalArgumentException if provided matrix is not 3x1.
601      */
602     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(final Matrix bias) {
603         super(bias);
604     }
605 
606     /**
607      * Constructor.
608      *
609      * @param bias     known gyroscope bias.
610      * @param listener listener to be notified of events such as when estimation
611      *                 starts, ends or its progress significantly changes.
612      * @throws IllegalArgumentException if provided matrix is not 3x1.
613      */
614     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
615             final Matrix bias, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
616         super(bias, listener);
617     }
618 
619     /**
620      * Constructor.
621      *
622      * @param measurements list of body kinematics measurements with standard
623      *                     deviations taken at different frames (positions, orientations
624      *                     and velocities).
625      * @param bias         known gyroscope bias.
626      * @throws IllegalArgumentException if provided matrix is not 3x1.
627      */
628     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
629             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias) {
630         super(measurements, bias);
631     }
632 
633     /**
634      * Constructor.
635      *
636      * @param measurements list of body kinematics measurements with standard
637      *                     deviations taken at different frames (positions, orientations
638      *                     and velocities).
639      * @param bias         known gyroscope bias.
640      * @param listener     listener to handle events raised by this calibrator.
641      * @throws IllegalArgumentException if provided matrix is not 3x1.
642      */
643     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
644             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
645             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
646         super(measurements, bias, listener);
647     }
648 
649     /**
650      * Constructor.
651      *
652      * @param bias           known gyroscope bias.
653      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
654      *                       accelerometer and gyroscope.
655      * @throws IllegalArgumentException if provided matrix is not 3x1.
656      */
657     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(final Matrix bias, final boolean commonAxisUsed) {
658         super(bias, commonAxisUsed);
659     }
660 
661     /**
662      * Constructor.
663      *
664      * @param bias           known gyroscope bias.
665      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
666      *                       accelerometer and gyroscope.
667      * @param listener       listener to handle events raised by this calibrator.
668      * @throws IllegalArgumentException if provided matrix is not 3x1.
669      */
670     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
671             final Matrix bias, final boolean commonAxisUsed,
672             final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
673         super(bias, commonAxisUsed, listener);
674     }
675 
676     /**
677      * Constructor.
678      *
679      * @param measurements   list of body kinematics measurements with standard
680      *                       deviations taken at different frames (positions, orientations
681      *                       and velocities).
682      * @param bias           known gyroscope bias.
683      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
684      *                       accelerometer and gyroscope.
685      * @throws IllegalArgumentException if provided matrix is not 3x1.
686      */
687     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
688             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
689             final boolean commonAxisUsed) {
690         super(measurements, bias, commonAxisUsed);
691     }
692 
693     /**
694      * Constructor.
695      *
696      * @param measurements   list of body kinematics measurements with standard
697      *                       deviations taken at different frames (positions, orientations
698      *                       and velocities).
699      * @param bias           known gyroscope bias.
700      * @param commonAxisUsed indicates whether z-axis is assumed to be common for
701      *                       accelerometer and gyroscope.
702      * @param listener       listener to handle events raised by this calibrator.
703      * @throws IllegalArgumentException if provided matrix is not 3x1.
704      */
705     public RANSACRobustKnownBiasAndFrameGyroscopeCalibrator(
706             final List<StandardDeviationFrameBodyKinematics> measurements, final Matrix bias,
707             final boolean commonAxisUsed, final RobustKnownBiasAndFrameGyroscopeCalibratorListener listener) {
708         super(measurements, bias, commonAxisUsed, listener);
709     }
710 
711     /**
712      * Gets threshold to determine whether samples are inliers or not when testing possible solutions.
713      * The threshold refers to the amount of error on norm between measured angular rates and the
714      * ones generated with estimated calibration parameters provided for each sample.
715      *
716      * @return threshold to determine whether samples are inliers or not.
717      */
718     public double getThreshold() {
719         return threshold;
720     }
721 
722     /**
723      * Sets threshold to determine whether samples are inliers or not when testing possible solutions.
724      * The threshold refers to the amount of error on norm between measured angular rates and the
725      * ones generated with estimated calibration parameters provided for each sample.
726      *
727      * @param threshold threshold to determine whether samples are inliers or not.
728      * @throws IllegalArgumentException if provided value is equal or less than zero.
729      * @throws LockedException          if calibrator is currently running.
730      */
731     public void setThreshold(final double threshold) throws LockedException {
732         if (running) {
733             throw new LockedException();
734         }
735         if (threshold <= MIN_THRESHOLD) {
736             throw new IllegalArgumentException();
737         }
738         this.threshold = threshold;
739     }
740 
741     /**
742      * Indicates whether inliers must be computed and kept.
743      *
744      * @return true if inliers must be computed and kept, false if inliers
745      * only need to be computed but not kept.
746      */
747     public boolean isComputeAndKeepInliersEnabled() {
748         return computeAndKeepInliers;
749     }
750 
751     /**
752      * Specifies whether inliers must be computed and kept.
753      *
754      * @param computeAndKeepInliers true if inliers must be computed and kept,
755      *                              false if inliers only need to be computed but not kept.
756      * @throws LockedException if calibrator is currently running.
757      */
758     public void setComputeAndKeepInliersEnabled(final boolean computeAndKeepInliers) throws LockedException {
759         if (running) {
760             throw new LockedException();
761         }
762         this.computeAndKeepInliers = computeAndKeepInliers;
763     }
764 
765     /**
766      * Indicates whether residuals must be computed and kept.
767      *
768      * @return true if residuals must be computed and kept, false if residuals
769      * only need to be computed but not kept.
770      */
771     public boolean isComputeAndKeepResiduals() {
772         return computeAndKeepResiduals;
773     }
774 
775     /**
776      * Specifies whether residuals must be computed and kept.
777      *
778      * @param computeAndKeepResiduals true if residuals must be computed and kept,
779      *                                false if residuals only need to be computed but not kept.
780      * @throws LockedException if calibrator is currently running.
781      */
782     public void setComputeAndKeepResidualsEnabled(final boolean computeAndKeepResiduals) throws LockedException {
783         if (running) {
784             throw new LockedException();
785         }
786         this.computeAndKeepResiduals = computeAndKeepResiduals;
787     }
788 
789     /**
790      * Estimates gyroscope calibration parameters containing bias, scale factors
791      * cross-coupling errors and g-dependant cross biases.
792      *
793      * @throws LockedException      if calibrator is currently running.
794      * @throws NotReadyException    if calibrator is not ready.
795      * @throws CalibrationException if estimation fails for numerical reasons.
796      */
797     @SuppressWarnings("DuplicatedCode")
798     @Override
799     public void calibrate() throws LockedException, NotReadyException, CalibrationException {
800         if (running) {
801             throw new LockedException();
802         }
803         if (!isReady()) {
804             throw new NotReadyException();
805         }
806 
807         final var innerEstimator = new RANSACRobustEstimator<>(new RANSACRobustEstimatorListener<PreliminaryResult>() {
808             @Override
809             public double getThreshold() {
810                 return threshold;
811             }
812 
813             @Override
814             public int getTotalSamples() {
815                 return measurements.size();
816             }
817 
818             @Override
819             public int getSubsetSize() {
820                 return preliminarySubsetSize;
821             }
822 
823             @Override
824             public void estimatePreliminarSolutions(
825                     final int[] samplesIndices, final List<PreliminaryResult> solutions) {
826                 computePreliminarySolutions(samplesIndices, solutions);
827             }
828 
829             @Override
830             public double computeResidual(final PreliminaryResult currentEstimation, final int i) {
831                 return computeError(measurements.get(i), currentEstimation);
832             }
833 
834             @Override
835             public boolean isReady() {
836                 return RANSACRobustKnownBiasAndFrameGyroscopeCalibrator.super.isReady();
837             }
838 
839             @Override
840             public void onEstimateStart(final RobustEstimator<PreliminaryResult> estimator) {
841                 // no action needed
842             }
843 
844             @Override
845             public void onEstimateEnd(final RobustEstimator<PreliminaryResult> estimator) {
846                 // no action needed
847             }
848 
849             @Override
850             public void onEstimateNextIteration(
851                     final RobustEstimator<PreliminaryResult> estimator, final int iteration) {
852                 if (listener != null) {
853                     listener.onCalibrateNextIteration(
854                             RANSACRobustKnownBiasAndFrameGyroscopeCalibrator.this, iteration);
855                 }
856             }
857 
858             @Override
859             public void onEstimateProgressChange(
860                     final RobustEstimator<PreliminaryResult> estimator, final float progress) {
861                 if (listener != null) {
862                     listener.onCalibrateProgressChange(
863                             RANSACRobustKnownBiasAndFrameGyroscopeCalibrator.this, progress);
864                 }
865             }
866         });
867 
868         try {
869             running = true;
870 
871             if (listener != null) {
872                 listener.onCalibrateStart(this);
873             }
874 
875             inliersData = null;
876             innerEstimator.setComputeAndKeepInliersEnabled(computeAndKeepInliers || refineResult);
877             innerEstimator.setComputeAndKeepResidualsEnabled(computeAndKeepResiduals || refineResult);
878             innerEstimator.setConfidence(confidence);
879             innerEstimator.setMaxIterations(maxIterations);
880             innerEstimator.setProgressDelta(progressDelta);
881             final var preliminaryResult = innerEstimator.estimate();
882             inliersData = innerEstimator.getInliersData();
883 
884             attemptRefine(preliminaryResult);
885 
886             if (listener != null) {
887                 listener.onCalibrateEnd(this);
888             }
889 
890         } catch (final com.irurueta.numerical.LockedException e) {
891             throw new LockedException(e);
892         } catch (final com.irurueta.numerical.NotReadyException e) {
893             throw new NotReadyException(e);
894         } catch (final RobustEstimatorException e) {
895             throw new CalibrationException(e);
896         } finally {
897             running = false;
898         }
899     }
900 
901     /**
902      * Returns method being used for robust estimation.
903      *
904      * @return method being used for robust estimation.
905      */
906     @Override
907     public RobustEstimatorMethod getMethod() {
908         return RobustEstimatorMethod.RANSAC;
909     }
910 
911     /**
912      * Indicates whether this calibrator requires quality scores for each
913      * measurement/sequence or not.
914      *
915      * @return true if quality scores are required, false otherwise.
916      */
917     @Override
918     public boolean isQualityScoresRequired() {
919         return false;
920     }
921 }