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