1 /* Copyright 2022-2025 Romain Serra
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.control.indirect.adjoint.cost;
18
19 import org.hipparchus.util.FastMath;
20 import org.orekit.propagation.events.EventDetectionSettings;
21 import org.orekit.propagation.events.EventDetector;
22
23 import java.util.stream.Stream;
24
25 /**
26 * Class for bounded energy cost with Cartesian coordinates.
27 * An energy cost is proportional to the integral over time of the squared Euclidean norm of the control vector, often scaled with 1/2.
28 * This type of cost is not optimal in terms of mass consumption, however its solutions showcase a smoother behavior favorable for convergence in shooting techniques.
29 * Here, the control vector is chosen as the thrust force divided by the maximum thrust magnitude and expressed in the propagation frame.
30 *
31 * @author Romain Serra
32 * @see UnboundedCartesianEnergy
33 * @since 12.2
34 */
35 public class BoundedCartesianEnergy extends CartesianEnergyConsideringMass {
36
37 /** Maximum value of thrust force Euclidean norm. */
38 private final double maximumThrustMagnitude;
39
40 /**
41 * Constructor.
42 * @param name name
43 * @param massFlowRateFactor mass flow rate factor
44 * @param maximumThrustMagnitude maximum thrust magnitude
45 * @param eventDetectionSettings singularity event detection settings
46 */
47 public BoundedCartesianEnergy(final String name, final double massFlowRateFactor,
48 final double maximumThrustMagnitude,
49 final EventDetectionSettings eventDetectionSettings) {
50 super(name, massFlowRateFactor, eventDetectionSettings);
51 this.maximumThrustMagnitude = FastMath.abs(maximumThrustMagnitude);
52 }
53
54 /**
55 * Constructor.
56 * @param name name
57 * @param massFlowRateFactor mass flow rate factor
58 * @param maximumThrustMagnitude maximum thrust magnitude
59 */
60 public BoundedCartesianEnergy(final String name, final double massFlowRateFactor,
61 final double maximumThrustMagnitude) {
62 this(name, massFlowRateFactor, maximumThrustMagnitude, EventDetectionSettings.getDefaultEventDetectionSettings());
63 }
64
65 /** Getter for maximum thrust magnitude.
66 * @return maximum thrust
67 * @since 13.0
68 */
69 public double getMaximumThrustMagnitude() {
70 return maximumThrustMagnitude;
71 }
72
73 /** {@inheritDoc} */
74 @Override
75 protected double getThrustForceNorm(final double[] adjointVariables, final double mass) {
76 final double adjointVelocityNorm = getAdjointVelocityNorm(adjointVariables);
77 double factor = adjointVelocityNorm / mass;
78 if (getAdjointDimension() > 6) {
79 factor -= getMassFlowRateFactor() * adjointVariables[6];
80 }
81 if (factor > maximumThrustMagnitude) {
82 return maximumThrustMagnitude;
83 } else {
84 return FastMath.max(0., factor);
85 }
86 }
87
88 /** {@inheritDoc} */
89 @Override
90 public Stream<EventDetector> getEventDetectors() {
91 return Stream.of(new SingularityDetector(getEventDetectionSettings(), 0.),
92 new SingularityDetector(getEventDetectionSettings(), maximumThrustMagnitude));
93 }
94 }