1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.relative.maneuver;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.ode.events.Action;
21 import org.orekit.annotation.DefaultDataContext;
22 import org.orekit.propagation.SpacecraftState;
23 import org.orekit.propagation.events.DateDetector;
24 import org.orekit.propagation.events.EventDetector;
25 import org.orekit.propagation.events.handlers.EventHandler;
26 import org.orekit.propagation.relative.RelativeProvider;
27 import org.orekit.time.AbsoluteDate;
28 import org.orekit.time.TimeScale;
29 import org.orekit.time.TimeScalesFactory;
30 import org.orekit.utils.DataDictionary;
31 import org.orekit.utils.DoubleArrayDictionary;
32 import org.orekit.utils.TimeStampedPVCoordinates;
33
34 import java.util.Objects;
35
36
37
38
39
40
41
42
43 public abstract class AbstractRelativeManeuver<P extends RelativeProvider> implements RelativeManeuver {
44
45
46 private final EventDetector trigger;
47
48
49 private final Vector3D deltaV;
50
51
52 private boolean forward;
53
54
55 private final P relativeProvider;
56
57
58 private final EventHandler handler;
59
60
61
62
63
64
65
66
67
68
69 public AbstractRelativeManeuver(final EventDetector trigger, final Vector3D deltaV, final P relativeProvider) {
70 this.trigger = trigger;
71 this.deltaV = deltaV;
72 this.relativeProvider = relativeProvider;
73 this.handler = new Handler();
74 }
75
76
77 @Override
78 public void init(final SpacecraftState s0, final AbsoluteDate t) {
79 getDetector().init(s0, t);
80 forward = t.durationFrom(s0.getDate()) >= 0;
81 }
82
83
84 @Override
85 public EventDetector getDetector() {
86 return trigger;
87 }
88
89
90 @Override
91 public EventHandler getHandler() {
92 return handler;
93 }
94
95
96
97
98
99 @Override
100 @DefaultDataContext
101 public String toString() {
102 return toString(TimeScalesFactory.getUTC());
103 }
104
105
106
107
108
109
110
111 public String toString(final TimeScale timeScale) {
112 final String triggerString =
113 (getDetector() instanceof DateDetector) ?
114 ((DateDetector) getDetector()).getDate().toString(timeScale) :
115 getDetector().toString();
116 return "[trigger = " + triggerString + " ; ΔV = " + deltaV + " ; |ΔV| = " + deltaV.getNorm() + "]";
117 }
118
119
120
121
122 public boolean getForward() {
123 return forward;
124 }
125
126
127 @Override
128 public Vector3D getDeltaV() {
129 return deltaV;
130 }
131
132
133 @Override
134 public P getRelativeProvider() {
135 return this.relativeProvider;
136 }
137
138
139
140
141
142
143 private static class Handler implements EventHandler {
144
145
146 public Action eventOccurred(final SpacecraftState s, final EventDetector detector, final boolean increasing) {
147 final AbstractRelativeManeuver<?> im = (AbstractRelativeManeuver<?>) detector;
148 final Action underlyingAction = im.getDetector().getHandler().eventOccurred(s, im.getDetector(), increasing);
149 return (underlyingAction == Action.STOP) ? Action.RESET_STATE : Action.CONTINUE;
150 }
151
152
153 @Override
154 public SpacecraftState resetState(final EventDetector detector, final SpacecraftState oldState) {
155 final AbstractRelativeManeuver<?> maneuver = (AbstractRelativeManeuver<?>) detector;
156
157
158 final Vector3D deltaV = maneuver.getDeltaV();
159 final double sign = maneuver.getForward() ? +1 : -1;
160
161
162 final double[] chaserPV = oldState.getAdditionalState(maneuver.getRelativeProvider().getName());
163
164 chaserPV[3] += sign * deltaV.getX();
165 chaserPV[4] += sign * deltaV.getY();
166 chaserPV[5] += sign * deltaV.getZ();
167
168
169 maneuver.getRelativeProvider().setInitialChaserPVTLof(
170 new TimeStampedPVCoordinates(oldState.getDate(),
171 new Vector3D(chaserPV[0],
172 chaserPV[1],
173 chaserPV[2]),
174 new Vector3D(chaserPV[3],
175 chaserPV[4],
176 chaserPV[5])));
177
178
179 maneuver.resetTrueAnomalyAtManeuver(oldState.getOrbit());
180
181
182 SpacecraftState newState = new SpacecraftState(oldState.getOrbit(), oldState.getAttitude()).withMass(
183 oldState.getMass());
184
185
186 for (final DataDictionary.Entry entry : oldState.getAdditionalDataValues().getData()) {
187 if (!Objects.equals(entry.getKey(), maneuver.getRelativeProvider().getName())) {
188 newState = newState.addAdditionalData(entry.getKey(), entry.getValue());
189 } else {
190
191 newState = newState.addAdditionalData(maneuver.getRelativeProvider().getName(), chaserPV);
192 }
193 }
194
195
196 for (final DoubleArrayDictionary.Entry entry : oldState.getAdditionalStatesDerivatives().getData()) {
197 newState = newState.addAdditionalStateDerivative(entry.getKey(), entry.getValue());
198 }
199
200 return newState;
201 }
202 }
203 }