1 /*
2 * Copyright (C) 2020 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.navigation.inertial.calibration.noise;
17
18 import com.irurueta.navigation.LockedException;
19 import com.irurueta.navigation.inertial.BodyKinematics;
20 import com.irurueta.navigation.inertial.calibration.AccelerationTriad;
21 import com.irurueta.navigation.inertial.calibration.AccelerometerNoiseRootPsdSource;
22 import com.irurueta.navigation.inertial.calibration.AngularSpeedTriad;
23 import com.irurueta.navigation.inertial.calibration.GyroscopeNoiseRootPsdSource;
24 import com.irurueta.navigation.inertial.calibration.TimeIntervalEstimator;
25 import com.irurueta.units.Acceleration;
26 import com.irurueta.units.AccelerationConverter;
27 import com.irurueta.units.AccelerationUnit;
28 import com.irurueta.units.AngularSpeed;
29 import com.irurueta.units.AngularSpeedConverter;
30 import com.irurueta.units.AngularSpeedUnit;
31 import com.irurueta.units.Time;
32
33 /**
34 * Estimates accumulated acceleration and angular speed noise variances and PSD's
35 * (Power Spectral Densities) along with their average values.
36 * This estimator must be used when the body where the accelerometer and gyroscope
37 * are attached remains static on the same position with zero velocity and
38 * constant (or zero) angular speed while capturing data.
39 * To compute PSD's, this estimator assumes that measurement samples are obtained
40 * at a constant provided rate equal to {@link #getTimeInterval()} seconds.
41 * If not available, sampling rate average can be estimated using
42 * {@link TimeIntervalEstimator}.
43 * This estimator does NOT require the knowledge of current location and body
44 * orientation.
45 * Because body location and orientation is not known, estimated average values
46 * cannot be used to determine biases. Only norm of noise estimations
47 * (variance or standard deviation) can be safely used.
48 */
49 public class AccumulatedBodyKinematicsNoiseEstimator implements AccelerometerNoiseRootPsdSource,
50 GyroscopeNoiseRootPsdSource {
51
52 /**
53 * Default time interval between accelerometer samples expressed in seconds
54 * (s).
55 */
56 public static final double DEFAULT_TIME_INTERVAL_SECONDS =
57 AccumulatedTriadNoiseEstimator.DEFAULT_TIME_INTERVAL_SECONDS;
58
59 /**
60 * Listener to handle events raised by this estimator.
61 */
62 private AccumulatedBodyKinematicsNoiseEstimatorListener listener;
63
64 /**
65 * Last provided body kinematics.
66 */
67 private BodyKinematics lastBodyKinematics;
68
69 /**
70 * Accumulated acceleration estimator.
71 */
72 private final AccumulatedAccelerationTriadNoiseEstimator accelerationEstimator =
73 new AccumulatedAccelerationTriadNoiseEstimator();
74
75 /**
76 * Accumulated angular speed estimator.
77 */
78 private final AccumulatedAngularSpeedTriadNoiseEstimator angularSpeedEstimator =
79 new AccumulatedAngularSpeedTriadNoiseEstimator();
80
81 /**
82 * Indicates that estimator is running.
83 */
84 private boolean running;
85
86 /**
87 * Constructor.
88 */
89 public AccumulatedBodyKinematicsNoiseEstimator() {
90 }
91
92 /**
93 * Constructor.
94 *
95 * @param listener listener to handle events raised by this estimator.
96 */
97 public AccumulatedBodyKinematicsNoiseEstimator(final AccumulatedBodyKinematicsNoiseEstimatorListener listener) {
98 this.listener = listener;
99 }
100
101 /**
102 * Gets time interval between body kinematics samples expressed in
103 * seconds (s).
104 *
105 * @return time interval between body kinematics samples.
106 */
107 public double getTimeInterval() {
108 return accelerationEstimator.getTimeInterval();
109 }
110
111 /**
112 * Sets time interval between body kinematics samples expressed in
113 * seconds (s).
114 *
115 * @param timeInterval time interval between body kinematic samples.
116 * @throws IllegalArgumentException if provided value is negative.
117 * @throws LockedException if estimator is currently running.
118 */
119 public void setTimeInterval(final double timeInterval) throws LockedException {
120 if (running) {
121 throw new LockedException();
122 }
123
124 accelerationEstimator.setTimeInterval(timeInterval);
125 angularSpeedEstimator.setTimeInterval(timeInterval);
126 }
127
128 /**
129 * Gets time interval between body kinematics samples.
130 *
131 * @return time interval between body kinematics samples.
132 */
133 public Time getTimeIntervalAsTime() {
134 return accelerationEstimator.getTimeIntervalAsTime();
135 }
136
137 /**
138 * Gets time interval between body kinematics samples.
139 *
140 * @param result instance where body kinematics will be stored.
141 */
142 public void getTimeIntervalAsTime(final Time result) {
143 accelerationEstimator.getTimeIntervalAsTime(result);
144 }
145
146 /**
147 * Sets time interval between body kinematics samples.
148 *
149 * @param timeInterval time interval between body kinematics samples.
150 * @throws LockedException if estimator is currently running.
151 */
152 public void setTimeInterval(final Time timeInterval) throws LockedException {
153 if (running) {
154 throw new LockedException();
155 }
156
157 accelerationEstimator.setTimeInterval(timeInterval);
158 angularSpeedEstimator.setTimeInterval(timeInterval);
159 }
160
161 /**
162 * Gets listener to handle events raised by this estimator.
163 *
164 * @return listener to handle events raised by this estimator.
165 */
166 public AccumulatedBodyKinematicsNoiseEstimatorListener getListener() {
167 return listener;
168 }
169
170 /**
171 * Sets listener to handle events raised by this estimator.
172 *
173 * @param listener listener to handle events raised by this estimator.
174 * @throws LockedException if this estimator is running.
175 */
176 public void setListener(final AccumulatedBodyKinematicsNoiseEstimatorListener listener) throws LockedException {
177 if (running) {
178 throw new LockedException();
179 }
180
181 this.listener = listener;
182 }
183
184 /**
185 * Gets last provided body kinematics or null if not available.
186 *
187 * @return last provided body kinematics or null.
188 */
189 public BodyKinematics getLastBodyKinematics() {
190 return lastBodyKinematics;
191 }
192
193 /**
194 * Gets last provided body kinematics.
195 *
196 * @param result instance where last provided body kinematics will be stored.
197 * @return true if result instance was updated, false otherwise.
198 */
199 public boolean getLastBodyKinematics(final BodyKinematics result) {
200 if (lastBodyKinematics != null) {
201 lastBodyKinematics.copyTo(result);
202 return true;
203 } else {
204 return false;
205 }
206 }
207
208 /**
209 * Gets estimated average of x coordinate of accelerometer sensed specific force
210 * expressed in meters per squared second (m/s^2).
211 * This value will depend of body location and orientation, hence it should never
212 * be used as a calibration bias.
213 *
214 * @return average of x coordinate of sensed specific force.
215 */
216 public double getAvgSpecificForceX() {
217 return accelerationEstimator.getAvgX();
218 }
219
220 /**
221 * Gets estimated average of x coordinate of accelerometer sensed specific force.
222 * This value will depend of body location and orientation, hence it should never
223 * be used as a calibration bias.
224 *
225 * @return average of x coordinate of sensed specific force.
226 */
227 public Acceleration getAvgSpecificForceXAsMeasurement() {
228 return accelerationEstimator.getAvgXAsMeasurement();
229 }
230
231 /**
232 * Gets estimated average of x coordinate of accelerometer sensed specific force.
233 * This value will depend of body location and orientation, hence it should never
234 * be used as a calibration bias.
235 *
236 * @param result instance where average of x coordinate of sensed specific force
237 * will be stored.
238 */
239 public void getAvgSpecificForceXAsMeasurement(final Acceleration result) {
240 accelerationEstimator.getAvgXAsMeasurement(result);
241 }
242
243 /**
244 * Gets estimated average of y coordinate of accelerometer sensed specific force
245 * expressed in meters per squared second (m/s^2).
246 * This value will depend of body location and orientation, hence it should never
247 * be used as a calibration bias.
248 *
249 * @return average of y coordinate of sensed specific force.
250 */
251 public double getAvgSpecificForceY() {
252 return accelerationEstimator.getAvgY();
253 }
254
255 /**
256 * Gets estimated average of y coordinate of accelerometer sensed specific force.
257 * This value will depend of body location and orientation, hence it should never
258 * be used as a calibration bias.
259 *
260 * @return average of y coordinate of sensed specific force.
261 */
262 public Acceleration getAvgSpecificForceYAsMeasurement() {
263 return accelerationEstimator.getAvgYAsMeasurement();
264 }
265
266 /**
267 * Gets estimated average of y coordinate of accelerometer sensed specific force.
268 * This value will depend of body location and orientation, hence it should never
269 * be used as a calibration bias.
270 *
271 * @param result instance where average of y coordinate of sensed specific force
272 * will be stored.
273 */
274 public void getAvgSpecificForceYAsMeasurement(final Acceleration result) {
275 accelerationEstimator.getAvgYAsMeasurement(result);
276 }
277
278 /**
279 * Gets estimated average of z coordinate of accelerometer sensed specific force
280 * expressed in meters per squared second (m/s^2).
281 * This value will depend of body location and orientation, hence it should never
282 * be used as a calibration bias.
283 *
284 * @return average of z coordinate of sensed specific force.
285 */
286 public double getAvgSpecificForceZ() {
287 return accelerationEstimator.getAvgZ();
288 }
289
290 /**
291 * Gets estimated average of z coordinate of accelerometer sensed specific force.
292 * This value will depend of body location and orientation, hence it should never
293 * be used as a calibration bias.
294 *
295 * @return average of z coordinate of sensed specific force.
296 */
297 public Acceleration getAvgSpecificForceZAsMeasurement() {
298 return accelerationEstimator.getAvgZAsMeasurement();
299 }
300
301 /**
302 * Gets estimated average of z coordinate of accelerometer sensed specific force.
303 * This value will depend of body location and orientation, hence it should never
304 * be used as a calibration bias.
305 *
306 * @param result instance where average of z coordinate of sensed specific force
307 * will be stored.
308 */
309 public void getAvgSpecificForceZAsMeasurement(final Acceleration result) {
310 accelerationEstimator.getAvgZAsMeasurement(result);
311 }
312
313 /**
314 * Gets estimated average of accelerometer sensed specific force as a measurement
315 * triad.
316 *
317 * @return average accelerometer triad.
318 */
319 public AccelerationTriad getAvgSpecificForceAsTriad() {
320 return accelerationEstimator.getAvgTriad();
321 }
322
323 /**
324 * Gets estimated average of accelerometer sensed specific force as a measurement
325 * triad.
326 *
327 * @param result instance where average accelerometer triad will be stored.
328 */
329 public void getAvgSpecificForceAsTriad(final AccelerationTriad result) {
330 accelerationEstimator.getAvgTriad(result);
331 }
332
333 /**
334 * Gets norm of estimated average acceleration expressed in meters per squared
335 * second (m/s^2). This value is independent of body orientation.
336 *
337 * @return norm of estimated average acceleration.
338 */
339 public double getAvgSpecificForceNorm() {
340 return accelerationEstimator.getAvgNorm();
341 }
342
343 /**
344 * Gets norm of estimated average acceleration within current window.
345 *
346 * @return norm of estimated average acceleration.
347 */
348 public Acceleration getAvgSpecificForceNormAsMeasurement() {
349 return accelerationEstimator.getAvgNormAsMeasurement();
350 }
351
352 /**
353 * Gets norm of estimated average acceleration.
354 *
355 * @param result instance where norm of estimated average acceleration will be stored.
356 */
357 public void getAvgSpecificForceNormAsMeasurement(final Acceleration result) {
358 accelerationEstimator.getAvgNormAsMeasurement(result);
359 }
360
361 /**
362 * Gets estimated average of x coordinate of gyroscope sensed angular rate
363 * expressed in radians per second (rad/s).
364 * This value will depend of body location and orientation, hence it should
365 * never be used as a calibration bias.
366 *
367 * @return average of x coordinate of sensed angular rate.
368 */
369 public double getAvgAngularRateX() {
370 return angularSpeedEstimator.getAvgX();
371 }
372
373 /**
374 * Gets estimated average of x coordinate of gyroscope sensed angular rate.
375 * This value will depend of body location and orientation, hence it should never
376 * be used as a calibration bias.
377 *
378 * @return average of x coordinate of sensed angular rate.
379 */
380 public AngularSpeed getAvgAngularRateXAsMeasurement() {
381 return angularSpeedEstimator.getAvgXAsMeasurement();
382 }
383
384 /**
385 * Gets estimated average of x coordinate of gyroscope sensed angular rate.
386 * This value will depend of body location and orientation, hence it should never
387 * be used as a calibration bias.
388 *
389 * @param result instance where average of x coordinate of sensed angular rate
390 * will be stored.
391 */
392 public void getAvgAngularRateXAsMeasurement(final AngularSpeed result) {
393 angularSpeedEstimator.getAvgXAsMeasurement(result);
394 }
395
396 /**
397 * Gets estimated average of y coordinate of gyroscope sensed angular rate
398 * expressed in radians per second (rad/s).
399 * This value will depend of body location and orientation, hence it should never
400 * be used as a calibration bias.
401 *
402 * @return average of y coordinate of sensed angular rate.
403 */
404 public double getAvgAngularRateY() {
405 return angularSpeedEstimator.getAvgY();
406 }
407
408 /**
409 * Gets estimated average of y coordinate of gyroscope sensed angular rate.
410 * This value will depend of body location and orientation, hence it should never
411 * be used as a calibration bias.
412 *
413 * @return average of y coordinate of sensed angular rate.
414 */
415 public AngularSpeed getAvgAngularRateYAsMeasurement() {
416 return angularSpeedEstimator.getAvgYAsMeasurement();
417 }
418
419 /**
420 * Gets estimated average of y coordinate of gyroscope sensed angular rate.
421 * This value will depend of body location and orientation, hence it should never
422 * be used as a calibration bias.
423 *
424 * @param result instance where average of y coordinate of sensed angular rate
425 * will be stored.
426 */
427 public void getAvgAngularRateYAsMeasurement(final AngularSpeed result) {
428 angularSpeedEstimator.getAvgYAsMeasurement(result);
429 }
430
431 /**
432 * Gets estimated average of z coordinate of gyroscope sensed angular rate
433 * expressed in radians per second (rad/s).
434 * This value will depend of body location and orientation, hence it should never
435 * be used as a calibration bias.
436 *
437 * @return average of z coordinate of sensed angular rate.
438 */
439 public double getAvgAngularRateZ() {
440 return angularSpeedEstimator.getAvgZ();
441 }
442
443 /**
444 * Gets estimated average of z coordinate of gyroscope sensed angular rate.
445 * This value will depend of body location and orientation, hence it should never
446 * be used as a calibration bias.
447 *
448 * @return average of z coordinate of sensed angular rate.
449 */
450 public AngularSpeed getAvgAngularRateZAsMeasurement() {
451 return angularSpeedEstimator.getAvgZAsMeasurement();
452 }
453
454 /**
455 * Gets estimated average of z coordinate of gyroscope sensed angular rate.
456 * This value will depend of body location and orientation, hence it should never
457 * be used as a calibration bias.
458 *
459 * @param result instance where average of z coordinate of sensed angular rate
460 * will be stored.
461 */
462 public void getAvgAngularRateZAsMeasurement(final AngularSpeed result) {
463 angularSpeedEstimator.getAvgZAsMeasurement(result);
464 }
465
466 /**
467 * Gets estimated average of gyroscope sensed angular speed as a measurement
468 * triad.
469 *
470 * @return average angular speed triad.
471 */
472 public AngularSpeedTriad getAvgAngularRateTriad() {
473 return angularSpeedEstimator.getAvgTriad();
474 }
475
476 /**
477 * Gets estimated average of gyroscope sensed angular speed as a measurement
478 * triad.
479 *
480 * @param result instance where average angular speed triad will be stored.
481 */
482 public void getAvgAngularRateTriad(final AngularSpeedTriad result) {
483 angularSpeedEstimator.getAvgTriad(result);
484 }
485
486 /**
487 * Gets norm of estimated average angular speed expressed in radians per
488 * second (rad/s). This value is independent of body orientation.
489 *
490 * @return norm of estimated average angular speed.
491 */
492 public double getAvgAngularRateNorm() {
493 return angularSpeedEstimator.getAvgNorm();
494 }
495
496 /**
497 * Gets norm of estimated average angular speed.
498 * This value is independent of body orientation.
499 *
500 * @return norm of estimated average angular speed.
501 */
502 public AngularSpeed getAvgAngularRateNormAsMeasurement() {
503 return angularSpeedEstimator.getAvgNormAsMeasurement();
504 }
505
506 /**
507 * Gets norm of estimated average angular speed.
508 * This value is independent of body orientation.
509 *
510 * @param result instance where norm of estimated average angular speed will be stored.
511 */
512 public void getAvgAngularRateNormAsMeasurement(final AngularSpeed result) {
513 angularSpeedEstimator.getAvgNormAsMeasurement(result);
514 }
515
516 /**
517 * Gets estimated average of body kinematics.
518 *
519 * @return estimated average of body kinematics.
520 */
521 public BodyKinematics getAvgBodyKinematics() {
522 final var result = new BodyKinematics();
523 getAvgBodyKinematics(result);
524 return result;
525 }
526
527 /**
528 * Gets estimated average of body kinematics.
529 *
530 * @param result instance where estimated average of body kinematics will be stored.
531 */
532 public void getAvgBodyKinematics(final BodyKinematics result) {
533 final var avgFx = accelerationEstimator.getAvgX();
534 final var avgFy = accelerationEstimator.getAvgY();
535 final var avgFz = accelerationEstimator.getAvgZ();
536
537 final var avgWx = angularSpeedEstimator.getAvgX();
538 final var avgWy = angularSpeedEstimator.getAvgY();
539 final var avgWz = angularSpeedEstimator.getAvgZ();
540
541 result.setSpecificForceCoordinates(avgFx, avgFy, avgFz);
542 result.setAngularRateCoordinates(avgWx, avgWy, avgWz);
543 }
544
545 /**
546 * Gets estimated variance of x coordinate of accelerometer sensed specific force
547 * expressed in (m^2/s^4).
548 *
549 * @return estimated variance of x coordinate of sensed specific force.
550 */
551 public double getVarianceSpecificForceX() {
552 return accelerationEstimator.getVarianceX();
553 }
554
555 /**
556 * Gets estimated variance of y coordinate of accelerometer sensed specific
557 * force expressed in (m^2/s^4).
558 *
559 * @return estimated variance of y coordinate of sensed specific force.
560 */
561 public double getVarianceSpecificForceY() {
562 return accelerationEstimator.getVarianceY();
563 }
564
565 /**
566 * Gets estimated variance of z coordinate of accelerometer sensed specific
567 * force expressed in (m^2/s^4).
568 *
569 * @return estimated variance of z coordinate of sensed specific force.
570 */
571 public double getVarianceSpecificForceZ() {
572 return accelerationEstimator.getVarianceZ();
573 }
574
575 /**
576 * Gets estimated variance of x coordinate of gyroscope sensed angular rate
577 * expressed in (rad^2/s^2).
578 *
579 * @return estimated variance of x coordinate of sensed angular rate.
580 */
581 public double getVarianceAngularRateX() {
582 return angularSpeedEstimator.getVarianceX();
583 }
584
585 /**
586 * Gets estimated variance of y coordinate of gyroscope sensed angular rate
587 * expressed in (rad^2/s^2).
588 *
589 * @return estimated variance of y coordinate of sensed angular rate.
590 */
591 public double getVarianceAngularRateY() {
592 return angularSpeedEstimator.getVarianceY();
593 }
594
595 /**
596 * Gets estimated variance of z coordinate of gyroscope sensed angular rate
597 * expressed in (rad^2/s^2).
598 *
599 * @return estimated variance of z coordinate of sensed angular rate.
600 */
601 public double getVarianceAngularRateZ() {
602 return angularSpeedEstimator.getVarianceZ();
603 }
604
605 /**
606 * Gets estimated standard deviation of x coordinate of accelerometer
607 * sensed specific force expressed in meters per squared second (m/s^2).
608 *
609 * @return estimated standard deviation of x coordinate of sensed specific
610 * force.
611 */
612 public double getStandardDeviationSpecificForceX() {
613 return accelerationEstimator.getStandardDeviationX();
614 }
615
616 /**
617 * Gets estimated standard deviation of x coordinate of accelerometer
618 * sensed specific force.
619 *
620 * @return estimated standard deviation of x coordinate of sensed specific
621 * force.
622 */
623 public Acceleration getStandardDeviationSpecificForceXAsMeasurement() {
624 return accelerationEstimator.getStandardDeviationXAsMeasurement();
625 }
626
627 /**
628 * Gets estimated standard deviation of x coordinate of accelerometer
629 * sensed specific force.
630 *
631 * @param result instance where estimated standard deviation of x
632 * coordinate of sensed specific force will be stored.
633 */
634 public void getStandardDeviationSpecificForceXAsMeasurement(final Acceleration result) {
635 accelerationEstimator.getStandardDeviationXAsMeasurement(result);
636 }
637
638 /**
639 * Gets estimated standard deviation of y coordinate of accelerometer
640 * sensed specific force expressed in meters per squared second (m/s^2).
641 *
642 * @return estimated standard deviation of y coordinate of sensed specific
643 * force.
644 */
645 public double getStandardDeviationSpecificForceY() {
646 return accelerationEstimator.getStandardDeviationY();
647 }
648
649 /**
650 * Gets estimated standard deviation of y coordinate of accelerometer
651 * sensed specific force.
652 *
653 * @return estimated standard deviation of y coordinate of sensed specific
654 * force.
655 */
656 public Acceleration getStandardDeviationSpecificForceYAsMeasurement() {
657 return accelerationEstimator.getStandardDeviationYAsMeasurement();
658 }
659
660 /**
661 * Gets estimated standard deviation of y coordinate of accelerometer
662 * sensed specific force.
663 *
664 * @param result instance where estimated standard deviation of y
665 * coordinate of sensed specific force will be stored.
666 */
667 public void getStandardDeviationSpecificForceYAsMeasurement(final Acceleration result) {
668 accelerationEstimator.getStandardDeviationYAsMeasurement(result);
669 }
670
671 /**
672 * Gets estimated standard deviation of z coordinate of accelerometer
673 * sensed specific force expressed in meters per squared second (m/s^2).
674 *
675 * @return estimated standard deviation of z coordinate of sensed specific
676 * force.
677 */
678 public double getStandardDeviationSpecificForceZ() {
679 return accelerationEstimator.getStandardDeviationZ();
680 }
681
682 /**
683 * Gets estimated standard deviation of z coordinate of accelerometer
684 * sensed specific force.
685 *
686 * @return estimated standard deviation of z coordinate of sensed specific
687 * force.
688 */
689 public Acceleration getStandardDeviationSpecificForceZAsMeasurement() {
690 return accelerationEstimator.getStandardDeviationZAsMeasurement();
691 }
692
693 /**
694 * Gets estimated standard deviation of z coordinate of accelerometer
695 * sensed specific force.
696 *
697 * @param result instance where estimated standard deviation of z
698 * coordinate of sensed specific force will be stored.
699 */
700 public void getStandardDeviationSpecificForceZAsMeasurement(final Acceleration result) {
701 accelerationEstimator.getStandardDeviationZAsMeasurement(result);
702 }
703
704 /**
705 * Gets estimated standard deviation triad of accelerometer measurements.
706 *
707 * @return estimated standard deviation triad of accelerometer measurements.
708 */
709 public AccelerationTriad getStandardDeviationSpecificForceTriad() {
710 return accelerationEstimator.getStandardDeviationTriad();
711 }
712
713 /**
714 * Gets estimated standard deviation triad of accelerometer measurements.
715 *
716 * @param result instance where estimated standard deviation triad of
717 * accelerometer measurements will be stored.
718 */
719 public void getStandardDeviationSpecificForceTriad(final AccelerationTriad result) {
720 accelerationEstimator.getStandardDeviationTriad(result);
721 }
722
723 /**
724 * Gets norm of estimated standard deviation of accelerometer measurements
725 * expressed in meters per squared second (m/s^2).
726 *
727 * @return norm of estimated standard deviation of accelerometer
728 * measurements.
729 */
730 public double getStandardDeviationSpecificForceNorm() {
731 return accelerationEstimator.getStandardDeviationNorm();
732 }
733
734 /**
735 * Gets norm of estimated standard deviation of accelerometer measurements.
736 *
737 * @return norm of estimated standard deviation of measurements.
738 */
739 public Acceleration getStandardDeviationSpecificForceNormAsMeasurement() {
740 return accelerationEstimator.getStandardDeviationNormAsMeasurement();
741 }
742
743 /**
744 * Gets norm of estimated standard deviation of accelerometer measurements.
745 *
746 * @param result instance where norm of estimated standard deviation will be
747 * stored.
748 */
749 public void getStandardDeviationSpecificForceNormAsMeasurement(final Acceleration result) {
750 accelerationEstimator.getStandardDeviationNormAsMeasurement(result);
751 }
752
753 /**
754 * Gets average of estimated standard deviation coordinates of accelerometer
755 * measurements expressed in meters per squared second (m/s^2).
756 *
757 * @return average of estimated standard deviation coordinates.
758 */
759 public double getAverageStandardDeviationSpecificForce() {
760 return accelerationEstimator.getAverageStandardDeviation();
761 }
762
763 /**
764 * Gets average of estimated standard deviation coordinates of accelerometer
765 * measurements.
766 *
767 * @return average of estimated standard deviation coordinates.
768 */
769 public Acceleration getAverageStandardDeviationSpecificForceAsMeasurement() {
770 return accelerationEstimator.getAverageStandardDeviationAsMeasurement();
771 }
772
773 /**
774 * Gets average of estimated standard deviation coordinates of accelerometer
775 * measurements.
776 *
777 * @param result instance where average of estimated standard deviation coordinates
778 * will be stored.
779 */
780 public void getAverageStandardDeviationSpecificForceAsMeasurement(final Acceleration result) {
781 accelerationEstimator.getAverageStandardDeviationAsMeasurement(result);
782 }
783
784 /**
785 * Gets estimated standard deviation of x coordinate of gyroscope
786 * expressed in radians per second (rad/s).
787 *
788 * @return estimated standard deviation of x coordinate of gyroscope.
789 */
790 public double getStandardDeviationAngularRateX() {
791 return angularSpeedEstimator.getStandardDeviationX();
792 }
793
794 /**
795 * Gets estimated standard deviation of x coordinate of gyroscope.
796 *
797 * @return estimated standard deviation of x coordinate of gyroscope.
798 */
799 public AngularSpeed getStandardDeviationAngularRateXAsMeasurement() {
800 return angularSpeedEstimator.getStandardDeviationXAsMeasurement();
801 }
802
803 /**
804 * Gets estimated standard deviation of x coordinate of gyroscope.
805 *
806 * @param result estimated standard deviation of x coordinate of gyroscope.
807 */
808 public void getStandardDeviationAngularRateXAsMeasurement(final AngularSpeed result) {
809 angularSpeedEstimator.getStandardDeviationXAsMeasurement(result);
810 }
811
812 /**
813 * Gets estimated standard deviation of y coordinate of gyroscope
814 * expressed in radians per second (rad/s).
815 *
816 * @return estimated standard deviation of y coordinate of gyroscope.
817 */
818 public double getStandardDeviationAngularRateY() {
819 return angularSpeedEstimator.getStandardDeviationY();
820 }
821
822 /**
823 * Gets estimated standard deviation of y coordinate of gyroscope.
824 *
825 * @return estimated standard deviation of y coordinate of gyroscope.
826 */
827 public AngularSpeed getStandardDeviationAngularRateYAsMeasurement() {
828 return angularSpeedEstimator.getStandardDeviationYAsMeasurement();
829 }
830
831 /**
832 * Gets estimated standard deviation of y coordinate of gyroscope.
833 *
834 * @param result estimated standard deviation of y coordinate of gyroscope.
835 */
836 public void getStandardDeviationAngularRateYAsMeasurement(final AngularSpeed result) {
837 angularSpeedEstimator.getStandardDeviationYAsMeasurement(result);
838 }
839
840 /**
841 * Gets estimated standard deviation of z coordinate of gyroscope
842 * expressed in radians per second (rad/s).
843 *
844 * @return estimated standard deviation of z coordinate of gyroscope.
845 */
846 public double getStandardDeviationAngularRateZ() {
847 return angularSpeedEstimator.getStandardDeviationZ();
848 }
849
850 /**
851 * Gets estimated standard deviation of z coordinate of gyroscope.
852 *
853 * @return estimated standard deviation of z coordinate of gyroscope.
854 */
855 public AngularSpeed getStandardDeviationAngularRateZAsMeasurement() {
856 return angularSpeedEstimator.getStandardDeviationZAsMeasurement();
857 }
858
859 /**
860 * Gets estimated standard deviation of z coordinate of gyroscope.
861 *
862 * @param result estimated standard deviation of z coordinate of gyroscope.
863 */
864 public void getStandardDeviationAngularRateZAsMeasurement(final AngularSpeed result) {
865 angularSpeedEstimator.getStandardDeviationZAsMeasurement(result);
866 }
867
868 /**
869 * Gets estimated standard deviation triad of angular speed measurements.
870 *
871 * @return estimated standard deviation triad of angular speed measurements.
872 */
873 public AngularSpeedTriad getStandardDeviationAngularSpeedTriad() {
874 return angularSpeedEstimator.getStandardDeviationTriad();
875 }
876
877 /**
878 * Gets estimated standard deviation triad of angular speed measurements.
879 *
880 * @param result instance where estimated standard deviation triad of
881 * gyroscope measurements will be stored.
882 */
883 public void getStandardDeviationAngularSpeedTriad(final AngularSpeedTriad result) {
884 angularSpeedEstimator.getStandardDeviationTriad(result);
885 }
886
887 /**
888 * Gets norm of estimated standard deviation of gyroscope measurements
889 * expressed in radians per second (rad/s).
890 *
891 * @return norm of estimated standard deviation of gyroscope
892 * measurements.
893 */
894 public double getStandardDeviationAngularSpeedNorm() {
895 return angularSpeedEstimator.getStandardDeviationNorm();
896 }
897
898 /**
899 * Gets norm of estimated standard deviation of gyroscope measurements.
900 *
901 * @return norm of estimated standard deviation of measurements.
902 */
903 public AngularSpeed getStandardDeviationAngularSpeedNormAsMeasurement() {
904 return angularSpeedEstimator.getStandardDeviationNormAsMeasurement();
905 }
906
907 /**
908 * Gets norm of estimated standard deviation of gyroscope measurements.
909 *
910 * @param result instance where norm of estimated standard deviation will be
911 * stored.
912 */
913 public void getStandardDeviationAngularSpeedNormAsMeasurement(final AngularSpeed result) {
914 angularSpeedEstimator.getStandardDeviationNormAsMeasurement(result);
915 }
916
917 /**
918 * Gets average of estimated standard deviation coordinates of gyroscope
919 * measurements expressed in radians per second (rad/s).
920 *
921 * @return average of estimated standard deviation coordinates.
922 */
923 public double getAverageStandardDeviationAngularSpeed() {
924 return angularSpeedEstimator.getAverageStandardDeviation();
925 }
926
927 /**
928 * Gets average of estimated standard deviation coordinates of gyroscope
929 * measurements.
930 *
931 * @return average of estimated standard deviation coordinates.
932 */
933 public AngularSpeed getAverageStandardDeviationAngularSpeedAsMeasurement() {
934 return angularSpeedEstimator.getAverageStandardDeviationAsMeasurement();
935 }
936
937 /**
938 * Gets average of estimated standard deviation coordinates of gyroscope
939 * measurements.
940 *
941 * @param result instance where average of estimated standard deviation coordinates
942 * will be stored.
943 */
944 public void getAverageStandardDeviationAngularSpeedAsMeasurement(final AngularSpeed result) {
945 angularSpeedEstimator.getAverageStandardDeviationAsMeasurement(result);
946 }
947
948 /**
949 * Gets estimated standard deviations of accelerometer and gyroscope components
950 * as a body kinematics instance.
951 *
952 * @return a body kinematics instance containing standard deviation values.
953 */
954 public BodyKinematics getStandardDeviationAsBodyKinematics() {
955 return new BodyKinematics(getStandardDeviationSpecificForceX(),
956 getStandardDeviationSpecificForceY(),
957 getStandardDeviationSpecificForceZ(),
958 getStandardDeviationAngularRateX(),
959 getStandardDeviationAngularRateY(),
960 getStandardDeviationAngularRateZ());
961 }
962
963 /**
964 * Gets estimated standard deviations of accelerometer and gyroscope components
965 * as a body kinematics instance.
966 *
967 * @param result instance where data will be stored.
968 */
969 public void getStandardDeviationAsBodyKinematics(final BodyKinematics result) {
970 result.setSpecificForceCoordinates(getStandardDeviationSpecificForceX(),
971 getStandardDeviationSpecificForceY(),
972 getStandardDeviationSpecificForceZ());
973 result.setAngularRateCoordinates(getStandardDeviationAngularRateX(),
974 getStandardDeviationAngularRateY(),
975 getStandardDeviationAngularRateZ());
976 }
977
978 /**
979 * Gets accelerometer noise PSD (Power Spectral Density) on x axis expressed
980 * in (m^2 * s^-3).
981 *
982 * @return accelerometer noise PSD on x axis.
983 */
984 public double getSpecificForcePsdX() {
985 return accelerationEstimator.getPsdX();
986 }
987
988 /**
989 * Gets accelerometer noise PSD (Power Spectral Density) on y axis expressed
990 * in (m^2 * s^-3).
991 *
992 * @return accelerometer noise PSD on y axis.
993 */
994 public double getSpecificForcePsdY() {
995 return accelerationEstimator.getPsdY();
996 }
997
998 /**
999 * Gets accelerometer noise PSD (Power Spectral Density) on z axis expressed
1000 * in (m^2 * s^-3).
1001 *
1002 * @return accelerometer noise PSD on z axis.
1003 */
1004 public double getSpecificForcePsdZ() {
1005 return accelerationEstimator.getPsdZ();
1006 }
1007
1008 /**
1009 * Gets gyroscope noise PSD (Power Spectral Density) on x axis expressed
1010 * in (rad^2/s).
1011 *
1012 * @return gyroscope noise PSD on x axis.
1013 */
1014 public double getAngularRatePsdX() {
1015 return angularSpeedEstimator.getPsdX();
1016 }
1017
1018 /**
1019 * Gets gyroscope noise PSD (Power Spectral Density) on y axis expressed
1020 * in (rad^2/s).
1021 *
1022 * @return gyroscope noise PSD on y axis.
1023 */
1024 public double getAngularRatePsdY() {
1025 return angularSpeedEstimator.getPsdY();
1026 }
1027
1028 /**
1029 * Gets gyroscope noise PSD (Power Spectral Density) on z axis expressed
1030 * in (rad^2/s).
1031 *
1032 * @return gyroscope noise PSD on z axis.
1033 */
1034 public double getAngularRatePsdZ() {
1035 return angularSpeedEstimator.getPsdZ();
1036 }
1037
1038 /**
1039 * Gets accelerometer noise root PSD (Power Spectral Density) on x axis
1040 * expressed in (m * s^-1.5).
1041 *
1042 * @return accelerometer noise root PSD on x axis.
1043 */
1044 public double getSpecificForceRootPsdX() {
1045 return accelerationEstimator.getRootPsdX();
1046 }
1047
1048 /**
1049 * Gets accelerometer noise root PSD (Power Spectral Density) on y axis
1050 * expressed in (m * s^-1.5).
1051 *
1052 * @return accelerometer noise root PSD on y axis.
1053 */
1054 public double getSpecificForceRootPsdY() {
1055 return accelerationEstimator.getRootPsdY();
1056 }
1057
1058 /**
1059 * Gets accelerometer noise root PSD (Power Spectral Density) on z axis
1060 * expressed in (m * s^-1.5).
1061 *
1062 * @return accelerometer noise root PSD on z axis.
1063 */
1064 public double getSpecificForceRootPsdZ() {
1065 return accelerationEstimator.getRootPsdZ();
1066 }
1067
1068 /**
1069 * Gets gyroscope noise root PSD (Power Spectral Density) on x axis
1070 * expressed in (rad * s^-0.5).
1071 *
1072 * @return gyroscope noise root PSD on x axis.
1073 */
1074 public double getAngularRateRootPsdX() {
1075 return angularSpeedEstimator.getRootPsdX();
1076 }
1077
1078 /**
1079 * Gets gyroscope noise root PSD (Power Spectral Density) on y axis
1080 * expressed in (rad * s^-0.5).
1081 *
1082 * @return gyroscope noise root PSD on y axis.
1083 */
1084 public double getAngularRateRootPsdY() {
1085 return angularSpeedEstimator.getRootPsdY();
1086 }
1087
1088 /**
1089 * Gets gyroscope noise root PSD (Power Spectral Density) on z axis
1090 * expressed in (rad * s^-0.5).
1091 *
1092 * @return gyroscope noise root PSD on z axis.
1093 */
1094 public double getAngularRateRootPsdZ() {
1095 return angularSpeedEstimator.getRootPsdZ();
1096 }
1097
1098 /**
1099 * Gets average accelerometer noise PSD (Power Spectral Density) among
1100 * x,y,z components expressed as (m^2/s^-3).
1101 *
1102 * @return average accelerometer noise PSD.
1103 */
1104 public double getAvgSpecificForceNoisePsd() {
1105 return accelerationEstimator.getAvgNoisePsd();
1106 }
1107
1108 /**
1109 * Gets norm of noise root PSD (Power Spectral Density) among x,y,z
1110 * components expressed as (m * s^-1.5).
1111 *
1112 * @return norm of noise root PSD.
1113 */
1114 public double getSpecificForceNoiseRootPsdNorm() {
1115 return accelerationEstimator.getNoiseRootPsdNorm();
1116 }
1117
1118 /**
1119 * Gets average gyroscope noise PSD (Power Spectral Density) among
1120 * x,y,z components expressed in (rad^2/s).
1121 *
1122 * @return average gyroscope noise PSD.
1123 */
1124 public double getAvgAngularRateNoisePsd() {
1125 return angularSpeedEstimator.getAvgNoisePsd();
1126 }
1127
1128 /**
1129 * Gets norm of noise root PSD (Power Spectral Density) among x,y,z
1130 * components expressed as (rad * s^-0.5).
1131 *
1132 * @return norm of noise root PSD.
1133 */
1134 public double getAngularRateNoiseRootPsdNorm() {
1135 return angularSpeedEstimator.getNoiseRootPsdNorm();
1136 }
1137
1138 /**
1139 * Gets number of samples that have been processed so far.
1140 *
1141 * @return number of samples that have been processed so far.
1142 */
1143 public int getNumberOfProcessedSamples() {
1144 return accelerationEstimator.getNumberOfProcessedSamples();
1145 }
1146
1147 /**
1148 * Indicates whether estimator is currently running or not.
1149 *
1150 * @return true if estimator is running, false otherwise.
1151 */
1152 public boolean isRunning() {
1153 return running;
1154 }
1155
1156 /**
1157 * Adds body kinematics measurement samples.
1158 *
1159 * @param specificForceX x coordinate of specific force expressed in meters per squared second (m/s^2).
1160 * @param specificForceY y coordinate of specific force expressed in meters per squared second (m/s^2).
1161 * @param specificForceZ z coordinate of specific force expressed in meters per squared second (m/s^2).
1162 * @param angularRateX x coordinate of angular rate expressed in radians per second (rad/s).
1163 * @param angularRateY y coordinate of angular rate expressed in radians per second (rad/s).
1164 * @param angularRateZ z coordinate of angular rate expressed in radians per second (rad/s).
1165 * @throws LockedException if estimator is currently running.
1166 */
1167 public void addBodyKinematics(
1168 final double specificForceX, final double specificForceY, final double specificForceZ,
1169 final double angularRateX, final double angularRateY, final double angularRateZ) throws LockedException {
1170
1171 if (running) {
1172 throw new LockedException();
1173 }
1174
1175 running = true;
1176
1177 if (lastBodyKinematics == null && listener != null) {
1178 listener.onStart(this);
1179 }
1180
1181 if (lastBodyKinematics == null) {
1182 lastBodyKinematics = new BodyKinematics();
1183 }
1184 lastBodyKinematics.setSpecificForceCoordinates(specificForceX, specificForceY, specificForceZ);
1185 lastBodyKinematics.setAngularRateCoordinates(angularRateX, angularRateY, angularRateZ);
1186
1187 accelerationEstimator.addTriad(specificForceX, specificForceY, specificForceZ);
1188 angularSpeedEstimator.addTriad(angularRateX, angularRateY, angularRateZ);
1189
1190 if (listener != null) {
1191 listener.onBodyKinematicsAdded(this);
1192 }
1193
1194 running = false;
1195 }
1196
1197 /**
1198 * Adds body kinematics measurement samples.
1199 *
1200 * @param specificForceX x coordinate of specific force.
1201 * @param specificForceY y coordinate of specific force.
1202 * @param specificForceZ z coordinate of specific force.
1203 * @param angularRateX x coordinate of angular rate.
1204 * @param angularRateY y coordinate of angular rate.
1205 * @param angularRateZ z coordinate of angular rate.
1206 * @throws LockedException if estimator is currently running.
1207 */
1208 public void addBodyKinematics(
1209 final Acceleration specificForceX, final Acceleration specificForceY, final Acceleration specificForceZ,
1210 final AngularSpeed angularRateX, final AngularSpeed angularRateY, final AngularSpeed angularRateZ)
1211 throws LockedException {
1212 addBodyKinematics(convertAcceleration(specificForceX),
1213 convertAcceleration(specificForceY),
1214 convertAcceleration(specificForceZ),
1215 convertAngularSpeed(angularRateX),
1216 convertAngularSpeed(angularRateY),
1217 convertAngularSpeed(angularRateZ));
1218 }
1219
1220 /**
1221 * Adds body kinematics measurement samples.
1222 *
1223 * @param specificForce specific force triad.
1224 * @param angularSpeed angular speed triad.
1225 * @throws LockedException if estimator is currently running.
1226 */
1227 public void addBodyKinematics(
1228 final AccelerationTriad specificForce, final AngularSpeedTriad angularSpeed) throws LockedException {
1229 addBodyKinematics(convertAcceleration(specificForce.getValueX(), specificForce.getUnit()),
1230 convertAcceleration(specificForce.getValueY(), specificForce.getUnit()),
1231 convertAcceleration(specificForce.getValueZ(), specificForce.getUnit()),
1232 convertAngularSpeed(angularSpeed.getValueX(), angularSpeed.getUnit()),
1233 convertAngularSpeed(angularSpeed.getValueY(), angularSpeed.getUnit()),
1234 convertAngularSpeed(angularSpeed.getValueZ(), angularSpeed.getUnit()));
1235 }
1236
1237 /**
1238 * Adds body kinematics measurement.
1239 *
1240 * @param bodyKinematics body kinematics.
1241 * @throws LockedException if estimator is currently running.
1242 */
1243 public void addBodyKinematics(final BodyKinematics bodyKinematics) throws LockedException {
1244 addBodyKinematics(bodyKinematics.getFx(), bodyKinematics.getFy(), bodyKinematics.getFz(),
1245 bodyKinematics.getAngularRateX(), bodyKinematics.getAngularRateY(), bodyKinematics.getAngularRateZ());
1246 }
1247
1248 /**
1249 * Resets current estimator.
1250 *
1251 * @return true if estimator was successfully reset, false if no reset was needed.
1252 * @throws LockedException if estimator is currently running.
1253 */
1254 public boolean reset() throws LockedException {
1255 if (running) {
1256 throw new LockedException();
1257 }
1258
1259 running = true;
1260
1261 lastBodyKinematics = null;
1262 final var result = accelerationEstimator.reset() && angularSpeedEstimator.reset();
1263
1264 if (listener != null) {
1265 listener.onReset(this);
1266 }
1267
1268 running = false;
1269
1270 return result;
1271 }
1272
1273 /**
1274 * Converts an acceleration instance to meters per squared seconds (m/s^2).
1275 *
1276 * @param value value to be converted.
1277 * @return converted value.
1278 */
1279 private double convertAcceleration(final Acceleration value) {
1280 return AccelerationConverter.convert(value.getValue().doubleValue(), value.getUnit(),
1281 AccelerationUnit.METERS_PER_SQUARED_SECOND);
1282 }
1283
1284 /**
1285 * Converts an acceleration value and unit to meters per squared seconds (m/s^2).
1286 *
1287 * @param value value to be converted.
1288 * @param unit unit of value to be converted.
1289 * @return converted value.
1290 */
1291 private double convertAcceleration(final double value, final AccelerationUnit unit) {
1292 return AccelerationConverter.convert(value, unit, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1293 }
1294
1295 /**
1296 * Converts an angular speed instance to radians per second (rad/s).
1297 *
1298 * @param value value to be converted.
1299 * @return converted value.
1300 */
1301 private double convertAngularSpeed(final AngularSpeed value) {
1302 return AngularSpeedConverter.convert(value.getValue().doubleValue(), value.getUnit(),
1303 AngularSpeedUnit.RADIANS_PER_SECOND);
1304 }
1305
1306 /**
1307 * Converts an angular speed value and unit to radians per second (rad/s).
1308 *
1309 * @param value value to be converted.
1310 * @param unit unit of value to be converted.
1311 * @return converted value.
1312 */
1313 private double convertAngularSpeed(final double value, final AngularSpeedUnit unit) {
1314 return AngularSpeedConverter.convert(value, unit, AngularSpeedUnit.RADIANS_PER_SECOND);
1315 }
1316
1317 /**
1318 * Gets accelerometer base noise level root PSD (Power Spectral Density)
1319 * expressed in (m * s^-1.5).
1320 *
1321 * @return accelerometer base noise level root PSD.
1322 */
1323 @Override
1324 public double getAccelerometerBaseNoiseLevelRootPsd() {
1325 return getSpecificForceNoiseRootPsdNorm();
1326 }
1327
1328 /**
1329 * Gets gyroscope base noise level root PSD (Power Spectral Density)
1330 * expressed in (rad * s^-0.5)
1331 *
1332 * @return gyroscope base noise level root PSD.
1333 */
1334 @Override
1335 public double getGyroscopeBaseNoiseLevelRootPsd() {
1336 return getAngularRateNoiseRootPsdNorm();
1337 }
1338 }