CartesianEnergyConsideringMass.java

  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. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  19. import org.orekit.propagation.SpacecraftState;
  20. import org.orekit.propagation.events.EventDetectionSettings;

  21. /**
  22.  * Abstract class for energy cost with Cartesian coordinates.
  23.  * An energy cost is proportional to the integral over time of the squared Euclidean norm of the control vector, often scaled with 1/2.
  24.  * 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.
  25.  *
  26.  * @author Romain Serra
  27.  * @since 12.2
  28.  */
  29. abstract class CartesianEnergyConsideringMass extends AbstractCartesianCost {

  30.     /** Detection settings for singularity detection. */
  31.     private final EventDetectionSettings eventDetectionSettings;

  32.     /**
  33.      * Constructor.
  34.      * @param name name
  35.      * @param massFlowRateFactor mass flow rate factor
  36.      * @param eventDetectionSettings settings for singularity detections
  37.      */
  38.     protected CartesianEnergyConsideringMass(final String name, final double massFlowRateFactor,
  39.                                              final EventDetectionSettings eventDetectionSettings) {
  40.         super(name, massFlowRateFactor);
  41.         this.eventDetectionSettings = eventDetectionSettings;
  42.     }

  43.     /**
  44.      * Getter for event detection settings.
  45.      * @return detection settings.
  46.      */
  47.     public EventDetectionSettings getEventDetectionSettings() {
  48.         return eventDetectionSettings;
  49.     }

  50.     /** {@inheritDoc} */
  51.     @Override
  52.     public Vector3D getThrustAccelerationVector(final double[] adjointVariables, final double mass) {
  53.         return getThrustDirection(adjointVariables).scalarMultiply(getThrustForceNorm(adjointVariables, mass) / mass);
  54.     }

  55.     /**
  56.      * Computes the direction of thrust.
  57.      * @param adjointVariables adjoint vector
  58.      * @return thrust direction
  59.      */
  60.     protected Vector3D getThrustDirection(final double[] adjointVariables) {
  61.         return new Vector3D(adjointVariables[3], adjointVariables[4], adjointVariables[5]).normalize();
  62.     }

  63.     /**
  64.      * Computes the Euclidean norm of the thrust force.
  65.      * @param adjointVariables adjoint vector
  66.      * @param mass mass
  67.      * @return norm of thrust
  68.      */
  69.     protected abstract double getThrustForceNorm(double[] adjointVariables, double mass);

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public void updateAdjointDerivatives(final double[] adjointVariables, final double mass,
  73.                                          final double[] adjointDerivatives) {
  74.         if (getAdjointDimension() > 6) {
  75.             adjointDerivatives[6] += getThrustForceNorm(adjointVariables, mass) * getAdjointVelocityNorm(adjointVariables) / (mass * mass);
  76.         }
  77.     }

  78.     /** {@inheritDoc} */
  79.     @Override
  80.     public double getHamiltonianContribution(final double[] adjointVariables, final double mass) {
  81.         final Vector3D thrustForce = getThrustAccelerationVector(adjointVariables, mass).scalarMultiply(mass);
  82.         return -thrustForce.getNormSq() / 2.;
  83.     }

  84.     /**
  85.      * Event detector for singularities in adjoint dynamics.
  86.      */
  87.     class SingularityDetector extends ControlSwitchDetector {

  88.         /** Value to detect. */
  89.         private final double detectionValue;

  90.         /**
  91.          * Constructor.
  92.          * @param detectionSettings detection settings
  93.          * @param detectionValue value to detect
  94.          */
  95.         SingularityDetector(final EventDetectionSettings detectionSettings, final double detectionValue) {
  96.             super(detectionSettings);
  97.             this.detectionValue = detectionValue;
  98.         }

  99.         /** {@inheritDoc} */
  100.         @Override
  101.         public double g(final SpacecraftState state) {
  102.             final double[] adjoint = state.getAdditionalState(getAdjointName());
  103.             return evaluateVariablePart(adjoint, state.getMass()) - detectionValue;
  104.         }

  105.         /**
  106.          * Evaluate variable part of singularity function.
  107.          * @param adjointVariables adjoint vector
  108.          * @param mass mass
  109.          * @return singularity function without the constant part
  110.          */
  111.         private double evaluateVariablePart(final double[] adjointVariables, final double mass) {
  112.             final double adjointVelocityNorm = getAdjointVelocityNorm(adjointVariables);
  113.             double variablePart = adjointVelocityNorm / mass;
  114.             if (getAdjointDimension() > 6) {
  115.                 variablePart -= getMassFlowRateFactor() * adjointVariables[6];
  116.             }
  117.             return variablePart;
  118.         }

  119.     }

  120. }