1   /* Copyright 2002-2024 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.ssa.collision.shorttermencounter.probability.twod;
18  
19  import org.hipparchus.Field;
20  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21  import org.hipparchus.geometry.euclidean.twod.FieldVector2D;
22  import org.hipparchus.linear.BlockFieldMatrix;
23  import org.hipparchus.linear.FieldMatrix;
24  import org.hipparchus.linear.MatrixUtils;
25  import org.hipparchus.stat.descriptive.DescriptiveStatistics;
26  import org.hipparchus.util.Binary64;
27  import org.hipparchus.util.Binary64Field;
28  import org.hipparchus.util.FastMath;
29  import org.junit.jupiter.api.Assertions;
30  import org.junit.jupiter.api.BeforeAll;
31  import org.junit.jupiter.api.DisplayName;
32  import org.junit.jupiter.api.Test;
33  import org.mockito.Mockito;
34  import org.orekit.Utils;
35  import org.orekit.errors.OrekitException;
36  import org.orekit.frames.Frame;
37  import org.orekit.frames.FramesFactory;
38  import org.orekit.frames.LOFType;
39  import org.orekit.frames.encounter.EncounterLOFType;
40  import org.orekit.orbits.FieldCartesianOrbit;
41  import org.orekit.orbits.FieldOrbit;
42  import org.orekit.orbits.Orbit;
43  import org.orekit.propagation.FieldStateCovariance;
44  import org.orekit.propagation.StateCovariance;
45  import org.orekit.ssa.collision.shorttermencounter.probability.twod.armellinutils.ArmellinStatistics;
46  import org.orekit.time.AbsoluteDate;
47  import org.orekit.time.FieldAbsoluteDate;
48  import org.orekit.utils.Constants;
49  import org.orekit.utils.FieldPVCoordinates;
50  
51  import java.io.IOException;
52  
53  class FieldShortTermEncounter2DDefinitionTest {
54  
55      /**
56       * Threshold below which values are considered equal to zero.
57       */
58      private final double DEFAULT_ZERO_THRESHOLD = 5e-14;
59  
60      @BeforeAll
61      static void initializeOrekitData() {
62          Utils.setDataRoot("regular-data");
63      }
64  
65      @Test
66      @DisplayName("Test the combined radius (sum of each collision object sphere equivalent radius)")
67      public void testGiveTheSumOfEachCollisionObjectRadius() {
68  
69          // GIVEN
70          // Define the time of closest approach
71          final Field<Binary64>             field                 = Binary64Field.getInstance();
72          final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
73  
74          // Define the primary collision object
75          @SuppressWarnings("unchecked")
76          final FieldOrbit<Binary64> primaryMock = Mockito.mock(FieldOrbit.class);
77  
78          Mockito.when(primaryMock.getDate()).thenReturn(timeOfClosestApproach);
79  
80          @SuppressWarnings("unchecked")
81          final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
82  
83          final Binary64 primaryRadius = new Binary64(5);
84  
85          // Define the secondary collision object
86          @SuppressWarnings("unchecked")
87          final FieldOrbit<Binary64> secondaryMock = Mockito.mock(FieldOrbit.class);
88  
89          Mockito.when(secondaryMock.getDate()).thenReturn(timeOfClosestApproach);
90  
91          @SuppressWarnings("unchecked")
92          final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
93  
94          final Binary64 secondaryRadius = new Binary64(3);
95  
96          final FieldShortTermEncounter2DDefinition<Binary64> collision =
97                  new FieldShortTermEncounter2DDefinition<>(primaryMock, primaryCovariance,
98                                                            primaryRadius, secondaryMock,
99                                                            secondaryCovariance,
100                                                           secondaryRadius);
101 
102         // WHEN
103         final Binary64 combinedRadius = collision.getCombinedRadius();
104 
105         // THEN
106         Assertions.assertEquals(8, combinedRadius.getReal());
107     }
108 
109     /**
110      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
111      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
112      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
113      * <p>
114      * Each of the collision object have an identical diagonal covariance matrix.
115      * </p>
116      * <p>
117      * The goal of this test is to verify if the computed projection matrix from primary inertial to default collision plane
118      * is the same as expected (computed by hand).
119      * </p>
120      */
121     @Test
122     @DisplayName("Test the projection matrix from primary inertial to the default collision plane")
123     public void testReturnProjectionMatrixFromPrimaryInertialToDefaultCollisionPlane() {
124 
125         // GIVEN
126         // Define the time of closest approach and mu
127         final Field<Binary64>             field                 = Binary64Field.getInstance();
128         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
129         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
130 
131         // Define the primary collision object
132         final Frame primaryInertialFrame = FramesFactory.getEME2000();
133 
134         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
135                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
136                                                              new Binary64(0),
137                                                              new Binary64(0)),
138                                          new FieldVector3D<>(new Binary64(0),
139                                                              new Binary64(7668.631425),
140                                                              new Binary64(0))),
141                 primaryInertialFrame, timeOfClosestApproach, mu);
142 
143         @SuppressWarnings("unchecked")
144         final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
145 
146         final Binary64 primaryRadius = new Binary64(5);
147 
148         // Define the secondary collision object
149         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
150 
151         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
152                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
153                                                              new Binary64(0),
154                                                              new Binary64(0)),
155                                          new FieldVector3D<>(new Binary64(0),
156                                                              new Binary64(0),
157                                                              new Binary64(7668.631425))),
158                 secondaryInertialFrame, timeOfClosestApproach, mu);
159 
160         @SuppressWarnings("unchecked")
161         final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
162         final Binary64 secondaryRadius = new Binary64(5);
163 
164         // Collision definition
165         final FieldShortTermEncounter2DDefinition<Binary64> collision =
166                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
167                                                           primaryRadius, secondary,
168                                                           secondaryCovariance,
169                                                           secondaryRadius);
170 
171         // WHEN
172         final FieldMatrix<Binary64> projectionMatrixFromPrimaryInertialToCollisionPlane =
173                 collision.computeReferenceInertialToCollisionPlaneProjectionMatrix();
174 
175         // THEN
176         Assertions.assertEquals(1, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 0).getReal(), 1e-10);
177         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 1).getReal(), 1e-10);
178         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 2).getReal(), 1e-10);
179         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 0).getReal(), 1e-10);
180         Assertions.assertEquals(FastMath.sqrt(2) * 0.5,
181                                 projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 1).getReal(), 1e-7);
182         Assertions.assertEquals(FastMath.sqrt(2) * 0.5,
183                                 projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 2).getReal(), 1e-7);
184     }
185 
186     /**
187      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
188      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
189      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
190      * <p>
191      * Each of the collision object have an identical diagonal covariance matrix.
192      * </p>
193      * <p>
194      * The goal of this test is to verify if the computed projection matrix from primary inertial to Valsecchi collision
195      * plane is the same as expected (computed by hand).
196      * </p>
197      */
198     @Test
199     @DisplayName("Test the projection matrix from primary inertial to the Valsecchi collision plane")
200     public void testReturnProjectionMatrixFromPrimaryInertialToValsecchiCollisionPlane() {
201 
202         // GIVEN
203         // Define the time of closest approach and mu
204         final Field<Binary64>             field                 = Binary64Field.getInstance();
205         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
206         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
207 
208         // Define the primary collision object
209         final Frame primaryInertialFrame = FramesFactory.getEME2000();
210 
211         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
212                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
213                                                              new Binary64(0),
214                                                              new Binary64(0)),
215                                          new FieldVector3D<>(new Binary64(0),
216                                                              new Binary64(7668.631425),
217                                                              new Binary64(0))), primaryInertialFrame,
218                 timeOfClosestApproach, mu);
219 
220         @SuppressWarnings("unchecked")
221         final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
222 
223         final Binary64 primaryRadius = new Binary64(5);
224 
225         // Define the secondary collision object
226         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
227 
228         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
229                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
230                                                              new Binary64(0),
231                                                              new Binary64(0)),
232                                          new FieldVector3D<>(new Binary64(0),
233                                                              new Binary64(0),
234                                                              new Binary64(7668.631425))),
235                 secondaryInertialFrame, timeOfClosestApproach, mu);
236 
237         @SuppressWarnings("unchecked")
238         final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
239 
240         final Binary64 secondaryRadius = new Binary64(5);
241 
242         // Collision definition
243         final FieldShortTermEncounter2DDefinition<Binary64> collision =
244                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
245                                                           primaryRadius, secondary,
246                                                           secondaryCovariance,
247                                                           secondaryRadius,
248                                                           EncounterLOFType.VALSECCHI,
249                                                           1e-6);
250 
251         // WHEN
252         final FieldMatrix<Binary64> projectionMatrixFromPrimaryInertialToCollisionPlane =
253                 collision.computeReferenceInertialToCollisionPlaneProjectionMatrix();
254 
255         // THEN
256         Assertions.assertEquals(1, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 0).getReal(), 1e-10);
257         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 1).getReal(), 1e-10);
258         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(0, 2).getReal(), 1e-10);
259         Assertions.assertEquals(0, projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 0).getReal(), 1e-10);
260         Assertions.assertEquals(-FastMath.sqrt(2) / 2,
261                                 projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 1).getReal(), 1e-7);
262         Assertions.assertEquals(-FastMath.sqrt(2) / 2,
263                                 projectionMatrixFromPrimaryInertialToCollisionPlane.getEntry(1, 2).getReal(), 1e-7);
264     }
265 
266     /**
267      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
268      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
269      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
270      * <p>
271      * Each of the collision object have an identical diagonal covariance matrix.
272      * </p>
273      * <p>
274      * The goal of this test is to verify if the computed relative PVCoordinates of the secondary collision object to the
275      * primary collision object is the same as expected.
276      * </p>
277      */
278     @Test
279     @DisplayName("Test the relative PVCoordinates of the secondary collision object to the primary collision object")
280     public void testReturnSecondaryRelativeToPrimaryInPrimaryInertial() {
281 
282         // GIVEN
283         // Define the time of closest approach and mu
284         final Field<Binary64>             field                 = Binary64Field.getInstance();
285         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
286         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
287 
288         // Define the primary collision object
289         final Frame primaryInertialFrame = FramesFactory.getEME2000();
290 
291         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
292                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
293                                                              new Binary64(0),
294                                                              new Binary64(0)),
295                                          new FieldVector3D<>(new Binary64(0),
296                                                              new Binary64(7668.631425),
297                                                              new Binary64(0))),
298                 primaryInertialFrame, timeOfClosestApproach, mu);
299 
300         @SuppressWarnings("unchecked")
301         final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
302 
303         final Binary64 primaryRadius = new Binary64(5);
304 
305         // Define the secondary collision object
306         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
307 
308         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
309                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
310                                                              new Binary64(0),
311                                                              new Binary64(0)),
312                                          new FieldVector3D<>(new Binary64(0),
313                                                              new Binary64(0),
314                                                              new Binary64(7668.631425))),
315                 secondaryInertialFrame, timeOfClosestApproach, mu);
316 
317         @SuppressWarnings("unchecked")
318         final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
319 
320         final Binary64 secondaryRadius = new Binary64(5);
321 
322         // Collision definition
323         final FieldShortTermEncounter2DDefinition<Binary64> collision =
324                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
325                                                           primaryRadius, secondary,
326                                                           secondaryCovariance,
327                                                           secondaryRadius);
328 
329         // WHEN
330         final FieldPVCoordinates<Binary64> secondaryRelativeToPrimaryPVInPrimaryInertial =
331                 collision.computeOtherRelativeToReferencePVInReferenceInertial();
332 
333         // THEN
334         Assertions.assertEquals(new FieldVector3D<>(new Binary64(1),
335                                                     new Binary64(0),
336                                                     new Binary64(0)),
337                                 secondaryRelativeToPrimaryPVInPrimaryInertial.getPosition());
338         Assertions.assertEquals(new FieldVector3D<>(new Binary64(0),
339                                                     new Binary64(-7668.631425),
340                                                     new Binary64(7668.631425)),
341                                 secondaryRelativeToPrimaryPVInPrimaryInertial.getVelocity());
342     }
343 
344     /**
345      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km and u =
346      * 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> of a
347      * slightly different radius as primary (1 meter difference). Moreover, they both have the same inertial frame of
348      * reference (EME2000).
349      * <p>
350      * Each of the collision object have an identical diagonal covariance matrix.
351      * </p>
352      * <p>
353      * The goal of this test is to verify if the computed projected diagonalized combined covariance matrix is the same as
354      * expected.
355      * </p>
356      */
357     @Test
358     @DisplayName("Test the projection and diagonalizing method of the combined covariance matrix with diagonal input matrices")
359     public void testComputeTheDiagonalizedCombinedCovarianceMatrixProjectedOntoCollisionPlaneWithDiagonalCovarianceAsInput() {
360 
361         // GIVEN
362         // Define the time of closest approach and mu
363         final Field<Binary64>             field                 = Binary64Field.getInstance();
364         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
365         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
366 
367         // Define the primary collision object
368         final Frame primaryInertialFrame = FramesFactory.getEME2000();
369 
370         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
371                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
372                                                              new Binary64(0),
373                                                              new Binary64(0)),
374                                          new FieldVector3D<>(new Binary64(0),
375                                                              new Binary64(7668.631425),
376                                                              new Binary64(0))),
377                 primaryInertialFrame, timeOfClosestApproach, mu);
378 
379         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
380                 new Binary64[][] { { new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
381                                      new Binary64(0) },
382                                    { new Binary64(0), new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0),
383                                      new Binary64(0) },
384                                    { new Binary64(0), new Binary64(0), new Binary64(200), new Binary64(0), new Binary64(0),
385                                      new Binary64(0) },
386                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
387                                      new Binary64(0) },
388                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
389                                      new Binary64(0) },
390                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
391                                      new Binary64(100) } });
392         final FieldStateCovariance<Binary64> primaryCovariance =
393                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
394                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
395 
396         final Binary64 primaryRadius = new Binary64(5);
397 
398         // Define the secondary collision object
399         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
400         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
401                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1), new Binary64(0), new Binary64(0)),
402                                          new FieldVector3D<>(new Binary64(0), new Binary64(0), new Binary64(7668.631425))),
403                 secondaryInertialFrame, timeOfClosestApproach, mu);
404         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
405                 new Binary64[][] { { new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
406                                      new Binary64(0) },
407                                    { new Binary64(0), new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0),
408                                      new Binary64(0) },
409                                    { new Binary64(0), new Binary64(0), new Binary64(200), new Binary64(0), new Binary64(0),
410                                      new Binary64(0) },
411                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
412                                      new Binary64(0) },
413                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
414                                      new Binary64(0) },
415                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
416                                      new Binary64(100) } });
417         final FieldStateCovariance<Binary64> secondaryCovariance =
418                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
419                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
420         final Binary64 secondaryRadius = new Binary64(5);
421 
422         final FieldShortTermEncounter2DDefinition<Binary64> collision =
423                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
424                                                           primaryRadius, secondary,
425                                                           secondaryCovariance,
426                                                           secondaryRadius);
427 
428         // WHEN
429         final FieldMatrix<Binary64> projectedDiagonalizedCombinedCovarianceMatrix =
430                 collision.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();
431 
432         final Binary64 sigmaX = projectedDiagonalizedCombinedCovarianceMatrix.getEntry(
433                 0, 0);
434         final Binary64 sigmaY = projectedDiagonalizedCombinedCovarianceMatrix.getEntry(
435                 1, 1);
436         final Binary64 crossTerm = projectedDiagonalizedCombinedCovarianceMatrix.getEntry(
437                 0, 1);
438 
439         // THEN
440         Assertions.assertEquals(200, sigmaX.getReal(), 1e-15);
441         Assertions.assertEquals(300, sigmaY.getReal(), 1e-12);
442         Assertions.assertEquals(0, crossTerm.getReal(), 1e-15);
443         Assertions.assertEquals(projectedDiagonalizedCombinedCovarianceMatrix.getEntry(1, 0),
444                                 projectedDiagonalizedCombinedCovarianceMatrix.getEntry(0, 1));
445     }
446 
447     /**
448      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
449      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
450      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
451      * <p>
452      * Each of the collision object have an identical non diagonal covariance matrix.
453      * </p>
454      * <p>
455      * The goal of this test is to verify if the computed projected diagonalized combined covariance matrix is the same as
456      * expected with non diagonal covariance matrices as input.
457      * </p>
458      */
459     @Test
460     @DisplayName("Test the projection and diagonalizing method of the combined covariance matrix on non diagonal input matrices")
461     public void testComputeTheDiagonalizedCombinedCovarianceMatrixProjectedOntoCollisionPlaneWithNonDiagonalCovarianceAsInput() {
462 
463         // GIVEN
464         // Define the time of closest approach and mu
465         final Field<Binary64>             field                 = Binary64Field.getInstance();
466         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
467         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
468 
469         // Define the primary collision object
470         final Frame primaryInertialFrame = FramesFactory.getEME2000();
471 
472         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
473                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
474                                                              new Binary64(0),
475                                                              new Binary64(0)),
476                                          new FieldVector3D<>(new Binary64(0),
477                                                              new Binary64(7668.631425),
478                                                              new Binary64(0))), primaryInertialFrame,
479                 timeOfClosestApproach, mu);
480 
481         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
482                 new Binary64[][] {
483                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
484                           new Binary64(100) },
485                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
486                           new Binary64(100) },
487                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
488                           new Binary64(100) },
489                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
490                           new Binary64(100) },
491                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
492                           new Binary64(100) },
493                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
494                           new Binary64(100) } });
495         final FieldStateCovariance<Binary64> primaryCovariance =
496                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
497                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
498 
499         final Binary64 primaryRadius = new Binary64(5);
500 
501         // Define the secondary collision object
502         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
503 
504         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
505                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
506                                                              new Binary64(0),
507                                                              new Binary64(0)),
508                                          new FieldVector3D<>(new Binary64(0),
509                                                              new Binary64(0),
510                                                              new Binary64(7668.631425))),
511                 secondaryInertialFrame, timeOfClosestApproach, mu);
512 
513         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
514                 new Binary64[][] {
515                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
516                           new Binary64(100) },
517                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
518                           new Binary64(100) },
519                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
520                           new Binary64(100) },
521                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
522                           new Binary64(100) },
523                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
524                           new Binary64(100) },
525                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
526                           new Binary64(100) } });
527         final FieldStateCovariance<Binary64> secondaryCovariance =
528                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
529                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
530 
531         final Binary64 secondaryRadius = new Binary64(5);
532 
533         final FieldShortTermEncounter2DDefinition<Binary64> collision =
534                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
535                                                           primaryRadius, secondary,
536                                                           secondaryCovariance,
537                                                           secondaryRadius);
538 
539         // WHEN
540 
541         final FieldMatrix<Binary64> projectedDiagonalizedCombinedCovarianceMatrix =
542                 collision.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();
543 
544         final Binary64 sigmaX = projectedDiagonalizedCombinedCovarianceMatrix.getEntry(0, 0);
545         final Binary64 sigmaY = projectedDiagonalizedCombinedCovarianceMatrix.getEntry(1, 1);
546 
547         // THEN
548         Assertions.assertEquals(100, sigmaX.getReal(), 1e-5);
549         Assertions.assertEquals(400, sigmaY.getReal(), 1e-5);
550     }
551 
552     /**
553      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
554      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
555      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
556      * <p>
557      * Each of the collision object have an identical covariance matrix.
558      * </p>
559      * <p>
560      * Test the computation of the secondary collision object position projected and rotated onto the collision plane with
561      * identity covariance matrix as input in order to test the sigmaXSquared <= sigmaYSquared condition with correlation = 0
562      * in {@link FieldShortTermEncounter2DDefinition <Binary64>}.
563      * </p>
564      */
565     @Test
566     @DisplayName("Test the computation of the secondary collision object position projected and rotated onto the collision plane with identity covariance matrix as input.")
567     public void testComputeSecondaryPositionProjectedAndRotatedOntoCollisionPlaneWithIdentityCovarianceMatrixAsInput() {
568 
569         // GIVEN
570         // Define the time of closest approach and mu
571         final Field<Binary64>             field                 = Binary64Field.getInstance();
572         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
573         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
574 
575         // Define the primary collision object
576         final Frame primaryInertialFrame = FramesFactory.getEME2000();
577 
578         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
579                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
580                                                              new Binary64(0),
581                                                              new Binary64(0)),
582                                          new FieldVector3D<>(new Binary64(0),
583                                                              new Binary64(7668.631425),
584                                                              new Binary64(0))), primaryInertialFrame,
585                 timeOfClosestApproach, mu);
586 
587         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = MatrixUtils.createFieldIdentityMatrix(field, 6);
588         final FieldStateCovariance<Binary64> primaryCovariance =
589                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
590                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
591 
592         final Binary64 primaryRadius = new Binary64(5);
593 
594         // Define the secondary collision object
595         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
596 
597         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
598                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
599                                                              new Binary64(0),
600                                                              new Binary64(0)),
601                                          new FieldVector3D<>(new Binary64(0),
602                                                              new Binary64(0),
603                                                              new Binary64(7668.631425))),
604                 secondaryInertialFrame, timeOfClosestApproach, mu);
605 
606         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN =
607                 MatrixUtils.createFieldIdentityMatrix(field, 6);
608         final FieldStateCovariance<Binary64> secondaryCovariance =
609                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
610                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
611         final Binary64 secondaryRadius = new Binary64(5);
612 
613         final FieldShortTermEncounter2DDefinition<Binary64> collision =
614                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
615                                                           primaryRadius, secondary,
616                                                           secondaryCovariance,
617                                                           secondaryRadius);
618 
619         // WHEN
620         final FieldVector2D<Binary64> secondaryPositionProjectedAndRotatedOntoCollisionPlane =
621                 collision.computeOtherPositionInRotatedCollisionPlane();
622 
623         // THEN
624         Assertions.assertEquals(1, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getX().getReal(), 1e-10);
625         Assertions.assertEquals(0, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getY().getReal(), 1e-10);
626 
627     }
628 
629     /**
630      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
631      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
632      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
633      * <p>
634      * The primary collision object has an identity matrix as covariance and the secondary collision object has a specific
635      * matrix.
636      * <p>
637      * Test the computation of the secondary collision object position projected and rotated onto the collision plane with
638      * specific covariance matrix as input in order to test the sigmaXSquared > sigmaYSquared condition in
639      * {@link FieldShortTermEncounter2DDefinition <Binary64>}.
640      * </p>
641      */
642     @Test
643     @DisplayName("Test the computation of the secondary collision object position projected and rotated onto the collision plane with specific covariance matrix as input")
644     public void testComputeSecondaryPositionProjectedAndRotatedOntoCollisionPlaneWithSpecificCovarianceMatrixAsInput() {
645 
646         // GIVEN
647         // Define the time of closest approach and mu
648         final Field<Binary64>             field                 = Binary64Field.getInstance();
649         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
650         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
651 
652         // Define the primary collision object
653         final Frame primaryInertialFrame = FramesFactory.getEME2000();
654 
655         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
656                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
657                                                              new Binary64(0),
658                                                              new Binary64(0)),
659                                          new FieldVector3D<>(new Binary64(0),
660                                                              new Binary64(7668.631425),
661                                                              new Binary64(0))),
662                 primaryInertialFrame, timeOfClosestApproach, mu);
663 
664         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = MatrixUtils.createFieldIdentityMatrix(field, 6);
665         final FieldStateCovariance<Binary64> primaryCovariance =
666                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
667                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
668 
669         final Binary64 primaryRadius = new Binary64(5);
670 
671         // Define the secondary collision object
672         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
673 
674         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
675                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
676                                                              new Binary64(0),
677                                                              new Binary64(0)),
678                                          new FieldVector3D<>(new Binary64(0),
679                                                              new Binary64(0),
680                                                              new Binary64(7668.631425))),
681                 secondaryInertialFrame, timeOfClosestApproach, mu);
682 
683         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN =
684                 MatrixUtils.createFieldIdentityMatrix(field, 6);
685         secondaryCovarianceMatrixInSecondaryRTN.setEntry(0, 0, new Binary64(199));
686         final FieldStateCovariance<Binary64> secondaryCovariance =
687                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
688                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
689 
690         final Binary64 secondaryRadius = new Binary64(5);
691 
692         // Define custom threshold to test condition where combined covariance matrix is already diagonalized
693         final double CUSTOMZEROTHRESHOLD = 5e-14;
694 
695         final FieldShortTermEncounter2DDefinition<Binary64> collision =
696                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
697                                                           primaryRadius, secondary,
698                                                           secondaryCovariance,
699                                                           secondaryRadius);
700 
701         // WHEN
702         final FieldVector2D<Binary64> secondaryPositionProjectedAndRotatedOntoCollisionPlane =
703                 collision.computeOtherPositionInRotatedCollisionPlane(CUSTOMZEROTHRESHOLD);
704 
705         // THEN
706         Assertions.assertEquals(0, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getX().getReal(), 1e-10);
707         Assertions.assertEquals(-1, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getY().getReal(), 1e-10);
708 
709     }
710 
711     /**
712      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
713      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
714      * same radius as primary. Moreover, they both have the same inertial frame (EME2000).
715      * <p>
716      * Each of the collision object have an identical non diagonal covariance matrix.
717      * </p>
718      * <p>
719      * The goal of this test is to verify that the computed secondary collision object position projected and rotated onto
720      * the collision plane is the same as expected.
721      * </p>
722      */
723     @Test
724     @DisplayName("Test the computation of the secondary collision object position projected and rotated onto the collision plane.")
725     public void testComputeSecondaryPositionProjectedAndRotatedOntoCollisionPlaneWithNonDiagonalCovarianceAsInput() {
726 
727         // GIVEN
728         // Define the time of closest approach and mu
729         final Field<Binary64>             field                 = Binary64Field.getInstance();
730         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
731         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
732 
733         // Define the primary collision object
734         final Frame primaryInertialFrame = FramesFactory.getEME2000();
735 
736         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
737                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
738                                                              new Binary64(0),
739                                                              new Binary64(0)),
740                                          new FieldVector3D<>(new Binary64(0),
741                                                              new Binary64(7668.631425),
742                                                              new Binary64(0))),
743                 primaryInertialFrame, timeOfClosestApproach, mu);
744 
745         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
746                 new Binary64[][] {
747                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
748                           new Binary64(100) },
749                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
750                           new Binary64(100) },
751                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
752                           new Binary64(100) },
753                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
754                           new Binary64(100) },
755                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
756                           new Binary64(100) },
757                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
758                           new Binary64(100) } });
759         final FieldStateCovariance<Binary64> primaryCovariance =
760                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
761                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
762 
763         final Binary64 primaryRadius = new Binary64(5);
764 
765         // Define the secondary collision object
766         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
767 
768         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
769                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
770                                                              new Binary64(0),
771                                                              new Binary64(0)),
772                                          new FieldVector3D<>(new Binary64(0),
773                                                              new Binary64(0),
774                                                              new Binary64(7668.631425))),
775                 secondaryInertialFrame, timeOfClosestApproach, mu);
776 
777         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
778                 new Binary64[][] {
779                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
780                           new Binary64(100) },
781                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
782                           new Binary64(100) },
783                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
784                           new Binary64(100) },
785                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
786                           new Binary64(100) },
787                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
788                           new Binary64(100) },
789                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
790                           new Binary64(100) } });
791         final FieldStateCovariance<Binary64> secondaryCovariance =
792                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
793                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
794 
795         final Binary64 secondaryRadius = new Binary64(5);
796 
797         final FieldShortTermEncounter2DDefinition<Binary64> collision =
798                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
799                                                           primaryRadius, secondary,
800                                                           secondaryCovariance,
801                                                           secondaryRadius);
802 
803         // WHEN
804         final FieldVector2D<Binary64> secondaryPositionProjectedAndRotatedOntoCollisionPlane =
805                 collision.computeOtherPositionInRotatedCollisionPlane(
806                         DEFAULT_ZERO_THRESHOLD);
807 
808         // THEN
809         Assertions.assertEquals(0.8164965809277260, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getX().getReal());
810         Assertions.assertEquals(0.5773502691896257, secondaryPositionProjectedAndRotatedOntoCollisionPlane.getY().getReal());
811 
812     }
813 
814     /**
815      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
816      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
817      * (almost) same radius as primary. Moreover, they both have the same inertial frame (EME2000).
818      * <p>
819      * Each of the collision object have an identical non diagonal covariance matrix.
820      * </p>
821      * <p>
822      * The goal of this test is to verify that the computed mahalanobis distance is the same as expected.
823      * </p>
824      */
825     @Test
826     @DisplayName("Test the computation of the mahalanobis distance")
827     public void testComputeMahalanobisDistance() {
828 
829         // GIVEN
830         // Define the time of closest approach and mu
831         final Field<Binary64>             field                 = Binary64Field.getInstance();
832         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
833         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
834 
835         // Define the primary collision object
836         final Frame primaryInertialFrame = FramesFactory.getEME2000();
837         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
838                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
839                                                              new Binary64(0),
840                                                              new Binary64(0)),
841                                          new FieldVector3D<>(new Binary64(0),
842                                                              new Binary64(7668.631425),
843                                                              new Binary64(0))),
844                 primaryInertialFrame, timeOfClosestApproach, mu);
845         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
846                 new Binary64[][] {
847                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
848                           new Binary64(100) },
849                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
850                           new Binary64(100) },
851                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
852                           new Binary64(100) },
853                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
854                           new Binary64(100) },
855                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
856                           new Binary64(100) },
857                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
858                           new Binary64(100) } });
859         final FieldStateCovariance<Binary64> primaryCovariance =
860                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
861                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
862         final Binary64 primaryRadiusMock = new Binary64(5);
863 
864         // Define the secondary collision object
865         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
866         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
867                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
868                                                              new Binary64(0),
869                                                              new Binary64(0)),
870                                          new FieldVector3D<>(new Binary64(0),
871                                                              new Binary64(0),
872                                                              new Binary64(7668.631425))),
873                 secondaryInertialFrame, timeOfClosestApproach, mu);
874         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
875                 new Binary64[][] {
876                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
877                           new Binary64(100) },
878                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
879                           new Binary64(100) },
880                         { new Binary64(100), new Binary64(100), new Binary64(200), new Binary64(100), new Binary64(100),
881                           new Binary64(100) },
882                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
883                           new Binary64(100) },
884                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
885                           new Binary64(100) },
886                         { new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100), new Binary64(100),
887                           new Binary64(100) } });
888         final FieldStateCovariance<Binary64> secondaryCovariance =
889                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
890                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
891         final Binary64 secondaryRadiusMock = new Binary64(5);
892 
893         final FieldShortTermEncounter2DDefinition<Binary64>
894                 collision = new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
895                                                                       primaryRadiusMock, secondary,
896                                                                       secondaryCovariance,
897                                                                       secondaryRadiusMock);
898 
899         // WHEN
900         final Binary64 mahalanobisDistance1 = FastMath.sqrt(collision.computeSquaredMahalanobisDistance());
901         final Binary64 mahalanobisDistance2 = collision.computeMahalanobisDistance();
902 
903         // THEN
904         Assertions.assertEquals(0.08660254037844388, mahalanobisDistance1.getReal(), 1e-17);
905         Assertions.assertEquals(0.08660254037844388, mahalanobisDistance2.getReal(), 1e-17);
906     }
907 
908     @Test
909     @DisplayName("Test the computation of the mahalanobis distance on Armellin's paper appendix case")
910     public void testComputeExpectedMahalanobisDistanceFromArmellinPaperAppendixCase() {
911 
912         // GIVEN
913         // Define the time of closest approach and mu
914         final Field<Binary64>             field                 = Binary64Field.getInstance();
915         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
916         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
917 
918         // Define the combined radius from Armellin's paper appendix (m)
919         final Binary64 combinedRadius = new Binary64(29.71);
920 
921         // Define the primary collision object according to Armellin's paper appendix
922         final Frame primaryInertialFrame = FramesFactory.getEME2000();
923 
924         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
925                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(2.33052185175137e3),
926                                                              new Binary64(-1.10370451050201e6),
927                                                              new Binary64(7.10588764299718e6)),
928                                          new FieldVector3D<>(new Binary64(-7.44286282871773e3),
929                                                              new Binary64(-6.13734743652660e-1),
930                                                              new Binary64(3.95136139293349e0))),
931                 primaryInertialFrame, timeOfClosestApproach, mu);
932 
933         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
934                 new Binary64[][] { { new Binary64(9.31700905887535e1), new Binary64(-2.623398113500550e2),
935                                      new Binary64(2.360382173935300e1), new Binary64(0), new Binary64(0), new Binary64(0) },
936                                    { new Binary64(-2.623398113500550e2), new Binary64(1.77796454279511e4),
937                                      new Binary64(-9.331225387386501e1), new Binary64(0), new Binary64(0), new Binary64(0) },
938                                    { new Binary64(2.360382173935300e1), new Binary64(-9.331225387386501e1),
939                                      new Binary64(1.917372231880040e1), new Binary64(0), new Binary64(0), new Binary64(0) },
940                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
941                                      new Binary64(0) },
942                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
943                                      new Binary64(0) },
944                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
945                                      new Binary64(0) } });
946         final FieldStateCovariance<Binary64> primaryCovariance =
947                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
948                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
949 
950         final Binary64 primaryRadius = combinedRadius.multiply(0.5);
951 
952         // Define the secondary collision object according to Armellin's paper appendix
953         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
954 
955         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
956                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(2.333465506263321e3),
957                                                              new Binary64(-1.103671212478364e6),
958                                                              new Binary64(7.105914958099038e6)),
959                                          new FieldVector3D<>(new Binary64(7.353740487126315e3),
960                                                              new Binary64(-1.142814049765362e3),
961                                                              new Binary64(-1.982472259113771e2))),
962                 secondaryInertialFrame, timeOfClosestApproach, mu);
963 
964         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
965                 new Binary64[][] { { new Binary64(6.346570910720371e2), new Binary64(-1.962292216245289e3),
966                                      new Binary64(7.077413655227660e1), new Binary64(0), new Binary64(0), new Binary64(0) },
967                                    { new Binary64(-1.962292216245289e3), new Binary64(8.199899363150306e5),
968                                      new Binary64(1.139823810584350e3), new Binary64(0), new Binary64(0), new Binary64(0) },
969                                    { new Binary64(7.077413655227660e1), new Binary64(1.139823810584350e3),
970                                      new Binary64(2.510340829074070e2), new Binary64(0), new Binary64(0), new Binary64(0) },
971                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
972                                      new Binary64(0) },
973                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
974                                      new Binary64(0) },
975                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
976                                      new Binary64(0) } });
977         final FieldStateCovariance<Binary64> secondaryCovariance =
978                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
979                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
980 
981         final Binary64 secondaryRadius = combinedRadius.multiply(0.5);
982 
983         // Defining collision
984         final FieldShortTermEncounter2DDefinition<Binary64> collision =
985                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
986                                                           primaryRadius, secondary,
987                                                           secondaryCovariance,
988                                                           secondaryRadius);
989 
990         // WHEN
991         final Binary64 result = collision.computeMahalanobisDistance(DEFAULT_ZERO_THRESHOLD);
992 
993         // THEN
994         Assertions.assertEquals(0.933624872, result.getReal(), 1e-9);
995     }
996 
997     @Test
998     @DisplayName("Test the computation of the miss distance on Armellin's paper appendix case")
999     public void testComputeExpectedMissDistanceFromArmellinPaperAppendixCase() {
1000 
1001         // GIVEN
1002         // Define the time of closest approach and mu
1003         final Field<Binary64>             field                 = Binary64Field.getInstance();
1004         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
1005         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
1006 
1007         // Define the combined radius from Armellin's paper appendix (m)
1008         final Binary64 combinedRadius = new Binary64(29.71);
1009 
1010         // Define the primary collision object according to Armellin's paper appendix
1011         final Frame primaryInertialFrame = FramesFactory.getEME2000();
1012 
1013         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
1014                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(2.33052185175137e3),
1015                                                              new Binary64(-1.10370451050201e6),
1016                                                              new Binary64(7.10588764299718e6)),
1017                                          new FieldVector3D<>(new Binary64(-7.44286282871773e3),
1018                                                              new Binary64(-6.13734743652660e-1),
1019                                                              new Binary64(3.95136139293349e0))),
1020                 primaryInertialFrame, timeOfClosestApproach, mu);
1021 
1022         @SuppressWarnings("unchecked")
1023         final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
1024 
1025         final Binary64 primaryRadius = combinedRadius.multiply(0.5);
1026 
1027         // Define the secondary collision object according to Armellin's paper appendix
1028         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
1029 
1030         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
1031                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(2.333465506263321e3),
1032                                                              new Binary64(-1.103671212478364e6),
1033                                                              new Binary64(7.105914958099038e6)),
1034                                          new FieldVector3D<>(new Binary64(7.353740487126315e3),
1035                                                              new Binary64(-1.142814049765362e3),
1036                                                              new Binary64(-1.982472259113771e2))),
1037                 secondaryInertialFrame, timeOfClosestApproach, mu);
1038 
1039         @SuppressWarnings("unchecked")
1040         final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
1041 
1042         final Binary64 secondaryRadius = combinedRadius.multiply(0.5);
1043 
1044         // Defining collision
1045         final FieldShortTermEncounter2DDefinition<Binary64> collision =
1046                 new FieldShortTermEncounter2DDefinition<>(primary, primaryCovariance,
1047                                                           primaryRadius, secondary,
1048                                                           secondaryCovariance,
1049                                                           secondaryRadius);
1050 
1051         // WHEN
1052         final Binary64 result = collision.computeMissDistance();
1053 
1054         // THEN
1055         Assertions.assertEquals(43.16871865, result.getReal(), 1e-8);
1056     }
1057 
1058     @Test
1059     @DisplayName("Test mahalanobis distance method on Armellin's data and make statistics")
1060     public void testCompareStatisticsAboutMahalanobisDistanceWithArmellinData() throws IOException {
1061 
1062         // GIVEN & When
1063         final DescriptiveStatistics statistics =
1064                 ArmellinStatistics.getMahalanobisDistanceRelativeDifferenceStatistics();
1065 
1066         // THEN
1067         Assertions.assertTrue(statistics.getMean() <= 1.655252960031764E-10);
1068         Assertions.assertTrue(statistics.getStandardDeviation() <= 5.289370450380533E-10);
1069     }
1070 
1071     @Test
1072     @DisplayName("Test IllegalArgumentException thrown when collision object definition date are different")
1073     void testThrowIllegalArgumentException() {
1074 
1075         // GIVEN
1076         final Field<Binary64> field = Binary64Field.getInstance();
1077 
1078         // Define primary collision object
1079         final FieldAbsoluteDate<Binary64> primaryDate = new FieldAbsoluteDate<>(field);
1080 
1081         @SuppressWarnings("unchecked")
1082         final FieldOrbit<Binary64> primaryMock = Mockito.mock(FieldOrbit.class);
1083 
1084         Mockito.when(primaryMock.getDate()).thenReturn(primaryDate);
1085 
1086         @SuppressWarnings("unchecked")
1087         final FieldStateCovariance<Binary64> primaryCovariance = Mockito.mock(FieldStateCovariance.class);
1088 
1089         final Binary64 primaryRadius = new Binary64(1);
1090 
1091         // Define secondary collision object
1092         final FieldAbsoluteDate<Binary64> secondaryDate = new FieldAbsoluteDate<>(field).shiftedBy(1);
1093 
1094         @SuppressWarnings("unchecked")
1095         final FieldOrbit<Binary64> secondaryMock = Mockito.mock(FieldOrbit.class);
1096 
1097         Mockito.when(secondaryMock.getDate()).thenReturn(secondaryDate);
1098 
1099         @SuppressWarnings("unchecked")
1100         final FieldStateCovariance<Binary64> secondaryCovariance = Mockito.mock(FieldStateCovariance.class);
1101 
1102         final Binary64 secondaryRadius = new Binary64(2);
1103 
1104         // THEN
1105         Assertions.assertThrows(OrekitException.class,
1106                                 () -> new FieldShortTermEncounter2DDefinition<>(primaryMock, primaryCovariance,
1107                                                                                 primaryRadius,
1108                                                                                 secondaryMock, secondaryCovariance,
1109                                                                                 secondaryRadius));
1110 
1111     }
1112 
1113     /**
1114      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
1115      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
1116      * (almost) same radius as primary. Moreover, they both have the same inertial frame (EME2000).
1117      * <p>
1118      * Each of the collision object have an identical non diagonal covariance matrix.
1119      * </p>
1120      * <p>
1121      * The goal of this test is to verify that the computed encounter duration evaluation is the same as expected.
1122      * </p>
1123      */
1124     @Test
1125     @DisplayName("Test Coppola's estimation of conjunction time")
1126     void testComputeShortEncounterDuration() {
1127 
1128         // GIVEN
1129         // Define the time of closest approach and mu
1130         final Field<Binary64>             field                 = Binary64Field.getInstance();
1131         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
1132         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
1133 
1134         // Define the primary collision object
1135         final Frame primaryInertialFrame = FramesFactory.getEME2000();
1136 
1137         final FieldOrbit<Binary64> primary = new FieldCartesianOrbit<>(
1138                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
1139                                                              new Binary64(0),
1140                                                              new Binary64(0)),
1141                                          new FieldVector3D<>(new Binary64(0),
1142                                                              new Binary64(7668.631425),
1143                                                              new Binary64(0))),
1144                 primaryInertialFrame, timeOfClosestApproach, mu);
1145 
1146         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
1147                 new Binary64[][] { { new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1148                                      new Binary64(0) },
1149                                    { new Binary64(0), new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0),
1150                                      new Binary64(0) },
1151                                    { new Binary64(0), new Binary64(0), new Binary64(200), new Binary64(0), new Binary64(0),
1152                                      new Binary64(0) },
1153                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
1154                                      new Binary64(0) },
1155                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
1156                                      new Binary64(0) },
1157                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1158                                      new Binary64(100) } });
1159         final FieldStateCovariance<Binary64> primaryCovariance =
1160                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
1161                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
1162 
1163         final Binary64 primaryRadius = new Binary64(5);
1164 
1165         // Define the secondary collision object
1166         final Frame secondaryInertialFrame = FramesFactory.getEME2000();
1167 
1168         final FieldOrbit<Binary64> secondary = new FieldCartesianOrbit<>(
1169                 new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
1170                                                              new Binary64(0),
1171                                                              new Binary64(0)),
1172                                          new FieldVector3D<>(new Binary64(0),
1173                                                              new Binary64(0),
1174                                                              new Binary64(7668.631425))),
1175                 secondaryInertialFrame, timeOfClosestApproach, mu);
1176 
1177         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
1178                 new Binary64[][] { { new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1179                                      new Binary64(0) },
1180                                    { new Binary64(0), new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0),
1181                                      new Binary64(0) },
1182                                    { new Binary64(0), new Binary64(0), new Binary64(200), new Binary64(0), new Binary64(0),
1183                                      new Binary64(0) },
1184                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
1185                                      new Binary64(0) },
1186                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
1187                                      new Binary64(0) },
1188                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1189                                      new Binary64(100) } });
1190         final FieldStateCovariance<Binary64> secondaryCovariance =
1191                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
1192                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
1193 
1194         final Binary64 secondaryRadius = new Binary64(5);
1195 
1196         final FieldShortTermEncounter2DDefinition<Binary64> collisionDefinition =
1197                 new FieldShortTermEncounter2DDefinition<>(primary,
1198                                                           primaryCovariance,
1199                                                           primaryRadius,
1200                                                           secondary,
1201                                                           secondaryCovariance,
1202                                                           secondaryRadius);
1203 
1204         // WHEN
1205         final Binary64 encounterTimeDuration = collisionDefinition.computeCoppolaEncounterDuration();
1206 
1207         // THEN
1208         Assertions.assertEquals(0.02741114742, encounterTimeDuration.getReal(), 1e-11);
1209     }
1210 
1211     /**
1212      * Test with a primary collision object on a circular equatorial FieldOrbit<Binary64> with a radius of 6778 km with a mu
1213      * = 398600 km^3/s^2. The secondary object is on an intersect course with a circular polar FieldOrbit<Binary64> with the
1214      * (almost) same radius as primary. Moreover, they both have the same inertial frame (EME2000).
1215      * <p>
1216      * Each of the collision object have an identical non diagonal covariance matrix.
1217      * </p>
1218      * <p>
1219      * The goal of this test is to verify that the computed encounter duration evaluation is the same as expected.
1220      * </p>
1221      */
1222     @Test
1223     @DisplayName("Test Coppola's estimation of conjunction time")
1224     void testComputeLongEncounterDuration() {
1225 
1226         // GIVEN
1227         // Define the time of closest approach and mu
1228         final Field<Binary64>             field                 = Binary64Field.getInstance();
1229         final FieldAbsoluteDate<Binary64> timeOfClosestApproach = new FieldAbsoluteDate<>(field);
1230         final Binary64                    mu                    = new Binary64(Constants.IERS2010_EARTH_MU);
1231 
1232         // Define the primary collision object
1233         final Frame primaryInertialFrame = FramesFactory.getEME2000();
1234 
1235         final FieldOrbit<Binary64> primary =
1236                 new FieldCartesianOrbit<>(new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000),
1237                                                                                        new Binary64(0),
1238                                                                                        new Binary64(0)),
1239                                                                    new FieldVector3D<>(new Binary64(0),
1240                                                                                        new Binary64(7668.631425),
1241                                                                                        new Binary64(0))),
1242                                           primaryInertialFrame, timeOfClosestApproach, mu);
1243 
1244         final FieldMatrix<Binary64> primaryCovarianceMatrixInPrimaryRTN = new BlockFieldMatrix<>(
1245                 new Binary64[][] {
1246                         { new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1247                           new Binary64(0) },
1248                         { new Binary64(0), new Binary64(100), new Binary64(0), new Binary64(0), new Binary64(0),
1249                           new Binary64(0) },
1250                         { new Binary64(0), new Binary64(0), new Binary64(200), new Binary64(0), new Binary64(0),
1251                           new Binary64(0) },
1252                         { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
1253                           new Binary64(0) },
1254                         { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
1255                           new Binary64(0) },
1256                         { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1257                           new Binary64(100) } });
1258         final FieldStateCovariance<Binary64> primaryCovariance =
1259                 new FieldStateCovariance<>(primaryCovarianceMatrixInPrimaryRTN,
1260                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
1261         final Binary64 primaryRadius = new Binary64(5);
1262 
1263         // Define the secondary collision object
1264         final Binary64 angleInRad             = new Binary64(FastMath.toRadians(0.01));
1265         final Frame    secondaryInertialFrame = FramesFactory.getEME2000();
1266 
1267         final FieldOrbit<Binary64> secondary =
1268                 new FieldCartesianOrbit<>(new FieldPVCoordinates<>(new FieldVector3D<>(new Binary64(6778000 + 1),
1269                                                                                        new Binary64(0),
1270                                                                                        new Binary64(0)),
1271                                                                    new FieldVector3D<>(new Binary64(0),
1272                                                                                        angleInRad.cos()
1273                                                                                                  .multiply(7668.631425),
1274                                                                                        angleInRad.sin()
1275                                                                                                  .multiply(-7668.631425))),
1276                                           secondaryInertialFrame, timeOfClosestApproach, mu);
1277 
1278         final FieldMatrix<Binary64> secondaryCovarianceMatrixInSecondaryRTN = new BlockFieldMatrix<>(
1279                 new Binary64[][] { { new Binary64(100), new Binary64(50), new Binary64(40), new Binary64(0), new Binary64(0),
1280                                      new Binary64(0) },
1281                                    { new Binary64(50), new Binary64(100), new Binary64(30), new Binary64(0), new Binary64(0),
1282                                      new Binary64(0) },
1283                                    { new Binary64(40), new Binary64(30), new Binary64(200), new Binary64(0), new Binary64(0),
1284                                      new Binary64(0) },
1285                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100), new Binary64(0),
1286                                      new Binary64(0) },
1287                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(100),
1288                                      new Binary64(0) },
1289                                    { new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0), new Binary64(0),
1290                                      new Binary64(100) } });
1291         final FieldStateCovariance<Binary64> secondaryCovariance =
1292                 new FieldStateCovariance<>(secondaryCovarianceMatrixInSecondaryRTN,
1293                                            timeOfClosestApproach, LOFType.QSW_INERTIAL);
1294 
1295         final Binary64 secondaryRadius = new Binary64(5);
1296 
1297         final FieldShortTermEncounter2DDefinition<Binary64>
1298                 collisionDefinition = new FieldShortTermEncounter2DDefinition<>(primary,
1299                                                                                 primaryCovariance,
1300                                                                                 primaryRadius,
1301                                                                                 secondary,
1302                                                                                 secondaryCovariance,
1303                                                                                 secondaryRadius);
1304 
1305         // WHEN
1306         final Binary64 encounterTimeDuration = collisionDefinition.computeCoppolaEncounterDuration();
1307 
1308         // THEN
1309         Assertions.assertEquals(254.56056997152353, encounterTimeDuration.getReal(), 1e-14);
1310 
1311     }
1312 
1313     @Test
1314     @DisplayName("Test FieldShortTermEncounter2DDefinition<Binary64> getters")
1315     void testReturnInitialInstances() {
1316         // GIVEN
1317         final Field<Binary64>             field = Binary64Field.getInstance();
1318         final FieldAbsoluteDate<Binary64> tca   = new FieldAbsoluteDate<>(field);
1319 
1320         @SuppressWarnings("unchecked")
1321         final FieldOrbit<Binary64> referenceOrbit = Mockito.mock(FieldCartesianOrbit.class);
1322         @SuppressWarnings("unchecked")
1323         final FieldStateCovariance<Binary64> referenceCovariance = Mockito.mock(FieldStateCovariance.class);
1324         final Binary64 referenceRadius = new Binary64(5);
1325 
1326         @SuppressWarnings("unchecked")
1327         final FieldOrbit<Binary64> otherOrbit = Mockito.mock(FieldCartesianOrbit.class);
1328         @SuppressWarnings("unchecked")
1329         final FieldStateCovariance<Binary64> otherCovariance = Mockito.mock(FieldStateCovariance.class);
1330         final Binary64 otherRadius = new Binary64(5);
1331 
1332         Mockito.when(referenceOrbit.getDate()).thenReturn(tca);
1333         Mockito.when(otherOrbit.getDate()).thenReturn(tca);
1334 
1335         final FieldShortTermEncounter2DDefinition<Binary64> encounter =
1336                 new FieldShortTermEncounter2DDefinition<>(referenceOrbit, referenceCovariance,
1337                                                           referenceRadius, otherOrbit,
1338                                                           otherCovariance, otherRadius);
1339 
1340         // WHEN
1341         final FieldAbsoluteDate<Binary64> gottenTCA = encounter.getTca();
1342 
1343         final FieldOrbit<Binary64>           gottenReferenceOrbit      = encounter.getReferenceAtTCA();
1344         final FieldStateCovariance<Binary64> gottenReferenceCovariance = encounter.getReferenceCovariance();
1345 
1346         final FieldOrbit<Binary64>           gottenOtherOrbit      = encounter.getOtherAtTCA();
1347         final FieldStateCovariance<Binary64> gottenOtherCovariance = encounter.getOtherCovariance();
1348 
1349         // THEN
1350         Assertions.assertEquals(tca, gottenTCA);
1351         Assertions.assertEquals(referenceOrbit, gottenReferenceOrbit);
1352         Assertions.assertEquals(referenceCovariance, gottenReferenceCovariance);
1353         Assertions.assertEquals(otherOrbit, gottenOtherOrbit);
1354         Assertions.assertEquals(otherCovariance, gottenOtherCovariance);
1355     }
1356 
1357     @Test
1358     void testConversionToNonFieldEquivalent() {
1359 
1360         // GIVEN
1361         final AbsoluteDate                DEFAULT_DATE       = new AbsoluteDate();
1362         final FieldAbsoluteDate<Binary64> DEFAULT_FIELD_DATE = new FieldAbsoluteDate<>(Binary64Field.getInstance());
1363 
1364         // Create non field version
1365         final Orbit referenceOrbitMock = Mockito.mock(Orbit.class);
1366         Mockito.when(referenceOrbitMock.getDate()).thenReturn(DEFAULT_DATE);
1367         final StateCovariance referenceCovarianceMock = Mockito.mock(StateCovariance.class);
1368 
1369         final Orbit otherOrbitMock = Mockito.mock(Orbit.class);
1370         Mockito.when(otherOrbitMock.getDate()).thenReturn(DEFAULT_DATE);
1371         final StateCovariance otherCovarianceMock = Mockito.mock(StateCovariance.class);
1372 
1373         final double combinedRadius = 1;
1374 
1375         // Create field equivalent
1376         @SuppressWarnings("unchecked")
1377         final FieldOrbit<Binary64> fieldReferenceOrbitMock = Mockito.mock(FieldOrbit.class);
1378         Mockito.when(fieldReferenceOrbitMock.getDate()).thenReturn(DEFAULT_FIELD_DATE);
1379         Mockito.when(fieldReferenceOrbitMock.toOrbit()).thenReturn(referenceOrbitMock);
1380 
1381         @SuppressWarnings("unchecked")
1382         final FieldStateCovariance<Binary64> fieldReferenceCovarianceMock = Mockito.mock(FieldStateCovariance.class);
1383         Mockito.when(fieldReferenceCovarianceMock.toStateCovariance()).thenReturn(referenceCovarianceMock);
1384 
1385         @SuppressWarnings("unchecked")
1386         final FieldOrbit<Binary64> fieldOtherOrbitMock = Mockito.mock(FieldOrbit.class);
1387         Mockito.when(fieldOtherOrbitMock.getDate()).thenReturn(DEFAULT_FIELD_DATE);
1388         Mockito.when(fieldOtherOrbitMock.toOrbit()).thenReturn(otherOrbitMock);
1389 
1390         @SuppressWarnings("unchecked")
1391         final FieldStateCovariance<Binary64> fieldOtherCovarianceMock = Mockito.mock(FieldStateCovariance.class);
1392         Mockito.when(fieldOtherCovarianceMock.toStateCovariance()).thenReturn(otherCovarianceMock);
1393 
1394         final Binary64 fieldCombinedRadiusMock = Mockito.mock(Binary64.class);
1395         Mockito.when(fieldCombinedRadiusMock.getReal()).thenReturn(combinedRadius);
1396 
1397         final FieldShortTermEncounter2DDefinition<Binary64> fieldEncounter =
1398                 new FieldShortTermEncounter2DDefinition<>(fieldReferenceOrbitMock, fieldReferenceCovarianceMock,
1399                                                           fieldOtherOrbitMock, fieldOtherCovarianceMock,
1400                                                           fieldCombinedRadiusMock);
1401 
1402         // WHEN
1403         final ShortTermEncounter2DDefinition encounter = fieldEncounter.toEncounter();
1404 
1405         // THEN
1406         Assertions.assertEquals(referenceOrbitMock, encounter.getReferenceAtTCA());
1407         Assertions.assertEquals(referenceCovarianceMock, encounter.getReferenceCovariance());
1408         Assertions.assertEquals(otherOrbitMock, encounter.getOtherAtTCA());
1409         Assertions.assertEquals(otherCovarianceMock, encounter.getOtherCovariance());
1410         Assertions.assertEquals(combinedRadius, encounter.getCombinedRadius());
1411     }
1412 }