1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.gravity;
18
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.stream.Stream;
22
23 import org.hipparchus.Field;
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.hipparchus.util.FastMath;
28 import org.orekit.bodies.CelestialBodies;
29 import org.orekit.bodies.CelestialBody;
30 import org.orekit.forces.AbstractForceModel;
31 import org.orekit.propagation.FieldSpacecraftState;
32 import org.orekit.propagation.SpacecraftState;
33 import org.orekit.propagation.events.EventDetector;
34 import org.orekit.propagation.events.FieldEventDetector;
35 import org.orekit.utils.FieldPVCoordinates;
36 import org.orekit.utils.PVCoordinates;
37 import org.orekit.utils.ParameterDriver;
38
39
40
41
42
43 public class SingleBodyRelativeAttraction extends AbstractForceModel {
44
45
46 public static final String ATTRACTION_COEFFICIENT_SUFFIX = " attraction coefficient";
47
48
49
50
51
52
53
54 private static final double MU_SCALE = FastMath.scalb(1.0, 32);
55
56
57 private final ParameterDriver gmDriver;
58
59
60 private final CelestialBody body;
61
62
63
64
65
66
67 public SingleBodyRelativeAttraction(final CelestialBody body) {
68 gmDriver = new ParameterDriver(body.getName() + ATTRACTION_COEFFICIENT_SUFFIX,
69 body.getGM(), MU_SCALE,
70 0.0, Double.POSITIVE_INFINITY);
71
72 this.body = body;
73 }
74
75
76 @Override
77 public boolean dependsOnPositionOnly() {
78 return true;
79 }
80
81
82 public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
83
84
85 final PVCoordinates bodyPV = body.getPVCoordinates(s.getDate(), s.getFrame());
86 final Vector3D satToBody = bodyPV.getPosition().subtract(s.getPVCoordinates().getPosition());
87 final double r2Sat = satToBody.getNormSq();
88
89
90 final double gm = parameters[0];
91 final double a = gm / r2Sat;
92 return new Vector3D(a, satToBody.normalize()).add(bodyPV.getAcceleration());
93
94 }
95
96
97 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s,
98 final T[] parameters) {
99
100
101 final FieldPVCoordinates<T> bodyPV = body.getPVCoordinates(s.getDate(), s.getFrame());
102 final FieldVector3D<T> satToBody = bodyPV.getPosition().subtract(s.getPVCoordinates().getPosition());
103 final T r2Sat = satToBody.getNormSq();
104
105
106 final T gm = parameters[0];
107 final T a = gm.divide(r2Sat);
108 return new FieldVector3D<>(a, satToBody.normalize()).add(bodyPV.getAcceleration());
109
110 }
111
112
113 public Stream<EventDetector> getEventsDetectors() {
114 return Stream.empty();
115 }
116
117 @Override
118
119 public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(final Field<T> field) {
120 return Stream.empty();
121 }
122
123
124 public List<ParameterDriver> getParametersDrivers() {
125 return Collections.singletonList(gmDriver);
126 }
127
128 }