1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.events;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.ode.events.Action;
21 import org.hipparchus.util.FastMath;
22 import org.hipparchus.util.SinCos;
23 import org.orekit.orbits.Orbit;
24 import org.orekit.propagation.SpacecraftState;
25 import org.orekit.propagation.events.handlers.EventHandler;
26 import org.orekit.propagation.events.handlers.StopOnIncreasing;
27 import org.orekit.utils.PVCoordinates;
28 import org.orekit.utils.PVCoordinatesProvider;
29
30
31
32
33
34
35
36
37
38
39
40 public class AlignmentDetector extends AbstractDetector<AlignmentDetector> {
41
42
43 private final PVCoordinatesProvider body;
44
45
46 private final double alignAngle;
47
48
49 private final double cosAlignAngle;
50
51
52 private final double sinAlignAngle;
53
54
55
56
57
58
59
60
61 public AlignmentDetector(final Orbit orbit,
62 final PVCoordinatesProvider body,
63 final double alignAngle) {
64 this(1.0e-13 * orbit.getKeplerianPeriod(), orbit, body, alignAngle);
65 }
66
67
68
69
70
71
72
73 public AlignmentDetector(final double maxCheck, final double threshold,
74 final PVCoordinatesProvider body,
75 final double alignAngle) {
76 this(new EventDetectionSettings(maxCheck, threshold, EventDetectionSettings.DEFAULT_MAX_ITER),
77 new StopOnIncreasing(), body, alignAngle);
78 }
79
80
81
82
83
84
85
86 public AlignmentDetector(final EventDetectionSettings detectionSettings,
87 final PVCoordinatesProvider body,
88 final double alignAngle) {
89 this(detectionSettings, new StopOnIncreasing(), body, alignAngle);
90 }
91
92
93
94
95
96
97
98
99
100 public AlignmentDetector(final double threshold,
101 final Orbit orbit,
102 final PVCoordinatesProvider body,
103 final double alignAngle) {
104 this(orbit.getKeplerianPeriod() / 3, threshold, body, alignAngle);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119 protected AlignmentDetector(final EventDetectionSettings detectionSettings, final EventHandler handler,
120 final PVCoordinatesProvider body,
121 final double alignAngle) {
122 super(detectionSettings, handler);
123 final SinCos sc = FastMath.sinCos(alignAngle);
124 this.body = body;
125 this.alignAngle = alignAngle;
126 this.cosAlignAngle = sc.cos();
127 this.sinAlignAngle = sc.sin();
128 }
129
130
131 @Override
132 protected AlignmentDetector create(final EventDetectionSettings detectionSettings, final EventHandler newHandler) {
133 return new AlignmentDetector(detectionSettings, newHandler, body, alignAngle);
134 }
135
136
137
138
139 public PVCoordinatesProvider getPVCoordinatesProvider() {
140 return body;
141 }
142
143
144
145
146 public double getAlignAngle() {
147 return alignAngle;
148 }
149
150
151
152
153
154
155
156
157 public double g(final SpacecraftState s) {
158 final PVCoordinates pv = s.getPVCoordinates();
159 final Vector3D a = pv.getPosition().normalize();
160 final Vector3D b = Vector3D.crossProduct(pv.getMomentum(), a).normalize();
161 final Vector3D x = new Vector3D(cosAlignAngle, a, sinAlignAngle, b);
162 final Vector3D y = new Vector3D(sinAlignAngle, a, -cosAlignAngle, b);
163 final Vector3D pb = body.getPosition(s.getDate(), s.getFrame());
164 final double beta = FastMath.atan2(Vector3D.dotProduct(pb, y), Vector3D.dotProduct(pb, x));
165 final double betm = -FastMath.PI - beta;
166 final double betp = FastMath.PI - beta;
167 if (beta < betm) {
168 return betm;
169 } else if (beta < betp) {
170 return beta;
171 } else {
172 return betp;
173 }
174 }
175
176 }