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.estimation.measurements;
18  
19  import java.util.Arrays;
20  
21  import org.hipparchus.analysis.UnivariateFunction;
22  import org.hipparchus.analysis.solvers.BracketingNthOrderBrentSolver;
23  import org.hipparchus.analysis.solvers.UnivariateSolver;
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.hipparchus.util.FastMath;
26  import org.orekit.errors.OrekitException;
27  import org.orekit.estimation.Context;
28  import org.orekit.frames.Frame;
29  import org.orekit.frames.Transform;
30  import org.orekit.propagation.SpacecraftState;
31  import org.orekit.time.AbsoluteDate;
32  import org.orekit.utils.Constants;
33  import org.orekit.utils.ParameterDriver;
34  
35  public class RangeMeasurementCreator2 extends MeasurementCreator {
36  
37      private final Context context;
38      private final Vector3D antennaPhaseCenter;
39      private final ObservableSatellite satellite;
40  
41      public RangeMeasurementCreator2(final Context context) {
42          this(context, Vector3D.ZERO);
43      }
44  
45      public RangeMeasurementCreator2(final Context context, final Vector3D antennaPhaseCenter) {
46          this.context            = context;
47          this.antennaPhaseCenter = antennaPhaseCenter;
48          this.satellite          = new ObservableSatellite(0);
49      }
50  
51      public void init(SpacecraftState s0, AbsoluteDate t, double step) {
52          for (final GroundStation station : context.stations) {
53              for (ParameterDriver driver : Arrays.asList(station.getClockOffsetDriver(),
54                                                          station.getEastOffsetDriver(),
55                                                          station.getNorthOffsetDriver(),
56                                                          station.getZenithOffsetDriver(),
57                                                          station.getPrimeMeridianOffsetDriver(),
58                                                          station.getPrimeMeridianDriftDriver(),
59                                                          station.getPolarOffsetXDriver(),
60                                                          station.getPolarDriftXDriver(),
61                                                          station.getPolarOffsetYDriver(),
62                                                          station.getPolarDriftYDriver())) {
63                  if (driver.getReferenceDate() == null) {
64                      driver.setReferenceDate(s0.getDate());
65                  }
66              }
67  
68          }
69      }
70  
71      public void handleStep(final SpacecraftState currentState) {
72          try {
73              for (final GroundStation station : context.stations) {
74                  final AbsoluteDate     date      = currentState.getDate();
75                  final Frame            inertial  = currentState.getFrame();
76                  final Vector3D         position  = currentState.toTransform().getInverse().transformPosition(antennaPhaseCenter);
77  
78                  if (station.getBaseFrame().getElevation(position, inertial, date) > FastMath.toRadians(30.0)) {
79                      final UnivariateSolver solver = new BracketingNthOrderBrentSolver(1.0e-12, 5);
80  
81                      final double downLinkDelay  = solver.solve(1000, new UnivariateFunction() {
82                          public double value(final double x) {
83                              final Transform t = station.getOffsetToInertial(inertial, date.shiftedBy(x));
84                              final double d = Vector3D.distance(position, t.transformPosition(Vector3D.ZERO));
85                              return d - x * Constants.SPEED_OF_LIGHT;
86                          }
87                      }, -1.0, 1.0);
88                      final AbsoluteDate receptionDate  = currentState.getDate().shiftedBy(downLinkDelay);
89                      final Vector3D stationAtReception =
90                                      station.getOffsetToInertial(inertial, receptionDate).transformPosition(Vector3D.ZERO);
91                      final double downLinkDistance = Vector3D.distance(position, stationAtReception);
92  
93                      addMeasurement(new Range(station, false, receptionDate, downLinkDistance,
94                                               1.0, 10, satellite));
95                  }
96  
97              }
98          } catch (OrekitException oe) {
99              throw new OrekitException(oe);
100         }
101     }
102 
103 }