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