1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.sp3;
18
19 import org.hipparchus.analysis.interpolation.HermiteInterpolator;
20 import org.orekit.attitudes.AttitudeProvider;
21 import org.orekit.attitudes.FrameAlignedProvider;
22 import org.orekit.files.general.EphemerisFile;
23 import org.orekit.files.general.EphemerisSegmentPropagator;
24 import org.orekit.frames.Frame;
25 import org.orekit.propagation.BoundedPropagator;
26 import org.orekit.propagation.SpacecraftState;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.time.ClockModel;
29 import org.orekit.time.ClockOffset;
30 import org.orekit.time.SampledClockModel;
31 import org.orekit.utils.CartesianDerivativesFilter;
32 import org.orekit.utils.SortedListTrimmer;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.List;
37
38
39
40
41
42
43
44 public class SP3Segment implements EphemerisFile.EphemerisSegment<SP3Coordinate> {
45
46
47 private final double mu;
48
49
50 private final Frame frame;
51
52
53 private final int interpolationSamples;
54
55
56 private final CartesianDerivativesFilter filter;
57
58
59 private final List<SP3Coordinate> coordinates;
60
61
62
63
64
65
66
67
68 public SP3Segment(final double mu, final Frame frame,
69 final int interpolationSamples, final CartesianDerivativesFilter filter) {
70 this.mu = mu;
71 this.frame = frame;
72 this.interpolationSamples = interpolationSamples;
73 this.filter = filter;
74 this.coordinates = new ArrayList<>();
75 }
76
77
78
79
80
81
82
83
84
85
86 public ClockModel extractClockModel() {
87 final List<ClockOffset> sample = new ArrayList<>(coordinates.size());
88 coordinates.forEach(c -> {
89 final AbsoluteDate date = c.getDate();
90 final double offset = c.getClockCorrection();
91 if (!Double.isNaN(offset)) {
92 final double rate = filter.getMaxOrder() > 0 ? c.getClockRateChange() : Double.NaN;
93 sample.add(new ClockOffset(date, offset, rate, Double.NaN));
94 }
95 });
96 return new SampledClockModel(sample, interpolationSamples);
97 }
98
99
100 @Override
101 public double getMu() {
102 return mu;
103 }
104
105
106 @Override
107 public AbsoluteDate getStart() {
108 return coordinates.get(0).getDate();
109 }
110
111
112 @Override
113 public AbsoluteDate getStop() {
114 return coordinates.get(coordinates.size() - 1).getDate();
115 }
116
117
118 @Override
119 public Frame getFrame() {
120 return frame;
121 }
122
123
124 @Override
125 public int getInterpolationSamples() {
126 return interpolationSamples;
127 }
128
129
130 @Override
131 public CartesianDerivativesFilter getAvailableDerivatives() {
132 return filter;
133 }
134
135
136 @Override
137 public List<SP3Coordinate> getCoordinates() {
138 return Collections.unmodifiableList(this.coordinates);
139 }
140
141
142
143
144 public void addCoordinate(final SP3Coordinate coord) {
145 coordinates.add(coord);
146 }
147
148
149 @Override
150 public BoundedPropagator getPropagator() {
151 return new PropagatorWithClock(new FrameAlignedProvider(getInertialFrame()));
152 }
153
154
155 @Override
156 public BoundedPropagator getPropagator(final AttitudeProvider attitudeProvider) {
157 return new PropagatorWithClock(attitudeProvider);
158 }
159
160
161
162
163 private class PropagatorWithClock extends EphemerisSegmentPropagator<SP3Coordinate> {
164
165
166 private final SortedListTrimmer trimmer;
167
168
169
170
171 PropagatorWithClock(final AttitudeProvider attitudeProvider) {
172 super(SP3Segment.this, attitudeProvider);
173 this.trimmer = new SortedListTrimmer(getInterpolationSamples());
174 }
175
176
177 @Override
178 public SpacecraftState updateAdditionalData(final SpacecraftState original) {
179
180 final HermiteInterpolator interpolator = new HermiteInterpolator();
181
182
183 trimmer.
184 getNeighborsSubList(original.getDate(), coordinates).
185 forEach(c -> {
186 final double deltaT = c.getDate().durationFrom(original.getDate());
187 if (filter.getMaxOrder() < 1) {
188
189 interpolator.addSamplePoint(deltaT,
190 new double[] { c.getClockCorrection() });
191 } else {
192
193 interpolator.addSamplePoint(deltaT,
194 new double[] { c.getClockCorrection() },
195 new double[] { c.getClockRateChange() });
196 }
197 });
198
199
200 final double[][] derivatives = interpolator.derivatives(0.0, 1);
201
202
203 return super.updateAdditionalData(original).
204 addAdditionalData(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[0]).
205 addAdditionalStateDerivative(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[1]);
206
207 }
208
209 }
210
211 }