1 /*
2 * Copyright (C) 2020 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.navigation.inertial.calibration;
17
18 import com.irurueta.units.Acceleration;
19 import com.irurueta.units.AccelerationConverter;
20 import com.irurueta.units.AccelerationUnit;
21
22 import java.io.Serial;
23 import java.io.Serializable;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Objects;
27
28 /**
29 * Contains a collection of items containing body kinematics
30 * measurements ordered by the timestamp when the measurement was made.
31 * Measurements within a sequence will be made while the device is
32 * being moved.
33 * Samples between sequences will be ignored because it will be assumed
34 * that the device will be static.
35 * Hence, during static periods, only the mean accelerations will be measured.
36 * The mean accelerations during static periods will approximately match the
37 * gravity versor expressed in body coordinates.
38 *
39 * @param <T> a type of {@link TimedBodyKinematics}.
40 */
41 public class BodyKinematicsSequence<T extends TimedBodyKinematics> implements Serializable, Cloneable {
42
43 /**
44 * Serialization version. This is used to ensure compatibility of deserialization of permanently stored serialized
45 * instances.
46 */
47 @Serial
48 private static final long serialVersionUID = 0L;
49
50 /**
51 * List of items.
52 * If items are provided unsorted, they are reordered by timestamp on
53 * getter method.
54 */
55 private ArrayList<T> items;
56
57 /**
58 * Contains sorted list of items.
59 * This list is kept for performance reasons to reduce the amount of
60 * required sorting.
61 */
62 private ArrayList<T> sortedItems;
63
64 /**
65 * X-coordinate of mean specific force during the static period happening
66 * right before this sequence was measured. Expressed in meters per
67 * squared second (m/s^2).
68 */
69 private double beforeMeanFx;
70
71 /**
72 * Y-coordinate of mean specific force during the static period happening
73 * right before this sequence was measured. Expressed in meters per
74 * squared second (m/s^2).
75 */
76 private double beforeMeanFy;
77
78 /**
79 * Z-coordinate of mean specific force during the static period happening
80 * right before this sequence was measured. Expressed in meters per
81 * squared second (m/s^2).
82 */
83 private double beforeMeanFz;
84
85 /**
86 * X-coordinate of mean specific force during the static period happening
87 * right after this sequence was measured. Expressed in meters per squared
88 * second (m/s^2).
89 */
90 private double afterMeanFx;
91
92 /**
93 * Y-coordinate of mean specific force during the static period happening
94 * right after this sequence was measured. Expressed in meters per squared
95 * second (m/s^2).
96 */
97 private double afterMeanFy;
98
99 /**
100 * Z-coordinate of mean specific force during the static period happening
101 * right after this sequence was measured. Expressed in meters per squared
102 * second (m/s^2).
103 */
104 private double afterMeanFz;
105
106 /**
107 * Constructor.
108 */
109 public BodyKinematicsSequence() {
110 }
111
112 /**
113 * Constructor.
114 *
115 * @param items list of items containing body kinematics to be kept into
116 * this sequence.
117 */
118 public BodyKinematicsSequence(final List<T> items) {
119 setItems(items);
120 }
121
122 /**
123 * Constructor.
124 *
125 * @param beforeMeanFx x-coordinate of mean specific force during the static
126 * period happening right before this sequence was measured.
127 * Expressed in meters per squared second (m/s^2).
128 * @param beforeMeanFy y-coordinate of mean specific force during the static
129 * period happening right before this sequence was measured.
130 * Expressed in meters per squared second (m/s^2).
131 * @param beforeMeanFz z-coordinate of mean specific force during the static
132 * period happening right before this sequence was measured.
133 * Expressed in meters per squared second (m/s^2).
134 * @param afterMeanFx x-coordinate of mean specific force during the static
135 * period happening right after this sequence was measured.
136 * Expressed in meters per squared second (m/s^2).
137 * @param afterMeanFy y-coordinate of mean specific force during the static
138 * period happening right after this sequence was measured.
139 * Expressed in meters per squared second (m/s^2).
140 * @param afterMeanFz z-coordinate of mean specific force during the static
141 * period happening right after this sequence was measured.
142 * Expressed in meters per squared second (m/s^2).
143 */
144 public BodyKinematicsSequence(
145 final double beforeMeanFx, final double beforeMeanFy, final double beforeMeanFz,
146 final double afterMeanFx, final double afterMeanFy, final double afterMeanFz) {
147 setBeforeMeanSpecificForceCoordinates(beforeMeanFx, beforeMeanFy, beforeMeanFz);
148 setAfterMeanSpecificForceCoordinates(afterMeanFx, afterMeanFy, afterMeanFz);
149 }
150
151 /**
152 * Constructor.
153 *
154 * @param beforeMeanSpecificForceX x-coordinate of mean specific force during
155 * the static period happening right before this
156 * sequence was measured.
157 * @param beforeMeanSpecificForceY y-coordinate of mean specific force during
158 * the static period happening right before this
159 * sequence was measured.
160 * @param beforeMeanSpecificForceZ z-coordinate of mean specific force during
161 * the static period happening right before this
162 * sequence was measured.
163 * @param afterMeanSpecificForceX x-coordinate of mean specific force during
164 * the static period happening right after this
165 * sequence was measured.
166 * @param afterMeanSpecificForceY y-coordinate of mean specific force during
167 * the static period happening right after this
168 * sequence was measured.
169 * @param afterMeanSpecificForceZ z-coordinate of mean specific force during
170 * the static period happening right after this
171 * sequence was measured.
172 */
173 public BodyKinematicsSequence(
174 final Acceleration beforeMeanSpecificForceX,
175 final Acceleration beforeMeanSpecificForceY,
176 final Acceleration beforeMeanSpecificForceZ,
177 final Acceleration afterMeanSpecificForceX,
178 final Acceleration afterMeanSpecificForceY,
179 final Acceleration afterMeanSpecificForceZ) {
180 setBeforeMeanSpecificForceCoordinates(
181 beforeMeanSpecificForceX, beforeMeanSpecificForceY, beforeMeanSpecificForceZ);
182 setAfterMeanSpecificForceCoordinates(
183 afterMeanSpecificForceX, afterMeanSpecificForceY, afterMeanSpecificForceZ);
184 }
185
186 /**
187 * @param items list of items containing body kinematics to be kept into
188 * this sequence.
189 * @param beforeMeanFx x-coordinate of mean specific force during the static
190 * period happening right before this sequence was measured.
191 * Expressed in meters per squared second (m/s^2).
192 * @param beforeMeanFy y-coordinate of mean specific force during the static
193 * period happening right before this sequence was measured.
194 * Expressed in meters per squared second (m/s^2).
195 * @param beforeMeanFz z-coordinate of mean specific force during the static
196 * period happening right before this sequence was measured.
197 * Expressed in meters per squared second (m/s^2).
198 * @param afterMeanFx x-coordinate of mean specific force during the static
199 * period happening right after this sequence was measured.
200 * Expressed in meters per squared second (m/s^2).
201 * @param afterMeanFy y-coordinate of mean specific force during the static
202 * period happening right after this sequence was measured.
203 * Expressed in meters per squared second (m/s^2).
204 * @param afterMeanFz z-coordinate of mean specific force during the static
205 * period happening right after this sequence was measured.
206 * Expressed in meters per squared second (m/s^2).
207 */
208 public BodyKinematicsSequence(
209 final List<T> items, final double beforeMeanFx, final double beforeMeanFy, final double beforeMeanFz,
210 final double afterMeanFx, final double afterMeanFy, final double afterMeanFz) {
211 this(items);
212 setBeforeMeanSpecificForceCoordinates(beforeMeanFx, beforeMeanFy, beforeMeanFz);
213 setAfterMeanSpecificForceCoordinates(afterMeanFx, afterMeanFy, afterMeanFz);
214 }
215
216 /**
217 * Constructor.
218 *
219 * @param items list of items containing body kinematics to be kept into
220 * this sequence.
221 * @param beforeMeanSpecificForceX x-coordinate of mean specific force during
222 * the static period happening right before this
223 * sequence was measured.
224 * @param beforeMeanSpecificForceY y-coordinate of mean specific force during
225 * the static period happening right before this
226 * sequence was measured.
227 * @param beforeMeanSpecificForceZ z-coordinate of mean specific force during
228 * the static period happening right before this
229 * sequence was measured.
230 * @param afterMeanSpecificForceX x-coordinate of mean specific force during
231 * the static period happening right after this
232 * sequence was measured.
233 * @param afterMeanSpecificForceY y-coordinate of mean specific force during
234 * the static period happening right after this
235 * sequence was measured.
236 * @param afterMeanSpecificForceZ z-coordinate of mean specific force during
237 * the static period happening right after this
238 * sequence was measured.
239 */
240 public BodyKinematicsSequence(
241 final List<T> items,
242 final Acceleration beforeMeanSpecificForceX,
243 final Acceleration beforeMeanSpecificForceY,
244 final Acceleration beforeMeanSpecificForceZ,
245 final Acceleration afterMeanSpecificForceX,
246 final Acceleration afterMeanSpecificForceY,
247 final Acceleration afterMeanSpecificForceZ) {
248 this(items);
249 setBeforeMeanSpecificForceCoordinates(
250 beforeMeanSpecificForceX, beforeMeanSpecificForceY, beforeMeanSpecificForceZ);
251 setAfterMeanSpecificForceCoordinates(
252 afterMeanSpecificForceX, afterMeanSpecificForceY, afterMeanSpecificForceZ);
253 }
254
255 /**
256 * Constructor.
257 *
258 * @param input instance to copy data from.
259 */
260 public BodyKinematicsSequence(final BodyKinematicsSequence<T> input) {
261 copyFrom(input);
262 }
263
264 /**
265 * Gets items in this sequence ordered by ascending timestamp.
266 *
267 * @param result instance where sorted items will be stored.
268 * @return true if sorted items could be retrieved, false if no items
269 * are available.
270 */
271 public boolean getSortedItems(final List<T> result) {
272 // already sorted items are available.
273 if (sortedItems != null) {
274 result.clear();
275 result.addAll(sortedItems);
276 return true;
277 }
278
279 if (items != null) {
280 sortedItems = new ArrayList<>(items);
281 sortedItems.sort((o1, o2) -> {
282 final var t1 = o1.getTimestampSeconds();
283 final var t2 = o2.getTimestampSeconds();
284 return Double.compare(t1, t2);
285 });
286
287 result.clear();
288 result.addAll(sortedItems);
289 return true;
290 }
291
292 return false;
293 }
294
295 /**
296 * Gets items in this sequence ordered by ascending timestamp.
297 *
298 * @return a new list containing sorted items or null if sorted items
299 * could not be retrieved..
300 */
301 public List<T> getSortedItems() {
302 final var result = new ArrayList<T>();
303 if (getSortedItems(result)) {
304 return result;
305 } else {
306 return null;
307 }
308 }
309
310 /**
311 * Sets list of items containing body kinematics to be kept into this
312 * sequence.
313 *
314 * @param items items to be kept.
315 */
316 public void setItems(final List<T> items) {
317 if (items instanceof ArrayList) {
318 this.items = (ArrayList<T>) items;
319 } else {
320 this.items = new ArrayList<>(items);
321 }
322 sortedItems = null;
323 }
324
325 /**
326 * Gets number of items in this sequence.
327 *
328 * @return number of items in this sequence.
329 */
330 public int getItemsCount() {
331 return items != null ? items.size() : 0;
332 }
333
334 /**
335 * Gets x-coordinate of mean specific force during the static period
336 * happening right before this sequence was measured. Expressed in
337 * meters per squared second (m/s^2).
338 *
339 * @return x-coordinate of mean specific force.
340 */
341 public double getBeforeMeanFx() {
342 return beforeMeanFx;
343 }
344
345 /**
346 * Sets x-coordinate of mean specific force during the static period
347 * happening right before this sequence was measured. Expressed in
348 * meters per squared second (m/s^2).
349 *
350 * @param beforeMeanFx x-coordinate of mean specific force.
351 */
352 public void setBeforeMeanFx(final double beforeMeanFx) {
353 this.beforeMeanFx = beforeMeanFx;
354 }
355
356 /**
357 * Gets y-coordinate of mean specific force during the static period
358 * happening right before this sequence was measured. Expressed in
359 * meters per squared second (m/s^2).
360 *
361 * @return y-coordinate of mean specific force.
362 */
363 public double getBeforeMeanFy() {
364 return beforeMeanFy;
365 }
366
367 /**
368 * Sets y-coordinate of mean specific force during the static period
369 * happening right before this sequence was measured. Expressed in
370 * meters per squared second (m/s^2).
371 *
372 * @param beforeMeanFy y-coordinate of mean specific force.
373 */
374 public void setBeforeMeanFy(final double beforeMeanFy) {
375 this.beforeMeanFy = beforeMeanFy;
376 }
377
378 /**
379 * Gets z-coordinate of mean specific force during the static period
380 * happening right before this sequence was measured. Expressed in
381 * meters per squared second (m/s^2).
382 *
383 * @return z-coordinate of mean specific force.
384 */
385 public double getBeforeMeanFz() {
386 return beforeMeanFz;
387 }
388
389 /**
390 * Sets z-coordinate of mean specific force during the static period
391 * happening right before this sequence was measured. Expressed in
392 * meters per squared second (m/s^2).
393 *
394 * @param beforeMeanFz z-coordinate of mean specific force.
395 */
396 public void setBeforeMeanFz(final double beforeMeanFz) {
397 this.beforeMeanFz = beforeMeanFz;
398 }
399
400 /**
401 * Sets coordinates of mean specific force during the static period
402 * happening right before this sequence was measured. Expressed in
403 * meters per squared second (m/s^2).
404 *
405 * @param beforeMeanFx x-coordinate of mean specific force.
406 * @param beforeMeanFy y-coordinate of mean specific force.
407 * @param beforeMeanFz z-coordinate of mean specific force.
408 */
409 public void setBeforeMeanSpecificForceCoordinates(
410 final double beforeMeanFx, final double beforeMeanFy, final double beforeMeanFz) {
411 this.beforeMeanFx = beforeMeanFx;
412 this.beforeMeanFy = beforeMeanFy;
413 this.beforeMeanFz = beforeMeanFz;
414 }
415
416 /**
417 * Gets x-coordinate of mean specific force during the static period
418 * happening right before this sequence was measured.
419 *
420 * @param result x-coordinate of mean specific force.
421 */
422 public void getBeforeMeanSpecificForceX(final Acceleration result) {
423 result.setValue(beforeMeanFx);
424 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
425 }
426
427 /**
428 * Gets x-coordinate of mean specific force during the static period
429 * happening right before this sequence was measured.
430 *
431 * @return x-coordinate of mean specific force.
432 */
433 public Acceleration getBeforeMeanSpecificForceX() {
434 return new Acceleration(beforeMeanFx, AccelerationUnit.METERS_PER_SQUARED_SECOND);
435 }
436
437 /**
438 * Sets x-coordinate of mean specific force during the static period
439 * happening right before this sequence was measured.
440 *
441 * @param beforeMeanSpecificForceX x-coordinate of mean specific force.
442 */
443 public void setBeforeMeanSpecificForceX(final Acceleration beforeMeanSpecificForceX) {
444 beforeMeanFx = convertAcceleration(beforeMeanSpecificForceX);
445 }
446
447 /**
448 * Gets y-coordinate of mean specific force during the static period
449 * happening right before this sequence was measured.
450 *
451 * @param result y-coordinate of mean specific force.
452 */
453 public void getBeforeMeanSpecificForceY(final Acceleration result) {
454 result.setValue(beforeMeanFy);
455 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
456 }
457
458 /**
459 * Gets y-coordinate of mean specific force during the static period
460 * happening right before this sequence was measured.
461 *
462 * @return y-coordinate of mean specific force.
463 */
464 public Acceleration getBeforeMeanSpecificForceY() {
465 return new Acceleration(beforeMeanFy, AccelerationUnit.METERS_PER_SQUARED_SECOND);
466 }
467
468 /**
469 * Sets y-coordinate of mean specific force during the static period
470 * happening right before this sequence was measured.
471 *
472 * @param beforeMeanSpecificForceY y-coordinate of mean specific force.
473 */
474 public void setBeforeMeanSpecificForceY(final Acceleration beforeMeanSpecificForceY) {
475 beforeMeanFy = convertAcceleration(beforeMeanSpecificForceY);
476 }
477
478 /**
479 * Gets z-coordinate of mean specific force during the static period
480 * happening right before this sequence was measured.
481 *
482 * @param result z-coordinate of mean specific force.
483 */
484 public void getBeforeMeanSpecificForceZ(final Acceleration result) {
485 result.setValue(beforeMeanFz);
486 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
487 }
488
489 /**
490 * Gets z-coordinate of mean specific force during the static period
491 * happening right before this sequence was measured.
492 *
493 * @return z-coordinate of mean specific force.
494 */
495 public Acceleration getBeforeMeanSpecificForceZ() {
496 return new Acceleration(beforeMeanFz, AccelerationUnit.METERS_PER_SQUARED_SECOND);
497 }
498
499 /**
500 * Sets z-coordinate of mean specific force during the static period
501 * happening right before this sequence was measured.
502 *
503 * @param beforeMeanSpecificForceZ z-coordinate of mean specific force.
504 */
505 public void setBeforeMeanSpecificForceZ(final Acceleration beforeMeanSpecificForceZ) {
506 beforeMeanFz = convertAcceleration(beforeMeanSpecificForceZ);
507 }
508
509 /**
510 * Sets coordinates of mean specific force during the static period
511 * happening right before this sequence was measured.
512 *
513 * @param beforeMeanSpecificForceX x-coordinate of mean specific force.
514 * @param beforeMeanSpecificForceY y-coordinate of mean specific force.
515 * @param beforeMeanSpecificForceZ z-coordinate of mean specific force.
516 */
517 public void setBeforeMeanSpecificForceCoordinates(
518 final Acceleration beforeMeanSpecificForceX, final Acceleration beforeMeanSpecificForceY,
519 final Acceleration beforeMeanSpecificForceZ) {
520 setBeforeMeanSpecificForceX(beforeMeanSpecificForceX);
521 setBeforeMeanSpecificForceY(beforeMeanSpecificForceY);
522 setBeforeMeanSpecificForceZ(beforeMeanSpecificForceZ);
523 }
524
525 /**
526 * Gets x-coordinate of mean specific force during the static period
527 * happening right after this sequence was measured. Expressed in
528 * meters per squared second (m/s^2).
529 *
530 * @return x-coordinate of mean specific force.
531 */
532 public double getAfterMeanFx() {
533 return afterMeanFx;
534 }
535
536 /**
537 * Sets x-coordinate of mean specific force during the static period
538 * happening right after this sequence was measured. Expressed in
539 * meters per squared second (m/s^2).
540 *
541 * @param afterMeanFx x-coordinate of mean specific force.
542 */
543 public void setAfterMeanFx(final double afterMeanFx) {
544 this.afterMeanFx = afterMeanFx;
545 }
546
547 /**
548 * Gets y-coordinate of mean specific force during the static period
549 * happening right after this sequence was measured. Expressed in
550 * meters per squared second (m/s^2).
551 *
552 * @return y-coordinate of mean specific force.
553 */
554 public double getAfterMeanFy() {
555 return afterMeanFy;
556 }
557
558 /**
559 * Sets y-coordinate of mean specific force during the static period
560 * happening right after this sequence was measured. Expressed in
561 * meters per squared second (m/s^2).
562 *
563 * @param afterMeanFy y-coordinate of mean specific force.
564 */
565 public void setAfterMeanFy(final double afterMeanFy) {
566 this.afterMeanFy = afterMeanFy;
567 }
568
569 /**
570 * Gets z-coordinate of mean specific force during the static period
571 * happening right after this sequence was measured. Expressed in
572 * meters per squared second (m/s^2).
573 *
574 * @return z-coordinate of mean specific force.
575 */
576 public double getAfterMeanFz() {
577 return afterMeanFz;
578 }
579
580 /**
581 * Sets z-coordinate of mean specific force during the static period
582 * happening right after this sequence was measured. Expressed in
583 * meters per squared second (m/s^2).
584 *
585 * @param afterMeanFz z-coordinate of mean specific force.
586 */
587 public void setAfterMeanFz(final double afterMeanFz) {
588 this.afterMeanFz = afterMeanFz;
589 }
590
591 /**
592 * Sets coordinates of mean specific force during the static period
593 * happening right after this sequence was measured. Expressed in
594 * meters per squared second (m/s^2).
595 *
596 * @param afterMeanFx x-coordinate of mean specific force.
597 * @param afterMeanFy y-coordinate of mean specific force.
598 * @param afterMeanFz z-coordinate of mean specific force.
599 */
600 public void setAfterMeanSpecificForceCoordinates(
601 final double afterMeanFx, final double afterMeanFy, final double afterMeanFz) {
602 this.afterMeanFx = afterMeanFx;
603 this.afterMeanFy = afterMeanFy;
604 this.afterMeanFz = afterMeanFz;
605 }
606
607 /**
608 * Gets x-coordinate of mean specific force during the static period
609 * happening right after this sequence was measured.
610 *
611 * @param result x-coordinate of mean specific force.
612 */
613 public void getAfterMeanSpecificForceX(final Acceleration result) {
614 result.setValue(afterMeanFx);
615 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
616 }
617
618 /**
619 * Gets x-coordinate of mean specific force during the static period
620 * happening right after this sequence was measured.
621 *
622 * @return x-coordinate of mean specific force.
623 */
624 public Acceleration getAfterMeanSpecificForceX() {
625 return new Acceleration(afterMeanFx, AccelerationUnit.METERS_PER_SQUARED_SECOND);
626 }
627
628 /**
629 * Sets x-coordinate of mean specific force during the static period
630 * happening right after this sequence was measured.
631 *
632 * @param afterMeanSpecificForceX x-coordinate of mean specific force.
633 */
634 public void setAfterMeanSpecificForceX(final Acceleration afterMeanSpecificForceX) {
635 afterMeanFx = convertAcceleration(afterMeanSpecificForceX);
636 }
637
638 /**
639 * Gets y-coordinate of mean specific force during the static period
640 * happening right after this sequence was measured.
641 *
642 * @param result y-coordinate of mean specific force.
643 */
644 public void getAfterMeanSpecificForceY(final Acceleration result) {
645 result.setValue(afterMeanFy);
646 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
647 }
648
649 /**
650 * Gets y-coordinate of mean specific force during the static period
651 * happening right after this sequence was measured.
652 *
653 * @return y-coordinate of mean specific force.
654 */
655 public Acceleration getAfterMeanSpecificForceY() {
656 return new Acceleration(afterMeanFy, AccelerationUnit.METERS_PER_SQUARED_SECOND);
657 }
658
659 /**
660 * Sets y-coordinate of mean specific force during the static period
661 * happening right after this sequence was measured.
662 *
663 * @param afterMeanSpecificForceY y-coordinate of mean specific force.
664 */
665 public void setAfterMeanSpecificForceY(final Acceleration afterMeanSpecificForceY) {
666 afterMeanFy = convertAcceleration(afterMeanSpecificForceY);
667 }
668
669 /**
670 * Gets z-coordinate of mean specific force during the static period
671 * happening right after this sequence was measured.
672 *
673 * @param result z-coordinate of mean specific force.
674 */
675 public void getAfterMeanSpecificForceZ(final Acceleration result) {
676 result.setValue(afterMeanFz);
677 result.setUnit(AccelerationUnit.METERS_PER_SQUARED_SECOND);
678 }
679
680 /**
681 * Gets z-coordinate of mean specific force during the static period
682 * happening right after this sequence was measured.
683 *
684 * @return z-coordinate of mean specific force.
685 */
686 public Acceleration getAfterMeanSpecificForceZ() {
687 return new Acceleration(afterMeanFz, AccelerationUnit.METERS_PER_SQUARED_SECOND);
688 }
689
690 /**
691 * Sets z-coordinate of mean specific force during the static period
692 * happening right after this sequence was measured.
693 *
694 * @param afterMeanSpecificForceZ z-coordinate of mean specific force.
695 */
696 public void setAfterMeanSpecificForceZ(final Acceleration afterMeanSpecificForceZ) {
697 afterMeanFz = convertAcceleration(afterMeanSpecificForceZ);
698 }
699
700 /**
701 * Sets coordinates of mean specific force during the static period
702 * happening right after this sequence was measured.
703 *
704 * @param afterMeanSpecificForceX x-coordinate of mean specific force.
705 * @param afterMeanSpecificForceY y-coordinate of mean specific force.
706 * @param afterMeanSpecificForceZ z-coordinate of mean specific force.
707 */
708 public void setAfterMeanSpecificForceCoordinates(
709 final Acceleration afterMeanSpecificForceX, final Acceleration afterMeanSpecificForceY,
710 final Acceleration afterMeanSpecificForceZ) {
711 setAfterMeanSpecificForceX(afterMeanSpecificForceX);
712 setAfterMeanSpecificForceY(afterMeanSpecificForceY);
713 setAfterMeanSpecificForceZ(afterMeanSpecificForceZ);
714 }
715
716 /**
717 * Copies data of provided instance into this instance.
718 *
719 * @param input instance to copy data from.
720 */
721 public void copyFrom(final BodyKinematicsSequence<T> input) {
722 if (input.items != null) {
723 items = cloneList(input.items);
724 } else {
725 items = null;
726 }
727 if (input.sortedItems != null) {
728 sortedItems = cloneList(input.sortedItems);
729 } else {
730 sortedItems = null;
731 }
732
733 beforeMeanFx = input.beforeMeanFx;
734 beforeMeanFy = input.beforeMeanFy;
735 beforeMeanFz = input.beforeMeanFz;
736
737 afterMeanFx = input.afterMeanFx;
738 afterMeanFy = input.afterMeanFy;
739 afterMeanFz = input.afterMeanFz;
740 }
741
742 /**
743 * Copies this instance data into provided instance.
744 *
745 * @param output destination instance where data will be copied to.
746 */
747 public void copyTo(final BodyKinematicsSequence<T> output) {
748 output.copyFrom(this);
749 }
750
751 /***
752 * Checks if provided instance is a BodyKinematicsSequence2 having exactly
753 * the same contents as this instance.
754 *
755 * @param o object to be compared.
756 * @return true if both objects are considered to be equal, false otherwise.
757 */
758 @Override
759 public boolean equals(Object o) {
760 if (this == o) {
761 return true;
762 }
763 if (o == null || getClass() != o.getClass()) {
764 return false;
765 }
766
767 final var that = (BodyKinematicsSequence<?>) o;
768 return Double.compare(that.beforeMeanFx, beforeMeanFx) == 0 &&
769 Double.compare(that.beforeMeanFy, beforeMeanFy) == 0 &&
770 Double.compare(that.beforeMeanFz, beforeMeanFz) == 0 &&
771 Double.compare(that.afterMeanFx, afterMeanFx) == 0 &&
772 Double.compare(that.afterMeanFy, afterMeanFy) == 0 &&
773 Double.compare(that.afterMeanFz, afterMeanFz) == 0 &&
774 Objects.equals(items, that.items) &&
775 Objects.equals(sortedItems, that.sortedItems);
776 }
777
778 /**
779 * Computes and returns hash code for this instance. Hash codes are almost unique
780 * values that are useful for fast classification and storage of objects in collections.
781 *
782 * @return Hash code.
783 */
784 @Override
785 public int hashCode() {
786 return Objects.hash(items, sortedItems, beforeMeanFx, beforeMeanFy, beforeMeanFz,
787 afterMeanFx, afterMeanFy, afterMeanFz);
788 }
789
790 /**
791 * Makes a copy of this instance.
792 *
793 * @return a copy of this instance.
794 * @throws CloneNotSupportedException if clone fails for some reason.
795 */
796 @Override
797 protected Object clone() throws CloneNotSupportedException {
798 //noinspection unchecked
799 final var result = (BodyKinematicsSequence<T>) super.clone();
800 copyTo(result);
801 return result;
802 }
803
804 /**
805 * Clones a list of {@link TimedBodyKinematics}.
806 *
807 * @param list list to be cloned.
808 * @return cloned list.
809 */
810 @SuppressWarnings("unchecked")
811 private ArrayList<T> cloneList(final List<T> list) {
812 // constructor with list only creates a new list containing the
813 // same instances as the original list.
814 // ArrayList is publicly Cloneable, so we clone it to get copies
815 // of the elements contained within.
816
817 final var result = new ArrayList<T>();
818 for (final var item : list) {
819 if (item instanceof StandardDeviationTimedBodyKinematics) {
820 final var newItem = new StandardDeviationTimedBodyKinematics();
821 newItem.copyFrom(item);
822 result.add((T) newItem);
823 } else {
824 final var newItem = new TimedBodyKinematics(item);
825 result.add((T) newItem);
826 }
827 }
828
829 return result;
830 }
831
832 /**
833 * Converts an acceleration instance into its corresponding value
834 * expressed in meters per squared second.
835 *
836 * @param acceleration an acceleration to be converted.
837 * @return converted value.
838 */
839 private static double convertAcceleration(final Acceleration acceleration) {
840 return AccelerationConverter.convert(acceleration.getValue().doubleValue(),
841 acceleration.getUnit(), AccelerationUnit.METERS_PER_SQUARED_SECOND);
842 }
843 }