1 /*
2 * Copyright (C) 2021 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;
17
18 import com.irurueta.algebra.AlgebraException;
19 import com.irurueta.algebra.Matrix;
20 import com.irurueta.geometry.InvalidRotationMatrixException;
21 import com.irurueta.geometry.Quaternion;
22 import com.irurueta.geometry.Rotation3D;
23 import com.irurueta.navigation.LockedException;
24 import com.irurueta.navigation.NotReadyException;
25 import com.irurueta.navigation.frames.CoordinateTransformation;
26 import com.irurueta.navigation.frames.ECEFFrame;
27 import com.irurueta.navigation.frames.ECEFPosition;
28 import com.irurueta.navigation.frames.ECEFVelocity;
29 import com.irurueta.navigation.frames.InvalidSourceAndDestinationFrameTypeException;
30 import com.irurueta.navigation.frames.NEDFrame;
31 import com.irurueta.navigation.frames.NEDPosition;
32 import com.irurueta.navigation.frames.NEDVelocity;
33 import com.irurueta.navigation.frames.converters.ECEFtoNEDFrameConverter;
34 import com.irurueta.navigation.frames.converters.NEDtoECEFFrameConverter;
35 import com.irurueta.navigation.inertial.BodyKinematics;
36 import com.irurueta.navigation.inertial.navigators.ECEFInertialNavigator;
37 import com.irurueta.navigation.inertial.navigators.InertialNavigatorException;
38 import com.irurueta.units.Acceleration;
39 import com.irurueta.units.AccelerationUnit;
40 import com.irurueta.units.Angle;
41 import com.irurueta.units.AngleUnit;
42 import com.irurueta.units.AngularSpeed;
43 import com.irurueta.units.AngularSpeedUnit;
44 import com.irurueta.units.Distance;
45 import com.irurueta.units.DistanceUnit;
46 import com.irurueta.units.Speed;
47 import com.irurueta.units.SpeedUnit;
48 import com.irurueta.units.Time;
49 import com.irurueta.units.TimeConverter;
50 import com.irurueta.units.TimeUnit;
51
52 /**
53 * Estimates accumulated drift in body orientation, position and velocity per
54 * unit of time.
55 * This estimator must be executed while the body where the IMU is placed remains
56 * static.
57 */
58 public class DriftEstimator {
59
60 /**
61 * Default time interval between kinematics samples expressed in seconds (s).
62 */
63 public static final double DEFAULT_TIME_INTERVAL_SECONDS = 0.02;
64
65 /**
66 * Indicates whether this estimator is running.
67 */
68 protected boolean running;
69
70 /**
71 * Number of processed body kinematics samples.
72 */
73 protected int numberOfProcessedSamples;
74
75 /**
76 * Time interval expressed in seconds (s) between body kinematics samples.
77 */
78 protected double timeInterval = DEFAULT_TIME_INTERVAL_SECONDS;
79
80 /**
81 * Fixes body kinematics measurements using accelerometer and gyroscope
82 * calibration data to fix measurements.
83 */
84 protected final BodyKinematicsFixer fixer = new BodyKinematicsFixer();
85
86 /**
87 * Instance containing the last fixed body kinematics to be reused.
88 */
89 protected final BodyKinematics fixedKinematics = new BodyKinematics();
90
91 /**
92 * Indicates whether measured kinematics must be fixed or not.
93 * When enabled, provided calibration data is used; otherwise it is
94 * ignored.
95 * By default, this is enabled.
96 */
97 protected boolean fixKinematics = true;
98
99 /**
100 * Listener to handle events raised by this estimator.
101 */
102 protected DriftEstimatorListener listener;
103
104 /**
105 * Initial frame containing body position, velocity and orientation expressed
106 * in ECEF coordinates before starting drift estimation.
107 */
108 protected ECEFFrame referenceFrame;
109
110 /**
111 * Contains the current frame after one navigation step.
112 * This is reused for efficiency.
113 */
114 protected final ECEFFrame frame = new ECEFFrame();
115
116 /**
117 * Contains orientation of a reference frame.
118 * This is reused for efficiency.
119 */
120 protected final Quaternion refQ = new Quaternion();
121
122 /**
123 * Contains orientation inverse of the reference frame.
124 * This is reused for efficiency.
125 */
126 protected final Quaternion invRefQ = new Quaternion();
127
128 /**
129 * Contains current frame orientation drift.
130 * This is reused for efficiency.
131 */
132 protected final Quaternion q = new Quaternion();
133
134 /**
135 * Contains current position drift.
136 */
137 protected final ECEFPosition currentPositionDrift = new ECEFPosition();
138
139 /**
140 * Contains current velocity drift.
141 */
142 protected final ECEFVelocity currentVelocityDrift = new ECEFVelocity();
143
144 /**
145 * Contains current orientation expressed as a 3D rotation matrix.
146 */
147 protected Matrix currentC;
148
149 /**
150 * Current position drift expressed in meters (m).
151 */
152 protected double currentPositionDriftMeters;
153
154 /**
155 * Current velocity drift expressed in meters per second (m/s).
156 */
157 protected double currentVelocityDriftMetersPerSecond;
158
159 /**
160 * Current orientation drift expressed in radians (rad).
161 */
162 protected double currentOrientationDriftRadians;
163
164 /**
165 * Constructor.
166 */
167 public DriftEstimator() {
168 }
169
170 /**
171 * Constructor.
172 *
173 * @param listener listener to handle events.
174 */
175 public DriftEstimator(final DriftEstimatorListener listener) {
176 this.listener = listener;
177 }
178
179 /**
180 * Constructor.
181 *
182 * @param referenceFrame initial frame containing body position, velocity and
183 * orientation expressed in ECEF coordinates.
184 */
185 public DriftEstimator(final ECEFFrame referenceFrame) {
186 this.referenceFrame = referenceFrame;
187 }
188
189 /**
190 * Constructor.
191 *
192 * @param referenceFrame initial frame containing body position, velocity and
193 * orientation expressed in ECEF coordinates.
194 * @param listener listener to handle events.
195 */
196 public DriftEstimator(final ECEFFrame referenceFrame,
197 final DriftEstimatorListener listener) {
198 this.referenceFrame = referenceFrame;
199 this.listener = listener;
200 }
201
202 /**
203 * Constructor.
204 *
205 * @param referenceFrame initial frame containing body position, velocity and
206 * orientation expressed in NED coordinates.
207 */
208 public DriftEstimator(final NEDFrame referenceFrame) {
209 try {
210 setReferenceNedFrame(referenceFrame);
211 } catch (final LockedException ignore) {
212 // never happens
213 }
214 }
215
216 /**
217 * Constructor.
218 *
219 * @param referenceFrame initial frame containing body position, velocity and
220 * orientation expressed in NED coordinates.
221 * @param listener listener to handle events.
222 */
223 public DriftEstimator(final NEDFrame referenceFrame,
224 final DriftEstimatorListener listener) {
225 this(referenceFrame);
226 this.listener = listener;
227 }
228
229 /**
230 * Constructor.
231 *
232 * @param ba acceleration bias to be set.
233 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
234 * @param bg angular speed bias to be set.
235 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
236 * @throws AlgebraException if provided cross-coupling matrices cannot
237 * be inverted.
238 * @throws IllegalArgumentException if any provided matrices are not 3x3.
239 */
240 public DriftEstimator(final AccelerationTriad ba,
241 final Matrix ma,
242 final AngularSpeedTriad bg,
243 final Matrix mg) throws AlgebraException {
244 try {
245 setAccelerationBias(ba);
246 setAccelerationCrossCouplingErrors(ma);
247 setAngularSpeedBias(bg);
248 setAngularSpeedCrossCouplingErrors(mg);
249 } catch (final LockedException ignore) {
250 // never happens
251 }
252 }
253
254 /**
255 * Constructor.
256 *
257 * @param ba acceleration bias to be set.
258 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
259 * @param bg angular speed bias to be set.
260 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
261 * @param listener listener to handle events.
262 * @throws AlgebraException if provided cross-coupling matrices cannot
263 * be inverted.
264 * @throws IllegalArgumentException if any provided matrices are not 3x3.
265 */
266 public DriftEstimator(
267 final AccelerationTriad ba,
268 final Matrix ma,
269 final AngularSpeedTriad bg,
270 final Matrix mg,
271 final DriftEstimatorListener listener) throws AlgebraException {
272 this(ba, ma, bg, mg);
273 this.listener = listener;
274 }
275
276 /**
277 * Constructor.
278 *
279 * @param ba acceleration bias to be set.
280 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
281 * @param bg angular speed bias to be set.
282 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
283 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
284 * @throws AlgebraException if provided cross-coupling matrices cannot
285 * be inverted.
286 * @throws IllegalArgumentException if any provided matrices are not 3x3.
287 */
288 public DriftEstimator(
289 final AccelerationTriad ba,
290 final Matrix ma,
291 final AngularSpeedTriad bg,
292 final Matrix mg,
293 final Matrix gg) throws AlgebraException {
294 this(ba, ma, bg, mg);
295 try {
296 setAngularSpeedGDependantCrossBias(gg);
297 } catch (final LockedException ignore) {
298 // never happens
299 }
300 }
301
302 /**
303 * Constructor.
304 *
305 * @param ba acceleration bias to be set.
306 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
307 * @param bg angular speed bias to be set.
308 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
309 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
310 * @param listener listener to handle events.
311 * @throws AlgebraException if provided cross-coupling matrices cannot
312 * be inverted.
313 * @throws IllegalArgumentException if any provided matrices are not 3x3.
314 */
315 public DriftEstimator(
316 final AccelerationTriad ba,
317 final Matrix ma,
318 final AngularSpeedTriad bg,
319 final Matrix mg,
320 final Matrix gg,
321 final DriftEstimatorListener listener) throws AlgebraException {
322 this(ba, ma, bg, mg, gg);
323 this.listener = listener;
324 }
325
326 /**
327 * Constructor.
328 *
329 * @param ba acceleration bias to be set expressed in meters per squared second
330 * (m/s`2). Must be 3x1.
331 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
332 * @param bg angular speed bias to be set expressed in radians per second
333 * (rad/s). Must be 3x1.
334 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
335 * @throws AlgebraException if provided cross-coupling matrices cannot
336 * be inverted.
337 * @throws IllegalArgumentException if any provided matrices are not 3x3.
338 */
339 public DriftEstimator(
340 final Matrix ba,
341 final Matrix ma,
342 final Matrix bg,
343 final Matrix mg) throws AlgebraException {
344 try {
345 setAccelerationBias(ba);
346 setAccelerationCrossCouplingErrors(ma);
347 setAngularSpeedBias(bg);
348 setAngularSpeedCrossCouplingErrors(mg);
349 } catch (final LockedException ignore) {
350 // never happens
351 }
352 }
353
354 /**
355 * Constructor.
356 *
357 * @param ba acceleration bias to be set expressed in meters per squared second
358 * (m/s`2). Must be 3x1.
359 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
360 * @param bg angular speed bias to be set expressed in radians per second
361 * (rad/s). Must be 3x1.
362 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
363 * @param listener listener to handle events.
364 * @throws AlgebraException if provided cross-coupling matrices cannot
365 * be inverted.
366 * @throws IllegalArgumentException if any provided matrices are not 3x3.
367 */
368 public DriftEstimator(
369 final Matrix ba,
370 final Matrix ma,
371 final Matrix bg,
372 final Matrix mg,
373 final DriftEstimatorListener listener) throws AlgebraException {
374 this(ba, ma, bg, mg);
375 this.listener = listener;
376 }
377
378 /**
379 * Constructor.
380 *
381 * @param ba acceleration bias to be set expressed in meters per squared second
382 * (m/s`2). Must be 3x1.
383 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
384 * @param bg angular speed bias to be set expressed in radians per second
385 * (rad/s). Must be 3x1.
386 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
387 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
388 * @throws AlgebraException if provided cross-coupling matrices cannot
389 * be inverted.
390 * @throws IllegalArgumentException if any provided matrices are not 3x3.
391 */
392 public DriftEstimator(
393 final Matrix ba,
394 final Matrix ma,
395 final Matrix bg,
396 final Matrix mg,
397 final Matrix gg) throws AlgebraException {
398 this(ba, ma, bg, mg);
399 try {
400 setAngularSpeedGDependantCrossBias(gg);
401 } catch (final LockedException ignore) {
402 // never happens
403 }
404 }
405
406 /**
407 * Constructor.
408 *
409 * @param ba acceleration bias to be set expressed in meters per squared second
410 * (m/s`2). Must be 3x1.
411 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
412 * @param bg angular speed bias to be set expressed in radians per second
413 * (rad/s). Must be 3x1.
414 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
415 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
416 * @param listener listener to handle events.
417 * @throws AlgebraException if provided cross-coupling matrices cannot
418 * be inverted.
419 * @throws IllegalArgumentException if any provided matrices are not 3x3.
420 */
421 public DriftEstimator(
422 final Matrix ba,
423 final Matrix ma,
424 final Matrix bg,
425 final Matrix mg,
426 final Matrix gg,
427 final DriftEstimatorListener listener) throws AlgebraException {
428 this(ba, ma, bg, mg, gg);
429 this.listener = listener;
430 }
431
432 /**
433 * Constructor.
434 *
435 * @param referenceFrame initial frame containing body position, velocity and
436 * orientation expressed in ECEF coordinates.
437 * @param ba acceleration bias to be set.
438 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
439 * @param bg angular speed bias to be set.
440 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
441 * @throws AlgebraException if provided cross-coupling matrices cannot
442 * be inverted.
443 * @throws IllegalArgumentException if any provided matrices are not 3x3.
444 */
445 public DriftEstimator(final ECEFFrame referenceFrame,
446 final AccelerationTriad ba,
447 final Matrix ma,
448 final AngularSpeedTriad bg,
449 final Matrix mg) throws AlgebraException {
450 this(ba, ma, bg, mg);
451 this.referenceFrame = referenceFrame;
452 }
453
454 /**
455 * Constructor.
456 *
457 * @param referenceFrame initial frame containing body position, velocity and
458 * orientation expressed in ECEF coordinates.
459 * @param ba acceleration bias to be set.
460 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
461 * @param bg angular speed bias to be set.
462 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
463 * @param listener listener to handle events.
464 * @throws AlgebraException if provided cross-coupling matrices cannot
465 * be inverted.
466 * @throws IllegalArgumentException if any provided matrices are not 3x3.
467 */
468 public DriftEstimator(
469 final ECEFFrame referenceFrame,
470 final AccelerationTriad ba,
471 final Matrix ma,
472 final AngularSpeedTriad bg,
473 final Matrix mg,
474 final DriftEstimatorListener listener) throws AlgebraException {
475 this(ba, ma, bg, mg, listener);
476 this.referenceFrame = referenceFrame;
477 }
478
479 /**
480 * Constructor.
481 *
482 * @param referenceFrame initial frame containing body position, velocity and
483 * orientation expressed in ECEF coordinates.
484 * @param ba acceleration bias to be set.
485 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
486 * @param bg angular speed bias to be set.
487 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
488 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
489 * @throws AlgebraException if provided cross-coupling matrices cannot
490 * be inverted.
491 * @throws IllegalArgumentException if any provided matrices are not 3x3.
492 */
493 public DriftEstimator(
494 final ECEFFrame referenceFrame,
495 final AccelerationTriad ba,
496 final Matrix ma,
497 final AngularSpeedTriad bg,
498 final Matrix mg,
499 final Matrix gg) throws AlgebraException {
500 this(ba, ma, bg, mg, gg);
501 this.referenceFrame = referenceFrame;
502 }
503
504 /**
505 * Constructor.
506 *
507 * @param referenceFrame initial frame containing body position, velocity and
508 * orientation expressed in ECEF coordinates.
509 * @param ba acceleration bias to be set.
510 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
511 * @param bg angular speed bias to be set.
512 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
513 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
514 * @param listener listener to handle events.
515 * @throws AlgebraException if provided cross-coupling matrices cannot
516 * be inverted.
517 * @throws IllegalArgumentException if any provided matrices are not 3x3.
518 */
519 public DriftEstimator(
520 final ECEFFrame referenceFrame,
521 final AccelerationTriad ba,
522 final Matrix ma,
523 final AngularSpeedTriad bg,
524 final Matrix mg,
525 final Matrix gg,
526 final DriftEstimatorListener listener) throws AlgebraException {
527 this(ba, ma, bg, mg, gg, listener);
528 this.referenceFrame = referenceFrame;
529 }
530
531 /**
532 * Constructor.
533 *
534 * @param referenceFrame initial frame containing body position, velocity and
535 * orientation expressed in ECEF coordinates.
536 * @param ba acceleration bias to be set expressed in meters per squared second
537 * (m/s`2). Must be 3x1.
538 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
539 * @param bg angular speed bias to be set expressed in radians per second
540 * (rad/s). Must be 3x1.
541 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
542 * @throws AlgebraException if provided cross-coupling matrices cannot
543 * be inverted.
544 * @throws IllegalArgumentException if any provided matrices are not 3x3.
545 */
546 public DriftEstimator(
547 final ECEFFrame referenceFrame,
548 final Matrix ba,
549 final Matrix ma,
550 final Matrix bg,
551 final Matrix mg) throws AlgebraException {
552 this(ba, ma, bg, mg);
553 this.referenceFrame = referenceFrame;
554 }
555
556 /**
557 * Constructor.
558 *
559 * @param referenceFrame initial frame containing body position, velocity and
560 * orientation expressed in ECEF coordinates.
561 * @param ba acceleration bias to be set expressed in meters per squared second
562 * (m/s`2). Must be 3x1.
563 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
564 * @param bg angular speed bias to be set expressed in radians per second
565 * (rad/s). Must be 3x1.
566 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
567 * @param listener listener to handle events.
568 * @throws AlgebraException if provided cross-coupling matrices cannot
569 * be inverted.
570 * @throws IllegalArgumentException if any provided matrices are not 3x3.
571 */
572 public DriftEstimator(
573 final ECEFFrame referenceFrame,
574 final Matrix ba,
575 final Matrix ma,
576 final Matrix bg,
577 final Matrix mg,
578 final DriftEstimatorListener listener) throws AlgebraException {
579 this(ba, ma, bg, mg, listener);
580 this.referenceFrame = referenceFrame;
581 }
582
583 /**
584 * Constructor.
585 *
586 * @param referenceFrame initial frame containing body position, velocity and
587 * orientation expressed in ECEF coordinates.
588 * @param ba acceleration bias to be set expressed in meters per squared second
589 * (m/s`2). Must be 3x1.
590 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
591 * @param bg angular speed bias to be set expressed in radians per second
592 * (rad/s). Must be 3x1.
593 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
594 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
595 * @throws AlgebraException if provided cross-coupling matrices cannot
596 * be inverted.
597 * @throws IllegalArgumentException if any provided matrices are not 3x3.
598 */
599 public DriftEstimator(
600 final ECEFFrame referenceFrame,
601 final Matrix ba,
602 final Matrix ma,
603 final Matrix bg,
604 final Matrix mg,
605 final Matrix gg) throws AlgebraException {
606 this(ba, ma, bg, mg, gg);
607 this.referenceFrame = referenceFrame;
608 }
609
610 /**
611 * Constructor.
612 *
613 * @param referenceFrame initial frame containing body position, velocity and
614 * orientation expressed in ECEF coordinates.
615 * @param ba acceleration bias to be set expressed in meters per squared second
616 * (m/s`2). Must be 3x1.
617 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
618 * @param bg angular speed bias to be set expressed in radians per second
619 * (rad/s). Must be 3x1.
620 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
621 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
622 * @param listener listener to handle events.
623 * @throws AlgebraException if provided cross-coupling matrices cannot
624 * be inverted.
625 * @throws IllegalArgumentException if any provided matrices are not 3x3.
626 */
627 public DriftEstimator(
628 final ECEFFrame referenceFrame,
629 final Matrix ba,
630 final Matrix ma,
631 final Matrix bg,
632 final Matrix mg,
633 final Matrix gg,
634 final DriftEstimatorListener listener) throws AlgebraException {
635 this(ba, ma, bg, mg, gg, listener);
636 this.referenceFrame = referenceFrame;
637 }
638
639 /**
640 * Constructor.
641 *
642 * @param referenceFrame initial frame containing body position, velocity and
643 * orientation expressed in NED coordinates.
644 * @param ba acceleration bias to be set.
645 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
646 * @param bg angular speed bias to be set.
647 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
648 * @throws AlgebraException if provided cross-coupling matrices cannot
649 * be inverted.
650 * @throws IllegalArgumentException if any provided matrices are not 3x3.
651 */
652 public DriftEstimator(final NEDFrame referenceFrame,
653 final AccelerationTriad ba,
654 final Matrix ma,
655 final AngularSpeedTriad bg,
656 final Matrix mg) throws AlgebraException {
657 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg);
658 }
659
660 /**
661 * Constructor.
662 *
663 * @param referenceFrame initial frame containing body position, velocity and
664 * orientation expressed in NED coordinates.
665 * @param ba acceleration bias to be set.
666 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
667 * @param bg angular speed bias to be set.
668 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
669 * @param listener listener to handle events.
670 * @throws AlgebraException if provided cross-coupling matrices cannot
671 * be inverted.
672 * @throws IllegalArgumentException if any provided matrices are not 3x3.
673 */
674 public DriftEstimator(
675 final NEDFrame referenceFrame,
676 final AccelerationTriad ba,
677 final Matrix ma,
678 final AngularSpeedTriad bg,
679 final Matrix mg,
680 final DriftEstimatorListener listener) throws AlgebraException {
681 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, listener);
682 }
683
684 /**
685 * Constructor.
686 *
687 * @param referenceFrame initial frame containing body position, velocity and
688 * orientation expressed in NED coordinates.
689 * @param ba acceleration bias to be set.
690 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
691 * @param bg angular speed bias to be set.
692 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
693 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
694 * @throws AlgebraException if provided cross-coupling matrices cannot
695 * be inverted.
696 * @throws IllegalArgumentException if any provided matrices are not 3x3.
697 */
698 public DriftEstimator(
699 final NEDFrame referenceFrame,
700 final AccelerationTriad ba,
701 final Matrix ma,
702 final AngularSpeedTriad bg,
703 final Matrix mg,
704 final Matrix gg) throws AlgebraException {
705 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, gg);
706 }
707
708 /**
709 * Constructor.
710 *
711 * @param referenceFrame initial frame containing body position, velocity and
712 * orientation expressed in NED coordinates.
713 * @param ba acceleration bias to be set.
714 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
715 * @param bg angular speed bias to be set.
716 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
717 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
718 * @param listener listener to handle events.
719 * @throws AlgebraException if provided cross-coupling matrices cannot
720 * be inverted.
721 * @throws IllegalArgumentException if any provided matrices are not 3x3.
722 */
723 public DriftEstimator(
724 final NEDFrame referenceFrame,
725 final AccelerationTriad ba,
726 final Matrix ma,
727 final AngularSpeedTriad bg,
728 final Matrix mg,
729 final Matrix gg,
730 final DriftEstimatorListener listener) throws AlgebraException {
731 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, gg, listener);
732 }
733
734 /**
735 * Constructor.
736 *
737 * @param referenceFrame initial frame containing body position, velocity and
738 * orientation expressed in NED coordinates.
739 * @param ba acceleration bias to be set expressed in meters per squared second
740 * (m/s`2). Must be 3x1.
741 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
742 * @param bg angular speed bias to be set expressed in radians per second
743 * (rad/s). Must be 3x1.
744 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
745 * @throws AlgebraException if provided cross-coupling matrices cannot
746 * be inverted.
747 * @throws IllegalArgumentException if any provided matrices are not 3x3.
748 */
749 public DriftEstimator(
750 final NEDFrame referenceFrame,
751 final Matrix ba,
752 final Matrix ma,
753 final Matrix bg,
754 final Matrix mg) throws AlgebraException {
755 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg);
756 }
757
758 /**
759 * Constructor.
760 *
761 * @param referenceFrame initial frame containing body position, velocity and
762 * orientation expressed in NED coordinates.
763 * @param ba acceleration bias to be set expressed in meters per squared second
764 * (m/s`2). Must be 3x1.
765 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
766 * @param bg angular speed bias to be set expressed in radians per second
767 * (rad/s). Must be 3x1.
768 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
769 * @param listener listener to handle events.
770 * @throws AlgebraException if provided cross-coupling matrices cannot
771 * be inverted.
772 * @throws IllegalArgumentException if any provided matrices are not 3x3.
773 */
774 public DriftEstimator(
775 final NEDFrame referenceFrame,
776 final Matrix ba,
777 final Matrix ma,
778 final Matrix bg,
779 final Matrix mg,
780 final DriftEstimatorListener listener) throws AlgebraException {
781 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, listener);
782 }
783
784 /**
785 * Constructor.
786 *
787 * @param referenceFrame initial frame containing body position, velocity and
788 * orientation expressed in NED coordinates.
789 * @param ba acceleration bias to be set expressed in meters per squared second
790 * (m/s`2). Must be 3x1.
791 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
792 * @param bg angular speed bias to be set expressed in radians per second
793 * (rad/s). Must be 3x1.
794 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
795 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
796 * @throws AlgebraException if provided cross-coupling matrices cannot
797 * be inverted.
798 * @throws IllegalArgumentException if any provided matrices are not 3x3.
799 */
800 public DriftEstimator(
801 final NEDFrame referenceFrame,
802 final Matrix ba,
803 final Matrix ma,
804 final Matrix bg,
805 final Matrix mg,
806 final Matrix gg) throws AlgebraException {
807 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, gg);
808 }
809
810 /**
811 * Constructor.
812 *
813 * @param referenceFrame initial frame containing body position, velocity and
814 * orientation expressed in ECEF coordinates.
815 * @param ba acceleration bias to be set expressed in meters per squared second
816 * (m/s`2). Must be 3x1.
817 * @param ma acceleration cross-coupling errors matrix. Must be 3x3.
818 * @param bg angular speed bias to be set expressed in radians per second
819 * (rad/s). Must be 3x1.
820 * @param mg angular speed cross-coupling errors matrix. Must be 3x3.
821 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3.
822 * @param listener listener to handle events.
823 * @throws AlgebraException if provided cross-coupling matrices cannot
824 * be inverted.
825 * @throws IllegalArgumentException if any provided matrices are not 3x3.
826 */
827 public DriftEstimator(
828 final NEDFrame referenceFrame,
829 final Matrix ba,
830 final Matrix ma,
831 final Matrix bg,
832 final Matrix mg,
833 final Matrix gg,
834 final DriftEstimatorListener listener) throws AlgebraException {
835 this(NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceFrame), ba, ma, bg, mg, gg, listener);
836 }
837
838 /**
839 * Gets listener to handle events raised by this estimator.
840 *
841 * @return listener to handle events raised by this estimator.
842 */
843 public DriftEstimatorListener getListener() {
844 return listener;
845 }
846
847 /**
848 * Sets listener to handle events raised by this estimator.
849 *
850 * @param listener listener to handle events raised by this estimator.
851 * @throws LockedException if estimator is running.
852 */
853 public void setListener(final DriftEstimatorListener listener) throws LockedException {
854 if (running) {
855 throw new LockedException();
856 }
857
858 this.listener = listener;
859 }
860
861 /**
862 * Gets initial frame containing body position, velocity and orientation
863 * expressed in ECEF coordinates before starting drift estimation.
864 *
865 * @return initial body frame or null.
866 */
867 public ECEFFrame getReferenceFrame() {
868 return referenceFrame;
869 }
870
871 /**
872 * Sets initial frame containing body position, velocity and orientation
873 * expressed in ECEF coordinates before starting drift estimation.
874 *
875 * @param referenceFrame initial frame or null.
876 * @throws LockedException if estimator is already running.
877 */
878 public void setReferenceFrame(final ECEFFrame referenceFrame) throws LockedException {
879 if (running) {
880 throw new LockedException();
881 }
882 this.referenceFrame = referenceFrame;
883 }
884
885 /**
886 * Gets initial frame containing body position, velocity and orientation
887 * expressed in NED coordinates before starting drift estimation.
888 *
889 * @return initial body frame or null.
890 */
891 public NEDFrame getReferenceNedFrame() {
892 return referenceFrame != null
893 ? ECEFtoNEDFrameConverter.convertECEFtoNEDAndReturnNew(referenceFrame)
894 : null;
895 }
896
897 /**
898 * Gets initial frame containing body position, velocity and orientation
899 * expressed in NED coordinates before starting drift estimation.
900 *
901 * @param result instance where the result will be stored.
902 * @return true if the initial frame was available and the result was updated, false
903 * otherwise.
904 * @throws NullPointerException if provided result instance is null.
905 */
906 public boolean getReferenceNedFrame(final NEDFrame result) {
907 if (referenceFrame != null) {
908 ECEFtoNEDFrameConverter.convertECEFtoNED(referenceFrame, result);
909 return true;
910 } else {
911 return false;
912 }
913 }
914
915 /**
916 * Sets an initial frame containing body position, velocity and orientation
917 * expressed in NED coordinates before starting drift estimation.
918 *
919 * @param referenceNedFrame initial body frame or null.
920 * @throws LockedException if estimator is already running.
921 */
922 public void setReferenceNedFrame(final NEDFrame referenceNedFrame) throws LockedException {
923 if (running) {
924 throw new LockedException();
925 }
926
927 if (referenceNedFrame != null) {
928 if (referenceFrame != null) {
929 NEDtoECEFFrameConverter.convertNEDtoECEF(referenceNedFrame, referenceFrame);
930 } else {
931 referenceFrame = NEDtoECEFFrameConverter.convertNEDtoECEFAndReturnNew(referenceNedFrame);
932 }
933 } else {
934 referenceFrame = null;
935 }
936 }
937
938 /**
939 * Gets initial body position, expressed in ECEF coordinates, before starting
940 * drift estimation.
941 *
942 * @return initial body position or null.
943 */
944 public ECEFPosition getReferenceEcefPosition() {
945 return referenceFrame != null ? referenceFrame.getECEFPosition() : null;
946 }
947
948 /**
949 * Gets initial body position, expressed in ECEF coordinates, before starting
950 * drift estimation.
951 *
952 * @param result instance where the result will be stored.
953 * @return true if the initial body position was available and the result was updated,
954 * false otherwise.
955 * @throws NullPointerException if provided result instance is null.
956 */
957 public boolean getReferenceEcefPosition(final ECEFPosition result) {
958 if (referenceFrame != null) {
959 referenceFrame.getECEFPosition(result);
960 return true;
961 } else {
962 return false;
963 }
964 }
965
966 /**
967 * Sets initial body position, expressed in ECEF coordinates, before starting
968 * drift estimation.
969 *
970 * @param referenceEcefPosition initial body position.
971 * @throws LockedException if estimator is already running.
972 * @throws NullPointerException if provided position is null.
973 */
974 public void setReferenceEcefPosition(final ECEFPosition referenceEcefPosition) throws LockedException {
975 if (running) {
976 throw new LockedException();
977 }
978
979 if (referenceFrame != null) {
980 referenceFrame.setPosition(referenceEcefPosition);
981 } else {
982 referenceFrame = new ECEFFrame(referenceEcefPosition);
983 }
984 }
985
986 /**
987 * Gets initial body velocity, expressed in ECEF coordinates, before starting
988 * drift estimation.
989 *
990 * @return initial body velocity or null.
991 */
992 public ECEFVelocity getReferenceEcefVelocity() {
993 return referenceFrame != null ? referenceFrame.getECEFVelocity() : null;
994 }
995
996 /**
997 * Gets initial body velocity, expressed in ECEF coordinates, before starting
998 * drift estimation.
999 *
1000 * @param result instance where the result will be stored.
1001 * @return true if initial body velocity was available and the result was updated,
1002 * false otherwise.
1003 * @throws NullPointerException if provided result instance is null.
1004 */
1005 public boolean getReferenceEcefVelocity(final ECEFVelocity result) {
1006 if (referenceFrame != null) {
1007 referenceFrame.getECEFVelocity(result);
1008 return true;
1009 } else {
1010 return false;
1011 }
1012 }
1013
1014 /**
1015 * Sets initial body velocity, expressed in ECEF coordinates, before starting
1016 * drift estimation.
1017 *
1018 * @param referenceEcefVelocity initial body velocity.
1019 * @throws LockedException if estimator is already running.
1020 * @throws NullPointerException if velocity is null.
1021 */
1022 public void setReferenceEcefVelocity(final ECEFVelocity referenceEcefVelocity) throws LockedException {
1023 if (running) {
1024 throw new LockedException();
1025 }
1026
1027 if (referenceFrame == null) {
1028 referenceFrame = new ECEFFrame();
1029 }
1030
1031 referenceFrame.setVelocity(referenceEcefVelocity);
1032 }
1033
1034 /**
1035 * Gets initial body coordinate transformation, containing body orientation
1036 * expressed in ECEF coordinates, before starting estimation.
1037 *
1038 * @return initial body orientation or null.
1039 */
1040 public CoordinateTransformation getReferenceEcefCoordinateTransformation() {
1041 return referenceFrame != null ?
1042 referenceFrame.getCoordinateTransformation() : null;
1043 }
1044
1045 /**
1046 * Gets initial body coordinate transformation, containing body orientation
1047 * expressed in ECEF coordinates, before starting estimation.
1048 *
1049 * @param result instance where the result will be stored.
1050 * @return true if initial body orientation was available and a result was
1051 * updated, false otherwise.
1052 * @throws NullPointerException if provided result instance is null.
1053 */
1054 public boolean getReferenceEcefCoordinateTransformation(final CoordinateTransformation result) {
1055 if (referenceFrame != null) {
1056 referenceFrame.getCoordinateTransformation(result);
1057 return true;
1058 } else {
1059 return false;
1060 }
1061 }
1062
1063 /**
1064 * Sets initial body coordinate transformation, containing body orientation
1065 * expressed in ECEF coordinates, before starting estimation.
1066 *
1067 * @param referenceEcefCoordinateTransformation initial body orientation.
1068 * @throws LockedException if estimator is already running.
1069 * @throws InvalidSourceAndDestinationFrameTypeException if source and
1070 * destination types are invalid. Source type must be
1071 * {@link com.irurueta.navigation.frames.FrameType#BODY_FRAME} and the destination
1072 * type must be {@link com.irurueta.navigation.frames.FrameType#EARTH_CENTERED_EARTH_FIXED_FRAME}
1073 * indicating that body orientation is expressed respect ECEF coordinates.
1074 * @throws NullPointerException if orientation is null.
1075 */
1076 public void setReferenceEcefCoordinateTransformation(
1077 final CoordinateTransformation referenceEcefCoordinateTransformation) throws LockedException,
1078 InvalidSourceAndDestinationFrameTypeException {
1079 if (running) {
1080 throw new LockedException();
1081 }
1082
1083 if (referenceFrame == null) {
1084 referenceFrame = new ECEFFrame(referenceEcefCoordinateTransformation);
1085 } else {
1086 referenceFrame.setCoordinateTransformation(referenceEcefCoordinateTransformation);
1087 }
1088 }
1089
1090 /**
1091 * Gets initial body position, expressed in NED coordinates, before starting
1092 * drift estimation.
1093 *
1094 * @return initial body position or null.
1095 */
1096 public NEDPosition getReferenceNedPosition() {
1097 final var nedFrame = getReferenceNedFrame();
1098 return nedFrame != null ? nedFrame.getPosition() : null;
1099 }
1100
1101 /**
1102 * Gets initial body position, expressed in NED coordinates, before starting
1103 * drift estimation.
1104 *
1105 * @param result instance where the result will be stored.
1106 * @return true if the initial body position was available and the result was updated,
1107 * false otherwise.
1108 * @throws NullPointerException if provided result instance is null.
1109 */
1110 public boolean getReferenceNedPosition(final NEDPosition result) {
1111 if (referenceFrame != null) {
1112 final var nedFrame = getReferenceNedFrame();
1113 nedFrame.getPosition(result);
1114 return true;
1115 } else {
1116 return false;
1117 }
1118 }
1119
1120 /**
1121 * Sets initial body position, expressed in NED coordinates, before starting
1122 * drift estimation.
1123 *
1124 * @param referenceNedPosition initial body position.
1125 * @throws LockedException if estimator is already running.
1126 * @throws NullPointerException if provided position is null.
1127 */
1128 public void setReferenceNedPosition(final NEDPosition referenceNedPosition) throws LockedException {
1129 if (running) {
1130 throw new LockedException();
1131 }
1132
1133 if (referenceFrame != null) {
1134 final var nedFrame = getReferenceNedFrame();
1135 nedFrame.setPosition(referenceNedPosition);
1136 setReferenceNedFrame(nedFrame);
1137 } else {
1138 setReferenceNedFrame(new NEDFrame(referenceNedPosition));
1139 }
1140 }
1141
1142 /**
1143 * Gets initial body velocity, expressed in NED coordinates, before starting
1144 * drift estimation.
1145 *
1146 * @return initial body velocity or null.
1147 */
1148 public NEDVelocity getReferenceNedVelocity() {
1149 final var nedFrame = getReferenceNedFrame();
1150 return nedFrame != null ? nedFrame.getVelocity() : null;
1151 }
1152
1153 /**
1154 * Gets initial body velocity, expressed in NED coordinates, before starting
1155 * drift estimation.
1156 *
1157 * @param result instance where the result will be stored.
1158 * @return true if initial body velocity was available and the result was updated,
1159 * false otherwise.
1160 * @throws NullPointerException if provided result instance is null.
1161 */
1162 public boolean getReferenceNedVelocity(final NEDVelocity result) {
1163 if (referenceFrame != null) {
1164 final var nedFrame = getReferenceNedFrame();
1165 nedFrame.getVelocity(result);
1166 return true;
1167 } else {
1168 return false;
1169 }
1170 }
1171
1172 /**
1173 * Sets initial body velocity, expressed in NED coordinates, before starting
1174 * drift estimation.
1175 *
1176 * @param referenceNedVelocity initial body velocity.
1177 * @throws LockedException if estimator is already running.
1178 * @throws NullPointerException if velocity is null.
1179 */
1180 public void setReferenceNedVelocity(final NEDVelocity referenceNedVelocity) throws LockedException {
1181 if (running) {
1182 throw new LockedException();
1183 }
1184
1185 final NEDFrame nedFrame;
1186 if (referenceFrame != null) {
1187 nedFrame = getReferenceNedFrame();
1188 } else {
1189 nedFrame = new NEDFrame();
1190 }
1191
1192 nedFrame.setVelocity(referenceNedVelocity);
1193 setReferenceNedFrame(nedFrame);
1194 }
1195
1196 /**
1197 * Gets initial body coordinate transformation, containing body orientation
1198 * expressed in NED coordinates, before starting estimation.
1199 *
1200 * @return initial body orientation or null.
1201 */
1202 public CoordinateTransformation getReferenceNedCoordinateTransformation() {
1203 final var nedFrame = getReferenceNedFrame();
1204 return nedFrame != null ? nedFrame.getCoordinateTransformation() : null;
1205 }
1206
1207 /**
1208 * Gets initial body coordinate transformation, containing body orientation
1209 * expressed in NED coordinates, before starting estimation.
1210 *
1211 * @param result instance where the result will be stored.
1212 * @return true if initial body orientation was available and the result was
1213 * updated, false otherwise.
1214 * @throws NullPointerException if provided result instance is null.
1215 */
1216 public boolean getReferenceNedCoordinateTransformation(final CoordinateTransformation result) {
1217 if (referenceFrame != null) {
1218 final var nedFrame = getReferenceNedFrame();
1219 nedFrame.getCoordinateTransformation(result);
1220 return true;
1221 } else {
1222 return false;
1223 }
1224 }
1225
1226 /**
1227 * Sets initial body coordinate transformation, containing body orientation
1228 * expressed in NED coordinates, before starting estimation.
1229 *
1230 * @param referenceNedCoordinateTransformation initial body orientation.
1231 * @throws LockedException if estimator is already running.
1232 * @throws InvalidSourceAndDestinationFrameTypeException if source and
1233 * destination types are invalid. Source type must be
1234 * {@link com.irurueta.navigation.frames.FrameType#BODY_FRAME} and the destination
1235 * type must be {@link com.irurueta.navigation.frames.FrameType#LOCAL_NAVIGATION_FRAME}
1236 * indicating that body orientation is expressed respect NED coordinates.
1237 * @throws NullPointerException if orientation is null.
1238 */
1239 public void setReferenceNedCoordinateTransformation(
1240 final CoordinateTransformation referenceNedCoordinateTransformation) throws LockedException,
1241 InvalidSourceAndDestinationFrameTypeException {
1242 if (running) {
1243 throw new LockedException();
1244 }
1245
1246 final NEDFrame nedFrame;
1247 if (referenceFrame == null) {
1248 nedFrame = new NEDFrame(referenceNedCoordinateTransformation);
1249 setReferenceNedFrame(nedFrame);
1250 } else {
1251 nedFrame = getReferenceNedFrame();
1252 nedFrame.setCoordinateTransformation(referenceNedCoordinateTransformation);
1253 }
1254 }
1255
1256 /**
1257 * Gets acceleration bias values expressed in meters per squared second (m/s^2).
1258 *
1259 * @return bias values expressed in meters per squared second.
1260 */
1261 public Matrix getAccelerationBias() {
1262 return fixer.getAccelerationBias();
1263 }
1264
1265 /**
1266 * Gets acceleration bias values expressed in meters per squared second (m/s^2).
1267 *
1268 * @param result instance where the result will be stored.
1269 */
1270 public void getAccelerationBias(final Matrix result) {
1271 fixer.getAccelerationBias(result);
1272 }
1273
1274 /**
1275 * Sets acceleration bias values expressed in meters per squared second (m/s^2).
1276 *
1277 * @param bias bias values expressed in meters per squared second.
1278 * Must be 3x1.
1279 * @throws LockedException if estimator is running.
1280 * @throws IllegalArgumentException if any provided matrix is not 3x1.
1281 */
1282 public void setAccelerationBias(final Matrix bias) throws LockedException {
1283 if (running) {
1284 throw new LockedException();
1285 }
1286
1287 fixer.setAccelerationBias(bias);
1288 }
1289
1290 /**
1291 * Gets acceleration bias values expressed in meters per squared second (m/s^2).
1292 *
1293 * @return bias values expressed in meters per squared second.
1294 */
1295 public double[] getAccelerationBiasArray() {
1296 return fixer.getAccelerationBiasArray();
1297 }
1298
1299 /**
1300 * Gets acceleration bias values expressed in meters per squared second (m/s^2).
1301 *
1302 * @param result instance where result data will be stored.
1303 * @throws IllegalArgumentException if provided array does not have length 3.
1304 */
1305 public void getAccelerationBiasArray(final double[] result) {
1306 fixer.getAccelerationBiasArray(result);
1307 }
1308
1309 /**
1310 * Sets acceleration bias values expressed in meters per squared second (m/s^2).
1311 *
1312 * @param bias bias values expressed in meters per squared second (m/s^2).
1313 * Must have length 3.
1314 * @throws IllegalArgumentException if provided array does not have length 3.
1315 * @throws LockedException if estimator is running.
1316 */
1317 public void setAccelerationBias(final double[] bias) throws LockedException {
1318 if (running) {
1319 throw new LockedException();
1320 }
1321
1322 fixer.setAccelerationBias(bias);
1323 }
1324
1325 /**
1326 * Gets acceleration bias.
1327 *
1328 * @return acceleration bias.
1329 */
1330 public AccelerationTriad getAccelerationBiasAsTriad() {
1331 return fixer.getAccelerationBiasAsTriad();
1332 }
1333
1334 /**
1335 * Gets acceleration bias.
1336 *
1337 * @param result instance where the result will be stored.
1338 */
1339 public void getAccelerationBiasAsTriad(final AccelerationTriad result) {
1340 fixer.getAccelerationBiasAsTriad(result);
1341 }
1342
1343 /**
1344 * Sets acceleration bias.
1345 *
1346 * @param bias acceleration bias to be set.
1347 * @throws LockedException if estimator is running.
1348 */
1349 public void setAccelerationBias(final AccelerationTriad bias) throws LockedException {
1350 if (running) {
1351 throw new LockedException();
1352 }
1353
1354 fixer.setAccelerationBias(bias);
1355 }
1356
1357 /**
1358 * Gets acceleration x-coordinate of bias expressed in meters per squared
1359 * second (m/s^2).
1360 *
1361 * @return x-coordinate of bias expressed in meters per squared second (m/s^2).
1362 */
1363 public double getAccelerationBiasX() {
1364 return fixer.getAccelerationBiasX();
1365 }
1366
1367 /**
1368 * Sets acceleration x-coordinate of bias expressed in meters per squared
1369 * second (m/s^2).
1370 *
1371 * @param biasX x-coordinate of bias expressed in meters per squared second
1372 * (m/s^2).
1373 * @throws LockedException if estimator is running.
1374 */
1375 public void setAccelerationBiasX(final double biasX) throws LockedException {
1376 if (running) {
1377 throw new LockedException();
1378 }
1379
1380 fixer.setAccelerationBiasX(biasX);
1381 }
1382
1383 /**
1384 * Gets acceleration y-coordinate of bias expressed in meters per squared
1385 * second (m/s^2).
1386 *
1387 * @return y-coordinate of bias expressed in meters per squared second (m/s^2).
1388 */
1389 public double getAccelerationBiasY() {
1390 return fixer.getAccelerationBiasY();
1391 }
1392
1393 /**
1394 * Sets acceleration y-coordinate of bias expressed in meters per squared
1395 * second (m/s^2).
1396 *
1397 * @param biasY y-coordinate of bias expressed in meters per squared second
1398 * (m/s^2).
1399 * @throws LockedException if estimator is running.
1400 */
1401 public void setAccelerationBiasY(final double biasY) throws LockedException {
1402 if (running) {
1403 throw new LockedException();
1404 }
1405
1406 fixer.setAccelerationBiasY(biasY);
1407 }
1408
1409 /**
1410 * Gets acceleration z-coordinate of bias expressed in meters per squared
1411 * second (m/s^2).
1412 *
1413 * @return z-coordinate of bias expressed in meters per squared second (m/s^2).
1414 */
1415 public double getAccelerationBiasZ() {
1416 return fixer.getAccelerationBiasZ();
1417 }
1418
1419 /**
1420 * Sets acceleration z-coordinate of bias expressed in meters per squared
1421 * second (m/s^2).
1422 *
1423 * @param biasZ z-coordinate of bias expressed in meters per squared second (m/s^2).
1424 * @throws LockedException if estimator is running.
1425 */
1426 public void setAccelerationBiasZ(final double biasZ) throws LockedException {
1427 if (running) {
1428 throw new LockedException();
1429 }
1430
1431 fixer.setAccelerationBiasZ(biasZ);
1432 }
1433
1434 /**
1435 * Sets acceleration coordinates of bias expressed in meters per squared
1436 * second (m/s^2).
1437 *
1438 * @param biasX x-coordinate of bias.
1439 * @param biasY y-coordinate of bias.
1440 * @param biasZ z-coordinate of bias.
1441 * @throws LockedException if estimator is running.
1442 */
1443 public void setAccelerationBias(final double biasX, final double biasY, final double biasZ) throws LockedException {
1444 if (running) {
1445 throw new LockedException();
1446 }
1447
1448 fixer.setAccelerationBias(biasX, biasY, biasZ);
1449 }
1450
1451 /**
1452 * Gets acceleration x-coordinate of bias.
1453 *
1454 * @return acceleration x-coordinate of bias.
1455 */
1456 public Acceleration getAccelerationBiasXAsAcceleration() {
1457 return fixer.getAccelerationBiasXAsAcceleration();
1458 }
1459
1460 /**
1461 * Gets acceleration x-coordinate of bias.
1462 *
1463 * @param result instance where the result will be stored.
1464 */
1465 public void getAccelerationBiasXAsAcceleration(final Acceleration result) {
1466 fixer.getAccelerationBiasXAsAcceleration(result);
1467 }
1468
1469 /**
1470 * Sets acceleration x-coordinate of bias.
1471 *
1472 * @param biasX acceleration x-coordinate of bias.
1473 * @throws LockedException if estimator is running.
1474 */
1475 public void setAccelerationBiasX(final Acceleration biasX) throws LockedException {
1476 if (running) {
1477 throw new LockedException();
1478 }
1479
1480 fixer.setAccelerationBiasX(biasX);
1481 }
1482
1483 /**
1484 * Gets acceleration y-coordinate of bias.
1485 *
1486 * @return acceleration y-coordinate of bias.
1487 */
1488 public Acceleration getAccelerationBiasYAsAcceleration() {
1489 return fixer.getAccelerationBiasYAsAcceleration();
1490 }
1491
1492 /**
1493 * Gets acceleration y-coordinate of bias.
1494 *
1495 * @param result instance where the result will be stored.
1496 */
1497 public void getAccelerationBiasYAsAcceleration(final Acceleration result) {
1498 fixer.getAccelerationBiasYAsAcceleration(result);
1499 }
1500
1501 /**
1502 * Sets acceleration y-coordinate of bias.
1503 *
1504 * @param biasY acceleration y-coordinate of bias.
1505 * @throws LockedException if estimator is running.
1506 */
1507 public void setAccelerationBiasY(final Acceleration biasY) throws LockedException {
1508 if (running) {
1509 throw new LockedException();
1510 }
1511
1512 fixer.setAccelerationBiasY(biasY);
1513 }
1514
1515 /**
1516 * Gets acceleration z-coordinate of bias.
1517 *
1518 * @return acceleration z-coordinate of bias.
1519 */
1520 public Acceleration getAccelerationBiasZAsAcceleration() {
1521 return fixer.getAccelerationBiasZAsAcceleration();
1522 }
1523
1524 /**
1525 * Gets acceleration z-coordinate of bias.
1526 *
1527 * @param result instance where the result will be stored.
1528 */
1529 public void getAccelerationBiasZAsAcceleration(final Acceleration result) {
1530 fixer.getAccelerationBiasZAsAcceleration(result);
1531 }
1532
1533 /**
1534 * Sets acceleration z-coordinate of bias.
1535 *
1536 * @param biasZ z-coordinate of bias.
1537 * @throws LockedException if estimator is running.
1538 */
1539 public void setAccelerationBiasZ(final Acceleration biasZ) throws LockedException {
1540 if (running) {
1541 throw new LockedException();
1542 }
1543
1544 fixer.setAccelerationBiasZ(biasZ);
1545 }
1546
1547 /**
1548 * Sets acceleration coordinates of bias.
1549 *
1550 * @param biasX x-coordinate of bias.
1551 * @param biasY y-coordinate of bias.
1552 * @param biasZ z-coordinate of bias.
1553 * @throws LockedException if estimator is running.
1554 */
1555 public void setAccelerationBias(
1556 final Acceleration biasX,
1557 final Acceleration biasY,
1558 final Acceleration biasZ) throws LockedException {
1559 if (running) {
1560 throw new LockedException();
1561 }
1562
1563 fixer.setAccelerationBias(biasX, biasY, biasZ);
1564 }
1565
1566 /**
1567 * Gets acceleration cross-coupling errors matrix.
1568 *
1569 * @return acceleration cross-coupling errors matrix.
1570 */
1571 public Matrix getAccelerationCrossCouplingErrors() {
1572 return fixer.getAccelerationCrossCouplingErrors();
1573 }
1574
1575 /**
1576 * Gets acceleration cross-coupling errors matrix.
1577 *
1578 * @param result instance where the result will be stored.
1579 */
1580 public void getAccelerationCrossCouplingErrors(final Matrix result) {
1581 fixer.getAccelerationCrossCouplingErrors(result);
1582 }
1583
1584 /**
1585 * Sets acceleration cross-coupling errors matrix.
1586 *
1587 * @param crossCouplingErrors acceleration cross-coupling errors matrix.
1588 * Must be 3x3.
1589 * @throws LockedException if estimator is running.
1590 * @throws AlgebraException if matrix cannot be inverted.
1591 * @throws IllegalArgumentException if matrix is not 3x3.
1592 */
1593 public void setAccelerationCrossCouplingErrors(final Matrix crossCouplingErrors) throws AlgebraException,
1594 LockedException {
1595 if (running) {
1596 throw new LockedException();
1597 }
1598
1599 fixer.setAccelerationCrossCouplingErrors(crossCouplingErrors);
1600 }
1601
1602 /**
1603 * Gets acceleration x scaling factor.
1604 *
1605 * @return x scaling factor.
1606 */
1607 public double getAccelerationSx() {
1608 return fixer.getAccelerationSx();
1609 }
1610
1611 /**
1612 * Sets acceleration x scaling factor.
1613 *
1614 * @param sx x scaling factor.
1615 * @throws LockedException if estimator is running.
1616 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1617 */
1618 public void setAccelerationSx(final double sx) throws LockedException, AlgebraException {
1619 if (running) {
1620 throw new LockedException();
1621 }
1622
1623 fixer.setAccelerationSx(sx);
1624 }
1625
1626 /**
1627 * Gets acceleration y scaling factor.
1628 *
1629 * @return y scaling factor.
1630 */
1631 public double getAccelerationSy() {
1632 return fixer.getAccelerationSy();
1633 }
1634
1635 /**
1636 * Sets acceleration y scaling factor.
1637 *
1638 * @param sy y scaling factor.
1639 * @throws LockedException if estimator is running.
1640 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1641 */
1642 public void setAccelerationSy(final double sy) throws LockedException, AlgebraException {
1643 if (running) {
1644 throw new LockedException();
1645 }
1646
1647 fixer.setAccelerationSy(sy);
1648 }
1649
1650 /**
1651 * Gets acceleration z scaling factor.
1652 *
1653 * @return z scaling factor.
1654 */
1655 public double getAccelerationSz() {
1656 return fixer.getAccelerationSz();
1657 }
1658
1659 /**
1660 * Sets acceleration z scaling factor.
1661 *
1662 * @param sz z scaling factor.
1663 * @throws LockedException if estimator is running.
1664 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1665 */
1666 public void setAccelerationSz(final double sz) throws LockedException, AlgebraException {
1667 if (running) {
1668 throw new LockedException();
1669 }
1670
1671 fixer.setAccelerationSz(sz);
1672 }
1673
1674 /**
1675 * Gets acceleration x-y cross-coupling error.
1676 *
1677 * @return acceleration x-y cross-coupling error.
1678 */
1679 public double getAccelerationMxy() {
1680 return fixer.getAccelerationMxy();
1681 }
1682
1683 /**
1684 * Sets acceleration x-y cross-coupling error.
1685 *
1686 * @param mxy acceleration x-y cross-coupling error.
1687 * @throws LockedException if estimator is running.
1688 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1689 */
1690 public void setAccelerationMxy(final double mxy) throws LockedException, AlgebraException {
1691 if (running) {
1692 throw new LockedException();
1693 }
1694
1695 fixer.setAccelerationMxy(mxy);
1696 }
1697
1698 /**
1699 * Gets acceleration x-z cross-coupling error.
1700 *
1701 * @return acceleration x-z cross-coupling error.
1702 */
1703 public double getAccelerationMxz() {
1704 return fixer.getAccelerationMxz();
1705 }
1706
1707 /**
1708 * Sets acceleration x-z cross-coupling error.
1709 *
1710 * @param mxz acceleration x-z cross-coupling error.
1711 * @throws LockedException if estimator is running.
1712 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1713 */
1714 public void setAccelerationMxz(final double mxz) throws LockedException, AlgebraException {
1715 if (running) {
1716 throw new LockedException();
1717 }
1718
1719 fixer.setAccelerationMxz(mxz);
1720 }
1721
1722 /**
1723 * Gets acceleration y-x cross-coupling error.
1724 *
1725 * @return acceleration y-x cross-coupling error.
1726 */
1727 public double getAccelerationMyx() {
1728 return fixer.getAccelerationMyx();
1729 }
1730
1731 /**
1732 * Sets acceleration y-x cross-coupling error.
1733 *
1734 * @param myx acceleration y-x cross-coupling error.
1735 * @throws LockedException if estimator is running.
1736 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1737 */
1738 public void setAccelerationMyx(final double myx) throws LockedException, AlgebraException {
1739 if (running) {
1740 throw new LockedException();
1741 }
1742
1743 fixer.setAccelerationMyx(myx);
1744 }
1745
1746 /**
1747 * Gets acceleration y-z cross-coupling error.
1748 *
1749 * @return y-z cross coupling error.
1750 */
1751 public double getAccelerationMyz() {
1752 return fixer.getAccelerationMyz();
1753 }
1754
1755 /**
1756 * Sets acceleration y-z cross-coupling error.
1757 *
1758 * @param myz y-z cross coupling error.
1759 * @throws LockedException if estimator is running.
1760 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1761 */
1762 public void setAccelerationMyz(final double myz) throws LockedException, AlgebraException {
1763 if (running) {
1764 throw new LockedException();
1765 }
1766
1767 fixer.setAccelerationMyz(myz);
1768 }
1769
1770 /**
1771 * Gets acceleration z-x cross-coupling error.
1772 *
1773 * @return acceleration z-x cross-coupling error.
1774 */
1775 public double getAccelerationMzx() {
1776 return fixer.getAccelerationMzx();
1777 }
1778
1779 /**
1780 * Sets acceleration z-x cross coupling error.
1781 *
1782 * @param mzx acceleration z-x cross coupling error.
1783 * @throws LockedException if estimator is running.
1784 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1785 */
1786 public void setAccelerationMzx(final double mzx) throws LockedException, AlgebraException {
1787 if (running) {
1788 throw new LockedException();
1789 }
1790
1791 fixer.setAccelerationMzx(mzx);
1792 }
1793
1794 /**
1795 * Gets acceleration z-y cross-coupling error.
1796 *
1797 * @return acceleration z-y cross-coupling error.
1798 */
1799 public double getAccelerationMzy() {
1800 return fixer.getAccelerationMzy();
1801 }
1802
1803 /**
1804 * Sets acceleration z-y cross-coupling error.
1805 *
1806 * @param mzy acceleration z-y cross coupling error.
1807 * @throws LockedException if estimator is running.
1808 * @throws AlgebraException if provided value makes acceleration cross-coupling matrix non-invertible.
1809 */
1810 public void setAccelerationMzy(final double mzy) throws LockedException, AlgebraException {
1811 if (running) {
1812 throw new LockedException();
1813 }
1814
1815 fixer.setAccelerationMzy(mzy);
1816 }
1817
1818 /**
1819 * Sets acceleration scaling factors.
1820 *
1821 * @param sx x scaling factor.
1822 * @param sy y scaling factor.
1823 * @param sz z scaling factor.
1824 * @throws LockedException if estimator is running.
1825 * @throws AlgebraException if provided values make acceleration cross-coupling matrix non-invertible.
1826 */
1827 public void setAccelerationScalingFactors(final double sx, final double sy, final double sz)
1828 throws LockedException, AlgebraException {
1829 if (running) {
1830 throw new LockedException();
1831 }
1832
1833 fixer.setAccelerationScalingFactors(sx, sy, sz);
1834 }
1835
1836 /**
1837 * Sets acceleration cross-coupling errors.
1838 *
1839 * @param mxy x-y cross coupling error.
1840 * @param mxz x-z cross coupling error.
1841 * @param myx y-x cross coupling error.
1842 * @param myz y-z cross coupling error.
1843 * @param mzx z-x cross coupling error.
1844 * @param mzy z-y cross coupling error.
1845 * @throws LockedException if estimator is running.
1846 * @throws AlgebraException if provided values make acceleration cross-coupling matrix non-invertible.
1847 */
1848 public void setAccelerationCrossCouplingErrors(
1849 final double mxy, final double mxz,
1850 final double myx, final double myz,
1851 final double mzx, final double mzy) throws LockedException, AlgebraException {
1852 if (running) {
1853 throw new LockedException();
1854 }
1855
1856 fixer.setAccelerationCrossCouplingErrors(mxy, mxz, myx, myz, mzx, mzy);
1857 }
1858
1859 /**
1860 * Sets acceleration scaling factors and cross-coupling errors.
1861 *
1862 * @param sx x scaling factor.
1863 * @param sy y scaling factor.
1864 * @param sz z scaling factor.
1865 * @param mxy x-y cross coupling error.
1866 * @param mxz x-z cross coupling error.
1867 * @param myx y-x cross coupling error.
1868 * @param myz y-z cross coupling error.
1869 * @param mzx z-x cross coupling error.
1870 * @param mzy z-y cross coupling error.
1871 * @throws LockedException if estimator is running.
1872 * @throws AlgebraException if provided values make acceleration cross-coupling matrix non-invertible.
1873 */
1874 public void setAccelerationScalingFactorsAndCrossCouplingErrors(
1875 final double sx, final double sy, final double sz,
1876 final double mxy, final double mxz,
1877 final double myx, final double myz,
1878 final double mzx, final double mzy) throws LockedException, AlgebraException {
1879 if (running) {
1880 throw new LockedException();
1881 }
1882
1883 fixer.setAccelerationScalingFactorsAndCrossCouplingErrors(sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy);
1884 }
1885
1886 /**
1887 * Gets angular speed bias values expressed in radians per second (rad/s).
1888 *
1889 * @return angular speed bias values expressed in radians per second.
1890 */
1891 public Matrix getAngularSpeedBias() {
1892 return fixer.getAngularSpeedBias();
1893 }
1894
1895 /**
1896 * Gets angular speed bias values expressed in radians per second (rad/s).
1897 *
1898 * @param result instance where the result will be stored.
1899 */
1900 public void getAngularSpeedBias(final Matrix result) {
1901 fixer.getAngularSpeedBias(result);
1902 }
1903
1904 /**
1905 * Sets angular speed bias values expressed in radians per second (rad/s).
1906 *
1907 * @param bias bias values expressed in radians per second. Must be 3x1.
1908 * @throws IllegalArgumentException if matrix is not 3x1.
1909 * @throws LockedException if estimator is running.
1910 */
1911 public void setAngularSpeedBias(final Matrix bias) throws LockedException {
1912 if (running) {
1913 throw new LockedException();
1914 }
1915
1916 fixer.setAngularSpeedBias(bias);
1917 }
1918
1919 /**
1920 * Gets angular speed bias values expressed in radians per second (rad/s).
1921 *
1922 * @return bias values expressed in radians per second.
1923 */
1924 public double[] getAngularSpeedBiasArray() {
1925 return fixer.getAngularSpeedBiasArray();
1926 }
1927
1928 /**
1929 * Gets angular speed bias values expressed in radians per second (rad/s).
1930 *
1931 * @param result instance where result data will be stored.
1932 * @throws IllegalArgumentException if provided array does not have length 3.
1933 */
1934 public void getAngularSpeedBiasArray(final double[] result) {
1935 fixer.getAngularSpeedBiasArray(result);
1936 }
1937
1938 /**
1939 * Sets angular speed bias values expressed in radians per second (rad/s).
1940 *
1941 * @param bias bias values expressed in radians per second (rad/s). Must
1942 * have length 3.
1943 * @throws IllegalArgumentException if provided array does not have length 3.
1944 * @throws LockedException if estimator is running.
1945 */
1946 public void setAngularSpeedBias(final double[] bias) throws LockedException {
1947 if (running) {
1948 throw new LockedException();
1949 }
1950
1951 fixer.setAngularSpeedBias(bias);
1952 }
1953
1954 /**
1955 * Gets angular speed bias.
1956 *
1957 * @return angular speed bias.
1958 */
1959 public AngularSpeedTriad getAngularSpeedBiasAsTriad() {
1960 return fixer.getAngularSpeedBiasAsTriad();
1961 }
1962
1963 /**
1964 * Gets angular speed bias.
1965 *
1966 * @param result instance where the result will be stored.
1967 */
1968 public void getAngularSpeedBiasAsTriad(final AngularSpeedTriad result) {
1969 fixer.getAngularSpeedBiasAsTriad(result);
1970 }
1971
1972 /**
1973 * Sets angular speed bias.
1974 *
1975 * @param bias angular speed bias to be set.
1976 * @throws LockedException if estimator is running.
1977 */
1978 public void setAngularSpeedBias(final AngularSpeedTriad bias) throws LockedException {
1979 if (running) {
1980 throw new LockedException();
1981 }
1982
1983 fixer.setAngularSpeedBias(bias);
1984 }
1985
1986 /**
1987 * Gets angular speed x-coordinate of bias expressed in radians per second
1988 * (rad/s).
1989 *
1990 * @return x-coordinate of bias expressed in radians per second (rad/s).
1991 */
1992 public double getAngularSpeedBiasX() {
1993 return fixer.getAngularSpeedBiasX();
1994 }
1995
1996 /**
1997 * Sets angular speed x-coordinate of bias expressed in radians per second
1998 * (rad/s).
1999 *
2000 * @param biasX x-coordinate of bias expressed in radians per second (rad/s).
2001 * @throws LockedException if estimator is running.
2002 */
2003 public void setAngularSpeedBiasX(final double biasX) throws LockedException {
2004 if (running) {
2005 throw new LockedException();
2006 }
2007
2008 fixer.setAngularSpeedBiasX(biasX);
2009 }
2010
2011 /**
2012 * Gets angular speed y-coordinate of bias expressed in radians per second
2013 * (rad/s).
2014 *
2015 * @return y-coordinate of bias expressed in radians per second (rad/s).
2016 */
2017 public double getAngularSpeedBiasY() {
2018 return fixer.getAngularSpeedBiasY();
2019 }
2020
2021 /**
2022 * Sets angular speed y-coordinate of bias expressed in radians per second
2023 * (rad/s).
2024 *
2025 * @param biasY y-coordinate of bias expressed in radians per second (rad/s).
2026 * @throws LockedException if estimator is running.
2027 */
2028 public void setAngularSpeedBiasY(final double biasY) throws LockedException {
2029 if (running) {
2030 throw new LockedException();
2031 }
2032
2033 fixer.setAngularSpeedBiasY(biasY);
2034 }
2035
2036 /**
2037 * Gets angular speed z-coordinate of bias expressed in radians per second
2038 * (rad/s).
2039 *
2040 * @return z-coordinate of bias expressed in radians per second (rad/s).
2041 */
2042 public double getAngularSpeedBiasZ() {
2043 return fixer.getAngularSpeedBiasZ();
2044 }
2045
2046 /**
2047 * Sets angular speed z-coordinate of bias expressed in radians per second
2048 * (rad/s).
2049 *
2050 * @param biasZ z-coordinate of bias expressed in radians per second (rad/s).
2051 * @throws LockedException if estimator is running.
2052 */
2053 public void setAngularSpeedBiasZ(final double biasZ) throws LockedException {
2054 if (running) {
2055 throw new LockedException();
2056 }
2057
2058 fixer.setAngularSpeedBiasZ(biasZ);
2059 }
2060
2061 /**
2062 * Sets angular speed coordinates of bias expressed in radians per second
2063 * (rad/s).
2064 *
2065 * @param biasX x-coordinate of bias.
2066 * @param biasY y-coordinate of bias.
2067 * @param biasZ z-coordinate of bias.
2068 * @throws LockedException if estimator is running.
2069 */
2070 public void setAngularSpeedBias(final double biasX, final double biasY, final double biasZ) throws LockedException {
2071 if (running) {
2072 throw new LockedException();
2073 }
2074
2075 fixer.setAngularSpeedBias(biasX, biasY, biasZ);
2076 }
2077
2078 /**
2079 * Gets angular speed x-coordinate of bias.
2080 *
2081 * @return x-coordinate of bias.
2082 */
2083 public AngularSpeed getAngularSpeedBiasXAsAngularSpeed() {
2084 return fixer.getAngularSpeedBiasXAsAngularSpeed();
2085 }
2086
2087 /**
2088 * Gets angular speed x-coordinate of bias.
2089 *
2090 * @param result instance where the result will be stored.
2091 */
2092 public void getAngularSpeedBiasXAsAngularSpeed(final AngularSpeed result) {
2093 fixer.getAngularSpeedBiasXAsAngularSpeed(result);
2094 }
2095
2096 /**
2097 * Sets angular speed x-coordinate of bias.
2098 *
2099 * @param biasX x-coordinate of bias.
2100 * @throws LockedException if estimator is running.
2101 */
2102 public void setAngularSpeedBiasX(final AngularSpeed biasX) throws LockedException {
2103 if (running) {
2104 throw new LockedException();
2105 }
2106
2107 fixer.setAngularSpeedBiasX(biasX);
2108 }
2109
2110 /**
2111 * Gets angular speed y-coordinate of bias.
2112 *
2113 * @return y-coordinate of bias.
2114 */
2115 public AngularSpeed getAngularSpeedBiasYAsAngularSpeed() {
2116 return fixer.getAngularSpeedBiasYAsAngularSpeed();
2117 }
2118
2119 /**
2120 * Gets angular speed y-coordinate of bias.
2121 *
2122 * @param result instance where the result will be stored.
2123 */
2124 public void getAngularSpeedBiasYAsAngularSpeed(final AngularSpeed result) {
2125 fixer.getAngularSpeedBiasYAsAngularSpeed(result);
2126 }
2127
2128 /**
2129 * Sets angular speed y-coordinate of bias.
2130 *
2131 * @param biasY y-coordinate of bias.
2132 * @throws LockedException if estimator is running.
2133 */
2134 public void setAngularSpeedBiasY(final AngularSpeed biasY) throws LockedException {
2135 if (running) {
2136 throw new LockedException();
2137 }
2138
2139 fixer.setAngularSpeedBiasY(biasY);
2140 }
2141
2142 /**
2143 * Gets angular speed z-coordinate of bias.
2144 *
2145 * @return z-coordinate of bias.
2146 */
2147 public AngularSpeed getAngularSpeedBiasZAsAngularSpeed() {
2148 return fixer.getAngularSpeedBiasZAsAngularSpeed();
2149 }
2150
2151 /**
2152 * Gets angular speed z-coordinate of bias.
2153 *
2154 * @param result instance where the result will be stored.
2155 */
2156 public void getAngularSpeedBiasZAsAngularSpeed(final AngularSpeed result) {
2157 fixer.getAngularSpeedBiasZAsAngularSpeed(result);
2158 }
2159
2160 /**
2161 * Sets angular speed z-coordinate of bias.
2162 *
2163 * @param biasZ z-coordinate of bias.
2164 * @throws LockedException if estimator is running.
2165 */
2166 public void setAngularSpeedBiasZ(final AngularSpeed biasZ) throws LockedException {
2167 if (running) {
2168 throw new LockedException();
2169 }
2170
2171 fixer.setAngularSpeedBiasZ(biasZ);
2172 }
2173
2174 /**
2175 * Sets angular speed coordinates of bias.
2176 *
2177 * @param biasX x-coordinate of bias.
2178 * @param biasY y-coordinate of bias.
2179 * @param biasZ z-coordinate of bias.
2180 * @throws LockedException if estimator is running.
2181 */
2182 public void setAngularSpeedBias(
2183 final AngularSpeed biasX,
2184 final AngularSpeed biasY,
2185 final AngularSpeed biasZ) throws LockedException {
2186 if (running) {
2187 throw new LockedException();
2188 }
2189
2190 fixer.setAngularSpeedBias(biasX, biasY, biasZ);
2191 }
2192
2193 /**
2194 * Gets angular speed cross-coupling errors matrix.
2195 *
2196 * @return cross coupling errors matrix.
2197 */
2198 public Matrix getAngularSpeedCrossCouplingErrors() {
2199 return fixer.getAngularSpeedCrossCouplingErrors();
2200 }
2201
2202 /**
2203 * Gets angular speed cross-coupling errors matrix.
2204 *
2205 * @param result instance where the result will be stored.
2206 */
2207 public void getAngularSpeedCrossCouplingErrors(final Matrix result) {
2208 fixer.getAngularSpeedCrossCouplingErrors(result);
2209 }
2210
2211 /**
2212 * Sets angular speed cross-coupling errors matrix.
2213 *
2214 * @param crossCouplingErrors cross-coupling errors matrix. Must be 3x3.
2215 * @throws AlgebraException if matrix cannot be inverted.
2216 * @throws IllegalArgumentException if matrix is not 3x3.
2217 * @throws LockedException if estimator is running.
2218 */
2219 public void setAngularSpeedCrossCouplingErrors(final Matrix crossCouplingErrors) throws AlgebraException,
2220 LockedException {
2221 if (running) {
2222 throw new LockedException();
2223 }
2224
2225 fixer.setAngularSpeedCrossCouplingErrors(crossCouplingErrors);
2226 }
2227
2228 /**
2229 * Gets angular speed x scaling factor.
2230 *
2231 * @return x scaling factor.
2232 */
2233 public double getAngularSpeedSx() {
2234 return fixer.getAngularSpeedSx();
2235 }
2236
2237 /**
2238 * Sets angular speed x scaling factor.
2239 *
2240 * @param sx x scaling factor.
2241 * @throws LockedException if estimator is running.
2242 * @throws AlgebraException if provided value makes angular speed
2243 * cross-coupling matrix non-invertible.
2244 */
2245 public void setAngularSpeedSx(final double sx) throws LockedException, AlgebraException {
2246 if (running) {
2247 throw new LockedException();
2248 }
2249
2250 fixer.setAngularSpeedSx(sx);
2251 }
2252
2253 /**
2254 * Gets angular speed y scaling factor.
2255 *
2256 * @return y scaling factor.
2257 */
2258 public double getAngularSpeedSy() {
2259 return fixer.getAngularSpeedSy();
2260 }
2261
2262 /**
2263 * Sets angular speed y-scaling factor.
2264 *
2265 * @param sy y scaling factor.
2266 * @throws LockedException if estimator is running.
2267 * @throws AlgebraException if provided value makes angular speed
2268 * cross-coupling matrix non-invertible.
2269 */
2270 public void setAngularSpeedSy(final double sy) throws LockedException, AlgebraException {
2271 if (running) {
2272 throw new LockedException();
2273 }
2274
2275 fixer.setAngularSpeedSy(sy);
2276 }
2277
2278 /**
2279 * Gets angular speed z scaling factor.
2280 *
2281 * @return z scaling factor.
2282 */
2283 public double getAngularSpeedSz() {
2284 return fixer.getAngularSpeedSz();
2285 }
2286
2287 /**
2288 * Sets angular speed z scaling factor.
2289 *
2290 * @param sz z scaling factor.
2291 * @throws LockedException if estimator is running.
2292 * @throws AlgebraException if provided value makes angular speed
2293 * cross-coupling matrix non-invertible.
2294 */
2295 public void setAngularSpeedSz(final double sz) throws LockedException, AlgebraException {
2296 if (running) {
2297 throw new LockedException();
2298 }
2299
2300 fixer.setAngularSpeedSz(sz);
2301 }
2302
2303 /**
2304 * Gets angular speed x-y cross-coupling error.
2305 *
2306 * @return x-y cross coupling error.
2307 */
2308 public double getAngularSpeedMxy() {
2309 return fixer.getAngularSpeedMxy();
2310 }
2311
2312 /**
2313 * Sets angular speed x-y cross-coupling error.
2314 *
2315 * @param mxy x-y cross coupling error.
2316 * @throws LockedException if estimator is running.
2317 * @throws AlgebraException if provided value makes angular speed
2318 * cross-coupling matrix non-invertible.
2319 */
2320 public void setAngularSpeedMxy(final double mxy) throws LockedException, AlgebraException {
2321 if (running) {
2322 throw new LockedException();
2323 }
2324
2325 fixer.setAngularSpeedMxy(mxy);
2326 }
2327
2328 /**
2329 * Gets angular speed x-z cross-coupling error.
2330 *
2331 * @return x-z cross coupling error.
2332 */
2333 public double getAngularSpeedMxz() {
2334 return fixer.getAngularSpeedMxz();
2335 }
2336
2337 /**
2338 * Sets angular speed x-z cross-coupling error.
2339 *
2340 * @param mxz x-z cross coupling error.
2341 * @throws LockedException if estimator is running.
2342 * @throws AlgebraException if provided value makes angular speed
2343 * cross-coupling matrix non-invertible.
2344 */
2345 public void setAngularSpeedMxz(final double mxz) throws LockedException, AlgebraException {
2346 if (running) {
2347 throw new LockedException();
2348 }
2349
2350 fixer.setAngularSpeedMxz(mxz);
2351 }
2352
2353 /**
2354 * Gets angular speed y-x cross-coupling error.
2355 *
2356 * @return y-x cross coupling error.
2357 */
2358 public double getAngularSpeedMyx() {
2359 return fixer.getAngularSpeedMyx();
2360 }
2361
2362 /**
2363 * Sets angular speed y-x cross-coupling error.
2364 *
2365 * @param myx y-x cross coupling error.
2366 * @throws LockedException if estimator is running.
2367 * @throws AlgebraException if provided value makes angular speed
2368 * cross-coupling matrix non-invertible.
2369 */
2370 public void setAngularSpeedMyx(final double myx) throws LockedException, AlgebraException {
2371 if (running) {
2372 throw new LockedException();
2373 }
2374
2375 fixer.setAngularSpeedMyx(myx);
2376 }
2377
2378 /**
2379 * Gets angular speed y-z cross-coupling error.
2380 *
2381 * @return y-z cross coupling error.
2382 */
2383 public double getAngularSpeedMyz() {
2384 return fixer.getAngularSpeedMyz();
2385 }
2386
2387 /**
2388 * Sets angular speed y-z cross-coupling error.
2389 *
2390 * @param myz y-z cross coupling error.
2391 * @throws LockedException if estimator is running.
2392 * @throws AlgebraException if provided value makes angular speed
2393 * cross-coupling matrix non-invertible.
2394 */
2395 public void setAngularSpeedMyz(final double myz) throws LockedException, AlgebraException {
2396 if (running) {
2397 throw new LockedException();
2398 }
2399
2400 fixer.setAngularSpeedMyz(myz);
2401 }
2402
2403 /**
2404 * Gets angular speed z-x cross-coupling error.
2405 *
2406 * @return z-x cross coupling error.
2407 */
2408 public double getAngularSpeedMzx() {
2409 return fixer.getAngularSpeedMzx();
2410 }
2411
2412 /**
2413 * Sets angular speed z-x cross-coupling error.
2414 *
2415 * @param mzx z-x cross coupling error.
2416 * @throws LockedException if estimator is running.
2417 * @throws AlgebraException if provided value makes angular speed
2418 * cross-coupling matrix non-invertible.
2419 */
2420 public void setAngularSpeedMzx(final double mzx) throws LockedException, AlgebraException {
2421 if (running) {
2422 throw new LockedException();
2423 }
2424
2425 fixer.setAngularSpeedMzx(mzx);
2426 }
2427
2428 /**
2429 * Gets angular speed z-y cross-coupling error.
2430 *
2431 * @return z-y cross coupling error.
2432 */
2433 public double getAngularSpeedMzy() {
2434 return fixer.getAngularSpeedMzy();
2435 }
2436
2437 /**
2438 * Sets angular speed z-y cross-coupling error.
2439 *
2440 * @param mzy z-y cross coupling error.
2441 * @throws LockedException if estimator is running.
2442 * @throws AlgebraException if provided value makes angular speed
2443 * cross-coupling matrix non-invertible.
2444 */
2445 public void setAngularSpeedMzy(final double mzy) throws LockedException, AlgebraException {
2446 if (running) {
2447 throw new LockedException();
2448 }
2449
2450 fixer.setAngularSpeedMzy(mzy);
2451 }
2452
2453 /**
2454 * Sets angular speed scaling factors.
2455 *
2456 * @param sx x scaling factor.
2457 * @param sy y scaling factor.
2458 * @param sz z scaling factor.
2459 * @throws LockedException if estimator is running.
2460 * @throws AlgebraException if provided values make angular speed
2461 * cross-coupling matrix non-invertible.
2462 */
2463 public void setAngularSpeedScalingFactors(final double sx, final double sy, final double sz) throws LockedException,
2464 AlgebraException {
2465 if (running) {
2466 throw new LockedException();
2467 }
2468
2469 fixer.setAngularSpeedScalingFactors(sx, sy, sz);
2470 }
2471
2472 /**
2473 * Sets angular speed cross-coupling errors.
2474 *
2475 * @param mxy x-y cross coupling error.
2476 * @param mxz x-z cross coupling error.
2477 * @param myx y-x cross coupling error.
2478 * @param myz y-z cross coupling error.
2479 * @param mzx z-x cross coupling error.
2480 * @param mzy z-y cross coupling error.
2481 * @throws LockedException if estimator is running.
2482 * @throws AlgebraException if provided values make angular speed
2483 * cross-coupling matrix non-invertible.
2484 */
2485 public void setAngularSpeedCrossCouplingErrors(
2486 final double mxy, final double mxz,
2487 final double myx, final double myz,
2488 final double mzx, final double mzy) throws LockedException, AlgebraException {
2489 if (running) {
2490 throw new LockedException();
2491 }
2492
2493 fixer.setAngularSpeedCrossCouplingErrors(mxy, mxz, myx, myz, mzx, mzy);
2494 }
2495
2496 /**
2497 * Sets angular speed scaling factors and cross-coupling errors.
2498 *
2499 * @param sx x scaling factor.
2500 * @param sy y scaling factor.
2501 * @param sz z scaling factor.
2502 * @param mxy x-y cross coupling error.
2503 * @param mxz x-z cross coupling error.
2504 * @param myx y-x cross coupling error.
2505 * @param myz y-z cross coupling error.
2506 * @param mzx z-x cross coupling error.
2507 * @param mzy z-y cross coupling error.
2508 * @throws LockedException if estimator is running.
2509 * @throws AlgebraException if provided values make angular speed
2510 * cross-coupling matrix non-invertible.
2511 */
2512 public void setAngularSpeedScalingFactorsAndCrossCouplingErrors(
2513 final double sx, final double sy, final double sz,
2514 final double mxy, final double mxz,
2515 final double myx, final double myz,
2516 final double mzx, final double mzy) throws LockedException, AlgebraException {
2517 if (running) {
2518 throw new LockedException();
2519 }
2520
2521 fixer.setAngularSpeedScalingFactorsAndCrossCouplingErrors(sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy);
2522 }
2523
2524 /**
2525 * Gets angular speed g-dependant cross biases matrix.
2526 *
2527 * @return g-dependant cross biases matrix.
2528 */
2529 public Matrix getAngularSpeedGDependantCrossBias() {
2530 return fixer.getAngularSpeedGDependantCrossBias();
2531 }
2532
2533 /**
2534 * Gets angular speed g-dependant cross biases matrix.
2535 *
2536 * @param result instance where the result will be stored.
2537 */
2538 public void getAngularSpeedGDependantCrossBias(final Matrix result) {
2539 fixer.getAngularSpeedGDependantCrossBias(result);
2540 }
2541
2542 /**
2543 * Sets angular speed g-dependant cross biases matrix.
2544 *
2545 * @param gDependantCrossBias g-dependant cross biases matrix.
2546 * @throws IllegalArgumentException if matrix is not 3x3.
2547 * @throws LockedException if estimator is running.
2548 */
2549 public void setAngularSpeedGDependantCrossBias(final Matrix gDependantCrossBias) throws LockedException {
2550 if (running) {
2551 throw new LockedException();
2552 }
2553
2554 fixer.setAngularSpeedGDependantCrossBias(gDependantCrossBias);
2555 }
2556
2557 /**
2558 * Indicates whether measured kinematics must be fixed or not.
2559 * When enabled, provided calibration data is used; otherwise it is
2560 * ignored.
2561 * By default, this is enabled.
2562 *
2563 * @return indicates whether measured kinematics must be fixed or not.
2564 */
2565 public boolean isFixKinematicsEnabled() {
2566 return fixKinematics;
2567 }
2568
2569 /**
2570 * Specifies whether measured kinematics must be fixed or not.
2571 * When enabled, provided calibration data is used; otherwise it is
2572 * ignored.
2573 *
2574 * @param fixKinematics true if measured kinematics must be fixed or not.
2575 * @throws LockedException if estimator is currently running.
2576 */
2577 public void setFixKinematicsEnabled(final boolean fixKinematics) throws LockedException {
2578 if (running) {
2579 throw new LockedException();
2580 }
2581 this.fixKinematics = fixKinematics;
2582 }
2583
2584 /**
2585 * Gets the time interval between body kinematics (IMU acceleration and gyroscope)
2586 * samples expressed in seconds (s).
2587 *
2588 * @return time interval between body kinematics samples.
2589 */
2590 public double getTimeInterval() {
2591 return timeInterval;
2592 }
2593
2594 /**
2595 * Sets a time interval between body kinematics (IMU acceleration and gyroscope)
2596 * samples expressed in seconds (s).
2597 *
2598 * @param timeInterval time interval between body kinematics samples.
2599 * @throws LockedException if estimator is currently running.
2600 */
2601 public void setTimeInterval(final double timeInterval) throws LockedException {
2602 if (running) {
2603 throw new LockedException();
2604 }
2605
2606 if (timeInterval < 0.0) {
2607 throw new IllegalArgumentException();
2608 }
2609
2610 this.timeInterval = timeInterval;
2611 }
2612
2613 /**
2614 * Gets time interval between body kinematics (IMU acceleration and gyroscope)
2615 * samples.
2616 *
2617 * @return time interval between body kinematics samples.
2618 */
2619 public Time getTimeIntervalAsTime() {
2620 return new Time(timeInterval, TimeUnit.SECOND);
2621 }
2622
2623 /**
2624 * Gets time interval between body kinematics (IMU acceleration and gyroscope)
2625 * samples.
2626 *
2627 * @param result instance where the time interval will be stored.
2628 */
2629 public void getTimeIntervalAsTime(final Time result) {
2630 result.setValue(timeInterval);
2631 result.setUnit(TimeUnit.SECOND);
2632 }
2633
2634 /**
2635 * Sets time interval between body kinematics (IMU acceleration and gyroscope)
2636 * samples.
2637 *
2638 * @param timeInterval time interval between body kinematics samples.
2639 * @throws LockedException if estimator is currently running.
2640 */
2641 public void setTimeInterval(final Time timeInterval) throws LockedException {
2642 setTimeInterval(convertTime(timeInterval));
2643 }
2644
2645 /**
2646 * Indicates if estimator is ready to start processing additional kinematics
2647 * measurements.
2648 *
2649 * @return true if ready, false otherwise.
2650 */
2651 public boolean isReady() {
2652 return referenceFrame != null;
2653 }
2654
2655 /**
2656 * Indicates whether this estimator is running.
2657 *
2658 * @return true if this estimator is running, false otherwise.
2659 */
2660 public boolean isRunning() {
2661 return running;
2662 }
2663
2664 /**
2665 * Adds a sample of measured body kinematics (accelerometer and gyroscope readings)
2666 * obtained from an IMU, fixes their values and uses fixed values to estimate
2667 * current drift and their average values.
2668 *
2669 * @param kinematics measured body kinematics.
2670 * @throws LockedException if estimator is currently running.
2671 * @throws NotReadyException if estimator is not ready.
2672 * @throws DriftEstimationException if estimation fails for some reason.
2673 */
2674 public void addBodyKinematics(final BodyKinematics kinematics) throws LockedException, NotReadyException,
2675 DriftEstimationException {
2676 if (running) {
2677 throw new LockedException();
2678 }
2679
2680 if (!isReady()) {
2681 throw new NotReadyException();
2682 }
2683
2684 try {
2685 running = true;
2686
2687 if (numberOfProcessedSamples == 0) {
2688 if (listener != null) {
2689 listener.onStart(this);
2690 }
2691
2692 final var c = referenceFrame.getCoordinateTransformation();
2693 c.asRotation(refQ);
2694 refQ.inverse(invRefQ);
2695
2696 frame.copyFrom(referenceFrame);
2697 }
2698
2699 if (fixKinematics) {
2700 fixer.fix(kinematics, fixedKinematics);
2701 } else {
2702 fixedKinematics.copyFrom(kinematics);
2703 }
2704
2705 // estimate navigation variation respect to previous frame
2706 ECEFInertialNavigator.navigateECEF(timeInterval, frame, fixedKinematics, frame);
2707
2708 // estimate drift values
2709 computeCurrentPositionDrift();
2710 computeCurrentVelocityDrift();
2711 computeCurrentOrientationDrift();
2712
2713 numberOfProcessedSamples++;
2714
2715 if (listener != null) {
2716 listener.onBodyKinematicsAdded(this, kinematics, fixedKinematics);
2717 }
2718
2719 } catch (final AlgebraException | InertialNavigatorException | InvalidRotationMatrixException e) {
2720 throw new DriftEstimationException(e);
2721 } finally {
2722 running = false;
2723 }
2724 }
2725
2726 /**
2727 * Resets this estimator to its initial state.
2728 *
2729 * @throws LockedException if estimator is currently running.
2730 */
2731 public void reset() throws LockedException {
2732 if (running) {
2733 throw new LockedException();
2734 }
2735
2736 running = true;
2737 numberOfProcessedSamples = 0;
2738
2739 currentPositionDriftMeters = 0.0;
2740 currentVelocityDriftMetersPerSecond = 0.0;
2741 currentOrientationDriftRadians = 0.0;
2742
2743 if (listener != null) {
2744 listener.onReset(this);
2745 }
2746
2747 running = false;
2748 }
2749
2750 /**
2751 * Gets the number of samples that have been processed so far.
2752 *
2753 * @return number of samples that have been processed so far.
2754 */
2755 public int getNumberOfProcessedSamples() {
2756 return numberOfProcessedSamples;
2757 }
2758
2759 /**
2760 * Gets elapsed time since the first processed measurement expressed in seconds.
2761 *
2762 * @return elapsed time.
2763 */
2764 public double getElapsedTimeSeconds() {
2765 return numberOfProcessedSamples * timeInterval;
2766 }
2767
2768 /**
2769 * Gets elapsed time since the first processed measurement.
2770 *
2771 * @return elapsed time.
2772 */
2773 public Time getElapsedTime() {
2774 return numberOfProcessedSamples > 0 ? new Time(getElapsedTimeSeconds(), TimeUnit.SECOND) : null;
2775 }
2776
2777 /**
2778 * Gets elapsed time since the first processed measurement.
2779 *
2780 * @param result instance where the result will be stored.
2781 * @return true if elapsed time is available and the result is updated,
2782 * false otherwise.
2783 */
2784 public boolean getElapsedTime(final Time result) {
2785 if (numberOfProcessedSamples > 0) {
2786 result.setValue(getElapsedTimeSeconds());
2787 result.setUnit(TimeUnit.SECOND);
2788 return true;
2789 } else {
2790 return false;
2791 }
2792 }
2793
2794 /**
2795 * Gets current position drift for last processed body kinematics
2796 * measurement expressed in meters (m) respect ECEF coordinates.
2797 *
2798 * @return current position drift or null.
2799 */
2800 public ECEFPosition getCurrentPositionDrift() {
2801 return numberOfProcessedSamples > 0 ? new ECEFPosition(currentPositionDrift) : null;
2802 }
2803
2804 /**
2805 * Gets current position drift for last processed body kinematics
2806 * measurement expressed in meters (m) respect ECEF coordinates.
2807 *
2808 * @param result instance where the result will be stored.
2809 * @return true if the current position drift is available and the result is updated,
2810 * false otherwise.
2811 */
2812 public boolean getCurrentPositionDrift(final ECEFPosition result) {
2813 if (numberOfProcessedSamples > 0) {
2814 result.copyFrom(currentPositionDrift);
2815 return true;
2816 } else {
2817 return false;
2818 }
2819 }
2820
2821 /**
2822 * Gets current velocity drift for the last processed body kinematics
2823 * measurement expressed in meters per second (m/s) respect ECEF coordinates.
2824 *
2825 * @return current velocity drift or null.
2826 */
2827 public ECEFVelocity getCurrentVelocityDrift() {
2828 return numberOfProcessedSamples > 0 ? new ECEFVelocity(currentVelocityDrift) : null;
2829 }
2830
2831 /**
2832 * Gets current velocity drift for the last processed body kinematics
2833 * measurement expressed in meters per second (m/s) respect ECEF coordinates.
2834 *
2835 * @param result instance where the result will be stored.
2836 * @return true if the current velocity drift is available and the result is updated,
2837 * false otherwise.
2838 */
2839 public boolean getCurrentVelocityDrift(final ECEFVelocity result) {
2840 if (numberOfProcessedSamples > 0) {
2841 result.copyFrom(currentVelocityDrift);
2842 return true;
2843 } else {
2844 return false;
2845 }
2846 }
2847
2848 /**
2849 * Gets current orientation drift as a 3D rotation for the last processed body
2850 * kinematics measurement respect ECEF coordinates.
2851 *
2852 * @return current orientation drift or null.
2853 */
2854 public Rotation3D getCurrentOrientationDrift() {
2855 return numberOfProcessedSamples > 0 ? new Quaternion(q) : null;
2856 }
2857
2858 /**
2859 * Gets current orientation drift as a 3D rotation for the last processed body
2860 * kinematics measurement respect ECEF coordinates.
2861 *
2862 * @param result instance where the result will be stored.
2863 * @return true if the current orientation drift is available and the result is
2864 * updated, false otherwise.
2865 */
2866 public boolean getCurrentOrientationDrift(final Rotation3D result) {
2867 if (numberOfProcessedSamples > 0) {
2868 result.fromRotation(q);
2869 return true;
2870 } else {
2871 return false;
2872 }
2873 }
2874
2875 /**
2876 * Gets current amount of position drift for last processed body kinematics
2877 * measurement expressed in meters (m).
2878 *
2879 * @return the current amount of position drift or null.
2880 */
2881 public Double getCurrentPositionDriftNormMeters() {
2882 return numberOfProcessedSamples > 0 ? currentPositionDriftMeters : null;
2883 }
2884
2885 /**
2886 * Gets current amount of position drift for last processed body kinematics
2887 * measurement.
2888 *
2889 * @return the current amount of position drift or null.
2890 */
2891 public Distance getCurrentPositionDriftNorm() {
2892 final var positionDrift = getCurrentPositionDriftNormMeters();
2893 return positionDrift != null ? new Distance(positionDrift, DistanceUnit.METER) : null;
2894 }
2895
2896 /**
2897 * Gets current amount of position drift for last processed body kinematics
2898 * measurement.
2899 *
2900 * @param result instance where the result will be stored.
2901 * @return true if the current position drift is available and the result is updated,
2902 * false otherwise.
2903 */
2904 public boolean getCurrentPositionDriftNorm(final Distance result) {
2905 final var positionDrift = getCurrentPositionDriftNormMeters();
2906 if (positionDrift != null) {
2907 result.setValue(positionDrift);
2908 result.setUnit(DistanceUnit.METER);
2909 return true;
2910 } else {
2911 return false;
2912 }
2913 }
2914
2915 /**
2916 * Gets current amount of velocity drift for the last processed body kinematics
2917 * measurement expressed in meters per second (m/s).
2918 *
2919 * @return current amount of velocity drift or null.
2920 */
2921 public Double getCurrentVelocityDriftNormMetersPerSecond() {
2922 return numberOfProcessedSamples > 0 ? currentVelocityDriftMetersPerSecond : null;
2923 }
2924
2925 /**
2926 * Gets current amount of velocity drift for last processed body kinematics
2927 * measurement.
2928 *
2929 * @return current amount of velocity drift or null.
2930 */
2931 public Speed getCurrentVelocityDriftNorm() {
2932 final var velocityDrift = getCurrentVelocityDriftNormMetersPerSecond();
2933 return velocityDrift != null ? new Speed(velocityDrift, SpeedUnit.METERS_PER_SECOND) : null;
2934 }
2935
2936 /**
2937 * Gets current amount of velocity drift for last processed body kinematics
2938 * measurement.
2939 *
2940 * @param result instance where the result will be stored.
2941 * @return true if the current velocity drift is available and the result is updated,
2942 * false otherwise.
2943 */
2944 public boolean getCurrentVelocityDriftNorm(final Speed result) {
2945 final var velocityDrift = getCurrentVelocityDriftNormMetersPerSecond();
2946 if (velocityDrift != null) {
2947 result.setValue(velocityDrift);
2948 result.setUnit(SpeedUnit.METERS_PER_SECOND);
2949 return true;
2950 } else {
2951 return false;
2952 }
2953 }
2954
2955 /**
2956 * Gets current amount of orientation drift for last processed body kinematics
2957 * measurement expressed in radians (rad).
2958 *
2959 * @return current amount of orientation drift or null.
2960 */
2961 public Double getCurrentOrientationDriftRadians() {
2962 return numberOfProcessedSamples > 0 ? currentOrientationDriftRadians : null;
2963 }
2964
2965 /**
2966 * Gets current amount of orientation drift for last processed body kinematics
2967 * measurement.
2968 *
2969 * @return current amount of orientation drift or null.
2970 */
2971 public Angle getCurrentOrientationDriftAngle() {
2972 final var orientationDrift = getCurrentOrientationDriftRadians();
2973 return orientationDrift != null ? new Angle(orientationDrift, AngleUnit.RADIANS) : null;
2974 }
2975
2976 /**
2977 * Gets current amount of orientation drift for last processed body kinematics
2978 * measurement.
2979 *
2980 * @param result instance where the result will be stored.
2981 * @return true if the current orientation drift is available and the result is
2982 * updated, false otherwise.
2983 */
2984 public boolean getCurrentOrientationDriftAngle(final Angle result) {
2985 final var orientationDrift = getCurrentOrientationDriftRadians();
2986 if (orientationDrift != null) {
2987 result.setValue(orientationDrift);
2988 result.setUnit(AngleUnit.RADIANS);
2989 return true;
2990 } else {
2991 return false;
2992 }
2993 }
2994
2995 /**
2996 * Gets the current amount of position drift per time unit expressed in meters
2997 * per second (m/s).
2998 *
2999 * @return current amount of position drift per time unit or null.
3000 */
3001 public Double getCurrentPositionDriftPerTimeUnit() {
3002 final var positionDrift = getCurrentPositionDriftNormMeters();
3003 final var elapsedTime = getElapsedTimeSeconds();
3004 return positionDrift != null ? positionDrift / elapsedTime : null;
3005 }
3006
3007 /**
3008 * Gets the current amount of position drift per time unit.
3009 *
3010 * @return current amount of position drift per time unit or null.
3011 */
3012 public Speed getCurrentPositionDriftPerTimeUnitAsSpeed() {
3013 final var positionDriftPerTimeUnit = getCurrentPositionDriftPerTimeUnit();
3014 return positionDriftPerTimeUnit != null ? new Speed(positionDriftPerTimeUnit, SpeedUnit.METERS_PER_SECOND)
3015 : null;
3016 }
3017
3018 /**
3019 * Gets the current amount of position drift per time unit.
3020 *
3021 * @param result instance where the result will be stored.
3022 * @return true if the current amount of position drift per time unit is
3023 * available and the result is updated, false otherwise.
3024 */
3025 public boolean getCurrentPositionDriftPerTimeUnitAsSpeed(final Speed result) {
3026 final var positionDriftPerTimeUnit = getCurrentPositionDriftPerTimeUnit();
3027 if (positionDriftPerTimeUnit != null) {
3028 result.setValue(positionDriftPerTimeUnit);
3029 result.setUnit(SpeedUnit.METERS_PER_SECOND);
3030 return true;
3031 } else {
3032 return false;
3033 }
3034 }
3035
3036 /**
3037 * Gets the current amount of velocity drift per time unit expressed in meters
3038 * per squared second (m/s^2).
3039 *
3040 * @return the current amount of velocity drift per time unit or null.
3041 */
3042 public Double getCurrentVelocityDriftPerTimeUnit() {
3043 final var velocityDrift = getCurrentVelocityDriftNormMetersPerSecond();
3044 final var elapsedTime = getElapsedTimeSeconds();
3045 return velocityDrift != null ? velocityDrift / elapsedTime : null;
3046 }
3047
3048 /**
3049 * Gets the current amount of velocity drift per time unit.
3050 *
3051 * @return the current amount of velocity drift per time unit or null.
3052 */
3053 public Acceleration getCurrentVelocityDriftPerTimeUnitAsAcceleration() {
3054 final var velocityDriftPerTimeUnit = getCurrentVelocityDriftPerTimeUnit();
3055 return velocityDriftPerTimeUnit != null
3056 ? new Acceleration(velocityDriftPerTimeUnit, AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
3057 }
3058
3059 /**
3060 * Gets the current amount of velocity drift per time unit.
3061 *
3062 * @param result instance where the result will be stored.
3063 * @return true if the current amount of velocity drift per time unit is available
3064 * and the result is updated, false otherwise.
3065 */
3066 public boolean getCurrentVelocityDriftPerTimeUnitAsAcceleration(final Acceleration result) {
3067 final var velocityDriftPerTimeUnit = getCurrentVelocityDriftPerTimeUnit();
3068 if (velocityDriftPerTimeUnit != null) {
3069 result.setValue(velocityDriftPerTimeUnit);
3070 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3071 return true;
3072 } else {
3073 return false;
3074 }
3075 }
3076
3077 /**
3078 * Gets the current amount of orientation drift per time unit expressed in radians
3079 * per second (rad/s).
3080 *
3081 * @return amount of orientation drift per time unit or null.
3082 */
3083 public Double getCurrentOrientationDriftPerTimeUnit() {
3084 final var orientationDrift = getCurrentOrientationDriftRadians();
3085 final var elapsedTime = getElapsedTimeSeconds();
3086 return orientationDrift != null ? orientationDrift / elapsedTime : null;
3087 }
3088
3089 /**
3090 * Gets the current amount of orientation drift per time unit.
3091 *
3092 * @return amount of orientation drift per time unit or null.
3093 */
3094 public AngularSpeed getCurrentOrientationDriftPerTimeUnitAsAngularSpeed() {
3095 final var orientationDriftPerTimeUnit = getCurrentOrientationDriftPerTimeUnit();
3096 return orientationDriftPerTimeUnit != null ?
3097 new AngularSpeed(orientationDriftPerTimeUnit, AngularSpeedUnit.RADIANS_PER_SECOND) : null;
3098 }
3099
3100 /**
3101 * Gets the current amount of orientation drift per time unit.
3102 *
3103 * @param result instance where the result will be stored.
3104 * @return true if the current amount of orientation drift is available and the result
3105 * is updated, false otherwise.
3106 */
3107 public boolean getCurrentOrientationDriftPerTimeUnitAsAngularSpeed(final AngularSpeed result) {
3108 final var orientationDriftPerTimeUnit = getCurrentOrientationDriftPerTimeUnit();
3109 if (orientationDriftPerTimeUnit != null) {
3110 result.setValue(orientationDriftPerTimeUnit);
3111 result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
3112 return true;
3113 } else {
3114 return false;
3115 }
3116 }
3117
3118 /**
3119 * Computes current position drift.
3120 */
3121 protected void computeCurrentPositionDrift() {
3122 final var initX = referenceFrame.getX();
3123 final var initY = referenceFrame.getY();
3124 final var initZ = referenceFrame.getZ();
3125
3126 final var currentX = frame.getX();
3127 final var currentY = frame.getY();
3128 final var currentZ = frame.getZ();
3129
3130 final var diffX = currentX - initX;
3131 final var diffY = currentY - initY;
3132 final var diffZ = currentZ - initZ;
3133
3134 currentPositionDrift.setCoordinates(diffX, diffY, diffZ);
3135
3136 currentPositionDriftMeters = currentPositionDrift.getNorm();
3137 }
3138
3139 /**
3140 * Computes current velocity drift.
3141 */
3142 protected void computeCurrentVelocityDrift() {
3143 final var initVx = referenceFrame.getVx();
3144 final var initVy = referenceFrame.getVy();
3145 final var initVz = referenceFrame.getVz();
3146
3147 final var currentVx = frame.getVx();
3148 final var currentVy = frame.getVy();
3149 final var currentVz = frame.getVz();
3150
3151 final var diffVx = currentVx - initVx;
3152 final var diffVy = currentVy - initVy;
3153 final var diffVz = currentVz - initVz;
3154
3155 currentVelocityDrift.setCoordinates(diffVx, diffVy, diffVz);
3156
3157 currentVelocityDriftMetersPerSecond = currentVelocityDrift.getNorm();
3158 }
3159
3160 /**
3161 * Computes current orientation drift.
3162 *
3163 * @throws AlgebraException if there are numerical instabilities.
3164 * @throws InvalidRotationMatrixException if rotation cannot be accurately
3165 * estimated.
3166 */
3167 protected void computeCurrentOrientationDrift() throws AlgebraException, InvalidRotationMatrixException {
3168 if (currentC == null) {
3169 currentC = new Matrix(Rotation3D.INHOM_COORDS, Rotation3D.INHOM_COORDS);
3170 }
3171 frame.getCoordinateTransformationMatrix(currentC);
3172
3173 q.fromMatrix(currentC);
3174 q.combine(invRefQ);
3175
3176 currentOrientationDriftRadians = q.getRotationAngle();
3177 }
3178
3179 /**
3180 * Converts the provided time instance to seconds.
3181 *
3182 * @param time instance to be converted.
3183 * @return conversion in seconds.
3184 */
3185 private static double convertTime(final Time time) {
3186 return TimeConverter.convert(time.getValue().doubleValue(), time.getUnit(), TimeUnit.SECOND);
3187 }
3188 }