1   /* Copyright 2002-2021 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.modifiers;
18  
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.hipparchus.geometry.euclidean.threed.Vector3D;
23  import org.orekit.estimation.measurements.EstimatedMeasurement;
24  import org.orekit.estimation.measurements.EstimationModifier;
25  import org.orekit.estimation.measurements.InterSatellitesRange;
26  import org.orekit.frames.Transform;
27  import org.orekit.propagation.SpacecraftState;
28  import org.orekit.time.AbsoluteDate;
29  import org.orekit.utils.ParameterDriver;
30  import org.orekit.utils.TimeStampedPVCoordinates;
31  
32  /** On-board antenna offset effect on inter-satellites range measurements.
33   * @author Luc Maisonobe
34   * @since 9.0
35   */
36  public class OnBoardAntennaInterSatellitesRangeModifier implements EstimationModifier<InterSatellitesRange> {
37  
38      /** Position of the Antenna Phase Center in satellite 1 frame. */
39      private final Vector3D antennaPhaseCenter1;
40  
41      /** Position of the Antenna Phase Center in satellite 2 frame. */
42      private final Vector3D antennaPhaseCenter2;
43  
44      /** Simple constructor.
45       * @param antennaPhaseCenter1 position of the Antenna Phase Center in satellite 1 frame
46       * (i.e. the satellite which receives the signal and performs the measurement)
47       * @param antennaPhaseCenter2 position of the Antenna Phase Center in satellite 2 frame
48       * (i.e. the satellite which simply emits the signal in the one-way
49       * case, or reflects the signal in the two-way case)
50       */
51      public OnBoardAntennaInterSatellitesRangeModifier(final Vector3D antennaPhaseCenter1,
52                                                        final Vector3D antennaPhaseCenter2) {
53          this.antennaPhaseCenter1 = antennaPhaseCenter1;
54          this.antennaPhaseCenter2 = antennaPhaseCenter2;
55      }
56  
57      /** {@inheritDoc} */
58      @Override
59      public List<ParameterDriver> getParametersDrivers() {
60          return Collections.emptyList();
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public void modify(final EstimatedMeasurement<InterSatellitesRange> estimated) {
66          if (estimated.getParticipants().length < 3) {
67              modifyOneWay(estimated);
68          } else {
69              modifyTwoWay(estimated);
70          }
71      }
72  
73      /** Apply a modifier to an estimated measurement in the one-way case.
74       * @param estimated estimated measurement to modify
75       */
76      private void modifyOneWay(final EstimatedMeasurement<InterSatellitesRange> estimated) {
77  
78          // the participants are satellite 2 at emission, satellite 1 at reception
79          final TimeStampedPVCoordinates[] participants  = estimated.getParticipants();
80          final AbsoluteDate               emissionDate  = participants[0].getDate();
81          final AbsoluteDate               receptionDate = participants[1].getDate();
82  
83          // transforms from spacecraft to inertial frame at emission/reception dates
84          final SpacecraftState refState1                  = estimated.getStates()[0];
85          final SpacecraftState receptionState             = refState1.shiftedBy(receptionDate.durationFrom(refState1.getDate()));
86          final Transform       receptionSpacecraftToInert = receptionState.toTransform().getInverse();
87          final SpacecraftState refState2                  = estimated.getStates()[1];
88          final SpacecraftState emissionState              = refState2.shiftedBy(emissionDate.durationFrom(refState2.getDate()));
89          final Transform       emissionSpacecraftToInert  = emissionState.toTransform().getInverse();
90  
91          // compute the geometrical value of the inter-satellites range directly from participants positions.
92          // Note that this may be different from the value returned by estimated.getEstimatedValue(),
93          // because other modifiers may already have been taken into account
94          final Vector3D pSpacecraftReception = receptionSpacecraftToInert.transformPosition(Vector3D.ZERO);
95          final Vector3D pSpacecraftEmission  = emissionSpacecraftToInert.transformPosition(Vector3D.ZERO);
96          final double interSatellitesRangeUsingSpacecraftCenter =
97                          Vector3D.distance(pSpacecraftEmission, pSpacecraftReception);
98  
99          // compute the geometrical value of the range replacing
100         // the spacecraft positions with antenna phase center positions
101         final Vector3D pAPCReception = receptionSpacecraftToInert.transformPosition(antennaPhaseCenter1);
102         final Vector3D pAPCEmission  = emissionSpacecraftToInert.transformPosition(antennaPhaseCenter2);
103         final double interSatellitesRangeUsingAntennaPhaseCenter =
104                         Vector3D.distance(pAPCEmission, pAPCReception);
105 
106         // get the estimated value before this modifier is applied
107         final double[] value = estimated.getEstimatedValue();
108 
109         // modify the value
110         value[0] += interSatellitesRangeUsingAntennaPhaseCenter - interSatellitesRangeUsingSpacecraftCenter;
111         estimated.setEstimatedValue(value);
112 
113     }
114 
115     /** Apply a modifier to an estimated measurement in the two-way case.
116      * @param estimated estimated measurement to modify
117      */
118     private void modifyTwoWay(final EstimatedMeasurement<InterSatellitesRange> estimated) {
119 
120         // the participants are satellite 1 at emission, satellite 2 at transit, satellite 1 at reception
121         final TimeStampedPVCoordinates[] participants  = estimated.getParticipants();
122         final AbsoluteDate               emissionDate  = participants[0].getDate();
123         final AbsoluteDate               transitDate   = participants[1].getDate();
124         final AbsoluteDate               receptionDate = participants[2].getDate();
125 
126         // transforms from spacecraft to inertial frame at emission/reception dates
127         final SpacecraftState refState1                  = estimated.getStates()[0];
128         final SpacecraftState receptionState             = refState1.shiftedBy(receptionDate.durationFrom(refState1.getDate()));
129         final Transform       receptionSpacecraftToInert = receptionState.toTransform().getInverse();
130         final SpacecraftState refState2                  = estimated.getStates()[1];
131         final SpacecraftState transitState               = refState2.shiftedBy(transitDate.durationFrom(refState2.getDate()));
132         final Transform       transitSpacecraftToInert   = transitState.toTransform().getInverse();
133         final SpacecraftState emissionState              = refState1.shiftedBy(emissionDate.durationFrom(refState1.getDate()));
134         final Transform       emissionSpacecraftToInert  = emissionState.toTransform().getInverse();
135 
136         // compute the geometrical value of the inter-satellites range directly from participants positions.
137         // Note that this may be different from the value returned by estimated.getEstimatedValue(),
138         // because other modifiers may already have been taken into account
139         final Vector3D pSpacecraftReception = receptionSpacecraftToInert.transformPosition(Vector3D.ZERO);
140         final Vector3D pSpacecraftTransit   = transitSpacecraftToInert.transformPosition(Vector3D.ZERO);
141         final Vector3D pSpacecraftEmission  = emissionSpacecraftToInert.transformPosition(Vector3D.ZERO);
142         final double interSatellitesRangeUsingSpacecraftCenter =
143                         0.5 * (Vector3D.distance(pSpacecraftEmission, pSpacecraftTransit) +
144                                Vector3D.distance(pSpacecraftTransit, pSpacecraftReception));
145 
146         // compute the geometrical value of the range replacing
147         // the spacecraft positions with antenna phase center positions
148         final Vector3D pAPCReception = receptionSpacecraftToInert.transformPosition(antennaPhaseCenter1);
149         final Vector3D pAPCTransit   = transitSpacecraftToInert.transformPosition(antennaPhaseCenter2);
150         final Vector3D pAPCEmission  = emissionSpacecraftToInert.transformPosition(antennaPhaseCenter1);
151         final double interSatellitesRangeUsingAntennaPhaseCenter =
152                         0.5 * (Vector3D.distance(pAPCEmission, pAPCTransit) +
153                                Vector3D.distance(pAPCTransit, pAPCReception));
154 
155 
156         // get the estimated value before this modifier is applied
157         final double[] value = estimated.getEstimatedValue();
158 
159         // modify the value
160         value[0] += interSatellitesRangeUsingAntennaPhaseCenter - interSatellitesRangeUsingSpacecraftCenter;
161         estimated.setEstimatedValue(value);
162 
163     }
164 
165 }