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.geometry.euclidean.threed.Vector3D;
20 import org.orekit.control.indirect.adjoint.CartesianAdjointDerivativesProvider;
21 import org.orekit.propagation.SpacecraftState;
22 import org.orekit.propagation.events.EventDetector;
23 import org.orekit.propagation.integration.AdditionalDerivativesProvider;
24 import org.orekit.propagation.integration.CombinedDerivatives;
25
26 import java.util.stream.Stream;
27
28 /**
29 * Interface to definite cost function in the frame of Pontryagin's Maximum Principle using Cartesian coordinates.
30 * It provides the link between the optimal control and the adjoint variables. This relationship is obtained by maximizing the Hamiltonian.
31 * The choice of control vector impacts on it.
32 * Both standard (double type) and (Calculus)Field versions are to be implemented by inheritors.
33 * @author Romain Serra
34 * @see CartesianAdjointDerivativesProvider
35 * @since 12.2
36 */
37 public interface CartesianCost {
38
39 /** Getter for adjoint vector name.
40 * @return adjoint vector name
41 */
42 String getAdjointName();
43
44 /** Getter for adjoint vector dimension.
45 * @return adjoint dimension
46 */
47 int getAdjointDimension();
48
49 /** Getter for mass flow rate factor. It is negated and multiplied by the thrust force magnitude to obtain the mass time derivative.
50 * The fact that it is a constant means that the exhaust speed is assumed to be independent of time.
51 * @return mass flow rate factor
52 */
53 double getMassFlowRateFactor();
54
55 /**
56 * Computes the thrust acceleration vector in propagation frame from the adjoint variables and the mass.
57 * @param adjointVariables adjoint vector
58 * @param mass mass
59 * @return thrust vector
60 */
61 Vector3D getThrustAccelerationVector(double[] adjointVariables, double mass);
62
63 /**
64 * Update the adjoint derivatives if necessary.
65 *
66 * @param adjointVariables adjoint vector
67 * @param mass mass
68 * @param adjointDerivatives derivatives to update
69 */
70 void updateAdjointDerivatives(double[] adjointVariables, double mass, double[] adjointDerivatives);
71
72 /**
73 * Computes the Hamiltonian contribution to the cost function.
74 * It equals the Lagrange-form integrand multiplied by -1.
75 * @param adjointVariables adjoint vector
76 * @param mass mass
77 * @return contribution to Hamiltonian
78 */
79 double getHamiltonianContribution(double[] adjointVariables, double mass);
80
81 /**
82 * Get the detectors needed for propagation.
83 * @return event detectors
84 */
85 default Stream<EventDetector> getEventDetectors() {
86 return Stream.of();
87 }
88
89 /**
90 * Get the derivatives provider to be able to integrate the cost function.
91 * @param name name of cost as additional state variable
92 * @return derivatives provider
93 * @since 13.0
94 */
95 default AdditionalDerivativesProvider getCostDerivativeProvider(final String name) {
96 return new AdditionalDerivativesProvider() {
97 @Override
98 public String getName() {
99 return name;
100 }
101
102 @Override
103 public int getDimension() {
104 return 1;
105 }
106
107 @Override
108 public boolean yields(final SpacecraftState state) {
109 return !state.hasAdditionalData(getAdjointName());
110 }
111
112 @Override
113 public CombinedDerivatives combinedDerivatives(final SpacecraftState s) {
114 final double[] adjoint = s.getAdditionalState(getAdjointName());
115 final double hamiltonianContribution = getHamiltonianContribution(adjoint, s.getMass());
116 return new CombinedDerivatives(new double[] { -hamiltonianContribution }, null);
117 }
118 };
119 }
120 }