1   /* Copyright 2013-2025 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.rugged.utils;
18  
19  import java.io.File;
20  import java.net.URISyntaxException;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.List;
25  
26  import org.hipparchus.geometry.euclidean.threed.Vector3D;
27  import org.hipparchus.util.FastMath;
28  import org.junit.jupiter.api.AfterEach;
29  import org.junit.jupiter.api.Assertions;
30  import org.junit.jupiter.api.BeforeEach;
31  import org.junit.jupiter.params.ParameterizedTest;
32  import org.junit.jupiter.params.provider.MethodSource;
33  import org.orekit.bodies.BodyShape;
34  import org.orekit.data.DataContext;
35  import org.orekit.data.DirectoryCrawler;
36  import org.orekit.errors.OrekitException;
37  import org.orekit.frames.FramesFactory;
38  import org.orekit.orbits.Orbit;
39  import org.orekit.rugged.TestUtils;
40  import org.orekit.rugged.errors.RuggedException;
41  import org.orekit.rugged.errors.RuggedMessages;
42  import org.orekit.rugged.linesensor.LineSensor;
43  import org.orekit.rugged.linesensor.LinearLineDatation;
44  import org.orekit.rugged.los.LOSBuilder;
45  import org.orekit.time.AbsoluteDate;
46  import org.orekit.utils.AngularDerivativesFilter;
47  import org.orekit.utils.CartesianDerivativesFilter;
48  import org.orekit.utils.Constants;
49  import org.orekit.utils.TimeStampedAngularCoordinates;
50  import org.orekit.utils.TimeStampedPVCoordinates;
51  
52  
53  public class SpacecraftToObservedBodyTest {
54  
55  	public static Collection<Object[]> data() {
56  		return Arrays.asList(new Object[][] {
57  			// Run multiple times the tests, constructing this class with the following parameters
58  			{ +10, +1., -1., +1}, { -1., -10., -1., +1}, { -1., +1., +15., +1}, { -1., +1., -1., -15.}
59  		});
60  	}
61  	   
62  	// configuration of the run : shift of date for PV and Q (min and max values)
63  	private double shiftPVmin;
64  	private double shiftPVmax;
65  	private double shiftQmin;
66  	private double shiftQmax;
67  
68  
69      @MethodSource("data")
70      @ParameterizedTest
71      public void testIssue256(double shiftPVmin, double shiftPVmax, double shiftQmin, double shiftQmax) {
72  
73          initSpacecraftToObservedBodyTest(shiftPVmin, shiftPVmax, shiftQmin, shiftQmax);
74          
75          AbsoluteDate minSensorDate = sensor.getDate(0);
76          AbsoluteDate maxSensorDate = sensor.getDate(2000);
77          
78          AbsoluteDate minPVdate = minSensorDate.shiftedBy(this.shiftPVmin);
79          AbsoluteDate maxPVdate = maxSensorDate.shiftedBy(this.shiftPVmax);
80          List<TimeStampedPVCoordinates> pvList = TestUtils.orbitToPV(orbit, earth, minPVdate, maxPVdate, 0.25);
81          
82          AbsoluteDate minQdate = minSensorDate.shiftedBy(this.shiftQmin);
83          AbsoluteDate maxQdate = maxSensorDate.shiftedBy(this.shiftQmax);
84          List<TimeStampedAngularCoordinates> qList = TestUtils.orbitToQ(orbit, earth, minQdate, maxQdate, 0.25);
85          
86          try {
87          
88      	new SpacecraftToObservedBody(FramesFactory.getEME2000(), earth.getBodyFrame(),
89                  minSensorDate, maxSensorDate, 0.01,
90                  5.0,
91                  pvList,
92                  8, CartesianDerivativesFilter.USE_PV,
93                  qList,
94                  2, AngularDerivativesFilter.USE_R);
95          Assertions.fail("an exception should have been thrown");
96      	
97          } catch (RuggedException re){
98              Assertions.assertEquals(RuggedMessages.OUT_OF_TIME_RANGE, re.getSpecifier());
99          }        	
100     }
101 
102 
103     public void initSpacecraftToObservedBodyTest(double shiftPVmin, double shiftPVmax, double shiftQmin, double shiftQmax) {
104 		this.shiftPVmin = shiftPVmin;
105 		this.shiftPVmax = shiftPVmax;
106 		this.shiftQmin = shiftQmin;
107 		this.shiftQmax = shiftQmax;
108 	}
109 	
110 
111     @BeforeEach
112     public void setUp() {
113         try {
114 
115             String path = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
116             DataContext.getDefault().getDataProvidersManager().addProvider(new DirectoryCrawler(new File(path)));
117 
118             earth = TestUtils.createEarth();
119             orbit = TestUtils.createOrbit(Constants.EIGEN5C_EARTH_MU);
120             
121             // build lists of pixels regularly spread on a perfect plane
122             final Vector3D position  = new Vector3D(1.5, Vector3D.PLUS_I);
123             final Vector3D normal    = Vector3D.PLUS_I;
124             final Vector3D fovCenter = Vector3D.PLUS_K;
125             final Vector3D cross     = Vector3D.crossProduct(normal, fovCenter);
126             
127             final List<Vector3D> los = new ArrayList<Vector3D>();
128             for (int i = -1000; i <= 1000; ++i) {
129                 final double alpha = i * 0.17 / 1000;
130                 los.add(new Vector3D(FastMath.cos(alpha), fovCenter, FastMath.sin(alpha), cross));
131             }
132             sensor = new LineSensor("perfect line", new LinearLineDatation(AbsoluteDate.J2000_EPOCH, 0.0, 1.0 / 1.5e-3),
133                                     position, new LOSBuilder(los).build());
134             
135 
136         } catch (OrekitException oe) {
137             Assertions.fail(oe.getLocalizedMessage());
138         } catch (URISyntaxException use) {
139             Assertions.fail(use.getLocalizedMessage());
140         }
141     }
142 
143     @AfterEach
144     public void tearDown() {
145     }
146 
147 	private BodyShape  earth = null;
148 	private Orbit      orbit = null;
149 	private LineSensor sensor = null;
150 	
151 }