1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.irurueta.navigation.gnss;
17
18 import com.irurueta.algebra.Matrix;
19 import com.irurueta.algebra.WrongSizeException;
20 import com.irurueta.geometry.InhomogeneousPoint3D;
21 import com.irurueta.geometry.Point3D;
22 import com.irurueta.navigation.frames.ECEFPosition;
23 import com.irurueta.navigation.frames.ECEFVelocity;
24 import com.irurueta.units.Distance;
25 import com.irurueta.units.DistanceConverter;
26 import com.irurueta.units.DistanceUnit;
27 import com.irurueta.units.Speed;
28 import com.irurueta.units.SpeedConverter;
29 import com.irurueta.units.SpeedUnit;
30
31 import java.io.Serializable;
32 import java.util.Objects;
33
34
35
36
37
38 public class GNSSEstimation implements Serializable, Cloneable {
39
40
41
42
43 public static final int NUM_PARAMETERS = 8;
44
45
46
47
48 private double x;
49
50
51
52
53 private double y;
54
55
56
57
58 private double z;
59
60
61
62
63 private double vx;
64
65
66
67
68 private double vy;
69
70
71
72
73 private double vz;
74
75
76
77
78 private double clockOffset;
79
80
81
82
83 private double clockDrift;
84
85
86
87
88 public GNSSEstimation() {
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103 public GNSSEstimation(final double x, final double y, final double z,
104 final double vx, final double vy, final double vz,
105 final double clockOffset, final double clockDrift) {
106 setPositionCoordinates(x, y, z);
107 setVelocityCoordinates(vx, vy, vz);
108 setClockOffset(clockOffset);
109 setClockDrift(clockDrift);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public GNSSEstimation(final Distance x, final Distance y, final Distance z,
125 final Speed vx, final Speed vy, final Speed vz,
126 final Distance clockOffset, final Speed clockDrift) {
127 setPositionCoordinates(x, y, z);
128 setVelocityCoordinates(vx, vy, vz);
129 setClockOffset(clockOffset);
130 setClockDrift(clockDrift);
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public GNSSEstimation(final Point3D position, final double vx, final double vy, final double vz,
149 final double clockOffset, final double clockDrift) {
150 setPosition(position);
151 setVelocityCoordinates(vx, vy, vz);
152 setClockOffset(clockOffset);
153 setClockDrift(clockDrift);
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167 public GNSSEstimation(final Point3D position, final Speed vx, final Speed vy, final Speed vz,
168 final Distance clockOffset, final Speed clockDrift) {
169 setPosition(position);
170 setVelocityCoordinates(vx, vy, vz);
171 setClockOffset(clockOffset);
172 setClockDrift(clockDrift);
173 }
174
175
176
177
178
179
180
181
182
183
184 public GNSSEstimation(final ECEFPosition position, final ECEFVelocity velocity,
185 final double clockOffset, final double clockDrift) {
186 setEcefPosition(position);
187 setEcefVelocity(velocity);
188 setClockOffset(clockOffset);
189 setClockDrift(clockDrift);
190 }
191
192
193
194
195
196
197
198
199
200 public GNSSEstimation(final ECEFPosition position, final ECEFVelocity velocity, final Distance clockOffset,
201 final Speed clockDrift) {
202 setEcefPosition(position);
203 setEcefVelocity(velocity);
204 setClockOffset(clockOffset);
205 setClockDrift(clockDrift);
206 }
207
208
209
210
211
212
213
214
215
216
217 public GNSSEstimation(final ECEFPositionAndVelocity positionAndVelocity, final double clockOffset,
218 final double clockDrift) {
219 setPositionAndVelocity(positionAndVelocity);
220 setClockOffset(clockOffset);
221 setClockDrift(clockDrift);
222 }
223
224
225
226
227
228
229
230
231 public GNSSEstimation(final ECEFPositionAndVelocity positionAndVelocity, final Distance clockOffset,
232 final Speed clockDrift) {
233 setPositionAndVelocity(positionAndVelocity);
234 setClockOffset(clockOffset);
235 setClockDrift(clockDrift);
236 }
237
238
239
240
241
242
243 public GNSSEstimation(final GNSSEstimation input) {
244 copyFrom(input);
245 }
246
247
248
249
250
251
252 public double getX() {
253 return x;
254 }
255
256
257
258
259
260
261 public void setX(final double x) {
262 this.x = x;
263 }
264
265
266
267
268
269
270 public double getY() {
271 return y;
272 }
273
274
275
276
277
278
279 public void setY(final double y) {
280 this.y = y;
281 }
282
283
284
285
286
287
288 public double getZ() {
289 return z;
290 }
291
292
293
294
295
296
297 public void setZ(final double z) {
298 this.z = z;
299 }
300
301
302
303
304
305
306
307
308 public void setPositionCoordinates(final double x, final double y, final double z) {
309 this.x = x;
310 this.y = y;
311 this.z = z;
312 }
313
314
315
316
317
318
319 public double getVx() {
320 return vx;
321 }
322
323
324
325
326
327
328 public void setVx(final double vx) {
329 this.vx = vx;
330 }
331
332
333
334
335
336
337 public double getVy() {
338 return vy;
339 }
340
341
342
343
344
345
346 public void setVy(final double vy) {
347 this.vy = vy;
348 }
349
350
351
352
353
354
355 public double getVz() {
356 return vz;
357 }
358
359
360
361
362
363
364 public void setVz(final double vz) {
365 this.vz = vz;
366 }
367
368
369
370
371
372
373
374
375 public void setVelocityCoordinates(final double vx, final double vy, final double vz) {
376 this.vx = vx;
377 this.vy = vy;
378 this.vz = vz;
379 }
380
381
382
383
384
385
386
387
388 public double getClockOffset() {
389 return clockOffset;
390 }
391
392
393
394
395
396
397
398
399 public void setClockOffset(final double clockOffset) {
400 this.clockOffset = clockOffset;
401 }
402
403
404
405
406
407
408
409
410 public double getClockDrift() {
411 return clockDrift;
412 }
413
414
415
416
417
418
419
420
421 public void setClockDrift(final double clockDrift) {
422 this.clockDrift = clockDrift;
423 }
424
425
426
427
428
429
430 public void getDistanceX(final Distance result) {
431 result.setValue(x);
432 result.setUnit(DistanceUnit.METER);
433 }
434
435
436
437
438
439
440 public Distance getDistanceX() {
441 return new Distance(x, DistanceUnit.METER);
442 }
443
444
445
446
447
448
449 public void setDistanceX(final Distance x) {
450 this.x = DistanceConverter.convert(x.getValue().doubleValue(), x.getUnit(), DistanceUnit.METER);
451 }
452
453
454
455
456
457
458 public void getDistanceY(final Distance result) {
459 result.setValue(y);
460 result.setUnit(DistanceUnit.METER);
461 }
462
463
464
465
466
467
468 public Distance getDistanceY() {
469 return new Distance(y, DistanceUnit.METER);
470 }
471
472
473
474
475
476
477 public void setDistanceY(final Distance y) {
478 this.y = DistanceConverter.convert(y.getValue().doubleValue(), y.getUnit(), DistanceUnit.METER);
479 }
480
481
482
483
484
485
486 public void getDistanceZ(final Distance result) {
487 result.setValue(z);
488 result.setUnit(DistanceUnit.METER);
489 }
490
491
492
493
494
495
496 public Distance getDistanceZ() {
497 return new Distance(z, DistanceUnit.METER);
498 }
499
500
501
502
503
504
505 public void setDistanceZ(final Distance z) {
506 this.z = DistanceConverter.convert(z.getValue().doubleValue(), z.getUnit(), DistanceUnit.METER);
507 }
508
509
510
511
512
513
514
515
516 public void setPositionCoordinates(final Distance x, final Distance y, final Distance z) {
517 setDistanceX(x);
518 setDistanceY(y);
519 setDistanceZ(z);
520 }
521
522
523
524
525
526
527
528 public void getSpeedX(final Speed result) {
529 result.setValue(vx);
530 result.setUnit(SpeedUnit.METERS_PER_SECOND);
531 }
532
533
534
535
536
537
538 public Speed getSpeedX() {
539 return new Speed(vx, SpeedUnit.METERS_PER_SECOND);
540 }
541
542
543
544
545
546
547 public void setSpeedX(final Speed speedX) {
548 vx = SpeedConverter.convert(speedX.getValue().doubleValue(), speedX.getUnit(), SpeedUnit.METERS_PER_SECOND);
549 }
550
551
552
553
554
555
556
557 public void getSpeedY(final Speed result) {
558 result.setValue(vy);
559 result.setUnit(SpeedUnit.METERS_PER_SECOND);
560 }
561
562
563
564
565
566
567 public Speed getSpeedY() {
568 return new Speed(vy, SpeedUnit.METERS_PER_SECOND);
569 }
570
571
572
573
574
575
576 public void setSpeedY(final Speed speedY) {
577 vy = SpeedConverter.convert(speedY.getValue().doubleValue(), speedY.getUnit(), SpeedUnit.METERS_PER_SECOND);
578 }
579
580
581
582
583
584
585
586 public void getSpeedZ(final Speed result) {
587 result.setValue(vz);
588 result.setUnit(SpeedUnit.METERS_PER_SECOND);
589 }
590
591
592
593
594
595
596 public Speed getSpeedZ() {
597 return new Speed(vz, SpeedUnit.METERS_PER_SECOND);
598 }
599
600
601
602
603
604
605 public void setSpeedZ(final Speed speedZ) {
606 vz = SpeedConverter.convert(speedZ.getValue().doubleValue(), speedZ.getUnit(), SpeedUnit.METERS_PER_SECOND);
607 }
608
609
610
611
612
613
614
615
616 public void setVelocityCoordinates(final Speed speedX, final Speed speedY, final Speed speedZ) {
617 setSpeedX(speedX);
618 setSpeedY(speedY);
619 setSpeedZ(speedZ);
620 }
621
622
623
624
625
626
627
628
629 public void getClockOffsetDistance(final Distance result) {
630 result.setValue(clockOffset);
631 result.setUnit(DistanceUnit.METER);
632 }
633
634
635
636
637
638
639
640
641 public Distance getClockOffsetDistance() {
642 return new Distance(clockOffset, DistanceUnit.METER);
643 }
644
645
646
647
648
649
650
651
652 public void setClockOffset(final Distance clockOffset) {
653 this.clockOffset = DistanceConverter.convert(clockOffset.getValue().doubleValue(), clockOffset.getUnit(),
654 DistanceUnit.METER);
655 }
656
657
658
659
660
661
662
663
664 public void getClockDriftSpeed(final Speed result) {
665 result.setValue(clockDrift);
666 result.setUnit(SpeedUnit.METERS_PER_SECOND);
667 }
668
669
670
671
672
673
674
675
676 public Speed getClockDriftSpeed() {
677 return new Speed(clockDrift, SpeedUnit.METERS_PER_SECOND);
678 }
679
680
681
682
683
684
685
686
687 public void setClockDrift(final Speed clockDrift) {
688 this.clockDrift = SpeedConverter.convert(clockDrift.getValue().doubleValue(), clockDrift.getUnit(),
689 SpeedUnit.METERS_PER_SECOND);
690 }
691
692
693
694
695
696
697 public void getPosition(final Point3D result) {
698 result.setInhomogeneousCoordinates(x, y, z);
699 }
700
701
702
703
704
705
706 public Point3D getPosition() {
707 return new InhomogeneousPoint3D(x, y, z);
708 }
709
710
711
712
713
714
715 public void setPosition(final Point3D position) {
716 x = position.getInhomX();
717 y = position.getInhomY();
718 z = position.getInhomZ();
719 }
720
721
722
723
724
725
726 public void getEcefPosition(final ECEFPosition result) {
727 result.setCoordinates(x, y, z);
728 }
729
730
731
732
733
734
735 public ECEFPosition getEcefPosition() {
736 return new ECEFPosition(x, y, z);
737 }
738
739
740
741
742
743
744 public void setEcefPosition(final ECEFPosition ecefPosition) {
745 x = ecefPosition.getX();
746 y = ecefPosition.getY();
747 z = ecefPosition.getZ();
748 }
749
750
751
752
753
754
755 public void getEcefVelocity(final ECEFVelocity result) {
756 result.setCoordinates(vx, vy, vz);
757 }
758
759
760
761
762
763
764 public ECEFVelocity getEcefVelocity() {
765 return new ECEFVelocity(vx, vy, vz);
766 }
767
768
769
770
771
772
773 public void setEcefVelocity(final ECEFVelocity ecefVelocity) {
774 vx = ecefVelocity.getVx();
775 vy = ecefVelocity.getVy();
776 vz = ecefVelocity.getVz();
777 }
778
779
780
781
782
783
784 public void getPositionAndVelocity(final ECEFPositionAndVelocity result) {
785 result.setPositionCoordinates(x, y, z);
786 result.setVelocityCoordinates(vx, vy, vz);
787 }
788
789
790
791
792
793
794 public ECEFPositionAndVelocity getPositionAndVelocity() {
795 return new ECEFPositionAndVelocity(x, y, z, vx, vy, vz);
796 }
797
798
799
800
801
802
803 public void setPositionAndVelocity(final ECEFPositionAndVelocity positionAndVelocity) {
804 setPositionCoordinates(positionAndVelocity.getX(), positionAndVelocity.getY(), positionAndVelocity.getZ());
805 setVelocityCoordinates(positionAndVelocity.getVx(), positionAndVelocity.getVy(), positionAndVelocity.getVz());
806 }
807
808
809
810
811
812
813
814 public void asArray(final double[] result) {
815 if (result.length != NUM_PARAMETERS) {
816 throw new IllegalArgumentException();
817 }
818
819 result[0] = x;
820 result[1] = y;
821 result[2] = z;
822 result[3] = vx;
823 result[4] = vy;
824 result[5] = vz;
825 result[6] = clockOffset;
826 result[7] = clockDrift;
827 }
828
829
830
831
832
833
834 public double[] asArray() {
835 final var result = new double[NUM_PARAMETERS];
836 asArray(result);
837 return result;
838 }
839
840
841
842
843
844
845
846 public void fromArray(final double[] array) {
847 if (array.length != NUM_PARAMETERS) {
848 throw new IllegalArgumentException();
849 }
850
851 x = array[0];
852 y = array[1];
853 z = array[2];
854 vx = array[3];
855 vy = array[4];
856 vz = array[5];
857 clockOffset = array[6];
858 clockDrift = array[7];
859 }
860
861
862
863
864
865
866
867 public void asMatrix(final Matrix result) {
868 if (result.getRows() != NUM_PARAMETERS || result.getColumns() != 1) {
869 try {
870 result.resize(NUM_PARAMETERS, 1);
871 } catch (WrongSizeException ignore) {
872
873 }
874 }
875
876 result.setElementAtIndex(0, x);
877 result.setElementAtIndex(1, y);
878 result.setElementAtIndex(2, z);
879 result.setElementAtIndex(3, vx);
880 result.setElementAtIndex(4, vy);
881 result.setElementAtIndex(5, vz);
882 result.setElementAtIndex(6, clockOffset);
883 result.setElementAtIndex(7, clockDrift);
884 }
885
886
887
888
889
890
891 public Matrix asMatrix() {
892 final Matrix result;
893 try {
894 result = new Matrix(NUM_PARAMETERS, 1);
895 asMatrix(result);
896 return result;
897 } catch (final WrongSizeException ignore) {
898
899 return null;
900 }
901 }
902
903
904
905
906
907
908
909 public void fromMatrix(final Matrix matrix) {
910 if (matrix.getRows() != NUM_PARAMETERS || matrix.getColumns() != 1) {
911 throw new IllegalArgumentException();
912 }
913 fromArray(matrix.getBuffer());
914 }
915
916
917
918
919
920
921 public void copyTo(final GNSSEstimation output) {
922 output.x = x;
923 output.y = y;
924 output.z = z;
925
926 output.vx = vx;
927 output.vy = vy;
928 output.vz = vz;
929
930 output.clockOffset = clockOffset;
931 output.clockDrift = clockDrift;
932 }
933
934
935
936
937
938
939 public void copyFrom(final GNSSEstimation input) {
940 x = input.x;
941 y = input.y;
942 z = input.z;
943
944 vx = input.vx;
945 vy = input.vy;
946 vz = input.vz;
947
948 clockOffset = input.clockOffset;
949 clockDrift = input.clockDrift;
950 }
951
952
953
954
955
956
957
958 @Override
959 public int hashCode() {
960 return Objects.hash(x, y, z, vx, vy, vz, clockOffset, clockDrift);
961 }
962
963
964
965
966
967
968
969
970 @Override
971 public boolean equals(final Object obj) {
972 if (obj == this) {
973 return true;
974 }
975 if (obj == null || getClass() != obj.getClass()) {
976 return false;
977 }
978
979 final GNSSEstimation other = (GNSSEstimation) obj;
980 return equals(other);
981 }
982
983
984
985
986
987
988
989 public boolean equals(final GNSSEstimation other) {
990 return equals(other, 0.0);
991 }
992
993
994
995
996
997
998
999
1000
1001
1002 public boolean equals(final GNSSEstimation other, final double threshold) {
1003 if (other == null) {
1004 return false;
1005 }
1006
1007 return Math.abs(x - other.x) <= threshold
1008 && Math.abs(y - other.y) <= threshold
1009 && Math.abs(z - other.z) <= threshold
1010 && Math.abs(vx - other.vx) <= threshold
1011 && Math.abs(vy - other.vy) <= threshold
1012 && Math.abs(vz - other.vz) <= threshold
1013 && Math.abs(clockOffset - other.clockOffset) <= threshold
1014 && Math.abs(clockDrift - other.clockDrift) <= threshold;
1015 }
1016
1017
1018
1019
1020
1021
1022
1023 @Override
1024 protected Object clone() throws CloneNotSupportedException {
1025 final var result = (GNSSEstimation) super.clone();
1026 copyTo(result);
1027 return result;
1028 }
1029 }