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.WrongSizeException;
21 import com.irurueta.navigation.LockedException;
22 import com.irurueta.navigation.NotReadyException;
23 import com.irurueta.navigation.inertial.BodyKinematics;
24 import com.irurueta.navigation.inertial.INSLooselyCoupledKalmanInitializerConfig;
25 import com.irurueta.navigation.inertial.INSTightlyCoupledKalmanInitializerConfig;
26 import com.irurueta.navigation.inertial.calibration.AccelerationTriad;
27 import com.irurueta.navigation.inertial.calibration.AccelerometerBiasUncertaintySource;
28 import com.irurueta.navigation.inertial.calibration.AccelerometerCalibrationSource;
29 import com.irurueta.navigation.inertial.calibration.CalibrationException;
30 import com.irurueta.navigation.inertial.calibration.StandardDeviationFrameBodyKinematics;
31 import com.irurueta.navigation.inertial.estimators.ECEFKinematicsEstimator;
32 import com.irurueta.numerical.fitting.FittingException;
33 import com.irurueta.numerical.fitting.LevenbergMarquardtMultiVariateFitter;
34 import com.irurueta.numerical.fitting.LevenbergMarquardtMultiVariateFunctionEvaluator;
35 import com.irurueta.statistics.MaxIterationsExceededException;
36 import com.irurueta.units.Acceleration;
37 import com.irurueta.units.AccelerationConverter;
38 import com.irurueta.units.AccelerationUnit;
39
40 import java.util.Collection;
41
42 /**
43 * Estimates accelerometer biases, cross couplings and scaling factors.
44 * <p>
45 * This calibrator uses an iterative approach to find a minimum least squared error
46 * solution.
47 * <p>
48 * To use this calibrator at least 4 measurements at different known frames must
49 * be provided. In other words, accelerometer samples must be obtained at 4
50 * different positions, orientations and velocities (although typically velocities are
51 * always zero).
52 * <p>
53 * Measured specific force is assumed to follow the model shown below:
54 * <pre>
55 * fmeas = ba + (I + Ma) * ftrue + w
56 * </pre>
57 * Where:
58 * - fmeas is the measured specific force. This is a 3x1 vector.
59 * - ba is accelerometer bias. Ideally, on a perfect accelerometer, this should be a
60 * 3x1 zero vector.
61 * - I is the 3x3 identity matrix.
62 * - Ma is the 3x3 matrix containing cross-couplings and scaling factors. Ideally, on
63 * a perfect accelerometer, this should be a 3x3 zero matrix.
64 * - ftrue is ground-truth specific force.
65 * - w is measurement noise.
66 */
67 public class KnownFrameAccelerometerNonLinearLeastSquaresCalibrator implements
68 KnownFrameAccelerometerCalibrator<StandardDeviationFrameBodyKinematics,
69 KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener>, AccelerometerNonLinearCalibrator,
70 UnknownBiasNonLinearAccelerometerCalibrator, AccelerometerCalibrationSource,
71 AccelerometerBiasUncertaintySource, UnorderedStandardDeviationFrameBodyKinematicsAccelerometerCalibrator {
72
73 /**
74 * Indicates whether by default a common z-axis is assumed for both the accelerometer
75 * and gyroscope.
76 */
77 public static final boolean DEFAULT_USE_COMMON_Z_AXIS = false;
78
79 /**
80 * Required minimum number of measurements.
81 */
82 public static final int MINIMUM_MEASUREMENTS = 4;
83
84 /**
85 * Number of unknowns when common z-axis is assumed for both the accelerometer
86 * and gyroscope.
87 */
88 private static final int COMMON_Z_AXIS_UNKNOWNS = 9;
89
90 /**
91 * Number of unknowns for the general case.
92 */
93 private static final int GENERAL_UNKNOWNS = 12;
94
95 /**
96 * Levenberg-Marquardt fitter to find a non-linear solution.
97 */
98 private final LevenbergMarquardtMultiVariateFitter fitter = new LevenbergMarquardtMultiVariateFitter();
99
100 /**
101 * Initial x-coordinate of accelerometer bias to be used to find a solution.
102 * This is expressed in meters per squared second (m/s^2).
103 */
104 private double initialBiasX;
105
106 /**
107 * Initial y-coordinate of accelerometer bias to be used to find a solution.
108 * This is expressed in meters per squared second (m/s^2).
109 */
110 private double initialBiasY;
111
112 /**
113 * Initial z-coordinate of accelerometer bias to be used to find a solution.
114 * This is expressed in meters per squared second (m/s^2).
115 */
116 private double initialBiasZ;
117
118 /**
119 * Initial x scaling factor.
120 */
121 private double initialSx;
122
123 /**
124 * Initial y scaling factor.
125 */
126 private double initialSy;
127
128 /**
129 * Initial z scaling factor.
130 */
131 private double initialSz;
132
133 /**
134 * Initial x-y cross coupling error.
135 */
136 private double initialMxy;
137
138 /**
139 * Initial x-z cross coupling error.
140 */
141 private double initialMxz;
142
143 /**
144 * Initial y-x cross coupling error.
145 */
146 private double initialMyx;
147
148 /**
149 * Initial y-z cross coupling error.
150 */
151 private double initialMyz;
152
153 /**
154 * Initial z-x cross coupling error.
155 */
156 private double initialMzx;
157
158 /**
159 * Initial z-y cross coupling error.
160 */
161 private double initialMzy;
162
163 /**
164 * Contains a collection of body kinematics measurements taken at different
165 * frames (positions, orientations and velocities) and containing the standard
166 * deviations of accelerometer and gyroscope measurements.
167 * If a single device IMU needs to be calibrated, typically all measurements are
168 * taken at the same position, with zero velocity and multiple orientations.
169 * However, if we just want to calibrate a given IMU model (e.g. obtain
170 * an average and less precise calibration for the IMU of a given phone model),
171 * we could take measurements collected throughout the planet at multiple positions
172 * while the phone remains static (e.g. while charging), hence each measurement
173 * position will change, velocity will remain zero and orientation will be
174 * typically constant at horizontal orientation while the phone remains on a
175 * flat surface.
176 */
177 private Collection<StandardDeviationFrameBodyKinematics> measurements;
178
179 /**
180 * This flag indicates whether z-axis is assumed to be common for accelerometer
181 * and gyroscope.
182 * When enabled, this eliminates 3 variables from Ma matrix.
183 */
184 private boolean commonAxisUsed = DEFAULT_USE_COMMON_Z_AXIS;
185
186 /**
187 * Listener to handle events raised by this calibrator.
188 */
189 private KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener;
190
191 /**
192 * Estimated accelerometer biases for each IMU axis expressed in meter per squared
193 * second (m/s^2).
194 */
195 private double[] estimatedBiases;
196
197 /**
198 * Estimated accelerometer scale factors and cross coupling errors.
199 * This is the product of matrix Ta containing cross coupling errors and Ka
200 * containing scaling factors.
201 * So tat:
202 * <pre>
203 * Ma = [sx mxy mxz] = Ta*Ka
204 * [myx sy myz]
205 * [mzx mzy sz ]
206 * </pre>
207 * Where:
208 * <pre>
209 * Ka = [sx 0 0 ]
210 * [0 sy 0 ]
211 * [0 0 sz]
212 * </pre>
213 * and
214 * <pre>
215 * Ta = [1 -alphaXy alphaXz ]
216 * [alphaYx 1 -alphaYz]
217 * [-alphaZx alphaZy 1 ]
218 * </pre>
219 * Hence:
220 * <pre>
221 * Ma = [sx mxy mxz] = Ta*Ka = [sx -sy * alphaXy sz * alphaXz ]
222 * [myx sy myz] [sx * alphaYx sy -sz * alphaYz]
223 * [mzx mzy sz ] [-sx * alphaZx sy * alphaZy sz ]
224 * </pre>
225 * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
226 * are considered to be zero if the accelerometer z-axis is assumed to be the same
227 * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Ma matrix
228 * becomes upper diagonal:
229 * <pre>
230 * Ma = [sx mxy mxz]
231 * [0 sy myz]
232 * [0 0 sz ]
233 * </pre>
234 * Values of this matrix are unit-less.
235 */
236 private Matrix estimatedMa;
237
238 /**
239 * Estimated covariance matrix for estimated parameters.
240 */
241 private Matrix estimatedCovariance;
242
243 /**
244 * Estimated chi square value.
245 */
246 private double estimatedChiSq;
247
248 /**
249 * Estimated degrees of freedom of chi square value. Degrees of freedom is equal to the number of sampled data
250 * minus the number of estimated parameters.
251 */
252 private int estimatedChiSqDegreesOfFreedom;
253
254 /**
255 * Estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
256 * freedom. Ideally this value should be close to 1.0.
257 */
258 private double estimatedReducedChiSq;
259
260 /**
261 * Estimated mean square error respect to provided measurements.
262 */
263 private double estimatedMse;
264
265 /**
266 * Estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The smaller
267 * the found chi square value is, the better the fit of the estimated parameters to the actual parameter. Thus, the
268 * smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
269 */
270 private double estimatedP;
271
272 /**
273 * Estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value is,
274 * the better the fit that has been estimated.
275 */
276 private double estimatedQ;
277
278 /**
279 * Indicates whether calibrator is running.
280 */
281 private boolean running;
282
283 /**
284 * Constructor.
285 */
286 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator() {
287 }
288
289 /**
290 * Constructor.
291 *
292 * @param listener listener to handle events raised by this calibrator.
293 */
294 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
295 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
296 this.listener = listener;
297 }
298
299 /**
300 * Constructor.
301 *
302 * @param measurements collection of body kinematics measurements with standard
303 * deviations taken at different frames (positions, orientations
304 * and velocities).
305 */
306 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
307 final Collection<StandardDeviationFrameBodyKinematics> measurements) {
308 this.measurements = measurements;
309 }
310
311 /**
312 * Constructor.
313 *
314 * @param measurements collection of body kinematics measurements with standard
315 * deviations taken at different frames (positions, orientations
316 * and velocities).
317 * @param listener listener to handle events raised by this calibrator.
318 */
319 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
320 final Collection<StandardDeviationFrameBodyKinematics> measurements,
321 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
322 this(measurements);
323 this.listener = listener;
324 }
325
326 /**
327 * Constructor.
328 *
329 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
330 * accelerometer and gyroscope.
331 */
332 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(final boolean commonAxisUsed) {
333 this.commonAxisUsed = commonAxisUsed;
334 }
335
336 /**
337 * Constructor.
338 *
339 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
340 * accelerometer and gyroscope.
341 * @param listener listener to handle events raised by this calibrator.
342 */
343 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
344 final boolean commonAxisUsed,
345 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
346 this(commonAxisUsed);
347 this.listener = listener;
348 }
349
350 /**
351 * Constructor.
352 *
353 * @param measurements collection of body kinematics measurements with standard
354 * deviations taken at different frames (positions, orientations
355 * and velocities).
356 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
357 * accelerometer and gyroscope.
358 */
359 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
360 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed) {
361 this(measurements);
362 this.commonAxisUsed = commonAxisUsed;
363 }
364
365 /**
366 * Constructor.
367 *
368 * @param measurements collection of body kinematics measurements with standard
369 * deviations taken at different frames (positions, orientations
370 * and velocities).
371 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
372 * accelerometer and gyroscope.
373 * @param listener listener to handle events raised by this calibrator.
374 */
375 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
376 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
377 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
378 this(measurements, commonAxisUsed);
379 this.listener = listener;
380 }
381
382 /**
383 * Constructor.
384 *
385 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
386 * to find a solution. This is expressed in meters per squared
387 * second (m/s^2).
388 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
389 * to find a solution. This is expressed in meters per squared
390 * second (m/s^2).
391 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
392 * to find a solution. This is expressed in meters per squared
393 * second (m/s^2).
394 */
395 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
396 final double initialBiasX, final double initialBiasY, final double initialBiasZ) {
397 try {
398 setInitialBias(initialBiasX, initialBiasY, initialBiasZ);
399 } catch (final LockedException ignore) {
400 // never happens
401 }
402 }
403
404 /**
405 * Constructor.
406 *
407 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
408 * to find a solution. This is expressed in meters per squared
409 * second (m/s^2).
410 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
411 * to find a solution. This is expressed in meters per squared
412 * second (m/s^2).
413 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
414 * to find a solution. This is expressed in meters per squared
415 * second (m/s^2).
416 * @param listener listener to handle events raised by this calibrator.
417 */
418 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
419 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
420 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
421 this(initialBiasX, initialBiasY, initialBiasZ);
422 this.listener = listener;
423 }
424
425 /**
426 * Constructor.
427 *
428 * @param measurements collection of body kinematics measurements with standard
429 * deviations taken at different frames (positions, orientations
430 * and velocities).
431 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
432 * to find a solution. This is expressed in meters per squared
433 * second (m/s^2).
434 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
435 * to find a solution. This is expressed in meters per squared
436 * second (m/s^2).
437 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
438 * to find a solution. This is expressed in meters per squared
439 * second (m/s^2).
440 */
441 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
442 final Collection<StandardDeviationFrameBodyKinematics> measurements,
443 final double initialBiasX, final double initialBiasY, final double initialBiasZ) {
444 this(initialBiasX, initialBiasY, initialBiasZ);
445 this.measurements = measurements;
446 }
447
448 /**
449 * Constructor.
450 *
451 * @param measurements collection of body kinematics measurements with standard
452 * deviations taken at different frames (positions, orientations
453 * and velocities).
454 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
455 * to find a solution. This is expressed in meters per squared
456 * second (m/s^2).
457 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
458 * to find a solution. This is expressed in meters per squared
459 * second (m/s^2).
460 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
461 * to find a solution. This is expressed in meters per squared
462 * second (m/s^2).
463 * @param listener listener to handle events raised by this calibrator.
464 */
465 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
466 final Collection<StandardDeviationFrameBodyKinematics> measurements,
467 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
468 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
469 this(measurements, initialBiasX, initialBiasY, initialBiasZ);
470 this.listener = listener;
471 }
472
473 /**
474 * Constructor.
475 *
476 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
477 * accelerometer and gyroscope.
478 * @param initialBiasX initial x-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 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
482 * to find a solution. This is expressed in meters per squared
483 * second (m/s^2).
484 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
485 * to find a solution. This is expressed in meters per squared
486 * second (m/s^2).
487 */
488 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
489 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
490 final double initialBiasZ) {
491 this(initialBiasX, initialBiasY, initialBiasZ);
492 this.commonAxisUsed = commonAxisUsed;
493 }
494
495 /**
496 * Constructor.
497 *
498 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
499 * accelerometer and gyroscope.
500 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
501 * to find a solution. This is expressed in meters per squared
502 * second (m/s^2).
503 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
504 * to find a solution. This is expressed in meters per squared
505 * second (m/s^2).
506 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
507 * to find a solution. This is expressed in meters per squared
508 * second (m/s^2).
509 * @param listener listener to handle events raised by this calibrator.
510 */
511 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
512 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
513 final double initialBiasZ, final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
514 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
515 this.listener = listener;
516 }
517
518 /**
519 * Constructor.
520 *
521 * @param measurements collection of body kinematics measurements with standard
522 * deviations taken at different frames (positions, orientations
523 * and velocities).
524 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
525 * accelerometer and gyroscope.
526 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
527 * to find a solution. This is expressed in meters per squared
528 * second (m/s^2).
529 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
530 * to find a solution. This is expressed in meters per squared
531 * second (m/s^2).
532 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
533 * to find a solution. This is expressed in meters per squared
534 * second (m/s^2).
535 */
536 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
537 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
538 final double initialBiasX, final double initialBiasY, final double initialBiasZ) {
539 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
540 this.measurements = measurements;
541 }
542
543 /**
544 * Constructor.
545 *
546 * @param measurements collection of body kinematics measurements with standard
547 * deviations taken at different frames (positions, orientations
548 * and velocities).
549 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
550 * accelerometer and gyroscope.
551 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
552 * to find a solution. This is expressed in meters per squared
553 * second (m/s^2).
554 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
555 * to find a solution. This is expressed in meters per squared
556 * second (m/s^2).
557 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
558 * to find a solution. This is expressed in meters per squared
559 * second (m/s^2).
560 * @param listener listener to handle events raised by this calibrator.
561 */
562 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
563 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
564 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
565 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
566 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
567 this.listener = listener;
568 }
569
570 /**
571 * Constructor.
572 *
573 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
574 * to find a solution.
575 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
576 * to find a solution.
577 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
578 * to find a solution.
579 */
580 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
581 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ) {
582 try {
583 setInitialBias(initialBiasX, initialBiasY, initialBiasZ);
584 } catch (final LockedException ignore) {
585 // never happens
586 }
587 }
588
589 /**
590 * Constructor.
591 *
592 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
593 * to find a solution.
594 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
595 * to find a solution.
596 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
597 * to find a solution.
598 * @param listener listener to handle events raised by this calibrator.
599 */
600 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
601 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
602 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
603 this(initialBiasX, initialBiasY, initialBiasZ);
604 this.listener = listener;
605 }
606
607 /**
608 * Constructor.
609 *
610 * @param measurements collection of body kinematics measurements with standard
611 * deviations taken at different frames (positions, orientations
612 * and velocities).
613 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
614 * to find a solution.
615 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
616 * to find a solution.
617 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
618 * to find a solution.
619 */
620 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
621 final Collection<StandardDeviationFrameBodyKinematics> measurements,
622 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ) {
623 this(initialBiasX, initialBiasY, initialBiasZ);
624 this.measurements = measurements;
625 }
626
627 /**
628 * Constructor.
629 *
630 * @param measurements collection of body kinematics measurements with standard
631 * deviations taken at different frames (positions, orientations
632 * and velocities).
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 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
642 final Collection<StandardDeviationFrameBodyKinematics> measurements,
643 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
644 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
645 this(measurements, initialBiasX, initialBiasY, initialBiasZ);
646 this.listener = listener;
647 }
648
649 /**
650 * Constructor.
651 *
652 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
653 * accelerometer and gyroscope.
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 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
662 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
663 final Acceleration initialBiasZ) {
664 this(initialBiasX, initialBiasY, initialBiasZ);
665 this.commonAxisUsed = commonAxisUsed;
666 }
667
668 /**
669 * Constructor.
670 *
671 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
672 * accelerometer and gyroscope.
673 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
674 * to find a solution.
675 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
676 * to find a solution.
677 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
678 * to find a solution.
679 * @param listener listener to handle events raised by this calibrator.
680 */
681 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
682 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
683 final Acceleration initialBiasZ,
684 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
685 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
686 this.listener = listener;
687 }
688
689 /**
690 * Constructor.
691 *
692 * @param measurements collection of body kinematics measurements with standard
693 * deviations taken at different frames (positions, orientations
694 * and velocities).
695 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
696 * accelerometer and gyroscope.
697 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
698 * to find a solution.
699 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
700 * to find a solution.
701 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
702 * to find a solution.
703 */
704 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
705 final Collection<StandardDeviationFrameBodyKinematics> measurements,
706 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
707 final Acceleration initialBiasZ) {
708 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
709 this.measurements = measurements;
710 }
711
712 /**
713 * Constructor.
714 *
715 * @param measurements collection of body kinematics measurements with standard
716 * deviations taken at different frames (positions, orientations
717 * and velocities).
718 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
719 * accelerometer and gyroscope.
720 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
721 * to find a solution.
722 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
723 * to find a solution.
724 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
725 * to find a solution.
726 * @param listener listener to handle events raised by this calibrator.
727 */
728 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
729 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
730 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
731 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
732 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ);
733 this.listener = listener;
734 }
735
736 /**
737 * Constructor.
738 *
739 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
740 * to find a solution. This is expressed in meters per squared
741 * second (m/s^2).
742 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
743 * to find a solution. This is expressed in meters per squared
744 * second (m/s^2).
745 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
746 * to find a solution. This is expressed in meters per squared
747 * second (m/s^2).
748 * @param initialSx initial x scaling factor.
749 * @param initialSy initial y scaling factor.
750 * @param initialSz initial z scaling factor.
751 */
752 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
753 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
754 final double initialSx, final double initialSy, final double initialSz) {
755 this(initialBiasX, initialBiasY, initialBiasZ);
756 try {
757 setInitialScalingFactors(initialSx, initialSy, initialSz);
758 } catch (final LockedException ignore) {
759 // never happens
760 }
761 }
762
763 /**
764 * Constructor.
765 *
766 * @param measurements collection of body kinematics measurements with standard
767 * deviations taken at different frames (positions, orientations
768 * and velocities).
769 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
770 * to find a solution. This is expressed in meters per squared
771 * second (m/s^2).
772 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
773 * to find a solution. This is expressed in meters per squared
774 * second (m/s^2).
775 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
776 * to find a solution. This is expressed in meters per squared
777 * second (m/s^2).
778 * @param initialSx initial x scaling factor.
779 * @param initialSy initial y scaling factor.
780 * @param initialSz initial z scaling factor.
781 */
782 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
783 final Collection<StandardDeviationFrameBodyKinematics> measurements,
784 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
785 final double initialSx, final double initialSy, final double initialSz) {
786 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
787 this.measurements = measurements;
788 }
789
790 /**
791 * Constructor.
792 *
793 * @param measurements collection of body kinematics measurements with standard
794 * deviations taken at different frames (positions, orientations
795 * and velocities).
796 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
797 * to find a solution. This is expressed in meters per squared
798 * second (m/s^2).
799 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
800 * to find a solution. This is expressed in meters per squared
801 * second (m/s^2).
802 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
803 * to find a solution. This is expressed in meters per squared
804 * second (m/s^2).
805 * @param initialSx initial x scaling factor.
806 * @param initialSy initial y scaling factor.
807 * @param initialSz initial z scaling factor.
808 * @param listener listener to handle events raised by this calibrator.
809 */
810 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
811 final Collection<StandardDeviationFrameBodyKinematics> measurements,
812 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
813 final double initialSx, final double initialSy, final double initialSz,
814 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
815 this(measurements, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
816 this.listener = listener;
817 }
818
819 /**
820 * Constructor.
821 *
822 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
823 * accelerometer and gyroscope.
824 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
825 * to find a solution. This is expressed in meters per squared
826 * second (m/s^2).
827 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
828 * to find a solution. This is expressed in meters per squared
829 * second (m/s^2).
830 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
831 * to find a solution. This is expressed in meters per squared
832 * second (m/s^2).
833 * @param initialSx initial x scaling factor.
834 * @param initialSy initial y scaling factor.
835 * @param initialSz initial z scaling factor.
836 */
837 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
838 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
839 final double initialBiasZ, final double initialSx, final double initialSy, final double initialSz) {
840 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
841 this.commonAxisUsed = commonAxisUsed;
842 }
843
844 /**
845 * Constructor.
846 *
847 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
848 * accelerometer and gyroscope.
849 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
850 * to find a solution. This is expressed in meters per squared
851 * second (m/s^2).
852 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
853 * to find a solution. This is expressed in meters per squared
854 * second (m/s^2).
855 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
856 * to find a solution. This is expressed in meters per squared
857 * second (m/s^2).
858 * @param initialSx initial x scaling factor.
859 * @param initialSy initial y scaling factor.
860 * @param initialSz initial z scaling factor.
861 * @param listener listener to handle events raised by this calibrator.
862 */
863 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
864 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
865 final double initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
866 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
867 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
868 this.listener = listener;
869 }
870
871 /**
872 * Constructor.
873 *
874 * @param measurements collection of body kinematics measurements with standard
875 * deviations taken at different frames (positions, orientations
876 * and velocities).
877 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
878 * accelerometer and gyroscope.
879 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
880 * to find a solution. This is expressed in meters per squared
881 * second (m/s^2).
882 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
883 * to find a solution. This is expressed in meters per squared
884 * second (m/s^2).
885 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
886 * to find a solution. This is expressed in meters per squared
887 * second (m/s^2).
888 * @param initialSx initial x scaling factor.
889 * @param initialSy initial y scaling factor.
890 * @param initialSz initial z scaling factor.
891 */
892 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
893 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
894 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
895 final double initialSx, final double initialSy, final double initialSz) {
896 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
897 this.measurements = measurements;
898 }
899
900 /**
901 * Constructor.
902 *
903 * @param measurements collection of body kinematics measurements with standard
904 * deviations taken at different frames (positions, orientations
905 * and velocities).
906 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
907 * accelerometer and gyroscope.
908 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
909 * to find a solution. This is expressed in meters per squared
910 * second (m/s^2).
911 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
912 * to find a solution. This is expressed in meters per squared
913 * second (m/s^2).
914 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
915 * to find a solution. This is expressed in meters per squared
916 * second (m/s^2).
917 * @param initialSx initial x scaling factor.
918 * @param initialSy initial y scaling factor.
919 * @param initialSz initial z scaling factor.
920 * @param listener listener to handle events raised by this calibrator.
921 */
922 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
923 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
924 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
925 final double initialSx, final double initialSy, final double initialSz,
926 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
927 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
928 this.listener = listener;
929 }
930
931 /**
932 * Constructor.
933 *
934 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
935 * to find a solution.
936 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
937 * to find a solution.
938 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
939 * to find a solution.
940 * @param initialSx initial x scaling factor.
941 * @param initialSy initial y scaling factor.
942 * @param initialSz initial z scaling factor.
943 */
944 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
945 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
946 final double initialSx, final double initialSy, final double initialSz) {
947 this(initialBiasX, initialBiasY, initialBiasZ);
948 try {
949 setInitialScalingFactors(initialSx, initialSy, initialSz);
950 } catch (final LockedException ignore) {
951 // never happens
952 }
953 }
954
955 /**
956 * Constructor.
957 *
958 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
959 * to find a solution.
960 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
961 * to find a solution.
962 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
963 * to find a solution.
964 * @param initialSx initial x scaling factor.
965 * @param initialSy initial y scaling factor.
966 * @param initialSz initial z scaling factor.
967 * @param listener listener to handle events raised by this calibrator.
968 */
969 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
970 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
971 final double initialSx, final double initialSy, final double initialSz,
972 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
973 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
974 this.listener = listener;
975 }
976
977 /**
978 * Constructor.
979 *
980 * @param measurements collection of body kinematics measurements with standard
981 * deviations taken at different frames (positions, orientations
982 * and velocities).
983 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
984 * to find a solution.
985 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
986 * to find a solution.
987 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
988 * to find a solution.
989 * @param initialSx initial x scaling factor.
990 * @param initialSy initial y scaling factor.
991 * @param initialSz initial z scaling factor.
992 */
993 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
994 final Collection<StandardDeviationFrameBodyKinematics> measurements,
995 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
996 final double initialSx, final double initialSy, final double initialSz) {
997 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
998 this.measurements = measurements;
999 }
1000
1001 /**
1002 * Constructor.
1003 *
1004 * @param measurements collection of body kinematics measurements with standard
1005 * deviations taken at different frames (positions, orientations
1006 * and velocities).
1007 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1008 * to find a solution.
1009 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1010 * to find a solution.
1011 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1012 * to find a solution.
1013 * @param initialSx initial x scaling factor.
1014 * @param initialSy initial y scaling factor.
1015 * @param initialSz initial z scaling factor.
1016 * @param listener listener to handle events raised by this calibrator.
1017 */
1018 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1019 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1020 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1021 final double initialSx, final double initialSy, final double initialSz,
1022 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1023 this(measurements, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
1024 this.listener = listener;
1025 }
1026
1027 /**
1028 * Constructor.
1029 *
1030 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1031 * accelerometer and gyroscope.
1032 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1033 * to find a solution.
1034 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1035 * to find a solution.
1036 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1037 * to find a solution.
1038 * @param initialSx initial x scaling factor.
1039 * @param initialSy initial y scaling factor.
1040 * @param initialSz initial z scaling factor.
1041 */
1042 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1043 final boolean commonAxisUsed, final Acceleration initialBiasX,
1044 final Acceleration initialBiasY, final Acceleration initialBiasZ,
1045 final double initialSx, final double initialSy, final double initialSz) {
1046 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
1047 this.commonAxisUsed = commonAxisUsed;
1048 }
1049
1050 /**
1051 * Constructor.
1052 *
1053 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1054 * accelerometer and gyroscope.
1055 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1056 * to find a solution.
1057 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1058 * to find a solution.
1059 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1060 * to find a solution.
1061 * @param initialSx initial x scaling factor.
1062 * @param initialSy initial y scaling factor.
1063 * @param initialSz initial z scaling factor.
1064 * @param listener listener to handle events raised by this calibrator.
1065 */
1066 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1067 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
1068 final Acceleration initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
1069 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1070 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
1071 this.listener = listener;
1072 }
1073
1074 /**
1075 * Constructor.
1076 *
1077 * @param measurements collection of body kinematics measurements with standard
1078 * deviations taken at different frames (positions, orientations
1079 * and velocities).
1080 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1081 * accelerometer and gyroscope.
1082 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1083 * to find a solution.
1084 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1085 * to find a solution.
1086 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1087 * to find a solution.
1088 * @param initialSx initial x scaling factor.
1089 * @param initialSy initial y scaling factor.
1090 * @param initialSz initial z scaling factor.
1091 */
1092 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1093 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1094 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
1095 final Acceleration initialBiasZ, final double initialSx, final double initialSy, final double initialSz) {
1096 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
1097 this.measurements = measurements;
1098 }
1099
1100 /**
1101 * Constructor.
1102 *
1103 * @param measurements collection of body kinematics measurements with standard
1104 * deviations taken at different frames (positions, orientations
1105 * and velocities).
1106 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1107 * accelerometer and gyroscope.
1108 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1109 * to find a solution.
1110 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1111 * to find a solution.
1112 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1113 * to find a solution.
1114 * @param initialSx initial x scaling factor.
1115 * @param initialSy initial y scaling factor.
1116 * @param initialSz initial z scaling factor.
1117 * @param listener listener to handle events raised by this calibrator.
1118 */
1119 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1120 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1121 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1122 final double initialSx, final double initialSy, final double initialSz,
1123 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1124 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz);
1125 this.listener = listener;
1126 }
1127
1128 /**
1129 * Constructor.
1130 *
1131 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1132 * to find a solution. This is expressed in meters per squared
1133 * second (m/s^2).
1134 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1135 * to find a solution. This is expressed in meters per squared
1136 * second (m/s^2).
1137 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1138 * to find a solution. This is expressed in meters per squared
1139 * second (m/s^2).
1140 * @param initialSx initial x scaling factor.
1141 * @param initialSy initial y scaling factor.
1142 * @param initialSz initial z scaling factor.
1143 * @param initialMxy initial x-y cross coupling error.
1144 * @param initialMxz initial x-z cross coupling error.
1145 * @param initialMyx initial y-x cross coupling error.
1146 * @param initialMyz initial y-z cross coupling error.
1147 * @param initialMzx initial z-x cross coupling error.
1148 * @param initialMzy initial z-y cross coupling error.
1149 */
1150 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1151 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
1152 final double initialSx, final double initialSy, final double initialSz,
1153 final double initialMxy, final double initialMxz, final double initialMyx,
1154 final double initialMyz, final double initialMzx, final double initialMzy) {
1155 this(initialBiasX, initialBiasY, initialBiasZ);
1156 try {
1157 setInitialScalingFactorsAndCrossCouplingErrors(initialSx, initialSy, initialSz,
1158 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1159 } catch (final LockedException ignore) {
1160 // never happens
1161 }
1162 }
1163
1164 /**
1165 * Constructor.
1166 *
1167 * @param measurements collection of body kinematics measurements with standard
1168 * deviations taken at different frames (positions, orientations
1169 * and velocities).
1170 * @param initialBiasX initial x-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 initialBiasY initial y-coordinate of accelerometer bias to be used
1174 * to find a solution. This is expressed in meters per squared
1175 * second (m/s^2).
1176 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1177 * to find a solution. This is expressed in meters per squared
1178 * second (m/s^2).
1179 * @param initialSx initial x scaling factor.
1180 * @param initialSy initial y scaling factor.
1181 * @param initialSz initial z scaling factor.
1182 * @param initialMxy initial x-y cross coupling error.
1183 * @param initialMxz initial x-z cross coupling error.
1184 * @param initialMyx initial y-x cross coupling error.
1185 * @param initialMyz initial y-z cross coupling error.
1186 * @param initialMzx initial z-x cross coupling error.
1187 * @param initialMzy initial z-y cross coupling error.
1188 */
1189 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1190 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1191 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
1192 final double initialSx, final double initialSy, final double initialSz,
1193 final double initialMxy, final double initialMxz, final double initialMyx,
1194 final double initialMyz, final double initialMzx, final double initialMzy) {
1195 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1196 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1197 this.measurements = measurements;
1198 }
1199
1200 /**
1201 * Constructor.
1202 *
1203 * @param measurements collection of body kinematics measurements with standard
1204 * deviations taken at different frames (positions, orientations
1205 * and velocities).
1206 * @param initialBiasX initial x-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 initialBiasY initial y-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 initialBiasZ initial z-coordinate of accelerometer bias to be used
1213 * to find a solution. This is expressed in meters per squared
1214 * second (m/s^2).
1215 * @param initialSx initial x scaling factor.
1216 * @param initialSy initial y scaling factor.
1217 * @param initialSz initial z scaling factor.
1218 * @param initialMxy initial x-y cross coupling error.
1219 * @param initialMxz initial x-z cross coupling error.
1220 * @param initialMyx initial y-x cross coupling error.
1221 * @param initialMyz initial y-z cross coupling error.
1222 * @param initialMzx initial z-x cross coupling error.
1223 * @param initialMzy initial z-y cross coupling error.
1224 * @param listener listener to handle events raised by this calibrator.
1225 */
1226 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1227 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1228 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
1229 final double initialSx, final double initialSy, final double initialSz,
1230 final double initialMxy, final double initialMxz, final double initialMyx,
1231 final double initialMyz, final double initialMzx, final double initialMzy,
1232 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1233 this(measurements, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1234 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1235 this.listener = listener;
1236 }
1237
1238 /**
1239 * Constructor.
1240 *
1241 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1242 * accelerometer and gyroscope.
1243 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1244 * to find a solution. This is expressed in meters per squared
1245 * second (m/s^2).
1246 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1247 * to find a solution. This is expressed in meters per squared
1248 * second (m/s^2).
1249 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1250 * to find a solution. This is expressed in meters per squared
1251 * second (m/s^2).
1252 * @param initialSx initial x scaling factor.
1253 * @param initialSy initial y scaling factor.
1254 * @param initialSz initial z scaling factor.
1255 * @param initialMxy initial x-y cross coupling error.
1256 * @param initialMxz initial x-z cross coupling error.
1257 * @param initialMyx initial y-x cross coupling error.
1258 * @param initialMyz initial y-z cross coupling error.
1259 * @param initialMzx initial z-x cross coupling error.
1260 * @param initialMzy initial z-y cross coupling error.
1261 */
1262 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1263 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
1264 final double initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
1265 final double initialMxy, final double initialMxz, final double initialMyx,
1266 final double initialMyz, final double initialMzx, final double initialMzy) {
1267 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1268 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1269 this.commonAxisUsed = commonAxisUsed;
1270 }
1271
1272 /**
1273 * Constructor.
1274 *
1275 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1276 * accelerometer and gyroscope.
1277 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1278 * to find a solution. This is expressed in meters per squared
1279 * second (m/s^2).
1280 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1281 * to find a solution. This is expressed in meters per squared
1282 * second (m/s^2).
1283 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1284 * to find a solution. This is expressed in meters per squared
1285 * second (m/s^2).
1286 * @param initialSx initial x scaling factor.
1287 * @param initialSy initial y scaling factor.
1288 * @param initialSz initial z scaling factor.
1289 * @param initialMxy initial x-y cross coupling error.
1290 * @param initialMxz initial x-z cross coupling error.
1291 * @param initialMyx initial y-x cross coupling error.
1292 * @param initialMyz initial y-z cross coupling error.
1293 * @param initialMzx initial z-x cross coupling error.
1294 * @param initialMzy initial z-y cross coupling error.
1295 * @param listener listener to handle events raised by this calibrator.
1296 */
1297 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1298 final boolean commonAxisUsed, final double initialBiasX, final double initialBiasY,
1299 final double initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
1300 final double initialMxy, final double initialMxz, final double initialMyx,
1301 final double initialMyz, final double initialMzx, final double initialMzy,
1302 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1303 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1304 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1305 this.listener = listener;
1306 }
1307
1308 /**
1309 * Constructor.
1310 *
1311 * @param measurements collection of body kinematics measurements with standard
1312 * deviations taken at different frames (positions, orientations
1313 * and velocities).
1314 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1315 * accelerometer and gyroscope.
1316 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1317 * to find a solution. This is expressed in meters per squared
1318 * second (m/s^2).
1319 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1320 * to find a solution. This is expressed in meters per squared
1321 * second (m/s^2).
1322 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1323 * to find a solution. This is expressed in meters per squared
1324 * second (m/s^2).
1325 * @param initialSx initial x scaling factor.
1326 * @param initialSy initial y scaling factor.
1327 * @param initialSz initial z scaling factor.
1328 * @param initialMxy initial x-y cross coupling error.
1329 * @param initialMxz initial x-z cross coupling error.
1330 * @param initialMyx initial y-x cross coupling error.
1331 * @param initialMyz initial y-z cross coupling error.
1332 * @param initialMzx initial z-x cross coupling error.
1333 * @param initialMzy initial z-y cross coupling error.
1334 */
1335 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1336 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1337 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
1338 final double initialSx, final double initialSy, final double initialSz,
1339 final double initialMxy, final double initialMxz, final double initialMyx,
1340 final double initialMyz, final double initialMzx, final double initialMzy) {
1341 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1342 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1343 this.measurements = measurements;
1344 }
1345
1346 /**
1347 * Constructor.
1348 *
1349 * @param measurements collection of body kinematics measurements with standard
1350 * deviations taken at different frames (positions, orientations
1351 * and velocities).
1352 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1353 * accelerometer and gyroscope.
1354 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1355 * to find a solution. This is expressed in meters per squared
1356 * second (m/s^2).
1357 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1358 * to find a solution. This is expressed in meters per squared
1359 * second (m/s^2).
1360 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1361 * to find a solution. This is expressed in meters per squared
1362 * second (m/s^2).
1363 * @param initialSx initial x scaling factor.
1364 * @param initialSy initial y scaling factor.
1365 * @param initialSz initial z scaling factor.
1366 * @param initialMxy initial x-y cross coupling error.
1367 * @param initialMxz initial x-z cross coupling error.
1368 * @param initialMyx initial y-x cross coupling error.
1369 * @param initialMyz initial y-z cross coupling error.
1370 * @param initialMzx initial z-x cross coupling error.
1371 * @param initialMzy initial z-y cross coupling error.
1372 * @param listener listener to handle events raised by this calibrator.
1373 */
1374 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1375 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1376 final double initialBiasX, final double initialBiasY, final double initialBiasZ,
1377 final double initialSx, final double initialSy, final double initialSz,
1378 final double initialMxy, final double initialMxz, final double initialMyx,
1379 final double initialMyz, final double initialMzx, final double initialMzy,
1380 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1381 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1382 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1383 this.listener = listener;
1384 }
1385
1386 /**
1387 * Constructor.
1388 *
1389 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1390 * to find a solution.
1391 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1392 * to find a solution.
1393 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1394 * to find a solution.
1395 * @param initialSx initial x scaling factor.
1396 * @param initialSy initial y scaling factor.
1397 * @param initialSz initial z scaling factor.
1398 * @param initialMxy initial x-y cross coupling error.
1399 * @param initialMxz initial x-z cross coupling error.
1400 * @param initialMyx initial y-x cross coupling error.
1401 * @param initialMyz initial y-z cross coupling error.
1402 * @param initialMzx initial z-x cross coupling error.
1403 * @param initialMzy initial z-y cross coupling error.
1404 */
1405 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1406 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1407 final double initialSx, final double initialSy, final double initialSz,
1408 final double initialMxy, final double initialMxz, final double initialMyx,
1409 final double initialMyz, final double initialMzx, final double initialMzy) {
1410 this(initialBiasX, initialBiasY, initialBiasZ);
1411 try {
1412 setInitialScalingFactorsAndCrossCouplingErrors(initialSx, initialSy, initialSz,
1413 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1414 } catch (final LockedException ignore) {
1415 // never happens
1416 }
1417 }
1418
1419 /**
1420 * Constructor.
1421 *
1422 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1423 * to find a solution.
1424 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1425 * to find a solution.
1426 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1427 * to find a solution.
1428 * @param initialSx initial x scaling factor.
1429 * @param initialSy initial y scaling factor.
1430 * @param initialSz initial z scaling factor.
1431 * @param initialMxy initial x-y cross coupling error.
1432 * @param initialMxz initial x-z cross coupling error.
1433 * @param initialMyx initial y-x cross coupling error.
1434 * @param initialMyz initial y-z cross coupling error.
1435 * @param initialMzx initial z-x cross coupling error.
1436 * @param initialMzy initial z-y cross coupling error.
1437 * @param listener listener to handle events raised by this calibrator.
1438 */
1439 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1440 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1441 final double initialSx, final double initialSy, final double initialSz,
1442 final double initialMxy, final double initialMxz, final double initialMyx,
1443 final double initialMyz, final double initialMzx, final double initialMzy,
1444 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1445 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1446 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1447 this.listener = listener;
1448 }
1449
1450 /**
1451 * Constructor.
1452 *
1453 * @param measurements collection of body kinematics measurements with standard
1454 * deviations taken at different frames (positions, orientations
1455 * and velocities).
1456 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1457 * to find a solution.
1458 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1459 * to find a solution.
1460 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1461 * to find a solution.
1462 * @param initialSx initial x scaling factor.
1463 * @param initialSy initial y scaling factor.
1464 * @param initialSz initial z scaling factor.
1465 * @param initialMxy initial x-y cross coupling error.
1466 * @param initialMxz initial x-z cross coupling error.
1467 * @param initialMyx initial y-x cross coupling error.
1468 * @param initialMyz initial y-z cross coupling error.
1469 * @param initialMzx initial z-x cross coupling error.
1470 * @param initialMzy initial z-y cross coupling error.
1471 */
1472 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1473 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1474 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1475 final double initialSx, final double initialSy, final double initialSz,
1476 final double initialMxy, final double initialMxz, final double initialMyx,
1477 final double initialMyz, final double initialMzx, final double initialMzy) {
1478 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1479 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1480 this.measurements = measurements;
1481 }
1482
1483 /**
1484 * Constructor.
1485 *
1486 * @param measurements collection of body kinematics measurements with standard
1487 * deviations taken at different frames (positions, orientations
1488 * and velocities).
1489 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1490 * to find a solution.
1491 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1492 * to find a solution.
1493 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1494 * to find a solution.
1495 * @param initialSx initial x scaling factor.
1496 * @param initialSy initial y scaling factor.
1497 * @param initialSz initial z scaling factor.
1498 * @param initialMxy initial x-y cross coupling error.
1499 * @param initialMxz initial x-z cross coupling error.
1500 * @param initialMyx initial y-x cross coupling error.
1501 * @param initialMyz initial y-z cross coupling error.
1502 * @param initialMzx initial z-x cross coupling error.
1503 * @param initialMzy initial z-y cross coupling error.
1504 * @param listener listener to handle events raised by this calibrator.
1505 */
1506 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1507 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1508 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1509 final double initialSx, final double initialSy, final double initialSz,
1510 final double initialMxy, final double initialMxz, final double initialMyx,
1511 final double initialMyz, final double initialMzx, final double initialMzy,
1512 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1513 this(measurements, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1514 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1515 this.listener = listener;
1516 }
1517
1518 /**
1519 * Constructor.
1520 *
1521 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1522 * accelerometer and gyroscope.
1523 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1524 * to find a solution.
1525 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1526 * to find a solution.
1527 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1528 * to find a solution.
1529 * @param initialSx initial x scaling factor.
1530 * @param initialSy initial y scaling factor.
1531 * @param initialSz initial z scaling factor.
1532 * @param initialMxy initial x-y cross coupling error.
1533 * @param initialMxz initial x-z cross coupling error.
1534 * @param initialMyx initial y-x cross coupling error.
1535 * @param initialMyz initial y-z cross coupling error.
1536 * @param initialMzx initial z-x cross coupling error.
1537 * @param initialMzy initial z-y cross coupling error.
1538 */
1539 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1540 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
1541 final Acceleration initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
1542 final double initialMxy, final double initialMxz, final double initialMyx,
1543 final double initialMyz, final double initialMzx, final double initialMzy) {
1544 this(initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1545 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1546 this.commonAxisUsed = commonAxisUsed;
1547 }
1548
1549 /**
1550 * Constructor.
1551 *
1552 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1553 * accelerometer and gyroscope.
1554 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1555 * to find a solution.
1556 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1557 * to find a solution.
1558 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1559 * to find a solution.
1560 * @param initialSx initial x scaling factor.
1561 * @param initialSy initial y scaling factor.
1562 * @param initialSz initial z scaling factor.
1563 * @param initialMxy initial x-y cross coupling error.
1564 * @param initialMxz initial x-z cross coupling error.
1565 * @param initialMyx initial y-x cross coupling error.
1566 * @param initialMyz initial y-z cross coupling error.
1567 * @param initialMzx initial z-x cross coupling error.
1568 * @param initialMzy initial z-y cross coupling error.
1569 * @param listener listener to handle events raised by this calibrator.
1570 */
1571 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1572 final boolean commonAxisUsed, final Acceleration initialBiasX, final Acceleration initialBiasY,
1573 final Acceleration initialBiasZ, final double initialSx, final double initialSy, final double initialSz,
1574 final double initialMxy, final double initialMxz, final double initialMyx,
1575 final double initialMyz, final double initialMzx, final double initialMzy,
1576 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1577 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1578 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1579 this.listener = listener;
1580 }
1581
1582 /**
1583 * Constructor.
1584 *
1585 * @param measurements collection of body kinematics measurements with standard
1586 * deviations taken at different frames (positions, orientations
1587 * and velocities).
1588 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1589 * accelerometer and gyroscope.
1590 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1591 * to find a solution.
1592 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1593 * to find a solution.
1594 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1595 * to find a solution.
1596 * @param initialSx initial x scaling factor.
1597 * @param initialSy initial y scaling factor.
1598 * @param initialSz initial z scaling factor.
1599 * @param initialMxy initial x-y cross coupling error.
1600 * @param initialMxz initial x-z cross coupling error.
1601 * @param initialMyx initial y-x cross coupling error.
1602 * @param initialMyz initial y-z cross coupling error.
1603 * @param initialMzx initial z-x cross coupling error.
1604 * @param initialMzy initial z-y cross coupling error.
1605 */
1606 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1607 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1608 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1609 final double initialSx, final double initialSy, final double initialSz,
1610 final double initialMxy, final double initialMxz, final double initialMyx,
1611 final double initialMyz, final double initialMzx, final double initialMzy) {
1612 this(commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1613 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1614 this.measurements = measurements;
1615 }
1616
1617 /**
1618 * Constructor.
1619 *
1620 * @param measurements collection of body kinematics measurements with standard
1621 * deviations taken at different frames (positions, orientations
1622 * and velocities).
1623 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1624 * accelerometer and gyroscope.
1625 * @param initialBiasX initial x-coordinate of accelerometer bias to be used
1626 * to find a solution.
1627 * @param initialBiasY initial y-coordinate of accelerometer bias to be used
1628 * to find a solution.
1629 * @param initialBiasZ initial z-coordinate of accelerometer bias to be used
1630 * to find a solution.
1631 * @param initialSx initial x scaling factor.
1632 * @param initialSy initial y scaling factor.
1633 * @param initialSz initial z scaling factor.
1634 * @param initialMxy initial x-y cross coupling error.
1635 * @param initialMxz initial x-z cross coupling error.
1636 * @param initialMyx initial y-x cross coupling error.
1637 * @param initialMyz initial y-z cross coupling error.
1638 * @param initialMzx initial z-x cross coupling error.
1639 * @param initialMzy initial z-y cross coupling error.
1640 * @param listener listener to handle events raised by this calibrator.
1641 */
1642 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1643 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1644 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ,
1645 final double initialSx, final double initialSy, final double initialSz,
1646 final double initialMxy, final double initialMxz, final double initialMyx,
1647 final double initialMyz, final double initialMzx, final double initialMzy,
1648 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1649 this(measurements, commonAxisUsed, initialBiasX, initialBiasY, initialBiasZ, initialSx, initialSy, initialSz,
1650 initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
1651 this.listener = listener;
1652 }
1653
1654 /**
1655 * Constructor.
1656 *
1657 * @param initialBias initial accelerometer bias to be used to find a solution.
1658 * This must have length 3 and is expressed in meters per
1659 * squared second (m/s^2).
1660 * @throws IllegalArgumentException if provided bias array does not have length 3.
1661 */
1662 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(final double[] initialBias) {
1663 try {
1664 setInitialBias(initialBias);
1665 } catch (final LockedException ignore) {
1666 // never happens
1667 }
1668 }
1669
1670 /**
1671 * Constructor.
1672 *
1673 * @param initialBias initial accelerometer bias to be used to find a solution.
1674 * This must have length 3 and is expressed in meters per
1675 * squared second (m/s^2).
1676 * @param listener listener to handle events raised by this calibrator.
1677 * @throws IllegalArgumentException if provided bias array does not have length 3.
1678 */
1679 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1680 final double[] initialBias, final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1681 this(initialBias);
1682 this.listener = listener;
1683 }
1684
1685 /**
1686 * Constructor.
1687 *
1688 * @param measurements collection of body kinematics measurements with standard
1689 * deviations taken at different frames (positions, orientations
1690 * and velocities).
1691 * @param initialBias initial accelerometer bias to be used to find a solution.
1692 * This must have length 3 and is expressed in meters per
1693 * squared second (m/s^2).
1694 * @throws IllegalArgumentException if provided bias array does not have length 3.
1695 */
1696 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1697 final Collection<StandardDeviationFrameBodyKinematics> measurements, final double[] initialBias) {
1698 this(initialBias);
1699 this.measurements = measurements;
1700 }
1701
1702 /**
1703 * Constructor.
1704 *
1705 * @param measurements collection of body kinematics measurements with standard
1706 * deviations taken at different frames (positions, orientations
1707 * and velocities).
1708 * @param initialBias initial accelerometer bias to be used to find a solution.
1709 * This must have length 3 and is expressed in meters per
1710 * squared second (m/s^2).
1711 * @param listener listener to handle events raised by this calibrator.
1712 * @throws IllegalArgumentException if provided bias array does not have length 3.
1713 */
1714 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1715 final Collection<StandardDeviationFrameBodyKinematics> measurements, final double[] initialBias,
1716 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1717 this(measurements, initialBias);
1718 this.listener = listener;
1719 }
1720
1721 /**
1722 * Constructor
1723 *
1724 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1725 * accelerometer and gyroscope.
1726 * @param initialBias initial accelerometer bias to be used to find a solution.
1727 * This must have length 3 and is expressed in meters per
1728 * squared second (m/s^2).
1729 * @throws IllegalArgumentException if provided bias array does not have length 3.
1730 */
1731 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1732 final boolean commonAxisUsed, final double[] initialBias) {
1733 this(initialBias);
1734 this.commonAxisUsed = commonAxisUsed;
1735 }
1736
1737 /**
1738 * Constructor.
1739 *
1740 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1741 * accelerometer and gyroscope.
1742 * @param initialBias initial accelerometer bias to be used to find a solution.
1743 * This must have length 3 and is expressed in meters per
1744 * squared second (m/s^2).
1745 * @param listener listener to handle events raised by this calibrator.
1746 * @throws IllegalArgumentException if provided bias array does not have length 3.
1747 */
1748 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1749 final boolean commonAxisUsed, final double[] initialBias,
1750 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1751 this(commonAxisUsed, initialBias);
1752 this.listener = listener;
1753 }
1754
1755 /**
1756 * Constructor.
1757 *
1758 * @param measurements collection of body kinematics measurements with standard
1759 * deviations taken at different frames (positions, orientations
1760 * and velocities).
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 * @throws IllegalArgumentException if provided bias array does not have length 3.
1767 */
1768 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1769 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1770 final boolean commonAxisUsed, final double[] initialBias) {
1771 this(commonAxisUsed, initialBias);
1772 this.measurements = measurements;
1773 }
1774
1775 /**
1776 * Constructor.
1777 *
1778 * @param measurements collection of body kinematics measurements with standard
1779 * deviations taken at different frames (positions, orientations
1780 * and velocities).
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 * @param listener listener to handle events raised by this calibrator.
1787 * @throws IllegalArgumentException if provided bias array does not have length 3.
1788 */
1789 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1790 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1791 final double[] initialBias, final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1792 this(measurements, commonAxisUsed, initialBias);
1793 this.listener = listener;
1794 }
1795
1796 /**
1797 * Constructor.
1798 *
1799 * @param initialBias initial bias to find a solution.
1800 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1801 */
1802 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(final Matrix initialBias) {
1803 try {
1804 setInitialBias(initialBias);
1805 } catch (final LockedException ignore) {
1806 // never happens
1807 }
1808 }
1809
1810 /**
1811 * Constructor.
1812 *
1813 * @param initialBias initial bias to find a solution.
1814 * @param listener listener to handle events raised by this calibrator.
1815 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1816 */
1817 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1818 final Matrix initialBias, final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1819 this(initialBias);
1820 this.listener = listener;
1821 }
1822
1823 /**
1824 * Constructor.
1825 *
1826 * @param measurements collection of body kinematics measurements with standard
1827 * deviations taken at different frames (positions, orientations
1828 * and velocities).
1829 * @param initialBias initial bias to find a solution.
1830 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1831 */
1832 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1833 final Collection<StandardDeviationFrameBodyKinematics> measurements, final Matrix initialBias) {
1834 this(initialBias);
1835 this.measurements = measurements;
1836 }
1837
1838 /**
1839 * Constructor.
1840 *
1841 * @param measurements collection of body kinematics measurements with standard
1842 * deviations taken at different frames (positions, orientations
1843 * and velocities).
1844 * @param initialBias initial bias to find a solution.
1845 * @param listener listener to handle events raised by this calibrator.
1846 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1847 */
1848 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1849 final Collection<StandardDeviationFrameBodyKinematics> measurements, final Matrix initialBias,
1850 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1851 this(measurements, initialBias);
1852 this.listener = listener;
1853 }
1854
1855 /**
1856 * Constructor.
1857 *
1858 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1859 * accelerometer and gyroscope.
1860 * @param initialBias initial bias to find a solution.
1861 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1862 */
1863 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1864 final boolean commonAxisUsed, final Matrix initialBias) {
1865 this(initialBias);
1866 this.commonAxisUsed = commonAxisUsed;
1867 }
1868
1869 /**
1870 * Constructor.
1871 *
1872 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1873 * accelerometer and gyroscope.
1874 * @param initialBias initial bias to find a solution.
1875 * @param listener listener to handle events raised by this calibrator.
1876 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1877 */
1878 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1879 final boolean commonAxisUsed, final Matrix initialBias,
1880 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1881 this(commonAxisUsed, initialBias);
1882 this.listener = listener;
1883 }
1884
1885 /**
1886 * Constructor.
1887 *
1888 * @param measurements collection of body kinematics measurements with standard
1889 * deviations taken at different frames (positions, orientations
1890 * and velocities).
1891 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1892 * accelerometer and gyroscope.
1893 * @param initialBias initial bias to find a solution.
1894 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1895 */
1896 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1897 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1898 final boolean commonAxisUsed, final Matrix initialBias) {
1899 this(commonAxisUsed, initialBias);
1900 this.measurements = measurements;
1901 }
1902
1903 /**
1904 * Constructor.
1905 *
1906 * @param measurements collection of body kinematics measurements with standard
1907 * deviations taken at different frames (positions, orientations
1908 * and velocities).
1909 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1910 * accelerometer and gyroscope.
1911 * @param initialBias initial bias to find a solution.
1912 * @param listener listener to handle events raised by this calibrator.
1913 * @throws IllegalArgumentException if provided bias matrix is not 3x1.
1914 */
1915 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1916 final Collection<StandardDeviationFrameBodyKinematics> measurements, final boolean commonAxisUsed,
1917 final Matrix initialBias, final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1918 this(measurements, commonAxisUsed, initialBias);
1919 this.listener = listener;
1920 }
1921
1922 /**
1923 * Constructor.
1924 *
1925 * @param initialBias initial bias to find a solution.
1926 * @param initialMa initial scale factors and cross coupling errors matrix.
1927 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1928 * scaling and coupling error matrix is not 3x3.
1929 */
1930 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(final Matrix initialBias, final Matrix initialMa) {
1931 this(initialBias);
1932 try {
1933 setInitialMa(initialMa);
1934 } catch (final LockedException ignore) {
1935 // never happens
1936 }
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 * @param listener listener to handle events raised by this calibrator.
1945 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1946 * scaling and coupling error matrix is not 3x3.
1947 */
1948 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1949 final Matrix initialBias, final Matrix initialMa,
1950 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1951 this(initialBias, initialMa);
1952 this.listener = listener;
1953 }
1954
1955 /**
1956 * Constructor.
1957 *
1958 * @param measurements collection of body kinematics measurements with standard
1959 * deviations taken at different frames (positions, orientations
1960 * and velocities).
1961 * @param initialBias initial bias to find a solution.
1962 * @param initialMa initial scale factors and cross coupling errors matrix.
1963 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1964 * scaling and coupling error matrix is not 3x3.
1965 */
1966 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1967 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1968 final Matrix initialBias, final Matrix initialMa) {
1969 this(initialBias, initialMa);
1970 this.measurements = measurements;
1971 }
1972
1973 /**
1974 * Constructor.
1975 *
1976 * @param measurements collection of body kinematics measurements with standard
1977 * deviations taken at different frames (positions, orientations
1978 * and velocities).
1979 * @param initialBias initial bias to find a solution.
1980 * @param initialMa initial scale factors and cross coupling errors matrix.
1981 * @param listener listener to handle events raised by this calibrator.
1982 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
1983 * scaling and coupling error matrix is not 3x3.
1984 */
1985 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
1986 final Collection<StandardDeviationFrameBodyKinematics> measurements,
1987 final Matrix initialBias, final Matrix initialMa,
1988 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
1989 this(measurements, initialBias, initialMa);
1990 this.listener = listener;
1991 }
1992
1993 /**
1994 * Constructor.
1995 *
1996 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
1997 * accelerometer and gyroscope.
1998 * @param initialBias initial bias to find a solution.
1999 * @param initialMa initial scale factors and cross coupling errors matrix.
2000 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
2001 * scaling and coupling error matrix is not 3x3.
2002 */
2003 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
2004 final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
2005 this(initialBias, initialMa);
2006 this.commonAxisUsed = commonAxisUsed;
2007 }
2008
2009 /**
2010 * Constructor.
2011 *
2012 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
2013 * accelerometer and gyroscope.
2014 * @param initialBias initial bias to find a solution.
2015 * @param initialMa initial scale factors and cross coupling errors matrix.
2016 * @param listener listener to handle events raised by this calibrator.
2017 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
2018 * scaling and coupling error matrix is not 3x3.
2019 */
2020 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
2021 final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
2022 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
2023 this(commonAxisUsed, initialBias, initialMa);
2024 this.listener = listener;
2025 }
2026
2027 /**
2028 * Constructor.
2029 *
2030 * @param measurements collection of body kinematics measurements with standard
2031 * deviations taken at different frames (positions, orientations
2032 * and velocities).
2033 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
2034 * accelerometer and gyroscope.
2035 * @param initialBias initial bias to find a solution.
2036 * @param initialMa initial scale factors and cross coupling errors matrix.
2037 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
2038 * scaling and coupling error matrix is not 3x3.
2039 */
2040 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
2041 final Collection<StandardDeviationFrameBodyKinematics> measurements,
2042 final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa) {
2043 this(commonAxisUsed, initialBias, initialMa);
2044 this.measurements = measurements;
2045 }
2046
2047 /**
2048 * Constructor.
2049 *
2050 * @param measurements collection of body kinematics measurements with standard
2051 * deviations taken at different frames (positions, orientations
2052 * and velocities).
2053 * @param commonAxisUsed indicates whether z-axis is assumed to be common for
2054 * accelerometer and gyroscope.
2055 * @param initialBias initial bias to find a solution.
2056 * @param initialMa initial scale factors and cross coupling errors matrix.
2057 * @param listener listener to handle events raised by this calibrator.
2058 * @throws IllegalArgumentException if either provided bias matrix is not 3x1 or
2059 * scaling and coupling error matrix is not 3x3.
2060 */
2061 public KnownFrameAccelerometerNonLinearLeastSquaresCalibrator(
2062 final Collection<StandardDeviationFrameBodyKinematics> measurements,
2063 final boolean commonAxisUsed, final Matrix initialBias, final Matrix initialMa,
2064 final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener) {
2065 this(measurements, commonAxisUsed, initialBias, initialMa);
2066 this.listener = listener;
2067 }
2068
2069 /**
2070 * Gets initial x-coordinate of accelerometer bias to be used to find a solution.
2071 * This is expressed in meters per squared second (m/s^2).
2072 *
2073 * @return initial x-coordinate of accelerometer bias.
2074 */
2075 @Override
2076 public double getInitialBiasX() {
2077 return initialBiasX;
2078 }
2079
2080 /**
2081 * Sets initial x-coordinate of accelerometer bias to be used to find a solution.
2082 * This is expressed in meters per squared second (m/s^2).
2083 *
2084 * @param initialBiasX initial x-coordinate of accelerometer bias.
2085 * @throws LockedException if calibrator is currently running.
2086 */
2087 @Override
2088 public void setInitialBiasX(final double initialBiasX) throws LockedException {
2089 if (running) {
2090 throw new LockedException();
2091 }
2092 this.initialBiasX = initialBiasX;
2093 }
2094
2095 /**
2096 * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
2097 * This is expressed in meters per squared second (m/s^2).
2098 *
2099 * @return initial y-coordinate of accelerometer bias.
2100 */
2101 @Override
2102 public double getInitialBiasY() {
2103 return initialBiasY;
2104 }
2105
2106 /**
2107 * Sets initial y-coordinate of accelerometer bias to be used to find a solution.
2108 * This is expressed in meters per squared second (m/s^2).
2109 *
2110 * @param initialBiasY initial y-coordinate of accelerometer bias.
2111 * @throws LockedException if calibrator is currently running.
2112 */
2113 @Override
2114 public void setInitialBiasY(final double initialBiasY) throws LockedException {
2115 if (running) {
2116 throw new LockedException();
2117 }
2118 this.initialBiasY = initialBiasY;
2119 }
2120
2121 /**
2122 * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
2123 * This is expressed in meters per squared second (m/s^2).
2124 *
2125 * @return initial z-coordinate of accelerometer bias.
2126 */
2127 @Override
2128 public double getInitialBiasZ() {
2129 return initialBiasZ;
2130 }
2131
2132 /**
2133 * Sets initial z-coordinate of accelerometer bias to be used to find a solution.
2134 * This is expressed in meters per squared second (m/s^2).
2135 *
2136 * @param initialBiasZ initial z-coordinate of accelerometer bias.
2137 * @throws LockedException if calibrator is currently running.
2138 */
2139 @Override
2140 public void setInitialBiasZ(final double initialBiasZ) throws LockedException {
2141 if (running) {
2142 throw new LockedException();
2143 }
2144 this.initialBiasZ = initialBiasZ;
2145 }
2146
2147 /**
2148 * Gets initial x-coordinate of accelerometer bias to be used to find a solution.
2149 *
2150 * @return initial x-coordinate of accelerometer bias.
2151 */
2152 @Override
2153 public Acceleration getInitialBiasXAsAcceleration() {
2154 return new Acceleration(initialBiasX, AccelerationUnit.METERS_PER_SQUARED_SECOND);
2155 }
2156
2157 /**
2158 * Gets initial x-coordinate of accelerometer bias to be used to find a solution.
2159 *
2160 * @param result instance where result data will be stored.
2161 */
2162 @Override
2163 public void getInitialBiasXAsAcceleration(final Acceleration result) {
2164 result.setValue(initialBiasX);
2165 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2166 }
2167
2168 /**
2169 * Sets initial x-coordinate of accelerometer bias to be used to find a solution.
2170 *
2171 * @param initialBiasX initial x-coordinate of accelerometer bias.
2172 * @throws LockedException if calibrator is currently running.
2173 */
2174 @Override
2175 public void setInitialBiasX(final Acceleration initialBiasX) throws LockedException {
2176 if (running) {
2177 throw new LockedException();
2178 }
2179 this.initialBiasX = convertAcceleration(initialBiasX);
2180 }
2181
2182 /**
2183 * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
2184 *
2185 * @return initial y-coordinate of accelerometer bias.
2186 */
2187 @Override
2188 public Acceleration getInitialBiasYAsAcceleration() {
2189 return new Acceleration(initialBiasY, AccelerationUnit.METERS_PER_SQUARED_SECOND);
2190 }
2191
2192 /**
2193 * Gets initial y-coordinate of accelerometer bias to be used to find a solution.
2194 *
2195 * @param result instance where result data will be stored.
2196 */
2197 @Override
2198 public void getInitialBiasYAsAcceleration(final Acceleration result) {
2199 result.setValue(initialBiasY);
2200 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2201 }
2202
2203 /**
2204 * Sets initial y-coordinate of accelerometer bias to be used to find a solution.
2205 *
2206 * @param initialBiasY initial y-coordinate of accelerometer bias.
2207 * @throws LockedException if calibrator is currently running.
2208 */
2209 @Override
2210 public void setInitialBiasY(final Acceleration initialBiasY) throws LockedException {
2211 if (running) {
2212 throw new LockedException();
2213 }
2214 this.initialBiasY = convertAcceleration(initialBiasY);
2215 }
2216
2217 /**
2218 * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
2219 *
2220 * @return initial z-coordinate of accelerometer bias.
2221 */
2222 @Override
2223 public Acceleration getInitialBiasZAsAcceleration() {
2224 return new Acceleration(initialBiasZ, AccelerationUnit.METERS_PER_SQUARED_SECOND);
2225 }
2226
2227 /**
2228 * Gets initial z-coordinate of accelerometer bias to be used to find a solution.
2229 *
2230 * @param result instance where result data will be stored.
2231 */
2232 @Override
2233 public void getInitialBiasZAsAcceleration(final Acceleration result) {
2234 result.setValue(initialBiasZ);
2235 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
2236 }
2237
2238 /**
2239 * Sets initial z-coordinate of accelerometer bias to be used to find a solution.
2240 *
2241 * @param initialBiasZ initial z-coordinate of accelerometer bias.
2242 * @throws LockedException if calibrator is currently running.
2243 */
2244 @Override
2245 public void setInitialBiasZ(final Acceleration initialBiasZ) throws LockedException {
2246 if (running) {
2247 throw new LockedException();
2248 }
2249 this.initialBiasZ = convertAcceleration(initialBiasZ);
2250 }
2251
2252 /**
2253 * Sets initial bias coordinates of accelerometer used to find a solution
2254 * expressed in meters per squared second (m/s^2).
2255 *
2256 * @param initialBiasX initial x-coordinate of accelerometer bias.
2257 * @param initialBiasY initial y-coordinate of accelerometer bias.
2258 * @param initialBiasZ initial z-coordinate of accelerometer bias.
2259 * @throws LockedException if calibrator is currently running.
2260 */
2261 @Override
2262 public void setInitialBias(
2263 final double initialBiasX, final double initialBiasY, final double initialBiasZ) throws LockedException {
2264 if (running) {
2265 throw new LockedException();
2266 }
2267 this.initialBiasX = initialBiasX;
2268 this.initialBiasY = initialBiasY;
2269 this.initialBiasZ = initialBiasZ;
2270 }
2271
2272 /**
2273 * Sets initial bias coordinates of accelerometer used to find a solution.
2274 *
2275 * @param initialBiasX initial x-coordinate of accelerometer bias.
2276 * @param initialBiasY initial y-coordinate of accelerometer bias.
2277 * @param initialBiasZ initial z-coordinate of accelerometer bias.
2278 * @throws LockedException if calibrator is currently running.
2279 */
2280 @Override
2281 public void setInitialBias(
2282 final Acceleration initialBiasX, final Acceleration initialBiasY, final Acceleration initialBiasZ)
2283 throws LockedException {
2284 if (running) {
2285 throw new LockedException();
2286 }
2287 this.initialBiasX = convertAcceleration(initialBiasX);
2288 this.initialBiasY = convertAcceleration(initialBiasY);
2289 this.initialBiasZ = convertAcceleration(initialBiasZ);
2290 }
2291
2292 /**
2293 * Gets initial bias coordinates of accelerometer used to find a solution.
2294 *
2295 * @return initial bias coordinates.
2296 */
2297 @Override
2298 public AccelerationTriad getInitialBiasAsTriad() {
2299 return new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
2300 initialBiasX, initialBiasY, initialBiasZ);
2301 }
2302
2303 /**
2304 * Gets initial bias coordinates of accelerometer used to find a solution.
2305 *
2306 * @param result instance where result will be stored.
2307 */
2308 @Override
2309 public void getInitialBiasAsTriad(final AccelerationTriad result) {
2310 result.setValueCoordinatesAndUnit(initialBiasX, initialBiasY, initialBiasZ,
2311 AccelerationUnit.METERS_PER_SQUARED_SECOND);
2312 }
2313
2314 /**
2315 * Sets initial bias coordinates of accelerometer used to find a solution.
2316 *
2317 * @param initialBias initial bias coordinates to be set.
2318 * @throws LockedException if calibrator is currently running.
2319 */
2320 @Override
2321 public void setInitialBias(final AccelerationTriad initialBias) throws LockedException {
2322 if (running) {
2323 throw new LockedException();
2324 }
2325
2326 initialBiasX = convertAcceleration(initialBias.getValueX(), initialBias.getUnit());
2327 initialBiasY = convertAcceleration(initialBias.getValueY(), initialBias.getUnit());
2328 initialBiasZ = convertAcceleration(initialBias.getValueZ(), initialBias.getUnit());
2329 }
2330
2331 /**
2332 * Gets initial x scaling factor.
2333 *
2334 * @return initial x scaling factor.
2335 */
2336 @Override
2337 public double getInitialSx() {
2338 return initialSx;
2339 }
2340
2341 /**
2342 * Sets initial x scaling factor.
2343 *
2344 * @param initialSx initial x scaling factor.
2345 * @throws LockedException if calibrator is currently running.
2346 */
2347 @Override
2348 public void setInitialSx(final double initialSx) throws LockedException {
2349 if (running) {
2350 throw new LockedException();
2351 }
2352 this.initialSx = initialSx;
2353 }
2354
2355 /**
2356 * Gets initial y scaling factor.
2357 *
2358 * @return initial y scaling factor.
2359 */
2360 @Override
2361 public double getInitialSy() {
2362 return initialSy;
2363 }
2364
2365 /**
2366 * Sets initial y scaling factor.
2367 *
2368 * @param initialSy initial y scaling factor.
2369 * @throws LockedException if calibrator is currently running.
2370 */
2371 @Override
2372 public void setInitialSy(final double initialSy) throws LockedException {
2373 if (running) {
2374 throw new LockedException();
2375 }
2376 this.initialSy = initialSy;
2377 }
2378
2379 /**
2380 * Gets initial z scaling factor.
2381 *
2382 * @return initial z scaling factor.
2383 */
2384 @Override
2385 public double getInitialSz() {
2386 return initialSz;
2387 }
2388
2389 /**
2390 * Sets initial z scaling factor.
2391 *
2392 * @param initialSz initial z scaling factor.
2393 * @throws LockedException if calibrator is currently running.
2394 */
2395 @Override
2396 public void setInitialSz(final double initialSz) throws LockedException {
2397 if (running) {
2398 throw new LockedException();
2399 }
2400 this.initialSz = initialSz;
2401 }
2402
2403 /**
2404 * Gets initial x-y cross coupling error.
2405 *
2406 * @return initial x-y cross coupling error.
2407 */
2408 @Override
2409 public double getInitialMxy() {
2410 return initialMxy;
2411 }
2412
2413 /**
2414 * Sets initial x-y cross coupling error.
2415 *
2416 * @param initialMxy initial x-y cross coupling error.
2417 * @throws LockedException if calibrator is currently running.
2418 */
2419 @Override
2420 public void setInitialMxy(final double initialMxy) throws LockedException {
2421 if (running) {
2422 throw new LockedException();
2423 }
2424 this.initialMxy = initialMxy;
2425 }
2426
2427 /**
2428 * Gets initial x-z cross coupling error.
2429 *
2430 * @return initial x-z cross coupling error.
2431 */
2432 @Override
2433 public double getInitialMxz() {
2434 return initialMxz;
2435 }
2436
2437 /**
2438 * Sets initial x-z cross coupling error.
2439 *
2440 * @param initialMxz initial x-z cross coupling error.
2441 * @throws LockedException if calibrator is currently running.
2442 */
2443 @Override
2444 public void setInitialMxz(final double initialMxz) throws LockedException {
2445 if (running) {
2446 throw new LockedException();
2447 }
2448 this.initialMxz = initialMxz;
2449 }
2450
2451 /**
2452 * Gets initial y-x cross coupling error.
2453 *
2454 * @return initial y-x cross coupling error.
2455 */
2456 @Override
2457 public double getInitialMyx() {
2458 return initialMyx;
2459 }
2460
2461 /**
2462 * Sets initial y-x cross coupling error.
2463 *
2464 * @param initialMyx initial y-x cross coupling error.
2465 * @throws LockedException if calibrator is currently running.
2466 */
2467 @Override
2468 public void setInitialMyx(final double initialMyx) throws LockedException {
2469 if (running) {
2470 throw new LockedException();
2471 }
2472 this.initialMyx = initialMyx;
2473 }
2474
2475 /**
2476 * Gets initial y-z cross coupling error.
2477 *
2478 * @return initial y-z cross coupling error.
2479 */
2480 @Override
2481 public double getInitialMyz() {
2482 return initialMyz;
2483 }
2484
2485 /**
2486 * Sets initial y-z cross coupling error.
2487 *
2488 * @param initialMyz initial y-z cross coupling error.
2489 * @throws LockedException if calibrator is currently running.
2490 */
2491 @Override
2492 public void setInitialMyz(final double initialMyz) throws LockedException {
2493 if (running) {
2494 throw new LockedException();
2495 }
2496 this.initialMyz = initialMyz;
2497 }
2498
2499 /**
2500 * Gets initial z-x cross coupling error.
2501 *
2502 * @return initial z-x cross coupling error.
2503 */
2504 @Override
2505 public double getInitialMzx() {
2506 return initialMzx;
2507 }
2508
2509 /**
2510 * Sets initial z-x cross coupling error.
2511 *
2512 * @param initialMzx initial z-x cross coupling error.
2513 * @throws LockedException if calibrator is currently running.
2514 */
2515 @Override
2516 public void setInitialMzx(final double initialMzx) throws LockedException {
2517 if (running) {
2518 throw new LockedException();
2519 }
2520 this.initialMzx = initialMzx;
2521 }
2522
2523 /**
2524 * Gets initial z-y cross coupling error.
2525 *
2526 * @return initial z-y cross coupling error.
2527 */
2528 @Override
2529 public double getInitialMzy() {
2530 return initialMzy;
2531 }
2532
2533 /**
2534 * Sets initial z-y cross coupling error.
2535 *
2536 * @param initialMzy initial z-y cross coupling error.
2537 * @throws LockedException if calibrator is currently running.
2538 */
2539 @Override
2540 public void setInitialMzy(final double initialMzy) throws LockedException {
2541 if (running) {
2542 throw new LockedException();
2543 }
2544 this.initialMzy = initialMzy;
2545 }
2546
2547 /**
2548 * Sets initial scaling factors.
2549 *
2550 * @param initialSx initial x scaling factor.
2551 * @param initialSy initial y scaling factor.
2552 * @param initialSz initial z scaling factor.
2553 * @throws LockedException if calibrator is currently running.
2554 */
2555 @Override
2556 public void setInitialScalingFactors(
2557 final double initialSx, final double initialSy, final double initialSz) throws LockedException {
2558 if (running) {
2559 throw new LockedException();
2560 }
2561 this.initialSx = initialSx;
2562 this.initialSy = initialSy;
2563 this.initialSz = initialSz;
2564 }
2565
2566 /**
2567 * Sets initial cross coupling errors.
2568 *
2569 * @param initialMxy initial x-y cross coupling error.
2570 * @param initialMxz initial x-z cross coupling error.
2571 * @param initialMyx initial y-x cross coupling error.
2572 * @param initialMyz initial y-z cross coupling error.
2573 * @param initialMzx initial z-x cross coupling error.
2574 * @param initialMzy initial z-y cross coupling error.
2575 * @throws LockedException if calibrator is currently running.
2576 */
2577 @Override
2578 public void setInitialCrossCouplingErrors(
2579 final double initialMxy, final double initialMxz, final double initialMyx,
2580 final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
2581 if (running) {
2582 throw new LockedException();
2583 }
2584 this.initialMxy = initialMxy;
2585 this.initialMxz = initialMxz;
2586 this.initialMyx = initialMyx;
2587 this.initialMyz = initialMyz;
2588 this.initialMzx = initialMzx;
2589 this.initialMzy = initialMzy;
2590 }
2591
2592 /**
2593 * Sets initial scaling factors and cross coupling errors.
2594 *
2595 * @param initialSx initial x scaling factor.
2596 * @param initialSy initial y scaling factor.
2597 * @param initialSz initial z scaling factor.
2598 * @param initialMxy initial x-y cross coupling error.
2599 * @param initialMxz initial x-z cross coupling error.
2600 * @param initialMyx initial y-x cross coupling error.
2601 * @param initialMyz initial y-z cross coupling error.
2602 * @param initialMzx initial z-x cross coupling error.
2603 * @param initialMzy initial z-y cross coupling error.
2604 * @throws LockedException if calibrator is currently running.
2605 */
2606 @Override
2607 public void setInitialScalingFactorsAndCrossCouplingErrors(
2608 final double initialSx, final double initialSy, final double initialSz,
2609 final double initialMxy, final double initialMxz, final double initialMyx,
2610 final double initialMyz, final double initialMzx, final double initialMzy) throws LockedException {
2611 if (running) {
2612 throw new LockedException();
2613 }
2614 setInitialScalingFactors(initialSx, initialSy, initialSz);
2615 setInitialCrossCouplingErrors(initialMxy, initialMxz, initialMyx, initialMyz, initialMzx, initialMzy);
2616 }
2617
2618 /**
2619 * Gets initial bias to be used to find a solution as an array.
2620 * Array values are expressed in meters per squared second (m/s^2).
2621 *
2622 * @return array containing coordinates of initial bias.
2623 */
2624 @Override
2625 public double[] getInitialBias() {
2626 final var result = new double[BodyKinematics.COMPONENTS];
2627 getInitialBias(result);
2628 return result;
2629 }
2630
2631 /**
2632 * Gets initial bias to be used to find a solution as an array.
2633 * Array values are expressed in meters per squared second (m/s^2).
2634 *
2635 * @param result instance where result data will be copied to.
2636 * @throws IllegalArgumentException if provided array does not have length 3.
2637 */
2638 @Override
2639 public void getInitialBias(final double[] result) {
2640 if (result.length != BodyKinematics.COMPONENTS) {
2641 throw new IllegalArgumentException();
2642 }
2643 result[0] = initialBiasX;
2644 result[1] = initialBiasY;
2645 result[2] = initialBiasZ;
2646 }
2647
2648 /**
2649 * Sets initial bias to be used to find a solution as an array.
2650 * Array values are expressed in meters per squared second (m/s^2).
2651 *
2652 * @param initialBias initial bias to find a solution.
2653 * @throws LockedException if calibrator is currently running.
2654 * @throws IllegalArgumentException if provided array does not have length 3.
2655 */
2656 @Override
2657 public void setInitialBias(final double[] initialBias) throws LockedException {
2658 if (running) {
2659 throw new LockedException();
2660 }
2661
2662 if (initialBias.length != BodyKinematics.COMPONENTS) {
2663 throw new IllegalArgumentException();
2664 }
2665 initialBiasX = initialBias[0];
2666 initialBiasY = initialBias[1];
2667 initialBiasZ = initialBias[2];
2668 }
2669
2670 /**
2671 * Gets initial bias to be used to find a solution as a column matrix.
2672 * Values are expressed in meters per squared second (m/s^2).
2673 *
2674 * @return initial bias to be used to find a solution as a column matrix.
2675 */
2676 @Override
2677 public Matrix getInitialBiasAsMatrix() {
2678 Matrix result;
2679 try {
2680 result = new Matrix(BodyKinematics.COMPONENTS, 1);
2681 getInitialBiasAsMatrix(result);
2682 } catch (final WrongSizeException ignore) {
2683 // never happens
2684 result = null;
2685 }
2686 return result;
2687 }
2688
2689 /**
2690 * Gets initial bias to be used to find a solution as a column matrix.
2691 * Values are expressed in meters per squared second (m/s^2).
2692 *
2693 * @param result instance where result data will be copied to.
2694 * @throws IllegalArgumentException if provided matrix is not 3x1.
2695 */
2696 @Override
2697 public void getInitialBiasAsMatrix(final Matrix result) {
2698 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != 1) {
2699 throw new IllegalArgumentException();
2700 }
2701 result.setElementAtIndex(0, initialBiasX);
2702 result.setElementAtIndex(1, initialBiasY);
2703 result.setElementAtIndex(2, initialBiasZ);
2704 }
2705
2706 /**
2707 * Sets initial bias to be used to find a solution as a column matrix with
2708 * values expressed in meters per squared second (m/s^2).
2709 *
2710 * @param initialBias initial bias to find a solution.
2711 * @throws LockedException if calibrator is currently running.
2712 * @throws IllegalArgumentException if provided matrix is not 3x1.
2713 */
2714 @Override
2715 public void setInitialBias(final Matrix initialBias) throws LockedException {
2716 if (running) {
2717 throw new LockedException();
2718 }
2719 if (initialBias.getRows() != BodyKinematics.COMPONENTS || initialBias.getColumns() != 1) {
2720 throw new IllegalArgumentException();
2721 }
2722
2723 initialBiasX = initialBias.getElementAtIndex(0);
2724 initialBiasY = initialBias.getElementAtIndex(1);
2725 initialBiasZ = initialBias.getElementAtIndex(2);
2726 }
2727
2728 /**
2729 * Gets initial scale factors and cross coupling errors matrix.
2730 *
2731 * @return initial scale factors and cross coupling errors matrix.
2732 */
2733 @Override
2734 public Matrix getInitialMa() {
2735 Matrix result;
2736 try {
2737 result = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
2738 getInitialMa(result);
2739 } catch (final WrongSizeException ignore) {
2740 // never happens
2741 result = null;
2742 }
2743 return result;
2744 }
2745
2746 /**
2747 * Gets initial scale factors and cross coupling errors matrix.
2748 *
2749 * @param result instance where data will be stored.
2750 * @throws IllegalArgumentException if provided matrix is not 3x3.
2751 */
2752 @Override
2753 public void getInitialMa(final Matrix result) {
2754 if (result.getRows() != BodyKinematics.COMPONENTS || result.getColumns() != BodyKinematics.COMPONENTS) {
2755 throw new IllegalArgumentException();
2756 }
2757 result.setElementAtIndex(0, initialSx);
2758 result.setElementAtIndex(1, initialMyx);
2759 result.setElementAtIndex(2, initialMzx);
2760
2761 result.setElementAtIndex(3, initialMxy);
2762 result.setElementAtIndex(4, initialSy);
2763 result.setElementAtIndex(5, initialMzy);
2764
2765 result.setElementAtIndex(6, initialMxz);
2766 result.setElementAtIndex(7, initialMyz);
2767 result.setElementAtIndex(8, initialSz);
2768 }
2769
2770 /**
2771 * Sets initial scale factors and cross coupling errors matrix.
2772 *
2773 * @param initialMa initial scale factors and cross coupling errors matrix.
2774 * @throws IllegalArgumentException if provided matrix is not 3x3.
2775 * @throws LockedException if calibrator is currently running.
2776 */
2777 @Override
2778 public void setInitialMa(final Matrix initialMa) throws LockedException {
2779 if (running) {
2780 throw new LockedException();
2781 }
2782 if (initialMa.getRows() != BodyKinematics.COMPONENTS || initialMa.getColumns() != BodyKinematics.COMPONENTS) {
2783 throw new IllegalArgumentException();
2784 }
2785
2786 initialSx = initialMa.getElementAtIndex(0);
2787 initialMyx = initialMa.getElementAtIndex(1);
2788 initialMzx = initialMa.getElementAtIndex(2);
2789
2790 initialMxy = initialMa.getElementAtIndex(3);
2791 initialSy = initialMa.getElementAtIndex(4);
2792 initialMzy = initialMa.getElementAtIndex(5);
2793
2794 initialMxz = initialMa.getElementAtIndex(6);
2795 initialMyz = initialMa.getElementAtIndex(7);
2796 initialSz = initialMa.getElementAtIndex(8);
2797 }
2798
2799 /**
2800 * Gets a collection of body kinematics measurements taken at different
2801 * frames (positions, orientations and velocities) and containing the standard
2802 * deviations of accelerometer and gyroscope measurements.
2803 * If a single device IMU needs to be calibrated, typically all measurements are
2804 * taken at the same position, with zero velocity and multiple orientations.
2805 * However, if we just want to calibrate a given IMU model (e.g. obtain
2806 * an average and less precise calibration for the IMU of a given phone model),
2807 * we could take measurements collected throughout the planet at multiple positions
2808 * while the phone remains static (e.g. while charging), hence each measurement
2809 * position will change, velocity will remain zero and orientation will be
2810 * typically constant at horizontal orientation while the phone remains on a
2811 * flat surface.
2812 *
2813 * @return a collection of body kinematics measurements taken at different
2814 * frames (positions, orientations and velocities).
2815 */
2816 @Override
2817 public Collection<StandardDeviationFrameBodyKinematics> getMeasurements() {
2818 return measurements;
2819 }
2820
2821 /**
2822 * Sets a collection of body kinematics measurements taken at different
2823 * frames (positions, orientations and velocities) and containing the standard
2824 * deviations of accelerometer and gyroscope measurements.
2825 * If a single device IMU needs to be calibrated, typically all measurements are
2826 * taken at the same position, with zero velocity and multiple orientations.
2827 * However, if we just want to calibrate a given IMU model (e.g. obtain
2828 * an average and less precise calibration for the IMU of a given phone model),
2829 * we could take measurements collected throughout the planet at multiple positions
2830 * while the phone remains static (e.g. while charging), hence each measurement
2831 * position will change, velocity will remain zero and orientation will be
2832 * typically constant at horizontal orientation while the phone remains on a
2833 * flat surface.
2834 *
2835 * @param measurements collection of body kinematics measurements taken at different
2836 * frames (positions, orientations and velocities).
2837 * @throws LockedException if calibrator is currently running.
2838 */
2839 @Override
2840 public void setMeasurements(
2841 final Collection<? extends StandardDeviationFrameBodyKinematics> measurements) throws LockedException {
2842 if (running) {
2843 throw new LockedException();
2844 }
2845 //noinspection unchecked
2846 this.measurements = (Collection<StandardDeviationFrameBodyKinematics>) measurements;
2847 }
2848
2849 /**
2850 * Indicates the type of measurement used by this calibrator.
2851 *
2852 * @return type of measurement used by this calibrator.
2853 */
2854 @Override
2855 public AccelerometerCalibratorMeasurementType getMeasurementType() {
2856 return AccelerometerCalibratorMeasurementType.STANDARD_DEVIATION_FRAME_BODY_KINEMATICS;
2857 }
2858
2859 /**
2860 * Indicates whether this calibrator requires ordered measurements in a
2861 * list or not.
2862 *
2863 * @return true if measurements must be ordered, false otherwise.
2864 */
2865 @Override
2866 public boolean isOrderedMeasurementsRequired() {
2867 return false;
2868 }
2869
2870 /**
2871 * Indicates whether this calibrator requires quality scores for each
2872 * measurement or not.
2873 *
2874 * @return true if quality scores are required, false otherwise.
2875 */
2876 @Override
2877 public boolean isQualityScoresRequired() {
2878 return false;
2879 }
2880
2881 /**
2882 * Indicates whether z-axis is assumed to be common for accelerometer and
2883 * gyroscope.
2884 * When enabled, this eliminates 3 variables from Ma matrix.
2885 *
2886 * @return true if z-axis is assumed to be common for accelerometer and gyroscope,
2887 * false otherwise.
2888 */
2889 @Override
2890 public boolean isCommonAxisUsed() {
2891 return commonAxisUsed;
2892 }
2893
2894 /**
2895 * Specifies whether z-axis is assumed to be common for accelerometer and
2896 * gyroscope.
2897 * When enabled, this eliminates 3 variables from Ma matrix.
2898 *
2899 * @param commonAxisUsed true if z-axis is assumed to be common for accelerometer
2900 * and gyroscope, false otherwise.
2901 * @throws LockedException if calibrator is currently running.
2902 */
2903 @Override
2904 public void setCommonAxisUsed(final boolean commonAxisUsed) throws LockedException {
2905 if (running) {
2906 throw new LockedException();
2907 }
2908
2909 this.commonAxisUsed = commonAxisUsed;
2910 }
2911
2912 /**
2913 * Gets listener to handle events raised by this estimator.
2914 *
2915 * @return listener to handle events raised by this estimator.
2916 */
2917 @Override
2918 public KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener getListener() {
2919 return listener;
2920 }
2921
2922 /**
2923 * Sets listener to handle events raised by this estimator.
2924 *
2925 * @param listener listener to handle events raised by this estimator.
2926 * @throws LockedException if calibrator is currently running.
2927 */
2928 @Override
2929 public void setListener(final KnownFrameAccelerometerNonLinearLeastSquaresCalibratorListener listener)
2930 throws LockedException {
2931 if (running) {
2932 throw new LockedException();
2933 }
2934
2935 this.listener = listener;
2936 }
2937
2938 /**
2939 * Gets minimum number of required measurements.
2940 *
2941 * @return minimum number of required measurements.
2942 */
2943 @Override
2944 public int getMinimumRequiredMeasurements() {
2945 return MINIMUM_MEASUREMENTS;
2946 }
2947
2948 /**
2949 * Indicates whether calibrator is ready to start.
2950 *
2951 * @return true if calibrator is ready, false otherwise.
2952 */
2953 @Override
2954 public boolean isReady() {
2955 return measurements != null && measurements.size() >= MINIMUM_MEASUREMENTS;
2956 }
2957
2958 /**
2959 * Indicates whether calibrator is currently running or not.
2960 *
2961 * @return true if calibrator is running, false otherwise.
2962 */
2963 @Override
2964 public boolean isRunning() {
2965 return running;
2966 }
2967
2968 /**
2969 * Estimates accelerometer calibration parameters containing bias, scale factors
2970 * and cross-coupling errors.
2971 *
2972 * @throws LockedException if calibrator is currently running.
2973 * @throws NotReadyException if calibrator is not ready.
2974 * @throws CalibrationException if estimation fails for numerical reasons.
2975 */
2976 @Override
2977 public void calibrate() throws LockedException, NotReadyException, CalibrationException {
2978 if (running) {
2979 throw new LockedException();
2980 }
2981
2982 if (!isReady()) {
2983 throw new NotReadyException();
2984 }
2985
2986 try {
2987 running = true;
2988
2989 if (listener != null) {
2990 listener.onCalibrateStart(this);
2991 }
2992
2993 if (commonAxisUsed) {
2994 calibrateCommonAxis();
2995 } else {
2996 calibrateGeneral();
2997 }
2998
2999 if (listener != null) {
3000 listener.onCalibrateEnd(this);
3001 }
3002
3003 } catch (final AlgebraException | FittingException | com.irurueta.numerical.NotReadyException e) {
3004 throw new CalibrationException(e);
3005 } finally {
3006 running = false;
3007 }
3008 }
3009
3010 /**
3011 * Gets array containing x,y,z components of estimated accelerometer biases
3012 * expressed in meters per squared second (m/s^2).
3013 *
3014 * @return array containing x,y,z components of estimated accelerometer biases.
3015 */
3016 @Override
3017 public double[] getEstimatedBiases() {
3018 return estimatedBiases;
3019 }
3020
3021 /**
3022 * Gets array containing x,y,z components of estimated accelerometer biases
3023 * expressed in meters per squared second (m/s^2).
3024 *
3025 * @param result instance where estimated accelerometer biases will be stored.
3026 * @return true if result instance was updated, false otherwise (when estimation
3027 * is not yet available).
3028 */
3029 @Override
3030 public boolean getEstimatedBiases(final double[] result) {
3031 if (estimatedBiases != null) {
3032 System.arraycopy(estimatedBiases, 0, result, 0, estimatedBiases.length);
3033 return true;
3034 } else {
3035 return false;
3036 }
3037 }
3038
3039 /**
3040 * Gets column matrix containing x,y,z components of estimated accelerometer biases
3041 * expressed in meters per squared second (m/s^2).
3042 *
3043 * @return column matrix containing x,y,z components of estimated accelerometer
3044 * biases.
3045 */
3046 @Override
3047 public Matrix getEstimatedBiasesAsMatrix() {
3048 return estimatedBiases != null ? Matrix.newFromArray(estimatedBiases) : null;
3049 }
3050
3051 /**
3052 * Gets column matrix containing x,y,z components of estimated accelerometer biases
3053 * expressed in meters per squared second (m/s^2).
3054 *
3055 * @param result instance where result data will be stored.
3056 * @return true if result was updated, false otherwise.
3057 * @throws WrongSizeException if provided result instance has invalid size.
3058 */
3059 @Override
3060 public boolean getEstimatedBiasesAsMatrix(final Matrix result) throws WrongSizeException {
3061 if (estimatedBiases != null) {
3062 result.fromArray(estimatedBiases);
3063 return true;
3064 } else {
3065 return false;
3066 }
3067 }
3068
3069 /**
3070 * Gets x coordinate of estimated accelerometer bias expressed in meters per
3071 * squared second (m/s^2).
3072 *
3073 * @return x coordinate of estimated accelerometer bias or null if not available.
3074 */
3075 @Override
3076 public Double getEstimatedBiasFx() {
3077 return estimatedBiases != null ? estimatedBiases[0] : null;
3078 }
3079
3080 /**
3081 * Gets y coordinate of estimated accelerometer bias expressed in meters per
3082 * squared second (m/s^2).
3083 *
3084 * @return y coordinate of estimated accelerometer bias or null if not available.
3085 */
3086 @Override
3087 public Double getEstimatedBiasFy() {
3088 return estimatedBiases != null ? estimatedBiases[1] : null;
3089 }
3090
3091 /**
3092 * Gets z coordinate of estimated accelerometer bias expressed in meters per
3093 * squared second (m/s^2).
3094 *
3095 * @return z coordinate of estimated accelerometer bias or null if not available.
3096 */
3097 @Override
3098 public Double getEstimatedBiasFz() {
3099 return estimatedBiases != null ? estimatedBiases[2] : null;
3100 }
3101
3102 /**
3103 * Gets x coordinate of estimated accelerometer bias.
3104 *
3105 * @return x coordinate of estimated accelerometer bias or null if not available.
3106 */
3107 @Override
3108 public Acceleration getEstimatedBiasFxAsAcceleration() {
3109 return estimatedBiases != null
3110 ? new Acceleration(estimatedBiases[0], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
3111 }
3112
3113 /**
3114 * Gets x coordinate of estimated accelerometer bias.
3115 *
3116 * @param result instance where result will be stored.
3117 * @return true if result was updated, false if estimation is not available.
3118 */
3119 @Override
3120 public boolean getEstimatedBiasFxAsAcceleration(final Acceleration result) {
3121 if (estimatedBiases != null) {
3122 result.setValue(estimatedBiases[0]);
3123 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3124 return true;
3125 } else {
3126 return false;
3127 }
3128 }
3129
3130 /**
3131 * Gets y coordinate of estimated accelerometer bias.
3132 *
3133 * @return y coordinate of estimated accelerometer bias or null if not available.
3134 */
3135 @Override
3136 public Acceleration getEstimatedBiasFyAsAcceleration() {
3137 return estimatedBiases != null
3138 ? new Acceleration(estimatedBiases[1], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
3139 }
3140
3141 /**
3142 * Gets y coordinate of estimated accelerometer bias.
3143 *
3144 * @param result instance where result will be stored.
3145 * @return true if result was updated, false if estimation is not available.
3146 */
3147 @Override
3148 public boolean getEstimatedBiasFyAsAcceleration(final Acceleration result) {
3149 if (estimatedBiases != null) {
3150 result.setValue(estimatedBiases[1]);
3151 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3152 return true;
3153 } else {
3154 return false;
3155 }
3156 }
3157
3158 /**
3159 * Gets z coordinate of estimated accelerometer bias.
3160 *
3161 * @return z coordinate of estimated accelerometer bias or null if not available.
3162 */
3163 @Override
3164 public Acceleration getEstimatedBiasFzAsAcceleration() {
3165 return estimatedBiases != null
3166 ? new Acceleration(estimatedBiases[2], AccelerationUnit.METERS_PER_SQUARED_SECOND) : null;
3167 }
3168
3169 /**
3170 * Gets z coordinate of estimated accelerometer bias.
3171 *
3172 * @param result instance where result will be stored.
3173 * @return true if result was updated, false if estimation is not available.
3174 */
3175 @Override
3176 public boolean getEstimatedBiasFzAsAcceleration(final Acceleration result) {
3177 if (estimatedBiases != null) {
3178 result.setValue(estimatedBiases[2]);
3179 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3180 return true;
3181 } else {
3182 return false;
3183 }
3184 }
3185
3186 /**
3187 * Gets estimated accelerometer bias.
3188 *
3189 * @return estimated accelerometer bias or null if not available.
3190 */
3191 @Override
3192 public AccelerationTriad getEstimatedBiasAsTriad() {
3193 return estimatedBiases != null
3194 ? new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
3195 estimatedBiases[0], estimatedBiases[1], estimatedBiases[2])
3196 : null;
3197 }
3198
3199 /**
3200 * Gets estimated accelerometer bias.
3201 *
3202 * @param result instance where result will be stored.
3203 * @return true if estimated accelerometer bias is available and result was
3204 * modified, false otherwise.
3205 */
3206 @Override
3207 public boolean getEstimatedBiasAsTriad(final AccelerationTriad result) {
3208 if (estimatedBiases != null) {
3209 result.setValueCoordinatesAndUnit(
3210 estimatedBiases[0], estimatedBiases[1], estimatedBiases[2],
3211 AccelerationUnit.METERS_PER_SQUARED_SECOND);
3212 return true;
3213 } else {
3214 return false;
3215 }
3216 }
3217
3218 /**
3219 * Gets estimated accelerometer scale factors and ross coupling errors.
3220 * This is the product of matrix Ta containing cross coupling errors and Ka
3221 * containing scaling factors.
3222 * So tat:
3223 * <pre>
3224 * Ma = [sx mxy mxz] = Ta*Ka
3225 * [myx sy myz]
3226 * [mzx mzy sz ]
3227 * </pre>
3228 * Where:
3229 * <pre>
3230 * Ka = [sx 0 0 ]
3231 * [0 sy 0 ]
3232 * [0 0 sz]
3233 * </pre>
3234 * and
3235 * <pre>
3236 * Ta = [1 -alphaXy alphaXz ]
3237 * [alphaYx 1 -alphaYz]
3238 * [-alphaZx alphaZy 1 ]
3239 * </pre>
3240 * Hence:
3241 * <pre>
3242 * Ma = [sx mxy mxz] = Ta*Ka = [sx -sy * alphaXy sz * alphaXz ]
3243 * [myx sy myz] [sx * alphaYx sy -sz * alphaYz]
3244 * [mzx mzy sz ] [-sx * alphaZx sy * alphaZy sz ]
3245 * </pre>
3246 * This instance allows any 3x3 matrix however, typically alphaYx, alphaZx and alphaZy
3247 * are considered to be zero if the accelerometer z-axis is assumed to be the same
3248 * as the body z-axis. When this is assumed, myx = mzx = mzy = 0 and the Ma matrix
3249 * becomes upper diagonal:
3250 * <pre>
3251 * Ma = [sx mxy mxz]
3252 * [0 sy myz]
3253 * [0 0 sz ]
3254 * </pre>
3255 * Values of this matrix are unit-less.
3256 *
3257 * @return estimated accelerometer scale factors and cross coupling errors, or null
3258 * if not available.
3259 */
3260 @Override
3261 public Matrix getEstimatedMa() {
3262 return estimatedMa;
3263 }
3264
3265 /**
3266 * Gets estimated x-axis scale factor.
3267 *
3268 * @return estimated x-axis scale factor or null if not available.
3269 */
3270 @Override
3271 public Double getEstimatedSx() {
3272 return estimatedMa != null ? estimatedMa.getElementAt(0, 0) : null;
3273 }
3274
3275 /**
3276 * Gets estimated y-axis scale factor.
3277 *
3278 * @return estimated y-axis scale factor or null if not available.
3279 */
3280 @Override
3281 public Double getEstimatedSy() {
3282 return estimatedMa != null ? estimatedMa.getElementAt(1, 1) : null;
3283 }
3284
3285 /**
3286 * Gets estimated z-axis scale factor.
3287 *
3288 * @return estimated z-axis scale factor or null if not available.
3289 */
3290 @Override
3291 public Double getEstimatedSz() {
3292 return estimatedMa != null ? estimatedMa.getElementAt(2, 2) : null;
3293 }
3294
3295 /**
3296 * Gets estimated x-y cross-coupling error.
3297 *
3298 * @return estimated x-y cross-coupling error or null if not available.
3299 */
3300 @Override
3301 public Double getEstimatedMxy() {
3302 return estimatedMa != null ? estimatedMa.getElementAt(0, 1) : null;
3303 }
3304
3305 /**
3306 * Gets estimated x-z cross-coupling error.
3307 *
3308 * @return estimated x-z cross-coupling error or null if not available.
3309 */
3310 @Override
3311 public Double getEstimatedMxz() {
3312 return estimatedMa != null ? estimatedMa.getElementAt(0, 2) : null;
3313 }
3314
3315 /**
3316 * Gets estimated y-x cross-coupling error.
3317 *
3318 * @return estimated y-x cross-coupling error or null if not available.
3319 */
3320 @Override
3321 public Double getEstimatedMyx() {
3322 return estimatedMa != null ? estimatedMa.getElementAt(1, 0) : null;
3323 }
3324
3325 /**
3326 * Gets estimated y-z cross-coupling error.
3327 *
3328 * @return estimated y-z cross-coupling error or null if not available.
3329 */
3330 @Override
3331 public Double getEstimatedMyz() {
3332 return estimatedMa != null ? estimatedMa.getElementAt(1, 2) : null;
3333 }
3334
3335 /**
3336 * Gets estimated z-x cross-coupling error.
3337 *
3338 * @return estimated z-x cross-coupling error or null if not available.
3339 */
3340 @Override
3341 public Double getEstimatedMzx() {
3342 return estimatedMa != null ? estimatedMa.getElementAt(2, 0) : null;
3343 }
3344
3345 /**
3346 * Gets estimated z-y cross-coupling error.
3347 *
3348 * @return estimated z-y cross-coupling error or null if not available.
3349 */
3350 @Override
3351 public Double getEstimatedMzy() {
3352 return estimatedMa != null ? estimatedMa.getElementAt(2, 1) : null;
3353 }
3354
3355 /**
3356 * Gets estimated covariance matrix for estimated calibration parameters.
3357 * Diagonal elements of the matrix contains variance for the following
3358 * parameters (following indicated order): bx, by, bz, sx, sy, sz,
3359 * mxy, mxz, myx, myz, mzx, mzy.
3360 *
3361 * @return estimated covariance matrix for estimated calibration parameters.
3362 */
3363 @Override
3364 public Matrix getEstimatedCovariance() {
3365 return estimatedCovariance;
3366 }
3367
3368 /**
3369 * Gets estimated chi square value.
3370 *
3371 * @return estimated chi square value.
3372 */
3373 @Override
3374 public double getEstimatedChiSq() {
3375 return estimatedChiSq;
3376 }
3377
3378 /**
3379 * Gets estimated chi square degrees of freedom. Degrees of freedom is equal to the number of sampled data minus the
3380 * number of estimated parameters.
3381 *
3382 * @return estimated degrees of freedom of chi square value
3383 */
3384 @Override
3385 public int getEstimatedChiSqDegreesOfFreedom() {
3386 return estimatedChiSqDegreesOfFreedom;
3387 }
3388
3389 /**
3390 * Gets estimated reduced chi square value. This is equal to estimated chi square value divided by its degrees of
3391 * freedom. Ideally this value should be close to 1.0, indicating that fit is optimal.
3392 * A value larger than 1.0 indicates that fit is not good or noise has been underestimated, and a value smaller than
3393 * 1.0 indicates that there is overfitting or noise has been overestimated.
3394 *
3395 * @return estimated reduced chi square value
3396 */
3397 @Override
3398 public double getEstimatedReducedChiSq() {
3399 return estimatedReducedChiSq;
3400 }
3401
3402 /**
3403 * Gets estimated mean square error respect to provided measurements.
3404 *
3405 * @return estimated mean square error respect to provided measurements.
3406 */
3407 @Override
3408 public double getEstimatedMse() {
3409 return estimatedMse;
3410 }
3411
3412 /**
3413 * Gets estimated probability of finding a smaller chi square value expressed as a value between 0.0 and 1.0. The
3414 * smaller the found chi square value is, the better the fit of the estimated parameters to the actual parameter.
3415 * Thus, the smaller the chance of finding a smaller chi square value, then the better the estimated fit is.
3416 *
3417 * @return estimated probability of finding a smaller chi square value.
3418 */
3419 @Override
3420 public double getEstimatedP() {
3421 return estimatedP;
3422 }
3423
3424 /**
3425 * Gets estimated measure of quality of estimated fit as a value between 0.0 and 1.0. The larger the quality value
3426 * is, the better the fit that has been estimated.
3427 *
3428 * @return estimated measure of quality of estimated fit.
3429 */
3430 @Override
3431 public double getEstimatedQ() {
3432 return estimatedQ;
3433 }
3434
3435 /**
3436 * Gets variance of estimated x coordinate of accelerometer bias expressed in (m^2/s^4).
3437 *
3438 * @return variance of estimated x coordinate of accelerometer bias or null if not available.
3439 */
3440 public Double getEstimatedBiasFxVariance() {
3441 return estimatedCovariance != null ? estimatedCovariance.getElementAt(0, 0) : null;
3442 }
3443
3444 /**
3445 * Gets standard deviation of estimated x coordinate of accelerometer bias expressed in
3446 * meters per squared second (m/s^2).
3447 *
3448 * @return standard deviation of estimated x coordinate of accelerometer bias or null if not
3449 * available.
3450 */
3451 public Double getEstimatedBiasFxStandardDeviation() {
3452 final var variance = getEstimatedBiasFxVariance();
3453 return variance != null ? Math.sqrt(variance) : null;
3454 }
3455
3456 /**
3457 * Gets standard deviation of estimated x coordinate of accelerometer bias.
3458 *
3459 * @return standard deviation of estimated x coordinate of accelerometer bias or null if not
3460 * available.
3461 */
3462 public Acceleration getEstimatedBiasFxStandardDeviationAsAcceleration() {
3463 return estimatedCovariance != null
3464 ? new Acceleration(getEstimatedBiasFxStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
3465 : null;
3466 }
3467
3468 /**
3469 * Gets standard deviation of estimated x coordinate of accelerometer bias.
3470 *
3471 * @param result instance where result will be stored.
3472 * @return true if standard deviation of estimated x coordinate of accelerometer bias is available,
3473 * false otherwise.
3474 */
3475 public boolean getEstimatedBiasFxStandardDeviationAsAcceleration(final Acceleration result) {
3476 if (estimatedCovariance != null) {
3477 result.setValue(getEstimatedBiasFxStandardDeviation());
3478 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3479 return true;
3480 } else {
3481 return false;
3482 }
3483 }
3484
3485 /**
3486 * Gets variance of estimated y coordinate of accelerometer bias expressed in (m^2/s^4).
3487 *
3488 * @return variance of estimated y coordinate of accelerometer bias or null if not available.
3489 */
3490 public Double getEstimatedBiasFyVariance() {
3491 return estimatedCovariance != null ? estimatedCovariance.getElementAt(1, 1) : null;
3492 }
3493
3494 /**
3495 * Gets standard deviation of estimated y coordinate of accelerometer bias expressed in
3496 * meters per squared second (m/s^2).
3497 *
3498 * @return standard deviation of estimated y coordinate of accelerometer bias or null if not
3499 * available.
3500 */
3501 public Double getEstimatedBiasFyStandardDeviation() {
3502 final var variance = getEstimatedBiasFyVariance();
3503 return variance != null ? Math.sqrt(variance) : null;
3504 }
3505
3506 /**
3507 * Gets standard deviation of estimated y coordinate of accelerometer bias.
3508 *
3509 * @return standard deviation of estimated y coordinate of accelerometer bias or null if not
3510 * available.
3511 */
3512 public Acceleration getEstimatedBiasFyStandardDeviationAsAcceleration() {
3513 return estimatedCovariance != null
3514 ? new Acceleration(getEstimatedBiasFyStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
3515 : null;
3516 }
3517
3518 /**
3519 * Gets standard deviation of estimated y coordinate of accelerometer bias.
3520 *
3521 * @param result instance where result will be stored.
3522 * @return true if standard deviation of estimated y coordinate of accelerometer bias is available,
3523 * false otherwise.
3524 */
3525 public boolean getEstimatedBiasFyStandardDeviationAsAcceleration(final Acceleration result) {
3526 if (estimatedCovariance != null) {
3527 result.setValue(getEstimatedBiasFyStandardDeviation());
3528 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3529 return true;
3530 } else {
3531 return false;
3532 }
3533 }
3534
3535 /**
3536 * Gets variance of estimated z coordinate of accelerometer bias expressed in (m^2/s^4).
3537 *
3538 * @return variance of estimated z coordinate of accelerometer bias or null if not available.
3539 */
3540 public Double getEstimatedBiasFzVariance() {
3541 return estimatedCovariance != null ? estimatedCovariance.getElementAt(2, 2) : null;
3542 }
3543
3544 /**
3545 * Gets standard deviation of estimated z coordinate of accelerometer bias expressed in
3546 * meters per squared second (m/s^2).
3547 *
3548 * @return standard deviation of estimated z coordinate of accelerometer bias or null if not
3549 * available.
3550 */
3551 public Double getEstimatedBiasFzStandardDeviation() {
3552 final var variance = getEstimatedBiasFzVariance();
3553 return variance != null ? Math.sqrt(variance) : null;
3554 }
3555
3556 /**
3557 * Gets standard deviation of estimated z coordinate of accelerometer bias.
3558 *
3559 * @return standard deviation of estimated z coordinate of accelerometer bias or null if not
3560 * available.
3561 */
3562 public Acceleration getEstimatedBiasFzStandardDeviationAsAcceleration() {
3563 return estimatedCovariance != null
3564 ? new Acceleration(getEstimatedBiasFzStandardDeviation(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
3565 : null;
3566 }
3567
3568 /**
3569 * Gets standard deviation of estimated z coordinate of accelerometer bias.
3570 *
3571 * @param result instance where result will be stored.
3572 * @return true if standard deviation of estimated z coordinate of accelerometer bias is available,
3573 * false otherwise.
3574 */
3575 public boolean getEstimatedBiasFzStandardDeviationAsAcceleration(final Acceleration result) {
3576 if (estimatedCovariance != null) {
3577 result.setValue(getEstimatedBiasFzStandardDeviation());
3578 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3579 return true;
3580 } else {
3581 return false;
3582 }
3583 }
3584
3585 /**
3586 * Gets standard deviation of estimated accelerometer bias coordinates.
3587 *
3588 * @return standard deviation of estimated accelerometer bias coordinates.
3589 */
3590 public AccelerationTriad getEstimatedBiasStandardDeviation() {
3591 return estimatedCovariance != null
3592 ? new AccelerationTriad(AccelerationUnit.METERS_PER_SQUARED_SECOND,
3593 getEstimatedBiasFxStandardDeviation(),
3594 getEstimatedBiasFyStandardDeviation(),
3595 getEstimatedBiasFzStandardDeviation())
3596 : null;
3597 }
3598
3599 /**
3600 * Gets standard deviation of estimated accelerometer bias coordinates.
3601 *
3602 * @param result instance where result will be stored.
3603 * @return true if standard deviation of accelerometer bias was available, false
3604 * otherwise.
3605 */
3606 public boolean getEstimatedBiasStandardDeviation(final AccelerationTriad result) {
3607 if (estimatedCovariance != null) {
3608 result.setValueCoordinatesAndUnit(
3609 getEstimatedBiasFxStandardDeviation(),
3610 getEstimatedBiasFyStandardDeviation(),
3611 getEstimatedBiasFzStandardDeviation(),
3612 AccelerationUnit.METERS_PER_SQUARED_SECOND);
3613 return true;
3614 } else {
3615 return false;
3616 }
3617 }
3618
3619 /**
3620 * Gets average of estimated standard deviation of accelerometer bias coordinates expressed
3621 * in meters per squared second (m/s^2).
3622 *
3623 * @return average of estimated standard deviation of accelerometer bias coordinates or null
3624 * if not available.
3625 */
3626 public Double getEstimatedBiasStandardDeviationAverage() {
3627 return estimatedCovariance != null
3628 ? (getEstimatedBiasFxStandardDeviation() + getEstimatedBiasFyStandardDeviation()
3629 + getEstimatedBiasFzStandardDeviation()) / 3.0 : null;
3630 }
3631
3632 /**
3633 * Gets average of estimated standard deviation of accelerometer bias coordinates.
3634 *
3635 * @return average of estimated standard deviation of accelerometer bias coordinates or null.
3636 */
3637 public Acceleration getEstimatedBiasStandardDeviationAverageAsAcceleration() {
3638 return estimatedCovariance != null
3639 ? new Acceleration(getEstimatedBiasStandardDeviationAverage(),
3640 AccelerationUnit.METERS_PER_SQUARED_SECOND)
3641 : null;
3642 }
3643
3644 /**
3645 * Gets average of estimated standard deviation of accelerometer bias coordinates.
3646 *
3647 * @param result instance where result will be stored.
3648 * @return true if average of estimated standard deviation of accelerometer bias is available,
3649 * false otherwise.
3650 */
3651 public boolean getEstimatedBiasStandardDeviationAverageAsAcceleration(final Acceleration result) {
3652 if (estimatedCovariance != null) {
3653 result.setValue(getEstimatedBiasStandardDeviationAverage());
3654 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3655 return true;
3656 } else {
3657 return false;
3658 }
3659 }
3660
3661 /**
3662 * Gets norm of estimated standard deviation of accelerometer bias expressed in
3663 * meters per squared second (m/s^2).
3664 * This can be used as the initial accelerometer bias uncertainty for
3665 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3666 *
3667 * @return norm of estimated standard deviation of accelerometer bias or null
3668 * if not available.
3669 */
3670 @Override
3671 public Double getEstimatedBiasStandardDeviationNorm() {
3672 return estimatedCovariance != null
3673 ? Math.sqrt(getEstimatedBiasFxVariance() + getEstimatedBiasFyVariance() + getEstimatedBiasFzVariance())
3674 : null;
3675 }
3676
3677 /**
3678 * Gets norm of estimated standard deviation of accelerometer bias.
3679 * This can be used as the initial accelerometer bias uncertainty for
3680 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3681 *
3682 * @return norm of estimated standard deviation of accelerometer bias or null
3683 * if not available.
3684 */
3685 public Acceleration getEstimatedBiasStandardDeviationNormAsAcceleration() {
3686 return estimatedCovariance != null
3687 ? new Acceleration(getEstimatedBiasStandardDeviationNorm(), AccelerationUnit.METERS_PER_SQUARED_SECOND)
3688 : null;
3689 }
3690
3691 /**
3692 * Gets norm of estimated standard deviation of accelerometer bias coordinates.
3693 * This can be used as the initial accelerometer bias uncertainty for
3694 * {@link INSLooselyCoupledKalmanInitializerConfig} or {@link INSTightlyCoupledKalmanInitializerConfig}.
3695 *
3696 * @param result instance where result will be stored.
3697 * @return true if norm of estimated standard deviation of accelerometer bias is
3698 * available, false otherwise.
3699 */
3700 public boolean getEstimatedBiasStandardDeviationNormAsAcceleration(final Acceleration result) {
3701 if (estimatedCovariance != null) {
3702 result.setValue(getEstimatedBiasStandardDeviationNorm());
3703 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
3704 return true;
3705 } else {
3706 return false;
3707 }
3708 }
3709
3710 /**
3711 * Internal method to perform calibration when common z-axis is assumed for both
3712 * the accelerometer and gyroscope.
3713 *
3714 * @throws AlgebraException if there are numerical errors.
3715 * @throws FittingException if no convergence to solution is found.
3716 * @throws com.irurueta.numerical.NotReadyException if fitter is not ready.
3717 */
3718 private void calibrateCommonAxis() throws AlgebraException, FittingException,
3719 com.irurueta.numerical.NotReadyException {
3720 // The accelerometer model is:
3721 // fmeas = ba + (I + Ma) * ftrue + w
3722
3723 // Ideally a least squares solution tries to minimize noise component, so:
3724 // fmeas = ba + (I + Ma) * ftrue
3725
3726 // Hence:
3727 // [fmeasx] = [bx] + ( [1 0 0] + [sx mxy mxz]) [ftruex]
3728 // [fmeasy] = [by] [0 1 0] [myx sy myz] [ftruey]
3729 // [fmeasz] = [bz] [0 0 1] [mzx mzy sz ] [ftruez]
3730
3731 // where myx = mzx = mzy = 0
3732
3733 // Hence:
3734 // [fmeasx] = [bx] + ( [1 0 0] + [sx mxy mxz]) [ftruex]
3735 // [fmeasy] = [by] [0 1 0] [0 sy myz] [ftruey]
3736 // [fmeasz] = [bz] [0 0 1] [0 0 sz ] [ftruez]
3737
3738 // [fmeasx] = [bx] + [1+sx mxy mxz ][ftruex]
3739 // [fmeasy] [by] [0 1+sy myz ][ftruey]
3740 // [fmeasz] [bz] [0 0 1+sz][ftruez]
3741
3742 // fmeasx = bx + (1+sx) * ftruex + mxy * ftruey + mxz * ftruez
3743 // fmeasy = by + (1+sy) * ftruey + myz * ftruez
3744 // fmeasz = bz + (1+sz) * ftruez
3745
3746 // Where the unknowns are: bx, by, bz, sx, sy, sz, mxy mxz, myz
3747 // Reordering:
3748 // fmeasx = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez
3749 // fmeasy = by + ftruey + sy * ftruey + myz * ftruez
3750 // fmeasz = bz + ftruez + sz * ftruez
3751
3752 // fmeasx - ftruex = bx + sx * ftruex + mxy * ftruey + mxz * ftruez
3753 // fmeasy - ftruey = by + sy * ftruey + myz * ftruez
3754 // fmeasz - ftruez = bz + sz * ftruez
3755
3756 // [1 0 0 ftruex 0 0 ftruey ftruez 0 ][bx ] = [fmeasx - ftruex]
3757 // [0 1 0 0 ftruey 0 0 0 ftruez][by ] [fmeasy - ftruey]
3758 // [0 0 1 0 0 ftruez 0 0 0 ][bz ] [fmeasz - ftruez]
3759 // [sx ]
3760 // [sy ]
3761 // [sz ]
3762 // [mxy]
3763 // [mxz]
3764 // [myz]
3765
3766 fitter.setFunctionEvaluator(new LevenbergMarquardtMultiVariateFunctionEvaluator() {
3767 @Override
3768 public int getNumberOfDimensions() {
3769 // Input points are true specific force coordinates
3770 return BodyKinematics.COMPONENTS;
3771 }
3772
3773 @Override
3774 public int getNumberOfVariables() {
3775 // The multivariate function returns the components of measured specific force
3776 return BodyKinematics.COMPONENTS;
3777 }
3778
3779 @Override
3780 public double[] createInitialParametersArray() {
3781 final var initial = new double[COMMON_Z_AXIS_UNKNOWNS];
3782
3783 initial[0] = initialBiasX;
3784 initial[1] = initialBiasY;
3785 initial[2] = initialBiasZ;
3786
3787 initial[3] = initialSx;
3788 initial[4] = initialSy;
3789 initial[5] = initialSz;
3790
3791 initial[6] = initialMxy;
3792 initial[7] = initialMxz;
3793 initial[8] = initialMyz;
3794
3795 return initial;
3796 }
3797
3798 @Override
3799 public void evaluate(final int i, final double[] point, final double[] result, final double[] params,
3800 final Matrix jacobian) {
3801 // We know that:
3802 // fmeasx = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez
3803 // fmeasy = by + ftruey + sy * ftruey + myz * ftruez
3804 // fmeasz = bz + ftruez + sz * ftruez
3805
3806 // Hence, the derivatives respect the parameters bx, by, bz, sx, sy,
3807 // sz, mxy, mxz, myz
3808
3809 // d(fmeasx)/d(bx) = 1.0
3810 // d(fmeasx)/d(by) = 0.0
3811 // d(fmeasx)/d(bz) = 0.0
3812 // d(fmeasx)/d(sx) = ftruex
3813 // d(fmeasx)/d(sy) = 0.0
3814 // d(fmeasx)/d(sz) = 0.0
3815 // d(fmeasx)/d(mxy) = ftruey
3816 // d(fmeasx)/d(mxz) = ftruez
3817 // d(fmeasx)/d(myz) = 0.0
3818
3819 // d(fmeasy)/d(bx) = 0.0
3820 // d(fmeasy)/d(by) = 1.0
3821 // d(fmeasy)/d(bz) = 0.0
3822 // d(fmeasy)/d(sx) = 0.0
3823 // d(fmeasy)/d(sy) = ftruey
3824 // d(fmeasy)/d(sz) = 0.0
3825 // d(fmeasy)/d(mxy) = 0.0
3826 // d(fmeasy)/d(mxz) = 0.0
3827 // d(fmeasy)/d(myz) = ftruez
3828
3829 // d(fmeasz)/d(bx) = 0.0
3830 // d(fmeasz)/d(by) = 0.0
3831 // d(fmeasz)/d(bz) = 1.0
3832 // d(fmeasz)/d(sx) = 0.0
3833 // d(fmeasz)/d(sy) = 0.0
3834 // d(fmeasz)/d(sz) = ftruez
3835 // d(fmeasz)/d(mxy) = 0.0
3836 // d(fmeasz)/d(mxz) = 0.0
3837 // d(fmeasz)/d(myz) = 0.0
3838
3839 final var bx = params[0];
3840 final var by = params[1];
3841 final var bz = params[2];
3842
3843 final var sx = params[3];
3844 final var sy = params[4];
3845 final var sz = params[5];
3846
3847 final var mxy = params[6];
3848 final var mxz = params[7];
3849 final var myz = params[8];
3850
3851 final var ftruex = point[0];
3852 final var ftruey = point[1];
3853 final var ftruez = point[2];
3854
3855 result[0] = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez;
3856 result[1] = by + ftruey + sy * ftruey + myz * ftruez;
3857 result[2] = bz + ftruez + sz * ftruez;
3858
3859 jacobian.setElementAt(0, 0, 1.0);
3860 jacobian.setElementAt(0, 1, 0.0);
3861 jacobian.setElementAt(0, 2, 0.0);
3862 jacobian.setElementAt(0, 3, ftruex);
3863 jacobian.setElementAt(0, 4, 0.0);
3864 jacobian.setElementAt(0, 5, 0.0);
3865 jacobian.setElementAt(0, 6, ftruey);
3866 jacobian.setElementAt(0, 7, ftruez);
3867 jacobian.setElementAt(0, 8, 0.0);
3868
3869 jacobian.setElementAt(1, 0, 0.0);
3870 jacobian.setElementAt(1, 1, 1.0);
3871 jacobian.setElementAt(1, 2, 0.0);
3872 jacobian.setElementAt(1, 3, 0.0);
3873 jacobian.setElementAt(1, 4, ftruey);
3874 jacobian.setElementAt(1, 5, 0.0);
3875 jacobian.setElementAt(1, 6, 0.0);
3876 jacobian.setElementAt(1, 7, 0.0);
3877 jacobian.setElementAt(1, 8, ftruez);
3878
3879 jacobian.setElementAt(2, 0, 0.0);
3880 jacobian.setElementAt(2, 1, 0.0);
3881 jacobian.setElementAt(2, 2, 1.0);
3882 jacobian.setElementAt(2, 3, 0.0);
3883 jacobian.setElementAt(2, 4, 0.0);
3884 jacobian.setElementAt(2, 5, ftruez);
3885 jacobian.setElementAt(2, 6, 0.0);
3886 jacobian.setElementAt(2, 7, 0.0);
3887 jacobian.setElementAt(2, 8, 0.0);
3888 }
3889 });
3890
3891 setInputData();
3892
3893 fitter.fit();
3894
3895 final var result = fitter.getA();
3896
3897 final var bx = result[0];
3898 final var by = result[1];
3899 final var bz = result[2];
3900
3901 final var sx = result[3];
3902 final var sy = result[4];
3903 final var sz = result[5];
3904
3905 final var mxy = result[6];
3906 final var mxz = result[7];
3907 final var myz = result[8];
3908
3909 if (estimatedBiases == null) {
3910 estimatedBiases = new double[BodyKinematics.COMPONENTS];
3911 }
3912
3913 estimatedBiases[0] = bx;
3914 estimatedBiases[1] = by;
3915 estimatedBiases[2] = bz;
3916
3917 if (estimatedMa == null) {
3918 estimatedMa = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
3919 } else {
3920 estimatedMa.initialize(0.0);
3921 }
3922
3923 estimatedMa.setElementAt(0, 0, sx);
3924
3925 estimatedMa.setElementAt(0, 1, mxy);
3926 estimatedMa.setElementAt(1, 1, sy);
3927
3928 estimatedMa.setElementAt(0, 2, mxz);
3929 estimatedMa.setElementAt(1, 2, myz);
3930 estimatedMa.setElementAt(2, 2, sz);
3931
3932 estimatedCovariance = fitter.getCovar();
3933
3934 // propagate covariance matrix so that all parameters are taken into
3935 // account in the order: bx, by, bz, sx, sy, sz, mxy, mxz, myx,
3936 // myz, mzx, mzy.
3937
3938 // We define a lineal function mapping original parameters for the common
3939 // axis case to the general case
3940 // [bx'] = [1 0 0 0 0 0 0 0 0][bx]
3941 // [by'] [0 1 0 0 0 0 0 0 0][by]
3942 // [bz'] [0 0 1 0 0 0 0 0 0][bz]
3943 // [sx'] [0 0 0 1 0 0 0 0 0][sx]
3944 // [sy'] [0 0 0 0 1 0 0 0 0][sy]
3945 // [sz'] [0 0 0 0 0 1 0 0 0][sz]
3946 // [mxy'] [0 0 0 0 0 0 1 0 0][mxy]
3947 // [mxz'] [0 0 0 0 0 0 0 1 0][mxz]
3948 // [myx'] [0 0 0 0 0 0 0 0 0][myz]
3949 // [myz'] [0 0 0 0 0 0 0 0 1]
3950 // [mzx'] [0 0 0 0 0 0 0 0 0]
3951 // [mzy'] [0 0 0 0 0 0 0 0 0]
3952
3953 // As defined in com.irurueta.statistics.MultivariateNormalDist,
3954 // if we consider the jacobian of the lineal application the matrix shown
3955 // above, then covariance can be propagated as follows
3956 final var jacobian = Matrix.identity(GENERAL_UNKNOWNS, COMMON_Z_AXIS_UNKNOWNS);
3957 jacobian.setElementAt(8, 8, 0.0);
3958 jacobian.setElementAt(9, 8, 1.0);
3959 // propagated covariance is J * Cov * J'
3960 final var jacobianTrans = jacobian.transposeAndReturnNew();
3961 jacobian.multiply(estimatedCovariance);
3962 jacobian.multiply(jacobianTrans);
3963 estimatedCovariance = jacobian;
3964 estimatedChiSq = fitter.getChisq();
3965 estimatedChiSqDegreesOfFreedom = fitter.getChisqDegreesOfFreedom();
3966 estimatedReducedChiSq = fitter.getReducedChisq();
3967 estimatedMse = fitter.getMse();
3968 try {
3969 estimatedP = fitter.getP();
3970 estimatedQ = fitter.getQ();
3971 } catch (final MaxIterationsExceededException ignore) {
3972 // if numerical instabilities arise, we assume worst case (no fit at all)
3973 // probability of finding a smaller chi square value is 1.0
3974 // quality of fit is 0.0
3975 estimatedP = 1.0;
3976 estimatedQ = 0.0;
3977 }
3978 }
3979
3980 /**
3981 * Internal method to perform general calibration.
3982 *
3983 * @throws AlgebraException if there are numerical errors.
3984 * @throws FittingException if no convergence to solution is found.
3985 * @throws com.irurueta.numerical.NotReadyException if fitter is not ready.
3986 */
3987 private void calibrateGeneral() throws AlgebraException, FittingException,
3988 com.irurueta.numerical.NotReadyException {
3989 // The accelerometer model is:
3990 // fmeas = ba + (I + Ma) * ftrue + w
3991
3992 // Ideally a least squares solution tries to minimize noise component, so:
3993 // fmeas = ba + (I + Ma) * ftrue
3994
3995 // Hence:
3996 // [fmeasx] = [bx] + ( [1 0 0] + [sx mxy mxz]) [ftruex]
3997 // [fmeasy] = [by] [0 1 0] [myx sy myz] [ftruey]
3998 // [fmeasz] = [bz] [0 0 1] [mzx mzy sz ] [ftruez]
3999
4000 // [fmeasx] = [bx] + [1+sx mxy mxz ][ftruex]
4001 // [fmeasy] [by] [myx 1+sy myz ][ftruey]
4002 // [fmeasz] [bz] [mzx mzy 1+sz][ftruez]
4003
4004 // fmeasx = bx + (1+sx) * ftruex + mxy * ftruey + mxz * ftruez
4005 // fmeasy = by + myx * ftruex + (1+sy) * ftruey + myz * ftruez
4006 // fmeasz = bz + mzx * ftruex + mzy * ftruey + (1+sz) * ftruez
4007
4008 // Where the unknowns are: bx, by, bz, sx, sy, sz, mxy mxz, myx, myz, mzx, mzy
4009 // Reordering:
4010 // fmeasx = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez
4011 // fmeasy = by + myx * ftruex + ftruey + sy * ftruey + myz * ftruez
4012 // fmeasz = bz + mzx * ftruex + mzy * ftruey + ftruez + sz * ftruez
4013
4014 // fmeasx - ftruex = bx + sx * ftruex + mxy * ftruey + mxz * ftruez
4015 // fmeasy - ftruey = by + myx * ftruex + sy * ftruey + myz * ftruez
4016 // fmeasz - ftruez = bz + mzx * ftruex + mzy * ftruey + sz * ftruez
4017
4018 // [1 0 0 ftruex 0 0 ftruey ftruez 0 0 0 0 ][bx ] = [fmeasx - ftruex]
4019 // [0 1 0 0 ftruey 0 0 0 ftruex ftruez 0 0 ][by ] [fmeasy - ftruey]
4020 // [0 0 1 0 0 ftruez 0 0 0 0 ftruex ftruey][bz ] [fmeasz - ftruez]
4021 // [sx ]
4022 // [sy ]
4023 // [sz ]
4024 // [mxy]
4025 // [mxz]
4026 // [myx]
4027 // [myz]
4028 // [mzx]
4029 // [mzy]
4030
4031 fitter.setFunctionEvaluator(new LevenbergMarquardtMultiVariateFunctionEvaluator() {
4032 @Override
4033 public int getNumberOfDimensions() {
4034 // Input points are true specific force coordinates
4035 return BodyKinematics.COMPONENTS;
4036 }
4037
4038 @Override
4039 public int getNumberOfVariables() {
4040 // The multivariate function returns the components of measured specific force
4041 return BodyKinematics.COMPONENTS;
4042 }
4043
4044 @Override
4045 public double[] createInitialParametersArray() {
4046 final var initial = new double[GENERAL_UNKNOWNS];
4047
4048 initial[0] = initialBiasX;
4049 initial[1] = initialBiasY;
4050 initial[2] = initialBiasZ;
4051
4052 initial[3] = initialSx;
4053 initial[4] = initialSy;
4054 initial[5] = initialSz;
4055
4056 initial[6] = initialMxy;
4057 initial[7] = initialMxz;
4058 initial[8] = initialMyx;
4059 initial[9] = initialMyz;
4060 initial[10] = initialMzx;
4061 initial[11] = initialMzy;
4062
4063 return initial;
4064 }
4065
4066 @Override
4067 public void evaluate(final int i, final double[] point, final double[] result, final double[] params,
4068 final Matrix jacobian) {
4069 // We know that:
4070 // fmeasx = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez
4071 // fmeasy = by + myx * ftruex + ftruey + sy * ftruey + myz * ftruez
4072 // fmeasz = bz + mzx * ftruex + mzy * ftruey + ftruez + sz * ftruez
4073
4074 // Hence, the derivatives respect the parameters bx, by, bz, sx, sy,
4075 // sz, mxy, mxz, myx, myz, mzx and mzy is:
4076
4077 // d(fmeasx)/d(bx) = 1.0
4078 // d(fmeasx)/d(by) = 0.0
4079 // d(fmeasx)/d(bz) = 0.0
4080 // d(fmeasx)/d(sx) = ftruex
4081 // d(fmeasx)/d(sy) = 0.0
4082 // d(fmeasx)/d(sz) = 0.0
4083 // d(fmeasx)/d(mxy) = ftruey
4084 // d(fmeasx)/d(mxz) = ftruez
4085 // d(fmeasx)/d(myx) = 0.0
4086 // d(fmeasx)/d(myz) = 0.0
4087 // d(fmeasx)/d(mzx) = 0.0
4088 // d(fmeasx)/d(mzy) = 0.0
4089
4090 // d(fmeasy)/d(bx) = 0.0
4091 // d(fmeasy)/d(by) = 1.0
4092 // d(fmeasy)/d(bz) = 0.0
4093 // d(fmeasy)/d(sx) = 0.0
4094 // d(fmeasy)/d(sy) = ftruey
4095 // d(fmeasy)/d(sz) = 0.0
4096 // d(fmeasy)/d(mxy) = 0.0
4097 // d(fmeasy)/d(mxz) = 0.0
4098 // d(fmeasy)/d(myx) = ftruex
4099 // d(fmeasy)/d(myz) = ftruez
4100 // d(fmeasy)/d(mzx) = 0.0
4101 // d(fmeasy)/d(mzy) = 0.0
4102
4103 // d(fmeasz)/d(bx) = 0.0
4104 // d(fmeasz)/d(by) = 0.0
4105 // d(fmeasz)/d(bz) = 1.0
4106 // d(fmeasz)/d(sx) = 0.0
4107 // d(fmeasz)/d(sy) = 0.0
4108 // d(fmeasz)/d(sz) = ftruez
4109 // d(fmeasz)/d(mxy) = 0.0
4110 // d(fmeasz)/d(mxz) = 0.0
4111 // d(fmeasz)/d(myx) = 0.0
4112 // d(fmeasz)/d(myz) = 0.0
4113 // d(fmeasz)/d(mzx) = ftruex
4114 // d(fmeasz)/d(mzy) = ftruey
4115
4116 final var bx = params[0];
4117 final var by = params[1];
4118 final var bz = params[2];
4119
4120 final var sx = params[3];
4121 final var sy = params[4];
4122 final var sz = params[5];
4123
4124 final var mxy = params[6];
4125 final var mxz = params[7];
4126 final var myx = params[8];
4127 final var myz = params[9];
4128 final var mzx = params[10];
4129 final var mzy = params[11];
4130
4131 final var ftruex = point[0];
4132 final var ftruey = point[1];
4133 final var ftruez = point[2];
4134
4135 result[0] = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez;
4136 result[1] = by + myx * ftruex + ftruey + sy * ftruey + myz * ftruez;
4137 result[2] = bz + mzx * ftruex + mzy * ftruey + ftruez + sz * ftruez;
4138
4139 jacobian.setElementAt(0, 0, 1.0);
4140 jacobian.setElementAt(0, 1, 0.0);
4141 jacobian.setElementAt(0, 2, 0.0);
4142 jacobian.setElementAt(0, 3, ftruex);
4143 jacobian.setElementAt(0, 4, 0.0);
4144 jacobian.setElementAt(0, 5, 0.0);
4145 jacobian.setElementAt(0, 6, ftruey);
4146 jacobian.setElementAt(0, 7, ftruez);
4147 jacobian.setElementAt(0, 8, 0.0);
4148 jacobian.setElementAt(0, 9, 0.0);
4149 jacobian.setElementAt(0, 10, 0.0);
4150 jacobian.setElementAt(0, 11, 0.0);
4151
4152 jacobian.setElementAt(1, 0, 0.0);
4153 jacobian.setElementAt(1, 1, 1.0);
4154 jacobian.setElementAt(1, 2, 0.0);
4155 jacobian.setElementAt(1, 3, 0.0);
4156 jacobian.setElementAt(1, 4, ftruey);
4157 jacobian.setElementAt(1, 5, 0.0);
4158 jacobian.setElementAt(1, 6, 0.0);
4159 jacobian.setElementAt(1, 7, 0.0);
4160 jacobian.setElementAt(1, 8, ftruex);
4161 jacobian.setElementAt(1, 9, ftruez);
4162 jacobian.setElementAt(1, 10, 0.0);
4163 jacobian.setElementAt(1, 11, 0.0);
4164
4165 jacobian.setElementAt(2, 0, 0.0);
4166 jacobian.setElementAt(2, 1, 0.0);
4167 jacobian.setElementAt(2, 2, 1.0);
4168 jacobian.setElementAt(2, 3, 0.0);
4169 jacobian.setElementAt(2, 4, 0.0);
4170 jacobian.setElementAt(2, 5, ftruez);
4171 jacobian.setElementAt(2, 6, 0.0);
4172 jacobian.setElementAt(2, 7, 0.0);
4173 jacobian.setElementAt(2, 8, 0.0);
4174 jacobian.setElementAt(2, 9, 0.0);
4175 jacobian.setElementAt(2, 10, ftruex);
4176 jacobian.setElementAt(2, 11, ftruey);
4177 }
4178 });
4179
4180 setInputData();
4181
4182 fitter.fit();
4183
4184 final var result = fitter.getA();
4185
4186 final var bx = result[0];
4187 final var by = result[1];
4188 final var bz = result[2];
4189
4190 final var sx = result[3];
4191 final var sy = result[4];
4192 final var sz = result[5];
4193
4194 final var mxy = result[6];
4195 final var mxz = result[7];
4196 final var myx = result[8];
4197 final var myz = result[9];
4198 final var mzx = result[10];
4199 final var mzy = result[11];
4200
4201 if (estimatedBiases == null) {
4202 estimatedBiases = new double[BodyKinematics.COMPONENTS];
4203 }
4204
4205 estimatedBiases[0] = bx;
4206 estimatedBiases[1] = by;
4207 estimatedBiases[2] = bz;
4208
4209 if (estimatedMa == null) {
4210 estimatedMa = new Matrix(BodyKinematics.COMPONENTS, BodyKinematics.COMPONENTS);
4211 } else {
4212 estimatedMa.initialize(0.0);
4213 }
4214
4215 estimatedMa.setElementAt(0, 0, sx);
4216 estimatedMa.setElementAt(1, 0, myx);
4217 estimatedMa.setElementAt(2, 0, mzx);
4218
4219 estimatedMa.setElementAt(0, 1, mxy);
4220 estimatedMa.setElementAt(1, 1, sy);
4221 estimatedMa.setElementAt(2, 1, mzy);
4222
4223 estimatedMa.setElementAt(0, 2, mxz);
4224 estimatedMa.setElementAt(1, 2, myz);
4225 estimatedMa.setElementAt(2, 2, sz);
4226
4227 estimatedCovariance = fitter.getCovar();
4228 estimatedChiSq = fitter.getChisq();
4229 estimatedChiSqDegreesOfFreedom = fitter.getChisqDegreesOfFreedom();
4230 estimatedReducedChiSq = fitter.getReducedChisq();
4231 estimatedMse = fitter.getMse();
4232 try {
4233 estimatedP = fitter.getP();
4234 estimatedQ = fitter.getQ();
4235 } catch (final MaxIterationsExceededException ignore) {
4236 // if numerical instabilities arise, we assume worst case (no fit at all)
4237 // probability of finding a smaller chi square value is 1.0
4238 // quality of fit is 0.0
4239 estimatedP = 1.0;
4240 estimatedQ = 0.0;
4241 }
4242 }
4243
4244 /**
4245 * Sets input data into Levenberg-Marquardt fitter.
4246 *
4247 * @throws WrongSizeException never happens.
4248 */
4249 private void setInputData() throws WrongSizeException {
4250 // set input data using:
4251 // fmeasx = bx + ftruex + sx * ftruex + mxy * ftruey + mxz * ftruez
4252 // fmeasy = by + myx * ftruex + ftruey + sy * ftruey + myz * ftruez
4253 // fmeasz = bz + mzx * ftruex + mzy * ftruey + ftruez + sz * ftruez
4254
4255 final var expectedKinematics = new BodyKinematics();
4256
4257 final var numMeasurements = measurements.size();
4258 final var x = new Matrix(numMeasurements, BodyKinematics.COMPONENTS);
4259 final var y = new Matrix(numMeasurements, BodyKinematics.COMPONENTS);
4260 final var specificForceStandardDeviations = new double[numMeasurements];
4261 var i = 0;
4262 for (final var measurement : measurements) {
4263 final var measuredKinematics = measurement.getKinematics();
4264 final var ecefFrame = measurement.getFrame();
4265 final var previousEcefFrame = measurement.getPreviousFrame();
4266 final var timeInterval = measurement.getTimeInterval();
4267
4268 ECEFKinematicsEstimator.estimateKinematics(timeInterval, ecefFrame, previousEcefFrame, expectedKinematics);
4269
4270 final var fMeasX = measuredKinematics.getFx();
4271 final var fMeasY = measuredKinematics.getFy();
4272 final var fMeasZ = measuredKinematics.getFz();
4273
4274 final var fTrueX = expectedKinematics.getFx();
4275 final var fTrueY = expectedKinematics.getFy();
4276 final var fTrueZ = expectedKinematics.getFz();
4277
4278 x.setElementAt(i, 0, fTrueX);
4279 x.setElementAt(i, 1, fTrueY);
4280 x.setElementAt(i, 2, fTrueZ);
4281
4282 y.setElementAt(i, 0, fMeasX);
4283 y.setElementAt(i, 1, fMeasY);
4284 y.setElementAt(i, 2, fMeasZ);
4285
4286 specificForceStandardDeviations[i] = measurement.getSpecificForceStandardDeviation();
4287 i++;
4288 }
4289
4290 fitter.setInputData(x, y, specificForceStandardDeviations);
4291 }
4292
4293 /**
4294 * Converts acceleration value and unit to meters per squared second.
4295 *
4296 * @param value acceleration value.
4297 * @param unit unit of acceleration value.
4298 * @return converted value.
4299 */
4300 private static double convertAcceleration(final double value, final AccelerationUnit unit) {
4301 return AccelerationConverter.convert(value, unit, AccelerationUnit.METERS_PER_SQUARED_SECOND);
4302 }
4303
4304 /**
4305 * Converts acceleration instance to meters per squared second.
4306 *
4307 * @param acceleration acceleration instance to be converted.
4308 * @return converted value.
4309 */
4310 private static double convertAcceleration(final Acceleration acceleration) {
4311 return convertAcceleration(acceleration.getValue().doubleValue(), acceleration.getUnit());
4312 }
4313 }