View Javadoc
1   /*
2    * Copyright (C) 2019 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.gnss;
17  
18  import com.irurueta.geometry.InhomogeneousPoint3D;
19  import com.irurueta.geometry.Point3D;
20  import com.irurueta.navigation.frames.ECEFPosition;
21  import com.irurueta.navigation.frames.ECEFVelocity;
22  import com.irurueta.units.Distance;
23  import com.irurueta.units.DistanceConverter;
24  import com.irurueta.units.DistanceUnit;
25  import com.irurueta.units.Speed;
26  import com.irurueta.units.SpeedConverter;
27  import com.irurueta.units.SpeedUnit;
28  
29  import java.io.Serializable;
30  import java.util.Objects;
31  
32  /**
33   * Contains position and velocity resolved in ECEF axes.
34   */
35  public class ECEFPositionAndVelocity implements Serializable, Cloneable {
36  
37      /**
38       * Cartesian x coordinate of position resolved in ECEF axes and expressed
39       * in meters (m).
40       */
41      double x;
42  
43      /**
44       * Cartesian y coordinate of position resolved in ECEF axes and expressed
45       * in meters (m).
46       */
47      double y;
48  
49      /**
50       * Cartesian z coordinate of position resolved in ECEF axes and expressed
51       * in meters(m).
52       */
53      double z;
54  
55      /**
56       * X coordinate of velocity resolved in ECEF axes and expressed in meters
57       * per second (m/s).
58       */
59      double vx;
60  
61      /**
62       * Y coordinate of velocity resolved in ECEF axes and expressed in meters
63       * per second (m/s).
64       */
65      double vy;
66  
67      /**
68       * Z coordinate of velocity resolved in ECEF axes and expressed in meters
69       * per second (m/s).
70       */
71      double vz;
72  
73      /**
74       * Constructor.
75       */
76      public ECEFPositionAndVelocity() {
77      }
78  
79      /**
80       * Constructor.
81       *
82       * @param x cartesian x coordinate of ECEF position expressed in
83       *          meters (m).
84       * @param y cartesian y coordinate of ECEF position expressed in
85       *          meters (m).
86       * @param z cartesian z coordinate of ECEF position expressed in
87       *          meters (m).
88       */
89      public ECEFPositionAndVelocity(final double x, final double y, final double z) {
90          setPositionCoordinates(x, y, z);
91      }
92  
93      /**
94       * Constructor.
95       *
96       * @param x cartesian x coordinate of ECEF position.
97       * @param y cartesian y coordinate of ECEF position.
98       * @param z cartesian z coordinate of ECEF position.
99       */
100     public ECEFPositionAndVelocity(final Distance x, final Distance y, final Distance z) {
101         setPositionDistanceCoordinates(x, y, z);
102     }
103 
104     /**
105      * Constructor.
106      *
107      * @param ecefPosition ECEF position.
108      */
109     public ECEFPositionAndVelocity(final ECEFPosition ecefPosition) {
110         setEcefPosition(ecefPosition);
111     }
112 
113     /**
114      * Constructor.
115      *
116      * @param position position to be set.
117      */
118     public ECEFPositionAndVelocity(final Point3D position) {
119         setPosition(position);
120     }
121 
122     /**
123      * Constructor.
124      *
125      * @param vx x coordinate of velocity resolved in ECEF axes.
126      * @param vy y coordinate of velocity resolved in ECEF axes.
127      * @param vz z coordinate of velocity resolved in ECEF axes.
128      */
129     public ECEFPositionAndVelocity(final Speed vx, final Speed vy, final Speed vz) {
130         setSpeedCoordinates(vx, vy, vz);
131     }
132 
133     /**
134      * Constructor.
135      *
136      * @param ecefVelocity velocity to be set.
137      */
138     public ECEFPositionAndVelocity(final ECEFVelocity ecefVelocity) {
139         setEcefVelocity(ecefVelocity);
140     }
141 
142     /**
143      * Constructor.
144      *
145      * @param x  cartesian x coordinate of ECEF position expressed in
146      *           meters (m).
147      * @param y  cartesian y coordinate of ECEF position expressed in
148      *           meters (m).
149      * @param z  cartesian z coordinate of ECEF position expressed in
150      *           meters (m).
151      * @param vx x coordinate of velocity resolved in ECEF axes and expressed
152      *           in meters per second (m/s).
153      * @param vy y coordinate of velocity resolved in ECEF axes and expressed
154      *           in meters per second (m/s).
155      * @param vz z coordinate of velocity resolved in ECEF axes and expressed
156      *           in meters per second (m/s).
157      */
158     public ECEFPositionAndVelocity(final double x, final double y, final double z,
159                                    final double vx, final double vy, final double vz) {
160         this(x, y, z);
161         setVelocityCoordinates(vx, vy, vz);
162     }
163 
164     /**
165      * Constructor.
166      *
167      * @param x  cartesian x coordinate of ECEF position expressed in
168      *           meters (m).
169      * @param y  cartesian y coordinate of ECEF position expressed in
170      *           meters (m).
171      * @param z  cartesian z coordinate of ECEF position expressed in
172      *           meters (m).
173      * @param vx x coordinate of velocity resolved in ECEF axes.
174      * @param vy y coordinate of velocity resolved in ECEF axes.
175      * @param vz z coordinate of velocity resolved in ECEF axes.
176      */
177     public ECEFPositionAndVelocity(final double x, final double y, final double z,
178                                    final Speed vx, final Speed vy, final Speed vz) {
179         this(x, y, z);
180         setSpeedCoordinates(vx, vy, vz);
181     }
182 
183     /**
184      * Constructor.
185      *
186      * @param x            cartesian x coordinate of ECEF position expressed in
187      *                     meters (m).
188      * @param y            cartesian y coordinate of ECEF position expressed in
189      *                     meters (m).
190      * @param z            cartesian z coordinate of ECEF position expressed in
191      *                     meters (m).
192      * @param ecefVelocity satellite velocity.
193      */
194     public ECEFPositionAndVelocity(final double x, final double y, final double z, final ECEFVelocity ecefVelocity) {
195         this(x, y, z);
196         setEcefVelocity(ecefVelocity);
197     }
198 
199     /**
200      * Constructor.
201      *
202      * @param x  cartesian x coordinate of ECEF position.
203      * @param y  cartesian y coordinate of ECEF position.
204      * @param z  cartesian z coordinate of ECEF position.
205      * @param vx x coordinate of velocity resolved in ECEF axes and expressed
206      *           in meters per second (m/s).
207      * @param vy y coordinate of velocity resolved in ECEF axes and expressed
208      *           in meters per second (m/s).
209      * @param vz z coordinate of velocity resolved in ECEF axes and expressed
210      *           in meters per second (m/s).
211      */
212     public ECEFPositionAndVelocity(final Distance x, final Distance y, final Distance z,
213                                    final double vx, final double vy, final double vz) {
214         this(x, y, z);
215         setVelocityCoordinates(vx, vy, vz);
216     }
217 
218     /**
219      * Constructor.
220      *
221      * @param x  cartesian x coordinate of ECEF position.
222      * @param y  cartesian y coordinate of ECEF position.
223      * @param z  cartesian z coordinate of ECEF position.
224      * @param vx x coordinate of velocity resolved in ECEF axes.
225      * @param vy y coordinate of velocity resolved in ECEF axes.
226      * @param vz z coordinate of velocity resolved in ECEF axes.
227      */
228     public ECEFPositionAndVelocity(final Distance x, final Distance y, final Distance z,
229                                    final Speed vx, final Speed vy, final Speed vz) {
230         this(x, y, z);
231         setSpeedCoordinates(vx, vy, vz);
232     }
233 
234     /**
235      * Constructor.
236      *
237      * @param x            cartesian x coordinate of ECEF position.
238      * @param y            cartesian y coordinate of ECEF position.
239      * @param z            cartesian z coordinate of ECEF position.
240      * @param ecefVelocity satellite velocity.
241      */
242     public ECEFPositionAndVelocity(final Distance x, final Distance y, final Distance z,
243                                    final ECEFVelocity ecefVelocity) {
244         this(x, y, z);
245         setEcefVelocity(ecefVelocity);
246     }
247 
248     /**
249      * Constructor.
250      *
251      * @param ecefPosition ECEF position to be set.
252      * @param vx           x coordinate of velocity resolved in ECEF axes and expressed
253      *                     in meters per second (m/s).
254      * @param vy           y coordinate of velocity resolved in ECEF axes and expressed
255      *                     in meters per second (m/s).
256      * @param vz           z coordinate of velocity resolved in ECEF axes and expressed
257      *                     in meters per second (m/s).
258      */
259     public ECEFPositionAndVelocity(final ECEFPosition ecefPosition,
260                                    final double vx, final double vy, final double vz) {
261         this(ecefPosition);
262         setVelocityCoordinates(vx, vy, vz);
263     }
264 
265     /**
266      * Constructor.
267      *
268      * @param ecefPosition ECEF position to be set.
269      * @param vx           x coordinate of velocity resolved in ECEF axes.
270      * @param vy           y coordinate of velocity resolved in ECEF axes.
271      * @param vz           z coordinate of velocity resolved in ECEF axes.
272      */
273     public ECEFPositionAndVelocity(final ECEFPosition ecefPosition,
274                                    final Speed vx, final Speed vy, final Speed vz) {
275         this(ecefPosition);
276         setSpeedCoordinates(vx, vy, vz);
277     }
278 
279     /**
280      * Constructor.
281      *
282      * @param ecefPosition ECEF position to be set.
283      * @param ecefVelocity velocity to be set.
284      */
285     public ECEFPositionAndVelocity(final ECEFPosition ecefPosition, final ECEFVelocity ecefVelocity) {
286         this(ecefPosition);
287         setEcefVelocity(ecefVelocity);
288     }
289 
290     /**
291      * Constructor.
292      *
293      * @param position position to be set.
294      * @param vx       x coordinate of velocity resolved in ECEF axes and expressed
295      *                 in meters per second (m/s).
296      * @param vy       y coordinate of velocity resolved in ECEF axes and expressed
297      *                 in meters per second (m/s).
298      * @param vz       z coordinate of velocity resolved in ECEF axes and expressed
299      *                 in meters per second (m/s).
300      */
301     public ECEFPositionAndVelocity(final Point3D position, final double vx, final double vy, final double vz) {
302         this(position);
303         setVelocityCoordinates(vx, vy, vz);
304     }
305 
306     /**
307      * Constructor.
308      *
309      * @param position position to be set.
310      * @param vx       x coordinate of velocity resolved in ECEF axes.
311      * @param vy       y coordinate of velocity resolved in ECEF axes.
312      * @param vz       z coordinate of velocity resolved in ECEF axes.
313      */
314     public ECEFPositionAndVelocity(final Point3D position, final Speed vx, final Speed vy, final Speed vz) {
315         this(position);
316         setSpeedCoordinates(vx, vy, vz);
317     }
318 
319     /**
320      * Constructor.
321      *
322      * @param position     position to be set.
323      * @param ecefVelocity velocity to be set.
324      */
325     public ECEFPositionAndVelocity(final Point3D position, final ECEFVelocity ecefVelocity) {
326         this(position);
327         setEcefVelocity(ecefVelocity);
328     }
329 
330     /**
331      * Copy constructor.
332      *
333      * @param input input instance to copy data from.
334      */
335     public ECEFPositionAndVelocity(final ECEFPositionAndVelocity input) {
336         copyFrom(input);
337     }
338 
339     /**
340      * Gets cartesian x coordinate of position resolved in ECEF axes and
341      * expressed in meters (m).
342      *
343      * @return cartesian x coordinate of position resolved in ECEF axes
344      * and expressed in meters (m).
345      */
346     public double getX() {
347         return x;
348     }
349 
350     /**
351      * Sets cartesian x coordinate of position resolved in ECEF axes and
352      * expressed in meters (m).
353      *
354      * @param x cartesian x coordinate of position resolved in ECEF axes
355      *          and expressed in meters (m).
356      */
357     public void setX(final double x) {
358         this.x = x;
359     }
360 
361     /**
362      * Gets cartesian y coordinate of position resolved in ECEF axes and
363      * expressed in meters (m).
364      *
365      * @return cartesian y coordinate of position resolved in ECEF axes
366      * and expressed in meters (m).
367      */
368     public double getY() {
369         return y;
370     }
371 
372     /**
373      * Sets cartesian y coordinate of position resolved in ECEF axes and
374      * expressed in meters (m).
375      *
376      * @param y cartesian y coordinate of position resolved in ECEF axes
377      *          and expressed in meters (m).
378      */
379     public void setY(final double y) {
380         this.y = y;
381     }
382 
383     /**
384      * Gets cartesian z coordinate of position resolved in ECEF axes and
385      * expressed in meters (m).
386      *
387      * @return cartesian z coordinate of position resolved in ECEF axes
388      * and expressed in meters (m).
389      */
390     public double getZ() {
391         return z;
392     }
393 
394     /**
395      * Sets cartesian z coordinate of position resolved in ECEF axes and
396      * expressed in meters (m).
397      *
398      * @param z cartesian z coordinate of position resolved in ECEF axes
399      *          and expressed in meters (m).
400      */
401     public void setZ(final double z) {
402         this.z = z;
403     }
404 
405     /**
406      * Sets ECEF position expressed in meters (m).
407      *
408      * @param x cartesian x coordinate of position.
409      * @param y cartesian y coordinate of position.
410      * @param z cartesian z coordinate of position.
411      */
412     public void setPositionCoordinates(final double x, final double y, final double z) {
413         this.x = x;
414         this.y = y;
415         this.z = z;
416     }
417 
418     /**
419      * Gets cartesian x coordinate of position resolved in ECEF axes.
420      *
421      * @param result instance where cartesian x coordinate of position will
422      *               be stored.
423      */
424     public void getXDistance(final Distance result) {
425         result.setValue(x);
426         result.setUnit(DistanceUnit.METER);
427     }
428 
429     /**
430      * Gets cartesian x coordinate of position resolved in ECEF axes.
431      *
432      * @return cartesian x coordinate of position.
433      */
434     public Distance getXDistance() {
435         return new Distance(x, DistanceUnit.METER);
436     }
437 
438     /**
439      * Sets cartesian x coordinate of position resolved in ECEF axes.
440      *
441      * @param x cartesian x coordinate of position.
442      */
443     public void setXDistance(final Distance x) {
444         this.x = DistanceConverter.convert(x.getValue().doubleValue(), x.getUnit(), DistanceUnit.METER);
445     }
446 
447     /**
448      * Gets cartesian y coordinate of position resolved in ECEF axes.
449      *
450      * @param result instance where cartesian y coordinate of position will
451      *               be stored.
452      */
453     public void getYDistance(final Distance result) {
454         result.setValue(y);
455         result.setUnit(DistanceUnit.METER);
456     }
457 
458     /**
459      * Gets cartesian y coordinate of position resolved in ECEF axes.
460      *
461      * @return cartesian y coordinate of position.
462      */
463     public Distance getYDistance() {
464         return new Distance(y, DistanceUnit.METER);
465     }
466 
467     /**
468      * Sets cartesian y coordinate of position resolved in ECEF axes.
469      *
470      * @param y cartesian y coordinate of position.
471      */
472     public void setYDistance(final Distance y) {
473         this.y = DistanceConverter.convert(y.getValue().doubleValue(), y.getUnit(), DistanceUnit.METER);
474     }
475 
476     /**
477      * Gets cartesian z coordinate of position resolved in ECEF axes.
478      *
479      * @param result instance where cartesian z coordinate of position will
480      *               be stored.
481      */
482     public void getZDistance(final Distance result) {
483         result.setValue(z);
484         result.setUnit(DistanceUnit.METER);
485     }
486 
487     /**
488      * Gets cartesian z coordinate of position resolved in ECEF axes.
489      *
490      * @return cartesian z coordinate of position.
491      */
492     public Distance getZDistance() {
493         return new Distance(z, DistanceUnit.METER);
494     }
495 
496     /**
497      * Sets cartesian z coordinate of position resolved in ECEF axes.
498      *
499      * @param z cartesian z coordinate of position.
500      */
501     public void setZDistance(final Distance z) {
502         this.z = DistanceConverter.convert(z.getValue().doubleValue(), z.getUnit(), DistanceUnit.METER);
503     }
504 
505     /**
506      * Sets position resolved in ECEF axes.
507      *
508      * @param x cartesian x coordinate of position.
509      * @param y cartesian y coordinate of position.
510      * @param z cartesian z coordinate of position.
511      */
512     public void setPositionDistanceCoordinates(final Distance x, final Distance y, final Distance z) {
513         setXDistance(x);
514         setYDistance(y);
515         setZDistance(z);
516     }
517 
518     /**
519      * Gets ECEF position.
520      *
521      * @param result instance where ECEF position will be stored.
522      */
523     public void getEcefPosition(final ECEFPosition result) {
524         result.setCoordinates(x, y, z);
525     }
526 
527     /**
528      * Gets ECEF position.
529      *
530      * @return ECEF position.
531      */
532     public ECEFPosition getEcefPosition() {
533         return new ECEFPosition(x, y, z);
534     }
535 
536     /**
537      * Sets ECEF position.
538      *
539      * @param ecefPosition ECEF position.
540      */
541     public void setEcefPosition(final ECEFPosition ecefPosition) {
542         x = ecefPosition.getX();
543         y = ecefPosition.getY();
544         z = ecefPosition.getZ();
545     }
546 
547     /**
548      * Gets position resolved in ECEF axes.
549      *
550      * @param result instance where position will be stored.
551      */
552     public void getPosition(final Point3D result) {
553         result.setInhomogeneousCoordinates(x, y, z);
554     }
555 
556     /**
557      * Gets position resolved in ECEF axes.
558      *
559      * @return position.
560      */
561     public Point3D getPosition() {
562         return new InhomogeneousPoint3D(x, y, z);
563     }
564 
565     /**
566      * Sets position resolved in ECEF axes.
567      *
568      * @param position position.
569      */
570     public void setPosition(final Point3D position) {
571         x = position.getInhomX();
572         y = position.getInhomY();
573         z = position.getInhomZ();
574     }
575 
576     /**
577      * Gets x coordinate of velocity resolved in ECEF axes and expressed in
578      * meters per second (m/s).
579      *
580      * @return x coordinate of velocity resolved in ECEF axes.
581      */
582     public double getVx() {
583         return vx;
584     }
585 
586     /**
587      * Sets x coordinate of velocity resolved in ECEF axes and expressed in
588      * meters per second (m/s).
589      *
590      * @param vx x coordinate of velocity resolved in ECEF axes.
591      */
592     public void setVx(final double vx) {
593         this.vx = vx;
594     }
595 
596     /**
597      * Gets y coordinate of velocity resolved in ECEF axes and expressed in
598      * meters per second (m/s).
599      *
600      * @return y coordinate of velocity resolved in ECEF axes.
601      */
602     public double getVy() {
603         return vy;
604     }
605 
606     /**
607      * Sets y coordinate of velocity resolved in ECEF axes and expressed in
608      * meters per second (m/s).
609      *
610      * @param vy y coordinate of velocity resolved in ECEf axes.
611      */
612     public void setVy(final double vy) {
613         this.vy = vy;
614     }
615 
616     /**
617      * Gets z coordinate of velocity resolved in ECEF axes and expressed in
618      * meters per second (m/s).
619      *
620      * @return z coordinate of velocity resolved in ECEF axes.
621      */
622     public double getVz() {
623         return vz;
624     }
625 
626     /**
627      * Sets z coordinate of velocity resolved in ECEF axes and expressed in
628      * meters per second (m/s).
629      *
630      * @param vz z coordinate of velocity resolved in ECEF axes.
631      */
632     public void setVz(final double vz) {
633         this.vz = vz;
634     }
635 
636     /**
637      * Sets velocity coordinates resolved in ECEF axes and expressed in
638      * meters per second (m/s).
639      *
640      * @param vx x coordinate of velocity.
641      * @param vy y coordinate of velocity.
642      * @param vz z coordinate of velocity.
643      */
644     public void setVelocityCoordinates(final double vx, final double vy, final double vz) {
645         this.vx = vx;
646         this.vy = vy;
647         this.vz = vz;
648     }
649 
650     /**
651      * Gets x coordinate of velocity resolved in ECEF axes.
652      *
653      * @param result instance where x coordinate of velocity will be stored.
654      */
655     public void getSpeedX(final Speed result) {
656         result.setValue(vx);
657         result.setUnit(SpeedUnit.METERS_PER_SECOND);
658     }
659 
660     /**
661      * Gets x coordinate of velocity resolved in ECEF axes.
662      *
663      * @return x coordinate of velocity.
664      */
665     public Speed getSpeedX() {
666         return new Speed(vx, SpeedUnit.METERS_PER_SECOND);
667     }
668 
669     /**
670      * Sets x coordinate of velocity resolved in ECEF axes.
671      *
672      * @param vx x coordinate of velocity.
673      */
674     public void setSpeedX(final Speed vx) {
675         this.vx = SpeedConverter.convert(vx.getValue().doubleValue(), vx.getUnit(), SpeedUnit.METERS_PER_SECOND);
676     }
677 
678     /**
679      * Gets y coordinate of velocity resolved in ECEF axes.
680      *
681      * @param result instance where y coordinate of velocity will be stored.
682      */
683     public void getSpeedY(final Speed result) {
684         result.setValue(vy);
685         result.setUnit(SpeedUnit.METERS_PER_SECOND);
686     }
687 
688     /**
689      * Gets y coordinate of velocity resolved in ECEF axes.
690      *
691      * @return y coordinate of velocity.
692      */
693     public Speed getSpeedY() {
694         return new Speed(vy, SpeedUnit.METERS_PER_SECOND);
695     }
696 
697     /**
698      * Sets y coordinate of velocity resolved in ECEF axes.
699      *
700      * @param vy y coordinate of velocity.
701      */
702     public void setSpeedY(final Speed vy) {
703         this.vy = SpeedConverter.convert(vy.getValue().doubleValue(), vy.getUnit(), SpeedUnit.METERS_PER_SECOND);
704     }
705 
706     /**
707      * Gets z coordinate of velocity resolved in ECEF axes.
708      *
709      * @param result instance where z coordinate of velocity will be stored.
710      */
711     public void getSpeedZ(final Speed result) {
712         result.setValue(vz);
713         result.setUnit(SpeedUnit.METERS_PER_SECOND);
714     }
715 
716     /**
717      * Gets z coordinate of velocity resolved in ECEF axes.
718      *
719      * @return z coordinate of velocity.
720      */
721     public Speed getSpeedZ() {
722         return new Speed(vz, SpeedUnit.METERS_PER_SECOND);
723     }
724 
725     /**
726      * Sets z coordinate of velocity resolved in ECEF axes.
727      *
728      * @param vz z coordinate of velocity.
729      */
730     public void setSpeedZ(final Speed vz) {
731         this.vz = SpeedConverter.convert(vz.getValue().doubleValue(), vz.getUnit(), SpeedUnit.METERS_PER_SECOND);
732     }
733 
734     /**
735      * Sets coordinates of velocity resolved in ECEF axes.
736      *
737      * @param vx x coordinate of velocity.
738      * @param vy y coordinate of velocity.
739      * @param vz z coordinate of velocity.
740      */
741     public void setSpeedCoordinates(final Speed vx, final Speed vy, final Speed vz) {
742         setSpeedX(vx);
743         setSpeedY(vy);
744         setSpeedZ(vz);
745     }
746 
747     /**
748      * Gets velocity resolved in ECEF axes.
749      *
750      * @param result instance where velocity will be stored.
751      */
752     public void getEcefVelocity(final ECEFVelocity result) {
753         result.setCoordinates(vx, vy, vz);
754     }
755 
756     /**
757      * Gets velocity resolved in ECEF axes.
758      *
759      * @return velocity.
760      */
761     public ECEFVelocity getEcefVelocity() {
762         return new ECEFVelocity(vx, vy, vz);
763     }
764 
765     /**
766      * Sets velocity resolved in ECEF axes.
767      *
768      * @param ecefVelocity velocity.
769      */
770     public void setEcefVelocity(final ECEFVelocity ecefVelocity) {
771         vx = ecefVelocity.getVx();
772         vy = ecefVelocity.getVy();
773         vz = ecefVelocity.getVz();
774     }
775 
776     /**
777      * Copies this instance data into provided instance.
778      *
779      * @param output destination instance where data will be copied to.
780      */
781     public void copyTo(final ECEFPositionAndVelocity output) {
782         output.x = x;
783         output.y = y;
784         output.z = z;
785 
786         output.vx = vx;
787         output.vy = vy;
788         output.vz = vz;
789     }
790 
791     /**
792      * Copies data of provided instance into this instance.
793      *
794      * @param input instance to copy data from.
795      */
796     public void copyFrom(final ECEFPositionAndVelocity input) {
797         x = input.x;
798         y = input.y;
799         z = input.z;
800 
801         vx = input.vx;
802         vy = input.vy;
803         vz = input.vz;
804     }
805 
806     /**
807      * Computes and returns hash code for this instance. Hash codes are almost unique
808      * values that are useful for fast classification and storage of objects in
809      * collections.
810      *
811      * @return Hash code.
812      */
813     @Override
814     public int hashCode() {
815         return Objects.hash(x, y, z, vx, vy, vz);
816     }
817 
818     /**
819      * Checks if provided object is a ECEFPositionAndVelocity having exactly the
820      * same contents as this instance.
821      *
822      * @param o object to be compared.
823      * @return true if both objects are considered to be equal, false otherwise.
824      */
825     @Override
826     public boolean equals(final Object o) {
827         if (this == o) {
828             return true;
829         }
830         if (o == null || getClass() != o.getClass()) {
831             return false;
832         }
833         final var other = (ECEFPositionAndVelocity) o;
834         return equals(other);
835     }
836 
837     /**
838      * Checks if provided instance has exactly the same contents as this instance.
839      *
840      * @param other instance to be compared.
841      * @return true if both instances are considered to be equal, false otherwise.
842      */
843     public boolean equals(final ECEFPositionAndVelocity other) {
844         return equals(other, 0.0);
845     }
846 
847     /**
848      * Checks if provided instance has contents similar to this instance up to provided
849      * threshold value.
850      *
851      * @param other     instance to be compared.
852      * @param threshold maximum difference allowed between position and velocity
853      *                  coordinates.
854      * @return true if both instances are considered to be equal (up to provided
855      * threshold), false otherwise.
856      */
857     public boolean equals(final ECEFPositionAndVelocity other, final double threshold) {
858         if (other == null) {
859             return false;
860         }
861 
862         return Math.abs(x - other.x) <= threshold
863                 && Math.abs(y - other.y) <= threshold
864                 && Math.abs(z - other.z) <= threshold
865                 && Math.abs(vx - other.vx) <= threshold
866                 && Math.abs(vy - other.vy) <= threshold
867                 && Math.abs(vz - other.vz) <= threshold;
868     }
869 
870     /**
871      * Makes a copy of this instance.
872      *
873      * @return a copy of this instance.
874      * @throws CloneNotSupportedException if clone fails for some reason.
875      */
876     @Override
877     protected Object clone() throws CloneNotSupportedException {
878         final var result = (ECEFPositionAndVelocity) super.clone();
879         copyTo(result);
880         return result;
881     }
882 }