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.navigation.LockedException; 22 import com.irurueta.navigation.NotReadyException; 23 import com.irurueta.navigation.frames.ECEFFrame; 24 import com.irurueta.navigation.frames.NEDFrame; 25 import com.irurueta.navigation.inertial.BodyKinematics; 26 import com.irurueta.navigation.inertial.INSException; 27 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanConfig; 28 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanFilteredEstimator; 29 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanInitializerConfig; 30 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanState; 31 32 /** 33 * Estimates accumulated drift in body orientation, position and velocity per 34 * unit of time using an INS Kalman filtered solution. 35 */ 36 public class KalmanDriftEstimator extends DriftEstimator { 37 38 /** 39 * Configuration parameters for INS Loosely Coupled Kalman filter obtained 40 * through calibration. 41 */ 42 private INSLooselyCoupledKalmanConfig kalmanConfig; 43 44 /** 45 * Configuration parameters determining initial system noise covariance matrix. 46 */ 47 private INSLooselyCoupledKalmanInitializerConfig initConfig; 48 49 /** 50 * Internal INS loosely coupled Kalman filtered estimator to estimate 51 * accumulated body position, velocity and orientation. 52 */ 53 private INSLooselyCoupledKalmanFilteredEstimator kalmanEstimator; 54 55 /** 56 * Current Kalman filter state. 57 */ 58 private INSLooselyCoupledKalmanState state; 59 60 /** 61 * Constructor. 62 */ 63 public KalmanDriftEstimator() { 64 super(); 65 } 66 67 /** 68 * Constructor. 69 * 70 * @param listener listener to handle events. 71 */ 72 public KalmanDriftEstimator(final DriftEstimatorListener listener) { 73 super(listener); 74 } 75 76 /** 77 * Constructor. 78 * 79 * @param kalmanConfig configuration parameters obtained through calibration. 80 * @param initConfig configuration parameters determining initial system 81 * noise covariance matrix. 82 */ 83 public KalmanDriftEstimator( 84 final INSLooselyCoupledKalmanConfig kalmanConfig, 85 final INSLooselyCoupledKalmanInitializerConfig initConfig) { 86 this.kalmanConfig = kalmanConfig; 87 this.initConfig = initConfig; 88 } 89 90 /** 91 * Constructor. 92 * 93 * @param kalmanConfig configuration parameters obtained through calibration. 94 * @param initConfig configuration parameters determining initial system 95 * noise covariance matrix. 96 * @param listener listener to handle events. 97 */ 98 public KalmanDriftEstimator( 99 final INSLooselyCoupledKalmanConfig kalmanConfig, 100 final INSLooselyCoupledKalmanInitializerConfig initConfig, 101 final DriftEstimatorListener listener) { 102 super(listener); 103 this.kalmanConfig = kalmanConfig; 104 this.initConfig = initConfig; 105 } 106 107 /** 108 * Constructor. 109 * 110 * @param referenceFrame initial frame containing body position, velocity and 111 * orientation expressed in ECEF coordinates. 112 * @param kalmanConfig configuration parameters obtained through calibration. 113 * @param initConfig configuration parameters determining initial system 114 * noise covariance matrix. 115 */ 116 public KalmanDriftEstimator( 117 final ECEFFrame referenceFrame, 118 final INSLooselyCoupledKalmanConfig kalmanConfig, 119 final INSLooselyCoupledKalmanInitializerConfig initConfig) { 120 super(referenceFrame); 121 this.kalmanConfig = kalmanConfig; 122 this.initConfig = initConfig; 123 } 124 125 /** 126 * Constructor. 127 * 128 * @param referenceFrame initial frame containing body position, velocity and 129 * orientation expressed in ECEF coordinates. 130 * @param kalmanConfig configuration parameters obtained through calibration. 131 * @param initConfig configuration parameters determining initial system 132 * noise covariance matrix. 133 * @param listener listener to handle events. 134 */ 135 public KalmanDriftEstimator( 136 final ECEFFrame referenceFrame, 137 final INSLooselyCoupledKalmanConfig kalmanConfig, 138 final INSLooselyCoupledKalmanInitializerConfig initConfig, 139 final DriftEstimatorListener listener) { 140 super(referenceFrame, listener); 141 this.kalmanConfig = kalmanConfig; 142 this.initConfig = initConfig; 143 } 144 145 /** 146 * Constructor. 147 * 148 * @param referenceFrame initial frame containing body position, velocity and 149 * orientation expressed in NED coordinates. 150 * @param kalmanConfig configuration parameters obtained through calibration. 151 * @param initConfig configuration parameters determining initial system 152 * noise covariance matrix. 153 */ 154 public KalmanDriftEstimator( 155 final NEDFrame referenceFrame, 156 final INSLooselyCoupledKalmanConfig kalmanConfig, 157 final INSLooselyCoupledKalmanInitializerConfig initConfig) { 158 super(referenceFrame); 159 this.kalmanConfig = kalmanConfig; 160 this.initConfig = initConfig; 161 } 162 163 /** 164 * Constructor. 165 * 166 * @param referenceFrame initial frame containing body position, velocity and 167 * orientation expressed in NED coordinates. 168 * @param kalmanConfig configuration parameters obtained through calibration. 169 * @param initConfig configuration parameters determining initial system 170 * noise covariance matrix. 171 * @param listener listener to handle events. 172 */ 173 public KalmanDriftEstimator( 174 final NEDFrame referenceFrame, 175 final INSLooselyCoupledKalmanConfig kalmanConfig, 176 final INSLooselyCoupledKalmanInitializerConfig initConfig, 177 final DriftEstimatorListener listener) { 178 super(referenceFrame, listener); 179 this.kalmanConfig = kalmanConfig; 180 this.initConfig = initConfig; 181 } 182 183 /** 184 * Constructor. 185 * 186 * @param ba acceleration bias to be set. 187 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 188 * @param bg angular speed bias to be set. 189 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 190 * @param kalmanConfig configuration parameters obtained through calibration. 191 * @param initConfig configuration parameters determining initial system 192 * noise covariance matrix. 193 * @throws AlgebraException if provided cross-coupling matrices cannot 194 * be inverted. 195 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 196 */ 197 public KalmanDriftEstimator( 198 final AccelerationTriad ba, 199 final Matrix ma, 200 final AngularSpeedTriad bg, 201 final Matrix mg, 202 final INSLooselyCoupledKalmanConfig kalmanConfig, 203 final INSLooselyCoupledKalmanInitializerConfig initConfig) 204 throws AlgebraException { 205 super(ba, ma, bg, mg); 206 this.kalmanConfig = kalmanConfig; 207 this.initConfig = initConfig; 208 } 209 210 /** 211 * Constructor. 212 * 213 * @param ba acceleration bias to be set. 214 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 215 * @param bg angular speed bias to be set. 216 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 217 * @param kalmanConfig configuration parameters obtained through calibration. 218 * @param initConfig configuration parameters determining initial system 219 * noise covariance matrix. 220 * @param listener listener to handle events. 221 * @throws AlgebraException if provided cross-coupling matrices cannot 222 * be inverted. 223 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 224 */ 225 public KalmanDriftEstimator( 226 final AccelerationTriad ba, 227 final Matrix ma, 228 final AngularSpeedTriad bg, 229 final Matrix mg, 230 final INSLooselyCoupledKalmanConfig kalmanConfig, 231 final INSLooselyCoupledKalmanInitializerConfig initConfig, 232 final DriftEstimatorListener listener) throws AlgebraException { 233 super(ba, ma, bg, mg, listener); 234 this.kalmanConfig = kalmanConfig; 235 this.initConfig = initConfig; 236 } 237 238 /** 239 * Constructor. 240 * 241 * @param ba acceleration bias to be set. 242 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 243 * @param bg angular speed bias to be set. 244 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 245 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 246 * @param kalmanConfig configuration parameters obtained through calibration. 247 * @param initConfig configuration parameters determining initial system 248 * noise covariance matrix. 249 * @throws AlgebraException if provided cross-coupling matrices cannot 250 * be inverted. 251 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 252 */ 253 public KalmanDriftEstimator( 254 final AccelerationTriad ba, 255 final Matrix ma, 256 final AngularSpeedTriad bg, 257 final Matrix mg, 258 final Matrix gg, 259 final INSLooselyCoupledKalmanConfig kalmanConfig, 260 final INSLooselyCoupledKalmanInitializerConfig initConfig) 261 throws AlgebraException { 262 super(ba, ma, bg, mg, gg); 263 this.kalmanConfig = kalmanConfig; 264 this.initConfig = initConfig; 265 } 266 267 /** 268 * Constructor. 269 * 270 * @param ba acceleration bias to be set. 271 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 272 * @param bg angular speed bias to be set. 273 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 274 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 275 * @param kalmanConfig configuration parameters obtained through calibration. 276 * @param initConfig configuration parameters determining initial system 277 * noise covariance matrix. 278 * @param listener listener to handle events. 279 * @throws AlgebraException if provided cross-coupling matrices cannot 280 * be inverted. 281 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 282 */ 283 public KalmanDriftEstimator( 284 final AccelerationTriad ba, 285 final Matrix ma, 286 final AngularSpeedTriad bg, 287 final Matrix mg, 288 final Matrix gg, 289 final INSLooselyCoupledKalmanConfig kalmanConfig, 290 final INSLooselyCoupledKalmanInitializerConfig initConfig, 291 final DriftEstimatorListener listener) throws AlgebraException { 292 super(ba, ma, bg, mg, gg, listener); 293 this.kalmanConfig = kalmanConfig; 294 this.initConfig = initConfig; 295 } 296 297 /** 298 * Constructor. 299 * 300 * @param ba acceleration bias to be set expressed in meters per squared second 301 * (m/s`2). Must be 3x1. 302 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 303 * @param bg angular speed bias to be set expressed in radians per second 304 * (rad/s). Must be 3x1. 305 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 306 * @param kalmanConfig configuration parameters obtained through calibration. 307 * @param initConfig configuration parameters determining initial system 308 * noise covariance matrix. 309 * @throws AlgebraException if provided cross-coupling matrices cannot 310 * be inverted. 311 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 312 */ 313 public KalmanDriftEstimator( 314 final Matrix ba, 315 final Matrix ma, 316 final Matrix bg, 317 final Matrix mg, 318 final INSLooselyCoupledKalmanConfig kalmanConfig, 319 final INSLooselyCoupledKalmanInitializerConfig initConfig) 320 throws AlgebraException { 321 super(ba, ma, bg, mg); 322 this.kalmanConfig = kalmanConfig; 323 this.initConfig = initConfig; 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 * @param kalmanConfig configuration parameters obtained through calibration. 336 * @param initConfig configuration parameters determining initial system 337 * noise covariance matrix. 338 * @param listener listener to handle events. 339 * @throws AlgebraException if provided cross-coupling matrices cannot 340 * be inverted. 341 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 342 */ 343 public KalmanDriftEstimator( 344 final Matrix ba, 345 final Matrix ma, 346 final Matrix bg, 347 final Matrix mg, 348 final INSLooselyCoupledKalmanConfig kalmanConfig, 349 final INSLooselyCoupledKalmanInitializerConfig initConfig, 350 final DriftEstimatorListener listener) throws AlgebraException { 351 super(ba, ma, bg, mg, listener); 352 this.kalmanConfig = kalmanConfig; 353 this.initConfig = initConfig; 354 } 355 356 /** 357 * Constructor. 358 * 359 * @param ba acceleration bias to be set expressed in meters per squared second 360 * (m/s`2). Must be 3x1. 361 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 362 * @param bg angular speed bias to be set expressed in radians per second 363 * (rad/s). Must be 3x1. 364 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 365 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 366 * @param kalmanConfig configuration parameters obtained through calibration. 367 * @param initConfig configuration parameters determining initial system 368 * noise covariance matrix. 369 * @throws AlgebraException if provided cross-coupling matrices cannot 370 * be inverted. 371 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 372 */ 373 public KalmanDriftEstimator( 374 final Matrix ba, 375 final Matrix ma, 376 final Matrix bg, 377 final Matrix mg, 378 final Matrix gg, 379 final INSLooselyCoupledKalmanConfig kalmanConfig, 380 final INSLooselyCoupledKalmanInitializerConfig initConfig) 381 throws AlgebraException { 382 super(ba, ma, bg, mg, gg); 383 this.kalmanConfig = kalmanConfig; 384 this.initConfig = initConfig; 385 } 386 387 /** 388 * Constructor. 389 * 390 * @param ba acceleration bias to be set expressed in meters per squared second 391 * (m/s`2). Must be 3x1. 392 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 393 * @param bg angular speed bias to be set expressed in radians per second 394 * (rad/s). Must be 3x1. 395 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 396 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 397 * @param kalmanConfig configuration parameters obtained through calibration. 398 * @param initConfig configuration parameters determining initial system 399 * noise covariance matrix. 400 * @param listener listener to handle events. 401 * @throws AlgebraException if provided cross-coupling matrices cannot 402 * be inverted. 403 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 404 */ 405 public KalmanDriftEstimator( 406 final Matrix ba, 407 final Matrix ma, 408 final Matrix bg, 409 final Matrix mg, 410 final Matrix gg, 411 final INSLooselyCoupledKalmanConfig kalmanConfig, 412 final INSLooselyCoupledKalmanInitializerConfig initConfig, 413 final DriftEstimatorListener listener) throws AlgebraException { 414 super(ba, ma, bg, mg, gg, listener); 415 this.kalmanConfig = kalmanConfig; 416 this.initConfig = initConfig; 417 } 418 419 /** 420 * Constructor. 421 * 422 * @param referenceFrame initial frame containing body position, velocity and 423 * orientation expressed in ECEF coordinates. 424 * @param ba acceleration bias to be set. 425 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 426 * @param bg angular speed bias to be set. 427 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 428 * @param kalmanConfig configuration parameters obtained through calibration. 429 * @param initConfig configuration parameters determining initial system 430 * noise covariance matrix. 431 * @throws AlgebraException if provided cross-coupling matrices cannot 432 * be inverted. 433 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 434 */ 435 public KalmanDriftEstimator( 436 final ECEFFrame referenceFrame, 437 final AccelerationTriad ba, 438 final Matrix ma, 439 final AngularSpeedTriad bg, 440 final Matrix mg, 441 final INSLooselyCoupledKalmanConfig kalmanConfig, 442 final INSLooselyCoupledKalmanInitializerConfig initConfig) 443 throws AlgebraException { 444 super(referenceFrame, ba, ma, bg, mg); 445 this.kalmanConfig = kalmanConfig; 446 this.initConfig = initConfig; 447 } 448 449 /** 450 * Constructor. 451 * 452 * @param referenceFrame initial frame containing body position, velocity and 453 * orientation expressed in ECEF coordinates. 454 * @param ba acceleration bias to be set. 455 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 456 * @param bg angular speed bias to be set. 457 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 458 * @param kalmanConfig configuration parameters obtained through calibration. 459 * @param initConfig configuration parameters determining initial system 460 * noise covariance matrix. 461 * @param listener listener to handle events. 462 * @throws AlgebraException if provided cross-coupling matrices cannot 463 * be inverted. 464 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 465 */ 466 public KalmanDriftEstimator( 467 final ECEFFrame referenceFrame, 468 final AccelerationTriad ba, 469 final Matrix ma, 470 final AngularSpeedTriad bg, 471 final Matrix mg, 472 final INSLooselyCoupledKalmanConfig kalmanConfig, 473 final INSLooselyCoupledKalmanInitializerConfig initConfig, 474 final DriftEstimatorListener listener) throws AlgebraException { 475 super(referenceFrame, ba, ma, bg, mg, listener); 476 this.kalmanConfig = kalmanConfig; 477 this.initConfig = initConfig; 478 } 479 480 /** 481 * Constructor. 482 * 483 * @param referenceFrame initial frame containing body position, velocity and 484 * orientation expressed in ECEF coordinates. 485 * @param ba acceleration bias to be set. 486 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 487 * @param bg angular speed bias to be set. 488 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 489 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 490 * @param kalmanConfig configuration parameters obtained through calibration. 491 * @param initConfig configuration parameters determining initial system 492 * noise covariance matrix. 493 * @throws AlgebraException if provided cross-coupling matrices cannot 494 * be inverted. 495 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 496 */ 497 public KalmanDriftEstimator( 498 final ECEFFrame referenceFrame, 499 final AccelerationTriad ba, 500 final Matrix ma, 501 final AngularSpeedTriad bg, 502 final Matrix mg, 503 final Matrix gg, 504 final INSLooselyCoupledKalmanConfig kalmanConfig, 505 final INSLooselyCoupledKalmanInitializerConfig initConfig) 506 throws AlgebraException { 507 super(referenceFrame, ba, ma, bg, mg, gg); 508 this.kalmanConfig = kalmanConfig; 509 this.initConfig = initConfig; 510 } 511 512 /** 513 * Constructor. 514 * 515 * @param referenceFrame initial frame containing body position, velocity and 516 * orientation expressed in ECEF coordinates. 517 * @param ba acceleration bias to be set. 518 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 519 * @param bg angular speed bias to be set. 520 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 521 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 522 * @param kalmanConfig configuration parameters obtained through calibration. 523 * @param initConfig configuration parameters determining initial system 524 * noise covariance matrix. 525 * @param listener listener to handle events. 526 * @throws AlgebraException if provided cross-coupling matrices cannot 527 * be inverted. 528 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 529 */ 530 public KalmanDriftEstimator( 531 final ECEFFrame referenceFrame, 532 final AccelerationTriad ba, 533 final Matrix ma, 534 final AngularSpeedTriad bg, 535 final Matrix mg, 536 final Matrix gg, 537 final INSLooselyCoupledKalmanConfig kalmanConfig, 538 final INSLooselyCoupledKalmanInitializerConfig initConfig, 539 final DriftEstimatorListener listener) throws AlgebraException { 540 super(referenceFrame, ba, ma, bg, mg, gg, listener); 541 this.kalmanConfig = kalmanConfig; 542 this.initConfig = initConfig; 543 } 544 545 /** 546 * Constructor. 547 * 548 * @param referenceFrame initial frame containing body position, velocity and 549 * orientation expressed in ECEF coordinates. 550 * @param ba acceleration bias to be set expressed in meters per squared second 551 * (m/s`2). Must be 3x1. 552 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 553 * @param bg angular speed bias to be set expressed in radians per second 554 * (rad/s). Must be 3x1. 555 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 556 * @param kalmanConfig configuration parameters obtained through calibration. 557 * @param initConfig configuration parameters determining initial system 558 * noise covariance matrix. 559 * @throws AlgebraException if provided cross-coupling matrices cannot 560 * be inverted. 561 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 562 */ 563 public KalmanDriftEstimator( 564 final ECEFFrame referenceFrame, 565 final Matrix ba, 566 final Matrix ma, 567 final Matrix bg, 568 final Matrix mg, 569 final INSLooselyCoupledKalmanConfig kalmanConfig, 570 final INSLooselyCoupledKalmanInitializerConfig initConfig) 571 throws AlgebraException { 572 super(referenceFrame, ba, ma, bg, mg); 573 this.kalmanConfig = kalmanConfig; 574 this.initConfig = initConfig; 575 } 576 577 /** 578 * Constructor. 579 * 580 * @param referenceFrame initial frame containing body position, velocity and 581 * orientation expressed in ECEF coordinates. 582 * @param ba acceleration bias to be set expressed in meters per squared second 583 * (m/s`2). Must be 3x1. 584 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 585 * @param bg angular speed bias to be set expressed in radians per second 586 * (rad/s). Must be 3x1. 587 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 588 * @param kalmanConfig configuration parameters obtained through calibration. 589 * @param initConfig configuration parameters determining initial system 590 * noise covariance matrix. 591 * @param listener listener to handle events. 592 * @throws AlgebraException if provided cross-coupling matrices cannot 593 * be inverted. 594 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 595 */ 596 public KalmanDriftEstimator( 597 final ECEFFrame referenceFrame, 598 final Matrix ba, 599 final Matrix ma, 600 final Matrix bg, 601 final Matrix mg, 602 final INSLooselyCoupledKalmanConfig kalmanConfig, 603 final INSLooselyCoupledKalmanInitializerConfig initConfig, 604 final DriftEstimatorListener listener) throws AlgebraException { 605 super(referenceFrame, ba, ma, bg, mg, listener); 606 this.kalmanConfig = kalmanConfig; 607 this.initConfig = initConfig; 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 kalmanConfig configuration parameters obtained through calibration. 623 * @param initConfig configuration parameters determining initial system 624 * noise covariance matrix. 625 * @throws AlgebraException if provided cross-coupling matrices cannot 626 * be inverted. 627 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 628 */ 629 public KalmanDriftEstimator( 630 final ECEFFrame referenceFrame, 631 final Matrix ba, 632 final Matrix ma, 633 final Matrix bg, 634 final Matrix mg, 635 final Matrix gg, 636 final INSLooselyCoupledKalmanConfig kalmanConfig, 637 final INSLooselyCoupledKalmanInitializerConfig initConfig) 638 throws AlgebraException { 639 super(referenceFrame, ba, ma, bg, mg, gg); 640 this.kalmanConfig = kalmanConfig; 641 this.initConfig = initConfig; 642 } 643 644 /** 645 * Constructor. 646 * 647 * @param referenceFrame initial frame containing body position, velocity and 648 * orientation expressed in ECEF coordinates. 649 * @param ba acceleration bias to be set expressed in meters per squared second 650 * (m/s`2). Must be 3x1. 651 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 652 * @param bg angular speed bias to be set expressed in radians per second 653 * (rad/s). Must be 3x1. 654 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 655 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 656 * @param kalmanConfig configuration parameters obtained through calibration. 657 * @param initConfig configuration parameters determining initial system 658 * noise covariance matrix. 659 * @param listener listener to handle events. 660 * @throws AlgebraException if provided cross-coupling matrices cannot 661 * be inverted. 662 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 663 */ 664 public KalmanDriftEstimator( 665 final ECEFFrame referenceFrame, 666 final Matrix ba, 667 final Matrix ma, 668 final Matrix bg, 669 final Matrix mg, 670 final Matrix gg, 671 final INSLooselyCoupledKalmanConfig kalmanConfig, 672 final INSLooselyCoupledKalmanInitializerConfig initConfig, 673 final DriftEstimatorListener listener) throws AlgebraException { 674 super(referenceFrame, ba, ma, bg, mg, gg, listener); 675 this.kalmanConfig = kalmanConfig; 676 this.initConfig = initConfig; 677 } 678 679 /** 680 * Constructor. 681 * 682 * @param referenceFrame initial frame containing body position, velocity and 683 * orientation expressed in NED coordinates. 684 * @param ba acceleration bias to be set. 685 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 686 * @param bg angular speed bias to be set. 687 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 688 * @param kalmanConfig configuration parameters obtained through calibration. 689 * @param initConfig configuration parameters determining initial system 690 * noise covariance matrix. 691 * @throws AlgebraException if provided cross-coupling matrices cannot 692 * be inverted. 693 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 694 */ 695 public KalmanDriftEstimator( 696 final NEDFrame referenceFrame, 697 final AccelerationTriad ba, 698 final Matrix ma, 699 final AngularSpeedTriad bg, 700 final Matrix mg, 701 final INSLooselyCoupledKalmanConfig kalmanConfig, 702 final INSLooselyCoupledKalmanInitializerConfig initConfig) 703 throws AlgebraException { 704 super(referenceFrame, ba, ma, bg, mg); 705 this.kalmanConfig = kalmanConfig; 706 this.initConfig = initConfig; 707 } 708 709 /** 710 * Constructor. 711 * 712 * @param referenceFrame initial frame containing body position, velocity and 713 * orientation expressed in NED coordinates. 714 * @param ba acceleration bias to be set. 715 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 716 * @param bg angular speed bias to be set. 717 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 718 * @param kalmanConfig configuration parameters obtained through calibration. 719 * @param initConfig configuration parameters determining initial system 720 * noise covariance matrix. 721 * @param listener listener to handle events. 722 * @throws AlgebraException if provided cross-coupling matrices cannot 723 * be inverted. 724 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 725 */ 726 public KalmanDriftEstimator( 727 final NEDFrame referenceFrame, 728 final AccelerationTriad ba, 729 final Matrix ma, 730 final AngularSpeedTriad bg, 731 final Matrix mg, 732 final INSLooselyCoupledKalmanConfig kalmanConfig, 733 final INSLooselyCoupledKalmanInitializerConfig initConfig, 734 final DriftEstimatorListener listener) throws AlgebraException { 735 super(referenceFrame, ba, ma, bg, mg, listener); 736 this.kalmanConfig = kalmanConfig; 737 this.initConfig = initConfig; 738 } 739 740 /** 741 * Constructor. 742 * 743 * @param referenceFrame initial frame containing body position, velocity and 744 * orientation expressed in NED coordinates. 745 * @param ba acceleration bias to be set. 746 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 747 * @param bg angular speed bias to be set. 748 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 749 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 750 * @param kalmanConfig configuration parameters obtained through calibration. 751 * @param initConfig configuration parameters determining initial system 752 * noise covariance matrix. 753 * @throws AlgebraException if provided cross-coupling matrices cannot 754 * be inverted. 755 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 756 */ 757 public KalmanDriftEstimator( 758 final NEDFrame referenceFrame, 759 final AccelerationTriad ba, 760 final Matrix ma, 761 final AngularSpeedTriad bg, 762 final Matrix mg, 763 final Matrix gg, 764 final INSLooselyCoupledKalmanConfig kalmanConfig, 765 final INSLooselyCoupledKalmanInitializerConfig initConfig) 766 throws AlgebraException { 767 super(referenceFrame, ba, ma, bg, mg, gg); 768 this.kalmanConfig = kalmanConfig; 769 this.initConfig = initConfig; 770 } 771 772 /** 773 * Constructor. 774 * 775 * @param referenceFrame initial frame containing body position, velocity and 776 * orientation expressed in NED coordinates. 777 * @param ba acceleration bias to be set. 778 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 779 * @param bg angular speed bias to be set. 780 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 781 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 782 * @param kalmanConfig configuration parameters obtained through calibration. 783 * @param initConfig configuration parameters determining initial system 784 * noise covariance matrix. 785 * @param listener listener to handle events. 786 * @throws AlgebraException if provided cross-coupling matrices cannot 787 * be inverted. 788 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 789 */ 790 public KalmanDriftEstimator( 791 final NEDFrame referenceFrame, 792 final AccelerationTriad ba, 793 final Matrix ma, 794 final AngularSpeedTriad bg, 795 final Matrix mg, 796 final Matrix gg, 797 final INSLooselyCoupledKalmanConfig kalmanConfig, 798 final INSLooselyCoupledKalmanInitializerConfig initConfig, 799 final DriftEstimatorListener listener) throws AlgebraException { 800 super(referenceFrame, ba, ma, bg, mg, gg, listener); 801 this.kalmanConfig = kalmanConfig; 802 this.initConfig = initConfig; 803 } 804 805 /** 806 * Constructor. 807 * 808 * @param referenceFrame initial frame containing body position, velocity and 809 * orientation expressed in NED coordinates. 810 * @param ba acceleration bias to be set expressed in meters per squared second 811 * (m/s`2). Must be 3x1. 812 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 813 * @param bg angular speed bias to be set expressed in radians per second 814 * (rad/s). Must be 3x1. 815 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 816 * @param kalmanConfig configuration parameters obtained through calibration. 817 * @param initConfig configuration parameters determining initial system 818 * noise covariance matrix. 819 * @throws AlgebraException if provided cross-coupling matrices cannot 820 * be inverted. 821 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 822 */ 823 public KalmanDriftEstimator( 824 final NEDFrame referenceFrame, 825 final Matrix ba, 826 final Matrix ma, 827 final Matrix bg, 828 final Matrix mg, 829 final INSLooselyCoupledKalmanConfig kalmanConfig, 830 final INSLooselyCoupledKalmanInitializerConfig initConfig) 831 throws AlgebraException { 832 super(referenceFrame, ba, ma, bg, mg); 833 this.kalmanConfig = kalmanConfig; 834 this.initConfig = initConfig; 835 } 836 837 /** 838 * Constructor. 839 * 840 * @param referenceFrame initial frame containing body position, velocity and 841 * orientation expressed in NED coordinates. 842 * @param ba acceleration bias to be set expressed in meters per squared second 843 * (m/s`2). Must be 3x1. 844 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 845 * @param bg angular speed bias to be set expressed in radians per second 846 * (rad/s). Must be 3x1. 847 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 848 * @param kalmanConfig configuration parameters obtained through calibration. 849 * @param initConfig configuration parameters determining initial system 850 * noise covariance matrix. 851 * @param listener listener to handle events. 852 * @throws AlgebraException if provided cross-coupling matrices cannot 853 * be inverted. 854 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 855 */ 856 public KalmanDriftEstimator( 857 final NEDFrame referenceFrame, 858 final Matrix ba, 859 final Matrix ma, 860 final Matrix bg, 861 final Matrix mg, 862 final INSLooselyCoupledKalmanConfig kalmanConfig, 863 final INSLooselyCoupledKalmanInitializerConfig initConfig, 864 final DriftEstimatorListener listener) throws AlgebraException { 865 super(referenceFrame, ba, ma, bg, mg, listener); 866 this.kalmanConfig = kalmanConfig; 867 this.initConfig = initConfig; 868 } 869 870 /** 871 * Constructor. 872 * 873 * @param referenceFrame initial frame containing body position, velocity and 874 * orientation expressed in NED coordinates. 875 * @param ba acceleration bias to be set expressed in meters per squared second 876 * (m/s`2). Must be 3x1. 877 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 878 * @param bg angular speed bias to be set expressed in radians per second 879 * (rad/s). Must be 3x1. 880 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 881 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 882 * @param kalmanConfig configuration parameters obtained through calibration. 883 * @param initConfig configuration parameters determining initial system 884 * noise covariance matrix. 885 * @throws AlgebraException if provided cross-coupling matrices cannot 886 * be inverted. 887 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 888 */ 889 public KalmanDriftEstimator( 890 final NEDFrame referenceFrame, 891 final Matrix ba, 892 final Matrix ma, 893 final Matrix bg, 894 final Matrix mg, 895 final Matrix gg, 896 final INSLooselyCoupledKalmanConfig kalmanConfig, 897 final INSLooselyCoupledKalmanInitializerConfig initConfig) 898 throws AlgebraException { 899 super(referenceFrame, ba, ma, bg, mg, gg); 900 this.kalmanConfig = kalmanConfig; 901 this.initConfig = initConfig; 902 } 903 904 /** 905 * Constructor. 906 * 907 * @param referenceFrame initial frame containing body position, velocity and 908 * orientation expressed in ECEF coordinates. 909 * @param ba acceleration bias to be set expressed in meters per squared second 910 * (m/s`2). Must be 3x1. 911 * @param ma acceleration cross-coupling errors matrix. Must be 3x3. 912 * @param bg angular speed bias to be set expressed in radians per second 913 * (rad/s). Must be 3x1. 914 * @param mg angular speed cross-coupling errors matrix. Must be 3x3. 915 * @param gg angular speed g-dependent cross-biases matrix. Must be 3x3. 916 * @param kalmanConfig configuration parameters obtained through calibration. 917 * @param initConfig configuration parameters determining initial system 918 * noise covariance matrix. 919 * @param listener listener to handle events. 920 * @throws AlgebraException if provided cross-coupling matrices cannot 921 * be inverted. 922 * @throws IllegalArgumentException if any of the provided matrices are not 3x3. 923 */ 924 public KalmanDriftEstimator( 925 final NEDFrame referenceFrame, 926 final Matrix ba, 927 final Matrix ma, 928 final Matrix bg, 929 final Matrix mg, 930 final Matrix gg, 931 final INSLooselyCoupledKalmanConfig kalmanConfig, 932 final INSLooselyCoupledKalmanInitializerConfig initConfig, 933 final DriftEstimatorListener listener) throws AlgebraException { 934 super(referenceFrame, ba, ma, bg, mg, gg, listener); 935 this.kalmanConfig = kalmanConfig; 936 this.initConfig = initConfig; 937 } 938 939 /** 940 * Gets configuration parameters for INS Loosely Coupled Kalman filter obtained 941 * through calibration. 942 * 943 * @return configuration parameters for Kalman filter or null. 944 */ 945 public INSLooselyCoupledKalmanConfig getKalmanConfig() { 946 return kalmanConfig; 947 } 948 949 /** 950 * Sets configuration parameters for INS Loosely Coupled Kalman filter obtained 951 * through calibration. 952 * 953 * @param kalmanConfig configuration parameters for Kalman filter. 954 * @throws LockedException if estimator is already running. 955 */ 956 public void setKalmanConfig(final INSLooselyCoupledKalmanConfig kalmanConfig) throws LockedException { 957 if (running) { 958 throw new LockedException(); 959 } 960 961 this.kalmanConfig = kalmanConfig; 962 } 963 964 /** 965 * Gets configuration parameters determining initial system noise covariance 966 * matrix. 967 * 968 * @return configuration parameters determining initial system noise covariance 969 * matrix or null. 970 */ 971 public INSLooselyCoupledKalmanInitializerConfig getInitConfig() { 972 return initConfig; 973 } 974 975 /** 976 * Sets configuration parameters determining initial system noise covariance 977 * matrix. 978 * 979 * @param initConfig configuration parameters determining initial system noise 980 * covariance matrix. 981 * @throws LockedException if estimator is already running. 982 */ 983 public void setInitConfig(final INSLooselyCoupledKalmanInitializerConfig initConfig) throws LockedException { 984 if (running) { 985 throw new LockedException(); 986 } 987 988 this.initConfig = initConfig; 989 } 990 991 /** 992 * Indicates if estimator is ready to start processing additional kinematics 993 * measurements. 994 * 995 * @return true if ready, false otherwise. 996 */ 997 @Override 998 public boolean isReady() { 999 return super.isReady() && kalmanConfig != null && initConfig != null; 1000 } 1001 1002 /** 1003 * Adds a sample of measured body kinematics (accelerometer and gyroscope readings) 1004 * obtained from an IMU, fixes their values and uses fixed values to estimate 1005 * current drift and their average values. 1006 * 1007 * @param kinematics measured body kinematics. 1008 * @throws LockedException if estimator is currently running. 1009 * @throws NotReadyException if estimator is not ready. 1010 * @throws DriftEstimationException if estimation fails for some reason. 1011 */ 1012 @Override 1013 public void addBodyKinematics(final BodyKinematics kinematics) throws LockedException, NotReadyException, 1014 DriftEstimationException { 1015 if (isRunning()) { 1016 throw new LockedException(); 1017 } 1018 1019 if (!isReady()) { 1020 throw new NotReadyException(); 1021 } 1022 1023 try { 1024 running = true; 1025 1026 if (numberOfProcessedSamples == 0) { 1027 if (listener != null) { 1028 listener.onStart(this); 1029 } 1030 1031 initialize(); 1032 } 1033 1034 if (fixKinematics) { 1035 // fix kinematics and update kalman filter 1036 fixer.fix(kinematics, fixedKinematics); 1037 } else { 1038 // only update kalman filter 1039 fixedKinematics.copyFrom(kinematics); 1040 } 1041 1042 final var timestamp = getElapsedTimeSeconds(); 1043 kalmanEstimator.update(fixedKinematics, timestamp); 1044 1045 if (state == null) { 1046 state = kalmanEstimator.getState(); 1047 } else { 1048 kalmanEstimator.getState(state); 1049 } 1050 1051 // estimate drift values 1052 computeCurrentPositionDrift(); 1053 computeCurrentVelocityDrift(); 1054 computeCurrentOrientationDrift(); 1055 1056 numberOfProcessedSamples++; 1057 1058 if (listener != null) { 1059 listener.onBodyKinematicsAdded(this, kinematics, fixedKinematics); 1060 } 1061 } catch (final AlgebraException | InvalidRotationMatrixException | INSException e) { 1062 throw new DriftEstimationException(e); 1063 } finally { 1064 running = false; 1065 } 1066 } 1067 1068 /** 1069 * Resets this estimator to its initial state. 1070 * 1071 * @throws LockedException if estimator is currently running. 1072 */ 1073 @Override 1074 public void reset() throws LockedException { 1075 if (isRunning()) { 1076 throw new LockedException(); 1077 } 1078 1079 kalmanEstimator = null; 1080 state = null; 1081 running = false; 1082 1083 super.reset(); 1084 } 1085 1086 /** 1087 * Gets state of internal Kalman filter containing current body position, 1088 * orientation and velocity after last provided body kinematics measurement. 1089 * 1090 * @return state of internal Kalman filter. 1091 */ 1092 public INSLooselyCoupledKalmanState getState() { 1093 return kalmanEstimator != null ? kalmanEstimator.getState() : null; 1094 } 1095 1096 /** 1097 * Gets state of internal Kalman filter containing current body position, 1098 * orientation and velocity after last provided body kinematics measurement. 1099 * 1100 * @param result instance where the result will be stored. 1101 * @return true if the internal Kalman filter state is available and the result is 1102 * updated, false otherwise. 1103 */ 1104 public boolean getState(final INSLooselyCoupledKalmanState result) { 1105 if (kalmanEstimator != null) { 1106 return kalmanEstimator.getState(result); 1107 } else { 1108 return false; 1109 } 1110 } 1111 1112 /** 1113 * Initializes internal frame and Kalman estimator when the first body kinematics 1114 * measurement is provided. 1115 * 1116 * @throws InvalidRotationMatrixException if orientation cannot be determined for 1117 * numerical reasons. 1118 */ 1119 private void initialize() throws InvalidRotationMatrixException { 1120 final var c = referenceFrame.getCoordinateTransformation(); 1121 c.asRotation(refQ); 1122 refQ.inverse(invRefQ); 1123 1124 frame.copyFrom(referenceFrame); 1125 1126 kalmanEstimator = new INSLooselyCoupledKalmanFilteredEstimator(kalmanConfig, initConfig, frame); 1127 } 1128 1129 /** 1130 * Computes current position drift. 1131 */ 1132 @Override 1133 protected void computeCurrentPositionDrift() { 1134 final var initX = referenceFrame.getX(); 1135 final var initY = referenceFrame.getY(); 1136 final var initZ = referenceFrame.getZ(); 1137 1138 final var currentX = state.getX(); 1139 final var currentY = state.getY(); 1140 final var currentZ = state.getZ(); 1141 1142 final var diffX = currentX - initX; 1143 final var diffY = currentY - initY; 1144 final var diffZ = currentZ - initZ; 1145 1146 currentPositionDrift.setCoordinates(diffX, diffY, diffZ); 1147 1148 currentPositionDriftMeters = currentPositionDrift.getNorm(); 1149 } 1150 1151 /** 1152 * Computes current velocity drift. 1153 */ 1154 @Override 1155 protected void computeCurrentVelocityDrift() { 1156 final var initVx = referenceFrame.getVx(); 1157 final var initVy = referenceFrame.getVy(); 1158 final var initVz = referenceFrame.getVz(); 1159 1160 final var currentVx = state.getVx(); 1161 final var currentVy = state.getVy(); 1162 final var currentVz = state.getVz(); 1163 1164 final var diffVx = currentVx - initVx; 1165 final var diffVy = currentVy - initVy; 1166 final var diffVz = currentVz - initVz; 1167 1168 currentVelocityDrift.setCoordinates(diffVx, diffVy, diffVz); 1169 1170 currentVelocityDriftMetersPerSecond = currentVelocityDrift.getNorm(); 1171 } 1172 1173 /** 1174 * Computes current orientation drift. 1175 * 1176 * @throws InvalidRotationMatrixException if rotation cannot be accurately 1177 * estimated. 1178 */ 1179 @Override 1180 protected void computeCurrentOrientationDrift() throws InvalidRotationMatrixException { 1181 currentC = state.getBodyToEcefCoordinateTransformationMatrix(); 1182 1183 q.fromMatrix(currentC); 1184 q.combine(invRefQ); 1185 1186 currentOrientationDriftRadians = q.getRotationAngle(); 1187 } 1188 }