AbstractShortTermEncounter2DPOCMethod.java

  1. /* Copyright 2002-2024 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. package org.orekit.ssa.collision.shorttermencounter.probability.twod;

  18. import org.hipparchus.CalculusFieldElement;
  19. import org.hipparchus.Field;
  20. import org.hipparchus.geometry.euclidean.twod.FieldVector2D;
  21. import org.hipparchus.geometry.euclidean.twod.Vector2D;
  22. import org.hipparchus.linear.FieldMatrix;
  23. import org.hipparchus.linear.RealMatrix;
  24. import org.hipparchus.util.FastMath;
  25. import org.orekit.data.DataContext;
  26. import org.orekit.files.ccsds.ndm.cdm.Cdm;
  27. import org.orekit.files.ccsds.ndm.cdm.CdmData;
  28. import org.orekit.files.ccsds.ndm.cdm.CdmMetadata;
  29. import org.orekit.files.ccsds.ndm.cdm.CdmRelativeMetadata;
  30. import org.orekit.frames.Frame;
  31. import org.orekit.frames.LOFType;
  32. import org.orekit.frames.Transform;
  33. import org.orekit.frames.encounter.EncounterLOFType;
  34. import org.orekit.orbits.CartesianOrbit;
  35. import org.orekit.orbits.FieldOrbit;
  36. import org.orekit.orbits.Orbit;
  37. import org.orekit.propagation.FieldStateCovariance;
  38. import org.orekit.propagation.StateCovariance;
  39. import org.orekit.ssa.metrics.FieldProbabilityOfCollision;
  40. import org.orekit.ssa.metrics.ProbabilityOfCollision;
  41. import org.orekit.time.AbsoluteDate;
  42. import org.orekit.utils.Fieldifier;
  43. import org.orekit.utils.PVCoordinates;

  44. /**
  45.  * This abstract class serves as a foundation to create 2D probability of collision computing method assuming a short term
  46.  * encounter model.
  47.  * <p>
  48.  * All the methods extending this class will at least assume the followings :
  49.  * <ul>
  50.  *     <li>Short term encounter leading to a linear relative motion.</li>
  51.  *     <li>Spherical collision object.</li>
  52.  *     <li>Uncorrelated positional covariance.</li>
  53.  *     <li>Gaussian distribution of the position uncertainties.</li>
  54.  *     <li>Deterministic velocity i.e. no velocity uncertainties.</li>
  55.  * </ul>
  56.  * As listed in the assumptions, methods extending this class are to be used in short encounter,
  57.  * meaning that there must be a high relative velocity. For ease of computation, the resulting swept volume
  58.  * is extended to infinity so that the integral becomes bivariate instead of trivariate (conservative hypothesis).
  59.  * <p>
  60.  * Consequently and if we consider Earth, methods implementing this interface are <u><b>recommended</b></u> for
  61.  * collision happening in Low/Medium Earth Orbit (LEO and MEO) but are <u><b>not recommended</b></u> for collision
  62.  * happening in Geostationary Earth Orbit (GEO).
  63.  *
  64.  * @author Vincent Cucchietti
  65.  * @since 12.0
  66.  */
  67. public abstract class AbstractShortTermEncounter2DPOCMethod implements ShortTermEncounter2DPOCMethod {

  68.     /** Default time of closest approach difference tolerance. */
  69.     public static final double DEFAULT_TCA_DIFFERENCE_TOLERANCE = 1e-6;

  70.     /** Name of the method. */
  71.     private final String name;

  72.     /**
  73.      * Constructor.
  74.      *
  75.      * @param name name of the method
  76.      */
  77.     protected AbstractShortTermEncounter2DPOCMethod(final String name) {
  78.         this.name = name;
  79.     }

  80.     /** {@inheritDoc} */
  81.     public ProbabilityOfCollision compute(final Cdm cdm, final double combinedRadius) {

  82.         final CdmRelativeMetadata cdmRelativeMetadata = cdm.getRelativeMetadata();
  83.         final CdmData             primaryData         = cdm.getDataObject1();
  84.         final CdmData             secondaryData       = cdm.getDataObject2();
  85.         final DataContext         cdmDataContext      = cdm.getDataContext();

  86.         // Extract primary data
  87.         final Orbit primaryOrbit = getObjectOrbitFromCdm(cdmRelativeMetadata, primaryData,
  88.                                                          cdm.getMetadataObject1(), cdmDataContext);
  89.         final StateCovariance primaryCovariance = getObjectStateCovarianceFromCdm(cdmRelativeMetadata, primaryData);

  90.         // Extract secondary data
  91.         final Orbit secondaryOrbit = getObjectOrbitFromCdm(cdmRelativeMetadata, secondaryData,
  92.                                                            cdm.getMetadataObject2(), cdmDataContext);
  93.         final StateCovariance secondaryCovariance = getObjectStateCovarianceFromCdm(cdmRelativeMetadata, secondaryData);

  94.         return compute(primaryOrbit, primaryCovariance, secondaryOrbit, secondaryCovariance, combinedRadius,
  95.                        DEFAULT_ZERO_THRESHOLD);
  96.     }

  97.     /** {@inheritDoc} */
  98.     public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(final Cdm cdm,
  99.                                                                                       final T combinedRadius,
  100.                                                                                       final double zeroThreshold) {

  101.         final Field<T>            field               = combinedRadius.getField();
  102.         final CdmRelativeMetadata cdmRelativeMetadata = cdm.getRelativeMetadata();
  103.         final CdmData             primaryData         = cdm.getDataObject1();
  104.         final CdmData             secondaryData       = cdm.getDataObject2();
  105.         final CdmMetadata         primaryMetadata     = cdm.getMetadataObject1();
  106.         final CdmMetadata         secondaryMetadata   = cdm.getMetadataObject2();
  107.         final DataContext         cdmDataContext      = cdm.getDataContext();

  108.         // Extract primary data
  109.         final Orbit primaryOrbitFromCdm = getObjectOrbitFromCdm(cdmRelativeMetadata, primaryData,
  110.                 primaryMetadata, cdmDataContext);
  111.         final FieldOrbit<T> primaryOrbit = primaryOrbitFromCdm.getType().convertToFieldOrbit(field,
  112.                 primaryOrbitFromCdm);
  113.         final FieldStateCovariance<T> primaryCovariance =
  114.                 Fieldifier.fieldify(field, getObjectStateCovarianceFromCdm(cdmRelativeMetadata, primaryData));

  115.         // Extract secondary data
  116.         final Orbit secondaryOrbitFromCdm = getObjectOrbitFromCdm(cdmRelativeMetadata, secondaryData,
  117.                 secondaryMetadata, cdmDataContext);
  118.         final FieldOrbit<T> secondaryOrbit = secondaryOrbitFromCdm.getType().convertToFieldOrbit(field,
  119.                 secondaryOrbitFromCdm);
  120.         final FieldStateCovariance<T> secondaryCovariance =
  121.                 Fieldifier.fieldify(field, getObjectStateCovarianceFromCdm(cdmRelativeMetadata, secondaryData));

  122.         return compute(primaryOrbit, primaryCovariance, secondaryOrbit, secondaryCovariance, combinedRadius, zeroThreshold);
  123.     }

  124.     /** {@inheritDoc} */
  125.     public ProbabilityOfCollision compute(final Orbit primaryAtTCA,
  126.                                           final StateCovariance primaryCovariance,
  127.                                           final Orbit secondaryAtTCA,
  128.                                           final StateCovariance secondaryCovariance,
  129.                                           final double combinedRadius,
  130.                                           final double zeroThreshold) {

  131.         final ShortTermEncounter2DDefinition shortTermEncounter2DDefinition = new ShortTermEncounter2DDefinition(
  132.                 primaryAtTCA, primaryCovariance, secondaryAtTCA, secondaryCovariance,
  133.                 combinedRadius, EncounterLOFType.DEFAULT, DEFAULT_TCA_DIFFERENCE_TOLERANCE);

  134.         return compute(shortTermEncounter2DDefinition, zeroThreshold);
  135.     }

  136.     /** {@inheritDoc} */
  137.     public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(
  138.             final FieldOrbit<T> primaryAtTCA, final FieldStateCovariance<T> primaryCovariance,
  139.             final FieldOrbit<T> secondaryAtTCA, final FieldStateCovariance<T> secondaryCovariance,
  140.             final T combinedRadius, final double zeroThreshold) {

  141.         final FieldShortTermEncounter2DDefinition<T> FieldShortTermEncounter2DDefinition =
  142.                 new FieldShortTermEncounter2DDefinition<>(
  143.                         primaryAtTCA, primaryCovariance, secondaryAtTCA, secondaryCovariance,
  144.                         combinedRadius, EncounterLOFType.DEFAULT, DEFAULT_TCA_DIFFERENCE_TOLERANCE);

  145.         return compute(FieldShortTermEncounter2DDefinition, zeroThreshold);
  146.     }

  147.     /** {@inheritDoc} */
  148.     public ProbabilityOfCollision compute(final ShortTermEncounter2DDefinition encounter,
  149.                                           final double zeroThreshold) {

  150.         final Vector2D otherPositionAfterRotationInCollisionPlane =
  151.                 encounter.computeOtherPositionInRotatedCollisionPlane(zeroThreshold);

  152.         final RealMatrix projectedDiagonalizedCombinedPositionalCovarianceMatrix =
  153.                 encounter.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();

  154.         return compute(otherPositionAfterRotationInCollisionPlane.getX(),
  155.                        otherPositionAfterRotationInCollisionPlane.getY(),
  156.                        FastMath.sqrt(projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(0, 0)),
  157.                        FastMath.sqrt(projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(1, 1)),
  158.                        encounter.getCombinedRadius());
  159.     }

  160.     /** {@inheritDoc} */
  161.     public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(
  162.             final FieldShortTermEncounter2DDefinition<T> encounter, final double zeroThreshold) {

  163.         final FieldVector2D<T> otherPositionAfterRotationInCollisionPlane =
  164.                 encounter.computeOtherPositionInRotatedCollisionPlane(zeroThreshold);

  165.         final FieldMatrix<T> projectedDiagonalizedCombinedPositionalCovarianceMatrix =
  166.                 encounter.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();

  167.         return compute(otherPositionAfterRotationInCollisionPlane.getX(),
  168.                        otherPositionAfterRotationInCollisionPlane.getY(),
  169.                        projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(0, 0).sqrt(),
  170.                        projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(1, 1).sqrt(),
  171.                        encounter.getCombinedRadius());
  172.     }

  173.     /** {@inheritDoc} */
  174.     @Override
  175.     public String getName() {
  176.         return name;
  177.     }

  178.     /** {@inheritDoc} */
  179.     @Override
  180.     public boolean isAMaximumProbabilityOfCollisionMethod() {
  181.         return false;
  182.     }

  183.     /**
  184.      * Extract collision object spacecraft state from given {@link Cdm Conjunction Data Message} data.
  185.      *
  186.      * @param cdmRelativeMetadata conjunction data message relative metadata
  187.      * @param cdmData collision object conjunction data message data
  188.      * @param cdmMetadata collision object conjunction data message metadata
  189.      * @param cdmDataContext conjunction data message data context
  190.      *
  191.      * @return basic collision object spacecraft state from conjunction data message
  192.      */
  193.     protected Orbit getObjectOrbitFromCdm(final CdmRelativeMetadata cdmRelativeMetadata,
  194.                                           final CdmData cdmData,
  195.                                           final CdmMetadata cdmMetadata,
  196.                                           final DataContext cdmDataContext) {

  197.         // Extract orbit
  198.         final Frame        frame = cdmMetadata.getRefFrame().asFrame();
  199.         final AbsoluteDate tca   = cdmRelativeMetadata.getTca();
  200.         final PVCoordinates pvInFrame = new PVCoordinates(cdmData.getStateVectorBlock().getPositionVector(),
  201.                                                           cdmData.getStateVectorBlock().getVelocityVector());
  202.         final double mu = cdmMetadata.getOrbitCenter().getBody().getGM();

  203.         // Simple case where the reference frame is already pseudo-inertial
  204.         if (frame.isPseudoInertial()) {
  205.             return new CartesianOrbit(pvInFrame, frame, tca, mu);
  206.         }
  207.         // Otherwise, convert coordinates to default inertial frame
  208.         final Frame         inertial     = cdmDataContext.getFrames().getGCRF();
  209.         final Transform     toInertial   = frame.getTransformTo(inertial, cdmRelativeMetadata.getTca());
  210.         final PVCoordinates pvInInertial = toInertial.transformPVCoordinates(pvInFrame);

  211.         return new CartesianOrbit(pvInInertial, inertial, tca, mu);
  212.     }

  213.     /**
  214.      * Get collision object state covariance from given {@link Cdm Conjunction Data Message} data.
  215.      *
  216.      * @param cdmRelativeMetadata conjunction data message relative metadata
  217.      * @param cdmData collision object conjunction data message data
  218.      *
  219.      * @return collision object state covariance
  220.      */
  221.     protected StateCovariance getObjectStateCovarianceFromCdm(final CdmRelativeMetadata cdmRelativeMetadata,
  222.                                                               final CdmData cdmData) {
  223.         final AbsoluteDate tca = cdmRelativeMetadata.getTca();
  224.         final RealMatrix rtnCovarianceMatrix =
  225.                 cdmData.getRTNCovarianceBlock().getRTNCovarianceMatrix().getSubMatrix(0, 5, 0, 5);
  226.         return new StateCovariance(rtnCovarianceMatrix, tca, LOFType.QSW_INERTIAL);
  227.     }

  228. }