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  package org.orekit.estimation.measurements.generation;
18  
19  import java.util.Map;
20  
21  import org.hipparchus.random.CorrelatedRandomVectorGenerator;
22  import org.orekit.estimation.measurements.AngularAzEl;
23  import org.orekit.estimation.measurements.EstimationModifier;
24  import org.orekit.estimation.measurements.GroundStation;
25  import org.orekit.estimation.measurements.ObservableSatellite;
26  import org.orekit.propagation.SpacecraftState;
27  import org.orekit.propagation.sampling.OrekitStepInterpolator;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.utils.ParameterDriver;
30  
31  
32  /** Builder for {@link AngularAzEl} measurements.
33   * @author Luc Maisonobe
34   * @since 9.3
35   */
36  public class AngularAzElBuilder extends AbstractMeasurementBuilder<AngularAzEl> {
37  
38      /** Ground station from which measurement is performed. */
39      private final GroundStation station;
40  
41      /** Satellite related to this builder.
42       * @since 12.0
43       */
44      private final ObservableSatellite satellite;
45  
46      /** Simple constructor.
47       * @param noiseSource noise source, may be null for generating perfect measurements
48       * @param station ground station from which measurement is performed
49       * @param sigma theoretical standard deviation
50       * @param baseWeight base weight
51       * @param satellite satellite related to this builder
52       */
53      public AngularAzElBuilder(final CorrelatedRandomVectorGenerator noiseSource,
54                                final GroundStation station,
55                                final double[] sigma, final double[] baseWeight,
56                                final ObservableSatellite satellite) {
57          super(noiseSource, sigma, baseWeight, satellite);
58          this.station   = station;
59          this.satellite = satellite;
60      }
61  
62      /** {@inheritDoc} */
63      @Override
64      public AngularAzEl build(final AbsoluteDate date, final Map<ObservableSatellite, OrekitStepInterpolator> interpolators) {
65  
66          final double[] sigma                = getTheoreticalStandardDeviation();
67          final double[] baseWeight           = getBaseWeight();
68          final SpacecraftState[] relevant    = new SpacecraftState[] { interpolators.get(satellite).getInterpolatedState(date) };
69  
70          // create a dummy measurement
71          final AngularAzEl dummy = new AngularAzEl(station, relevant[0].getDate(),
72                                                    new double[] {
73                                                        0.0, 0.0
74                                                    }, sigma, baseWeight, satellite);
75          for (final EstimationModifier<AngularAzEl> modifier : getModifiers()) {
76              dummy.addModifier(modifier);
77          }
78  
79          // set a reference date for parameters missing one
80          for (final ParameterDriver driver : dummy.getParametersDrivers()) {
81              if (driver.getReferenceDate() == null) {
82                  final AbsoluteDate start = getStart();
83                  final AbsoluteDate end   = getEnd();
84                  driver.setReferenceDate(start.durationFrom(end) <= 0 ? start : end);
85              }
86          }
87  
88          // estimate the perfect value of the measurement
89          final double[] angular = dummy.estimateWithoutDerivatives(relevant).getEstimatedValue();
90  
91          // add the noise
92          final double[] noise = getNoise();
93          if (noise != null) {
94              angular[0] += noise[0];
95              angular[1] += noise[1];
96          }
97  
98          // generate measurement
99          final AngularAzEl measurement = new AngularAzEl(station, relevant[0].getDate(), angular,
100                                                         sigma, baseWeight, satellite);
101         for (final EstimationModifier<AngularAzEl> modifier : getModifiers()) {
102             measurement.addModifier(modifier);
103         }
104         return measurement;
105 
106     }
107 
108 }