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  
18  package org.orekit.estimation.iod;
19  
20  import org.hipparchus.geometry.euclidean.threed.Vector3D;
21  import org.hipparchus.util.FastMath;
22  import org.junit.jupiter.api.BeforeEach;
23  import org.orekit.Utils;
24  import org.orekit.bodies.GeodeticPoint;
25  import org.orekit.bodies.OneAxisEllipsoid;
26  import org.orekit.estimation.measurements.AngularAzEl;
27  import org.orekit.estimation.measurements.AngularRaDec;
28  import org.orekit.estimation.measurements.EstimatedMeasurementBase;
29  import org.orekit.estimation.measurements.GroundStation;
30  import org.orekit.estimation.measurements.ObservableSatellite;
31  import org.orekit.frames.Frame;
32  import org.orekit.frames.FramesFactory;
33  import org.orekit.frames.TopocentricFrame;
34  import org.orekit.models.earth.troposphere.TroposphericModelUtils;
35  import org.orekit.orbits.Orbit;
36  import org.orekit.propagation.Propagator;
37  import org.orekit.propagation.SpacecraftState;
38  import org.orekit.time.AbsoluteDate;
39  import org.orekit.utils.AbsolutePVCoordinates;
40  import org.orekit.utils.Constants;
41  import org.orekit.utils.IERSConventions;
42  import org.orekit.utils.PVCoordinatesProvider;
43  import org.orekit.utils.TimeStampedPVCoordinates;
44  
45  public abstract class AbstractIodTest {
46      /**
47       * gcrf frame.
48       */
49      protected Frame gcrf;
50  
51      /**
52       * EME2OOO frame.
53       */
54      protected Frame eme2000;
55  
56      /**
57       * ground station for the observations.
58       */
59      protected GroundStation observer;
60  
61      /**
62       * gravitational constant.
63       */
64      protected double mu;
65  
66      /**
67       * itrf frame.
68       */
69      protected Frame itrf;
70  
71      @BeforeEach
72      public void setUp() {
73          Utils.setDataRoot("regular-data");
74  
75          this.mu      = Constants.WGS84_EARTH_MU;
76          this.gcrf    = FramesFactory.getGCRF();
77          this.eme2000 = FramesFactory.getEME2000();
78  
79          this.itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, false);
80          // The ground station is set to Austin, Texas, U.S.A
81          final OneAxisEllipsoid body = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
82                                                             Constants.WGS84_EARTH_FLATTENING, itrf);
83          this.observer = new GroundStation(new TopocentricFrame(body,
84                                                                 new GeodeticPoint(FastMath.toRadians(40),
85                                                                                   FastMath.toRadians(-110),
86                                                                                   2000.0), ""),
87                                            TroposphericModelUtils.STANDARD_ATMOSPHERE_PROVIDER);
88          this.observer.getPrimeMeridianOffsetDriver().setReferenceDate(AbsoluteDate.J2000_EPOCH);
89          this.observer.getPolarOffsetXDriver().setReferenceDate(AbsoluteDate.J2000_EPOCH);
90          this.observer.getPolarOffsetYDriver().setReferenceDate(AbsoluteDate.J2000_EPOCH);
91  
92      }
93  
94      // Computation of LOS angles
95      protected Vector3D getLOSAngles(final Propagator prop, final AbsoluteDate date) {
96          final AngularRaDec raDec = new AngularRaDec(observer, gcrf, date, new double[] { 0.0, 0.0 },
97                                                      new double[] { 1.0, 1.0 },
98                                                      new double[] { 1.0, 1.0 }, new ObservableSatellite(0));
99          return (getEstimatedLineOfSight(raDec, prop, date, gcrf));
100     }
101 
102     protected AngularAzEl getAzEl(final Propagator prop, final AbsoluteDate date) {
103         ObservableSatellite satellite = new ObservableSatellite(0);
104         final AngularAzEl azEl = new AngularAzEl(observer, date, new double[] { 0.0, 0.0 },
105                                                  new double[] { 1.0, 1.0 }, new double[] { 1.0, 1.0 },
106                                                  satellite);
107         EstimatedMeasurementBase<AngularAzEl> estimated = azEl.estimateWithoutDerivatives(new SpacecraftState[] {prop.propagate(date)});
108         return new AngularAzEl(observer, date, estimated.getEstimatedValue(), azEl.getBaseWeight(),
109                                azEl.getTheoreticalStandardDeviation(), satellite);
110     }
111 
112     protected double getRelativeRangeError(final Orbit estimatedGauss, final Orbit orbitRef) {
113 
114         return FastMath.abs(estimatedGauss.getPVCoordinates().getPosition().getNorm() -
115                                     orbitRef.getPVCoordinates().getPosition().getNorm()) /
116                 FastMath.abs(orbitRef.getPVCoordinates().getPosition().getNorm());
117     }
118 
119     // Computation of the relative error in velocity
120     protected double getRelativeVelocityError(final Orbit estimatedGauss, final Orbit orbitRef) {
121 
122         return FastMath.abs(estimatedGauss.getPVCoordinates().getVelocity().getNorm() -
123                                     orbitRef.getPVCoordinates().getVelocity().getNorm()) /
124                 FastMath.abs(orbitRef.getPVCoordinates().getVelocity().getNorm());
125     }
126     
127     /** Calculate the estimated Line Of Sight of a RADEC measurement at a given date.
128      *
129      * @param pvProvider provider for satellite coordinates
130      * @param date the date for which the line of sight must be computed
131      * @param outputFrame output frame for the line of sight
132      * @return the estimate line of Sight of the measurement at the given date.
133      */
134     private Vector3D getEstimatedLineOfSight(final AngularRaDec raDec, final PVCoordinatesProvider pvProvider, final AbsoluteDate date, final Frame outputFrame) {
135         final TimeStampedPVCoordinates satPV       = pvProvider.getPVCoordinates(date, outputFrame);
136         final AbsolutePVCoordinates    satPVInGCRF = new AbsolutePVCoordinates(outputFrame, satPV);
137         final SpacecraftState[]        satState    = new SpacecraftState[] { new SpacecraftState(satPVInGCRF) };
138         final double[]                 angular     = raDec.estimateWithoutDerivatives(satState).getEstimatedValue();
139 
140         // Rotate LOS from RADEC reference frame to output frame
141         return raDec.getReferenceFrame().getStaticTransformTo(outputFrame, date)
142                         .transformVector(new Vector3D(angular[0], angular[1]));
143     }
144 }