1 package org.orekit.rugged.adjustment.util;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.hipparchus.geometry.euclidean.threed.Rotation;
7 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
8 import org.hipparchus.geometry.euclidean.threed.RotationOrder;
9 import org.hipparchus.geometry.euclidean.threed.Vector3D;
10 import org.hipparchus.util.FastMath;
11 import org.orekit.attitudes.AttitudeProvider;
12 import org.orekit.attitudes.LofOffset;
13 import org.orekit.attitudes.NadirPointing;
14 import org.orekit.attitudes.TabulatedLofOffset;
15 import org.orekit.attitudes.YawCompensation;
16 import org.orekit.bodies.BodyShape;
17 import org.orekit.frames.Frame;
18 import org.orekit.frames.FramesFactory;
19 import org.orekit.frames.LOFType;
20 import org.orekit.orbits.CircularOrbit;
21 import org.orekit.orbits.Orbit;
22 import org.orekit.orbits.PositionAngleType;
23 import org.orekit.propagation.Propagator;
24 import org.orekit.propagation.analytical.KeplerianPropagator;
25 import org.orekit.time.AbsoluteDate;
26 import org.orekit.utils.AngularDerivativesFilter;
27 import org.orekit.utils.Constants;
28 import org.orekit.utils.TimeStampedAngularCoordinates;
29 import org.orekit.utils.TimeStampedPVCoordinates;
30
31
32
33
34 public class PleiadesOrbitModel {
35
36
37 private boolean userDefinedLOFTransform;
38
39
40 private double[] lofTransformRollPoly;
41
42
43 private double[] lofTransformPitchPoly;
44
45
46 private double[] lofTransformYawPoly;
47
48
49 private AbsoluteDate refDate;
50
51
52
53 public PleiadesOrbitModel() {
54 userDefinedLOFTransform = false;
55 }
56
57
58
59 public Orbit createOrbit(final double mu, final AbsoluteDate date) {
60
61
62
63
64
65
66
67
68
69
70
71
72
73 final Frame eme2000 = FramesFactory.getEME2000();
74 return new CircularOrbit(694000.0 + Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
75 -4.029194321683225E-4,
76 0.0013530362644647786,
77 FastMath.toRadians(98.2),
78 FastMath.toRadians(-86.47 + 180),
79 FastMath.toRadians(135.9 + 0.3),
80 PositionAngleType.TRUE,
81 eme2000,
82 date,
83 mu);
84 }
85
86
87
88 public void setLOFTransform(final double[] rollPoly, final double[] pitchPoly,
89 final double[] yawPoly, final AbsoluteDate date) {
90
91 this.userDefinedLOFTransform = true;
92 lofTransformRollPoly = rollPoly.clone();
93 lofTransformPitchPoly = pitchPoly.clone();
94 lofTransformYawPoly = yawPoly.clone();
95 this.refDate = date;
96 }
97
98
99
100 private double getPoly(final double[] poly, final double shift) {
101
102 double val = 0.0;
103 for (int coef = 0; coef < poly.length; coef++) {
104 val = val + poly[coef] * FastMath.pow(shift, coef);
105 }
106 return val;
107 }
108
109
110
111 private Rotation getOffset(final BodyShape earth, final Orbit orbit, final double shift) {
112
113 final LOFType type = LOFType.VVLH;
114 final double roll = getPoly(lofTransformRollPoly, shift);
115 final double pitch = getPoly(lofTransformPitchPoly, shift);
116 final double yaw = getPoly(lofTransformYawPoly, shift);
117
118 final LofOffset law = new LofOffset(orbit.getFrame(), type, RotationOrder.XYZ,
119 roll, pitch, yaw);
120 final Rotation offsetAtt = law.
121 getAttitude(orbit, orbit.getDate().shiftedBy(shift), orbit.getFrame()).
122 getRotation();
123 final NadirPointing nadirPointing = new NadirPointing(orbit.getFrame(), earth);
124 final Rotation nadirAtt = nadirPointing.
125 getAttitude(orbit, orbit.getDate().getDate().shiftedBy(shift), orbit.getFrame()).
126 getRotation();
127 final Rotation offsetProper = offsetAtt.compose(nadirAtt.revert(), RotationConvention.VECTOR_OPERATOR);
128
129 return offsetProper;
130 }
131
132
133
134 public AttitudeProvider createAttitudeProvider(final BodyShape earth, final Orbit orbit) {
135
136 if (userDefinedLOFTransform) {
137 final LOFType type = LOFType.VVLH;
138
139 final List<TimeStampedAngularCoordinates> list = new ArrayList<TimeStampedAngularCoordinates>();
140
141 for (double shift = -10.0; shift < +10.0; shift += 1e-2) {
142 list.add(new TimeStampedAngularCoordinates(refDate.shiftedBy(shift),
143 getOffset(earth, orbit, shift),
144 Vector3D.ZERO,
145 Vector3D.ZERO));
146 }
147
148 final TabulatedLofOffset tabulated = new TabulatedLofOffset(orbit.getFrame(), type, list,
149 2, AngularDerivativesFilter.USE_R);
150
151 return tabulated;
152 } else {
153 return new YawCompensation(orbit.getFrame(), new NadirPointing(orbit.getFrame(), earth));
154 }
155 }
156
157
158
159 public List<TimeStampedPVCoordinates> orbitToPV(final Orbit orbit, final BodyShape earth,
160 final AbsoluteDate minDate, final AbsoluteDate maxDate,
161 final double step) {
162
163 final Propagator propagator = new KeplerianPropagator(orbit);
164
165 propagator.setAttitudeProvider(createAttitudeProvider(earth, orbit));
166
167 propagator.propagate(minDate);
168 final List<TimeStampedPVCoordinates> list = new ArrayList<TimeStampedPVCoordinates>();
169 propagator.getMultiplexer().add(step,
170 currentState -> list.add(new TimeStampedPVCoordinates(currentState.getDate(),
171 currentState.getPVCoordinates().getPosition(),
172 currentState.getPVCoordinates().getVelocity(),
173 Vector3D.ZERO)));
174 propagator.propagate(maxDate);
175
176 return list;
177 }
178
179
180
181 public List<TimeStampedAngularCoordinates> orbitToQ(final Orbit orbit, final BodyShape earth,
182 final AbsoluteDate minDate, final AbsoluteDate maxDate,
183 final double step) {
184
185 final Propagator propagator = new KeplerianPropagator(orbit);
186 propagator.setAttitudeProvider(createAttitudeProvider(earth, orbit));
187 propagator.propagate(minDate);
188 final List<TimeStampedAngularCoordinates> list = new ArrayList<>();
189 propagator.getMultiplexer().add(step,
190 currentState -> list.add(new TimeStampedAngularCoordinates(currentState.getDate(),
191 currentState.getAttitude().getRotation(),
192 Vector3D.ZERO,
193 Vector3D.ZERO)));
194 propagator.propagate(maxDate);
195
196 return list;
197 }
198 }