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.AlgebraException;
19 import com.irurueta.algebra.ArrayUtils;
20 import com.irurueta.algebra.Matrix;
21 import com.irurueta.algebra.WrongSizeException;
22 import com.irurueta.geometry.InhomogeneousPoint3D;
23 import com.irurueta.geometry.Quaternion;
24 import com.irurueta.geometry.RotationException;
25 import com.irurueta.navigation.LockedException;
26 import com.irurueta.navigation.NotReadyException;
27 import com.irurueta.navigation.inertial.BodyKinematics;
28 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanInitializerConfig;
29 import com.irurueta.navigation.inertial.INSTightlyCoupledKalmanInitializerConfig;
30 import com.irurueta.navigation.inertial.calibration.AccelerationFixer;
31 import com.irurueta.navigation.inertial.calibration.AngularRateFixer;
32 import com.irurueta.navigation.inertial.calibration.AngularSpeedTriad;
33 import com.irurueta.navigation.inertial.calibration.BodyKinematicsSequence;
34 import com.irurueta.navigation.inertial.calibration.CalibrationException;
35 import com.irurueta.navigation.inertial.calibration.GyroscopeBiasUncertaintySource;
36 import com.irurueta.navigation.inertial.calibration.GyroscopeCalibrationSource;
37 import com.irurueta.navigation.inertial.calibration.StandardDeviationTimedBodyKinematics;
38 import com.irurueta.numerical.robust.InliersData;
39 import com.irurueta.numerical.robust.RobustEstimatorMethod;
40 import com.irurueta.units.Acceleration;
41 import com.irurueta.units.AccelerationConverter;
42 import com.irurueta.units.AccelerationUnit;
43 import com.irurueta.units.AngularSpeed;
44 import com.irurueta.units.AngularSpeedConverter;
45 import com.irurueta.units.AngularSpeedUnit;
46
47 import java.util.ArrayList;
48 import java.util.List;
49
50 /**
51 * This is an abstract class to robustly estimate gyroscope
52 * biases, cross couplings and scaling factors
53 * along with G-dependent cross biases introduced on the gyroscope by the
54 * specific forces sensed by the accelerometer.
55 * <p>
56 * This calibrator assumes that the IMU is at a more or less fixed location on
57 * Earth, and evaluates sequences of measured body kinematics to perform
58 * calibration for unknown orientations on those provided sequences.
59 * Each provided sequence will be preceded by a static period where mean
60 * specific force will be measured to determine gravity (and hence partial
61 * body attitude).
62 * <p>
63 * Measured gyroscope angular rates is assumed to follow the model shown below:
64 * <pre>
65 * Ωmeas = bg + (I + Mg) * Ωtrue + Gg * ftrue + w
66 * </pre>
67 * Where:
68 * - Ωmeas is the measured gyroscope angular rates. This is a 3x1 vector.
69 * - bg is the gyroscope bias. Ideally, on a perfect gyroscope, this should be a
70 * 3x1 zero vector.
71 * - I is the 3x3 identity matrix.
72 * - Mg is the 3x3 matrix containing cross-couplings and scaling factors. Ideally, on
73 * a perfect gyroscope, this should be a 3x3 zero matrix.
74 * - Ωtrue is ground-truth gyroscope angular rates.
75 * - Gg is the G-dependent cross biases introduced by the specific forces sensed
76 * by the accelerometer. Ideally, on a perfect gyroscope, this should be a 3x3
77 * zero matrix.
78 * - ftrue is ground-truth specific force. This is a 3x1 vector.
79 * - w is measurement noise. This is a 3x1 vector.
80 */
81 public abstract class RobustEasyGyroscopeCalibrator implements GyroscopeNonLinearCalibrator,
82 UnknownBiasGyroscopeCalibrator, GyroscopeCalibrationSource, GyroscopeBiasUncertaintySource,
83 OrderedBodyKinematicsSequenceGyroscopeCalibrator, QualityScoredGyroscopeCalibrator,
84 AccelerometerDependentGyroscopeCalibrator {
85
86 /**
87 * Indicates whether by default a common z-axis is assumed for both the accelerometer
88 * and gyroscope.
89 */
90 public static final boolean DEFAULT_USE_COMMON_Z_AXIS = true;
91
92 /**
93 * Indicates that by default G-dependent cross biases introduced
94 * by the accelerometer on the gyroscope are estimated.
95 */
96 public static final boolean DEFAULT_ESTIMATE_G_DEPENDENT_CROSS_BIASES = true;
97
98 /**
99 * Default robust estimator method when none is provided.
100 */
101 public static final RobustEstimatorMethod DEFAULT_ROBUST_METHOD = RobustEstimatorMethod.LMEDS;
102
103 /**
104 * Indicates that result is refined by default using a non-linear calibrator
105 * (which uses a Levenberg-Marquardt fitter).
106 */
107 public static final boolean DEFAULT_REFINE_RESULT = true;
108
109 /**
110 * Indicates that covariance is kept by default after refining result.
111 */
112 public static final boolean DEFAULT_KEEP_COVARIANCE = true;
113
114 /**
115 * Default amount of progress variation before notifying a change in estimation progress.
116 * By default this is set to 5%.
117 */
118 public static final float DEFAULT_PROGRESS_DELTA = 0.05f;
119
120 /**
121 * Minimum allowed value for progress delta.
122 */
123 public static final float MIN_PROGRESS_DELTA = 0.0f;
124
125 /**
126 * Maximum allowed value for progress delta.
127 */
128 public static final float MAX_PROGRESS_DELTA = 1.0f;
129
130 /**
131 * Constant defining default confidence of the estimated result, which is
132 * 99%. This means that with a probability of 99% estimation will be
133 * accurate because chosen sub-samples will be inliers.
134 */
135 public static final double DEFAULT_CONFIDENCE = 0.99;
136
137 /**
138 * Default maximum allowed number of iterations.
139 */
140 public static final int DEFAULT_MAX_ITERATIONS = 5000;
141
142 /**
143 * Minimum allowed confidence value.
144 */
145 public static final double MIN_CONFIDENCE = 0.0;
146
147 /**
148 * Maximum allowed confidence value.
149 */
150 public static final double MAX_CONFIDENCE = 1.0;
151
152 /**
153 * Minimum allowed number of iterations.
154 */
155 public static final int MIN_ITERATIONS = 1;
156
157 /**
158 * Known x-coordinate of accelerometer bias to be used to fix measured
159 * specific force and find cross biases introduced by the accelerometer.
160 * This is expressed in meters per squared second (m/s^2).
161 */
162 private double accelerometerBiasX;
163
164 /**
165 * Known y-coordinate of accelerometer bias to be used to fix measured
166 * specific force and find cross biases introduced by the accelerometer.
167 * This is expressed in meters per squared second (m/s^2).
168 */
169 private double accelerometerBiasY;
170
171 /**
172 * Known z-coordinate of accelerometer bias to be used to fix measured
173 * specific force and find cross biases introduced by the accelerometer.
174 * This is expressed in meters per squared second (m/s^2).
175 */
176 private double accelerometerBiasZ;
177
178 /**
179 * Known accelerometer x scaling factor to be used to fix measured
180 * specific force and find cross biases introduced by the accelerometer.
181 */
182 private double accelerometerSx;
183
184 /**
185 * Known accelerometer y scaling factor to be used to fix measured
186 * specific force and find cross biases introduced by the accelerometer.
187 */
188 private double accelerometerSy;
189
190 /**
191 * Known accelerometer z scaling factor to be used to fix measured
192 * specific force and find cross biases introduced by the accelerometer.
193 */
194 private double accelerometerSz;
195
196 /**
197 * Known accelerometer x-y cross coupling error to be used to fix measured
198 * specific force and find cross biases introduced by the accelerometer.
199 */
200 private double accelerometerMxy;
201
202 /**
203 * Know accelerometer x-z cross coupling error to be used to fix measured
204 * specific force and find cross biases introduced by the accelerometer.
205 */
206 private double accelerometerMxz;
207
208 /**
209 * Known accelerometer y-x cross coupling error to be used to fix measured
210 * specific force and find cross biases introduced by the accelerometer.
211 */
212 private double accelerometerMyx;
213
214 /**
215 * Known accelerometer y-z cross coupling error to be used to fix measured
216 * specific force and find cross biases introduced by the accelerometer.
217 */
218 private double accelerometerMyz;
219
220 /**
221 * Known accelerometer z-x cross coupling error to be used to fix measured
222 * specific force and find cross biases introduced by the accelerometer.
223 */
224 private double accelerometerMzx;
225
226 /**
227 * Known accelerometer z-y cross coupling error to be used to fix measured
228 * specific force and find cross biases introduced by the accelerometer.
229 */
230 private double accelerometerMzy;
231
232 /**
233 * Initial x-coordinate of gyroscope bias to be used to find a solution.
234 * This is expressed in radians per second (rad/s).
235 */
236 private double initialBiasX;
237
238 /**
239 * Initial y-coordinate of gyroscope bias to be used to find a solution.
240 * This is expressed in radians per second (rad/s).
241 */
242 private double initialBiasY;
243
244 /**
245 * Initial z-coordinate of gyroscope bias to be used to find a solution.
246 * This is expressed in radians per second (rad/s).
247 */
248 private double initialBiasZ;
249
250 /**
251 * Initial gyroscope x scaling factor.
252 */
253 private double initialSx;
254
255 /**
256 * Initial gyroscope y scaling factor.
257 */
258 private double initialSy;
259
260 /**
261 * Initial gyroscope z scaling factor.
262 */
263 private double initialSz;
264
265 /**
266 * Initial gyroscope x-y cross coupling error.
267 */
268 private double initialMxy;
269
270 /**
271 * Initial gyroscope x-z cross coupling error.
272 */
273 private double initialMxz;
274
275 /**
276 * Initial gyroscope y-x cross coupling error.
277 */
278 private double initialMyx;
279
280 /**
281 * Initial gyroscope y-z cross coupling error.
282 */
283 private double initialMyz;
284
285 /**
286 * Initial gyroscope z-x cross coupling error.
287 */
288 private double initialMzx;
289
290 /**
291 * Initial gyroscope z-y cross coupling error.
292 */
293 private double initialMzy;
294
295 /**
296 * Initial G-dependent cross biases introduced on the gyroscope by the
297 * specific forces sensed by the accelerometer.
298 */
299 private Matrix initialGg;
300
301 /**
302 * Contains a collection of sequences of timestamped body kinematics
303 * measurements taken at a given position where the device moves freely
304 * with different orientations.
305 */
306 protected List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences;
307
308 /**
309 * This flag indicates whether z-axis is assumed to be common for accelerometer
310 * and gyroscope.
311 * When enabled, this eliminates 3 variables from Mg matrix.
312 */
313 private boolean commonAxisUsed = DEFAULT_USE_COMMON_Z_AXIS;
314
315 /**
316 * This flag indicates whether G-dependent cross biases are being
317 * estimated or not.
318 * When enabled, this adds 9 variables from Gg matrix.
319 */
320 private boolean estimateGDependentCrossBiases = DEFAULT_ESTIMATE_G_DEPENDENT_CROSS_BIASES;
321
322 /**
323 * Listener to be notified of events such as when calibration starts, ends or its
324 * progress significantly changes.
325 */
326 protected RobustEasyGyroscopeCalibratorListener listener;
327
328 /**
329 * Estimated angular rate biases for each IMU axis expressed in radians per
330 * second (rad/s).
331 */
332 private double[] estimatedBiases;
333
334 /**
335 * Estimated gyroscope scale factors and cross coupling errors.
336 * This is the product of matrix Tg containing cross coupling errors and Kg
337 * containing scaling factors.
338 * So that:
339 * <pre>
340 * Mg = [sx mxy mxz] = Tg*Kg
341 * [myx sy myz]
342 * [mzx mzy sz ]
343 * </pre>
344 * Where:
345 * <pre>
346 * Kg = [sx 0 0 ]
347 * [0 sy 0 ]
348 * [0 0 sz]
349 * </pre>
350 * and
351 * <pre>
352 * Tg = [1 -alphaXy alphaXz ]
353 * [alphaYx 1 -alphaYz]
354 * [-alphaZx alphaZy 1 ]
355 * </pre>
356 * Hence:
357 * <pre>
358 * Mg = [sx mxy mxz] = Tg*Kg = [sx -sy * alphaXy sz * alphaXz ]
359 * [myx sy myz] [sx * alphaYx sy -sz * alphaYz]
360 * [mzx mzy sz ] [-sx * alphaZx sy * alphaZy sz ]
361 * </pre>
362 * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
363 * are considered to be zero if the gyroscope z-axis is assumed to be the same
364 * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mg matrix
365 * becomes upper diagonal:
366 * <pre>
367 * Mg = [sx mxy mxz]
368 * [0 sy myz]
369 * [0 0 sz ]
370 * </pre>
371 * Values of this matrix are unit-less.
372 */
373 private Matrix estimatedMg;
374
375 /**
376 * Estimated G-dependent cross biases introduced on the gyroscope by the
377 * specific forces sensed by the accelerometer.
378 * This instance allows any 3x3 matrix.
379 */
380 private Matrix estimatedGg;
381
382 /**
383 * Estimated covariance matrix for estimated parameters.
384 */
385 private Matrix estimatedCovariance;
386
387 /**
388 * Estimated chi square value.
389 */
390 private double estimatedChiSq;
391
392 /**
393 * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
394 * minus the number of estimated parameters.
395 */
396 private int estimatedChiSqDegreesOfFreedom;
397
398 /**
399 * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
400 * freedom. Ideally this value should be close to 1.0.
401 */
402 private double estimatedReducedChiSq;
403
404 /**
405 * Estimated mean square error respect to provided measurements.
406 */
407 private double estimatedMse;
408
409 /**
410 * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
411 * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
412 * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
413 */
414 private double estimatedP;
415
416 /**
417 * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
418 * the better the fit that has been estimated.
419 */
420 private double estimatedQ;
421
422 /**
423 * Indicates whether calibrator is running.
424 */
425 protected boolean running;
426
427 /**
428 * Amount of progress variation before notifying a progress change during calibration.
429 */
430 protected float progressDelta = DEFAULT_PROGRESS_DELTA;
431
432 /**
433 * Amount of confidence expressed as a value between 0.0 and 1.0 (which is equivalent
434 * to 100%). The amount of confidence indicates the probability that the estimated
435 * result is correct. Usually this value will be close to 1.0, but not exactly 1.0.
436 */
437 protected double confidence = DEFAULT_CONFIDENCE;
438
439 /**
440 * Maximum allowed number of iterations. When the maximum number of iterations is
441 * exceeded, result will not be available, however an approximate result will be
442 * available for retrieval.
443 */
444 protected int maxIterations = DEFAULT_MAX_ITERATIONS;
445
446 /**
447 * Data related to inliers found after calibration.
448 */
449 protected InliersData inliersData;
450
451 /**
452 * Indicates whether result must be refined using a non linear calibrator over
453 * found inliers.
454 * If true, inliers will be computed and kept in any implementation regardless of the
455 * settings.
456 */
457 protected boolean refineResult = DEFAULT_REFINE_RESULT;
458
459 /**
460 * Size of subsets to be checked during robust estimation.
461 */
462 protected int preliminarySubsetSize = EasyGyroscopeCalibrator.MINIMUM_SEQUENCES_GENERAL_AND_CROSS_BIASES;
463
464 /**
465 * Indicates whether covariance must be kept after refining result.
466 * This setting is only taken into account if result is refined.
467 */
468 private boolean keepCovariance = DEFAULT_KEEP_COVARIANCE;
469
470 /**
471 * Inner non-robust calibrator.
472 */
473 private final EasyGyroscopeCalibrator innerCalibrator = new EasyGyroscopeCalibrator();
474
475 /**
476 * Contains normalized start gravity coordinates.
477 * This is reused when computing error residuals.
478 */
479 private final InhomogeneousPoint3D startPoint = new InhomogeneousPoint3D();
480
481 /**
482 * Contains estimated normalized end gravity coordinates.
483 * This is reused when computing error residuals.
484 */
485 private final InhomogeneousPoint3D endPoint = new InhomogeneousPoint3D();
486
487 /**
488 * Contains expected normalized end gravity coordinates.
489 * This is reused when computing error residuals.
490 */
491 private final InhomogeneousPoint3D expectedEndPoint = new InhomogeneousPoint3D();
492
493 /**
494 * Contains amount of rotation for a given sequence and preliminary
495 * solution.
496 * This is reused when computing error residuals.
497 */
498 private final Quaternion q = new Quaternion();
499
500 /**
501 * Array containing measured specific force coordinates.
502 * This is reused when computing error residuals.
503 */
504 private final double[] measuredSpecificForce = new double[BodyKinematics.COMPONENTS];
505
506 /**
507 * Array containing fixed specific force coordinates.
508 * This is reused when computing error residuals.
509 */
510 private final double[] fixedSpecificForce = new double[BodyKinematics.COMPONENTS];
511
512 /**
513 * Array containing measured angular rate coordinates.
514 * This is reused when computing error residuals.
515 */
516 private final double[] measuredAngularRate = new double[BodyKinematics.COMPONENTS];
517
518 /**
519 * Array containing fixed angular rate coordinates.
520 * This is reused when computing error residuals.
521 */
522 private final double[] fixedAngularRate = new double[BodyKinematics.COMPONENTS];
523
524 /**
525 * An acceleration fixer.
526 * This is reused when computing error residuals.
527 */
528 private final AccelerationFixer accelerationFixer = new AccelerationFixer();
529
530 /**
531 * An angular rate fixer.
532 * This is reused when computing error residuals.
533 */
534 private final AngularRateFixer angularRateFixer = new AngularRateFixer();
535
536 /**
537 * Constructor.
538 */
539 protected RobustEasyGyroscopeCalibrator() {
540 try {
541 initialGg = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
542 } catch (final WrongSizeException ignore) {
543 // never happens
544 }
545 }
546
547 /**
548 * Constructor.
549 *
550 * @param sequences collection of sequences containing timestamped body
551 * kinematics measurements.
552 * @param initialBias initial gyroscope bias to be used to find a solution.
553 * This must be 3x1 and is expressed in radians per
554 * second (rad/s).
555 * @param initialMg initial gyroscope scale factors and cross coupling
556 * errors matrix. Must be 3x3.
557 * @param initialGg initial gyroscope G-dependent cross biases
558 * introduced on the gyroscope by the specific forces
559 * sensed by the accelerometer. Must be 3x3.
560 * @throws IllegalArgumentException if any of the provided values does
561 * not have proper size.
562 */
563 protected RobustEasyGyroscopeCalibrator(
564 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
565 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg) {
566 this();
567 this.sequences = sequences;
568 try {
569 setInitialBias(initialBias);
570 setInitialMg(initialMg);
571 setInitialGg(initialGg);
572 } catch (final LockedException ignore) {
573 // never happens
574 }
575 }
576
577 /**
578 * Constructor.
579 *
580 * @param sequences collection of sequences containing timestamped body
581 * kinematics measurements.
582 * @param initialBias initial gyroscope bias to be used to find a solution.
583 * This must be 3x1 and is expressed in radians per
584 * second (rad/s).
585 * @param initialMg initial gyroscope scale factors and cross coupling
586 * errors matrix. Must be 3x3.
587 * @param initialGg initial gyroscope G-dependent cross biases
588 * introduced on the gyroscope by the specific forces
589 * sensed by the accelerometer. Must be 3x3.
590 * @param listener listener to handle events raised by this
591 * calibrator.
592 * @throws IllegalArgumentException if any of the provided values does
593 * not have proper size.
594 */
595 protected RobustEasyGyroscopeCalibrator(
596 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
597 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
598 final RobustEasyGyroscopeCalibratorListener listener) {
599 this(sequences, initialBias, initialMg, initialGg);
600 this.listener = listener;
601 }
602
603 /**
604 * Constructor.
605 *
606 * @param sequences collection of sequences containing timestamped body
607 * kinematics measurements.
608 * @param initialBias initial gyroscope bias to be used to find a
609 * solution. This must have length 3 and is expressed
610 * in radians per second (rad/s).
611 * @param initialMg initial gyroscope scale factors and cross coupling
612 * errors matrix. Must be 3x3.
613 * @param initialGg initial gyroscope G-dependent cross biases
614 * introduced on the gyroscope by the specific forces
615 * sensed by the accelerometer. Must be 3x3.
616 * @throws IllegalArgumentException if any of the provided values does
617 * not have proper size.
618 */
619 protected RobustEasyGyroscopeCalibrator(
620 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
621 final double[] initialBias, final Matrix initialMg, final Matrix initialGg) {
622 this();
623 this.sequences = sequences;
624 try {
625 setInitialBias(initialBias);
626 setInitialMg(initialMg);
627 setInitialGg(initialGg);
628 } catch (final LockedException ignore) {
629 // never happens
630 }
631 }
632
633 /**
634 * Constructor.
635 *
636 * @param sequences collection of sequences containing timestamped body
637 * kinematics measurements.
638 * @param initialBias initial gyroscope bias to be used to find a
639 * solution. This must have length 3 and is expressed
640 * in radians per second (rad/s).
641 * @param initialMg initial gyroscope scale factors and cross coupling
642 * errors matrix. Must be 3x3.
643 * @param initialGg initial gyroscope G-dependent cross biases
644 * introduced on the gyroscope by the specific forces
645 * sensed by the accelerometer. Must be 3x3.
646 * @param listener listener to handle events raised by this
647 * calibrator.
648 * @throws IllegalArgumentException if any of the provided values does
649 * not have proper size.
650 */
651 protected RobustEasyGyroscopeCalibrator(
652 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
653 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
654 final RobustEasyGyroscopeCalibratorListener listener) {
655 this(sequences, initialBias, initialMg, initialGg);
656 this.listener = listener;
657 }
658
659 /**
660 * Constructor.
661 *
662 * @param sequences collection of sequences containing timestamped body
663 * kinematics measurements.
664 * @param initialBias initial gyroscope bias to be used to find a
665 * solution. This must have length 3 and is expressed
666 * in radians per second (rad/s).
667 * @param initialMg initial gyroscope scale factors and cross coupling
668 * errors matrix. Must be 3x3.
669 * @param initialGg initial gyroscope G-dependent cross biases
670 * introduced on the gyroscope by the specific forces
671 * sensed by the accelerometer. Must be 3x3.
672 * @param accelerometerBias known accelerometer bias. This must
673 * have length 3 and is expressed in
674 * meters per squared second
675 * (m/s^2).
676 * @param accelerometerMa known accelerometer scale factors and
677 * cross coupling matrix. Must be 3x3.
678 * @throws IllegalArgumentException if any of the provided values does
679 * not have proper size.
680 */
681 protected RobustEasyGyroscopeCalibrator(
682 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
683 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
684 final double[] accelerometerBias, final Matrix accelerometerMa) {
685 this(sequences, initialBias, initialMg, initialGg);
686 try {
687 setAccelerometerBias(accelerometerBias);
688 setAccelerometerMa(accelerometerMa);
689 } catch (final LockedException ignore) {
690 // never happens
691 }
692 }
693
694 /**
695 * Constructor.
696 *
697 * @param sequences collection of sequences containing timestamped body
698 * kinematics measurements.
699 * @param initialBias initial gyroscope bias to be used to find a
700 * solution. This must have length 3 and is expressed
701 * in radians per second (rad/s).
702 * @param initialMg initial gyroscope scale factors and cross coupling
703 * errors matrix. Must be 3x3.
704 * @param initialGg initial gyroscope G-dependent cross biases
705 * introduced on the gyroscope by the specific forces
706 * sensed by the accelerometer. Must be 3x3.
707 * @param accelerometerBias known accelerometer bias. This must
708 * have length 3 and is expressed in
709 * meters per squared second
710 * (m/s^2).
711 * @param accelerometerMa known accelerometer scale factors and
712 * cross coupling matrix. Must be 3x3.
713 * @param listener listener to handle events raised by this
714 * calibrator.
715 * @throws IllegalArgumentException if any of the provided values does
716 * not have proper size.
717 */
718 protected RobustEasyGyroscopeCalibrator(
719 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
720 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
721 final double[] accelerometerBias, final Matrix accelerometerMa,
722 final RobustEasyGyroscopeCalibratorListener listener) {
723 this(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa);
724 this.listener = listener;
725 }
726
727 /**
728 * Constructor.
729 *
730 * @param sequences collection of sequences containing timestamped body
731 * kinematics measurements.
732 * @param initialBias initial gyroscope bias to be used to find a
733 * solution. This must be 3x1 and is expressed
734 * in radians per second (rad/s).
735 * @param initialMg initial gyroscope scale factors and cross coupling
736 * errors matrix. Must be 3x3.
737 * @param initialGg initial gyroscope G-dependent cross biases
738 * introduced on the gyroscope by the specific forces
739 * sensed by the accelerometer. Must be 3x3.
740 * @param accelerometerBias known accelerometer bias. This must be 3x1
741 * and is expressed in meters per squared
742 * second (m/s^2).
743 * @param accelerometerMa known accelerometer scale factors and
744 * cross coupling matrix. Must be 3x3.
745 * @throws IllegalArgumentException if any of the provided values does
746 * not have proper size.
747 */
748 protected RobustEasyGyroscopeCalibrator(
749 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
750 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
751 final Matrix accelerometerMa) {
752 this(sequences, initialBias, initialMg, initialGg);
753 try {
754 setAccelerometerBias(accelerometerBias);
755 setAccelerometerMa(accelerometerMa);
756 } catch (final LockedException ignore) {
757 // never happens
758 }
759 }
760
761 /**
762 * Constructor.
763 *
764 * @param sequences collection of sequences containing timestamped body
765 * kinematics measurements.
766 * @param initialBias initial gyroscope bias to be used to find a
767 * solution. This must be 3x1 and is expressed
768 * in radians per second (rad/s).
769 * @param initialMg initial gyroscope scale factors and cross coupling
770 * errors matrix. Must be 3x3.
771 * @param initialGg initial gyroscope G-dependent cross biases
772 * introduced on the gyroscope by the specific forces
773 * sensed by the accelerometer. Must be 3x3.
774 * @param accelerometerBias known accelerometer bias. This must be 3x1
775 * and is expressed in meters per squared
776 * second (m/s^2).
777 * @param accelerometerMa known accelerometer scale factors and
778 * cross coupling matrix. Must be 3x3.
779 * @param listener listener to handle events raised by this
780 * calibrator.
781 * @throws IllegalArgumentException if any of the provided values does
782 * not have proper size.
783 */
784 protected RobustEasyGyroscopeCalibrator(
785 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
786 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
787 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
788 this(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa);
789 this.listener = listener;
790 }
791
792 /**
793 * Constructor.
794 *
795 * @param sequences collection of sequences containing timestamped body
796 * kinematics measurements.
797 * @param commonAxisUsed indicates whether z-axis is
798 * assumed to be common for
799 * accelerometer and gyroscope.
800 * @param estimateGDependentCrossBiases true if G-dependent cross biases
801 * will be estimated, false
802 * otherwise.
803 * @param initialBias initial gyroscope bias to be used to find a
804 * solution. This must be 3x1 and is expressed
805 * in radians per second (rad/s).
806 * @param initialMg initial gyroscope scale factors and cross coupling
807 * errors matrix. Must be 3x3.
808 * @param initialGg initial gyroscope G-dependent cross biases
809 * introduced on the gyroscope by the specific forces
810 * sensed by the accelerometer. Must be 3x3.
811 * @throws IllegalArgumentException if any of the provided values does
812 * not have proper size.
813 */
814 protected RobustEasyGyroscopeCalibrator(
815 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
816 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
817 final Matrix initialMg, final Matrix initialGg) {
818 this(sequences, initialBias, initialMg, initialGg);
819 this.commonAxisUsed = commonAxisUsed;
820 this.estimateGDependentCrossBiases = estimateGDependentCrossBiases;
821 }
822
823 /**
824 * Constructor.
825 *
826 * @param sequences collection of sequences containing timestamped body
827 * kinematics measurements.
828 * @param commonAxisUsed indicates whether z-axis is
829 * assumed to be common for
830 * accelerometer and gyroscope.
831 * @param estimateGDependentCrossBiases true if G-dependent cross biases
832 * will be estimated, false
833 * otherwise.
834 * @param initialBias initial gyroscope bias to be used to find a
835 * solution. This must be 3x1 and is expressed
836 * in radians per second (rad/s).
837 * @param initialMg initial gyroscope scale factors and cross coupling
838 * errors matrix. Must be 3x3.
839 * @param initialGg initial gyroscope G-dependent cross biases
840 * introduced on the gyroscope by the specific forces
841 * sensed by the accelerometer. Must be 3x3.
842 * @param listener listener to handle events raised by this
843 * calibrator.
844 * @throws IllegalArgumentException if any of the provided values does
845 * not have proper size.
846 */
847 protected RobustEasyGyroscopeCalibrator(
848 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
849 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
850 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener) {
851 this(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
852 this.listener = listener;
853 }
854
855 /**
856 * Constructor.
857 *
858 * @param sequences collection of sequences containing timestamped body
859 * kinematics measurements.
860 * @param commonAxisUsed indicates whether z-axis is
861 * assumed to be common for
862 * accelerometer and gyroscope.
863 * @param estimateGDependentCrossBiases true if G-dependent cross biases
864 * will be estimated, false
865 * otherwise.
866 * @param initialBias initial gyroscope bias to be used to find a
867 * solution. This must have length 3 and is expressed
868 * in radians per second (rad/s).
869 * @param initialMg initial gyroscope scale factors and cross coupling
870 * errors matrix. Must be 3x3.
871 * @param initialGg initial gyroscope G-dependent cross biases
872 * introduced on the gyroscope by the specific forces
873 * sensed by the accelerometer. Must be 3x3.
874 * @throws IllegalArgumentException if any of the provided values does
875 * not have proper size.
876 */
877 protected RobustEasyGyroscopeCalibrator(
878 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
879 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
880 final Matrix initialMg, final Matrix initialGg) {
881 this(sequences, initialBias, initialMg, initialGg);
882 this.commonAxisUsed = commonAxisUsed;
883 this.estimateGDependentCrossBiases = estimateGDependentCrossBiases;
884 }
885
886 /**
887 * Constructor.
888 *
889 * @param sequences collection of sequences containing timestamped body
890 * kinematics measurements.
891 * @param commonAxisUsed indicates whether z-axis is
892 * assumed to be common for
893 * accelerometer and gyroscope.
894 * @param estimateGDependentCrossBiases true if G-dependent cross biases
895 * will be estimated, false
896 * otherwise.
897 * @param initialBias initial gyroscope bias to be used to find a
898 * solution. This must have length 3 and is expressed
899 * in radians per second (rad/s).
900 * @param initialMg initial gyroscope scale factors and cross coupling
901 * errors matrix. Must be 3x3.
902 * @param initialGg initial gyroscope G-dependent cross biases
903 * introduced on the gyroscope by the specific forces
904 * sensed by the accelerometer. Must be 3x3.
905 * @param listener listener to handle events raised by this
906 * calibrator.
907 * @throws IllegalArgumentException if any of the provided values does
908 * not have proper size.
909 */
910 protected RobustEasyGyroscopeCalibrator(
911 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
912 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
913 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener) {
914 this(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
915 this.listener = listener;
916 }
917
918 /**
919 * Constructor.
920 *
921 * @param sequences collection of sequences containing timestamped body
922 * kinematics measurements.
923 * @param commonAxisUsed indicates whether z-axis is
924 * assumed to be common for
925 * accelerometer and gyroscope.
926 * @param estimateGDependentCrossBiases true if G-dependent cross biases
927 * will be estimated, false
928 * otherwise.
929 * @param initialBias initial gyroscope bias to be used to find a
930 * solution. This must have length 3 and is expressed
931 * in radians per second (rad/s).
932 * @param initialMg initial gyroscope scale factors and cross coupling
933 * errors matrix. Must be 3x3.
934 * @param initialGg initial gyroscope G-dependent cross biases
935 * introduced on the gyroscope by the specific forces
936 * sensed by the accelerometer. Must be 3x3.
937 * @param accelerometerBias known accelerometer bias. This
938 * must have length 3 and is
939 * expressed in meters per squared
940 * second (m/s^2).
941 * @param accelerometerMa known accelerometer scale factors
942 * and cross coupling matrix. Must
943 * be 3x3.
944 * @throws IllegalArgumentException if any of the provided values does
945 * not have proper size.
946 */
947 protected RobustEasyGyroscopeCalibrator(
948 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
949 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
950 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
951 final Matrix accelerometerMa) {
952 this(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa);
953 this.commonAxisUsed = commonAxisUsed;
954 this.estimateGDependentCrossBiases = estimateGDependentCrossBiases;
955 }
956
957 /**
958 * Constructor.
959 *
960 * @param sequences collection of sequences containing timestamped body
961 * kinematics measurements.
962 * @param commonAxisUsed indicates whether z-axis is
963 * assumed to be common for
964 * accelerometer and gyroscope.
965 * @param estimateGDependentCrossBiases true if G-dependent cross biases
966 * will be estimated, false
967 * otherwise.
968 * @param initialBias initial gyroscope bias to be used to find a
969 * solution. This must have length 3 and is expressed
970 * in radians per second (rad/s).
971 * @param initialMg initial gyroscope scale factors and cross coupling
972 * errors matrix. Must be 3x3.
973 * @param initialGg initial gyroscope G-dependent cross biases
974 * introduced on the gyroscope by the specific forces
975 * sensed by the accelerometer. Must be 3x3.
976 * @param accelerometerBias known accelerometer bias. This
977 * must have length 3 and is
978 * expressed in meters per squared
979 * second (m/s^2).
980 * @param accelerometerMa known accelerometer scale factors
981 * and cross coupling matrix. Must
982 * be 3x3.
983 * @param listener listener to handle events raised by this
984 * calibrator.
985 * @throws IllegalArgumentException if any of the provided values does
986 * not have proper size.
987 */
988 protected RobustEasyGyroscopeCalibrator(
989 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
990 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
991 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
992 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
993 this(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
994 accelerometerBias, accelerometerMa);
995 this.listener = listener;
996 }
997
998 /**
999 * Constructor.
1000 *
1001 * @param sequences collection of sequences containing timestamped body
1002 * kinematics measurements.
1003 * @param commonAxisUsed indicates whether z-axis is
1004 * assumed to be common for
1005 * accelerometer and gyroscope.
1006 * @param estimateGDependentCrossBiases true if G-dependent cross biases
1007 * will be estimated, false
1008 * otherwise.
1009 * @param initialBias initial gyroscope bias to be used to find a
1010 * solution. This must be 3x1 and is expressed
1011 * in radians per second (rad/s).
1012 * @param initialMg initial gyroscope scale factors and cross coupling
1013 * errors matrix. Must be 3x3.
1014 * @param initialGg initial gyroscope G-dependent cross biases
1015 * introduced on the gyroscope by the specific forces
1016 * sensed by the accelerometer. Must be 3x3.
1017 * @param accelerometerBias known accelerometer bias. This
1018 * must have length 3 and is
1019 * expressed in meters per squared
1020 * second (m/s^2).
1021 * @param accelerometerMa known accelerometer scale factors
1022 * and cross coupling matrix. Must
1023 * be 3x3.
1024 * @throws IllegalArgumentException if any of the provided values does
1025 * not have proper size.
1026 */
1027 protected RobustEasyGyroscopeCalibrator(
1028 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
1029 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
1030 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
1031 final Matrix accelerometerMa) {
1032 this(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa);
1033 this.commonAxisUsed = commonAxisUsed;
1034 this.estimateGDependentCrossBiases = estimateGDependentCrossBiases;
1035 }
1036
1037 /**
1038 * Constructor.
1039 *
1040 * @param sequences collection of sequences containing timestamped body
1041 * kinematics measurements.
1042 * @param commonAxisUsed indicates whether z-axis is
1043 * assumed to be common for
1044 * accelerometer and gyroscope.
1045 * @param estimateGDependentCrossBiases true if G-dependent cross biases
1046 * will be estimated, false
1047 * otherwise.
1048 * @param initialBias initial gyroscope bias to be used to find a
1049 * solution. This must be 3x1 and is expressed
1050 * in radians per second (rad/s).
1051 * @param initialMg initial gyroscope scale factors and cross coupling
1052 * errors matrix. Must be 3x3.
1053 * @param initialGg initial gyroscope G-dependent cross biases
1054 * introduced on the gyroscope by the specific forces
1055 * sensed by the accelerometer. Must be 3x3.
1056 * @param accelerometerBias known accelerometer bias. This
1057 * must have length 3 and is
1058 * expressed in meters per squared
1059 * second (m/s^2).
1060 * @param accelerometerMa known accelerometer scale factors
1061 * and cross coupling matrix. Must
1062 * be 3x3.
1063 * @param listener listener to handle events raised by this
1064 * calibrator.
1065 * @throws IllegalArgumentException if any of the provided values does
1066 * not have proper size.
1067 */
1068 protected RobustEasyGyroscopeCalibrator(
1069 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
1070 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
1071 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
1072 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
1073 this(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
1074 accelerometerBias, accelerometerMa);
1075 this.listener = listener;
1076 }
1077
1078 /**
1079 * Gets known x-coordinate of accelerometer bias to be used to fix
1080 * measured specific force and find cross biases introduced by the
1081 * accelerometer.
1082 * This is expressed in meters per squared second (m/s^2).
1083 *
1084 * @return known x-coordinate of accelerometer bias.
1085 */
1086 @Override
1087 public double getAccelerometerBiasX() {
1088 return accelerometerBiasX;
1089 }
1090
1091 /**
1092 * Sets known x-coordinate of accelerometer bias to be used to fix
1093 * measured specific force and find cross biases introduced by the
1094 * accelerometer.
1095 * This is expressed in meters per squared second (m/s^2).
1096 *
1097 * @param accelerometerBiasX known x-coordinate of accelerometer bias.
1098 * @throws LockedException if calibrator is currently running.
1099 */
1100 @Override
1101 public void setAccelerometerBiasX(final double accelerometerBiasX) throws LockedException {
1102 if (running) {
1103 throw new LockedException();
1104 }
1105 this.accelerometerBiasX = accelerometerBiasX;
1106 }
1107
1108 /**
1109 * Gets known y-coordinate of accelerometer bias to be used to fix
1110 * measured specific force and find cross biases introduced by the
1111 * accelerometer.
1112 * This is expressed in meters per squared second (m/s^2).
1113 *
1114 * @return known y-coordinate of accelerometer bias.
1115 */
1116 @Override
1117 public double getAccelerometerBiasY() {
1118 return accelerometerBiasY;
1119 }
1120
1121 /**
1122 * Sets known y-coordinate of accelerometer bias to be used to fix
1123 * measured specific force and find cross biases introduced by the
1124 * accelerometer.
1125 * This is expressed in meters per squared second (m/s^2).
1126 *
1127 * @param accelerometerBiasY known y-coordinate of accelerometer bias.
1128 * @throws LockedException if calibrator is currently running.
1129 */
1130 @Override
1131 public void setAccelerometerBiasY(final double accelerometerBiasY) throws LockedException {
1132 if (running) {
1133 throw new LockedException();
1134 }
1135 this.accelerometerBiasY = accelerometerBiasY;
1136 }
1137
1138 /**
1139 * Gets known z-coordinate of accelerometer bias to be used to fix
1140 * measured specific force and find cross biases introduced by the
1141 * accelerometer.
1142 * This is expressed in meters per squared second (m/s^2).
1143 *
1144 * @return known z-coordinate of accelerometer bias.
1145 */
1146 @Override
1147 public double getAccelerometerBiasZ() {
1148 return accelerometerBiasZ;
1149 }
1150
1151 /**
1152 * Sets known z-coordinate of accelerometer bias to be used to fix
1153 * measured specific force and find cross biases introduced by the
1154 * accelerometer.
1155 * This is expressed in meters per squared second (m/s^2).
1156 *
1157 * @param accelerometerBiasZ known z-coordinate of accelerometer bias.
1158 * @throws LockedException if calibrator is currently running.
1159 */
1160 @Override
1161 public void setAccelerometerBiasZ(final double accelerometerBiasZ) throws LockedException {
1162 if (running) {
1163 throw new LockedException();
1164 }
1165 this.accelerometerBiasZ = accelerometerBiasZ;
1166 }
1167
1168 /**
1169 * Gets known x-coordinate of accelerometer bias to be used to fix
1170 * measured specific force and find cross biases introduced by the
1171 * accelerometer.
1172 *
1173 * @return known x-coordinate of accelerometer bias.
1174 */
1175 @Override
1176 public Acceleration getAccelerometerBiasXAsAcceleration() {
1177 return new Acceleration(accelerometerBiasX, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1178 }
1179
1180 /**
1181 * Gets known x-coordinate of accelerometer bias to be used to fix
1182 * measured specific force and find cross biases introduced by the
1183 * accelerometer.
1184 *
1185 * @param result instance where result data will be stored.
1186 */
1187 @Override
1188 public void getAccelerometerBiasXAsAcceleration(final Acceleration result) {
1189 result.setValue(accelerometerBiasX);
1190 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1191 }
1192
1193 /**
1194 * Sets known x-coordinate of accelerometer bias to be used to fix
1195 * measured specific force and find cross biases introduced by the
1196 * accelerometer.
1197 *
1198 * @param accelerometerBiasX x-coordinate of accelerometer bias.
1199 * @throws LockedException if calibrator is currently running.
1200 */
1201 @Override
1202 public void setAccelerometerBiasX(final Acceleration accelerometerBiasX) throws LockedException {
1203 if (running) {
1204 throw new LockedException();
1205 }
1206 this.accelerometerBiasX = convertAcceleration(accelerometerBiasX);
1207 }
1208
1209 /**
1210 * Gets known y-coordinate of accelerometer bias to be used to fix
1211 * measured specific force and find cross biases introduced by the
1212 * accelerometer.
1213 *
1214 * @return known y-coordinate of accelerometer bias.
1215 */
1216 @Override
1217 public Acceleration getAccelerometerBiasYAsAcceleration() {
1218 return new Acceleration(accelerometerBiasY, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1219 }
1220
1221 /**
1222 * Gets known y-coordinate of accelerometer bias to be used to fix
1223 * measured specific force and find cross biases introduced by the
1224 * accelerometer.
1225 *
1226 * @param result instance where result data will be stored.
1227 */
1228 @Override
1229 public void getAccelerometerBiasYAsAcceleration(final Acceleration result) {
1230 result.setValue(accelerometerBiasY);
1231 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1232 }
1233
1234 /**
1235 * Sets known y-coordinate of accelerometer bias to be used to fix
1236 * measured specific force and find cross biases introduced by the
1237 * accelerometer.
1238 *
1239 * @param accelerometerBiasY y-coordinate of accelerometer bias.
1240 * @throws LockedException if calibrator is currently running.
1241 */
1242 @Override
1243 public void setAccelerometerBiasY(final Acceleration accelerometerBiasY) throws LockedException {
1244 if (running) {
1245 throw new LockedException();
1246 }
1247 this.accelerometerBiasY = convertAcceleration(accelerometerBiasY);
1248 }
1249
1250 /**
1251 * Gets known z-coordinate of accelerometer bias to be used to fix
1252 * measured specific force and find cross biases introduced by the
1253 * accelerometer.
1254 *
1255 * @return known z-coordinate of accelerometer bias.
1256 */
1257 @Override
1258 public Acceleration getAccelerometerBiasZAsAcceleration() {
1259 return new Acceleration(accelerometerBiasZ, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1260 }
1261
1262 /**
1263 * Gets known z-coordinate of accelerometer bias to be used to fix
1264 * measured specific force and find cross biases introduced by the
1265 * accelerometer.
1266 *
1267 * @param result instance where result data will be stored.
1268 */
1269 @Override
1270 public void getAccelerometerBiasZAsAcceleration(final Acceleration result) {
1271 result.setValue(accelerometerBiasZ);
1272 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
1273 }
1274
1275 /**
1276 * Sets known z-coordinate of accelerometer bias to be used to fix
1277 * measured specific force and find cross biases introduced by the
1278 * accelerometer.
1279 *
1280 * @param accelerometerBiasZ z-coordinate of accelerometer bias.
1281 * @throws LockedException if calibrator is currently running.
1282 */
1283 @Override
1284 public void setAccelerometerBiasZ(final Acceleration accelerometerBiasZ) throws LockedException {
1285 if (running) {
1286 throw new LockedException();
1287 }
1288 this.accelerometerBiasZ = convertAcceleration(accelerometerBiasZ);
1289 }
1290
1291 /**
1292 * Sets known accelerometer bias to be used to fix measured specific
1293 * force and find cross biases introduced by the accelerometer.
1294 * This is expressed in meters per squared second (m/s^2).
1295 *
1296 * @param accelerometerBiasX x-coordinate of accelerometer bias.
1297 * @param accelerometerBiasY y-coordinate of accelerometer bias.
1298 * @param accelerometerBiasZ z-coordinate of accelerometer bias.
1299 * @throws LockedException if calibrator is currently running.
1300 */
1301 @Override
1302 public void setAccelerometerBias(
1303 final double accelerometerBiasX, final double accelerometerBiasY, final double accelerometerBiasZ)
1304 throws LockedException {
1305 if (running) {
1306 throw new LockedException();
1307 }
1308
1309 this.accelerometerBiasX = accelerometerBiasX;
1310 this.accelerometerBiasY = accelerometerBiasY;
1311 this.accelerometerBiasZ = accelerometerBiasZ;
1312 }
1313
1314 /**
1315 * Sets known accelerometer bias to be used to fix measured specific
1316 * force and find cross biases introduced by the accelerometer.
1317 *
1318 * @param accelerometerBiasX x-coordinate of accelerometer bias.
1319 * @param accelerometerBiasY y-coordinate of accelerometer bias.
1320 * @param accelerometerBiasZ z-coordinate of accelerometer bias.
1321 * @throws LockedException if calibrator is currently running.
1322 */
1323 @Override
1324 public void setAccelerometerBias(
1325 final Acceleration accelerometerBiasX, final Acceleration accelerometerBiasY,
1326 final Acceleration accelerometerBiasZ) throws LockedException {
1327 if (running) {
1328 throw new LockedException();
1329 }
1330
1331 this.accelerometerBiasX = convertAcceleration(accelerometerBiasX);
1332 this.accelerometerBiasY = convertAcceleration(accelerometerBiasY);
1333 this.accelerometerBiasZ = convertAcceleration(accelerometerBiasZ);
1334 }
1335
1336 /**
1337 * Gets known accelerometer bias to be used to fix measured specific
1338 * force and find cross biases introduced by the accelerometer.
1339 * This is expressed in meters per squared second (m/s^2).
1340 *
1341 * @return known accelerometer bias.
1342 */
1343 @Override
1344 public double[] getAccelerometerBias() {
1345 final var result = new double[BodyKinematics.COMPONENTS];
1346 getAccelerometerBias(result);
1347 return result;
1348 }
1349
1350 /**
1351 * Gets known accelerometer bias to be used to fix measured specific
1352 * force and find cross biases introduced by the accelerometer.
1353 * This is expressed in meters per squared second (m/s^2).
1354 *
1355 * @param result instance where result data will be copied to.
1356 * @throws IllegalArgumentException if provided array does not have
1357 * length 3.
1358 */
1359 @Override
1360 public void getAccelerometerBias(final double[] result) {
1361 if (result.length != BodyKinematics.COMPONENTS) {
1362 throw new IllegalArgumentException();
1363 }
1364
1365 result[0] = accelerometerBiasX;
1366 result[1] = accelerometerBiasY;
1367 result[2] = accelerometerBiasZ;
1368 }
1369
1370 /**
1371 * Sets known accelerometer bias to be used to fix measured specific
1372 * force and find cross biases introduced by the accelerometer.
1373 * This is expressed in meters per squared second (m/s^2).
1374 *
1375 * @param accelerometerBias known accelerometer bias.
1376 * @throws LockedException if calibrator is currently running.
1377 * @throws IllegalArgumentException if provided array does not have
1378 * length 3.
1379 */
1380 @Override
1381 public void setAccelerometerBias(final double[] accelerometerBias) throws LockedException {
1382 if (running) {
1383 throw new LockedException();
1384 }
1385
1386 if (accelerometerBias.length != BodyKinematics.COMPONENTS) {
1387 throw new IllegalArgumentException();
1388 }
1389
1390 accelerometerBiasX = accelerometerBias[0];
1391 accelerometerBiasY = accelerometerBias[1];
1392 accelerometerBiasZ = accelerometerBias[2];
1393 }
1394
1395 /**
1396 * Gets known accelerometer bias to be used to fix measured specific
1397 * force and find cross biases introduced by the accelerometer.
1398 * This is expressed in meters per squared second (m/s^2).
1399 *
1400 * @return known accelerometer bias.
1401 */
1402 @Override
1403 public Matrix getAccelerometerBiasAsMatrix() {
1404 Matrix result;
1405 try {
1406 result = new Matrix(BodyKinematics.COMPONENTS, 1);
1407 getAccelerometerBiasAsMatrix(result);
1408 } catch (final WrongSizeException ignore) {
1409 // never happens
1410 result = null;
1411 }
1412 return result;
1413 }
1414
1415 /**
1416 * Gets known accelerometer bias to be used to fix measured specific
1417 * force and find cross biases introduced by the accelerometer.
1418 * This is expressed in meters per squared second (m/s^2).
1419 *
1420 * @param result instance where result data will be copied to.
1421 * @throws IllegalArgumentException if provided matrix is not 3x1.
1422 */
1423 @Override
1424 public void getAccelerometerBiasAsMatrix(final Matrix result) {
1425 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1426 throw new IllegalArgumentException();
1427 }
1428 result.setElementAtIndex(0, accelerometerBiasX);
1429 result.setElementAtIndex(1, accelerometerBiasY);
1430 result.setElementAtIndex(2, accelerometerBiasZ);
1431 }
1432
1433 /**
1434 * Sets known accelerometer bias to be used to fix measured specific
1435 * force and find cross biases introduced by the accelerometer.
1436 * This is expressed in meters per squared second (m/s^2).
1437 *
1438 * @param accelerometerBias known accelerometer bias. Must be 3x1.
1439 * @throws LockedException if calibrator is currently running.
1440 * @throws IllegalArgumentException if provided matrix is not 3x1.
1441 */
1442 @Override
1443 public void setAccelerometerBias(final Matrix accelerometerBias) throws LockedException {
1444 if (running) {
1445 throw new LockedException();
1446 }
1447 if (accelerometerBias.getRows() != BodyKinematics.COMPONENTS || accelerometerBias.getColumns() != 1) {
1448 throw new IllegalArgumentException();
1449 }
1450
1451 accelerometerBiasX = accelerometerBias.getElementAtIndex(0);
1452 accelerometerBiasY = accelerometerBias.getElementAtIndex(1);
1453 accelerometerBiasZ = accelerometerBias.getElementAtIndex(2);
1454 }
1455
1456 /**
1457 * Gets known accelerometer x scaling factor to be used to fix measured
1458 * specific force and find cross biases introduced by the accelerometer.
1459 *
1460 * @return known accelerometer x scaling factor.
1461 */
1462 @Override
1463 public double getAccelerometerSx() {
1464 return accelerometerSx;
1465 }
1466
1467 /**
1468 * Sets known accelerometer x scaling factor to be used to fix measured
1469 * specific force and find cross biases introduced by the accelerometer.
1470 *
1471 * @param accelerometerSx known accelerometer x scaling factor.
1472 * @throws LockedException if calibrator is currently running.
1473 */
1474 @Override
1475 public void setAccelerometerSx(final double accelerometerSx) throws LockedException {
1476 if (running) {
1477 throw new LockedException();
1478 }
1479 this.accelerometerSx = accelerometerSx;
1480 }
1481
1482 /**
1483 * Gets known accelerometer y scaling factor to be used to fix measured
1484 * specific force and find cross biases introduced by the accelerometer.
1485 *
1486 * @return known accelerometer y scaling factor.
1487 */
1488 @Override
1489 public double getAccelerometerSy() {
1490 return accelerometerSy;
1491 }
1492
1493 /**
1494 * Sets known accelerometer y scaling factor to be used to fix measured
1495 * specific force and find cross biases introduced by the accelerometer.
1496 *
1497 * @param accelerometerSy known accelerometer y scaling factor.
1498 * @throws LockedException if calibrator is currently running.
1499 */
1500 @Override
1501 public void setAccelerometerSy(final double accelerometerSy) throws LockedException {
1502 if (running) {
1503 throw new LockedException();
1504 }
1505 this.accelerometerSy = accelerometerSy;
1506 }
1507
1508 /**
1509 * Gets known accelerometer z scaling factor to be used to fix measured
1510 * specific force and find cross biases introduced by the accelerometer.
1511 *
1512 * @return known accelerometer z scaling factor.
1513 */
1514 @Override
1515 public double getAccelerometerSz() {
1516 return accelerometerSz;
1517 }
1518
1519 /**
1520 * Sets known accelerometer z scaling factor to be used to fix measured
1521 * specific force and find cross biases introduced by the accelerometer.
1522 *
1523 * @param accelerometerSz known accelerometer z scaling factor.
1524 * @throws LockedException if calibrator is currently running.
1525 */
1526 @Override
1527 public void setAccelerometerSz(final double accelerometerSz) throws LockedException {
1528 if (running) {
1529 throw new LockedException();
1530 }
1531 this.accelerometerSz = accelerometerSz;
1532 }
1533
1534 /**
1535 * Gets known accelerometer x-y cross coupling error to be used to fix
1536 * measured specific force and find cross biases introduced by the
1537 * accelerometer.
1538 *
1539 * @return known accelerometer x-y cross coupling error.
1540 */
1541 @Override
1542 public double getAccelerometerMxy() {
1543 return accelerometerMxy;
1544 }
1545
1546 /**
1547 * Sets known accelerometer x-y cross coupling error to be used to fix
1548 * measured specific force and find cross biases introduced by the
1549 * accelerometer.
1550 *
1551 * @param accelerometerMxy known accelerometer x-y cross coupling error.
1552 * @throws LockedException if calibrator is currently running.
1553 */
1554 @Override
1555 public void setAccelerometerMxy(final double accelerometerMxy) throws LockedException {
1556 if (running) {
1557 throw new LockedException();
1558 }
1559 this.accelerometerMxy = accelerometerMxy;
1560 }
1561
1562 /**
1563 * Gets known accelerometer x-z cross coupling error to be used to fix
1564 * measured specific force and find cross biases introduced by the
1565 * accelerometer.
1566 *
1567 * @return known accelerometer x-z cross coupling error.
1568 */
1569 @Override
1570 public double getAccelerometerMxz() {
1571 return accelerometerMxz;
1572 }
1573
1574 /**
1575 * Sets known accelerometer x-z cross coupling error to be used to fix
1576 * measured specific force and find cross biases introduced by the
1577 * accelerometer.
1578 *
1579 * @param accelerometerMxz known accelerometer x-z cross coupling error.
1580 * @throws LockedException if calibrator is currently running.
1581 */
1582 @Override
1583 public void setAccelerometerMxz(final double accelerometerMxz) throws LockedException {
1584 if (running) {
1585 throw new LockedException();
1586 }
1587 this.accelerometerMxz = accelerometerMxz;
1588 }
1589
1590 /**
1591 * Gets known accelerometer y-x cross coupling error to be used to fix
1592 * measured specific force and find cross biases introduced by the
1593 * accelerometer.
1594 *
1595 * @return known accelerometer y-x cross coupling error.
1596 */
1597 @Override
1598 public double getAccelerometerMyx() {
1599 return accelerometerMyx;
1600 }
1601
1602 /**
1603 * Sets known accelerometer y-x cross coupling error to be used to fix
1604 * measured specific force and find cross biases introduced by the
1605 * accelerometer.
1606 *
1607 * @param accelerometerMyx known accelerometer y-x cross coupling
1608 * error.
1609 * @throws LockedException if calibrator is currently running.
1610 */
1611 @Override
1612 public void setAccelerometerMyx(final double accelerometerMyx) throws LockedException {
1613 if (running) {
1614 throw new LockedException();
1615 }
1616 this.accelerometerMyx = accelerometerMyx;
1617 }
1618
1619 /**
1620 * Gets known accelerometer y-z cross coupling error to be used to fix
1621 * measured specific force and find cross biases introduced by the
1622 * accelerometer.
1623 *
1624 * @return known accelerometer y-z cross coupling error.
1625 */
1626 @Override
1627 public double getAccelerometerMyz() {
1628 return accelerometerMyz;
1629 }
1630
1631 /**
1632 * Sets known accelerometer y-z cross coupling error to be used to fix
1633 * measured specific force and find cross biases introduced by the
1634 * accelerometer.
1635 *
1636 * @param accelerometerMyz known accelerometer y-z cross coupling
1637 * error.
1638 * @throws LockedException if calibrator is currently running.
1639 */
1640 @Override
1641 public void setAccelerometerMyz(final double accelerometerMyz) throws LockedException {
1642 if (running) {
1643 throw new LockedException();
1644 }
1645 this.accelerometerMyz = accelerometerMyz;
1646 }
1647
1648 /**
1649 * Gets known accelerometer z-x cross coupling error to be used to fix
1650 * measured specific force and find cross biases introduced by the
1651 * accelerometer.
1652 *
1653 * @return known accelerometer z-x cross coupling error.
1654 */
1655 @Override
1656 public double getAccelerometerMzx() {
1657 return accelerometerMzx;
1658 }
1659
1660 /**
1661 * Sets known accelerometer z-x cross coupling error to be used to fix
1662 * measured specific force and find cross biases introduced by the
1663 * accelerometer.
1664 *
1665 * @param accelerometerMzx known accelerometer z-x cross coupling
1666 * error.
1667 * @throws LockedException if calibrator is currently running.
1668 */
1669 @Override
1670 public void setAccelerometerMzx(final double accelerometerMzx) throws LockedException {
1671 if (running) {
1672 throw new LockedException();
1673 }
1674 this.accelerometerMzx = accelerometerMzx;
1675 }
1676
1677 /**
1678 * Gets known accelerometer z-y cross coupling error to be used to fix
1679 * measured specific force and find cross biases introduced by the
1680 * accelerometer.
1681 *
1682 * @return known accelerometer z-y cross coupling error.
1683 */
1684 @Override
1685 public double getAccelerometerMzy() {
1686 return accelerometerMzy;
1687 }
1688
1689 /**
1690 * Sets known accelerometer z-y cross coupling error to be used to fix
1691 * measured specific force and find cross biases introduced by the
1692 * accelerometer.
1693 *
1694 * @param accelerometerMzy known accelerometer z-y cross coupling
1695 * error.
1696 * @throws LockedException if calibrator is currently running.
1697 */
1698 @Override
1699 public void setAccelerometerMzy(final double accelerometerMzy) throws LockedException {
1700 if (running) {
1701 throw new LockedException();
1702 }
1703 this.accelerometerMzy = accelerometerMzy;
1704 }
1705
1706 /**
1707 * Sets known accelerometer scaling factors to be used to fix measured
1708 * specific force and find cross biases introduced by the
1709 * accelerometer.
1710 *
1711 * @param accelerometerSx known accelerometer x scaling factor.
1712 * @param accelerometerSy known accelerometer y scaling factor.
1713 * @param accelerometerSz known accelerometer z scaling factor.
1714 * @throws LockedException if calibrator is currently running.
1715 */
1716 @Override
1717 public void setAccelerometerScalingFactors(
1718 final double accelerometerSx, final double accelerometerSy, final double accelerometerSz)
1719 throws LockedException {
1720 if (running) {
1721 throw new LockedException();
1722 }
1723 this.accelerometerSx = accelerometerSx;
1724 this.accelerometerSy = accelerometerSy;
1725 this.accelerometerSz = accelerometerSz;
1726 }
1727
1728 /**
1729 * Sets known accelerometer cross coupling errors to be used to fix
1730 * measured specific force and find cross biases introduced by the
1731 * accelerometer.
1732 *
1733 * @param accelerometerMxy known accelerometer x-y cross coupling
1734 * error.
1735 * @param accelerometerMxz known accelerometer x-z cross coupling
1736 * error.
1737 * @param accelerometerMyx known accelerometer y-x cross coupling
1738 * error.
1739 * @param accelerometerMyz known accelerometer y-z cross coupling
1740 * error.
1741 * @param accelerometerMzx known accelerometer z-x cross coupling
1742 * error.
1743 * @param accelerometerMzy known accelerometer z-y cross coupling
1744 * error.
1745 * @throws LockedException if calibrator is currently running.
1746 */
1747 @Override
1748 public void setAccelerometerCrossCouplingErrors(
1749 final double accelerometerMxy, final double accelerometerMxz,
1750 final double accelerometerMyx, final double accelerometerMyz,
1751 final double accelerometerMzx, final double accelerometerMzy) throws LockedException {
1752 if (running) {
1753 throw new LockedException();
1754 }
1755 this.accelerometerMxy = accelerometerMxy;
1756 this.accelerometerMxz = accelerometerMxz;
1757 this.accelerometerMyx = accelerometerMyx;
1758 this.accelerometerMyz = accelerometerMyz;
1759 this.accelerometerMzx = accelerometerMzx;
1760 this.accelerometerMzy = accelerometerMzy;
1761 }
1762
1763 /**
1764 * Sets known accelerometer scaling factors and cross coupling errors
1765 * to be used to fix measured specific force and find cross biases
1766 * introduced by the accelerometer.
1767 *
1768 * @param accelerometerSx known accelerometer x scaling factor.
1769 * @param accelerometerSy known accelerometer y scaling factor.
1770 * @param accelerometerSz known accelerometer z scaling factor.
1771 * @param accelerometerMxy known accelerometer x-y cross coupling
1772 * error.
1773 * @param accelerometerMxz known accelerometer x-z cross coupling
1774 * error.
1775 * @param accelerometerMyx known accelerometer y-x cross coupling
1776 * error.
1777 * @param accelerometerMyz known accelerometer y-z cross coupling
1778 * error.
1779 * @param accelerometerMzx known accelerometer z-x cross coupling
1780 * error.
1781 * @param accelerometerMzy known accelerometer z-y cross coupling
1782 * error.
1783 * @throws LockedException if calibrator is currently running.
1784 */
1785 @Override
1786 public void setAccelerometerScalingFactorsAndCrossCouplingErrors(
1787 final double accelerometerSx, final double accelerometerSy, final double accelerometerSz,
1788 final double accelerometerMxy, final double accelerometerMxz, final double accelerometerMyx,
1789 final double accelerometerMyz, final double accelerometerMzx, final double accelerometerMzy)
1790 throws LockedException {
1791 if (running) {
1792 throw new LockedException();
1793 }
1794 setAccelerometerScalingFactors(accelerometerSx, accelerometerSy, accelerometerSz);
1795 setAccelerometerCrossCouplingErrors(accelerometerMxy, accelerometerMxz, accelerometerMyx,
1796 accelerometerMyz, accelerometerMzx, accelerometerMzy);
1797 }
1798
1799 /**
1800 * Gets known accelerometer scale factors and cross coupling
1801 * errors matrix.
1802 *
1803 * @return known accelerometer scale factors and cross coupling
1804 * errors matrix.
1805 */
1806 @Override
1807 public Matrix getAccelerometerMa() {
1808 Matrix result;
1809 try {
1810 result = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
1811 getAccelerometerMa(result);
1812 } catch (final WrongSizeException ignore) {
1813 // never happens
1814 result = null;
1815 }
1816 return result;
1817 }
1818
1819 /**
1820 * Gets known accelerometer scale factors and cross coupling
1821 * errors matrix.
1822 *
1823 * @param result instance where data will be stored.
1824 * @throws IllegalArgumentException if provided matrix is not 3x3.
1825 */
1826 @Override
1827 public void getAccelerometerMa(final Matrix result) {
1828 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
1829 throw new IllegalArgumentException();
1830 }
1831 result.setElementAtIndex(0, accelerometerSx);
1832 result.setElementAtIndex(1, accelerometerMyx);
1833 result.setElementAtIndex(2, accelerometerMzx);
1834
1835 result.setElementAtIndex(3, accelerometerMxy);
1836 result.setElementAtIndex(4, accelerometerSy);
1837 result.setElementAtIndex(5, accelerometerMzy);
1838
1839 result.setElementAtIndex(6, accelerometerMxz);
1840 result.setElementAtIndex(7, accelerometerMyz);
1841 result.setElementAtIndex(8, accelerometerSz);
1842 }
1843
1844 /**
1845 * Sets known accelerometer scale factors and cross coupling
1846 * errors matrix.
1847 *
1848 * @param accelerometerMa known accelerometer scale factors and
1849 * cross coupling errors matrix. Must be 3x3.
1850 * @throws LockedException if calibrator is currently running.
1851 * @throws IllegalArgumentException if provided matrix is not 3x3.
1852 */
1853 @Override
1854 public void setAccelerometerMa(final Matrix accelerometerMa) throws LockedException {
1855 if (running) {
1856 throw new LockedException();
1857 }
1858 if (accelerometerMa.getRows() != BodyKinematics.COMPONENTS
1859 || accelerometerMa.getColumns() != BodyKinematics.COMPONENTS) {
1860 throw new IllegalArgumentException();
1861 }
1862
1863 accelerometerSx = accelerometerMa.getElementAtIndex(0);
1864 accelerometerMyx = accelerometerMa.getElementAtIndex(1);
1865 accelerometerMzx = accelerometerMa.getElementAtIndex(2);
1866
1867 accelerometerMxy = accelerometerMa.getElementAtIndex(3);
1868 accelerometerSy = accelerometerMa.getElementAtIndex(4);
1869 accelerometerMzy = accelerometerMa.getElementAtIndex(5);
1870
1871 accelerometerMxz = accelerometerMa.getElementAtIndex(6);
1872 accelerometerMyz = accelerometerMa.getElementAtIndex(7);
1873 accelerometerSz = accelerometerMa.getElementAtIndex(8);
1874 }
1875
1876 /**
1877 * Gets initial x-coordinate of gyroscope bias to be used to find
1878 * a solution.
1879 * This is expressed in radians per second (rad/s).
1880 *
1881 * @return initial x-coordinate of gyroscope bias.
1882 */
1883 public double getInitialBiasX() {
1884 return initialBiasX;
1885 }
1886
1887 /**
1888 * Sets initial x-coordinate of gyroscope bias to be used to find
1889 * a solution.
1890 * This is expressed in radians per second (rad/s).
1891 *
1892 * @param initialBiasX initial x-coordinate of gyroscope bias.
1893 * @throws LockedException if calibrator is currently running.
1894 */
1895 public void setInitialBiasX(final double initialBiasX) throws LockedException {
1896 if (running) {
1897 throw new LockedException();
1898 }
1899 this.initialBiasX = initialBiasX;
1900 }
1901
1902 /**
1903 * Gets initial y-coordinate of gyroscope bias to be used to find
1904 * a solution.
1905 * This is expressed in radians per second (rad/s).
1906 *
1907 * @return initial y-coordinate of gyroscope bias.
1908 */
1909 public double getInitialBiasY() {
1910 return initialBiasY;
1911 }
1912
1913 /**
1914 * Sets initial y-coordinate of gyroscope bias to be used to find
1915 * a solution.
1916 * This is expressed in radians per second (rad/s).
1917 *
1918 * @param initialBiasY initial y-coordinate of gyroscope bias.
1919 * @throws LockedException if calibrator is currently running.
1920 */
1921 public void setInitialBiasY(final double initialBiasY) throws LockedException {
1922 if (running) {
1923 throw new LockedException();
1924 }
1925 this.initialBiasY = initialBiasY;
1926 }
1927
1928 /**
1929 * Gets initial z-coordinate of gyroscope bias ot be used to find
1930 * a solution.
1931 * This is expressed in radians per second (rad/s).
1932 *
1933 * @return initial z-coordinate of gyroscope bias.
1934 */
1935 public double getInitialBiasZ() {
1936 return initialBiasZ;
1937 }
1938
1939 /**
1940 * Sets initial z-coordinate of gyroscope bias to be used to find
1941 * a solution.
1942 * This is expressed in radians per second (rad/s).
1943 *
1944 * @param initialBiasZ initial z-coordinate of gyroscope bias.
1945 * @throws LockedException if calibrator is currently running.
1946 */
1947 public void setInitialBiasZ(final double initialBiasZ) throws LockedException {
1948 if (running) {
1949 throw new LockedException();
1950 }
1951 this.initialBiasZ = initialBiasZ;
1952 }
1953
1954 /**
1955 * Gets initial x-coordinate of gyroscope bias to be used to find a
1956 * solution.
1957 *
1958 * @return initial x-coordinate of gyroscope bias.
1959 */
1960 public AngularSpeed getInitialBiasAngularSpeedX() {
1961 return new AngularSpeed(initialBiasX, AngularSpeedUnit.RADIANS_PER_SECOND);
1962 }
1963
1964 /**
1965 * Gets initial x-coordinate of gyroscope bias to be used to find a
1966 * solution.
1967 *
1968 * @param result instance where result data will be stored.
1969 */
1970 public void getInitialBiasAngularSpeedX(final AngularSpeed result) {
1971 result.setValue(initialBiasX);
1972 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
1973 }
1974
1975 /**
1976 * Sets initial x-coordinate of gyroscope bias to be used to find a
1977 * solution.
1978 *
1979 * @param initialBiasX initial x-coordinate of gyroscope bias.
1980 * @throws LockedException if calibrator is currently running.
1981 */
1982 public void setInitialBiasX(final AngularSpeed initialBiasX) throws LockedException {
1983 if (running) {
1984 throw new LockedException();
1985 }
1986 this.initialBiasX = convertAngularSpeed(initialBiasX);
1987 }
1988
1989 /**
1990 * Gets initial y-coordinate of gyroscope bias to be used to find a
1991 * solution.
1992 *
1993 * @return initial y-coordinate of gyroscope bias.
1994 */
1995 public AngularSpeed getInitialBiasAngularSpeedY() {
1996 return new AngularSpeed(initialBiasY, AngularSpeedUnit.RADIANS_PER_SECOND);
1997 }
1998
1999 /**
2000 * Gets initial y-coordinate of gyroscope bias to be used to find a
2001 * solution.
2002 *
2003 * @param result instance where result data will be stored.
2004 */
2005 public void getInitialBiasAngularSpeedY(final AngularSpeed result) {
2006 result.setValue(initialBiasY);
2007 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
2008 }
2009
2010 /**
2011 * Sets initial y-coordinate of gyroscope bias to be used to find a
2012 * solution.
2013 *
2014 * @param initialBiasY initial y-coordinate of gyroscope bias.
2015 * @throws LockedException if calibrator is currently running.
2016 */
2017 public void setInitialBiasY(final AngularSpeed initialBiasY) throws LockedException {
2018 if (running) {
2019 throw new LockedException();
2020 }
2021 this.initialBiasY = convertAngularSpeed(initialBiasY);
2022 }
2023
2024 /**
2025 * Gets initial z-coordinate of gyroscope bias to be used to find a
2026 * solution.
2027 *
2028 * @return initial z-coordinate of gyroscope bias.
2029 */
2030 public AngularSpeed getInitialBiasAngularSpeedZ() {
2031 return new AngularSpeed(initialBiasZ, AngularSpeedUnit.RADIANS_PER_SECOND);
2032 }
2033
2034 /**
2035 * Gets initial z-coordinate of gyroscope bias to be used to find a
2036 * solution.
2037 *
2038 * @param result instance where result data will be stored.
2039 */
2040 public void getInitialBiasAngularSpeedZ(final AngularSpeed result) {
2041 result.setValue(initialBiasZ);
2042 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
2043 }
2044
2045 /**
2046 * Sets initial z-coordinate of gyroscope bias to be used to find a
2047 * solution.
2048 *
2049 * @param initialBiasZ initial z-coordinate of gyroscope bias.
2050 * @throws LockedException if calibrator is currently running.
2051 */
2052 public void setInitialBiasZ(final AngularSpeed initialBiasZ) throws LockedException {
2053 if (running) {
2054 throw new LockedException();
2055 }
2056 this.initialBiasZ = convertAngularSpeed(initialBiasZ);
2057 }
2058
2059 /**
2060 * Sets initial bias coordinates of gyroscope used to find a solution
2061 * expressed in radians per second (rad/s).
2062 *
2063 * @param initialBiasX initial x-coordinate of gyroscope bias.
2064 * @param initialBiasY initial y-coordinate of gyroscope bias.
2065 * @param initialBiasZ initial z-coordinate of gyroscope bias.
2066 * @throws LockedException if calibrator is currently running.
2067 */
2068 public void setInitialBias(
2069 final double initialBiasX, final double initialBiasY, final double initialBiasZ) throws LockedException {
2070 if (running) {
2071 throw new LockedException();
2072 }
2073 this.initialBiasX = initialBiasX;
2074 this.initialBiasY = initialBiasY;
2075 this.initialBiasZ = initialBiasZ;
2076 }
2077
2078 /**
2079 * Sets initial bias coordinates of gyroscope used to find a solution.
2080 *
2081 * @param initialBiasX initial x-coordinate of gyroscope bias.
2082 * @param initialBiasY initial y-coordinate of gyroscope bias.
2083 * @param initialBiasZ initial z-coordinate of gyroscope bias.
2084 * @throws LockedException if calibrator is currently running.
2085 */
2086 public void setInitialBias(
2087 final AngularSpeed initialBiasX, final AngularSpeed initialBiasY, final AngularSpeed initialBiasZ)
2088 throws LockedException {
2089 if (running) {
2090 throw new LockedException();
2091 }
2092 this.initialBiasX = convertAngularSpeed(initialBiasX);
2093 this.initialBiasY = convertAngularSpeed(initialBiasY);
2094 this.initialBiasZ = convertAngularSpeed(initialBiasZ);
2095 }
2096
2097 /**
2098 * Gets initial x scaling factor of gyroscope.
2099 *
2100 * @return initial x scaling factor of gyroscope.
2101 */
2102 @Override
2103 public double getInitialSx() {
2104 return initialSx;
2105 }
2106
2107 /**
2108 * Sets initial x scaling factor of gyroscope.
2109 *
2110 * @param initialSx initial x scaling factor of gyroscope.
2111 * @throws LockedException if calibrator is currently running.
2112 */
2113 @Override
2114 public void setInitialSx(final double initialSx) throws LockedException {
2115 if (running) {
2116 throw new LockedException();
2117 }
2118 this.initialSx = initialSx;
2119 }
2120
2121 /**
2122 * Gets initial y scaling factor of gyroscope.
2123 *
2124 * @return initial y scaling factor of gyroscope.
2125 */
2126 @Override
2127 public double getInitialSy() {
2128 return initialSy;
2129 }
2130
2131 /**
2132 * Sets initial y scaling factor of gyroscope.
2133 *
2134 * @param initialSy initial y scaling factor of gyroscope.
2135 * @throws LockedException if calibrator is currently running.
2136 */
2137 @Override
2138 public void setInitialSy(final double initialSy) throws LockedException {
2139 if (running) {
2140 throw new LockedException();
2141 }
2142 this.initialSy = initialSy;
2143 }
2144
2145 /**
2146 * Gets initial z scaling factor of gyroscope.
2147 *
2148 * @return initial z scaling factor of gyroscope.
2149 */
2150 @Override
2151 public double getInitialSz() {
2152 return initialSz;
2153 }
2154
2155 /**
2156 * Sets initial z scaling factor of gyroscope.
2157 *
2158 * @param initialSz initial z scaling factor of gyroscope.
2159 * @throws LockedException if calibrator is currently running.
2160 */
2161 @Override
2162 public void setInitialSz(final double initialSz) throws LockedException {
2163 if (running) {
2164 throw new LockedException();
2165 }
2166 this.initialSz = initialSz;
2167 }
2168
2169 /**
2170 * Gets initial x-y cross coupling error of gyroscope.
2171 *
2172 * @return initial x-y cross coupling error of gyroscope.
2173 */
2174 @Override
2175 public double getInitialMxy() {
2176 return initialMxy;
2177 }
2178
2179 /**
2180 * Sets initial x-y cross coupling error of gyroscope.
2181 *
2182 * @param initialMxy initial x-y cross coupling error of gyroscope.
2183 * @throws LockedException if calibrator is currently running.
2184 */
2185 @Override
2186 public void setInitialMxy(final double initialMxy) throws LockedException {
2187 if (running) {
2188 throw new LockedException();
2189 }
2190 this.initialMxy = initialMxy;
2191 }
2192
2193 /**
2194 * Gets initial x-z cross coupling error of gyroscope.
2195 *
2196 * @return initial x-z cross coupling error of gyroscope.
2197 */
2198 @Override
2199 public double getInitialMxz() {
2200 return initialMxz;
2201 }
2202
2203 /**
2204 * Sets initial x-z cross coupling error of gyroscope.
2205 *
2206 * @param initialMxz initial x-z cross coupling error of gyroscope.
2207 * @throws LockedException if calibrator is currently running.
2208 */
2209 @Override
2210 public void setInitialMxz(final double initialMxz) throws LockedException {
2211 if (running) {
2212 throw new LockedException();
2213 }
2214 this.initialMxz = initialMxz;
2215 }
2216
2217 /**
2218 * Gets initial y-x cross coupling error of gyroscope.
2219 *
2220 * @return initial y-x cross coupling error of gyroscope.
2221 */
2222 @Override
2223 public double getInitialMyx() {
2224 return initialMyx;
2225 }
2226
2227 /**
2228 * Sets initial y-x cross coupling error of gyroscope.
2229 *
2230 * @param initialMyx initial y-x cross coupling error of gyroscope.
2231 * @throws LockedException if calibrator is currently running.
2232 */
2233 @Override
2234 public void setInitialMyx(final double initialMyx) throws LockedException {
2235 if (running) {
2236 throw new LockedException();
2237 }
2238 this.initialMyx = initialMyx;
2239 }
2240
2241 /**
2242 * Gets initial y-z cross coupling error of gyroscope.
2243 *
2244 * @return initial y-z cross coupling error of gyroscope.
2245 */
2246 @Override
2247 public double getInitialMyz() {
2248 return initialMyz;
2249 }
2250
2251 /**
2252 * Sets initial y-z cross coupling error of gyroscope.
2253 *
2254 * @param initialMyz initial y-z cross coupling error of gyroscope.
2255 * @throws LockedException if calibrator is currently running.
2256 */
2257 @Override
2258 public void setInitialMyz(final double initialMyz) throws LockedException {
2259 if (running) {
2260 throw new LockedException();
2261 }
2262 this.initialMyz = initialMyz;
2263 }
2264
2265 /**
2266 * Gets initial z-x cross coupling error of gyroscope.
2267 *
2268 * @return initial z-x cross coupling error of gyroscope.
2269 */
2270 @Override
2271 public double getInitialMzx() {
2272 return initialMzx;
2273 }
2274
2275 /**
2276 * Sets initial z-x cross coupling error of gyroscope.
2277 *
2278 * @param initialMzx initial z-x cross coupling error of gyroscope.
2279 * @throws LockedException if calibrator is currently running.
2280 */
2281 @Override
2282 public void setInitialMzx(final double initialMzx) throws LockedException {
2283 if (running) {
2284 throw new LockedException();
2285 }
2286 this.initialMzx = initialMzx;
2287 }
2288
2289 /**
2290 * Gets initial z-y cross coupling error of gyroscope.
2291 *
2292 * @return initial z-y cross coupling error of gyroscope.
2293 */
2294 @Override
2295 public double getInitialMzy() {
2296 return initialMzy;
2297 }
2298
2299 /**
2300 * Sets initial z-y cross coupling error of gyroscope.
2301 *
2302 * @param initialMzy initial z-y cross coupling error of gyroscope.
2303 * @throws LockedException if calibrator is currently running.
2304 */
2305 @Override
2306 public void setInitialMzy(final double initialMzy) throws LockedException {
2307 if (running) {
2308 throw new LockedException();
2309 }
2310 this.initialMzy = initialMzy;
2311 }
2312
2313 /**
2314 * Sets initial scaling factors of gyroscope.
2315 *
2316 * @param initialSx initial x scaling factor of gyroscope.
2317 * @param initialSy initial y scaling factor of gyroscope.
2318 * @param initialSz initial z scaling factor of gyroscope.
2319 * @throws LockedException if calibrator is currently running.
2320 */
2321 @Override
2322 public void setInitialScalingFactors(
2323 final double initialSx, final double initialSy, final double initialSz) throws LockedException {
2324 if (running) {
2325 throw new LockedException();
2326 }
2327 this.initialSx = initialSx;
2328 this.initialSy = initialSy;
2329 this.initialSz = initialSz;
2330 }
2331
2332 /**
2333 * Sets initial cross coupling errors of gyroscope.
2334 *
2335 * @param initialMxy initial x-y cross coupling error of gyroscope.
2336 * @param initialMxz initial x-z cross coupling error of gyroscope.
2337 * @param initialMyx initial y-x cross coupling error of gyroscope.
2338 * @param initialMyz initial y-z cross coupling error of gyroscope.
2339 * @param initialMzx initial z-x cross coupling error of gyroscope.
2340 * @param initialMzy initial z-y cross coupling error of gyroscope.
2341 * @throws LockedException if calibrator is currently running.
2342 */
2343 @Override
2344 public void setInitialCrossCouplingErrors(
2345 final double initialMxy, final double initialMxz, final double initialMyx,
2346 final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
2347 if (running) {
2348 throw new LockedException();
2349 }
2350 this.initialMxy = initialMxy;
2351 this.initialMxz = initialMxz;
2352 this.initialMyx = initialMyx;
2353 this.initialMyz = initialMyz;
2354 this.initialMzx = initialMzx;
2355 this.initialMzy = initialMzy;
2356 }
2357
2358 /**
2359 * Sets initial scaling factors and cross coupling errors of
2360 * gyroscope.
2361 *
2362 * @param initialSx initial x scaling factor of gyroscope.
2363 * @param initialSy initial y scaling factor of gyroscope.
2364 * @param initialSz initial z scaling factor of gyroscope.
2365 * @param initialMxy initial x-y cross coupling error of gyroscope.
2366 * @param initialMxz initial x-z cross coupling error of gyroscope.
2367 * @param initialMyx initial y-x cross coupling error of gyroscope.
2368 * @param initialMyz initial y-z cross coupling error of gyroscope.
2369 * @param initialMzx initial z-x cross coupling error of gyroscope.
2370 * @param initialMzy initial z-y cross coupling error of gyroscope.
2371 * @throws LockedException if calibrator is currently running.
2372 */
2373 @Override
2374 public void setInitialScalingFactorsAndCrossCouplingErrors(
2375 final double initialSx, final double initialSy, final double initialSz,
2376 final double initialMxy, final double initialMxz, final double initialMyx,
2377 final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
2378 if (running) {
2379 throw new LockedException();
2380 }
2381 setInitialScalingFactors(initialSx, initialSy, initialSz);
2382 setInitialCrossCouplingErrors(initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
2383 }
2384
2385 /**
2386 * Gets initial gyroscope bias to be used to find a solution as
2387 * an array.
2388 * Array values are expressed in radians per second (rad/s).
2389 *
2390 * @return array containing coordinates of initial gyroscope bias.
2391 */
2392 public double[] getInitialBias() {
2393 final double[] result = new double[BodyKinematics.COMPONENTS];
2394 getInitialBias(result);
2395 return result;
2396 }
2397
2398 /**
2399 * Gets initial gyroscope bias to be used to find a solution as
2400 * an array.
2401 * Array values are expressed in radians per second (rad/s).
2402 *
2403 * @param result instance where result data will be copied to.
2404 * @throws IllegalArgumentException if provided array does not have length 3.
2405 */
2406 public void getInitialBias(final double[] result) {
2407 if (result.length != BodyKinematics.COMPONENTS) {
2408 throw new IllegalArgumentException();
2409 }
2410 result[0] = initialBiasX;
2411 result[1] = initialBiasY;
2412 result[2] = initialBiasZ;
2413 }
2414
2415 /**
2416 * Sets initial gyroscope bias to be used to find a solution as
2417 * an array.
2418 * Array values are expressed in radians per second (rad/s).
2419 *
2420 * @param initialBias initial bias to find a solution.
2421 * @throws LockedException if calibrator is currently running.
2422 * @throws IllegalArgumentException if provided array does not have length 3.
2423 */
2424 public void setInitialBias(final double[] initialBias) throws LockedException {
2425 if (running) {
2426 throw new LockedException();
2427 }
2428
2429 if (initialBias.length != BodyKinematics.COMPONENTS) {
2430 throw new IllegalArgumentException();
2431 }
2432 initialBiasX = initialBias[0];
2433 initialBiasY = initialBias[1];
2434 initialBiasZ = initialBias[2];
2435 }
2436
2437 /**
2438 * Gets initial gyroscope bias to be used to find a solution as a
2439 * column matrix.
2440 * Values are expressed in radians per second (rad/s).
2441 *
2442 * @return initial gyroscope bias to be used to find a solution as a
2443 * column matrix.
2444 */
2445 public Matrix getInitialBiasAsMatrix() {
2446 Matrix result;
2447 try {
2448 result = new Matrix(BodyKinematics.COMPONENTS, 1);
2449 getInitialBiasAsMatrix(result);
2450 } catch (final WrongSizeException ignore) {
2451 // never happens
2452 result = null;
2453 }
2454 return result;
2455 }
2456
2457 /**
2458 * Gets initial gyroscope bias to be used to find a solution as a
2459 * column matrix.
2460 * Values are expressed in radians per second (rad/s).
2461 *
2462 * @param result instance where result data will be copied to.
2463 * @throws IllegalArgumentException if provided matrix is not 3x1.
2464 */
2465 public void getInitialBiasAsMatrix(final Matrix result) {
2466 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
2467 throw new IllegalArgumentException();
2468 }
2469 result.setElementAtIndex(0, initialBiasX);
2470 result.setElementAtIndex(1, initialBiasY);
2471 result.setElementAtIndex(2, initialBiasZ);
2472 }
2473
2474 /**
2475 * Sets initial gyroscope bias to be used to find a solution as
2476 * a column matrix with values expressed in radians per second (rad/s).
2477 *
2478 * @param initialBias initial gyroscope bias to find a solution.
2479 * @throws LockedException if calibrator is currently running.
2480 * @throws IllegalArgumentException if provided matrix is not 3x1.
2481 */
2482 public void setInitialBias(final Matrix initialBias) throws LockedException {
2483 if (running) {
2484 throw new LockedException();
2485 }
2486 if (initialBias.getRows() != BodyKinematics.COMPONENTS || initialBias.getColumns() != 1) {
2487 throw new IllegalArgumentException();
2488 }
2489
2490 initialBiasX = initialBias.getElementAtIndex(0);
2491 initialBiasY = initialBias.getElementAtIndex(1);
2492 initialBiasZ = initialBias.getElementAtIndex(2);
2493 }
2494
2495 /**
2496 * Gets initial bias coordinates of gyroscope used to find a solution.
2497 *
2498 * @return initial bias coordinates.
2499 */
2500 public AngularSpeedTriad getInitialBiasAsTriad() {
2501 return new AngularSpeedTriad(AngularSpeedUnit.RADIANS_PER_SECOND, initialBiasX, initialBiasY, initialBiasZ);
2502 }
2503
2504 /**
2505 * Gets initial bias coordinates of gyroscope used to find a solution.
2506 *
2507 * @param result instance where result will be stored.
2508 */
2509 public void getInitialBiasAsTriad(AngularSpeedTriad result) {
2510 result.setValueCoordinatesAndUnit(initialBiasX, initialBiasY, initialBiasZ,
2511 AngularSpeedUnit.RADIANS_PER_SECOND);
2512 }
2513
2514 /**
2515 * Sets initial bias coordinates of gyroscope used to find a solution.
2516 *
2517 * @param initialBias initial bias coordinates to be set.
2518 * @throws LockedException if calibrator is currently running.
2519 */
2520 public void setInitialBias(AngularSpeedTriad initialBias) throws LockedException {
2521 if (running) {
2522 throw new LockedException();
2523 }
2524
2525 initialBiasX = convertAngularSpeed(initialBias.getValueX(), initialBias.getUnit());
2526 initialBiasY = convertAngularSpeed(initialBias.getValueY(), initialBias.getUnit());
2527 initialBiasZ = convertAngularSpeed(initialBias.getValueZ(), initialBias.getUnit());
2528 }
2529
2530 /**
2531 * Gets initial gyroscope scale factors and cross coupling errors
2532 * matrix.
2533 *
2534 * @return initial gyroscope scale factors and cross coupling errors
2535 * matrix.
2536 */
2537 @Override
2538 public Matrix getInitialMg() {
2539 Matrix result;
2540 try {
2541 result = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
2542 getInitialMg(result);
2543 } catch (final WrongSizeException ignore) {
2544 // never happens
2545 result = null;
2546 }
2547 return result;
2548 }
2549
2550 /**
2551 * Gets initial gyroscope scale factors and cross coupling errors
2552 * matrix.
2553 *
2554 * @param result instance where data will be stored.
2555 * @throws IllegalArgumentException if provided matrix is not 3x3.
2556 */
2557 @Override
2558 public void getInitialMg(final Matrix result) {
2559 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
2560 throw new IllegalArgumentException();
2561 }
2562 result.setElementAtIndex(0, initialSx);
2563 result.setElementAtIndex(1, initialMyx);
2564 result.setElementAtIndex(2, initialMzx);
2565
2566 result.setElementAtIndex(3, initialMxy);
2567 result.setElementAtIndex(4, initialSy);
2568 result.setElementAtIndex(5, initialMzy);
2569
2570 result.setElementAtIndex(6, initialMxz);
2571 result.setElementAtIndex(7, initialMyz);
2572 result.setElementAtIndex(8, initialSz);
2573 }
2574
2575 /**
2576 * Sets initial gyroscope scale factors and cross coupling errors matrix.
2577 *
2578 * @param initialMg initial scale factors and cross coupling errors matrix.
2579 * @throws IllegalArgumentException if provided matrix is not 3x3.
2580 * @throws LockedException if calibrator is currently running.
2581 */
2582 @Override
2583 public void setInitialMg(final Matrix initialMg) throws LockedException {
2584 if (running) {
2585 throw new LockedException();
2586 }
2587 if (initialMg.getRows() != BodyKinematics.COMPONENTS || initialMg.getColumns() != BodyKinematics.COMPONENTS) {
2588 throw new IllegalArgumentException();
2589 }
2590
2591 initialSx = initialMg.getElementAtIndex(0);
2592 initialMyx = initialMg.getElementAtIndex(1);
2593 initialMzx = initialMg.getElementAtIndex(2);
2594
2595 initialMxy = initialMg.getElementAtIndex(3);
2596 initialSy = initialMg.getElementAtIndex(4);
2597 initialMzy = initialMg.getElementAtIndex(5);
2598
2599 initialMxz = initialMg.getElementAtIndex(6);
2600 initialMyz = initialMg.getElementAtIndex(7);
2601 initialSz = initialMg.getElementAtIndex(8);
2602 }
2603
2604 /**
2605 * Gets initial G-dependent cross biases introduced on the gyroscope by the
2606 * specific forces sensed by the accelerometer.
2607 *
2608 * @return a 3x3 matrix containing initial g-dependent cross biases.
2609 */
2610 @Override
2611 public Matrix getInitialGg() {
2612 return new Matrix(initialGg);
2613 }
2614
2615 /**
2616 * Gets initial G-dependent cross biases introduced on the gyroscope by the
2617 * specific forces sensed by the accelerometer.
2618 *
2619 * @param result instance where data will be stored.
2620 * @throws IllegalArgumentException if provided matrix is not 3x3.
2621 */
2622 @Override
2623 public void getInitialGg(final Matrix result) {
2624
2625 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
2626 throw new IllegalArgumentException();
2627 }
2628
2629 result.copyFrom(initialGg);
2630 }
2631
2632 /**
2633 * Sets initial G-dependent cross biases introduced on the gyroscope by the
2634 * specific forces sensed by the accelerometer.
2635 *
2636 * @param initialGg g-dependent cross biases.
2637 * @throws LockedException if calibrator is currently running.
2638 * @throws IllegalArgumentException if provided matrix is not 3x3.
2639 */
2640 @Override
2641 public void setInitialGg(final Matrix initialGg) throws LockedException {
2642 if (running) {
2643 throw new LockedException();
2644 }
2645
2646 if (initialGg.getRows() != BodyKinematics.COMPONENTS || initialGg.getColumns() != BodyKinematics.COMPONENTS) {
2647 throw new IllegalArgumentException();
2648 }
2649
2650 initialGg.copyTo(this.initialGg);
2651 }
2652
2653 /**
2654 * Gets collection of sequences of timestamped body kinematics
2655 * measurements taken at a given position where the device moves freely
2656 * with different orientations.
2657 *
2658 * @return collection of sequences of timestamped body kinematics
2659 * measurements.
2660 */
2661 @Override
2662 public List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> getSequences() {
2663 return sequences;
2664 }
2665
2666 /**
2667 * Sets collection of sequences of timestamped body kinematics
2668 * measurements taken at a given position where the device moves freely
2669 * with different orientations.
2670 *
2671 * @param sequences collection of sequences of timestamped body
2672 * kinematics measurements.
2673 * @throws LockedException if calibrator is currently running.
2674 */
2675 @Override
2676 public void setSequences(
2677 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences) throws LockedException {
2678 if (running) {
2679 throw new LockedException();
2680 }
2681 this.sequences = sequences;
2682 }
2683
2684 /**
2685 * Indicates the type of measurement or sequence used by this calibrator.
2686 *
2687 * @return type of measurement or sequence used by this calibrator.
2688 */
2689 @Override
2690 public GyroscopeCalibratorMeasurementOrSequenceType getMeasurementOrSequenceType() {
2691 return GyroscopeCalibratorMeasurementOrSequenceType.BODY_KINEMATICS_SEQUENCE;
2692 }
2693
2694 /**
2695 * Indicates whether this calibrator requires ordered measurements or sequences
2696 * in a list or not.
2697 *
2698 * @return true if measurements or sequences must be ordered, false otherwise.
2699 */
2700 @Override
2701 public boolean isOrderedMeasurementsOrSequencesRequired() {
2702 return true;
2703 }
2704
2705 /**
2706 * Indicates whether z-axis is assumed to be common for accelerometer and
2707 * gyroscope.
2708 * When enabled, this eliminates 3 variables from Ma matrix.
2709 *
2710 * @return true if z-axis is assumed to be common for accelerometer and gyroscope,
2711 * false otherwise.
2712 */
2713 @Override
2714 public boolean isCommonAxisUsed() {
2715 return commonAxisUsed;
2716 }
2717
2718 /**
2719 * Specifies whether z-axis is assumed to be common for accelerometer and
2720 * gyroscope.
2721 * When enabled, this eliminates 3 variables from Ma matrix.
2722 *
2723 * @param commonAxisUsed true if z-axis is assumed to be common for accelerometer
2724 * and gyroscope, false otherwise.
2725 * @throws LockedException if calibrator is currently running.
2726 */
2727 @Override
2728 public void setCommonAxisUsed(final boolean commonAxisUsed) throws LockedException {
2729 if (running) {
2730 throw new LockedException();
2731 }
2732
2733 this.commonAxisUsed = commonAxisUsed;
2734 }
2735
2736 /**
2737 * Indicates whether G-dependent cross biases are being estimated
2738 * or not.
2739 * When enabled, this adds 9 variables from Gg matrix.
2740 *
2741 * @return true if G-dependent cross biases will be estimated,
2742 * false otherwise.
2743 */
2744 public boolean isGDependentCrossBiasesEstimated() {
2745 return estimateGDependentCrossBiases;
2746 }
2747
2748 /**
2749 * Specifies whether G-dependent cross biases are being estimated
2750 * or not.
2751 * When enabled, this adds 9 variables from Gg matrix.
2752 *
2753 * @param estimateGDependentCrossBiases true if G-dependent cross
2754 * biases will be estimated,
2755 * false otherwise.
2756 * @throws LockedException if calibrator is currently running.
2757 */
2758 public void setGDependentCrossBiasesEstimated(final boolean estimateGDependentCrossBiases) throws LockedException {
2759 if (running) {
2760 throw new LockedException();
2761 }
2762
2763 this.estimateGDependentCrossBiases = estimateGDependentCrossBiases;
2764 }
2765
2766 /**
2767 * Gets listener to handle events raised by this estimator.
2768 *
2769 * @return listener to handle events raised by this estimator.
2770 */
2771 public RobustEasyGyroscopeCalibratorListener getListener() {
2772 return listener;
2773 }
2774
2775 /**
2776 * Sets listener to handle events raised by this estimator.
2777 *
2778 * @param listener listener to handle events raised by this estimator.
2779 * @throws LockedException if calibrator is currently running.
2780 */
2781 public void setListener(final RobustEasyGyroscopeCalibratorListener listener) throws LockedException {
2782 if (running) {
2783 throw new LockedException();
2784 }
2785
2786 this.listener = listener;
2787 }
2788
2789 /**
2790 * Gets minimum number of required sequences.
2791 *
2792 * @return minimum number of required sequences.
2793 */
2794 @Override
2795 public int getMinimumRequiredMeasurementsOrSequences() {
2796 if (commonAxisUsed) {
2797 if (estimateGDependentCrossBiases) {
2798 return EasyGyroscopeCalibrator.MINIMUM_SEQUENCES_COMMON_Z_AXIS_AND_CROSS_BIASES;
2799 } else {
2800 return EasyGyroscopeCalibrator.MINIMUM_SEQUENCES_COMMON_Z_AXIS;
2801 }
2802 } else {
2803 if (estimateGDependentCrossBiases) {
2804 return EasyGyroscopeCalibrator.MINIMUM_SEQUENCES_GENERAL_AND_CROSS_BIASES;
2805 } else {
2806 return EasyGyroscopeCalibrator.MINIMUM_SEQUENCES_GENERAL;
2807 }
2808 }
2809 }
2810
2811 /**
2812 * Indicates whether calibrator is ready to start.
2813 *
2814 * @return true if calibrator is ready, false otherwise.
2815 */
2816 @Override
2817 public boolean isReady() {
2818 return sequences != null && sequences.size() >= getMinimumRequiredMeasurementsOrSequences();
2819 }
2820
2821 /**
2822 * Indicates whether calibrator is currently running or not.
2823 *
2824 * @return true if calibrator is running, false otherwise.
2825 */
2826 @Override
2827 public boolean isRunning() {
2828 return running;
2829 }
2830
2831 /**
2832 * Returns amount of progress variation before notifying a progress change during
2833 * calibration.
2834 *
2835 * @return amount of progress variation before notifying a progress change during
2836 * calibration.
2837 */
2838 public float getProgressDelta() {
2839 return progressDelta;
2840 }
2841
2842 /**
2843 * Sets amount of progress variation before notifying a progress change during
2844 * calibration.
2845 *
2846 * @param progressDelta amount of progress variation before notifying a progress
2847 * change during calibration.
2848 * @throws IllegalArgumentException if progress delta is less than zero or greater than 1.
2849 * @throws LockedException if calibrator is currently running.
2850 */
2851 public void setProgressDelta(final float progressDelta) throws LockedException {
2852 if (running) {
2853 throw new LockedException();
2854 }
2855 if (progressDelta < MIN_PROGRESS_DELTA || progressDelta > MAX_PROGRESS_DELTA) {
2856 throw new IllegalArgumentException();
2857 }
2858 this.progressDelta = progressDelta;
2859 }
2860
2861 /**
2862 * Returns amount of confidence expressed as a value between 0.0 and 1.0
2863 * (which is equivalent to 100%). The amount of confidence indicates the probability
2864 * that the estimated result is correct. Usually this value will be close to 1.0, but
2865 * not exactly 1.0.
2866 *
2867 * @return amount of confidence as a value between 0.0 and 1.0.
2868 */
2869 public double getConfidence() {
2870 return confidence;
2871 }
2872
2873 /**
2874 * Sets amount of confidence expressed as a value between 0.0 and 1.0 (which is
2875 * equivalent to 100%). The amount of confidence indicates the probability that
2876 * the estimated result is correct. Usually this value will be close to 1.0, but
2877 * not exactly 1.0.
2878 *
2879 * @param confidence confidence to be set as a value between 0.0 and 1.0.
2880 * @throws IllegalArgumentException if provided value is not between 0.0 and 1.0.
2881 * @throws LockedException if calibrator is currently running.
2882 */
2883 public void setConfidence(final double confidence) throws LockedException {
2884 if (running) {
2885 throw new LockedException();
2886 }
2887 if (confidence < MIN_CONFIDENCE || confidence > MAX_CONFIDENCE) {
2888 throw new IllegalArgumentException();
2889 }
2890 this.confidence = confidence;
2891 }
2892
2893 /**
2894 * Returns maximum allowed number of iterations. If maximum allowed number of
2895 * iterations is achieved without converging to a result when calling calibrate(),
2896 * a RobustEstimatorException will be raised.
2897 *
2898 * @return maximum allowed number of iterations.
2899 */
2900 public int getMaxIterations() {
2901 return maxIterations;
2902 }
2903
2904 /**
2905 * Sets maximum allowed number of iterations. When the maximum number of iterations
2906 * is exceeded, result will not be available, however an approximate result will be
2907 * available for retrieval.
2908 *
2909 * @param maxIterations maximum allowed number of iterations to be set.
2910 * @throws IllegalArgumentException if provided value is less than 1.
2911 * @throws LockedException if calibrator is currently running.
2912 */
2913 public void setMaxIterations(final int maxIterations) throws LockedException {
2914 if (running) {
2915 throw new LockedException();
2916 }
2917 if (maxIterations < MIN_ITERATIONS) {
2918 throw new IllegalArgumentException();
2919 }
2920 this.maxIterations = maxIterations;
2921 }
2922
2923 /**
2924 * Gets data related to inliers found after estimation.
2925 *
2926 * @return data related to inliers found after estimation.
2927 */
2928 public InliersData getInliersData() {
2929 return inliersData;
2930 }
2931
2932 /**
2933 * Indicates whether result must be refined using a non-linear solver over found inliers.
2934 *
2935 * @return true to refine result, false to simply use result found by robust estimator
2936 * without further refining.
2937 */
2938 public boolean isResultRefined() {
2939 return refineResult;
2940 }
2941
2942 /**
2943 * Specifies whether result must be refined using a non-linear solver over found inliers.
2944 *
2945 * @param refineResult true to refine result, false to simply use result found by robust
2946 * estimator without further refining.
2947 * @throws LockedException if calibrator is currently running.
2948 */
2949 public void setResultRefined(final boolean refineResult) throws LockedException {
2950 if (running) {
2951 throw new LockedException();
2952 }
2953 this.refineResult = refineResult;
2954 }
2955
2956 /**
2957 * Indicates whether covariance must be kept after refining result.
2958 * This setting is only taken into account if result is refined.
2959 *
2960 * @return true if covariance must be kept after refining result, false otherwise.
2961 */
2962 public boolean isCovarianceKept() {
2963 return keepCovariance;
2964 }
2965
2966 /**
2967 * Specifies whether covariance must be kept after refining result.
2968 * This setting is only taken into account if result is refined.
2969 *
2970 * @param keepCovariance true if covariance must be kept after refining result,
2971 * false otherwise.
2972 * @throws LockedException if calibrator is currently running.
2973 */
2974 public void setCovarianceKept(final boolean keepCovariance) throws LockedException {
2975 if (running) {
2976 throw new LockedException();
2977 }
2978 this.keepCovariance = keepCovariance;
2979 }
2980
2981 /**
2982 * Returns quality scores corresponding to each sequence.
2983 * The larger the score value the better the quality of the sample.
2984 * This implementation always returns null.
2985 * Subclasses using quality scores must implement proper behavior.
2986 *
2987 * @return quality scores corresponding to each sample.
2988 */
2989 @Override
2990 public double[] getQualityScores() {
2991 return null;
2992 }
2993
2994 /**
2995 * Sets quality scores corresponding to each sequence.
2996 * The larger the score value the better the quality of the sample.
2997 * This implementation makes no action.
2998 * Subclasses using quality scores must implement proper behaviour.
2999 *
3000 * @param qualityScores quality scores corresponding to each sample.
3001 * @throws IllegalArgumentException if provided quality scores length
3002 * is smaller than minimum required samples.
3003 * @throws LockedException if calibrator is currently running.
3004 */
3005 @Override
3006 public void setQualityScores(final double[] qualityScores) throws LockedException {
3007 }
3008
3009 /**
3010 * Gets array containing x,y,z components of estimated gyroscope biases
3011 * expressed in radians per second (rad/s).
3012 *
3013 * @return array containing x,y,z components of estimated gyroscope biases.
3014 */
3015 @Override
3016 public double[] getEstimatedBiases() {
3017 return estimatedBiases;
3018 }
3019
3020 /**
3021 * Gets array containing x,y,z components of estimated gyroscope biases
3022 * expressed in radians per second (rad/s).
3023 *
3024 * @param result instance where estimated gyroscope biases will be stored.
3025 * @return true if result instance was updated, false otherwise (when estimation
3026 * is not yet available).
3027 */
3028 @Override
3029 public boolean getEstimatedBiases(final double[] result) {
3030 if (estimatedBiases != null) {
3031 System.arraycopy(estimatedBiases, 0, result, 0, estimatedBiases.length);
3032 return true;
3033 } else {
3034 return false;
3035 }
3036 }
3037
3038 /**
3039 * Gets column matrix containing x,y,z components of estimated gyroscope biases
3040 * expressed in radians per second (rad/s).
3041 *
3042 * @return column matrix containing x,y,z components of estimated gyroscope
3043 * biases.
3044 */
3045 @Override
3046 public Matrix getEstimatedBiasesAsMatrix() {
3047 return estimatedBiases != null ? Matrix.newFromArray(estimatedBiases) : null;
3048 }
3049
3050 /**
3051 * Gets column matrix containing x,y,z components of estimated gyroscope biases
3052 * expressed in radians per second (rad/s).
3053 *
3054 * @param result instance where result data will be stored.
3055 * @return true if result was updated, false otherwise.
3056 * @throws WrongSizeException if provided result instance has invalid size.
3057 */
3058 @Override
3059 public boolean getEstimatedBiasesAsMatrix(final Matrix result) throws WrongSizeException {
3060 if (estimatedBiases != null) {
3061 result.fromArray(estimatedBiases);
3062 return true;
3063 } else {
3064 return false;
3065 }
3066 }
3067
3068 /**
3069 * Gets x coordinate of estimated gyroscope bias expressed in radians per
3070 * second (rad/s).
3071 *
3072 * @return x coordinate of estimated gyroscope bias or null if not available.
3073 */
3074 @Override
3075 public Double getEstimatedBiasX() {
3076 return estimatedBiases != null ? estimatedBiases[0] : null;
3077 }
3078
3079 /**
3080 * Gets y coordinate of estimated gyroscope bias expressed in radians per
3081 * second (rad/s).
3082 *
3083 * @return y coordinate of estimated gyroscope bias or null if not available.
3084 */
3085 @Override
3086 public Double getEstimatedBiasY() {
3087 return estimatedBiases != null ? estimatedBiases[1] : null;
3088 }
3089
3090 /**
3091 * Gets z coordinate of estimated gyroscope bias expressed in radians per
3092 * second (rad/s).
3093 *
3094 * @return z coordinate of estimated gyroscope bias or null if not available.
3095 */
3096 @Override
3097 public Double getEstimatedBiasZ() {
3098 return estimatedBiases != null ? estimatedBiases[2] : null;
3099 }
3100
3101 /**
3102 * Gets x coordinate of estimated gyroscope bias.
3103 *
3104 * @return x coordinate of estimated gyroscope bias or null if not available.
3105 */
3106 @Override
3107 public AngularSpeed getEstimatedBiasAngularSpeedX() {
3108 return estimatedBiases != null
3109 ? new AngularSpeed(estimatedBiases[0], AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3110 }
3111
3112 /**
3113 * Gets x coordinate of estimated gyroscope bias.
3114 *
3115 * @param result instance where result will be stored.
3116 * @return true if result was updated, false if estimation is not available.
3117 */
3118 @Override
3119 public boolean getEstimatedBiasAngularSpeedX(final AngularSpeed result) {
3120 if (estimatedBiases != null) {
3121 result.setValue(estimatedBiases[0]);
3122 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3123 return true;
3124 } else {
3125 return false;
3126 }
3127 }
3128
3129 /**
3130 * Gets y coordinate of estimated gyroscope bias.
3131 *
3132 * @return y coordinate of estimated gyroscope bias or null if not available.
3133 */
3134 @Override
3135 public AngularSpeed getEstimatedBiasAngularSpeedY() {
3136 return estimatedBiases != null
3137 ? new AngularSpeed(estimatedBiases[1], AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3138 }
3139
3140 /**
3141 * Gets y coordinate of estimated gyroscope bias.
3142 *
3143 * @param result instance where result will be stored.
3144 * @return true if result was updated, false if estimation is not available.
3145 */
3146 @Override
3147 public boolean getEstimatedBiasAngularSpeedY(final AngularSpeed result) {
3148 if (estimatedBiases != null) {
3149 result.setValue(estimatedBiases[1]);
3150 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3151 return true;
3152 } else {
3153 return false;
3154 }
3155 }
3156
3157 /**
3158 * Gets z coordinate of estimated gyroscope bias.
3159 *
3160 * @return z coordinate of estimated gyroscope bias or null if not available.
3161 */
3162 @Override
3163 public AngularSpeed getEstimatedBiasAngularSpeedZ() {
3164 return estimatedBiases != null
3165 ? new AngularSpeed(estimatedBiases[2], AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3166 }
3167
3168 /**
3169 * Gets z coordinate of estimated gyroscope bias.
3170 *
3171 * @param result instance where result will be stored.
3172 * @return true if result was updated, false if estimation is not available.
3173 */
3174 @Override
3175 public boolean getEstimatedBiasAngularSpeedZ(final AngularSpeed result) {
3176 if (estimatedBiases != null) {
3177 result.setValue(estimatedBiases[2]);
3178 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3179 return true;
3180 } else {
3181 return false;
3182 }
3183 }
3184
3185 /**
3186 * Gets estimated gyroscope bias.
3187 *
3188 * @return estimated gyroscope bias or null if not available.
3189 */
3190 @Override
3191 public AngularSpeedTriad getEstimatedBiasAsTriad() {
3192 return estimatedBiases != null
3193 ? new AngularSpeedTriad(AngularSpeedUnit.RADIANS_PER_SECOND,
3194 estimatedBiases[0], estimatedBiases[1], estimatedBiases[2])
3195 : null;
3196 }
3197
3198 /**
3199 * Gets estimated gyroscope bias.
3200 *
3201 * @param result instance where result will be stored.
3202 * @return true if estimated gyroscope bias is available and result was
3203 * modified, false otherwise.
3204 */
3205 @Override
3206 public boolean getEstimatedBiasAsTriad(final AngularSpeedTriad result) {
3207 if (estimatedBiases != null) {
3208 result.setValueCoordinatesAndUnit(
3209 estimatedBiases[0], estimatedBiases[1], estimatedBiases[2], AngularSpeedUnit.RADIANS_PER_SECOND);
3210 return true;
3211 } else {
3212 return false;
3213 }
3214 }
3215
3216 /**
3217 * Gets estimated gyroscope scale factors and cross coupling errors.
3218 * This is the product of matrix Tg containing cross coupling errors and Kg
3219 * containing scaling factors.
3220 * So that:
3221 * <pre>
3222 * Mg = [sx mxy mxz] = Tg*Kg
3223 * [myx sy myz]
3224 * [mzx mzy sz ]
3225 * </pre>
3226 * Where:
3227 * <pre>
3228 * Kg = [sx 0 0 ]
3229 * [0 sy 0 ]
3230 * [0 0 sz]
3231 * </pre>
3232 * and
3233 * <pre>
3234 * Tg = [1 -alphaXy alphaXz ]
3235 * [alphaYx 1 -alphaYz]
3236 * [-alphaZx alphaZy 1 ]
3237 * </pre>
3238 * Hence:
3239 * <pre>
3240 * Mg = [sx mxy mxz] = Tg*Kg = [sx -sy * alphaXy sz * alphaXz ]
3241 * [myx sy myz] [sx * alphaYx sy -sz * alphaYz]
3242 * [mzx mzy sz ] [-sx * alphaZx sy * alphaZy sz ]
3243 * </pre>
3244 * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
3245 * are considered to be zero if the gyroscope z-axis is assumed to be the same
3246 * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mg matrix
3247 * becomes upper diagonal:
3248 * <pre>
3249 * Mg = [sx mxy mxz]
3250 * [0 sy myz]
3251 * [0 0 sz ]
3252 * </pre>
3253 * Values of this matrix are unit-less.
3254 *
3255 * @return estimated gyroscope scale factors and cross coupling errors, or null
3256 * if not available.
3257 */
3258 @Override
3259 public Matrix getEstimatedMg() {
3260 return estimatedMg;
3261 }
3262
3263 /**
3264 * Gets estimated gyroscope x-axis scale factor.
3265 *
3266 * @return estimated gyroscope x-axis scale factor or null
3267 * if not available.
3268 */
3269 @Override
3270 public Double getEstimatedSx() {
3271 return estimatedMg != null ? estimatedMg.getElementAt(0, 0) : null;
3272 }
3273
3274 /**
3275 * Gets estimated gyroscope y-axis scale factor.
3276 *
3277 * @return estimated gyroscope y-axis scale factor or null
3278 * if not available.
3279 */
3280 @Override
3281 public Double getEstimatedSy() {
3282 return estimatedMg != null ? estimatedMg.getElementAt(1, 1) : null;
3283 }
3284
3285 /**
3286 * Gets estimated gyroscope z-axis scale factor.
3287 *
3288 * @return estimated gyroscope z-axis scale factor or null
3289 * if not available.
3290 */
3291 @Override
3292 public Double getEstimatedSz() {
3293 return estimatedMg != null ? estimatedMg.getElementAt(2, 2) : null;
3294 }
3295
3296 /**
3297 * Gets estimated gyroscope x-y cross-coupling error.
3298 *
3299 * @return estimated gyroscope x-y cross-coupling error or null
3300 * if not available.
3301 */
3302 @Override
3303 public Double getEstimatedMxy() {
3304 return estimatedMg != null ? estimatedMg.getElementAt(0, 1) : null;
3305 }
3306
3307 /**
3308 * Gets estimated gyroscope x-z cross-coupling error.
3309 *
3310 * @return estimated gyroscope x-z cross-coupling error or null
3311 * if not available.
3312 */
3313 @Override
3314 public Double getEstimatedMxz() {
3315 return estimatedMg != null ? estimatedMg.getElementAt(0, 2) : null;
3316 }
3317
3318 /**
3319 * Gets estimated gyroscope y-x cross-coupling error.
3320 *
3321 * @return estimated gyroscope y-x cross-coupling error or null
3322 * if not available.
3323 */
3324 @Override
3325 public Double getEstimatedMyx() {
3326 return estimatedMg != null ? estimatedMg.getElementAt(1, 0) : null;
3327 }
3328
3329 /**
3330 * Gets estimated gyroscope y-z cross-coupling error.
3331 *
3332 * @return estimated gyroscope y-z cross-coupling error or null
3333 * if not available.
3334 */
3335 @Override
3336 public Double getEstimatedMyz() {
3337 return estimatedMg != null ? estimatedMg.getElementAt(1, 2) : null;
3338 }
3339
3340 /**
3341 * Gets estimated gyroscope z-x cross-coupling error.
3342 *
3343 * @return estimated gyroscope z-x cross-coupling error or null
3344 * if not available.
3345 */
3346 @Override
3347 public Double getEstimatedMzx() {
3348 return estimatedMg != null ? estimatedMg.getElementAt(2, 0) : null;
3349 }
3350
3351 /**
3352 * Gets estimated gyroscope z-y cross-coupling error.
3353 *
3354 * @return estimated gyroscope z-y cross-coupling error or null
3355 * if not available.
3356 */
3357 @Override
3358 public Double getEstimatedMzy() {
3359 return estimatedMg != null ? estimatedMg.getElementAt(2, 1) : null;
3360 }
3361
3362 /**
3363 * Gets estimated G-dependent cross biases introduced on the gyroscope by the
3364 * specific forces sensed by the accelerometer.
3365 * This instance allows any 3x3 matrix.
3366 *
3367 * @return estimated G-dependent cross biases.
3368 */
3369 @Override
3370 public Matrix getEstimatedGg() {
3371 return estimatedGg;
3372 }
3373
3374 /**
3375 * Gets estimated covariance matrix for estimated parameters.
3376 * Diagonal elements of the matrix contains variance for the following
3377 * parameters (following indicated order): bgx, bgy, bgz, sx, sy, sz,
3378 * mxy, mxz, myx, myz, mzx, mzy, gg11, gg21, gg31, gg12, gg22, gg32,
3379 * gg13, gg23, gg33.
3380 *
3381 * @return estimated covariance matrix for estimated parameters.
3382 */
3383 @Override
3384 public Matrix getEstimatedCovariance() {
3385 return estimatedCovariance;
3386 }
3387
3388 /**
3389 * Gets estimated chi square value.
3390 *
3391 * @return estimated chi square value.
3392 */
3393 public double getEstimatedChiSq() {
3394 return estimatedChiSq;
3395 }
3396
3397 /**
3398 * Gets estimated chi square degrees of freedom. Degrees of freedom is equal to the number of sampled data minus the
3399 * number of estimated parameters.
3400 *
3401 * @return estimated degrees of freedom of chi square value
3402 */
3403 @Override
3404 public int getEstimatedChiSqDegreesOfFreedom() {
3405 return estimatedChiSqDegreesOfFreedom;
3406 }
3407
3408 /**
3409 * Gets estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
3410 * freedom. Ideally this value should be close to 1.0, indicating that fit is optimal.
3411 * A value larger than 1.0 indicates that fit is not good or noise has been underestimated, and a value smaller than
3412 * 1.0 indicates that there is overfitting or noise has been overestimated.
3413 *
3414 * @return estimated reduced chi square value
3415 */
3416 @Override
3417 public double getEstimatedReducedChiSq() {
3418 return estimatedReducedChiSq;
3419 }
3420
3421 /**
3422 * Gets estimated mean square error respect to provided measurements.
3423 *
3424 * @return estimated mean square error respect to provided measurements.
3425 */
3426 @Override
3427 public double getEstimatedMse() {
3428 return estimatedMse;
3429 }
3430
3431 /**
3432 * Gets estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The
3433 * smaller the found chi square value is, the better the fit of the estimated parameters to the actual parameter.
3434 * Thus, the smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
3435 *
3436 * @return estimated probability of finding a smaller chi square value.
3437 */
3438 @Override
3439 public double getEstimatedP() {
3440 return estimatedP;
3441 }
3442
3443 /**
3444 * Gets estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value
3445 * is, the better the fit that has been estimated.
3446 *
3447 * @return estimated measure of quality of estimated fit.
3448 */
3449 @Override
3450 public double getEstimatedQ() {
3451 return estimatedQ;
3452 }
3453
3454 /**
3455 * Gets variance of estimated x coordinate of gyroscope bias expressed in (rad^2/s^2).
3456 *
3457 * @return variance of estimated x coordinate of gyroscope bias or null if not available.
3458 */
3459 public Double getEstimatedBiasXVariance() {
3460 return estimatedCovariance != null ? estimatedCovariance.getElementAt(0, 0) : null;
3461 }
3462
3463 /**
3464 * Gets standard deviation of estimated x coordinate of gyroscope bias expressed in
3465 * radians per second (rad/s).
3466 *
3467 * @return standard deviation of estimated x coordinate of gyroscope bias or null if not
3468 * available.
3469 */
3470 public Double getEstimatedBiasXStandardDeviation() {
3471 final var variance = getEstimatedBiasXVariance();
3472 return variance != null ? Math.sqrt(variance) : null;
3473 }
3474
3475 /**
3476 * Gets standard deviation of estimated x coordinate of gyroscope bias.
3477 *
3478 * @return standard deviation of estimated x coordinate of gyroscope bias or null if not
3479 * available.
3480 */
3481 public AngularSpeed getEstimatedBiasXStandardDeviationAsAngularSpeed() {
3482 return estimatedCovariance != null
3483 ? new AngularSpeed(getEstimatedBiasXStandardDeviation(), AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3484 }
3485
3486 /**
3487 * Gets standard deviation of estimated x coordinate of gyroscope bias.
3488 *
3489 * @param result instance where result will be stored.
3490 * @return true if standard deviation of estimated x coordinate of gyroscope bias is available,
3491 * false otherwise.
3492 */
3493 public boolean getEstimatedBiasXStandardDeviationAsAngularSpeed(final AngularSpeed result) {
3494 if (estimatedCovariance != null) {
3495 result.setValue(getEstimatedBiasXStandardDeviation());
3496 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3497 return true;
3498 } else {
3499 return false;
3500 }
3501 }
3502
3503 /**
3504 * Gets variance of estimated y coordinate of gyroscope bias expressed in (rad^2/s^2).
3505 *
3506 * @return variance of estimated y coordinate of gyroscope bias or null if not available.
3507 */
3508 public Double getEstimatedBiasYVariance() {
3509 return estimatedCovariance != null ? estimatedCovariance.getElementAt(1, 1) : null;
3510 }
3511
3512 /**
3513 * Gets standard deviation of estimated y coordinate of gyroscope bias expressed in
3514 * radians per second (rad/s).
3515 *
3516 * @return standard deviation of estimated y coordinate of gyroscope bias or null if not
3517 * available.
3518 */
3519 public Double getEstimatedBiasYStandardDeviation() {
3520 final var variance = getEstimatedBiasYVariance();
3521 return variance != null ? Math.sqrt(variance) : null;
3522 }
3523
3524 /**
3525 * Gets standard deviation of estimated y coordinate of gyroscope bias.
3526 *
3527 * @return standard deviation of estimated y coordinate of gyroscope bias or null if not
3528 * available.
3529 */
3530 public AngularSpeed getEstimatedBiasYStandardDeviationAsAngularSpeed() {
3531 return estimatedCovariance != null
3532 ? new AngularSpeed(getEstimatedBiasYStandardDeviation(), AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3533 }
3534
3535 /**
3536 * Gets standard deviation of estimated y coordinate of gyroscope bias.
3537 *
3538 * @param result instance where result will be stored.
3539 * @return true if standard deviation of estimated y coordinate of gyroscope bias is available,
3540 * false otherwise.
3541 */
3542 public boolean getEstimatedBiasYStandardDeviationAsAngularSpeed(final AngularSpeed result) {
3543 if (estimatedCovariance != null) {
3544 result.setValue(getEstimatedBiasYStandardDeviation());
3545 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3546 return true;
3547 } else {
3548 return false;
3549 }
3550 }
3551
3552 /**
3553 * Gets variance of estimated z coordinate of gyroscope bias expressed in (rad^2/s^2).
3554 *
3555 * @return variance of estimated z coordinate of gyroscope bias or null if not available.
3556 */
3557 public Double getEstimatedBiasZVariance() {
3558 return estimatedCovariance != null ? estimatedCovariance.getElementAt(2, 2) : null;
3559 }
3560
3561 /**
3562 * Gets standard deviation of estimated z coordinate of gyroscope bias expressed in
3563 * radians per second (rad/s).
3564 *
3565 * @return standard deviation of estimated z coordinate of gyroscope bias or null if not
3566 * available.
3567 */
3568 public Double getEstimatedBiasZStandardDeviation() {
3569 final var variance = getEstimatedBiasZVariance();
3570 return variance != null ? Math.sqrt(variance) : null;
3571 }
3572
3573 /**
3574 * Gets standard deviation of estimated z coordinate of gyroscope bias.
3575 *
3576 * @return standard deviation of estimated z coordinate of gyroscope bias or null if not
3577 * available.
3578 */
3579 public AngularSpeed getEstimatedBiasZStandardDeviationAsAngularSpeed() {
3580 return estimatedCovariance != null
3581 ? new AngularSpeed(getEstimatedBiasZStandardDeviation(), AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3582 }
3583
3584 /**
3585 * Gets standard deviation of estimated z coordinate of gyroscope bias.
3586 *
3587 * @param result instance where result will be stored.
3588 * @return true if standard deviation of estimated z coordinate of gyroscope bias is available,
3589 * false otherwise.
3590 */
3591 public boolean getEstimatedBiasZStandardDeviationAsAngularSpeed(final AngularSpeed result) {
3592 if (estimatedCovariance != null) {
3593 result.setValue(getEstimatedBiasZStandardDeviation());
3594 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3595 return true;
3596 } else {
3597 return false;
3598 }
3599 }
3600
3601 /**
3602 * Gets standard deviation of estimated gyroscope bias coordinates.
3603 *
3604 * @return standard deviation of estimated gyroscope bias coordinates.
3605 */
3606 public AngularSpeedTriad getEstimatedBiasStandardDeviation() {
3607 return estimatedCovariance != null
3608 ? new AngularSpeedTriad(AngularSpeedUnit.RADIANS_PER_SECOND,
3609 getEstimatedBiasXStandardDeviation(),
3610 getEstimatedBiasYStandardDeviation(),
3611 getEstimatedBiasZStandardDeviation())
3612 : null;
3613 }
3614
3615 /**
3616 * Gets standard deviation of estimated gyroscope bias coordinates.
3617 *
3618 * @param result instance where result will be stored.
3619 * @return true if standard deviation of gyroscope bias was available, false
3620 * otherwise.
3621 */
3622 public boolean getEstimatedBiasStandardDeviation(final AngularSpeedTriad result) {
3623 if (estimatedCovariance != null) {
3624 result.setValueCoordinatesAndUnit(
3625 getEstimatedBiasXStandardDeviation(),
3626 getEstimatedBiasYStandardDeviation(),
3627 getEstimatedBiasZStandardDeviation(),
3628 AngularSpeedUnit.RADIANS_PER_SECOND);
3629 return true;
3630 } else {
3631 return false;
3632 }
3633 }
3634
3635 /**
3636 * Gets average of estimated standard deviation of gyroscope bias coordinates expressed
3637 * in radians per second (rad/s).
3638 *
3639 * @return average of estimated standard deviation of gyroscope bias coordinates or null
3640 * if not available.
3641 */
3642 public Double getEstimatedBiasStandardDeviationAverage() {
3643 return estimatedCovariance != null
3644 ? (getEstimatedBiasXStandardDeviation() + getEstimatedBiasYStandardDeviation()
3645 + getEstimatedBiasZStandardDeviation()) / 3.0
3646 : null;
3647 }
3648
3649 /**
3650 * Gets average of estimated standard deviation of gyroscope bias coordinates.
3651 *
3652 * @return average of estimated standard deviation of gyroscope bias coordinates or null.
3653 */
3654 public AngularSpeed getEstimatedBiasStandardDeviationAverageAsAngularSpeed() {
3655 return estimatedCovariance != null
3656 ? new AngularSpeed(getEstimatedBiasStandardDeviationAverage(), AngularSpeedUnit.RADIANS_PER_SECOND)
3657 : null;
3658 }
3659
3660 /**
3661 * Gets average of estimated standard deviation of gyroscope bias coordinates.
3662 *
3663 * @param result instance where result will be stored.
3664 * @return true if average of estimated standard deviation of gyroscope bias is available,
3665 * false otherwise.
3666 */
3667 public boolean getEstimatedBiasStandardDeviationAverageAsAngularSpeed(final AngularSpeed result) {
3668 if (estimatedCovariance != null) {
3669 result.setValue(getEstimatedBiasStandardDeviationAverage());
3670 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3671 return true;
3672 } else {
3673 return false;
3674 }
3675 }
3676
3677 /**
3678 * Gets norm of estimated standard deviation of gyroscope bias expressed in
3679 * radians per second (rad/s).
3680 * This can be used as the initial gyroscope bias uncertainty for
3681 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3682 *
3683 * @return norm of estimated standard deviation of gyroscope bias or null
3684 * if not available.
3685 */
3686 @Override
3687 public Double getEstimatedBiasStandardDeviationNorm() {
3688 return estimatedCovariance != null
3689 ? Math.sqrt(getEstimatedBiasXVariance() + getEstimatedBiasYVariance() + getEstimatedBiasZVariance())
3690 : null;
3691 }
3692
3693 /**
3694 * Gets norm of estimated standard deviation of gyroscope bias.
3695 * This can be used as the initial gyroscope bias uncertainty for
3696 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3697 *
3698 * @return norm of estimated standard deviation of gyroscope bias or null
3699 * if not available.
3700 */
3701 public AngularSpeed getEstimatedBiasStandardDeviationNormAsAngularSpeed() {
3702 return estimatedCovariance != null
3703 ? new AngularSpeed(getEstimatedBiasStandardDeviationNorm(), AngularSpeedUnit.RADIANS_PER_SECOND)
3704 : null;
3705 }
3706
3707 /**
3708 * Gets norm of estimated standard deviation of gyroscope bias coordinates.
3709 * This can be used as the initial gyroscope bias uncertainty for
3710 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3711 *
3712 * @param result instance where result will be stored.
3713 * @return true if norm of estimated standard deviation of gyroscope bias is
3714 * available, false otherwise.
3715 */
3716 public boolean getEstimatedBiasStandardDeviationNormAsAngularSpeed(final AngularSpeed result) {
3717 if (estimatedCovariance != null) {
3718 result.setValue(getEstimatedBiasStandardDeviationNorm());
3719 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3720 return true;
3721 } else {
3722 return false;
3723 }
3724 }
3725
3726 /**
3727 * Gets size of subsets to be checked during robust estimation.
3728 * This has to be at least {@link #getMinimumRequiredMeasurementsOrSequences()}.
3729 *
3730 * @return size of subsets to be checked during robust estimation.
3731 */
3732 public int getPreliminarySubsetSize() {
3733 return preliminarySubsetSize;
3734 }
3735
3736 /**
3737 * Sets size of subsets to be checked during robust estimation.
3738 * This has to be at least {@link #getMinimumRequiredMeasurementsOrSequences}.
3739 *
3740 * @param preliminarySubsetSize size of subsets to be checked during robust estimation.
3741 * @throws LockedException if calibrator is currently running.
3742 * @throws IllegalArgumentException if provided value is less than
3743 * {@link #getMinimumRequiredMeasurementsOrSequences}.
3744 */
3745 public void setPreliminarySubsetSize(final int preliminarySubsetSize) throws LockedException {
3746 if (running) {
3747 throw new LockedException();
3748 }
3749 if (preliminarySubsetSize < getMinimumRequiredMeasurementsOrSequences()) {
3750 throw new IllegalArgumentException();
3751 }
3752
3753 this.preliminarySubsetSize = preliminarySubsetSize;
3754 }
3755
3756 /**
3757 * Returns method being used for robust estimation.
3758 *
3759 * @return method being used for robust estimation.
3760 */
3761 public abstract RobustEstimatorMethod getMethod();
3762
3763 /**
3764 * Creates a robust gyroscope calibrator.
3765 *
3766 * @param method robust estimator method.
3767 * @return a robust gyroscope calibrator.
3768 */
3769 public static RobustEasyGyroscopeCalibrator create(final RobustEstimatorMethod method) {
3770 return switch (method) {
3771 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator();
3772 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator();
3773 case MSAC -> new MSACRobustEasyGyroscopeCalibrator();
3774 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator();
3775 default -> new PROMedSRobustEasyGyroscopeCalibrator();
3776 };
3777 }
3778
3779 /**
3780 * Creates a robust gyroscope calibrator.
3781 *
3782 * @param sequences collection of sequences containing timestamped body
3783 * kinematics measurements.
3784 * @param initialBias initial gyroscope bias to be used to find a solution.
3785 * This must be 3x1 and is expressed in radians per
3786 * second (rad/s).
3787 * @param initialMg initial gyroscope scale factors and cross coupling
3788 * errors matrix. Must be 3x3.
3789 * @param initialGg initial gyroscope G-dependent cross biases
3790 * introduced on the gyroscope by the specific forces
3791 * sensed by the accelerometer. Must be 3x3.
3792 * @param method robust estimator method.
3793 * @return a robust gyroscope calibrator.
3794 * @throws IllegalArgumentException if any of the provided values does
3795 * not have proper size.
3796 */
3797 public static RobustEasyGyroscopeCalibrator create(
3798 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3799 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
3800 final RobustEstimatorMethod method) {
3801 return switch (method) {
3802 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3803 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3804 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3805 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3806 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3807 };
3808 }
3809
3810 /**
3811 * Creates a robust gyroscope calibrator.
3812 *
3813 * @param sequences collection of sequences containing timestamped body
3814 * kinematics measurements.
3815 * @param initialBias initial gyroscope bias to be used to find a solution.
3816 * This must be 3x1 and is expressed in radians per
3817 * second (rad/s).
3818 * @param initialMg initial gyroscope scale factors and cross coupling
3819 * errors matrix. Must be 3x3.
3820 * @param initialGg initial gyroscope G-dependent cross biases
3821 * introduced on the gyroscope by the specific forces
3822 * sensed by the accelerometer. Must be 3x3.
3823 * @param listener listener to handle events raised by this
3824 * calibrator.
3825 * @param method robust estimator method.
3826 * @return a robust gyroscope calibrator.
3827 * @throws IllegalArgumentException if any of the provided values does
3828 * not have proper size.
3829 */
3830 public static RobustEasyGyroscopeCalibrator create(
3831 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3832 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
3833 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
3834 return switch (method) {
3835 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3836 listener);
3837 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3838 listener);
3839 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3840 listener);
3841 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3842 listener);
3843 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3844 listener);
3845 };
3846 }
3847
3848 /**
3849 * Creates a robust gyroscope calibrator.
3850 *
3851 * @param sequences collection of sequences containing timestamped body
3852 * kinematics measurements.
3853 * @param initialBias initial gyroscope bias to be used to find a
3854 * solution. This must have length 3 and is expressed
3855 * in radians per second (rad/s).
3856 * @param initialMg initial gyroscope scale factors and cross coupling
3857 * errors matrix. Must be 3x3.
3858 * @param initialGg initial gyroscope G-dependent cross biases
3859 * introduced on the gyroscope by the specific forces
3860 * sensed by the accelerometer. Must be 3x3.
3861 * @param method robust estimator method.
3862 * @return a robust gyroscope calibrator.
3863 * @throws IllegalArgumentException if any of the provided values does
3864 * not have proper size.
3865 */
3866 public static RobustEasyGyroscopeCalibrator create(
3867 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3868 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
3869 final RobustEstimatorMethod method) {
3870 return switch (method) {
3871 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3872 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3873 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3874 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3875 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
3876 };
3877 }
3878
3879 /**
3880 * Creates a robust gyroscope calibrator.
3881 *
3882 * @param sequences collection of sequences containing timestamped body
3883 * kinematics measurements.
3884 * @param initialBias initial gyroscope bias to be used to find a
3885 * solution. This must have length 3 and is expressed
3886 * in radians per second (rad/s).
3887 * @param initialMg initial gyroscope scale factors and cross coupling
3888 * errors matrix. Must be 3x3.
3889 * @param initialGg initial gyroscope G-dependent cross biases
3890 * introduced on the gyroscope by the specific forces
3891 * sensed by the accelerometer. Must be 3x3.
3892 * @param listener listener to handle events raised by this
3893 * calibrator.
3894 * @param method robust estimator method.
3895 * @return a robust gyroscope calibrator.
3896 * @throws IllegalArgumentException if any of the provided values does
3897 * not have proper size.
3898 */
3899 public static RobustEasyGyroscopeCalibrator create(
3900 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3901 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
3902 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
3903 return switch (method) {
3904 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3905 listener);
3906 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3907 listener);
3908 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3909 listener);
3910 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3911 listener);
3912 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3913 listener);
3914 };
3915 }
3916
3917 /**
3918 * Creates a robust gyroscope calibrator.
3919 *
3920 * @param sequences collection of sequences containing timestamped body
3921 * kinematics measurements.
3922 * @param initialBias initial gyroscope bias to be used to find a
3923 * solution. This must have length 3 and is expressed
3924 * in radians per second (rad/s).
3925 * @param initialMg initial gyroscope scale factors and cross coupling
3926 * errors matrix. Must be 3x3.
3927 * @param initialGg initial gyroscope G-dependent cross biases
3928 * introduced on the gyroscope by the specific forces
3929 * sensed by the accelerometer. Must be 3x3.
3930 * @param accelerometerBias known accelerometer bias. This must
3931 * have length 3 and is expressed in
3932 * meters per squared second
3933 * (m/s^2).
3934 * @param accelerometerMa known accelerometer scale factors and
3935 * cross coupling matrix. Must be 3x3.
3936 * @param method robust estimator method.
3937 * @return a robust gyroscope calibrator.
3938 * @throws IllegalArgumentException if any of the provided values does
3939 * not have proper size.
3940 */
3941 public static RobustEasyGyroscopeCalibrator create(
3942 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3943 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
3944 final double[] accelerometerBias, final Matrix accelerometerMa, final RobustEstimatorMethod method) {
3945 return switch (method) {
3946 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3947 accelerometerBias, accelerometerMa);
3948 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3949 accelerometerBias, accelerometerMa);
3950 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3951 accelerometerBias, accelerometerMa);
3952 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3953 accelerometerBias, accelerometerMa);
3954 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3955 accelerometerBias, accelerometerMa);
3956 };
3957 }
3958
3959 /**
3960 * Creates a robust gyroscope calibrator.
3961 *
3962 * @param sequences collection of sequences containing timestamped body
3963 * kinematics measurements.
3964 * @param initialBias initial gyroscope bias to be used to find a
3965 * solution. This must have length 3 and is expressed
3966 * in radians per second (rad/s).
3967 * @param initialMg initial gyroscope scale factors and cross coupling
3968 * errors matrix. Must be 3x3.
3969 * @param initialGg initial gyroscope G-dependent cross biases
3970 * introduced on the gyroscope by the specific forces
3971 * sensed by the accelerometer. Must be 3x3.
3972 * @param accelerometerBias known accelerometer bias. This must
3973 * have length 3 and is expressed in
3974 * meters per squared second
3975 * (m/s^2).
3976 * @param accelerometerMa known accelerometer scale factors and
3977 * cross coupling matrix. Must be 3x3.
3978 * @param listener listener to handle events raised by this
3979 * calibrator.
3980 * @param method robust estimator method.
3981 * @return a robust gyroscope calibrator.
3982 * @throws IllegalArgumentException if any of the provided values does
3983 * not have proper size.
3984 */
3985 public static RobustEasyGyroscopeCalibrator create(
3986 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
3987 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
3988 final double[] accelerometerBias, final Matrix accelerometerMa,
3989 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
3990 return switch (method) {
3991 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3992 accelerometerBias, accelerometerMa, listener);
3993 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3994 accelerometerBias, accelerometerMa, listener);
3995 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3996 accelerometerBias, accelerometerMa, listener);
3997 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
3998 accelerometerBias, accelerometerMa, listener);
3999 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4000 accelerometerBias, accelerometerMa, listener);
4001 };
4002 }
4003
4004 /**
4005 * Creates a robust gyroscope calibrator.
4006 *
4007 * @param sequences collection of sequences containing timestamped body
4008 * kinematics measurements.
4009 * @param initialBias initial gyroscope bias to be used to find a
4010 * solution. This must be 3x1 and is expressed
4011 * in radians per second (rad/s).
4012 * @param initialMg initial gyroscope scale factors and cross coupling
4013 * errors matrix. Must be 3x3.
4014 * @param initialGg initial gyroscope G-dependent cross biases
4015 * introduced on the gyroscope by the specific forces
4016 * sensed by the accelerometer. Must be 3x3.
4017 * @param accelerometerBias known accelerometer bias. This must be 3x1
4018 * and is expressed in meters per squared
4019 * second (m/s^2).
4020 * @param accelerometerMa known accelerometer scale factors and
4021 * cross coupling matrix. Must be 3x3.
4022 * @param method robust estimator method.
4023 * @return a robust gyroscope calibrator.
4024 * @throws IllegalArgumentException if any of the provided values does
4025 * not have proper size.
4026 */
4027 public static RobustEasyGyroscopeCalibrator create(
4028 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4029 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4030 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
4031 return switch (method) {
4032 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4033 accelerometerBias, accelerometerMa);
4034 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4035 accelerometerBias, accelerometerMa);
4036 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4037 accelerometerBias, accelerometerMa);
4038 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4039 accelerometerBias, accelerometerMa);
4040 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4041 accelerometerBias, accelerometerMa);
4042 };
4043 }
4044
4045 /**
4046 * Creates a robust gyroscope calibrator.
4047 *
4048 * @param sequences collection of sequences containing timestamped body
4049 * kinematics measurements.
4050 * @param initialBias initial gyroscope bias to be used to find a
4051 * solution. This must be 3x1 and is expressed
4052 * in radians per second (rad/s).
4053 * @param initialMg initial gyroscope scale factors and cross coupling
4054 * errors matrix. Must be 3x3.
4055 * @param initialGg initial gyroscope G-dependent cross biases
4056 * introduced on the gyroscope by the specific forces
4057 * sensed by the accelerometer. Must be 3x3.
4058 * @param accelerometerBias known accelerometer bias. This must be 3x1
4059 * and is expressed in meters per squared
4060 * second (m/s^2).
4061 * @param accelerometerMa known accelerometer scale factors and
4062 * cross coupling matrix. Must be 3x3.
4063 * @param listener listener to handle events raised by this
4064 * calibrator.
4065 * @param method robust estimator method.
4066 * @return a robust gyroscope calibrator.
4067 * @throws IllegalArgumentException if any of the provided values does
4068 * not have proper size.
4069 */
4070 public static RobustEasyGyroscopeCalibrator create(
4071 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4072 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4073 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
4074 final RobustEstimatorMethod method) {
4075 return switch (method) {
4076 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4077 accelerometerBias, accelerometerMa, listener);
4078 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4079 accelerometerBias, accelerometerMa, listener);
4080 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4081 accelerometerBias, accelerometerMa, listener);
4082 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4083 accelerometerBias, accelerometerMa, listener);
4084 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4085 accelerometerBias, accelerometerMa, listener);
4086 };
4087 }
4088
4089 /**
4090 * Creates a robust gyroscope calibrator.
4091 *
4092 * @param sequences collection of sequences containing timestamped body
4093 * kinematics measurements.
4094 * @param commonAxisUsed indicates whether z-axis is
4095 * assumed to be common for
4096 * accelerometer and gyroscope.
4097 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4098 * will be estimated, false
4099 * otherwise.
4100 * @param initialBias initial gyroscope bias to be used to find a
4101 * solution. This must be 3x1 and is expressed
4102 * in radians per second (rad/s).
4103 * @param initialMg initial gyroscope scale factors and cross coupling
4104 * errors matrix. Must be 3x3.
4105 * @param initialGg initial gyroscope G-dependent cross biases
4106 * introduced on the gyroscope by the specific forces
4107 * sensed by the accelerometer. Must be 3x3.
4108 * @param method robust estimator method.
4109 * @return a robust gyroscope calibrator.
4110 * @throws IllegalArgumentException if any of the provided values does
4111 * not have proper size.
4112 */
4113 public static RobustEasyGyroscopeCalibrator create(
4114 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4115 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4116 final Matrix initialMg, final Matrix initialGg, final RobustEstimatorMethod method) {
4117 return switch (method) {
4118 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(
4119 sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4120 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(
4121 sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4122 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(
4123 sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4124 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(
4125 sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4126 default -> new PROMedSRobustEasyGyroscopeCalibrator(
4127 sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4128 };
4129 }
4130
4131 /**
4132 * Creates a robust gyroscope calibrator.
4133 *
4134 * @param sequences collection of sequences containing timestamped body
4135 * kinematics measurements.
4136 * @param commonAxisUsed indicates whether z-axis is
4137 * assumed to be common for
4138 * accelerometer and gyroscope.
4139 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4140 * will be estimated, false
4141 * otherwise.
4142 * @param initialBias initial gyroscope bias to be used to find a
4143 * solution. This must be 3x1 and is expressed
4144 * in radians per second (rad/s).
4145 * @param initialMg initial gyroscope scale factors and cross coupling
4146 * errors matrix. Must be 3x3.
4147 * @param initialGg initial gyroscope G-dependent cross biases
4148 * introduced on the gyroscope by the specific forces
4149 * sensed by the accelerometer. Must be 3x3.
4150 * @param listener listener to handle events raised by this
4151 * calibrator.
4152 * @param method robust estimator method.
4153 * @return a robust gyroscope calibrator.
4154 * @throws IllegalArgumentException if any of the provided values does
4155 * not have proper size.
4156 */
4157 public static RobustEasyGyroscopeCalibrator create(
4158 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4159 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4160 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener,
4161 final RobustEstimatorMethod method) {
4162 return switch (method) {
4163 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4164 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4165 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4166 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4167 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4168 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4169 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4170 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4171 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4172 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4173 };
4174 }
4175
4176 /**
4177 * Creates a robust gyroscope calibrator.
4178 *
4179 * @param sequences collection of sequences containing timestamped body
4180 * kinematics measurements.
4181 * @param commonAxisUsed indicates whether z-axis is
4182 * assumed to be common for
4183 * accelerometer and gyroscope.
4184 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4185 * will be estimated, false
4186 * otherwise.
4187 * @param initialBias initial gyroscope bias to be used to find a
4188 * solution. This must have length 3 and is expressed
4189 * in radians per second (rad/s).
4190 * @param initialMg initial gyroscope scale factors and cross coupling
4191 * errors matrix. Must be 3x3.
4192 * @param initialGg initial gyroscope G-dependent cross biases
4193 * introduced on the gyroscope by the specific forces
4194 * sensed by the accelerometer. Must be 3x3.
4195 * @param method robust estimator method.
4196 * @return a robust gyroscope calibrator.
4197 * @throws IllegalArgumentException if any of the provided values does
4198 * not have proper size.
4199 */
4200 public static RobustEasyGyroscopeCalibrator create(
4201 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4202 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
4203 final Matrix initialMg, final Matrix initialGg, final RobustEstimatorMethod method) {
4204 return switch (method) {
4205 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4206 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4207 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4208 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4209 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4210 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4211 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4212 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4213 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4214 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4215 };
4216 }
4217
4218 /**
4219 * Creates a robust gyroscope calibrator.
4220 *
4221 * @param sequences collection of sequences containing timestamped body
4222 * kinematics measurements.
4223 * @param commonAxisUsed indicates whether z-axis is
4224 * assumed to be common for
4225 * accelerometer and gyroscope.
4226 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4227 * will be estimated, false
4228 * otherwise.
4229 * @param initialBias initial gyroscope bias to be used to find a
4230 * solution. This must have length 3 and is expressed
4231 * in radians per second (rad/s).
4232 * @param initialMg initial gyroscope scale factors and cross coupling
4233 * errors matrix. Must be 3x3.
4234 * @param initialGg initial gyroscope G-dependent cross biases
4235 * introduced on the gyroscope by the specific forces
4236 * sensed by the accelerometer. Must be 3x3.
4237 * @param listener listener to handle events raised by this
4238 * calibrator.
4239 * @param method robust estimator method.
4240 * @return a robust gyroscope calibrator.
4241 * @throws IllegalArgumentException if any of the provided values does
4242 * not have proper size.
4243 */
4244 public static RobustEasyGyroscopeCalibrator create(
4245 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4246 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
4247 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener,
4248 final RobustEstimatorMethod method) {
4249 return switch (method) {
4250 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4251 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4252 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4253 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4254 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4255 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4256 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4257 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4258 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4259 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4260 };
4261 }
4262
4263 /**
4264 * Creates a robust gyroscope calibrator.
4265 *
4266 * @param sequences collection of sequences containing timestamped body
4267 * kinematics measurements.
4268 * @param commonAxisUsed indicates whether z-axis is
4269 * assumed to be common for
4270 * accelerometer and gyroscope.
4271 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4272 * will be estimated, false
4273 * otherwise.
4274 * @param initialBias initial gyroscope bias to be used to find a
4275 * solution. This must have length 3 and is expressed
4276 * in radians per second (rad/s).
4277 * @param initialMg initial gyroscope scale factors and cross coupling
4278 * errors matrix. Must be 3x3.
4279 * @param initialGg initial gyroscope G-dependent cross biases
4280 * introduced on the gyroscope by the specific forces
4281 * sensed by the accelerometer. Must be 3x3.
4282 * @param accelerometerBias known accelerometer bias. This
4283 * must have length 3 and is
4284 * expressed in meters per squared
4285 * second (m/s^2).
4286 * @param accelerometerMa known accelerometer scale factors
4287 * and cross coupling matrix. Must
4288 * be 3x3.
4289 * @param method robust estimator method.
4290 * @return a robust gyroscope calibrator.
4291 * @throws IllegalArgumentException if any of the provided values does
4292 * not have proper size.
4293 */
4294 public static RobustEasyGyroscopeCalibrator create(
4295 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4296 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
4297 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
4298 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
4299 return switch (method) {
4300 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4301 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4302 accelerometerMa);
4303 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4304 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4305 accelerometerMa);
4306 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4307 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4308 accelerometerMa);
4309 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4310 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4311 accelerometerMa);
4312 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4313 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4314 accelerometerMa);
4315 };
4316 }
4317
4318 /**
4319 * Creates a robust gyroscope calibrator.
4320 *
4321 * @param sequences collection of sequences containing timestamped body
4322 * kinematics measurements.
4323 * @param commonAxisUsed indicates whether z-axis is
4324 * assumed to be common for
4325 * accelerometer and gyroscope.
4326 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4327 * will be estimated, false
4328 * otherwise.
4329 * @param initialBias initial gyroscope bias to be used to find a
4330 * solution. This must have length 3 and is expressed
4331 * in radians per second (rad/s).
4332 * @param initialMg initial gyroscope scale factors and cross coupling
4333 * errors matrix. Must be 3x3.
4334 * @param initialGg initial gyroscope G-dependent cross biases
4335 * introduced on the gyroscope by the specific forces
4336 * sensed by the accelerometer. Must be 3x3.
4337 * @param accelerometerBias known accelerometer bias. This
4338 * must have length 3 and is
4339 * expressed in meters per squared
4340 * second (m/s^2).
4341 * @param accelerometerMa known accelerometer scale factors
4342 * and cross coupling matrix. Must
4343 * be 3x3.
4344 * @param listener listener to handle events raised by this
4345 * calibrator.
4346 * @param method robust estimator method.
4347 * @return a robust gyroscope calibrator.
4348 * @throws IllegalArgumentException if any of the provided values does
4349 * not have proper size.
4350 */
4351 public static RobustEasyGyroscopeCalibrator create(
4352 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4353 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
4354 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
4355 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
4356 final RobustEstimatorMethod method) {
4357 return switch (method) {
4358 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4359 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4360 accelerometerMa, listener);
4361 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4362 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4363 accelerometerMa, listener);
4364 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4365 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4366 accelerometerMa, listener);
4367 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4368 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4369 accelerometerMa, listener);
4370 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4371 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4372 accelerometerMa, listener);
4373 };
4374 }
4375
4376 /**
4377 * Creates a robust gyroscope calibrator.
4378 *
4379 * @param sequences collection of sequences containing timestamped body
4380 * kinematics measurements.
4381 * @param commonAxisUsed indicates whether z-axis is
4382 * assumed to be common for
4383 * accelerometer and gyroscope.
4384 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4385 * will be estimated, false
4386 * otherwise.
4387 * @param initialBias initial gyroscope bias to be used to find a
4388 * solution. This must be 3x1 and is expressed
4389 * in radians per second (rad/s).
4390 * @param initialMg initial gyroscope scale factors and cross coupling
4391 * errors matrix. Must be 3x3.
4392 * @param initialGg initial gyroscope G-dependent cross biases
4393 * introduced on the gyroscope by the specific forces
4394 * sensed by the accelerometer. Must be 3x3.
4395 * @param accelerometerBias known accelerometer bias. This
4396 * must have length 3 and is
4397 * expressed in meters per squared
4398 * second (m/s^2).
4399 * @param accelerometerMa known accelerometer scale factors
4400 * and cross coupling matrix. Must
4401 * be 3x3.
4402 * @param method robust estimator method.
4403 * @return a robust gyroscope calibrator.
4404 * @throws IllegalArgumentException if any of the provided values does
4405 * not have proper size.
4406 */
4407 public static RobustEasyGyroscopeCalibrator create(
4408 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4409 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4410 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4411 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
4412 return switch (method) {
4413 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4414 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4415 accelerometerMa);
4416 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4417 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4418 accelerometerMa);
4419 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4420 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4421 accelerometerMa);
4422 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4423 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4424 accelerometerMa);
4425 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4426 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4427 accelerometerMa);
4428 };
4429 }
4430
4431 /**
4432 * Creates a robust gyroscope calibrator.
4433 *
4434 * @param sequences collection of sequences containing timestamped body
4435 * kinematics measurements.
4436 * @param commonAxisUsed indicates whether z-axis is
4437 * assumed to be common for
4438 * accelerometer and gyroscope.
4439 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4440 * will be estimated, false
4441 * otherwise.
4442 * @param initialBias initial gyroscope bias to be used to find a
4443 * solution. This must be 3x1 and is expressed
4444 * in radians per second (rad/s).
4445 * @param initialMg initial gyroscope scale factors and cross coupling
4446 * errors matrix. Must be 3x3.
4447 * @param initialGg initial gyroscope G-dependent cross biases
4448 * introduced on the gyroscope by the specific forces
4449 * sensed by the accelerometer. Must be 3x3.
4450 * @param accelerometerBias known accelerometer bias. This
4451 * must have length 3 and is
4452 * expressed in meters per squared
4453 * second (m/s^2).
4454 * @param accelerometerMa known accelerometer scale factors
4455 * and cross coupling matrix. Must
4456 * be 3x3.
4457 * @param listener listener to handle events raised by this
4458 * calibrator.
4459 * @param method robust estimator method.
4460 * @return a robust gyroscope calibrator.
4461 * @throws IllegalArgumentException if any of the provided values does
4462 * not have proper size.
4463 */
4464 public static RobustEasyGyroscopeCalibrator create(
4465 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4466 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4467 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4468 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
4469 final RobustEstimatorMethod method) {
4470 return switch (method) {
4471 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4472 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4473 accelerometerMa, listener);
4474 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4475 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4476 accelerometerMa, listener);
4477 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4478 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4479 accelerometerMa, listener);
4480 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4481 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4482 accelerometerMa, listener);
4483 default -> new PROMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4484 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
4485 accelerometerMa, listener);
4486 };
4487 }
4488
4489 /**
4490 * Creates a robust gyroscope calibrator.
4491 *
4492 * @param qualityScores quality scores corresponding to each provided
4493 * sequence. The larger the score value the better
4494 * the quality of the sequence.
4495 * @param method robust estimator method.
4496 * @return a robust gyroscope calibrator.
4497 * @throws IllegalArgumentException if provided quality scores length
4498 * is smaller than 10.
4499 */
4500 public static RobustEasyGyroscopeCalibrator create(
4501 final double[] qualityScores, final RobustEstimatorMethod method) {
4502 return switch (method) {
4503 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator();
4504 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator();
4505 case MSAC -> new MSACRobustEasyGyroscopeCalibrator();
4506 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores);
4507 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores);
4508 };
4509 }
4510
4511 /**
4512 * Creates a robust gyroscope calibrator.
4513 *
4514 * @param qualityScores quality scores corresponding to each provided
4515 * sequence. The larger the score value the better
4516 * the quality of the sequence.
4517 * @param sequences collection of sequences containing timestamped body
4518 * kinematics measurements.
4519 * @param initialBias initial gyroscope bias to be used to find a solution.
4520 * This must be 3x1 and is expressed in radians per
4521 * second (rad/s).
4522 * @param initialMg initial gyroscope scale factors and cross coupling
4523 * errors matrix. Must be 3x3.
4524 * @param initialGg initial gyroscope G-dependent cross biases
4525 * introduced on the gyroscope by the specific forces
4526 * sensed by the accelerometer. Must be 3x3.
4527 * @param method robust estimator method.
4528 * @return a robust gyroscope calibrator.
4529 * @throws IllegalArgumentException if any of the provided values does
4530 * not have proper size or if provided
4531 * quality scores length is smaller
4532 * than 10.
4533 */
4534 public static RobustEasyGyroscopeCalibrator create(
4535 final double[] qualityScores,
4536 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4537 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
4538 final RobustEstimatorMethod method) {
4539 return switch (method) {
4540 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4541 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4542 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4543 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4544 initialGg);
4545 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4546 initialGg);
4547 };
4548 }
4549
4550 /**
4551 * Creates a robust gyroscope calibrator.
4552 *
4553 * @param qualityScores quality scores corresponding to each provided
4554 * sequence. The larger the score value the better
4555 * the quality of the sequence.
4556 * @param sequences collection of sequences containing timestamped body
4557 * kinematics measurements.
4558 * @param initialBias initial gyroscope bias to be used to find a solution.
4559 * This must be 3x1 and is expressed in radians per
4560 * second (rad/s).
4561 * @param initialMg initial gyroscope scale factors and cross coupling
4562 * errors matrix. Must be 3x3.
4563 * @param initialGg initial gyroscope G-dependent cross biases
4564 * introduced on the gyroscope by the specific forces
4565 * sensed by the accelerometer. Must be 3x3.
4566 * @param listener listener to handle events raised by this
4567 * calibrator.
4568 * @param method robust estimator method.
4569 * @return a robust gyroscope calibrator.
4570 * @throws IllegalArgumentException if any of the provided values does
4571 * not have proper size or if provided
4572 * quality scores length is smaller
4573 * than 10.
4574 */
4575 public static RobustEasyGyroscopeCalibrator create(
4576 final double[] qualityScores,
4577 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4578 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
4579 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
4580 return switch (method) {
4581 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4582 listener);
4583 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4584 listener);
4585 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4586 listener);
4587 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4588 initialGg, listener);
4589 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4590 initialGg, listener);
4591 };
4592 }
4593
4594 /**
4595 * Creates a robust gyroscope calibrator.
4596 *
4597 * @param qualityScores quality scores corresponding to each provided
4598 * sequence. The larger the score value the better
4599 * the quality of the sequence.
4600 * @param sequences collection of sequences containing timestamped body
4601 * kinematics measurements.
4602 * @param initialBias initial gyroscope bias to be used to find a
4603 * solution. This must have length 3 and is expressed
4604 * in radians per second (rad/s).
4605 * @param initialMg initial gyroscope scale factors and cross coupling
4606 * errors matrix. Must be 3x3.
4607 * @param initialGg initial gyroscope G-dependent cross biases
4608 * introduced on the gyroscope by the specific forces
4609 * sensed by the accelerometer. Must be 3x3.
4610 * @param method robust estimator method.
4611 * @return a robust gyroscope calibrator.
4612 * @throws IllegalArgumentException if any of the provided values does
4613 * not have proper size or if provided
4614 * quality scores length is smaller
4615 * than 10.
4616 */
4617 public static RobustEasyGyroscopeCalibrator create(
4618 final double[] qualityScores,
4619 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4620 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
4621 final RobustEstimatorMethod method) {
4622 return switch (method) {
4623 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4624 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4625 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg);
4626 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4627 initialGg);
4628 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4629 initialGg);
4630 };
4631 }
4632
4633 /**
4634 * Creates a robust gyroscope calibrator.
4635 *
4636 * @param qualityScores quality scores corresponding to each provided
4637 * sequence. The larger the score value the better
4638 * the quality of the sequence.
4639 * @param sequences collection of sequences containing timestamped body
4640 * kinematics measurements.
4641 * @param initialBias initial gyroscope bias to be used to find a
4642 * solution. This must have length 3 and is expressed
4643 * in radians per second (rad/s).
4644 * @param initialMg initial gyroscope scale factors and cross coupling
4645 * errors matrix. Must be 3x3.
4646 * @param initialGg initial gyroscope G-dependent cross biases
4647 * introduced on the gyroscope by the specific forces
4648 * sensed by the accelerometer. Must be 3x3.
4649 * @param listener listener to handle events raised by this
4650 * calibrator.
4651 * @param method robust estimator method.
4652 * @return a robust gyroscope calibrator.
4653 * @throws IllegalArgumentException if any of the provided values does
4654 * not have proper size or if provided
4655 * quality scores length is smaller
4656 * than 10.
4657 */
4658 public static RobustEasyGyroscopeCalibrator create(
4659 final double[] qualityScores,
4660 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4661 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
4662 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
4663 return switch (method) {
4664 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4665 listener);
4666 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4667 listener);
4668 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4669 listener);
4670 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4671 initialGg, listener);
4672 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4673 initialGg, listener);
4674 };
4675 }
4676
4677 /**
4678 * Creates a robust gyroscope calibrator.
4679 *
4680 * @param qualityScores quality scores corresponding to each provided
4681 * sequence. The larger the score value the better
4682 * the quality of the sequence.
4683 * @param sequences collection of sequences containing timestamped body
4684 * kinematics measurements.
4685 * @param initialBias initial gyroscope bias to be used to find a
4686 * solution. This must have length 3 and is expressed
4687 * in radians per second (rad/s).
4688 * @param initialMg initial gyroscope scale factors and cross coupling
4689 * errors matrix. Must be 3x3.
4690 * @param initialGg initial gyroscope G-dependent cross biases
4691 * introduced on the gyroscope by the specific forces
4692 * sensed by the accelerometer. Must be 3x3.
4693 * @param accelerometerBias known accelerometer bias. This must
4694 * have length 3 and is expressed in
4695 * meters per squared second
4696 * (m/s^2).
4697 * @param accelerometerMa known accelerometer scale factors and
4698 * cross coupling matrix. Must be 3x3.
4699 * @param method robust estimator method.
4700 * @return a robust gyroscope calibrator.
4701 * @throws IllegalArgumentException if any of the provided values does
4702 * not have proper size or if provided
4703 * quality scores length is smaller
4704 * than 10.
4705 */
4706 public static RobustEasyGyroscopeCalibrator create(
4707 final double[] qualityScores,
4708 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4709 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
4710 final double[] accelerometerBias, final Matrix accelerometerMa, final RobustEstimatorMethod method) {
4711 return switch (method) {
4712 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4713 accelerometerBias, accelerometerMa);
4714 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4715 accelerometerBias, accelerometerMa);
4716 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4717 accelerometerBias, accelerometerMa);
4718 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4719 initialGg, accelerometerBias, accelerometerMa);
4720 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4721 initialGg, accelerometerBias, accelerometerMa);
4722 };
4723 }
4724
4725 /**
4726 * Creates a robust gyroscope calibrator.
4727 *
4728 * @param qualityScores quality scores corresponding to each provided
4729 * sequence. The larger the score value the better
4730 * the quality of the sequence.
4731 * @param sequences collection of sequences containing timestamped body
4732 * kinematics measurements.
4733 * @param initialBias initial gyroscope bias to be used to find a
4734 * solution. This must have length 3 and is expressed
4735 * in radians per second (rad/s).
4736 * @param initialMg initial gyroscope scale factors and cross coupling
4737 * errors matrix. Must be 3x3.
4738 * @param initialGg initial gyroscope G-dependent cross biases
4739 * introduced on the gyroscope by the specific forces
4740 * sensed by the accelerometer. Must be 3x3.
4741 * @param accelerometerBias known accelerometer bias. This must
4742 * have length 3 and is expressed in
4743 * meters per squared second
4744 * (m/s^2).
4745 * @param accelerometerMa known accelerometer scale factors and
4746 * cross coupling matrix. Must be 3x3.
4747 * @param listener listener to handle events raised by this
4748 * calibrator.
4749 * @param method robust estimator method.
4750 * @return a robust gyroscope calibrator.
4751 * @throws IllegalArgumentException if any of the provided values does
4752 * not have proper size or if provided
4753 * quality scores length is smaller
4754 * than 10.
4755 */
4756 public static RobustEasyGyroscopeCalibrator create(
4757 final double[] qualityScores,
4758 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4759 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
4760 final double[] accelerometerBias, final Matrix accelerometerMa,
4761 final RobustEasyGyroscopeCalibratorListener listener, final RobustEstimatorMethod method) {
4762 return switch (method) {
4763 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4764 accelerometerBias, accelerometerMa, listener);
4765 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4766 accelerometerBias, accelerometerMa, listener);
4767 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4768 accelerometerBias, accelerometerMa, listener);
4769 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4770 initialGg, accelerometerBias, accelerometerMa, listener);
4771 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4772 initialGg, accelerometerBias, accelerometerMa, listener);
4773 };
4774 }
4775
4776 /**
4777 * Creates a robust gyroscope calibrator.
4778 *
4779 * @param qualityScores quality scores corresponding to each provided
4780 * sequence. The larger the score value the better
4781 * the quality of the sequence.
4782 * @param sequences collection of sequences containing timestamped body
4783 * kinematics measurements.
4784 * @param initialBias initial gyroscope bias to be used to find a
4785 * solution. This must be 3x1 and is expressed
4786 * in radians per second (rad/s).
4787 * @param initialMg initial gyroscope scale factors and cross coupling
4788 * errors matrix. Must be 3x3.
4789 * @param initialGg initial gyroscope G-dependent cross biases
4790 * introduced on the gyroscope by the specific forces
4791 * sensed by the accelerometer. Must be 3x3.
4792 * @param accelerometerBias known accelerometer bias. This must be 3x1
4793 * and is expressed in meters per squared
4794 * second (m/s^2).
4795 * @param accelerometerMa known accelerometer scale factors and
4796 * cross coupling matrix. Must be 3x3.
4797 * @param method robust estimator method.
4798 * @return a robust gyroscope calibrator.
4799 * @throws IllegalArgumentException if any of the provided values does
4800 * not have proper size or if provided
4801 * quality scores length is smaller
4802 * than 10.
4803 */
4804 public static RobustEasyGyroscopeCalibrator create(
4805 final double[] qualityScores,
4806 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4807 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4808 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
4809 return switch (method) {
4810 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4811 accelerometerBias, accelerometerMa);
4812 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4813 accelerometerBias, accelerometerMa);
4814 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4815 accelerometerBias, accelerometerMa);
4816 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4817 initialGg, accelerometerBias, accelerometerMa);
4818 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4819 initialGg, accelerometerBias, accelerometerMa);
4820 };
4821 }
4822
4823 /**
4824 * Creates a robust gyroscope calibrator.
4825 *
4826 * @param qualityScores quality scores corresponding to each provided
4827 * sequence. The larger the score value the better
4828 * the quality of the sequence.
4829 * @param sequences collection of sequences containing timestamped body
4830 * kinematics measurements.
4831 * @param initialBias initial gyroscope bias to be used to find a
4832 * solution. This must be 3x1 and is expressed
4833 * in radians per second (rad/s).
4834 * @param initialMg initial gyroscope scale factors and cross coupling
4835 * errors matrix. Must be 3x3.
4836 * @param initialGg initial gyroscope G-dependent cross biases
4837 * introduced on the gyroscope by the specific forces
4838 * sensed by the accelerometer. Must be 3x3.
4839 * @param accelerometerBias known accelerometer bias. This must be 3x1
4840 * and is expressed in meters per squared
4841 * second (m/s^2).
4842 * @param accelerometerMa known accelerometer scale factors and
4843 * cross coupling matrix. Must be 3x3.
4844 * @param listener listener to handle events raised by this
4845 * calibrator.
4846 * @param method robust estimator method.
4847 * @return a robust gyroscope calibrator.
4848 * @throws IllegalArgumentException if any of the provided values does
4849 * not have proper size or if provided
4850 * quality scores length is smaller
4851 * than 10.
4852 */
4853 public static RobustEasyGyroscopeCalibrator create(
4854 final double[] qualityScores,
4855 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4856 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
4857 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
4858 final RobustEstimatorMethod method) {
4859 return switch (method) {
4860 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4861 accelerometerBias, accelerometerMa, listener);
4862 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4863 accelerometerBias, accelerometerMa, listener);
4864 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, initialBias, initialMg, initialGg,
4865 accelerometerBias, accelerometerMa, listener);
4866 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4867 initialGg, accelerometerBias, accelerometerMa, listener);
4868 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, initialBias, initialMg,
4869 initialGg, accelerometerBias, accelerometerMa, listener);
4870 };
4871 }
4872
4873 /**
4874 * Creates a robust gyroscope calibrator.
4875 *
4876 * @param qualityScores quality scores corresponding to each provided
4877 * sequence. The larger the score value the better
4878 * the quality of the sequence.
4879 * @param sequences collection of sequences containing timestamped body
4880 * kinematics measurements.
4881 * @param commonAxisUsed indicates whether z-axis is
4882 * assumed to be common for
4883 * accelerometer and gyroscope.
4884 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4885 * will be estimated, false
4886 * otherwise.
4887 * @param initialBias initial gyroscope bias to be used to find a
4888 * solution. This must be 3x1 and is expressed
4889 * in radians per second (rad/s).
4890 * @param initialMg initial gyroscope scale factors and cross coupling
4891 * errors matrix. Must be 3x3.
4892 * @param initialGg initial gyroscope G-dependent cross biases
4893 * introduced on the gyroscope by the specific forces
4894 * sensed by the accelerometer. Must be 3x3.
4895 * @param method robust estimator method.
4896 * @return a robust gyroscope calibrator.
4897 * @throws IllegalArgumentException if any of the provided values does
4898 * not have proper size or if provided
4899 * quality scores length is smaller
4900 * than 10.
4901 */
4902 public static RobustEasyGyroscopeCalibrator create(
4903 final double[] qualityScores,
4904 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4905 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4906 final Matrix initialMg, final Matrix initialGg, final RobustEstimatorMethod method) {
4907 return switch (method) {
4908 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4909 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4910 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4911 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4912 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4913 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4914 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
4915 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4916 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
4917 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
4918 };
4919 }
4920
4921 /**
4922 * Creates a robust gyroscope calibrator.
4923 *
4924 * @param qualityScores quality scores corresponding to each provided
4925 * sequence. The larger the score value the better
4926 * the quality of the sequence.
4927 * @param sequences collection of sequences containing timestamped body
4928 * kinematics measurements.
4929 * @param commonAxisUsed indicates whether z-axis is
4930 * assumed to be common for
4931 * accelerometer and gyroscope.
4932 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4933 * will be estimated, false
4934 * otherwise.
4935 * @param initialBias initial gyroscope bias to be used to find a
4936 * solution. This must be 3x1 and is expressed
4937 * in radians per second (rad/s).
4938 * @param initialMg initial gyroscope scale factors and cross coupling
4939 * errors matrix. Must be 3x3.
4940 * @param initialGg initial gyroscope G-dependent cross biases
4941 * introduced on the gyroscope by the specific forces
4942 * sensed by the accelerometer. Must be 3x3.
4943 * @param listener listener to handle events raised by this
4944 * calibrator.
4945 * @param method robust estimator method.
4946 * @return a robust gyroscope calibrator.
4947 * @throws IllegalArgumentException if any of the provided values does
4948 * not have proper size or if provided
4949 * quality scores length is smaller
4950 * than 10.
4951 */
4952 public static RobustEasyGyroscopeCalibrator create(
4953 final double[] qualityScores,
4954 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
4955 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
4956 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener,
4957 final RobustEstimatorMethod method) {
4958 return switch (method) {
4959 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4960 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4961 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4962 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4963 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
4964 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4965 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
4966 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4967 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
4968 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
4969 };
4970 }
4971
4972 /**
4973 * Creates a robust gyroscope calibrator.
4974 *
4975 * @param qualityScores quality scores corresponding to each provided
4976 * sequence. The larger the score value the better
4977 * the quality of the sequence.
4978 * @param sequences collection of sequences containing timestamped body
4979 * kinematics measurements.
4980 * @param commonAxisUsed indicates whether z-axis is
4981 * assumed to be common for
4982 * accelerometer and gyroscope.
4983 * @param estimateGDependentCrossBiases true if G-dependent cross biases
4984 * will be estimated, false
4985 * otherwise.
4986 * @param initialBias initial gyroscope bias to be used to find a
4987 * solution. This must have length 3 and is expressed
4988 * in radians per second (rad/s).
4989 * @param initialMg initial gyroscope scale factors and cross coupling
4990 * errors matrix. Must be 3x3.
4991 * @param initialGg initial gyroscope G-dependent cross biases
4992 * introduced on the gyroscope by the specific forces
4993 * sensed by the accelerometer. Must be 3x3.
4994 * @param method robust estimator method.
4995 * @return a robust gyroscope calibrator.
4996 * @throws IllegalArgumentException if any of the provided values does
4997 * not have proper size or if provided
4998 * quality scores length is smaller
4999 * than 10.
5000 */
5001 public static RobustEasyGyroscopeCalibrator create(
5002 final double[] qualityScores,
5003 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5004 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5005 final Matrix initialMg, final Matrix initialGg, final RobustEstimatorMethod method) {
5006 return switch (method) {
5007 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5008 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
5009 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5010 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
5011 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5012 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
5013 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5014 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
5015 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5016 estimateGDependentCrossBiases, initialBias, initialMg, initialGg);
5017 };
5018 }
5019
5020 /**
5021 * Creates a robust gyroscope calibrator.
5022 *
5023 * @param qualityScores quality scores corresponding to each provided
5024 * sequence. The larger the score value the better
5025 * the quality of the sequence.
5026 * @param sequences collection of sequences containing timestamped body
5027 * kinematics measurements.
5028 * @param commonAxisUsed indicates whether z-axis is
5029 * assumed to be common for
5030 * accelerometer and gyroscope.
5031 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5032 * will be estimated, false
5033 * otherwise.
5034 * @param initialBias initial gyroscope bias to be used to find a
5035 * solution. This must have length 3 and is expressed
5036 * in radians per second (rad/s).
5037 * @param initialMg initial gyroscope scale factors and cross coupling
5038 * errors matrix. Must be 3x3.
5039 * @param initialGg initial gyroscope G-dependent cross biases
5040 * introduced on the gyroscope by the specific forces
5041 * sensed by the accelerometer. Must be 3x3.
5042 * @param listener listener to handle events raised by this
5043 * calibrator.
5044 * @param method robust estimator method.
5045 * @return a robust gyroscope calibrator.
5046 * @throws IllegalArgumentException if any of the provided values does
5047 * not have proper size or if provided
5048 * quality scores length is smaller
5049 * than 10.
5050 */
5051 public static RobustEasyGyroscopeCalibrator create(
5052 final double[] qualityScores,
5053 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5054 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5055 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener,
5056 final RobustEstimatorMethod method) {
5057 return switch (method) {
5058 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5059 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
5060 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5061 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
5062 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5063 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
5064 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5065 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
5066 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5067 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, listener);
5068 };
5069 }
5070
5071 /**
5072 * Creates a robust gyroscope calibrator.
5073 *
5074 * @param qualityScores quality scores corresponding to each provided
5075 * sequence. The larger the score value the better
5076 * the quality of the sequence.
5077 * @param sequences collection of sequences containing timestamped body
5078 * kinematics measurements.
5079 * @param commonAxisUsed indicates whether z-axis is
5080 * assumed to be common for
5081 * accelerometer and gyroscope.
5082 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5083 * will be estimated, false
5084 * otherwise.
5085 * @param initialBias initial gyroscope bias to be used to find a
5086 * solution. This must have length 3 and is expressed
5087 * in radians per second (rad/s).
5088 * @param initialMg initial gyroscope scale factors and cross coupling
5089 * errors matrix. Must be 3x3.
5090 * @param initialGg initial gyroscope G-dependent cross biases
5091 * introduced on the gyroscope by the specific forces
5092 * sensed by the accelerometer. Must be 3x3.
5093 * @param accelerometerBias known accelerometer bias. This
5094 * must have length 3 and is
5095 * expressed in meters per squared
5096 * second (m/s^2).
5097 * @param accelerometerMa known accelerometer scale factors
5098 * and cross coupling matrix. Must
5099 * be 3x3.
5100 * @param method robust estimator method.
5101 * @return a robust gyroscope calibrator.
5102 * @throws IllegalArgumentException if any of the provided values does
5103 * not have proper size or if provided
5104 * quality scores length is smaller
5105 * than 10.
5106 */
5107 public static RobustEasyGyroscopeCalibrator create(
5108 final double[] qualityScores,
5109 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5110 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5111 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
5112 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
5113 return switch (method) {
5114 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5115 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5116 accelerometerMa);
5117 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5118 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5119 accelerometerMa);
5120 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5121 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5122 accelerometerMa);
5123 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5124 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5125 accelerometerMa);
5126 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5127 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5128 accelerometerMa);
5129 };
5130 }
5131
5132 /**
5133 * Creates a robust gyroscope calibrator.
5134 *
5135 * @param qualityScores quality scores corresponding to each provided
5136 * sequence. The larger the score value the better
5137 * the quality of the sequence.
5138 * @param sequences collection of sequences containing timestamped body
5139 * kinematics measurements.
5140 * @param commonAxisUsed indicates whether z-axis is
5141 * assumed to be common for
5142 * accelerometer and gyroscope.
5143 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5144 * will be estimated, false
5145 * otherwise.
5146 * @param initialBias initial gyroscope bias to be used to find a
5147 * solution. This must have length 3 and is expressed
5148 * in radians per second (rad/s).
5149 * @param initialMg initial gyroscope scale factors and cross coupling
5150 * errors matrix. Must be 3x3.
5151 * @param initialGg initial gyroscope G-dependent cross biases
5152 * introduced on the gyroscope by the specific forces
5153 * sensed by the accelerometer. Must be 3x3.
5154 * @param accelerometerBias known accelerometer bias. This
5155 * must have length 3 and is
5156 * expressed in meters per squared
5157 * second (m/s^2).
5158 * @param accelerometerMa known accelerometer scale factors
5159 * and cross coupling matrix. Must
5160 * be 3x3.
5161 * @param listener listener to handle events raised by this
5162 * calibrator.
5163 * @param method robust estimator method.
5164 * @return a robust gyroscope calibrator.
5165 * @throws IllegalArgumentException if any of the provided values does
5166 * not have proper size or if provided
5167 * quality scores length is smaller
5168 * than 10.
5169 */
5170 public static RobustEasyGyroscopeCalibrator create(
5171 final double[] qualityScores,
5172 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5173 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5174 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
5175 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
5176 final RobustEstimatorMethod method) {
5177 return switch (method) {
5178 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5179 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5180 accelerometerMa, listener);
5181 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5182 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5183 accelerometerMa, listener);
5184 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5185 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5186 accelerometerMa, listener);
5187 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5188 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5189 accelerometerMa, listener);
5190 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5191 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5192 accelerometerMa, listener);
5193 };
5194 }
5195
5196 /**
5197 * Creates a robust gyroscope calibrator.
5198 *
5199 * @param qualityScores quality scores corresponding to each provided
5200 * sequence. The larger the score value the better
5201 * the quality of the sequence.
5202 * @param sequences collection of sequences containing timestamped body
5203 * kinematics measurements.
5204 * @param commonAxisUsed indicates whether z-axis is
5205 * assumed to be common for
5206 * accelerometer and gyroscope.
5207 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5208 * will be estimated, false
5209 * otherwise.
5210 * @param initialBias initial gyroscope bias to be used to find a
5211 * solution. This must be 3x1 and is expressed
5212 * in radians per second (rad/s).
5213 * @param initialMg initial gyroscope scale factors and cross coupling
5214 * errors matrix. Must be 3x3.
5215 * @param initialGg initial gyroscope G-dependent cross biases
5216 * introduced on the gyroscope by the specific forces
5217 * sensed by the accelerometer. Must be 3x3.
5218 * @param accelerometerBias known accelerometer bias. This
5219 * must have length 3 and is
5220 * expressed in meters per squared
5221 * second (m/s^2).
5222 * @param accelerometerMa known accelerometer scale factors
5223 * and cross coupling matrix. Must
5224 * be 3x3.
5225 * @param method robust estimator method.
5226 * @return a robust gyroscope calibrator.
5227 * @throws IllegalArgumentException if any of the provided values does
5228 * not have proper size or if provided
5229 * quality scores length is smaller
5230 * than 10.
5231 */
5232 public static RobustEasyGyroscopeCalibrator create(
5233 final double[] qualityScores,
5234 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5235 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5236 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5237 final Matrix accelerometerMa, final RobustEstimatorMethod method) {
5238 return switch (method) {
5239 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5240 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5241 accelerometerMa);
5242 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5243 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5244 accelerometerMa);
5245 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5246 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5247 accelerometerMa);
5248 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5249 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5250 accelerometerMa);
5251 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5252 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5253 accelerometerMa);
5254 };
5255 }
5256
5257 /**
5258 * Creates a robust gyroscope calibrator.
5259 *
5260 * @param qualityScores quality scores corresponding to each provided
5261 * sequence. The larger the score value the better
5262 * the quality of the sequence.
5263 * @param sequences collection of sequences containing timestamped body
5264 * kinematics measurements.
5265 * @param commonAxisUsed indicates whether z-axis is
5266 * assumed to be common for
5267 * accelerometer and gyroscope.
5268 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5269 * will be estimated, false
5270 * otherwise.
5271 * @param initialBias initial gyroscope bias to be used to find a
5272 * solution. This must be 3x1 and is expressed
5273 * in radians per second (rad/s).
5274 * @param initialMg initial gyroscope scale factors and cross coupling
5275 * errors matrix. Must be 3x3.
5276 * @param initialGg initial gyroscope G-dependent cross biases
5277 * introduced on the gyroscope by the specific forces
5278 * sensed by the accelerometer. Must be 3x3.
5279 * @param accelerometerBias known accelerometer bias. This
5280 * must have length 3 and is
5281 * expressed in meters per squared
5282 * second (m/s^2).
5283 * @param accelerometerMa known accelerometer scale factors
5284 * and cross coupling matrix. Must
5285 * be 3x3.
5286 * @param listener listener to handle events raised by this
5287 * calibrator.
5288 * @param method robust estimator method.
5289 * @return a robust gyroscope calibrator.
5290 * @throws IllegalArgumentException if any of the provided values does
5291 * not have proper size or if provided
5292 * quality scores length is smaller
5293 * than 10.
5294 */
5295 public static RobustEasyGyroscopeCalibrator create(
5296 final double[] qualityScores,
5297 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5298 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5299 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5300 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener,
5301 final RobustEstimatorMethod method) {
5302 return switch (method) {
5303 case RANSAC -> new RANSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5304 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5305 accelerometerMa, listener);
5306 case LMEDS -> new LMedSRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5307 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5308 accelerometerMa, listener);
5309 case MSAC -> new MSACRobustEasyGyroscopeCalibrator(sequences, commonAxisUsed,
5310 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5311 accelerometerMa, listener);
5312 case PROSAC -> new PROSACRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5313 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5314 accelerometerMa, listener);
5315 default -> new PROMedSRobustEasyGyroscopeCalibrator(qualityScores, sequences, commonAxisUsed,
5316 estimateGDependentCrossBiases, initialBias, initialMg, initialGg, accelerometerBias,
5317 accelerometerMa, listener);
5318 };
5319 }
5320
5321 /**
5322 * Creates a robust gyroscope calibrator using default robust method.
5323 *
5324 * @return a robust gyroscope calibrator.
5325 */
5326 public static RobustEasyGyroscopeCalibrator create() {
5327 return create(DEFAULT_ROBUST_METHOD);
5328 }
5329
5330 /**
5331 * Creates a robust gyroscope calibrator using default robust method.
5332 *
5333 * @param sequences collection of sequences containing timestamped body
5334 * kinematics measurements.
5335 * @param initialBias initial gyroscope bias to be used to find a solution.
5336 * This must be 3x1 and is expressed in radians per
5337 * second (rad/s).
5338 * @param initialMg initial gyroscope scale factors and cross coupling
5339 * errors matrix. Must be 3x3.
5340 * @param initialGg initial gyroscope G-dependent cross biases
5341 * introduced on the gyroscope by the specific forces
5342 * sensed by the accelerometer. Must be 3x3.
5343 * @return a robust gyroscope calibrator.
5344 * @throws IllegalArgumentException if any of the provided values does
5345 * not have proper size.
5346 */
5347 public static RobustEasyGyroscopeCalibrator create(
5348 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5349 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg) {
5350 return create(sequences, initialBias, initialMg, initialGg, DEFAULT_ROBUST_METHOD);
5351 }
5352
5353 /**
5354 * Creates a robust gyroscope calibrator using default robust method.
5355 *
5356 * @param sequences collection of sequences containing timestamped body
5357 * kinematics measurements.
5358 * @param initialBias initial gyroscope bias to be used to find a solution.
5359 * This must be 3x1 and is expressed in radians per
5360 * second (rad/s).
5361 * @param initialMg initial gyroscope scale factors and cross coupling
5362 * errors matrix. Must be 3x3.
5363 * @param initialGg initial gyroscope G-dependent cross biases
5364 * introduced on the gyroscope by the specific forces
5365 * sensed by the accelerometer. Must be 3x3.
5366 * @param listener listener to handle events raised by this
5367 * calibrator.
5368 * @return a robust gyroscope calibrator.
5369 * @throws IllegalArgumentException if any of the provided values does
5370 * not have proper size.
5371 */
5372 public static RobustEasyGyroscopeCalibrator create(
5373 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5374 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg,
5375 final RobustEasyGyroscopeCalibratorListener listener) {
5376 return create(sequences, initialBias, initialMg, initialGg, listener, DEFAULT_ROBUST_METHOD);
5377 }
5378
5379 /**
5380 * Creates a robust gyroscope calibrator using default robust method.
5381 *
5382 * @param sequences collection of sequences containing timestamped body
5383 * kinematics measurements.
5384 * @param initialBias initial gyroscope bias to be used to find a
5385 * solution. This must have length 3 and is expressed
5386 * in radians per second (rad/s).
5387 * @param initialMg initial gyroscope scale factors and cross coupling
5388 * errors matrix. Must be 3x3.
5389 * @param initialGg initial gyroscope G-dependent cross biases
5390 * introduced on the gyroscope by the specific forces
5391 * sensed by the accelerometer. Must be 3x3.
5392 * @return a robust gyroscope calibrator.
5393 * @throws IllegalArgumentException if any of the provided values does
5394 * not have proper size.
5395 */
5396 public static RobustEasyGyroscopeCalibrator create(
5397 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5398 final double[] initialBias, final Matrix initialMg, final Matrix initialGg) {
5399 return create(sequences, initialBias, initialMg, initialGg, DEFAULT_ROBUST_METHOD);
5400 }
5401
5402 /**
5403 * Creates a robust gyroscope calibrator using default robust method.
5404 *
5405 * @param sequences collection of sequences containing timestamped body
5406 * kinematics measurements.
5407 * @param initialBias initial gyroscope bias to be used to find a
5408 * solution. This must have length 3 and is expressed
5409 * in radians per second (rad/s).
5410 * @param initialMg initial gyroscope scale factors and cross coupling
5411 * errors matrix. Must be 3x3.
5412 * @param initialGg initial gyroscope G-dependent cross biases
5413 * introduced on the gyroscope by the specific forces
5414 * sensed by the accelerometer. Must be 3x3.
5415 * @param listener listener to handle events raised by this
5416 * calibrator.
5417 * @return a robust gyroscope calibrator.
5418 * @throws IllegalArgumentException if any of the provided values does
5419 * not have proper size.
5420 */
5421 public static RobustEasyGyroscopeCalibrator create(
5422 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5423 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
5424 final RobustEasyGyroscopeCalibratorListener listener) {
5425 return create(sequences, initialBias, initialMg, initialGg, listener, DEFAULT_ROBUST_METHOD);
5426 }
5427
5428 /**
5429 * Creates a robust gyroscope calibrator using default robust method.
5430 *
5431 * @param sequences collection of sequences containing timestamped body
5432 * kinematics measurements.
5433 * @param initialBias initial gyroscope bias to be used to find a
5434 * solution. This must have length 3 and is expressed
5435 * in radians per second (rad/s).
5436 * @param initialMg initial gyroscope scale factors and cross coupling
5437 * errors matrix. Must be 3x3.
5438 * @param initialGg initial gyroscope G-dependent cross biases
5439 * introduced on the gyroscope by the specific forces
5440 * sensed by the accelerometer. Must be 3x3.
5441 * @param accelerometerBias known accelerometer bias. This must
5442 * have length 3 and is expressed in
5443 * meters per squared second
5444 * (m/s^2).
5445 * @param accelerometerMa known accelerometer scale factors and
5446 * cross coupling matrix. Must be 3x3.
5447 * @return a robust gyroscope calibrator.
5448 * @throws IllegalArgumentException if any of the provided values does
5449 * not have proper size.
5450 */
5451 public static RobustEasyGyroscopeCalibrator create(
5452 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5453 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
5454 final double[] accelerometerBias, final Matrix accelerometerMa) {
5455 return create(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa,
5456 DEFAULT_ROBUST_METHOD);
5457 }
5458
5459 /**
5460 * Creates a robust gyroscope calibrator using default robust method.
5461 *
5462 * @param sequences collection of sequences containing timestamped body
5463 * kinematics measurements.
5464 * @param initialBias initial gyroscope bias to be used to find a
5465 * solution. This must have length 3 and is expressed
5466 * in radians per second (rad/s).
5467 * @param initialMg initial gyroscope scale factors and cross coupling
5468 * errors matrix. Must be 3x3.
5469 * @param initialGg initial gyroscope G-dependent cross biases
5470 * introduced on the gyroscope by the specific forces
5471 * sensed by the accelerometer. Must be 3x3.
5472 * @param accelerometerBias known accelerometer bias. This must
5473 * have length 3 and is expressed in
5474 * meters per squared second
5475 * (m/s^2).
5476 * @param accelerometerMa known accelerometer scale factors and
5477 * cross coupling matrix. Must be 3x3.
5478 * @param listener listener to handle events raised by this
5479 * calibrator.
5480 * @return a robust gyroscope calibrator.
5481 * @throws IllegalArgumentException if any of the provided values does
5482 * not have proper size.
5483 */
5484 public static RobustEasyGyroscopeCalibrator create(
5485 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5486 final double[] initialBias, final Matrix initialMg, final Matrix initialGg,
5487 final double[] accelerometerBias, final Matrix accelerometerMa,
5488 final RobustEasyGyroscopeCalibratorListener listener) {
5489 return create(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa, listener,
5490 DEFAULT_ROBUST_METHOD);
5491 }
5492
5493 /**
5494 * Creates a robust gyroscope calibrator using default robust method.
5495 *
5496 * @param sequences collection of sequences containing timestamped body
5497 * kinematics measurements.
5498 * @param initialBias initial gyroscope bias to be used to find a
5499 * solution. This must be 3x1 and is expressed
5500 * in radians per second (rad/s).
5501 * @param initialMg initial gyroscope scale factors and cross coupling
5502 * errors matrix. Must be 3x3.
5503 * @param initialGg initial gyroscope G-dependent cross biases
5504 * introduced on the gyroscope by the specific forces
5505 * sensed by the accelerometer. Must be 3x3.
5506 * @param accelerometerBias known accelerometer bias. This must be 3x1
5507 * and is expressed in meters per squared
5508 * second (m/s^2).
5509 * @param accelerometerMa known accelerometer scale factors and
5510 * cross coupling matrix. Must be 3x3.
5511 * @return a robust gyroscope calibrator.
5512 * @throws IllegalArgumentException if any of the provided values does
5513 * not have proper size.
5514 */
5515 public static RobustEasyGyroscopeCalibrator create(
5516 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5517 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5518 final Matrix accelerometerMa) {
5519 return create(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa,
5520 DEFAULT_ROBUST_METHOD);
5521 }
5522
5523 /**
5524 * Creates a robust gyroscope calibrator using default robust method.
5525 *
5526 * @param sequences collection of sequences containing timestamped body
5527 * kinematics measurements.
5528 * @param initialBias initial gyroscope bias to be used to find a
5529 * solution. This must be 3x1 and is expressed
5530 * in radians per second (rad/s).
5531 * @param initialMg initial gyroscope scale factors and cross coupling
5532 * errors matrix. Must be 3x3.
5533 * @param initialGg initial gyroscope G-dependent cross biases
5534 * introduced on the gyroscope by the specific forces
5535 * sensed by the accelerometer. Must be 3x3.
5536 * @param accelerometerBias known accelerometer bias. This must be 3x1
5537 * and is expressed in meters per squared
5538 * second (m/s^2).
5539 * @param accelerometerMa known accelerometer scale factors and
5540 * cross coupling matrix. Must be 3x3.
5541 * @param listener listener to handle events raised by this
5542 * calibrator.
5543 * @return a robust gyroscope calibrator.
5544 * @throws IllegalArgumentException if any of the provided values does
5545 * not have proper size.
5546 */
5547 public static RobustEasyGyroscopeCalibrator create(
5548 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5549 final Matrix initialBias, final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5550 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
5551 return create(sequences, initialBias, initialMg, initialGg, accelerometerBias, accelerometerMa, listener,
5552 DEFAULT_ROBUST_METHOD);
5553 }
5554
5555 /**
5556 * Creates a robust gyroscope calibrator using default robust method.
5557 *
5558 * @param sequences collection of sequences containing timestamped body
5559 * kinematics measurements.
5560 * @param commonAxisUsed indicates whether z-axis is
5561 * assumed to be common for
5562 * accelerometer and gyroscope.
5563 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5564 * will be estimated, false
5565 * otherwise.
5566 * @param initialBias initial gyroscope bias to be used to find a
5567 * solution. This must be 3x1 and is expressed
5568 * in radians per second (rad/s).
5569 * @param initialMg initial gyroscope scale factors and cross coupling
5570 * errors matrix. Must be 3x3.
5571 * @param initialGg initial gyroscope G-dependent cross biases
5572 * introduced on the gyroscope by the specific forces
5573 * sensed by the accelerometer. Must be 3x3.
5574 * @return a robust gyroscope calibrator.
5575 * @throws IllegalArgumentException if any of the provided values does
5576 * not have proper size.
5577 */
5578 public static RobustEasyGyroscopeCalibrator create(
5579 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5580 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5581 final Matrix initialMg, final Matrix initialGg) {
5582 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
5583 DEFAULT_ROBUST_METHOD);
5584 }
5585
5586 /**
5587 * Creates a robust gyroscope calibrator using default robust method.
5588 *
5589 * @param sequences collection of sequences containing timestamped body
5590 * kinematics measurements.
5591 * @param commonAxisUsed indicates whether z-axis is
5592 * assumed to be common for
5593 * accelerometer and gyroscope.
5594 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5595 * will be estimated, false
5596 * otherwise.
5597 * @param initialBias initial gyroscope bias to be used to find a
5598 * solution. This must be 3x1 and is expressed
5599 * in radians per second (rad/s).
5600 * @param initialMg initial gyroscope scale factors and cross coupling
5601 * errors matrix. Must be 3x3.
5602 * @param initialGg initial gyroscope G-dependent cross biases
5603 * introduced on the gyroscope by the specific forces
5604 * sensed by the accelerometer. Must be 3x3.
5605 * @param listener listener to handle events raised by this
5606 * calibrator.
5607 * @return a robust gyroscope calibrator.
5608 * @throws IllegalArgumentException if any of the provided values does
5609 * not have proper size.
5610 */
5611 public static RobustEasyGyroscopeCalibrator create(
5612 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5613 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5614 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener) {
5615 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
5616 listener, DEFAULT_ROBUST_METHOD);
5617 }
5618
5619 /**
5620 * Creates a robust gyroscope calibrator using default robust method.
5621 *
5622 * @param sequences collection of sequences containing timestamped body
5623 * kinematics measurements.
5624 * @param commonAxisUsed indicates whether z-axis is
5625 * assumed to be common for
5626 * accelerometer and gyroscope.
5627 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5628 * will be estimated, false
5629 * otherwise.
5630 * @param initialBias initial gyroscope bias to be used to find a
5631 * solution. This must have length 3 and is expressed
5632 * in radians per second (rad/s).
5633 * @param initialMg initial gyroscope scale factors and cross coupling
5634 * errors matrix. Must be 3x3.
5635 * @param initialGg initial gyroscope G-dependent cross biases
5636 * introduced on the gyroscope by the specific forces
5637 * sensed by the accelerometer. Must be 3x3.
5638 * @return a robust gyroscope calibrator.
5639 * @throws IllegalArgumentException if any of the provided values does
5640 * not have proper size.
5641 */
5642 public static RobustEasyGyroscopeCalibrator create(
5643 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5644 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5645 final Matrix initialMg, final Matrix initialGg) {
5646 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
5647 DEFAULT_ROBUST_METHOD);
5648 }
5649
5650 /**
5651 * Creates a robust gyroscope calibrator using default robust method.
5652 *
5653 * @param sequences collection of sequences containing timestamped body
5654 * kinematics measurements.
5655 * @param commonAxisUsed indicates whether z-axis is
5656 * assumed to be common for
5657 * accelerometer and gyroscope.
5658 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5659 * will be estimated, false
5660 * otherwise.
5661 * @param initialBias initial gyroscope bias to be used to find a
5662 * solution. This must have length 3 and is expressed
5663 * in radians per second (rad/s).
5664 * @param initialMg initial gyroscope scale factors and cross coupling
5665 * errors matrix. Must be 3x3.
5666 * @param initialGg initial gyroscope G-dependent cross biases
5667 * introduced on the gyroscope by the specific forces
5668 * sensed by the accelerometer. Must be 3x3.
5669 * @param listener listener to handle events raised by this
5670 * calibrator.
5671 * @return a robust gyroscope calibrator.
5672 * @throws IllegalArgumentException if any of the provided values does
5673 * not have proper size.
5674 */
5675 public static RobustEasyGyroscopeCalibrator create(
5676 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5677 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5678 final Matrix initialMg, final Matrix initialGg, final RobustEasyGyroscopeCalibratorListener listener) {
5679 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
5680 listener, DEFAULT_ROBUST_METHOD);
5681 }
5682
5683 /**
5684 * Creates a robust gyroscope calibrator using default robust method.
5685 *
5686 * @param sequences collection of sequences containing timestamped body
5687 * kinematics measurements.
5688 * @param commonAxisUsed indicates whether z-axis is
5689 * assumed to be common for
5690 * accelerometer and gyroscope.
5691 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5692 * will be estimated, false
5693 * otherwise.
5694 * @param initialBias initial gyroscope bias to be used to find a
5695 * solution. This must have length 3 and is expressed
5696 * in radians per second (rad/s).
5697 * @param initialMg initial gyroscope scale factors and cross coupling
5698 * errors matrix. Must be 3x3.
5699 * @param initialGg initial gyroscope G-dependent cross biases
5700 * introduced on the gyroscope by the specific forces
5701 * sensed by the accelerometer. Must be 3x3.
5702 * @param accelerometerBias known accelerometer bias. This
5703 * must have length 3 and is
5704 * expressed in meters per squared
5705 * second (m/s^2).
5706 * @param accelerometerMa known accelerometer scale factors
5707 * and cross coupling matrix. Must
5708 * be 3x3.
5709 * @return a robust gyroscope calibrator.
5710 * @throws IllegalArgumentException if any of the provided values does
5711 * not have proper size.
5712 */
5713 public static RobustEasyGyroscopeCalibrator create(
5714 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5715 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5716 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
5717 final Matrix accelerometerMa) {
5718 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg,
5719 initialGg, accelerometerBias, accelerometerMa, DEFAULT_ROBUST_METHOD);
5720 }
5721
5722 /**
5723 * Creates a robust gyroscope calibrator using default robust method.
5724 *
5725 * @param sequences collection of sequences containing timestamped body
5726 * kinematics measurements.
5727 * @param commonAxisUsed indicates whether z-axis is
5728 * assumed to be common for
5729 * accelerometer and gyroscope.
5730 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5731 * will be estimated, false
5732 * otherwise.
5733 * @param initialBias initial gyroscope bias to be used to find a
5734 * solution. This must have length 3 and is expressed
5735 * in radians per second (rad/s).
5736 * @param initialMg initial gyroscope scale factors and cross coupling
5737 * errors matrix. Must be 3x3.
5738 * @param initialGg initial gyroscope G-dependent cross biases
5739 * introduced on the gyroscope by the specific forces
5740 * sensed by the accelerometer. Must be 3x3.
5741 * @param accelerometerBias known accelerometer bias. This
5742 * must have length 3 and is
5743 * expressed in meters per squared
5744 * second (m/s^2).
5745 * @param accelerometerMa known accelerometer scale factors
5746 * and cross coupling matrix. Must
5747 * be 3x3.
5748 * @param listener listener to handle events raised by this
5749 * calibrator.
5750 * @return a robust gyroscope calibrator.
5751 * @throws IllegalArgumentException if any of the provided values does
5752 * not have proper size.
5753 */
5754 public static RobustEasyGyroscopeCalibrator create(
5755 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5756 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final double[] initialBias,
5757 final Matrix initialMg, final Matrix initialGg, final double[] accelerometerBias,
5758 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
5759 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg,
5760 initialGg, accelerometerBias, accelerometerMa, listener, DEFAULT_ROBUST_METHOD);
5761 }
5762
5763 /**
5764 * Creates a robust gyroscope calibrator using default robust method.
5765 *
5766 * @param sequences collection of sequences containing timestamped body
5767 * kinematics measurements.
5768 * @param commonAxisUsed indicates whether z-axis is
5769 * assumed to be common for
5770 * accelerometer and gyroscope.
5771 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5772 * will be estimated, false
5773 * otherwise.
5774 * @param initialBias initial gyroscope bias to be used to find a
5775 * solution. This must be 3x1 and is expressed
5776 * in radians per second (rad/s).
5777 * @param initialMg initial gyroscope scale factors and cross coupling
5778 * errors matrix. Must be 3x3.
5779 * @param initialGg initial gyroscope G-dependent cross biases
5780 * introduced on the gyroscope by the specific forces
5781 * sensed by the accelerometer. Must be 3x3.
5782 * @param accelerometerBias known accelerometer bias. This
5783 * must have length 3 and is
5784 * expressed in meters per squared
5785 * second (m/s^2).
5786 * @param accelerometerMa known accelerometer scale factors
5787 * and cross coupling matrix. Must
5788 * be 3x3.
5789 * @return a robust gyroscope calibrator.
5790 * @throws IllegalArgumentException if any of the provided values does
5791 * not have proper size.
5792 */
5793 public static RobustEasyGyroscopeCalibrator create(
5794 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5795 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5796 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5797 final Matrix accelerometerMa) {
5798 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg, initialGg,
5799 accelerometerBias, accelerometerMa, DEFAULT_ROBUST_METHOD);
5800 }
5801
5802 /**
5803 * Creates a robust gyroscope calibrator using default robust method.
5804 *
5805 * @param sequences collection of sequences containing timestamped body
5806 * kinematics measurements.
5807 * @param commonAxisUsed indicates whether z-axis is
5808 * assumed to be common for
5809 * accelerometer and gyroscope.
5810 * @param estimateGDependentCrossBiases true if G-dependent cross biases
5811 * will be estimated, false
5812 * otherwise.
5813 * @param initialBias initial gyroscope bias to be used to find a
5814 * solution. This must be 3x1 and is expressed
5815 * in radians per second (rad/s).
5816 * @param initialMg initial gyroscope scale factors and cross coupling
5817 * errors matrix. Must be 3x3.
5818 * @param initialGg initial gyroscope G-dependent cross biases
5819 * introduced on the gyroscope by the specific forces
5820 * sensed by the accelerometer. Must be 3x3.
5821 * @param accelerometerBias known accelerometer bias. This
5822 * must have length 3 and is
5823 * expressed in meters per squared
5824 * second (m/s^2).
5825 * @param accelerometerMa known accelerometer scale factors
5826 * and cross coupling matrix. Must
5827 * be 3x3.
5828 * @param listener listener to handle events raised by this
5829 * calibrator.
5830 * @return a robust gyroscope calibrator.
5831 * @throws IllegalArgumentException if any of the provided values does
5832 * not have proper size.
5833 */
5834 public static RobustEasyGyroscopeCalibrator create(
5835 final List<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>> sequences,
5836 final boolean commonAxisUsed, final boolean estimateGDependentCrossBiases, final Matrix initialBias,
5837 final Matrix initialMg, final Matrix initialGg, final Matrix accelerometerBias,
5838 final Matrix accelerometerMa, final RobustEasyGyroscopeCalibratorListener listener) {
5839 return create(sequences, commonAxisUsed, estimateGDependentCrossBiases, initialBias, initialMg,
5840 initialGg, accelerometerBias, accelerometerMa, listener, DEFAULT_ROBUST_METHOD);
5841 }
5842
5843 /**
5844 * Configures acceleration fixer
5845 *
5846 * @throws AlgebraException if provided accelerometer parameters
5847 * are numerically unstable.
5848 */
5849 protected void setupAccelerationFixer() throws AlgebraException {
5850 accelerationFixer.setBias(getAccelerometerBias());
5851 accelerationFixer.setCrossCouplingErrors(getAccelerometerMa());
5852 }
5853
5854 /**
5855 * Computes error of a preliminary result respect a given sequence.
5856 *
5857 * @param sequence a sequence.
5858 * @param preliminaryResult a preliminary result.
5859 * @return computed error.
5860 */
5861 protected double computeError(
5862 final BodyKinematicsSequence<StandardDeviationTimedBodyKinematics> sequence,
5863 final PreliminaryResult preliminaryResult) {
5864
5865 try {
5866 angularRateFixer.setBias(preliminaryResult.estimatedBiases);
5867 angularRateFixer.setCrossCouplingErrors(preliminaryResult.estimatedMg);
5868 angularRateFixer.setGDependantCrossBias(preliminaryResult.estimatedGg);
5869
5870 // copy measured sequence as it will be used to fix kinematics values
5871 // using preliminary gyroscope parameters
5872 final var fixedSequence = new BodyKinematicsSequence<>(sequence);
5873
5874 // fix body kinematic measurements of provided sequence
5875 final var numItems = sequence.getItemsCount();
5876 final var measuredItems = sequence.getSortedItems();
5877 final var fixedItems = fixedSequence.getSortedItems();
5878 for (var j = 0; j < numItems; j++) {
5879 final var measuredItem = measuredItems.get(j);
5880 final var fixedItem = fixedItems.get(j);
5881
5882 final var measuredKinematics = measuredItem.getKinematics();
5883 final var fixedKinematics = fixedItem.getKinematics();
5884 fixKinematics(measuredKinematics, fixedKinematics);
5885 }
5886
5887 // integrate fixed sequence to obtain attitude change
5888 QuaternionIntegrator.integrateGyroSequence(fixedSequence, QuaternionStepIntegratorType.RUNGE_KUTTA, q);
5889
5890 // fix before coordinates
5891 measuredSpecificForce[0] = sequence.getBeforeMeanFx();
5892 measuredSpecificForce[1] = sequence.getBeforeMeanFy();
5893 measuredSpecificForce[2] = sequence.getBeforeMeanFz();
5894 accelerationFixer.fix(measuredSpecificForce, fixedSpecificForce);
5895
5896 // normalize coordinates
5897 ArrayUtils.normalize(fixedSpecificForce);
5898
5899 // compute estimated normalized end coordinates
5900 startPoint.setCoordinates(fixedSpecificForce);
5901 q.inverse();
5902 q.rotate(startPoint, endPoint);
5903
5904 // fix after coordinates
5905 measuredSpecificForce[0] = sequence.getAfterMeanFx();
5906 measuredSpecificForce[1] = sequence.getAfterMeanFy();
5907 measuredSpecificForce[2] = sequence.getAfterMeanFz();
5908 accelerationFixer.fix(measuredSpecificForce, fixedSpecificForce);
5909
5910 // normalize coordinates
5911 ArrayUtils.normalize(fixedSpecificForce);
5912
5913 expectedEndPoint.setCoordinates(fixedSpecificForce);
5914
5915 // compare estimated normalized end coordinates with expected
5916 // ones
5917 return expectedEndPoint.distanceTo(endPoint);
5918
5919 } catch (final AlgebraException | RotationException e) {
5920 return Double.MAX_VALUE;
5921 }
5922 }
5923
5924 /**
5925 * Computes a preliminary solution for a subset of samples picked by a robust estimator.
5926 *
5927 * @param samplesIndices indices of samples picked by the robust estimator.
5928 * @param solutions list where estimated preliminary solution will be stored.
5929 */
5930 protected void computePreliminarySolutions(
5931 final int[] samplesIndices, final List<PreliminaryResult> solutions) {
5932 final var seqs = new ArrayList<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>>();
5933
5934 for (final var samplesIndex : samplesIndices) {
5935 seqs.add(this.sequences.get(samplesIndex));
5936 }
5937
5938 try {
5939 final var result = new PreliminaryResult();
5940 result.estimatedBiases = getInitialBias();
5941 result.estimatedMg = getInitialMg();
5942 result.estimatedGg = getInitialGg();
5943
5944 innerCalibrator.setGDependentCrossBiasesEstimated(estimateGDependentCrossBiases);
5945 innerCalibrator.setInitialBias(result.estimatedBiases);
5946 innerCalibrator.setInitialMg(result.estimatedMg);
5947 innerCalibrator.setInitialGg(result.estimatedGg);
5948 innerCalibrator.setAccelerometerBias(accelerometerBiasX, accelerometerBiasY, accelerometerBiasZ);
5949 innerCalibrator.setAccelerometerScalingFactorsAndCrossCouplingErrors(
5950 accelerometerSx, accelerometerSy, accelerometerSz,
5951 accelerometerMxy, accelerometerMxz, accelerometerMyx,
5952 accelerometerMyz, accelerometerMzx, accelerometerMzy);
5953 innerCalibrator.setCommonAxisUsed(commonAxisUsed);
5954 innerCalibrator.setSequences(seqs);
5955 innerCalibrator.calibrate();
5956
5957 innerCalibrator.getEstimatedBiases(result.estimatedBiases);
5958 result.estimatedMg = innerCalibrator.getEstimatedMg();
5959 result.estimatedGg = innerCalibrator.getEstimatedGg();
5960
5961 if (keepCovariance) {
5962 result.covariance = innerCalibrator.getEstimatedCovariance();
5963 } else {
5964 result.covariance = null;
5965 }
5966
5967 result.estimatedMse = innerCalibrator.getEstimatedMse();
5968 result.estimatedChiSq = innerCalibrator.getEstimatedChiSq();
5969 result.estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
5970 result.estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
5971 result.estimatedP = innerCalibrator.getEstimatedP();
5972 result.estimatedQ = innerCalibrator.getEstimatedQ();
5973
5974 solutions.add(result);
5975 } catch (final LockedException | CalibrationException | NotReadyException e) {
5976 solutions.clear();
5977 }
5978 }
5979
5980 /**
5981 * Attempts to refine calibration parameters if refinement is requested.
5982 * This method returns a refined solution or provided input if refinement is not
5983 * requested or has failed.
5984 * If refinement is enabled and it is requested to keep covariance, this method
5985 * will also keep covariance of refined position.
5986 *
5987 * @param preliminaryResult a preliminary result.
5988 */
5989 protected void attemptRefine(final PreliminaryResult preliminaryResult) {
5990 if (refineResult && inliersData != null) {
5991 final var inliers = inliersData.getInliers();
5992 final var nSamples = sequences.size();
5993
5994 final var inlierSequences = new ArrayList<BodyKinematicsSequence<StandardDeviationTimedBodyKinematics>>();
5995 for (var i = 0; i < nSamples; i++) {
5996 if (inliers.get(i)) {
5997 // sample is inlier
5998 inlierSequences.add(sequences.get(i));
5999 }
6000 }
6001
6002 try {
6003 innerCalibrator.setGDependentCrossBiasesEstimated(estimateGDependentCrossBiases);
6004 innerCalibrator.setInitialBias(preliminaryResult.estimatedBiases);
6005 innerCalibrator.setInitialMg(preliminaryResult.estimatedMg);
6006 innerCalibrator.setInitialGg(preliminaryResult.estimatedGg);
6007 innerCalibrator.setAccelerometerBias(accelerometerBiasX, accelerometerBiasY, accelerometerBiasZ);
6008 innerCalibrator.setAccelerometerScalingFactorsAndCrossCouplingErrors(
6009 accelerometerSx, accelerometerSy, accelerometerSz,
6010 accelerometerMxy, accelerometerMxz, accelerometerMyx,
6011 accelerometerMyz, accelerometerMzx, accelerometerMzy);
6012 innerCalibrator.setCommonAxisUsed(commonAxisUsed);
6013 innerCalibrator.setSequences(inlierSequences);
6014 innerCalibrator.calibrate();
6015
6016 estimatedBiases = innerCalibrator.getEstimatedBiases();
6017 estimatedMg = innerCalibrator.getEstimatedMg();
6018 estimatedGg = innerCalibrator.getEstimatedGg();
6019 estimatedCovariance = innerCalibrator.getEstimatedCovariance();
6020 estimatedMse = innerCalibrator.getEstimatedMse();
6021 estimatedChiSq = innerCalibrator.getEstimatedChiSq();
6022 estimatedChiSqDegreesOfFreedom = innerCalibrator.getEstimatedChiSqDegreesOfFreedom();
6023 estimatedReducedChiSq = innerCalibrator.getEstimatedReducedChiSq();
6024 estimatedP = innerCalibrator.getEstimatedP();
6025 estimatedQ = innerCalibrator.getEstimatedQ();
6026
6027 } catch (LockedException | CalibrationException | NotReadyException e) {
6028 estimatedCovariance = preliminaryResult.covariance;
6029 estimatedBiases = preliminaryResult.estimatedBiases;
6030 estimatedMg = preliminaryResult.estimatedMg;
6031 estimatedGg = preliminaryResult.estimatedGg;
6032 estimatedMse = preliminaryResult.estimatedMse;
6033 estimatedChiSq = preliminaryResult.estimatedChiSq;
6034 estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
6035 estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
6036 estimatedP = preliminaryResult.estimatedP;
6037 estimatedQ = preliminaryResult.estimatedQ;
6038 }
6039 } else {
6040 estimatedCovariance = preliminaryResult.covariance;
6041 estimatedBiases = preliminaryResult.estimatedBiases;
6042 estimatedMg = preliminaryResult.estimatedMg;
6043 estimatedGg = preliminaryResult.estimatedGg;
6044 estimatedMse = preliminaryResult.estimatedMse;
6045 estimatedChiSq = preliminaryResult.estimatedChiSq;
6046 estimatedChiSqDegreesOfFreedom = preliminaryResult.estimatedChiSqDegreesOfFreedom;
6047 estimatedReducedChiSq = preliminaryResult.estimatedReducedChiSq;
6048 estimatedP = preliminaryResult.estimatedP;
6049 estimatedQ = preliminaryResult.estimatedQ;
6050 }
6051 }
6052
6053 /**
6054 * Converts acceleration instance to meters per squared second.
6055 *
6056 * @param acceleration acceleration instance to be converted.
6057 * @return converted value.
6058 */
6059 private static double convertAcceleration(final Acceleration acceleration) {
6060 return AccelerationConverter.convert(acceleration.getValue().doubleValue(), acceleration.getUnit(),
6061 AccelerationUnit.METERS_PER_SQUARED_SECOND);
6062 }
6063
6064 /**
6065 * Converts angular speed value and unit to radians per second.
6066 *
6067 * @param value angular speed value.
6068 * @param unit unit of angular speed value.
6069 * @return converted value.
6070 */
6071 private static double convertAngularSpeed(final double value, final AngularSpeedUnit unit) {
6072 return AngularSpeedConverter.convert(value, unit, AngularSpeedUnit.RADIANS_PER_SECOND);
6073 }
6074
6075 /**
6076 * Converts angular speed instance to radians per second.
6077 *
6078 * @param angularSpeed angular speed instance to be converted.
6079 * @return converted value.
6080 */
6081 private static double convertAngularSpeed(final AngularSpeed angularSpeed) {
6082 return convertAngularSpeed(angularSpeed.getValue().doubleValue(), angularSpeed.getUnit());
6083 }
6084
6085 /**
6086 * Fixes a measured kinematics instance using current
6087 *
6088 * @param measuredKinematics a measured kinematics instance.
6089 * @param result instance where fixed values will be stored.
6090 * @throws AlgebraException if accelerometer or gyroscope parameters
6091 * contain numerical instabilities.
6092 */
6093 private void fixKinematics(final BodyKinematics measuredKinematics, final BodyKinematics result)
6094 throws AlgebraException {
6095
6096 measuredSpecificForce[0] = measuredKinematics.getFx();
6097 measuredSpecificForce[1] = measuredKinematics.getFy();
6098 measuredSpecificForce[2] = measuredKinematics.getFz();
6099 accelerationFixer.fix(measuredSpecificForce, fixedSpecificForce);
6100
6101 measuredAngularRate[0] = measuredKinematics.getAngularRateX();
6102 measuredAngularRate[1] = measuredKinematics.getAngularRateY();
6103 measuredAngularRate[2] = measuredKinematics.getAngularRateZ();
6104 angularRateFixer.fix(measuredAngularRate, fixedSpecificForce, fixedAngularRate);
6105
6106 result.setSpecificForceCoordinates(fixedSpecificForce[0], fixedSpecificForce[1], fixedSpecificForce[2]);
6107 result.setAngularRateCoordinates(fixedAngularRate[0], fixedAngularRate[1], fixedAngularRate[2]);
6108 }
6109
6110 /**
6111 * Internal class containing estimated preliminary result.
6112 */
6113 protected static class PreliminaryResult {
6114 /**
6115 * Estimated gyroscope biases for each IMU axis expressed in radians per second
6116 * (rad/s).
6117 */
6118 private double[] estimatedBiases;
6119
6120 /**
6121 * Estimated gyroscope scale factors and cross coupling errors.
6122 * This is the product of matrix Tg containing cross coupling errors and Kg
6123 * containing scaling factors.
6124 * So that:
6125 * <pre>
6126 * Mg = [sx mxy mxz] = Tg*Kg
6127 * [myx sy myz]
6128 * [mzx mzy sz ]
6129 * </pre>
6130 * Where:
6131 * <pre>
6132 * Kg = [sx 0 0 ]
6133 * [0 sy 0 ]
6134 * [0 0 sz]
6135 * </pre>
6136 * and
6137 * <pre>
6138 * Tg = [1 -alphaXy alphaXz ]
6139 * [alphaYx 1 -alphaYz]
6140 * [-alphaZx alphaZy 1 ]
6141 * </pre>
6142 * Hence:
6143 * <pre>
6144 * Mg = [sx mxy mxz] = Tg*Kg = [sx -sy * alphaXy sz * alphaXz ]
6145 * [myx sy myz] [sx * alphaYx sy -sz * alphaYz]
6146 * [mzx mzy sz ] [-sx * alphaZx sy * alphaZy sz ]
6147 * </pre>
6148 * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
6149 * are considered to be zero if the gyroscope z-axis is assumed to be the same
6150 * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Mg matrix
6151 * becomes upper diagonal:
6152 * <pre>
6153 * Mg = [sx mxy mxz]
6154 * [0 sy myz]
6155 * [0 0 sz ]
6156 * </pre>
6157 * Values of this matrix are unit-less.
6158 */
6159 private Matrix estimatedMg;
6160
6161 /**
6162 * Estimated G-dependent cross biases introduced on the gyroscope by the
6163 * specific forces sensed by the accelerometer.
6164 * This instance allows any 3x3 matrix.
6165 */
6166 private Matrix estimatedGg;
6167
6168 /**
6169 * Covariance matrix for estimated result.
6170 */
6171 private Matrix covariance;
6172
6173 /**
6174 * Estimated Mean Square Error.
6175 */
6176 private double estimatedMse;
6177
6178 /**
6179 * Estimated chi square value.
6180 */
6181 private double estimatedChiSq;
6182
6183 /**
6184 * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
6185 * minus the number of estimated parameters.
6186 */
6187 private int estimatedChiSqDegreesOfFreedom;
6188
6189 /**
6190 * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
6191 * freedom. Ideally this value should be close to 1.0.
6192 */
6193 private double estimatedReducedChiSq;
6194
6195 /**
6196 * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
6197 * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
6198 * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
6199 */
6200 private double estimatedP;
6201
6202 /**
6203 * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
6204 * the better the fit that has been estimated.
6205 */
6206 private double estimatedQ;
6207 }
6208 }