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