1   /* Copyright 2022-2025 Romain Serra
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.propagation.events;
18  
19  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
20  import org.hipparchus.geometry.euclidean.threed.Vector3D;
21  import org.hipparchus.util.Binary64;
22  import org.hipparchus.util.Binary64Field;
23  import org.junit.jupiter.api.Assertions;
24  import org.junit.jupiter.api.Test;
25  import org.orekit.TestUtils;
26  import org.orekit.frames.TopocentricFrame;
27  import org.orekit.models.AtmosphericRefractionModel;
28  import org.orekit.models.earth.ITURP834AtmosphericRefraction;
29  import org.orekit.propagation.FieldSpacecraftState;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.propagation.events.handlers.FieldEventHandler;
32  import org.orekit.propagation.events.handlers.FieldStopOnEvent;
33  import org.orekit.time.AbsoluteDate;
34  import org.orekit.utils.Constants;
35  import org.orekit.utils.ExtendedPositionProvider;
36  
37  import static org.junit.jupiter.api.Assertions.*;
38  import static org.mockito.Mockito.mock;
39  import static org.mockito.Mockito.when;
40  
41  class FieldGroundAtNightDetectorTest {
42  
43      @Test
44      void testDependsOnlyOnTime() {
45          // GIVEN
46          final FieldGroundAtNightDetector<Binary64> fieldDetector = new FieldGroundAtNightDetector<>(mock(TopocentricFrame.class),
47                  null, Binary64.ZERO, null);
48          // WHEN
49          final boolean value = fieldDetector.dependsOnTimeOnly();
50          // THEN
51          Assertions.assertTrue(value);
52      }
53  
54      @Test
55      void testGRefraction() {
56          // GIVEN
57          final Binary64Field field = Binary64Field.getInstance();
58          final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH));
59          final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
60          final TopocentricFrame frame = mock();
61          final Vector3D sunPosition = Vector3D.PLUS_J.scalarMultiply(Constants.JPL_SSD_ASTRONOMICAL_UNIT);
62          final FieldVector3D<Binary64> fieldSunPosition = new FieldVector3D<>(field, sunPosition);
63          when(frame.getElevation(fieldSunPosition, state.getFrame(), fieldState.getDate())).thenReturn(fieldSunPosition.getDelta());
64          when(frame.getElevation(sunPosition, state.getFrame(), state.getDate())).thenReturn(sunPosition.getDelta());
65          final ExtendedPositionProvider provider = mock();
66          when(provider.getPosition(fieldState.getDate(), fieldState.getFrame())).thenReturn(fieldSunPosition);
67          when(provider.getPosition(state.getDate(), state.getFrame())).thenReturn(sunPosition);
68          final Binary64 duskDawnElevation = Binary64.ZERO;
69          final AtmosphericRefractionModel model = new ITURP834AtmosphericRefraction(0.);
70          final FieldGroundAtNightDetector<Binary64> fieldDetector = new FieldGroundAtNightDetector<>(frame, provider,
71                  duskDawnElevation,  model);
72          // WHEN
73          final Binary64 actualG = fieldDetector.g(fieldState);
74          // THEN
75          final GroundAtNightDetector detector = new GroundAtNightDetector(frame, provider, duskDawnElevation.getReal(), model);
76          assertEquals(detector.g(state), actualG.getReal());
77      }
78  
79      @Test
80      void testG() {
81          // GIVEN
82          final Binary64Field field = Binary64Field.getInstance();
83          final SpacecraftState state = new SpacecraftState(TestUtils.getDefaultOrbit(AbsoluteDate.ARBITRARY_EPOCH));
84          final FieldSpacecraftState<Binary64> fieldState = new FieldSpacecraftState<>(field, state);
85          final TopocentricFrame frame = mock();
86          final Vector3D sunPosition = Vector3D.PLUS_J.scalarMultiply(Constants.JPL_SSD_ASTRONOMICAL_UNIT);
87          final FieldVector3D<Binary64> fieldSunPosition = new FieldVector3D<>(field, sunPosition);
88          when(frame.getElevation(fieldSunPosition, state.getFrame(), fieldState.getDate())).thenReturn(fieldSunPosition.getDelta());
89          final ExtendedPositionProvider provider = mock();
90          when(provider.getPosition(fieldState.getDate(), fieldState.getFrame())).thenReturn(fieldSunPosition);
91          final Binary64 duskDawnElevation = Binary64.ONE;
92          final FieldGroundAtNightDetector<Binary64> detector = new FieldGroundAtNightDetector<>(frame, provider,
93                  duskDawnElevation,  null);
94          // WHEN
95          final Binary64 actualG = detector.g(fieldState);
96          // THEN
97          assertEquals(fieldSunPosition.getDelta().subtract(duskDawnElevation).negate(), actualG);
98      }
99  
100     @Test
101     void testCreate() {
102         // GIVEN
103         final TopocentricFrame mockedFrame = mock();
104         final ExtendedPositionProvider mockedProvider = mock();
105         final FieldGroundAtNightDetector<Binary64> detector = new FieldGroundAtNightDetector<>(mockedFrame, mockedProvider,
106                 Binary64.ZERO,  null);
107         final FieldEventDetectionSettings<Binary64> detectionSettings = new FieldEventDetectionSettings<>(Binary64Field.getInstance(),
108                 EventDetectionSettings.getDefaultEventDetectionSettings());
109         final FieldEventHandler<Binary64> expectedHandler = new FieldStopOnEvent<>();
110         // WHEN
111         final FieldGroundAtNightDetector<Binary64> createdDetector = detector.create(detectionSettings, expectedHandler);
112         // THEN
113         assertEquals(detector.getTopocentricFrame(), createdDetector.getTopocentricFrame());
114         assertEquals(detectionSettings, createdDetector.getDetectionSettings());
115         assertEquals(expectedHandler, createdDetector.getHandler());
116     }
117 }
118