1   /* Copyright 2002-2022 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  
18  package org.orekit.forces.maneuvers.propulsion;
19  
20  import java.util.Arrays;
21  import java.util.List;
22  
23  import org.hipparchus.CalculusFieldElement;
24  import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
25  import org.hipparchus.geometry.euclidean.threed.Vector3D;
26  import org.hipparchus.util.FastMath;
27  import org.orekit.utils.Constants;
28  import org.orekit.utils.ParameterDriver;
29  
30  /** Constant thrust propulsion model with:
31   *  - Constant thrust direction in spacecraft frame
32   *  - Parameter drivers (for estimation) for the thrust norm or the flow rate.
33   * Note that both parameters CANNOT be selected at the same time since they depend on one another.
34   * @author Maxime Journot
35   * @since 10.2
36   */
37  public class BasicConstantThrustPropulsionModel extends AbstractConstantThrustPropulsionModel {
38  
39      /** Parameter name for thrust. */
40      public static final String THRUST = "thrust";
41  
42      /** Parameter name for flow rate. */
43      public static final String FLOW_RATE = "flow rate";
44  
45      /** Thrust scaling factor.
46       * <p>
47       * We use a power of 2 to avoid numeric noise introduction
48       * in the multiplications/divisions sequences.
49       * </p>
50       */
51      public static final double THRUST_SCALE = FastMath.scalb(1.0, -5);
52  
53      /** Flow rate scaling factor.
54       * <p>
55       * We use a power of 2 to avoid numeric noise introduction
56       * in the multiplications/divisions sequences.
57       * </p>
58       */
59      public static final double FLOW_RATE_SCALE = FastMath.scalb(1.0, -12);
60  
61      /** Driver for thrust parameter. */
62      private final ParameterDriver thrustDriver;
63  
64      /** Driver for flow rate parameter. */
65      private final ParameterDriver flowRateDriver;
66  
67      /** Thrust direction in spacecraft frame. */
68      private final Vector3D direction;
69  
70      /** Simple constructor.
71       * @param thrust thrust (N)
72       * @param isp isp (s)
73       * @param direction direction in spacecraft frame
74       * @param name name of the maneuver
75       */
76      public BasicConstantThrustPropulsionModel(final double thrust,
77                                                final double isp,
78                                                final Vector3D direction,
79                                                final String name) {
80          super(thrust, isp, direction, name);
81          this.direction = direction.normalize();
82  
83          final double initialFlowRate = -thrust / (Constants.G0_STANDARD_GRAVITY * isp);
84  
85          // Build the parameter drivers, using maneuver name as prefix
86          this.thrustDriver   = new ParameterDriver(name + THRUST, thrust, THRUST_SCALE,
87                                                    0.0, Double.POSITIVE_INFINITY);
88          this.flowRateDriver = new ParameterDriver(name + FLOW_RATE, initialFlowRate, FLOW_RATE_SCALE,
89                                                    Double.NEGATIVE_INFINITY, 0.0 );
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      public Vector3D getThrustVector() {
95          // Thrust vector does not depend on spacecraft state for a constant maneuver.
96          return direction.scalarMultiply(thrustDriver.getValue());
97      }
98  
99      /** {@inheritDoc} */
100     @Override
101     public double getFlowRate() {
102         // Flow rate does not depend on spacecraft state for a constant maneuver.
103         return flowRateDriver.getValue();
104     }
105 
106     /** {@inheritDoc} */
107     @Override
108     public List<ParameterDriver> getParametersDrivers() {
109         return Arrays.asList(thrustDriver, flowRateDriver);
110     }
111 
112     /** {@inheritDoc} */
113     @Override
114     public Vector3D getThrustVector(final double[] parameters) {
115         // Thrust vector does not depend on spacecraft state for a constant maneuver.
116         return direction.scalarMultiply(parameters[0]);
117     }
118 
119     /** {@inheritDoc} */
120     @Override
121     public double getFlowRate(final double[] parameters) {
122         return parameters[1];
123     }
124 
125     /** {@inheritDoc} */
126     @Override
127     public <T extends CalculusFieldElement<T>> FieldVector3D<T> getThrustVector(final T[] parameters) {
128         return new FieldVector3D<T>(parameters[0], direction);
129     }
130 
131     /** {@inheritDoc} */
132     @Override
133     public <T extends CalculusFieldElement<T>> T getFlowRate(final T[] parameters) {
134         return parameters[1];
135     }
136 }