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 java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.hipparchus.analysis.interpolation.HermiteInterpolator;
24 import org.orekit.attitudes.AttitudeProvider;
25 import org.orekit.attitudes.FrameAlignedProvider;
26 import org.orekit.files.general.EphemerisFile;
27 import org.orekit.files.general.EphemerisSegmentPropagator;
28 import org.orekit.frames.Frame;
29 import org.orekit.propagation.BoundedPropagator;
30 import org.orekit.propagation.SpacecraftState;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.ClockModel;
33 import org.orekit.time.ClockOffset;
34 import org.orekit.time.SampledClockModel;
35 import org.orekit.utils.CartesianDerivativesFilter;
36 import org.orekit.utils.SortedListTrimmer;
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 public ClockModel extractClockModel() {
82 final List<ClockOffset> sample = new ArrayList<>(coordinates.size());
83 coordinates.forEach(c -> {
84 final AbsoluteDate date = c.getDate();
85 final double offset = c.getClockCorrection();
86 final double rate = filter.getMaxOrder() > 0 ? c.getClockRateChange() : Double.NaN;
87 sample.add(new ClockOffset(date, offset, rate, Double.NaN));
88 });
89 return new SampledClockModel(sample, interpolationSamples);
90 }
91
92
93 @Override
94 public double getMu() {
95 return mu;
96 }
97
98
99 @Override
100 public AbsoluteDate getStart() {
101 return coordinates.get(0).getDate();
102 }
103
104
105 @Override
106 public AbsoluteDate getStop() {
107 return coordinates.get(coordinates.size() - 1).getDate();
108 }
109
110
111 @Override
112 public Frame getFrame() {
113 return frame;
114 }
115
116
117 @Override
118 public int getInterpolationSamples() {
119 return interpolationSamples;
120 }
121
122
123 @Override
124 public CartesianDerivativesFilter getAvailableDerivatives() {
125 return filter;
126 }
127
128
129 @Override
130 public List<SP3Coordinate> getCoordinates() {
131 return Collections.unmodifiableList(this.coordinates);
132 }
133
134
135
136
137 public void addCoordinate(final SP3Coordinate coord) {
138 coordinates.add(coord);
139 }
140
141
142 @Override
143 public BoundedPropagator getPropagator() {
144 return new PropagatorWithClock(new FrameAlignedProvider(getInertialFrame()));
145 }
146
147
148 @Override
149 public BoundedPropagator getPropagator(final AttitudeProvider attitudeProvider) {
150 return new PropagatorWithClock(attitudeProvider);
151 }
152
153
154
155
156 private class PropagatorWithClock extends EphemerisSegmentPropagator<SP3Coordinate> {
157
158
159 private final SortedListTrimmer trimmer;
160
161
162
163
164 PropagatorWithClock(final AttitudeProvider attitudeProvider) {
165 super(SP3Segment.this, attitudeProvider);
166 this.trimmer = new SortedListTrimmer(getInterpolationSamples());
167 }
168
169
170 @Override
171 protected SpacecraftState updateAdditionalStates(final SpacecraftState original) {
172
173 final HermiteInterpolator interpolator = new HermiteInterpolator();
174
175
176 trimmer.
177 getNeighborsSubList(original.getDate(), coordinates).
178 forEach(c -> {
179 final double deltaT = c.getDate().durationFrom(original.getDate());
180 if (filter.getMaxOrder() < 1) {
181
182 interpolator.addSamplePoint(deltaT,
183 new double[] { c.getClockCorrection() });
184 } else {
185
186 interpolator.addSamplePoint(deltaT,
187 new double[] { c.getClockCorrection() },
188 new double[] { c.getClockRateChange() });
189 }
190 });
191
192
193 final double[][] derivatives = interpolator.derivatives(0.0, 1);
194
195
196 return super.updateAdditionalStates(original).
197 addAdditionalState(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[0]).
198 addAdditionalStateDerivative(SP3Utils.CLOCK_ADDITIONAL_STATE, derivatives[1]);
199
200 }
201
202 }
203
204 }