1 /* Copyright 2002-2025 CS GROUP
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.forces.empirical;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.hipparchus.CalculusFieldElement;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Vector3D;
25 import org.orekit.attitudes.AttitudeProvider;
26 import org.orekit.propagation.FieldSpacecraftState;
27 import org.orekit.propagation.SpacecraftState;
28 import org.orekit.time.AbsoluteDate;
29 import org.orekit.utils.ParameterDriver;
30
31 /** This class implements a parametric acceleration.
32 * <p>Parametric accelerations are intended to model lesser-known
33 * forces, estimating a few defining parameters from a parametric
34 * function using orbit determination. Typical parametric functions
35 * are polynomial (often limited to a constant term) and harmonic
36 * (often with either orbital period or half orbital period).</p>
37 * <p>An important operational example is the infamous GPS Y-bias,
38 * which is thought to be related to a radiator thermal radiation.
39 * Other examples could be to model leaks that produce roughly constant
40 * trust in some spacecraft-related direction.</p>
41 * <p>The acceleration direction is considered constant in either:
42 * </p>
43 * <ul>
44 * <li>inertial frame</li>
45 * <li>spacecraft frame</li>
46 * <li>a dedicated attitude frame overriding spacecraft attitude
47 * (this could for example be used to model solar arrays orientation
48 * if the force is related to solar arrays)</li>
49 * </ul>
50 * <p>
51 * If the direction of the acceleration is unknown, then three instances
52 * of this class should be used, one along the X axis, one along the Y
53 * axis and one along the Z axis and their parameters estimated as usual.
54 * </p>
55 * @since 10.3
56 * @author Luc Maisonobe
57 * @author Bryan Cazabonne
58 * @author Melina Vanel
59 */
60 public class ParametricAcceleration extends AbstractParametricAcceleration {
61
62 /** Acceleration model. */
63 private final AccelerationModel accelerationModel;
64
65 /** Simple constructor.
66 * @param direction acceleration direction in overridden spacecraft frame
67 * @param isInertial if true, direction is defined in the same inertial
68 * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
69 * otherwise direction is defined in spacecraft frame (i.e. using the
70 * propagation {@link
71 * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
72 * attitude law})
73 * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
74 * direction
75 */
76 public ParametricAcceleration(final Vector3D direction,
77 final boolean isInertial,
78 final AccelerationModel accelerationModel) {
79 this(direction, isInertial, null, accelerationModel);
80 }
81
82 /** Simple constructor.
83 * @param direction acceleration direction in overridden spacecraft frame
84 * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
85 * otherwise direction is defined in spacecraft frame (i.e. using the
86 * propagation {@link
87 * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
88 * attitude law})
89 * @param attitudeOverride provider for attitude used to compute acceleration
90 * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
91 * direction
92 */
93 public ParametricAcceleration(final Vector3D direction,
94 final AttitudeProvider attitudeOverride,
95 final AccelerationModel accelerationModel) {
96 this(direction, false, attitudeOverride, accelerationModel);
97 }
98
99 /** Simple constructor.
100 * @param direction acceleration direction in overridden spacecraft frame
101 * @param isInertial if true, direction is defined in the same inertial
102 * frame used for propagation (i.e. {@link SpacecraftState#getFrame()}),
103 * otherwise direction is defined in spacecraft frame (i.e. using the
104 * propagation {@link
105 * org.orekit.propagation.Propagator#setAttitudeProvider(AttitudeProvider)
106 * attitude law})
107 * @param attitudeOverride provider for attitude used to compute acceleration
108 * @param accelerationModel acceleration model used to compute the contribution of the empirical acceleration
109 * direction
110 */
111 private ParametricAcceleration(final Vector3D direction,
112 final boolean isInertial,
113 final AttitudeProvider attitudeOverride,
114 final AccelerationModel accelerationModel) {
115 super(direction, isInertial, attitudeOverride);
116 this.accelerationModel = accelerationModel;
117 }
118
119 /** {@inheritDoc} */
120 @Override
121 public List<ParameterDriver> getParametersDrivers() {
122 final List<ParameterDriver> parameterDrivers = new ArrayList<>(accelerationModel.getParametersDrivers());
123 if (getAttitudeOverride() != null) {
124 parameterDrivers.addAll(getAttitudeOverride().getParametersDrivers());
125 }
126 return parameterDrivers;
127 }
128
129 /** {@inheritDoc} */
130 @Override
131 public void init(final SpacecraftState initialState, final AbsoluteDate target) {
132 accelerationModel.init(initialState, target);
133 }
134
135 /** {@inheritDoc} */
136 @Override
137 public Vector3D acceleration(final SpacecraftState state,
138 final double[] parameters) {
139 final Vector3D inertialDirection = getAccelerationDirection(state);
140
141 // Call the acceleration model to compute the acceleration
142 return new Vector3D(accelerationModel.signedAmplitude(state, parameters), inertialDirection);
143
144 }
145
146 /** {@inheritDoc} */
147 @Override
148 public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> state,
149 final T[] parameters) {
150 final FieldVector3D<T> inertialDirection = getAccelerationDirection(state);
151
152 // Call the acceleration model to compute the acceleration
153 return new FieldVector3D<>(accelerationModel.signedAmplitude(state, parameters), inertialDirection);
154
155 }
156
157 }