1   /* Copyright 2002-2022 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.propagation.analytical.gnss;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.hipparchus.util.FastMath;
24  import org.junit.Assert;
25  import org.junit.BeforeClass;
26  import org.junit.Test;
27  import org.orekit.Utils;
28  import org.orekit.data.DataContext;
29  import org.orekit.errors.OrekitException;
30  import org.orekit.errors.OrekitMessages;
31  import org.orekit.frames.Frame;
32  import org.orekit.frames.Frames;
33  import org.orekit.frames.FramesFactory;
34  import org.orekit.gnss.SatelliteSystem;
35  import org.orekit.propagation.analytical.gnss.data.GNSSOrbitalElements;
36  import org.orekit.propagation.analytical.gnss.data.IRNSSAlmanac;
37  import org.orekit.time.AbsoluteDate;
38  import org.orekit.time.GNSSDate;
39  import org.orekit.time.TimeScalesFactory;
40  import org.orekit.utils.CartesianDerivativesFilter;
41  import org.orekit.utils.Constants;
42  import org.orekit.utils.PVCoordinates;
43  import org.orekit.utils.TimeStampedPVCoordinates;
44  
45  public class IRNSSPropagatorTest {
46  
47      private static IRNSSAlmanac almanac;
48      private static Frames frames;
49  
50      @BeforeClass
51      public static void setUpBeforeClass() {
52          Utils.setDataRoot("gnss");
53  
54          // Almanac for satellite 1 for April 1st 2014 (Source: Rinex 3.04 format - Table A19)
55          almanac = new IRNSSAlmanac();
56          almanac.setPRN(1);
57          almanac.setWeek(1786);
58          almanac.setTime(172800.0);
59          almanac.setSqrtA(6.493487739563E03);
60          almanac.setE(2.257102518342E-03);
61          almanac.setI0(4.758105460020e-01);
62          almanac.setOmega0(-8.912102146884E-01);
63          almanac.setOmegaDot(-4.414469594664e-09);
64          almanac.setPa(-2.999907424014);
65          almanac.setM0(-1.396094758025);
66          almanac.setAf0(-9.473115205765e-04);
67          almanac.setAf1(1.250555214938e-12);
68          almanac.setDate(new GNSSDate(almanac.getWeek(), 1000.0 * almanac.getTime(), SatelliteSystem.IRNSS).getDate());
69  
70          frames = DataContext.getDefault().getFrames();
71      }
72  
73      @Test
74      public void testIRNSSCycle() {
75          // Builds the IRNSS propagator from the almanac
76          final GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
77          // Propagate at the IRNSS date and one IRNSS cycle later
78          final AbsoluteDate date0 = almanac.getDate();
79          final Vector3D p0 = propagator.propagateInEcef(date0).getPosition();
80          final double bdtCycleDuration = almanac.getCycleDuration();
81          final AbsoluteDate date1 = date0.shiftedBy(bdtCycleDuration);
82          final Vector3D p1 = propagator.propagateInEcef(date1).getPosition();
83  
84          // Checks
85          Assert.assertEquals(0., p0.distance(p1), 0.);
86      }
87  
88      @Test
89      public void testFrames() {
90          // Builds the IRNSS propagator from the almanac
91          final GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
92          Assert.assertEquals("EME2000", propagator.getFrame().getName());
93          Assert.assertEquals(3.986005e+14, almanac.getMu(), 1.0e6);
94          // Defines some date
95          final AbsoluteDate date = new AbsoluteDate(2016, 3, 3, 12, 0, 0., TimeScalesFactory.getUTC());
96          // Get PVCoordinates at the date in the ECEF
97          final PVCoordinates pv0 = propagator.propagateInEcef(date);
98          // Get PVCoordinates at the date in the ECEF
99          final PVCoordinates pv1 = propagator.getPVCoordinates(date, propagator.getECEF());
100 
101         // Checks
102         Assert.assertEquals(0., pv0.getPosition().distance(pv1.getPosition()), 3.3e-8);
103         Assert.assertEquals(0., pv0.getVelocity().distance(pv1.getVelocity()), 3.9e-12);
104     }
105 
106     @Test
107     public void testNoReset() {
108         try {
109             GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
110             propagator.resetInitialState(propagator.getInitialState());
111             Assert.fail("an exception should have been thrown");
112         } catch (OrekitException oe) {
113             Assert.assertEquals(OrekitMessages.NON_RESETABLE_STATE, oe.getSpecifier());
114         }
115         try {
116             GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
117             propagator.resetIntermediateState(propagator.getInitialState(), true);
118             Assert.fail("an exception should have been thrown");
119         } catch (OrekitException oe) {
120             Assert.assertEquals(OrekitMessages.NON_RESETABLE_STATE, oe.getSpecifier());
121         }
122     }
123 
124     @Test
125     public void testDerivativesConsistency() {
126 
127         final Frame eme2000 = FramesFactory.getEME2000();
128         double errorP = 0;
129         double errorV = 0;
130         double errorA = 0;
131         GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
132         GNSSOrbitalElements elements = propagator.getOrbitalElements();
133         AbsoluteDate t0 = new GNSSDate(elements.getWeek(), 0.001 * elements.getTime(), SatelliteSystem.IRNSS).getDate();
134         for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 600) {
135             final AbsoluteDate central = t0.shiftedBy(dt);
136             final PVCoordinates pv = propagator.getPVCoordinates(central, eme2000);
137             final double h = 10.0;
138             List<TimeStampedPVCoordinates> sample = new ArrayList<TimeStampedPVCoordinates>();
139             for (int i = -3; i <= 3; ++i) {
140                 sample.add(propagator.getPVCoordinates(central.shiftedBy(i * h), eme2000));
141             }
142             final PVCoordinates interpolated =
143                             TimeStampedPVCoordinates.interpolate(central,
144                                                                  CartesianDerivativesFilter.USE_P,
145                                                                  sample);
146             errorP = FastMath.max(errorP, Vector3D.distance(pv.getPosition(), interpolated.getPosition()));
147             errorV = FastMath.max(errorV, Vector3D.distance(pv.getVelocity(), interpolated.getVelocity()));
148             errorA = FastMath.max(errorA, Vector3D.distance(pv.getAcceleration(), interpolated.getAcceleration()));
149         }
150 
151         Assert.assertEquals(0.0, errorP, 3.8e-9);
152         Assert.assertEquals(0.0, errorV, 2.6e-7);
153         Assert.assertEquals(0.0, errorA, 6.5e-8);
154 
155     }
156 
157     @Test
158     public void testIssue544() {
159         // Builds the IRNSSPropagator from the almanac
160         final GNSSPropagator propagator = new GNSSPropagatorBuilder(almanac, frames).build();
161         // In order to test the issue, we voluntary set a Double.NaN value in the date.
162         final AbsoluteDate date0 = new AbsoluteDate(2010, 5, 7, 7, 50, Double.NaN, TimeScalesFactory.getUTC());
163         final PVCoordinates pv0 = propagator.propagateInEcef(date0);
164         // Verify that an infinite loop did not occur
165         Assert.assertEquals(Vector3D.NaN, pv0.getPosition());
166         Assert.assertEquals(Vector3D.NaN, pv0.getVelocity());
167     }
168 
169 }