View Javadoc
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;
17  
18  import com.irurueta.algebra.AlgebraException;
19  import com.irurueta.algebra.Matrix;
20  import com.irurueta.algebra.Utils;
21  import com.irurueta.algebra.WrongSizeException;
22  import com.irurueta.navigation.inertial.BodyKinematics;
23  import com.irurueta.units.Acceleration;
24  import com.irurueta.units.AccelerationConverter;
25  import com.irurueta.units.AccelerationUnit;
26  import com.irurueta.units.AngularSpeed;
27  import com.irurueta.units.AngularSpeedConverter;
28  import com.irurueta.units.AngularSpeedUnit;
29  
30  /**
31   * Fixes angular rate values taking into
32   * account provided bias, cross coupling errors and G-dependant errors.
33   */
34  @SuppressWarnings("DuplicatedCode")
35  public class AngularRateFixer {
36      /**
37       * Identity matrix to be reused.
38       */
39      private Matrix identity;
40  
41      /**
42       * Temporary matrix to be reused.
43       */
44      private Matrix tmp1;
45  
46      /**
47       * Temporary matrix to be reused.
48       */
49      private Matrix tmp2;
50  
51      /**
52       * Temporary matrix to be reused.
53       */
54      private Matrix tmp3;
55  
56      /**
57       * Temporary matrix to be reused.
58       */
59      private Matrix tmp4;
60  
61      /**
62       * Temporary matrix to be reused.
63       */
64      private Matrix diff;
65  
66      /**
67       * Temporary matrix to be reused.
68       */
69      private Matrix tmp5;
70  
71      /**
72       * Measured angular rate to be reused.
73       */
74      private final double[] measuredAngularRate = new double[BodyKinematics.COMPONENTS];
75  
76      /**
77       * True specific force to be reused.
78       */
79      private final double[] trueF = new double[BodyKinematics.COMPONENTS];
80  
81      /**
82       * Array containing result values to be reused.
83       */
84      private final double[] res = new double[BodyKinematics.COMPONENTS];
85  
86      /**
87       * Bias matrix to be reused.
88       */
89      private Matrix bias;
90  
91      /**
92       * Cross coupling errors matrix to be reused.
93       */
94      private Matrix crossCouplingErrors;
95  
96      /**
97       * G-dependant cross biases to be reused.
98       */
99      private Matrix gDependantCrossBias;
100 
101     /**
102      * Constructor.
103      */
104     public AngularRateFixer() {
105         try {
106             identity = Matrix.identity(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
107             tmp1 = Matrix.identity(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
108             tmp2 = Matrix.identity(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
109             tmp3 = new Matrix(BodyKinematics.COMPONENTS, 1);
110             tmp4 = new Matrix(BodyKinematics.COMPONENTS, 1);
111             diff = new Matrix(BodyKinematics.COMPONENTS, 1);
112             tmp5 = new Matrix(BodyKinematics.COMPONENTS, 1);
113 
114             bias = new Matrix(BodyKinematics.COMPONENTS, 1);
115             crossCouplingErrors = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
116             gDependantCrossBias = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
117         } catch (final WrongSizeException ignore) {
118             // never happens
119         }
120     }
121 
122     /**
123      * Gets bias values expressed in radians per second (rad/s).
124      *
125      * @return bias values expressed in radians per second.
126      */
127     public Matrix getBias() {
128         return new Matrix(bias);
129     }
130 
131     /**
132      * Gets bias values expressed in radians per second (rad/s).
133      *
134      * @param result instance where result will be stored.
135      */
136     public void getBias(final Matrix result) {
137         bias.copyTo(result);
138     }
139 
140     /**
141      * Sets bias values expressed in radians per second (rad/s).
142      *
143      * @param bias bias values expressed in radians per second. Must be 3x1.
144      * @throws IllegalArgumentException if provided matrix is not 3x1.
145      */
146     public void setBias(final Matrix bias) {
147         if (bias.getRows() != BodyKinematics.COMPONENTS || bias.getColumns() != 1) {
148             throw new IllegalArgumentException();
149         }
150         this.bias = bias;
151     }
152 
153     /**
154      * Gets bias values expressed in radians per second (rad/s).
155      *
156      * @return bias values expressed in radians per second.
157      */
158     public double[] getBiasArray() {
159         final var result = new double[BodyKinematics.COMPONENTS];
160         getBiasArray(result);
161         return result;
162     }
163 
164     /**
165      * Gets bias values expressed in radians per second (rad/s).
166      *
167      * @param result instance where result data will be stored.
168      * @throws IllegalArgumentException if provided array does not have
169      *                                  length 3.
170      */
171     public void getBiasArray(final double[] result) {
172         if (result.length != BodyKinematics.COMPONENTS) {
173             throw new IllegalArgumentException();
174         }
175 
176         try {
177             bias.toArray(result);
178         } catch (final WrongSizeException ignore) {
179             // never happens
180         }
181     }
182 
183     /**
184      * Sets bias values expressed in radians per second (rad/s).
185      *
186      * @param bias bias values expressed in radians per second (rad/s). Must
187      *             have length 3.
188      * @throws IllegalArgumentException if provided array does not have
189      *                                  length 3.
190      */
191     public void setBias(final double[] bias) {
192         if (bias.length != BodyKinematics.COMPONENTS) {
193             throw new IllegalArgumentException();
194         }
195 
196         try {
197             this.bias.fromArray(bias);
198         } catch (final WrongSizeException ignore) {
199             // never happens
200         }
201     }
202 
203     /**
204      * Gets angular speed bias.
205      *
206      * @return angular speed bias.
207      */
208     public AngularSpeedTriad getBiasAsTriad() {
209         return new AngularSpeedTriad(AngularSpeedUnit.RADIANS_PER_SECOND,
210                 bias.getElementAtIndex(0), bias.getElementAtIndex(1), bias.getElementAtIndex(2));
211     }
212 
213     /**
214      * Gets angular speed bias.
215      *
216      * @param result instance where result will be stored.
217      */
218     public void getBiasAsTriad(final AngularSpeedTriad result) {
219         result.setValueCoordinates(bias);
220         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
221     }
222 
223     /**
224      * Sets angular speed bias.
225      *
226      * @param bias angular speed bias to be set.
227      */
228     public void setBias(final AngularSpeedTriad bias) {
229         final var biasX = convertAngularSpeed(bias.getValueX(), bias.getUnit());
230         final var biasY = convertAngularSpeed(bias.getValueY(), bias.getUnit());
231         final var biasZ = convertAngularSpeed(bias.getValueZ(), bias.getUnit());
232         this.bias.setElementAtIndex(0, biasX);
233         this.bias.setElementAtIndex(1, biasY);
234         this.bias.setElementAtIndex(2, biasZ);
235     }
236 
237     /**
238      * Gets x-coordinate of bias expressed in radians per second (rad/s).
239      *
240      * @return x-coordinate of bias expressed in radians per second (rad/s).
241      */
242     public double getBiasX() {
243         return bias.getElementAtIndex(0);
244     }
245 
246     /**
247      * Sets x-coordinate of bias expressed in radians per second (rad/s).
248      *
249      * @param biasX x-coordinate of bias expressed in radians per second
250      *              (rad/s).
251      */
252     public void setBiasX(final double biasX) {
253         bias.setElementAtIndex(0, biasX);
254     }
255 
256     /**
257      * Gets y-coordinate of bias expressed in radians per second (rad/s).
258      *
259      * @return y-coordinate of bias expressed in radians per second (rad/s).
260      */
261     public double getBiasY() {
262         return bias.getElementAtIndex(1);
263     }
264 
265     /**
266      * Sets y-coordinate of bias expressed in radians per second (rad/s).
267      *
268      * @param biasY y-coordinate of bias expressed in radians per second
269      *              (rad/s).
270      */
271     public void setBiasY(final double biasY) {
272         bias.setElementAtIndex(1, biasY);
273     }
274 
275     /**
276      * Gets z-coordinate of bias expressed in radians per second (rad/s).
277      *
278      * @return z-coordinate of bias expressed in radians per second (rad/s).
279      */
280     public double getBiasZ() {
281         return bias.getElementAtIndex(2);
282     }
283 
284     /**
285      * Sets z-coordinate of bias expressed in radians per second (rad/s).
286      *
287      * @param biasZ z-coordinate of bias expressed in radians per second
288      *              (rad/s).
289      */
290     public void setBiasZ(final double biasZ) {
291         bias.setElementAtIndex(2, biasZ);
292     }
293 
294     /**
295      * Sets coordinates of bias expressed in radians per second (rad/s).
296      *
297      * @param biasX x-coordinate of bias.
298      * @param biasY y-coordinate of bias.
299      * @param biasZ z-coordinate of bias.
300      */
301     public void setBias(final double biasX, final double biasY, final double biasZ) {
302         setBiasX(biasX);
303         setBiasY(biasY);
304         setBiasZ(biasZ);
305     }
306 
307     /**
308      * Gets x-coordinate of bias.
309      *
310      * @return x-coordinate of bias.
311      */
312     public AngularSpeed getBiasXAsAngularSpeed() {
313         return new AngularSpeed(getBiasX(), AngularSpeedUnit.RADIANS_PER_SECOND);
314     }
315 
316     /**
317      * Gets x-coordinate of bias.
318      *
319      * @param result instance where result will be stored.
320      */
321     public void getBiasXAsAngularSpeed(final AngularSpeed result) {
322         result.setValue(getBiasX());
323         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
324     }
325 
326     /**
327      * Sets x-coordinate of bias.
328      *
329      * @param biasX x-coordinate of bias.
330      */
331     public void setBiasX(final AngularSpeed biasX) {
332         setBiasX(convertAngularSpeed(biasX));
333     }
334 
335     /**
336      * Gets y-coordinate of bias.
337      *
338      * @return y-coordinate of bias.
339      */
340     public AngularSpeed getBiasYAsAngularSpeed() {
341         return new AngularSpeed(getBiasY(), AngularSpeedUnit.RADIANS_PER_SECOND);
342     }
343 
344     /**
345      * Gets y-coordinate of bias.
346      *
347      * @param result instance where result will be stored.
348      */
349     public void getBiasYAsAngularSpeed(final AngularSpeed result) {
350         result.setValue(getBiasY());
351         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
352     }
353 
354     /**
355      * Sets y-coordinate of bias.
356      *
357      * @param biasY y-coordinate of bias.
358      */
359     public void setBiasY(final AngularSpeed biasY) {
360         setBiasY(convertAngularSpeed(biasY));
361     }
362 
363     /**
364      * Gets z-coordinate of bias.
365      *
366      * @return z-coordinate of bias.
367      */
368     public AngularSpeed getBiasZAsAngularSpeed() {
369         return new AngularSpeed(getBiasZ(), AngularSpeedUnit.RADIANS_PER_SECOND);
370     }
371 
372     /**
373      * Gets z-coordinate of bias.
374      *
375      * @param result instance where result will be stored.
376      */
377     public void getBiasZAsAngularSpeed(final AngularSpeed result) {
378         result.setValue(getBiasZ());
379         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
380     }
381 
382     /**
383      * Sets z-coordinate of bias.
384      *
385      * @param biasZ z-coordinate of bias.
386      */
387     public void setBiasZ(final AngularSpeed biasZ) {
388         setBiasZ(convertAngularSpeed(biasZ));
389     }
390 
391     /**
392      * Sets coordinates of bias.
393      *
394      * @param biasX x-coordinate of bias.
395      * @param biasY y-coordinate of bias.
396      * @param biasZ z-coordinate of bias.
397      */
398     public void setBias(final AngularSpeed biasX, final AngularSpeed biasY, final AngularSpeed biasZ) {
399         setBiasX(biasX);
400         setBiasY(biasY);
401         setBiasZ(biasZ);
402     }
403 
404     /**
405      * Gets cross coupling errors matrix.
406      *
407      * @return cross coupling errors matrix.
408      */
409     public Matrix getCrossCouplingErrors() {
410         return new Matrix(crossCouplingErrors);
411     }
412 
413     /**
414      * Gets cross coupling errors matrix.
415      *
416      * @param result instance where result will be stored.
417      */
418     public void getCrossCouplingErrors(final Matrix result) {
419         crossCouplingErrors.copyTo(result);
420     }
421 
422     /**
423      * Sets cross coupling errors matrix.
424      *
425      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
426      * @throws AlgebraException         if provided matrix cannot be inverted.
427      * @throws IllegalArgumentException if provided matrix is not 3x3.
428      */
429     public void setCrossCouplingErrors(final Matrix crossCouplingErrors) throws AlgebraException {
430         if (crossCouplingErrors.getRows() != BodyKinematics.COMPONENTS
431                 || crossCouplingErrors.getColumns() != BodyKinematics.COMPONENTS) {
432             throw new IllegalArgumentException();
433         }
434 
435         this.crossCouplingErrors = crossCouplingErrors;
436 
437         identity.add(crossCouplingErrors, tmp1);
438 
439         Utils.inverse(tmp1, tmp2);
440     }
441 
442     /**
443      * Gets x scaling factor.
444      *
445      * @return x scaling factor.
446      */
447     public double getSx() {
448         return crossCouplingErrors.getElementAt(0, 0);
449     }
450 
451     /**
452      * Sets x scaling factor
453      *
454      * @param sx x scaling factor.
455      * @throws AlgebraException if provided value makes cross coupling matrix
456      *                          non-invertible.
457      */
458     public void setSx(final double sx) throws AlgebraException {
459         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
460         m.copyFrom(crossCouplingErrors);
461         m.setElementAt(0, 0, sx);
462         setCrossCouplingErrors(m);
463     }
464 
465     /**
466      * Gets y scaling factor.
467      *
468      * @return y scaling factor.
469      */
470     public double getSy() {
471         return crossCouplingErrors.getElementAt(1, 1);
472     }
473 
474     /**
475      * Sets y scaling factor.
476      *
477      * @param sy y scaling factor.
478      * @throws AlgebraException if provided value makes cross coupling matrix
479      *                          non-invertible.
480      */
481     public void setSy(final double sy) throws AlgebraException {
482         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
483         m.copyFrom(crossCouplingErrors);
484         m.setElementAt(1, 1, sy);
485         setCrossCouplingErrors(m);
486     }
487 
488     /**
489      * Gets z scaling factor.
490      *
491      * @return z scaling factor.
492      */
493     public double getSz() {
494         return crossCouplingErrors.getElementAt(2, 2);
495     }
496 
497     /**
498      * Sets z scaling factor.
499      *
500      * @param sz z scaling factor.
501      * @throws AlgebraException if provided value makes cross coupling matrix
502      *                          non-invertible.
503      */
504     public void setSz(final double sz) throws AlgebraException {
505         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
506         m.copyFrom(crossCouplingErrors);
507         m.setElementAt(2, 2, sz);
508         setCrossCouplingErrors(m);
509     }
510 
511     /**
512      * Gets x-y cross coupling error.
513      *
514      * @return x-y cross coupling error.
515      */
516     public double getMxy() {
517         return crossCouplingErrors.getElementAt(0, 1);
518     }
519 
520     /**
521      * Sets x-y cross coupling error.
522      *
523      * @param mxy x-y cross coupling error.
524      * @throws AlgebraException if provided value makes cross coupling matrix
525      *                          non-invertible.
526      */
527     public void setMxy(final double mxy) throws AlgebraException {
528         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
529         m.copyFrom(crossCouplingErrors);
530         m.setElementAt(0, 1, mxy);
531         setCrossCouplingErrors(m);
532     }
533 
534     /**
535      * Gets x-z cross coupling error.
536      *
537      * @return x-z cross coupling error.
538      */
539     public double getMxz() {
540         return crossCouplingErrors.getElementAt(0, 2);
541     }
542 
543     /**
544      * Sets x-z cross coupling error.
545      *
546      * @param mxz x-z cross coupling error.
547      * @throws AlgebraException if provided value makes cross coupling matrix
548      *                          non-invertible.
549      */
550     public void setMxz(final double mxz) throws AlgebraException {
551         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
552         m.copyFrom(crossCouplingErrors);
553         m.setElementAt(0, 2, mxz);
554         setCrossCouplingErrors(m);
555     }
556 
557     /**
558      * Gets y-x cross coupling error.
559      *
560      * @return y-x cross coupling error.
561      */
562     public double getMyx() {
563         return crossCouplingErrors.getElementAt(1, 0);
564     }
565 
566     /**
567      * Sets y-x cross coupling error.
568      *
569      * @param myx y-x cross coupling error.
570      * @throws AlgebraException if provided value makes cross coupling matrix
571      *                          non-invertible.
572      */
573     public void setMyx(final double myx) throws AlgebraException {
574         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
575         m.copyFrom(crossCouplingErrors);
576         m.setElementAt(1, 0, myx);
577         setCrossCouplingErrors(m);
578     }
579 
580     /**
581      * Gets y-z cross coupling error.
582      *
583      * @return y-z cross coupling error.
584      */
585     public double getMyz() {
586         return crossCouplingErrors.getElementAt(1, 2);
587     }
588 
589     /**
590      * Sets y-z cross coupling error.
591      *
592      * @param myz y-z cross coupling error.
593      * @throws AlgebraException if provided value makes cross coupling matrix
594      *                          non-invertible.
595      */
596     public void setMyz(final double myz) throws AlgebraException {
597         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
598         m.copyFrom(crossCouplingErrors);
599         m.setElementAt(1, 2, myz);
600         setCrossCouplingErrors(m);
601     }
602 
603     /**
604      * Gets z-x cross coupling error.
605      *
606      * @return z-x cross coupling error.
607      */
608     public double getMzx() {
609         return crossCouplingErrors.getElementAt(2, 0);
610     }
611 
612     /**
613      * Sets z-x cross coupling error.
614      *
615      * @param mzx z-x cross coupling error.
616      * @throws AlgebraException if provided value makes cross coupling matrix
617      *                          non-invertible.
618      */
619     public void setMzx(final double mzx) throws AlgebraException {
620         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
621         m.copyFrom(crossCouplingErrors);
622         m.setElementAt(2, 0, mzx);
623         setCrossCouplingErrors(m);
624     }
625 
626     /**
627      * Gets z-y cross coupling error.
628      *
629      * @return z-y cross coupling error.
630      */
631     public double getMzy() {
632         return crossCouplingErrors.getElementAt(2, 1);
633     }
634 
635     /**
636      * Sets z-y cross coupling error.
637      *
638      * @param mzy z-y cross coupling error.
639      * @throws AlgebraException if provided value makes cross coupling matrix
640      *                          non-invertible.
641      */
642     public void setMzy(final double mzy) throws AlgebraException {
643         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
644         m.copyFrom(crossCouplingErrors);
645         m.setElementAt(2, 1, mzy);
646         setCrossCouplingErrors(m);
647     }
648 
649     /**
650      * Sets scaling factors.
651      *
652      * @param sx x scaling factor.
653      * @param sy y scaling factor.
654      * @param sz z scaling factor.
655      * @throws AlgebraException if provided values make cross coupling matrix
656      *                          non-invertible.
657      */
658     public void setScalingFactors(
659             final double sx, final double sy, final double sz) throws AlgebraException {
660         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
661         m.copyFrom(crossCouplingErrors);
662         m.setElementAt(0, 0, sx);
663         m.setElementAt(1, 1, sy);
664         m.setElementAt(2, 2, sz);
665         setCrossCouplingErrors(m);
666     }
667 
668     /**
669      * Sets cross coupling errors.
670      *
671      * @param mxy x-y cross coupling error.
672      * @param mxz x-z cross coupling error.
673      * @param myx y-x cross coupling error.
674      * @param myz y-z cross coupling error.
675      * @param mzx z-x cross coupling error.
676      * @param mzy z-y cross coupling error.
677      * @throws AlgebraException if provided values make cross coupling matrix
678      *                          non-invertible.
679      */
680     public void setCrossCouplingErrors(
681             final double mxy, final double mxz, final double myx,
682             final double myz, final double mzx, final double mzy) throws AlgebraException {
683         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
684         m.copyFrom(crossCouplingErrors);
685         m.setElementAt(0, 1, mxy);
686         m.setElementAt(0, 2, mxz);
687         m.setElementAt(1, 0, myx);
688         m.setElementAt(1, 2, myz);
689         m.setElementAt(2, 0, mzx);
690         m.setElementAt(2, 1, mzy);
691         setCrossCouplingErrors(m);
692     }
693 
694     /**
695      * Sets scaling factors and cross coupling errors.
696      *
697      * @param sx  x scaling factor.
698      * @param sy  y scaling factor.
699      * @param sz  z scaling factor.
700      * @param mxy x-y cross coupling error.
701      * @param mxz x-z cross coupling error.
702      * @param myx y-x cross coupling error.
703      * @param myz y-z cross coupling error.
704      * @param mzx z-x cross coupling error.
705      * @param mzy z-y cross coupling error.
706      * @throws AlgebraException if provided values make cross coupling matrix
707      *                          non-invertible.
708      */
709     public void setScalingFactorsAndCrossCouplingErrors(
710             final double sx, final double sy, final double sz,
711             final double mxy, final double mxz, final double myx,
712             final double myz, final double mzx, final double mzy) throws AlgebraException {
713         final var m = new Matrix(Triad.COMPONENTS, Triad.COMPONENTS);
714         m.copyFrom(crossCouplingErrors);
715         m.setElementAt(0, 0, sx);
716         m.setElementAt(1, 1, sy);
717         m.setElementAt(2, 2, sz);
718         m.setElementAt(0, 1, mxy);
719         m.setElementAt(0, 2, mxz);
720         m.setElementAt(1, 0, myx);
721         m.setElementAt(1, 2, myz);
722         m.setElementAt(2, 0, mzx);
723         m.setElementAt(2, 1, mzy);
724         setCrossCouplingErrors(m);
725     }
726 
727     /**
728      * Gets g-dependant cross biases matrix.
729      *
730      * @return g-dependant cross biases matrix.
731      */
732     public Matrix getGDependantCrossBias() {
733         return new Matrix(gDependantCrossBias);
734     }
735 
736     /**
737      * Gets g-dependant cross biases matrix.
738      *
739      * @param result instance where result will be stored.
740      */
741     public void getGDependantCrossBias(final Matrix result) {
742         gDependantCrossBias.copyTo(result);
743     }
744 
745     /**
746      * Sets g-dependant cross biases matrix.
747      *
748      * @param gDependantCrossBias g-dependant cross biases matrix.
749      * @throws IllegalArgumentException if provided matrix is not 3x3.
750      */
751     public void setGDependantCrossBias(final Matrix gDependantCrossBias) {
752         if (gDependantCrossBias.getRows() != BodyKinematics.COMPONENTS
753                 || gDependantCrossBias.getColumns() != BodyKinematics.COMPONENTS) {
754             throw new IllegalArgumentException();
755         }
756 
757         this.gDependantCrossBias = gDependantCrossBias;
758     }
759 
760     /**
761      * Fixes provided measured angular rate values by undoing the errors
762      * introduced by the gyroscope model to restore the true angular rate.
763      * This method uses last provided bias and cross coupling errors.
764      *
765      * @param measuredAngularRate measured angular rate.
766      * @param trueF               true (i.e. fixed) specific force.
767      * @param result              instance where restored true angular rate will
768      *                            be stored. Must have length 3.
769      * @throws AlgebraException         if there are numerical instabilities.
770      * @throws IllegalArgumentException if length of provided result array is
771      *                                  not 3.
772      */
773     public void fix(
774             final AngularSpeedTriad measuredAngularRate, final AccelerationTriad trueF, final double[] result)
775             throws AlgebraException {
776         if (result.length != Triad.COMPONENTS) {
777             throw new IllegalArgumentException();
778         }
779 
780         final var wX = convertAngularSpeed(measuredAngularRate.getValueX(), measuredAngularRate.getUnit());
781         final var wY = convertAngularSpeed(measuredAngularRate.getValueY(), measuredAngularRate.getUnit());
782         final var wZ = convertAngularSpeed(measuredAngularRate.getValueZ(), measuredAngularRate.getUnit());
783         final var trueFx = convertAcceleration(trueF.getValueX(), trueF.getUnit());
784         final var trueFy = convertAcceleration(trueF.getValueY(), trueF.getUnit());
785         final var trueFz = convertAcceleration(trueF.getValueZ(), trueF.getUnit());
786         fix(wX, wY, wZ, trueFx, trueFy, trueFz, result);
787     }
788 
789     /**
790      * Fixes provided measured angular rate values by undoing the errors
791      * introduced by the gyroscope model to restore the true angular rate.
792      * This method uses last provided bias and cross coupling errors.
793      *
794      * @param measuredAngularRate measured angular rate.
795      * @param trueF               true (i.e. fixed) specific force.
796      * @param result              instance where restored true angular rate will
797      *                            be stored. Must be 3x1.
798      * @throws AlgebraException         if there are numerical instabilities.
799      * @throws IllegalArgumentException if result matrix is not 3x1.
800      */
801     public void fix(
802             final AngularSpeedTriad measuredAngularRate, final AccelerationTriad trueF, final Matrix result)
803             throws AlgebraException {
804         if (result.getRows() != Triad.COMPONENTS || result.getColumns() != 1) {
805             throw new IllegalArgumentException();
806         }
807 
808         fix(measuredAngularRate, trueF, result.getBuffer());
809     }
810 
811     /**
812      * Fixes provided measured angular rate values by undoing the errors
813      * introduced by the gyroscope model to restore the true angular rate.
814      * This method uses last provided bias and cross coupling errors.
815      *
816      * @param measuredAngularRate measured angular rate.
817      * @param trueF               true (i.e. fixed) specific force.
818      * @param result              instance where restored true angular rate will be stored.
819      * @throws AlgebraException if there are numerical instabilities.
820      */
821     public void fix(
822             final AngularSpeedTriad measuredAngularRate, final AccelerationTriad trueF, final AngularSpeedTriad result)
823             throws AlgebraException {
824         fix(measuredAngularRate, trueF, this.res);
825         result.setValueCoordinates(this.res);
826         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
827     }
828 
829     /**
830      * Fixes provided measured angular rate values by undoing the errors
831      * introduced by the gyroscope model to restore the true angular rate.
832      * This method uses last provided and cross coupling errors.
833      *
834      * @param measuredAngularRateX x-coordinate of measured angular rate.
835      * @param measuredAngularRateY y-coordinate of measured angular rate.
836      * @param measuredAngularRateZ z-coordinate of measured angular rate.
837      * @param trueFx               x-coordinate of true (i.e. fixed) specific force.
838      * @param trueFy               y-coordinate of true (i.e. fixed) specific force.
839      * @param trueFz               z-coordinate of true (i.e. fixed) specific force.
840      * @param result               instance where restored true angular rate will be stored.
841      * @throws AlgebraException if there are numerical instabilities.
842      */
843     public void fix(
844             final AngularSpeed measuredAngularRateX, final AngularSpeed measuredAngularRateY,
845             final AngularSpeed measuredAngularRateZ, final Acceleration trueFx, final Acceleration trueFy,
846             final Acceleration trueFz, final AngularSpeedTriad result) throws AlgebraException {
847         final var wX = convertAngularSpeed(measuredAngularRateX);
848         final var wY = convertAngularSpeed(measuredAngularRateY);
849         final var wZ = convertAngularSpeed(measuredAngularRateZ);
850         final var fX = convertAcceleration(trueFx);
851         final var fY = convertAcceleration(trueFy);
852         final var fZ = convertAcceleration(trueFz);
853         fix(wX, wY, wZ, fX, fY, fZ, this.res);
854         result.setValueCoordinates(this.res);
855         result.setUnit(AngularSpeedUnit.RADIANS_PER_SECOND);
856     }
857 
858     /**
859      * Fixes provided measured angular rate values by undoing the errors
860      * introduced by the gyroscope model to restore the true angular
861      * rate.
862      * This method uses last provided bias and cross coupling errors.
863      *
864      * @param measuredAngularRate measured angular rate expressed in radians
865      *                            per second (rad/s). Must have length 3.
866      * @param trueF               true (i.e. fixed) specific force expressed
867      *                            in meters per squared second (m/s^2). Must
868      *                            have length 3.
869      * @param result              instance where restored true angular rate
870      *                            will be stored. Must have length 3.
871      * @throws AlgebraException         if there are numerical instabilities.
872      * @throws IllegalArgumentException if any of the provided parameters
873      *                                  does not have proper size.
874      */
875     public void fix(
876             final double[] measuredAngularRate, final double[] trueF, final double[] result) throws AlgebraException {
877         if (measuredAngularRate.length != BodyKinematics.COMPONENTS) {
878             throw new IllegalArgumentException();
879         }
880         if (trueF.length != BodyKinematics.COMPONENTS) {
881             throw new IllegalArgumentException();
882         }
883         if (result.length != BodyKinematics.COMPONENTS) {
884             throw new IllegalArgumentException();
885         }
886 
887         // The gyroscope model is
888         // Ωmeas = bg + (I + Mg) * Ωtrue + Gg * ftrue
889 
890         // Ωtrue = (I + Mg)^-1 * (Ωmeas - bg - Gg * ftrue)
891 
892         tmp3.fromArray(trueF);
893         gDependantCrossBias.multiply(tmp3, tmp4);
894 
895         for (var i = 0; i < BodyKinematics.COMPONENTS; i++) {
896             diff.setElementAtIndex(i, measuredAngularRate[i] - bias.getElementAtIndex(i)
897                     - tmp4.getElementAtIndex(i));
898         }
899 
900         tmp2.multiply(diff, tmp5);
901 
902         tmp5.toArray(result);
903     }
904 
905     /**
906      * Fixes provided measured angular rate values by undoing the errors
907      * introduced by the gyroscope model to restore the true angular
908      * rate.
909      * This method uses last provided bias and cross coupling errors.
910      *
911      * @param measuredAngularRate measured angular rate expressed in radians
912      *                            per second (rad/s). Must be 3x1.
913      * @param trueF               true (i.e. fixed) specific force expressed
914      *                            in meters per squared second (m/s^2). Must
915      *                            be 3x1.
916      * @param result              instance where restored true angular rate
917      *                            will be stored. Must have length 3.
918      * @throws AlgebraException         if there are numerical instabilities.
919      * @throws IllegalArgumentException if any of the provided parameters
920      *                                  does not have proper size.
921      */
922     public void fix(
923             final Matrix measuredAngularRate, final Matrix trueF, final double[] result) throws AlgebraException {
924         if (measuredAngularRate.getRows() != BodyKinematics.COMPONENTS || measuredAngularRate.getColumns() != 1) {
925             throw new IllegalArgumentException();
926         }
927         if (trueF.getRows() != BodyKinematics.COMPONENTS || trueF.getColumns() != 1) {
928             throw new IllegalArgumentException();
929         }
930 
931         fix(measuredAngularRate.getBuffer(), trueF.getBuffer(), result);
932     }
933 
934     /**
935      * Fixes provided measured angular rate values by undoing the errors
936      * introduced by the gyroscope model to restore the true angular
937      * rate.
938      * This method uses last provided bias and cross coupling errors.
939      *
940      * @param measuredAngularRate measured angular rate expressed in radians
941      *                            per second (rad/s). Must be 3x1.
942      * @param trueF               true (i.e. fixed) specific force expressed
943      *                            in meters per squared second (m/s^2). Must
944      *                            be 3x1.
945      * @param result              instance where restored true angular rate
946      *                            will be stored. Must be 3x1.
947      * @throws AlgebraException         if there are numerical instabilities.
948      * @throws IllegalArgumentException if any of the provided parameters
949      *                                  does not have proper size.
950      */
951     public void fix(
952             final Matrix measuredAngularRate, final Matrix trueF, final Matrix result) throws AlgebraException {
953 
954         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
955             throw new IllegalArgumentException();
956         }
957 
958         fix(measuredAngularRate, trueF, result.getBuffer());
959     }
960 
961     /**
962      * Fixes provided measured angular rate values by undoing the errors
963      * introduced by the gyroscope model to restore the true angular
964      * rate.
965      * This method uses last provided bias and cross coupling errors.
966      *
967      * @param measuredAngularRateX x-coordinate of measured angular rate
968      *                             expressed in radians per second (rad/s).
969      * @param measuredAngularRateY y-coordinate of measured angular rate
970      *                             expressed in radians per second (rad/s).
971      * @param measuredAngularRateZ z-coordinate of measured angular rate
972      *                             expressed in radians per second (rad/s).
973      * @param trueFx               x-coordinate of true (i.e. fixed)
974      *                             specific force expressed in meters per
975      *                             squared second (m/s^2).
976      * @param trueFy               y-coordinate of true (i.e. fixed)
977      *                             specific force expressed in meters per
978      *                             squared second (m/s^2).
979      * @param trueFz               z-coordinate of true (i.e. fixed)
980      *                             specific force expressed in meters per
981      *                             squared second (m/s^2).
982      * @param result               instance where restored true angular rate
983      *                             will be stored. Must have length 3.
984      * @throws AlgebraException         if there are numerical instabilities.
985      * @throws IllegalArgumentException if any of the provided parameters
986      *                                  does not have proper size.
987      */
988     public void fix(
989             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
990             final double trueFx, final double trueFy, final double trueFz, final double[] result)
991             throws AlgebraException {
992 
993         measuredAngularRate[0] = measuredAngularRateX;
994         measuredAngularRate[1] = measuredAngularRateY;
995         measuredAngularRate[2] = measuredAngularRateZ;
996 
997         trueF[0] = trueFx;
998         trueF[1] = trueFy;
999         trueF[2] = trueFz;
1000 
1001         fix(measuredAngularRate, trueF, result);
1002     }
1003 
1004     /**
1005      * Fixes provided measured angular rate values by undoing the errors
1006      * introduced by the gyroscope model to restore the true angular
1007      * rate.
1008      * This method uses last provided bias and cross coupling errors.
1009      *
1010      * @param measuredAngularRateX x-coordinate of measured angular rate
1011      *                             expressed in radians per second (rad/s).
1012      * @param measuredAngularRateY y-coordinate of measured angular rate
1013      *                             expressed in radians per second (rad/s).
1014      * @param measuredAngularRateZ z-coordinate of measured angular rate
1015      *                             expressed in radians per second (rad/s).
1016      * @param trueFx               x-coordinate of true (i.e. fixed)
1017      *                             specific force expressed in meters per
1018      *                             squared second (m/s^2).
1019      * @param trueFy               y-coordinate of true (i.e. fixed)
1020      *                             specific force expressed in meters per
1021      *                             squared second (m/s^2).
1022      * @param trueFz               z-coordinate of true (i.e. fixed)
1023      *                             specific force expressed in meters per
1024      *                             squared second (m/s^2).
1025      * @param result               instance where restored true angular rate
1026      *                             will be stored. Must be 3x1.
1027      * @throws AlgebraException         if there are numerical instabilities.
1028      * @throws IllegalArgumentException if any of the provided parameters
1029      *                                  does not have proper size.
1030      */
1031     public void fix(
1032             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1033             final double trueFx, final double trueFy, final double trueFz, final Matrix result)
1034             throws AlgebraException {
1035 
1036         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1037             throw new IllegalArgumentException();
1038         }
1039 
1040         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ, trueFx, trueFy, trueFz,
1041                 result.getBuffer());
1042     }
1043 
1044     /**
1045      * Fixes provided measured angular rate values by undoing the errors
1046      * introduced by the gyroscope model to restore the true angular
1047      * rate.
1048      *
1049      * @param measuredAngularRate measured angular rate expressed in radians
1050      *                            per second (rad/s). Must have length 3.
1051      * @param trueF               true (i.e. fixed) specific force expressed
1052      *                            in meters per squared second (m/s^2). Must
1053      *                            have length 3.
1054      * @param bias                bias values expressed in radians per
1055      *                            second (rad/s). Must be 3x1.
1056      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1057      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1058      *                            3x3.
1059      * @param result              instance where restored true angular rate
1060      *                            will be stored. Must have length 3.
1061      * @throws AlgebraException         if there are numerical instabilities.
1062      * @throws IllegalArgumentException if any of the provided parameters
1063      *                                  does not have proper size.
1064      */
1065     public void fix(
1066             final double[] measuredAngularRate, final double[] trueF, final Matrix bias,
1067             final Matrix crossCouplingErrors, final Matrix gDependantCrossBias, final double[] result)
1068             throws AlgebraException {
1069         if (measuredAngularRate.length != BodyKinematics.COMPONENTS) {
1070             throw new IllegalArgumentException();
1071         }
1072         if (trueF.length != BodyKinematics.COMPONENTS) {
1073             throw new IllegalArgumentException();
1074         }
1075         if (bias.getRows() != BodyKinematics.COMPONENTS || bias.getColumns() != 1) {
1076             throw new IllegalArgumentException();
1077         }
1078         if (crossCouplingErrors.getRows() != BodyKinematics.COMPONENTS
1079                 || crossCouplingErrors.getColumns() != BodyKinematics.COMPONENTS) {
1080             throw new IllegalArgumentException();
1081         }
1082         if (gDependantCrossBias.getRows() != BodyKinematics.COMPONENTS
1083                 || gDependantCrossBias.getColumns() != BodyKinematics.COMPONENTS) {
1084             throw new IllegalArgumentException();
1085         }
1086         if (result.length != BodyKinematics.COMPONENTS) {
1087             throw new IllegalArgumentException();
1088         }
1089 
1090         // The gyroscope model is
1091         // Ωmeas = bg + (I + Mg) * Ωtrue + Gg * ftrue
1092 
1093         // Ωtrue = (I + Mg)^-1 * (Ωmeas - bg - Gg * ftrue)
1094         identity.add(crossCouplingErrors, tmp1);
1095 
1096         Utils.inverse(tmp1, tmp2);
1097 
1098         tmp3.fromArray(trueF);
1099         gDependantCrossBias.multiply(tmp3, tmp4);
1100 
1101         for (var i = 0; i < BodyKinematics.COMPONENTS; i++) {
1102             diff.setElementAtIndex(i, measuredAngularRate[i] - bias.getElementAtIndex(i)
1103                     - tmp4.getElementAtIndex(i));
1104         }
1105 
1106         tmp2.multiply(diff, tmp5);
1107 
1108         tmp5.toArray(result);
1109     }
1110 
1111     /**
1112      * Fixes provided measured angular rate values by undoing the errors
1113      * introduced by the gyroscope model to restore the true angular
1114      * rate.
1115      *
1116      * @param measuredAngularRate measured angular rate expressed in radians
1117      *                            per second (rad/s). Must be 3x1.
1118      * @param trueF               true (i.e. fixed) specific force expressed
1119      *                            in meters per squared second (m/s^2). Must
1120      *                            be 3x1.
1121      * @param bias                bias values expressed in radians per
1122      *                            second (rad/s). Must be 3x1.
1123      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1124      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1125      *                            3x3.
1126      * @param result              instance where restored true angular rate
1127      *                            will be stored. Must have length 3.
1128      * @throws AlgebraException         if there are numerical instabilities.
1129      * @throws IllegalArgumentException if any of the provided parameters
1130      *                                  does not have proper size.
1131      */
1132     public void fix(
1133             final Matrix measuredAngularRate, final Matrix trueF, final Matrix bias, final Matrix crossCouplingErrors,
1134             final Matrix gDependantCrossBias, final double[] result) throws AlgebraException {
1135 
1136         if (measuredAngularRate.getRows() != BodyKinematics.COMPONENTS || measuredAngularRate.getColumns() != 1) {
1137             throw new IllegalArgumentException();
1138         }
1139         if (trueF.getRows() != BodyKinematics.COMPONENTS || trueF.getColumns() != 1) {
1140             throw new IllegalArgumentException();
1141         }
1142 
1143         fix(measuredAngularRate.getBuffer(), trueF.getBuffer(), bias, crossCouplingErrors, gDependantCrossBias, result);
1144     }
1145 
1146     /**
1147      * Fixes provided measured angular rate values by undoing the errors
1148      * introduced by the gyroscope model to restore the true angular
1149      * rate.
1150      *
1151      * @param measuredAngularRate measured angular rate expressed in radians
1152      *                            per second (rad/s). Must be 3x1.
1153      * @param trueF               true (i.e. fixed) specific force expressed
1154      *                            in meters per squared second (m/s^2). Must
1155      *                            be 3x1.
1156      * @param bias                bias values expressed in radians per
1157      *                            second (rad/s). Must be 3x1.
1158      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1159      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1160      *                            3x3.
1161      * @param result              instance where restored true angular rate
1162      *                            will be stored. Must be 3x1.
1163      * @throws AlgebraException         if there are numerical instabilities.
1164      * @throws IllegalArgumentException if any of the provided parameters
1165      *                                  does not have proper size.
1166      */
1167     public void fix(
1168             final Matrix measuredAngularRate, final Matrix trueF, final Matrix bias, final Matrix crossCouplingErrors,
1169             final Matrix gDependantCrossBias, final Matrix result) throws AlgebraException {
1170 
1171         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1172             throw new IllegalArgumentException();
1173         }
1174 
1175         fix(measuredAngularRate, trueF, bias, crossCouplingErrors, gDependantCrossBias, result.getBuffer());
1176     }
1177 
1178     /**
1179      * Fixes provided measured angular rate values by undoing the errors
1180      * introduced by the gyroscope model to restore the true angular
1181      * rate.
1182      *
1183      * @param measuredAngularRateX x-coordinate of measured angular rate
1184      *                             expressed in radians per second (rad/s).
1185      * @param measuredAngularRateY y-coordinate of measured angular rate
1186      *                             expressed in radians per second (rad/s).
1187      * @param measuredAngularRateZ z-coordinate of measured angular rate
1188      *                             expressed in radians per second (rad/s).
1189      * @param trueFx               x-coordinate of true (i.e. fixed)
1190      *                             specific force expressed in meters per
1191      *                             squared second (m/s^2).
1192      * @param trueFy               y-coordinate of true (i.e. fixed)
1193      *                             specific force expressed in meters per
1194      *                             squared second (m/s^2).
1195      * @param trueFz               z-coordinate of true (i.e. fixed)
1196      *                             specific force expressed in meters per
1197      *                             squared second (m/s^2).
1198      * @param biasX                x-coordinate of bias expressed in
1199      *                             meters per squared second (m/s^2).
1200      * @param biasY                y-coordinate of bias expressed in
1201      *                             meters per squared second (m/s^2).
1202      * @param biasZ                z-coordinate of bias expressed in
1203      *                             meters per squared second (m/s^2).
1204      * @param crossCouplingErrors  cross coupling errors matrix. Must be 3x3.
1205      * @param gDependantCrossBias  g-dependant cross biases matrix. Must be
1206      *                             3x3.
1207      * @param result               instance where restored true angular rate
1208      *                             will be stored. Must have length 3.
1209      * @throws AlgebraException         if there are numerical instabilities.
1210      * @throws IllegalArgumentException if any of the provided parameters
1211      *                                  does not have proper size.
1212      */
1213     public void fix(
1214             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1215             final double trueFx, final double trueFy, final double trueFz,
1216             final double biasX, final double biasY, final double biasZ, final Matrix crossCouplingErrors,
1217             final Matrix gDependantCrossBias, final double[] result) throws AlgebraException {
1218 
1219         measuredAngularRate[0] = measuredAngularRateX;
1220         measuredAngularRate[1] = measuredAngularRateY;
1221         measuredAngularRate[2] = measuredAngularRateZ;
1222 
1223         trueF[0] = trueFx;
1224         trueF[1] = trueFy;
1225         trueF[2] = trueFz;
1226 
1227         bias.setElementAtIndex(0, biasX);
1228         bias.setElementAtIndex(1, biasY);
1229         bias.setElementAtIndex(2, biasZ);
1230 
1231         fix(measuredAngularRate, trueF, bias, crossCouplingErrors, gDependantCrossBias, result);
1232     }
1233 
1234     /**
1235      * Fixes provided measured angular rate values by undoing the errors
1236      * introduced by the gyroscope model to restore the true angular
1237      * rate.
1238      *
1239      * @param measuredAngularRateX x-coordinate of measured angular rate
1240      *                             expressed in radians per second (rad/s).
1241      * @param measuredAngularRateY y-coordinate of measured angular rate
1242      *                             expressed in radians per second (rad/s).
1243      * @param measuredAngularRateZ z-coordinate of measured angular rate
1244      *                             expressed in radians per second (rad/s).
1245      * @param trueFx               x-coordinate of true (i.e. fixed)
1246      *                             specific force expressed in meters per
1247      *                             squared second (m/s^2).
1248      * @param trueFy               y-coordinate of true (i.e. fixed)
1249      *                             specific force expressed in meters per
1250      *                             squared second (m/s^2).
1251      * @param trueFz               z-coordinate of true (i.e. fixed)
1252      *                             specific force expressed in meters per
1253      *                             squared second (m/s^2).
1254      * @param biasX                x-coordinate of bias expressed in
1255      *                             meters per squared second (m/s^2).
1256      * @param biasY                y-coordinate of bias expressed in
1257      *                             meters per squared second (m/s^2).
1258      * @param biasZ                z-coordinate of bias expressed in
1259      *                             meters per squared second (m/s^2).
1260      * @param crossCouplingErrors  cross coupling errors matrix. Must be 3x3.
1261      * @param gDependantCrossBias  g-dependant cross biases matrix. Must be
1262      *                             3x3.
1263      * @param result               instance where restored true angular rate
1264      *                             will be stored. Must be 3x1.
1265      * @throws AlgebraException         if there are numerical instabilities.
1266      * @throws IllegalArgumentException if any of the provided parameters
1267      *                                  does not have proper size.
1268      */
1269     public void fix(
1270             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1271             final double trueFx, final double trueFy, final double trueFz,
1272             final double biasX, final double biasY, final double biasZ, final Matrix crossCouplingErrors,
1273             final Matrix gDependantCrossBias, final Matrix result) throws AlgebraException {
1274 
1275         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1276             throw new IllegalArgumentException();
1277         }
1278 
1279         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1280                 trueFx, trueFy, trueFz, biasX, biasY, biasZ, crossCouplingErrors, gDependantCrossBias,
1281                 result.getBuffer());
1282     }
1283 
1284     /**
1285      * Fixes provided measured angular rate values by undoing the errors
1286      * introduced by the gyroscope model to restore the true angular
1287      * rate.
1288      *
1289      * @param measuredAngularRateX x-coordinate of measured angular rate
1290      *                             expressed in radians per second (rad/s).
1291      * @param measuredAngularRateY y-coordinate of measured angular rate
1292      *                             expressed in radians per second (rad/s).
1293      * @param measuredAngularRateZ z-coordinate of measured angular rate
1294      *                             expressed in radians per second (rad/s).
1295      * @param trueFx               x-coordinate of true (i.e. fixed)
1296      *                             specific force expressed in meters per
1297      *                             squared second (m/s^2).
1298      * @param trueFy               y-coordinate of true (i.e. fixed)
1299      *                             specific force expressed in meters per
1300      *                             squared second (m/s^2).
1301      * @param trueFz               z-coordinate of true (i.e. fixed)
1302      *                             specific force expressed in meters per
1303      *                             squared second (m/s^2).
1304      * @param biasX                x-coordinate of bias expressed in
1305      *                             meters per squared second (m/s^2).
1306      * @param biasY                y-coordinate of bias expressed in
1307      *                             meters per squared second (m/s^2).
1308      * @param biasZ                z-coordinate of bias expressed in
1309      *                             meters per squared second (m/s^2).
1310      * @param sx                   initial x scaling factor.
1311      * @param sy                   initial y scaling factor.
1312      * @param sz                   initial z scaling factor.
1313      * @param mxy                  initial x-y cross coupling error.
1314      * @param mxz                  initial x-z cross coupling error.
1315      * @param myx                  initial y-x cross coupling error.
1316      * @param myz                  initial y-z cross coupling error.
1317      * @param mzx                  initial z-x cross coupling error.
1318      * @param mzy                  initial z-y cross coupling error.
1319      * @param g11                  element 1,1 of g-dependant cross biases.
1320      * @param g21                  element 2,1 of g-dependant cross biases.
1321      * @param g31                  element 3,1 of g-dependant cross biases.
1322      * @param g12                  element 1,2 of g-dependant cross biases.
1323      * @param g22                  element 2,2 of g-dependant cross biases.
1324      * @param g32                  element 3,2 of g-dependant cross biases.
1325      * @param g13                  element 1,3 of g-dependant cross biases.
1326      * @param g23                  element 2,3 of g-dependant cross biases.
1327      * @param g33                  element 3,3 of g-dependant cross biases.
1328      * @param result               instance where restored true angular rate
1329      *                             will be stored. Must have length 3.
1330      * @throws AlgebraException         if there are numerical instabilities.
1331      * @throws IllegalArgumentException if any of the provided parameters
1332      *                                  does not have proper size.
1333      */
1334     public void fix(
1335             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1336             final double trueFx, final double trueFy, final double trueFz,
1337             final double biasX, final double biasY, final double biasZ,
1338             final double sx, final double sy, final double sz,
1339             final double mxy, final double mxz, final double myx,
1340             final double myz, final double mzx, final double mzy,
1341             final double g11, final double g21, final double g31,
1342             final double g12, final double g22, final double g32,
1343             final double g13, final double g23, final double g33, final double[] result) throws AlgebraException {
1344 
1345         crossCouplingErrors.setElementAt(0, 0, sx);
1346         crossCouplingErrors.setElementAt(1, 1, sy);
1347         crossCouplingErrors.setElementAt(2, 2, sz);
1348         crossCouplingErrors.setElementAt(0, 1, mxy);
1349         crossCouplingErrors.setElementAt(0, 2, mxz);
1350         crossCouplingErrors.setElementAt(1, 0, myx);
1351         crossCouplingErrors.setElementAt(1, 2, myz);
1352         crossCouplingErrors.setElementAt(2, 0, mzx);
1353         crossCouplingErrors.setElementAt(2, 1, mzy);
1354 
1355         gDependantCrossBias.setElementAt(0, 0, g11);
1356         gDependantCrossBias.setElementAt(1, 0, g21);
1357         gDependantCrossBias.setElementAt(2, 0, g31);
1358         gDependantCrossBias.setElementAt(0, 1, g12);
1359         gDependantCrossBias.setElementAt(1, 1, g22);
1360         gDependantCrossBias.setElementAt(2, 1, g32);
1361         gDependantCrossBias.setElementAt(0, 2, g13);
1362         gDependantCrossBias.setElementAt(1, 2, g23);
1363         gDependantCrossBias.setElementAt(2, 2, g33);
1364 
1365         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ, trueFx, trueFy, trueFz,
1366                 biasX, biasY, biasZ, crossCouplingErrors, gDependantCrossBias, result);
1367     }
1368 
1369     /**
1370      * Fixes provided measured angular rate values by undoing the errors
1371      * introduced by the gyroscope model to restore the true angular
1372      * rate.
1373      *
1374      * @param measuredAngularRateX x-coordinate of measured angular rate
1375      *                             expressed in radians per second (rad/s).
1376      * @param measuredAngularRateY y-coordinate of measured angular rate
1377      *                             expressed in radians per second (rad/s).
1378      * @param measuredAngularRateZ z-coordinate of measured angular rate
1379      *                             expressed in radians per second (rad/s).
1380      * @param trueFx               x-coordinate of true (i.e. fixed)
1381      *                             specific force expressed in meters per
1382      *                             squared second (m/s^2).
1383      * @param trueFy               y-coordinate of true (i.e. fixed)
1384      *                             specific force expressed in meters per
1385      *                             squared second (m/s^2).
1386      * @param trueFz               z-coordinate of true (i.e. fixed)
1387      *                             specific force expressed in meters per
1388      *                             squared second (m/s^2).
1389      * @param biasX                x-coordinate of bias expressed in
1390      *                             meters per squared second (m/s^2).
1391      * @param biasY                y-coordinate of bias expressed in
1392      *                             meters per squared second (m/s^2).
1393      * @param biasZ                z-coordinate of bias expressed in
1394      *                             meters per squared second (m/s^2).
1395      * @param sx                   initial x scaling factor.
1396      * @param sy                   initial y scaling factor.
1397      * @param sz                   initial z scaling factor.
1398      * @param mxy                  initial x-y cross coupling error.
1399      * @param mxz                  initial x-z cross coupling error.
1400      * @param myx                  initial y-x cross coupling error.
1401      * @param myz                  initial y-z cross coupling error.
1402      * @param mzx                  initial z-x cross coupling error.
1403      * @param mzy                  initial z-y cross coupling error.
1404      * @param g11                  element 1,1 of g-dependant cross biases.
1405      * @param g21                  element 2,1 of g-dependant cross biases.
1406      * @param g31                  element 3,1 of g-dependant cross biases.
1407      * @param g12                  element 1,2 of g-dependant cross biases.
1408      * @param g22                  element 2,2 of g-dependant cross biases.
1409      * @param g32                  element 3,2 of g-dependant cross biases.
1410      * @param g13                  element 1,3 of g-dependant cross biases.
1411      * @param g23                  element 2,3 of g-dependant cross biases.
1412      * @param g33                  element 3,3 of g-dependant cross biases.
1413      * @param result               instance where restored true angular rate
1414      *                             will be stored. Must be 3x1.
1415      * @throws AlgebraException         if there are numerical instabilities.
1416      * @throws IllegalArgumentException if any of the provided parameters
1417      *                                  does not have proper size.
1418      */
1419     public void fix(
1420             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1421             final double trueFx, final double trueFy, final double trueFz,
1422             final double biasX, final double biasY, final double biasZ,
1423             final double sx, final double sy, final double sz,
1424             final double mxy, final double mxz, final double myx,
1425             final double myz, final double mzx, final double mzy,
1426             final double g11, final double g21, final double g31,
1427             final double g12, final double g22, final double g32,
1428             final double g13, final double g23, final double g33, final Matrix result) throws AlgebraException {
1429 
1430         if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
1431             throw new IllegalArgumentException();
1432         }
1433 
1434         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1435                 trueFx, trueFy, trueFz, biasX, biasY, biasZ,
1436                 sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy,
1437                 g11, g21, g31, g12, g22, g32, g13, g23, g33, result.getBuffer());
1438     }
1439 
1440     /**
1441      * Fixes provided measured angular rate values by undoing the errors
1442      * introduced by the gyroscope model to restore the true angular rate.
1443      * This method uses last provided bias and cross coupling errors.
1444      *
1445      * @param measuredAngularRate measured angular rate.
1446      * @param trueF               true (i.e. fixed) specific force.
1447      * @return restored true angular rate.
1448      * @throws AlgebraException if there are numerical instabilities.
1449      */
1450     public AngularSpeedTriad fixAndReturnNew(
1451             final AngularSpeedTriad measuredAngularRate, final AccelerationTriad trueF) throws AlgebraException {
1452         final var result = new AngularSpeedTriad();
1453         fix(measuredAngularRate, trueF, result);
1454         return result;
1455     }
1456 
1457     /**
1458      * Fixes provided measured angular rate values by undoing the errors
1459      * introduced by the gyroscope model to restore the true angular rate.
1460      * This method uses last provided bias and cross coupling errors.
1461      *
1462      * @param measuredAngularRateX x-coordinate of measured angular rate.
1463      * @param measuredAngularRateY y-coordinate of measured angular rate.
1464      * @param measuredAngularRateZ z-coordinate of measured angular rate.
1465      * @param trueFx               x-coordinate of true (i.e. fixed) specific force.
1466      * @param trueFy               y-coordinate of true (i.e. fixed) specific force.
1467      * @param trueFz               z-coordinate of true (i.e. fixed) specific force.
1468      * @return restored true angular rate.
1469      * @throws AlgebraException if there are numerical instabilities.
1470      */
1471     public AngularSpeedTriad fixAndReturnNew(
1472             final AngularSpeed measuredAngularRateX, final AngularSpeed measuredAngularRateY,
1473             final AngularSpeed measuredAngularRateZ, final Acceleration trueFx, final Acceleration trueFy,
1474             final Acceleration trueFz) throws AlgebraException {
1475         final var result = new AngularSpeedTriad();
1476         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ, trueFx, trueFy, trueFz, result);
1477         return result;
1478     }
1479 
1480     /**
1481      * Fixes provided measured angular rate values by undoing the errors
1482      * introduced by the gyroscope model to restore the true angular
1483      * rate.
1484      * This method uses last provided bias and cross coupling errors.
1485      *
1486      * @param measuredAngularRate measured angular rate expressed in radians
1487      *                            per second (rad/s). Must have length 3.
1488      * @param trueF               true (i.e. fixed) specific force expressed
1489      *                            in meters per squared second (m/s^2). Must
1490      *                            have length 3.
1491      * @return restored true angular rate.
1492      * @throws AlgebraException         if there are numerical instabilities.
1493      * @throws IllegalArgumentException if any of the provided parameters
1494      *                                  does not have proper size.
1495      */
1496     public double[] fixAndReturnNew(final double[] measuredAngularRate, final double[] trueF) throws AlgebraException {
1497         final var result = new double[BodyKinematics.COMPONENTS];
1498         fix(measuredAngularRate, trueF, result);
1499         return result;
1500     }
1501 
1502     /**
1503      * Fixes provided measured angular rate values by undoing the errors
1504      * introduced by the gyroscope model to restore the true angular
1505      * rate.
1506      * This method uses last provided bias and cross coupling errors.
1507      *
1508      * @param measuredAngularRate measured angular rate expressed in radians
1509      *                            per second (rad/s). Must be 3x1.
1510      * @param trueF               true (i.e. fixed) specific force expressed
1511      *                            in meters per squared second (m/s^2). Must
1512      *                            be 3x1.
1513      * @return restored true angular rate.
1514      * @throws AlgebraException         if there are numerical instabilities.
1515      * @throws IllegalArgumentException if any of the provided parameters
1516      *                                  does not have proper size.
1517      */
1518     public double[] fixAndReturnNew(final Matrix measuredAngularRate, final Matrix trueF) throws AlgebraException {
1519         final var result = new double[BodyKinematics.COMPONENTS];
1520         fix(measuredAngularRate, trueF, result);
1521         return result;
1522     }
1523 
1524     /**
1525      * Fixes provided measured angular rate values by undoing the errors
1526      * introduced by the gyroscope model to restore the true angular
1527      * rate.
1528      * This method uses last provided bias and cross coupling errors.
1529      *
1530      * @param measuredAngularRate measured angular rate expressed in radians
1531      *                            per second (rad/s). Must be 3x1.
1532      * @param trueF               true (i.e. fixed) specific force expressed
1533      *                            in meters per squared second (m/s^2). Must
1534      *                            be 3x1.
1535      * @return restored true angular rate.
1536      * @throws AlgebraException         if there are numerical instabilities.
1537      * @throws IllegalArgumentException if any of the provided parameters
1538      *                                  does not have proper size.
1539      */
1540     public Matrix fixAndReturnNewMatrix(
1541             final Matrix measuredAngularRate, final Matrix trueF) throws AlgebraException {
1542 
1543         final var result = new Matrix(BodyKinematics.COMPONENTS, 1);
1544         fix(measuredAngularRate, trueF, result);
1545         return result;
1546     }
1547 
1548     /**
1549      * Fixes provided measured angular rate values by undoing the errors
1550      * introduced by the gyroscope model to restore the true angular
1551      * rate.
1552      * This method uses last provided bias and cross coupling errors.
1553      *
1554      * @param measuredAngularRateX x-coordinate of measured angular rate
1555      *                             expressed in radians per second (rad/s).
1556      * @param measuredAngularRateY y-coordinate of measured angular rate
1557      *                             expressed in radians per second (rad/s).
1558      * @param measuredAngularRateZ z-coordinate of measured angular rate
1559      *                             expressed in radians per second (rad/s).
1560      * @param trueFx               x-coordinate of true (i.e. fixed)
1561      *                             specific force expressed in meters per
1562      *                             squared second (m/s^2).
1563      * @param trueFy               y-coordinate of true (i.e. fixed)
1564      *                             specific force expressed in meters per
1565      *                             squared second (m/s^2).
1566      * @param trueFz               z-coordinate of true (i.e. fixed)
1567      *                             specific force expressed in meters per
1568      *                             squared second (m/s^2).
1569      * @return restored true angular rate.
1570      * @throws AlgebraException if there are numerical instabilities.
1571      */
1572     public double[] fixAndReturnNew(
1573             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1574             final double trueFx, final double trueFy, final double trueFz) throws AlgebraException {
1575 
1576         final var result = new double[BodyKinematics.COMPONENTS];
1577         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ, trueFx, trueFy, trueFz, result);
1578         return result;
1579     }
1580 
1581     /**
1582      * Fixes provided measured angular rate values by undoing the errors
1583      * introduced by the gyroscope model to restore the true angular
1584      * rate.
1585      * This method uses last provided bias and cross coupling errors.
1586      *
1587      * @param measuredAngularRateX x-coordinate of measured angular rate
1588      *                             expressed in radians per second (rad/s).
1589      * @param measuredAngularRateY y-coordinate of measured angular rate
1590      *                             expressed in radians per second (rad/s).
1591      * @param measuredAngularRateZ z-coordinate of measured angular rate
1592      *                             expressed in radians per second (rad/s).
1593      * @param trueFx               x-coordinate of true (i.e. fixed)
1594      *                             specific force expressed in meters per
1595      *                             squared second (m/s^2).
1596      * @param trueFy               y-coordinate of true (i.e. fixed)
1597      *                             specific force expressed in meters per
1598      *                             squared second (m/s^2).
1599      * @param trueFz               z-coordinate of true (i.e. fixed)
1600      *                             specific force expressed in meters per
1601      *                             squared second (m/s^2).
1602      * @return restored true angular rate.
1603      * @throws AlgebraException if there are numerical instabilities.
1604      */
1605     public Matrix fixAndReturnNewMatrix(
1606             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1607             final double trueFx, final double trueFy, final double trueFz) throws AlgebraException {
1608 
1609         final var result = new Matrix(BodyKinematics.COMPONENTS, 1);
1610         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ, trueFx, trueFy, trueFz, result);
1611         return result;
1612     }
1613 
1614 
1615     /**
1616      * Fixes provided measured angular rate values by undoing the errors
1617      * introduced by the gyroscope model to restore the true angular
1618      * rate.
1619      *
1620      * @param measuredAngularRate measured angular rate expressed in radians
1621      *                            per second (rad/s). Must have length 3.
1622      * @param trueF               true (i.e. fixed) specific force expressed
1623      *                            in meters per squared second (m/s^2). Must
1624      *                            have length 3.
1625      * @param bias                bias values expressed in radians per
1626      *                            second (rad/s). Must be 3x1.
1627      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1628      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1629      *                            3x3.
1630      * @return restored true angular rate.
1631      * @throws AlgebraException         if there are numerical instabilities.
1632      * @throws IllegalArgumentException if any of the provided parameters
1633      *                                  does not have proper size.
1634      */
1635     public double[] fixAndReturnNew(
1636             final double[] measuredAngularRate, final double[] trueF, final Matrix bias,
1637             final Matrix crossCouplingErrors, final Matrix gDependantCrossBias) throws AlgebraException {
1638 
1639         final var result = new double[BodyKinematics.COMPONENTS];
1640         fix(measuredAngularRate, trueF, bias, crossCouplingErrors, gDependantCrossBias, result);
1641         return result;
1642     }
1643 
1644     /**
1645      * Fixes provided measured angular rate values by undoing the errors
1646      * introduced by the gyroscope model to restore the true angular
1647      * rate.
1648      *
1649      * @param measuredAngularRate measured angular rate expressed in radians
1650      *                            per second (rad/s). Must be 3x1.
1651      * @param trueF               true (i.e. fixed) specific force expressed
1652      *                            in meters per squared second (m/s^2). Must
1653      *                            be 3x1.
1654      * @param bias                bias values expressed in radians per
1655      *                            second (rad/s). Must be 3x1.
1656      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1657      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1658      *                            3x3.
1659      * @return restored true angular rate.
1660      * @throws AlgebraException         if there are numerical instabilities.
1661      * @throws IllegalArgumentException if any of the provided parameters
1662      *                                  does not have proper size.
1663      */
1664     public double[] fixAndReturnNew(
1665             final Matrix measuredAngularRate, final Matrix trueF, final Matrix bias,
1666             final Matrix crossCouplingErrors, final Matrix gDependantCrossBias) throws AlgebraException {
1667 
1668         final var result = new double[BodyKinematics.COMPONENTS];
1669         fix(measuredAngularRate, trueF, bias, crossCouplingErrors, gDependantCrossBias, result);
1670         return result;
1671     }
1672 
1673     /**
1674      * Fixes provided measured angular rate values by undoing the errors
1675      * introduced by the gyroscope model to restore the true angular
1676      * rate.
1677      *
1678      * @param measuredAngularRate measured angular rate expressed in radians
1679      *                            per second (rad/s). Must be 3x1.
1680      * @param trueF               true (i.e. fixed) specific force expressed
1681      *                            in meters per squared second (m/s^2). Must
1682      *                            be 3x1.
1683      * @param bias                bias values expressed in radians per
1684      *                            second (rad/s). Must be 3x1.
1685      * @param crossCouplingErrors cross coupling errors matrix. Must be 3x3.
1686      * @param gDependantCrossBias g-dependant cross biases matrix. Must be
1687      *                            3x3.
1688      * @return restored true angular rate.
1689      * @throws AlgebraException         if there are numerical instabilities.
1690      * @throws IllegalArgumentException if any of the provided parameters
1691      *                                  does not have proper size.
1692      */
1693     public Matrix fixAndReturnNewMatrix(
1694             final Matrix measuredAngularRate, final Matrix trueF, final Matrix bias,
1695             final Matrix crossCouplingErrors, final Matrix gDependantCrossBias) throws AlgebraException {
1696 
1697         final var result = new Matrix(BodyKinematics.COMPONENTS, 1);
1698         fix(measuredAngularRate, trueF, bias, crossCouplingErrors, gDependantCrossBias, result);
1699         return result;
1700     }
1701 
1702     /**
1703      * Fixes provided measured angular rate values by undoing the errors
1704      * introduced by the gyroscope model to restore the true angular
1705      * rate.
1706      *
1707      * @param measuredAngularRateX x-coordinate of measured angular rate
1708      *                             expressed in radians per second (rad/s).
1709      * @param measuredAngularRateY y-coordinate of measured angular rate
1710      *                             expressed in radians per second (rad/s).
1711      * @param measuredAngularRateZ z-coordinate of measured angular rate
1712      *                             expressed in radians per second (rad/s).
1713      * @param trueFx               x-coordinate of true (i.e. fixed)
1714      *                             specific force expressed in meters per
1715      *                             squared second (m/s^2).
1716      * @param trueFy               y-coordinate of true (i.e. fixed)
1717      *                             specific force expressed in meters per
1718      *                             squared second (m/s^2).
1719      * @param trueFz               z-coordinate of true (i.e. fixed)
1720      *                             specific force expressed in meters per
1721      *                             squared second (m/s^2).
1722      * @param biasX                x-coordinate of bias expressed in
1723      *                             meters per squared second (m/s^2).
1724      * @param biasY                y-coordinate of bias expressed in
1725      *                             meters per squared second (m/s^2).
1726      * @param biasZ                z-coordinate of bias expressed in
1727      *                             meters per squared second (m/s^2).
1728      * @param crossCouplingErrors  cross coupling errors matrix. Must be 3x3.
1729      * @param gDependantCrossBias  g-dependant cross biases matrix. Must be
1730      *                             3x3.
1731      * @return restored true angular rate.
1732      * @throws AlgebraException         if there are numerical instabilities.
1733      * @throws IllegalArgumentException if any of the provided parameters
1734      *                                  does not have proper size.
1735      */
1736     public double[] fixAndReturnNew(
1737             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1738             final double trueFx, final double trueFy, final double trueFz,
1739             final double biasX, final double biasY, final double biasZ, final Matrix crossCouplingErrors,
1740             final Matrix gDependantCrossBias) throws AlgebraException {
1741 
1742         final var result = new double[BodyKinematics.COMPONENTS];
1743         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1744                 trueFx, trueFy, trueFz, biasX, biasY, biasZ, crossCouplingErrors, gDependantCrossBias, result);
1745         return result;
1746     }
1747 
1748     /**
1749      * Fixes provided measured angular rate values by undoing the errors
1750      * introduced by the gyroscope model to restore the true angular
1751      * rate.
1752      *
1753      * @param measuredAngularRateX x-coordinate of measured angular rate
1754      *                             expressed in radians per second (rad/s).
1755      * @param measuredAngularRateY y-coordinate of measured angular rate
1756      *                             expressed in radians per second (rad/s).
1757      * @param measuredAngularRateZ z-coordinate of measured angular rate
1758      *                             expressed in radians per second (rad/s).
1759      * @param trueFx               x-coordinate of true (i.e. fixed)
1760      *                             specific force expressed in meters per
1761      *                             squared second (m/s^2).
1762      * @param trueFy               y-coordinate of true (i.e. fixed)
1763      *                             specific force expressed in meters per
1764      *                             squared second (m/s^2).
1765      * @param trueFz               z-coordinate of true (i.e. fixed)
1766      *                             specific force expressed in meters per
1767      *                             squared second (m/s^2).
1768      * @param biasX                x-coordinate of bias expressed in
1769      *                             meters per squared second (m/s^2).
1770      * @param biasY                y-coordinate of bias expressed in
1771      *                             meters per squared second (m/s^2).
1772      * @param biasZ                z-coordinate of bias expressed in
1773      *                             meters per squared second (m/s^2).
1774      * @param crossCouplingErrors  cross coupling errors matrix. Must be 3x3.
1775      * @param gDependantCrossBias  g-dependant cross biases matrix. Must be
1776      *                             3x3.
1777      * @return restored true angular rate.
1778      * @throws AlgebraException         if there are numerical instabilities.
1779      * @throws IllegalArgumentException if any of the provided parameters
1780      *                                  does not have proper size.
1781      */
1782     public Matrix fixAndReturnNewMatrix(
1783             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1784             final double trueFx, final double trueFy, final double trueFz,
1785             final double biasX, final double biasY, final double biasZ,
1786             final Matrix crossCouplingErrors, final Matrix gDependantCrossBias) throws AlgebraException {
1787 
1788         final var result = new Matrix(BodyKinematics.COMPONENTS, 1);
1789         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1790                 trueFx, trueFy, trueFz, biasX, biasY, biasZ, crossCouplingErrors, gDependantCrossBias, result);
1791         return result;
1792     }
1793 
1794     /**
1795      * Fixes provided measured angular rate values by undoing the errors
1796      * introduced by the gyroscope model to restore the true angular
1797      * rate.
1798      *
1799      * @param measuredAngularRateX x-coordinate of measured angular rate
1800      *                             expressed in radians per second (rad/s).
1801      * @param measuredAngularRateY y-coordinate of measured angular rate
1802      *                             expressed in radians per second (rad/s).
1803      * @param measuredAngularRateZ z-coordinate of measured angular rate
1804      *                             expressed in radians per second (rad/s).
1805      * @param trueFx               x-coordinate of true (i.e. fixed)
1806      *                             specific force expressed in meters per
1807      *                             squared second (m/s^2).
1808      * @param trueFy               y-coordinate of true (i.e. fixed)
1809      *                             specific force expressed in meters per
1810      *                             squared second (m/s^2).
1811      * @param trueFz               z-coordinate of true (i.e. fixed)
1812      *                             specific force expressed in meters per
1813      *                             squared second (m/s^2).
1814      * @param biasX                x-coordinate of bias expressed in
1815      *                             meters per squared second (m/s^2).
1816      * @param biasY                y-coordinate of bias expressed in
1817      *                             meters per squared second (m/s^2).
1818      * @param biasZ                z-coordinate of bias expressed in
1819      *                             meters per squared second (m/s^2).
1820      * @param sx                   initial x scaling factor.
1821      * @param sy                   initial y scaling factor.
1822      * @param sz                   initial z scaling factor.
1823      * @param mxy                  initial x-y cross coupling error.
1824      * @param mxz                  initial x-z cross coupling error.
1825      * @param myx                  initial y-x cross coupling error.
1826      * @param myz                  initial y-z cross coupling error.
1827      * @param mzx                  initial z-x cross coupling error.
1828      * @param mzy                  initial z-y cross coupling error.
1829      * @param g11                  element 1,1 of g-dependant cross biases.
1830      * @param g21                  element 2,1 of g-dependant cross biases.
1831      * @param g31                  element 3,1 of g-dependant cross biases.
1832      * @param g12                  element 1,2 of g-dependant cross biases.
1833      * @param g22                  element 2,2 of g-dependant cross biases.
1834      * @param g32                  element 3,2 of g-dependant cross biases.
1835      * @param g13                  element 1,3 of g-dependant cross biases.
1836      * @param g23                  element 2,3 of g-dependant cross biases.
1837      * @param g33                  element 3,3 of g-dependant cross biases.
1838      * @return restored true angular rate.
1839      * @throws AlgebraException if there are numerical instabilities.
1840      */
1841     public double[] fixAndReturnNew(
1842             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1843             final double trueFx, final double trueFy, final double trueFz,
1844             final double biasX, final double biasY, final double biasZ,
1845             final double sx, final double sy, final double sz,
1846             final double mxy, final double mxz, final double myx,
1847             final double myz, final double mzx, final double mzy,
1848             final double g11, final double g21, final double g31,
1849             final double g12, final double g22, final double g32,
1850             final double g13, final double g23, final double g33) throws AlgebraException {
1851 
1852         final var result = new double[BodyKinematics.COMPONENTS];
1853         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1854                 trueFx, trueFy, trueFz, biasX, biasY, biasZ, sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy,
1855                 g11, g21, g31, g12, g22, g32, g13, g23, g33, result);
1856         return result;
1857     }
1858 
1859     /**
1860      * Fixes provided measured angular rate values by undoing the errors
1861      * introduced by the gyroscope model to restore the true angular
1862      * rate.
1863      *
1864      * @param measuredAngularRateX x-coordinate of measured angular rate
1865      *                             expressed in radians per second (rad/s).
1866      * @param measuredAngularRateY y-coordinate of measured angular rate
1867      *                             expressed in radians per second (rad/s).
1868      * @param measuredAngularRateZ z-coordinate of measured angular rate
1869      *                             expressed in radians per second (rad/s).
1870      * @param trueFx               x-coordinate of true (i.e. fixed)
1871      *                             specific force expressed in meters per
1872      *                             squared second (m/s^2).
1873      * @param trueFy               y-coordinate of true (i.e. fixed)
1874      *                             specific force expressed in meters per
1875      *                             squared second (m/s^2).
1876      * @param trueFz               z-coordinate of true (i.e. fixed)
1877      *                             specific force expressed in meters per
1878      *                             squared second (m/s^2).
1879      * @param biasX                x-coordinate of bias expressed in
1880      *                             meters per squared second (m/s^2).
1881      * @param biasY                y-coordinate of bias expressed in
1882      *                             meters per squared second (m/s^2).
1883      * @param biasZ                z-coordinate of bias expressed in
1884      *                             meters per squared second (m/s^2).
1885      * @param sx                   initial x scaling factor.
1886      * @param sy                   initial y scaling factor.
1887      * @param sz                   initial z scaling factor.
1888      * @param mxy                  initial x-y cross coupling error.
1889      * @param mxz                  initial x-z cross coupling error.
1890      * @param myx                  initial y-x cross coupling error.
1891      * @param myz                  initial y-z cross coupling error.
1892      * @param mzx                  initial z-x cross coupling error.
1893      * @param mzy                  initial z-y cross coupling error.
1894      * @param g11                  element 1,1 of g-dependant cross biases.
1895      * @param g21                  element 2,1 of g-dependant cross biases.
1896      * @param g31                  element 3,1 of g-dependant cross biases.
1897      * @param g12                  element 1,2 of g-dependant cross biases.
1898      * @param g22                  element 2,2 of g-dependant cross biases.
1899      * @param g32                  element 3,2 of g-dependant cross biases.
1900      * @param g13                  element 1,3 of g-dependant cross biases.
1901      * @param g23                  element 2,3 of g-dependant cross biases.
1902      * @param g33                  element 3,3 of g-dependant cross biases.
1903      * @return restored true angular rate.
1904      * @throws AlgebraException if there are numerical instabilities.
1905      */
1906     public Matrix fixAndReturnNewMatrix(
1907             final double measuredAngularRateX, final double measuredAngularRateY, final double measuredAngularRateZ,
1908             final double trueFx, final double trueFy, final double trueFz,
1909             final double biasX, final double biasY, final double biasZ,
1910             final double sx, final double sy, final double sz,
1911             final double mxy, final double mxz, final double myx,
1912             final double myz, final double mzx, final double mzy,
1913             final double g11, final double g21, final double g31,
1914             final double g12, final double g22, final double g32,
1915             final double g13, final double g23, final double g33) throws AlgebraException {
1916 
1917         final var result = new Matrix(BodyKinematics.COMPONENTS, 1);
1918         fix(measuredAngularRateX, measuredAngularRateY, measuredAngularRateZ,
1919                 trueFx, trueFy, trueFz, biasX, biasY, biasZ, sx, sy, sz, mxy, mxz, myx, myz, mzx, mzy,
1920                 g11, g21, g31, g12, g22, g32, g13, g23, g33, result);
1921         return result;
1922     }
1923 
1924     /**
1925      * Converts angular speed value and unit to radians per second (rad/s).
1926      *
1927      * @param value value to be converted.
1928      * @param unit  unit of value to be converted.
1929      * @return converted value.
1930      */
1931     private static double convertAngularSpeed(final double value, final AngularSpeedUnit unit) {
1932         return AngularSpeedConverter.convert(value, unit, AngularSpeedUnit.RADIANS_PER_SECOND);
1933     }
1934 
1935     /**
1936      * Converts angular speed measurement to radians per second (rad/s).
1937      *
1938      * @param angularSpeed angular speed to be converted.
1939      * @return converted value.
1940      */
1941     private static double convertAngularSpeed(final AngularSpeed angularSpeed) {
1942         return convertAngularSpeed(angularSpeed.getValue().doubleValue(), angularSpeed.getUnit());
1943     }
1944 
1945     /**
1946      * Converts acceleration value and unit to meters per squared second (m/s^2).
1947      *
1948      * @param value value to be converted.
1949      * @param unit  unit of value to be converted.
1950      * @return converted value.
1951      */
1952     private static double convertAcceleration(final double value, final AccelerationUnit unit) {
1953         return AccelerationConverter.convert(value, unit, AccelerationUnit.METERS_PER_SQUARED_SECOND);
1954     }
1955 
1956     /**
1957      * Converts acceleration measurement to meters per squared second (m/s^2).
1958      *
1959      * @param acceleration acceleration to be converted.
1960      * @return converted value.
1961      */
1962     private static double convertAcceleration(final Acceleration acceleration) {
1963         return convertAcceleration(acceleration.getValue().doubleValue(), acceleration.getUnit());
1964     }
1965 }