1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.semianalytical.dsst.forces;
18
19 import java.util.List;
20 import java.util.stream.Stream;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.Field;
24 import org.hipparchus.util.FastMath;
25 import org.hipparchus.util.MathArrays;
26 import org.hipparchus.util.MathUtils;
27 import org.orekit.forces.drag.DragForce;
28 import org.orekit.forces.drag.DragSensitive;
29 import org.orekit.forces.drag.IsotropicDrag;
30 import org.orekit.models.earth.atmosphere.Atmosphere;
31 import org.orekit.propagation.FieldSpacecraftState;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.propagation.events.EventDetector;
34 import org.orekit.propagation.events.FieldEventDetector;
35 import org.orekit.propagation.semianalytical.dsst.utilities.AuxiliaryElements;
36 import org.orekit.propagation.semianalytical.dsst.utilities.FieldAuxiliaryElements;
37 import org.orekit.utils.Constants;
38 import org.orekit.utils.ParameterDriver;
39
40
41
42
43
44
45
46
47
48
49 public class DSSTAtmosphericDrag extends AbstractGaussianContribution {
50
51
52 private static final double GAUSS_THRESHOLD = 6.0e-10;
53
54
55 private static final double DEFAULT_MAX_ATMOSPHERE_ALTITUDE = 1000000.;
56
57
58 private final DragForce drag;
59
60
61
62
63 private double rbar;
64
65
66
67
68
69 public DSSTAtmosphericDrag(final DragForce force, final double mu) {
70
71 super("DSST-drag-", GAUSS_THRESHOLD, force, mu);
72 this.drag = force;
73 this.rbar = DEFAULT_MAX_ATMOSPHERE_ALTITUDE + Constants.WGS84_EARTH_EQUATORIAL_RADIUS;
74 }
75
76
77
78
79
80
81
82 public DSSTAtmosphericDrag(final Atmosphere atmosphere, final double cd,
83 final double area, final double mu) {
84 this(atmosphere, new IsotropicDrag(area, cd), mu);
85 }
86
87
88
89
90
91
92 public DSSTAtmosphericDrag(final Atmosphere atmosphere, final DragSensitive spacecraft, final double mu) {
93
94
95 this(new DragForce(atmosphere, spacecraft), mu);
96 }
97
98
99
100
101 public Atmosphere getAtmosphere() {
102 return drag.getAtmosphere();
103 }
104
105
106
107
108
109
110
111
112 public double getRbar() {
113 return rbar;
114 }
115
116
117
118
119
120
121
122 public void setRbar(final double rbar) {
123 this.rbar = rbar;
124 }
125
126
127 public Stream<EventDetector> getEventDetectors() {
128 return drag.getEventDetectors();
129 }
130
131
132 @Override
133 public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(final Field<T> field) {
134 return drag.getFieldEventDetectors(field);
135 }
136
137
138 protected double[] getLLimits(final SpacecraftState state, final AuxiliaryElements auxiliaryElements) {
139
140 final double perigee = auxiliaryElements.getSma() * (1. - auxiliaryElements.getEcc());
141
142
143 if (perigee > rbar) {
144 return new double[2];
145 }
146 final double apogee = auxiliaryElements.getSma() * (1. + auxiliaryElements.getEcc());
147
148 if (apogee < rbar) {
149 return new double[] { -FastMath.PI + MathUtils.normalizeAngle(state.getOrbit().getLv(), 0),
150 FastMath.PI + MathUtils.normalizeAngle(state.getOrbit().getLv(), 0) };
151 }
152
153 final double fb = FastMath.acos(((auxiliaryElements.getSma() * (1. - auxiliaryElements.getEcc() * auxiliaryElements.getEcc()) / rbar) - 1.) / auxiliaryElements.getEcc());
154 final double wW = FastMath.atan2(auxiliaryElements.getH(), auxiliaryElements.getK());
155 return new double[] {wW - fb, wW + fb};
156 }
157
158
159 protected <T extends CalculusFieldElement<T>> T[] getLLimits(final FieldSpacecraftState<T> state,
160 final FieldAuxiliaryElements<T> auxiliaryElements) {
161
162 final Field<T> field = state.getDate().getField();
163
164 final T[] tab = MathArrays.buildArray(field, 2);
165
166 final T perigee = auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().negate().add(1.));
167
168 if (perigee.getReal() > rbar) {
169 return tab;
170 }
171 final T apogee = auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().add(1.));
172
173 if (apogee.getReal() < rbar) {
174 final T zero = field.getZero();
175 final T pi = zero.getPi();
176 tab[0] = MathUtils.normalizeAngle(state.getOrbit().getLv(), zero).subtract(pi);
177 tab[1] = MathUtils.normalizeAngle(state.getOrbit().getLv(), zero).add(pi);
178 return tab;
179 }
180
181 final T fb = FastMath.acos(((auxiliaryElements.getSma().multiply(auxiliaryElements.getEcc().multiply(auxiliaryElements.getEcc()).negate().add(1.)).divide(rbar)).subtract(1.)).divide(auxiliaryElements.getEcc()));
182 final T wW = FastMath.atan2(auxiliaryElements.getH(), auxiliaryElements.getK());
183
184 tab[0] = wW.subtract(fb);
185 tab[1] = wW.add(fb);
186 return tab;
187 }
188
189
190 @Override
191 protected List<ParameterDriver> getParametersDriversWithoutMu() {
192 return drag.getParametersDrivers();
193 }
194
195
196
197
198
199 public DragSensitive getSpacecraft() {
200 return drag.getSpacecraft();
201 }
202
203
204
205
206
207 public DragForce getDrag() {
208 return drag;
209 }
210 }