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.CalculusFieldElement;
20 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
21 import org.hipparchus.ode.events.Action;
22 import org.orekit.propagation.FieldSpacecraftState;
23 import org.orekit.propagation.events.FieldEventDetector;
24 import org.orekit.propagation.events.handlers.FieldEventHandler;
25 import org.orekit.propagation.relative.FieldRelativeProvider;
26 import org.orekit.time.FieldAbsoluteDate;
27 import org.orekit.utils.FieldArrayDictionary;
28 import org.orekit.utils.FieldDataDictionary;
29 import org.orekit.utils.FieldPVCoordinates;
30 import org.orekit.utils.TimeStampedFieldPVCoordinates;
31
32 import java.util.Objects;
33
34
35
36
37
38
39
40
41
42 public abstract class FieldAbstractRelativeManeuver<T extends CalculusFieldElement<T>, P extends FieldRelativeProvider<T>>
43 implements FieldRelativeManeuver<T> {
44
45
46 private final FieldEventDetector<T> trigger;
47
48
49 private final FieldVector3D<T> deltaV;
50
51
52 private boolean forward;
53
54
55 private final P relativeProvider;
56
57
58 private final FieldEventHandler<T> handler;
59
60
61
62
63
64
65
66
67
68
69 public FieldAbstractRelativeManeuver(final FieldEventDetector<T> trigger, final FieldVector3D<T> deltaV,
70 final P relativeProvider) {
71 this.trigger = trigger;
72 this.deltaV = deltaV;
73 this.relativeProvider = relativeProvider;
74 this.handler = new Handler<>();
75 }
76
77
78 @Override
79 public void init(final FieldSpacecraftState<T> s0, final FieldAbsoluteDate<T> t) {
80 forward = t.durationFrom(s0.getDate()).getReal() >= 0;
81 getDetector().init(s0, t);
82 }
83
84
85 @Override
86 public FieldEventDetector<T> getDetector() {
87 return trigger;
88 }
89
90
91
92
93
94
95 public boolean getForward() {
96 return forward;
97 }
98
99
100 @Override
101 public FieldVector3D<T> getDeltaV() {
102 return deltaV;
103 }
104
105
106 @Override
107 public P getRelativeProvider() {
108 return this.relativeProvider;
109 }
110
111
112 @Override
113 public FieldEventHandler<T> getHandler() {
114 return handler;
115 }
116
117
118
119
120
121
122
123 private static class Handler<T extends CalculusFieldElement<T>> implements FieldEventHandler<T> {
124
125
126 @Override
127 public Action eventOccurred(final FieldSpacecraftState<T> s, final FieldEventDetector<T> detector,
128 final boolean increasing) {
129 final FieldAbstractRelativeManeuver<T, ?> im = (FieldAbstractRelativeManeuver<T, ?>) detector;
130 final Action underlyingAction =
131 im.getDetector().getHandler().eventOccurred(s, im.getDetector(), increasing);
132 return (underlyingAction == Action.STOP) ? Action.RESET_STATE : Action.CONTINUE;
133 }
134
135
136 @Override
137 public FieldSpacecraftState<T> resetState(final FieldEventDetector<T> detector,
138 final FieldSpacecraftState<T> oldState) {
139 final FieldAbstractRelativeManeuver<T, ?> maneuver = (FieldAbstractRelativeManeuver<T, ?>) detector;
140
141
142 final FieldVector3D<T> deltaV = maneuver.getDeltaV();
143 final double sign = maneuver.getForward() ? +1 : -1;
144
145
146 final T[] chaserPV = oldState.getAdditionalState(maneuver.getRelativeProvider().getName());
147 chaserPV[3] = chaserPV[3].add(deltaV.getX().multiply(sign));
148 chaserPV[4] = chaserPV[4].add(deltaV.getY().multiply(sign));
149 chaserPV[5] = chaserPV[5].add(deltaV.getZ().multiply(sign));
150
151
152 maneuver.getRelativeProvider().setInitialChaserPVTLof(
153 new TimeStampedFieldPVCoordinates<>(oldState.getDate(), new FieldPVCoordinates<>(
154 new FieldVector3D<>(chaserPV[0], chaserPV[1], chaserPV[2]),
155 new FieldVector3D<>(chaserPV[3], chaserPV[4], chaserPV[5]))));
156
157
158 FieldSpacecraftState<T> newState =
159 new FieldSpacecraftState<>(oldState.getOrbit(), oldState.getAttitude()).withMass(
160 oldState.getMass());
161
162
163 maneuver.resetTrueAnomalyAtManeuver(oldState.getOrbit());
164
165
166 for (final FieldDataDictionary<T>.Entry entry : oldState.getAdditionalDataValues().getData()) {
167 if (!Objects.equals(entry.getKey(), maneuver.getRelativeProvider().getName())) {
168 newState = newState.addAdditionalData(entry.getKey(), entry.getValue());
169 } else {
170
171 newState = newState.addAdditionalData(maneuver.getRelativeProvider().getName(), chaserPV);
172 }
173 }
174
175
176 for (final FieldArrayDictionary<T>.Entry entry : oldState.getAdditionalStatesDerivatives().getData()) {
177 newState = newState.addAdditionalStateDerivative(entry.getKey(), entry.getValue());
178 }
179
180 return newState;
181 }
182 }
183 }