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.Before;
26  import org.junit.BeforeClass;
27  import org.junit.Test;
28  import org.orekit.Utils;
29  import org.orekit.data.DataContext;
30  import org.orekit.errors.OrekitException;
31  import org.orekit.errors.OrekitMessages;
32  import org.orekit.frames.Frame;
33  import org.orekit.frames.Frames;
34  import org.orekit.frames.FramesFactory;
35  import org.orekit.gnss.SatelliteSystem;
36  import org.orekit.propagation.analytical.gnss.data.GNSSConstants;
37  import org.orekit.propagation.analytical.gnss.data.SBASNavigationMessage;
38  import org.orekit.propagation.analytical.gnss.data.SBASOrbitalElements;
39  import org.orekit.time.AbsoluteDate;
40  import org.orekit.time.GNSSDate;
41  import org.orekit.time.TimeScalesFactory;
42  import org.orekit.utils.CartesianDerivativesFilter;
43  import org.orekit.utils.Constants;
44  import org.orekit.utils.IERSConventions;
45  import org.orekit.utils.PVCoordinates;
46  import org.orekit.utils.TimeStampedPVCoordinates;
47  
48  
49  public class SBASPropagatorTest {
50  
51      /** Threshold for test validation. */
52      private static double eps = 1.0e-15;
53  
54      /** SBAS orbital elements. */
55      private SBASNavigationMessage soe;
56      private Frames frames;
57      
58      @Before
59      public void setUp() {
60          // Reference data are taken from IGS file brdm0370.17p
61          soe = new SBASNavigationMessage();
62          soe.setPRN(127);
63          soe.setTime(1.23303e+05);;
64          soe.setDate(new GNSSDate(1935, 1.23303e+05 * 1000.0, SatelliteSystem.SBAS).getDate());
65          soe.setX(2.406022248000e+07);
66          soe.setXDot(-2.712500000000e-01);
67          soe.setXDotDot(3.250000000000e-04);
68          soe.setY(3.460922568000e+07);
69          soe.setYDot(3.063125000000e-00);
70          soe.setYDotDot(-1.500000000000e-04);
71          soe.setZ(1.964040000000e+04);
72          soe.setZDot(1.012000000000e-00);
73          soe.setZDotDot(-1.250000000000e-04);
74          frames = DataContext.getDefault().getFrames();
75      }
76  
77      @BeforeClass
78      public static void setUpBeforeClass() {
79          Utils.setDataRoot("gnss");
80      }
81  
82      @Test
83      public void testPropagationAtReferenceTime() {
84          // SBAS propagator
85          final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).
86                          attitudeProvider(Utils.defaultLaw()).
87                          mu(GNSSConstants.SBAS_MU).
88                          mass(SBASPropagator.DEFAULT_MASS).
89                          eci(FramesFactory.getEME2000()).
90                          ecef(FramesFactory.getITRF(IERSConventions.IERS_2010, true)).
91                          build();
92          // Propagation
93          final PVCoordinates pv = propagator.propagateInEcef(soe.getDate());
94          // Position/Velocity/Acceleration
95          final Vector3D position = pv.getPosition();
96          final Vector3D velocity = pv.getVelocity();
97          final Vector3D acceleration = pv.getAcceleration();
98          // Verify
99          Assert.assertEquals(soe.getX(),       position.getX(),     eps);
100         Assert.assertEquals(soe.getY(),       position.getY(),     eps);
101         Assert.assertEquals(soe.getZ(),       position.getZ(),     eps);
102         Assert.assertEquals(soe.getXDot(),    velocity.getX(),     eps);
103         Assert.assertEquals(soe.getYDot(),    velocity.getY(),     eps);
104         Assert.assertEquals(soe.getZDot(),    velocity.getZ(),     eps);
105         Assert.assertEquals(soe.getXDotDot(), acceleration.getX(), eps);
106         Assert.assertEquals(soe.getYDotDot(), acceleration.getY(), eps);
107         Assert.assertEquals(soe.getZDotDot(), acceleration.getZ(), eps);
108     }
109 
110     @Test
111     public void testPropagation() {
112         // SBAS propagator
113         final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).build();
114         // Propagation
115         final PVCoordinates pv = propagator.propagateInEcef(soe.getDate().shiftedBy(1.0));
116         // Position/Velocity/Acceleration
117         final Vector3D position = pv.getPosition();
118         final Vector3D velocity = pv.getVelocity();
119         final Vector3D acceleration = pv.getAcceleration();
120         // Verify
121         Assert.assertEquals(24060222.2089125, position.getX(),     eps);
122         Assert.assertEquals(34609228.7430500, position.getY(),     eps);
123         Assert.assertEquals(19641.4119375,    position.getZ(),     eps);
124         Assert.assertEquals(-0.270925,        velocity.getX(),     eps);
125         Assert.assertEquals(3.062975,         velocity.getY(),     eps);
126         Assert.assertEquals(1.011875,         velocity.getZ(),     eps);
127         Assert.assertEquals(soe.getXDotDot(), acceleration.getX(), eps);
128         Assert.assertEquals(soe.getYDotDot(), acceleration.getY(), eps);
129         Assert.assertEquals(soe.getZDotDot(), acceleration.getZ(), eps);
130     }
131 
132     @Test
133     public void testFrames() {
134         // Builds the SBAS propagator from the ephemeris
135         final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).build();
136         Assert.assertEquals("EME2000", propagator.getFrame().getName());
137         Assert.assertEquals(3.986005e+14, propagator.getMU(), 1.0e6);
138         Assert.assertEquals(propagator.getECI().getName(), propagator.getFrame().getName());
139         // Defines some date
140         final AbsoluteDate date = new AbsoluteDate(2017, 2, 3, 12, 0, 0., TimeScalesFactory.getUTC());
141         // Get PVCoordinates at the date in the ECEF
142         final PVCoordinates pv0 = propagator.propagateInEcef(date);
143         // Get PVCoordinates at the date in the ECEF
144         final PVCoordinates pv1 = propagator.getPVCoordinates(date, propagator.getECEF());
145 
146         // Checks
147         Assert.assertEquals(0., pv0.getPosition().distance(pv1.getPosition()), 7.7e-9);
148         Assert.assertEquals(0., pv0.getVelocity().distance(pv1.getVelocity()), 3.8e-12);
149     }
150 
151     @Test
152     public void testDerivativesConsistency() {
153 
154         final Frame eme2000 = FramesFactory.getEME2000();
155         double errorP = 0;
156         double errorV = 0;
157         double errorA = 0;
158         final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).build();
159         SBASOrbitalElements elements = propagator.getSBASOrbitalElements();
160         AbsoluteDate t0 = new GNSSDate(elements.getWeek(), 1000.0 * elements.getTime(), SatelliteSystem.SBAS).getDate();
161         for (double dt = 0; dt < Constants.JULIAN_DAY; dt += 600) {
162             final AbsoluteDate central = t0.shiftedBy(dt);
163             final PVCoordinates pv = propagator.getPVCoordinates(central, eme2000);
164             final double h = 10.0;
165             List<TimeStampedPVCoordinates> sample = new ArrayList<TimeStampedPVCoordinates>();
166             for (int i = -3; i <= 3; ++i) {
167                 sample.add(propagator.getPVCoordinates(central.shiftedBy(i * h), eme2000));
168             }
169             final PVCoordinates interpolated =
170                             TimeStampedPVCoordinates.interpolate(central,
171                                                                  CartesianDerivativesFilter.USE_P,
172                                                                  sample);
173             errorP = FastMath.max(errorP, Vector3D.distance(pv.getPosition(), interpolated.getPosition()));
174             errorV = FastMath.max(errorV, Vector3D.distance(pv.getVelocity(), interpolated.getVelocity()));
175             errorA = FastMath.max(errorA, Vector3D.distance(pv.getAcceleration(), interpolated.getAcceleration()));
176         }
177         Assert.assertEquals(0.0, errorP, 1.5e-11);
178         Assert.assertEquals(0.0, errorV, 7.2e-3);
179         Assert.assertEquals(0.0, errorA, 1.7e-3);
180 
181     }
182 
183     @Test
184     public void testNoReset() {
185         try {
186             final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).build();
187             propagator.resetInitialState(propagator.getInitialState());
188             Assert.fail("an exception should have been thrown");
189         } catch (OrekitException oe) {
190             Assert.assertEquals(OrekitMessages.NON_RESETABLE_STATE, oe.getSpecifier());
191         }
192         try {
193             final SBASPropagator propagator = new SBASPropagatorBuilder(soe, frames).build();
194             propagator.resetIntermediateState(propagator.getInitialState(), true);
195             Assert.fail("an exception should have been thrown");
196         } catch (OrekitException oe) {
197             Assert.assertEquals(OrekitMessages.NON_RESETABLE_STATE, oe.getSpecifier());
198         }
199     }
200 }