1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.control.heuristics;
18
19 import org.hipparchus.Field;
20 import org.hipparchus.analysis.differentiation.Derivative;
21 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
22 import org.hipparchus.analysis.solvers.NewtonRaphsonSolver;
23 import org.hipparchus.exception.MathIllegalArgumentException;
24 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.orekit.orbits.FieldCartesianOrbit;
27 import org.orekit.orbits.Orbit;
28 import org.orekit.propagation.SpacecraftState;
29 import org.orekit.propagation.conversion.osc2mean.OsculatingToMeanConverter;
30 import org.orekit.time.FieldAbsoluteDate;
31 import org.orekit.utils.FieldPVCoordinates;
32
33
34
35
36
37
38
39
40
41
42
43 public class MeanSmaChangeImpulseProvider extends AbstractInPlaneImpulseProvider {
44
45
46 private final double targetSemiMajorAxis;
47
48
49 private final OsculatingToMeanConverter osculatingToMeanConverter;
50
51
52
53
54
55
56 public MeanSmaChangeImpulseProvider(final double targetSemiMajorAxis, final OsculatingToMeanConverter osculatingToMeanConverter) {
57 this(Double.POSITIVE_INFINITY, targetSemiMajorAxis, osculatingToMeanConverter);
58 }
59
60
61
62
63
64
65
66 public MeanSmaChangeImpulseProvider(final double maximumMagnitude, final double targetSemiMajorAxis,
67 final OsculatingToMeanConverter osculatingToMeanConverter) {
68 super(maximumMagnitude);
69 this.targetSemiMajorAxis = targetSemiMajorAxis;
70 this.osculatingToMeanConverter = osculatingToMeanConverter;
71 }
72
73 @Override
74 public Vector3D getUnconstrainedImpulse(final SpacecraftState state, final boolean isForward) {
75 final Orbit orbit = state.getOrbit();
76 final Vector3D velocity = state.getVelocity();
77 final OsculatingSmaChangeImpulseProvider osculatingSmaChangeImpulseProvider = new OsculatingSmaChangeImpulseProvider(getMaximumMagnitude(),
78 targetSemiMajorAxis);
79 final Vector3D osculatingImpulse = osculatingSmaChangeImpulseProvider.getUnconstrainedImpulse(state, isForward);
80 final Vector3D direction = velocity.normalize();
81 final NewtonRaphsonSolver solver = new NewtonRaphsonSolver();
82 final NewtonFunction function = new NewtonFunction(orbit, direction, osculatingToMeanConverter,
83 targetSemiMajorAxis);
84 final double guess = osculatingImpulse.add(velocity).getNorm2();
85 final double optimal = solver.solve(100, function, guess);
86 return direction.scalarMultiply(optimal).subtract(velocity);
87 }
88
89
90
91
92
93
94
95
96
97 private record NewtonFunction(Orbit templateOrbit, Vector3D direction, OsculatingToMeanConverter converter,
98 double targetMeanSma) implements UnivariateDifferentiableFunction {
99
100 @Override
101 public <T extends Derivative<T>> T value(final T t) throws MathIllegalArgumentException {
102 final Field<T> field = t.getField();
103 final FieldVector3D<T> velocity = new FieldVector3D<>(t, direction);
104 final FieldVector3D<T> position = new FieldVector3D<>(field, templateOrbit.getPosition());
105 final FieldCartesianOrbit<T> orbit = new FieldCartesianOrbit<>(new FieldPVCoordinates<>(position, velocity),
106 templateOrbit.getFrame(), new FieldAbsoluteDate<>(field, templateOrbit.getDate()),
107 field.getOne().newInstance(templateOrbit.getMu()));
108 return converter.convertToMean(orbit).getA().subtract(targetMeanSma);
109 }
110 }
111 }