AbstractShortTermEncounter2DPOCMethod.java
- /* Copyright 2002-2024 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.ssa.collision.shorttermencounter.probability.twod;
- import org.hipparchus.CalculusFieldElement;
- import org.hipparchus.Field;
- import org.hipparchus.geometry.euclidean.twod.FieldVector2D;
- import org.hipparchus.geometry.euclidean.twod.Vector2D;
- import org.hipparchus.linear.FieldMatrix;
- import org.hipparchus.linear.RealMatrix;
- import org.hipparchus.util.FastMath;
- import org.orekit.data.DataContext;
- import org.orekit.files.ccsds.ndm.cdm.Cdm;
- import org.orekit.files.ccsds.ndm.cdm.CdmData;
- import org.orekit.files.ccsds.ndm.cdm.CdmMetadata;
- import org.orekit.files.ccsds.ndm.cdm.CdmRelativeMetadata;
- import org.orekit.frames.Frame;
- import org.orekit.frames.LOFType;
- import org.orekit.frames.Transform;
- import org.orekit.frames.encounter.EncounterLOFType;
- import org.orekit.orbits.CartesianOrbit;
- import org.orekit.orbits.FieldOrbit;
- import org.orekit.orbits.Orbit;
- import org.orekit.propagation.FieldStateCovariance;
- import org.orekit.propagation.StateCovariance;
- import org.orekit.ssa.metrics.FieldProbabilityOfCollision;
- import org.orekit.ssa.metrics.ProbabilityOfCollision;
- import org.orekit.time.AbsoluteDate;
- import org.orekit.utils.Fieldifier;
- import org.orekit.utils.PVCoordinates;
- /**
- * This abstract class serves as a foundation to create 2D probability of collision computing method assuming a short term
- * encounter model.
- * <p>
- * All the methods extending this class will at least assume the followings :
- * <ul>
- * <li>Short term encounter leading to a linear relative motion.</li>
- * <li>Spherical collision object.</li>
- * <li>Uncorrelated positional covariance.</li>
- * <li>Gaussian distribution of the position uncertainties.</li>
- * <li>Deterministic velocity i.e. no velocity uncertainties.</li>
- * </ul>
- * As listed in the assumptions, methods extending this class are to be used in short encounter,
- * meaning that there must be a high relative velocity. For ease of computation, the resulting swept volume
- * is extended to infinity so that the integral becomes bivariate instead of trivariate (conservative hypothesis).
- * <p>
- * Consequently and if we consider Earth, methods implementing this interface are <u><b>recommended</b></u> for
- * collision happening in Low/Medium Earth Orbit (LEO and MEO) but are <u><b>not recommended</b></u> for collision
- * happening in Geostationary Earth Orbit (GEO).
- *
- * @author Vincent Cucchietti
- * @since 12.0
- */
- public abstract class AbstractShortTermEncounter2DPOCMethod implements ShortTermEncounter2DPOCMethod {
- /** Default time of closest approach difference tolerance. */
- public static final double DEFAULT_TCA_DIFFERENCE_TOLERANCE = 1e-6;
- /** Name of the method. */
- private final String name;
- /**
- * Constructor.
- *
- * @param name name of the method
- */
- protected AbstractShortTermEncounter2DPOCMethod(final String name) {
- this.name = name;
- }
- /** {@inheritDoc} */
- public ProbabilityOfCollision compute(final Cdm cdm, final double combinedRadius) {
- final CdmRelativeMetadata cdmRelativeMetadata = cdm.getRelativeMetadata();
- final CdmData primaryData = cdm.getDataObject1();
- final CdmData secondaryData = cdm.getDataObject2();
- final DataContext cdmDataContext = cdm.getDataContext();
- // Extract primary data
- final Orbit primaryOrbit = getObjectOrbitFromCdm(cdmRelativeMetadata, primaryData,
- cdm.getMetadataObject1(), cdmDataContext);
- final StateCovariance primaryCovariance = getObjectStateCovarianceFromCdm(cdmRelativeMetadata, primaryData);
- // Extract secondary data
- final Orbit secondaryOrbit = getObjectOrbitFromCdm(cdmRelativeMetadata, secondaryData,
- cdm.getMetadataObject2(), cdmDataContext);
- final StateCovariance secondaryCovariance = getObjectStateCovarianceFromCdm(cdmRelativeMetadata, secondaryData);
- return compute(primaryOrbit, primaryCovariance, secondaryOrbit, secondaryCovariance, combinedRadius,
- DEFAULT_ZERO_THRESHOLD);
- }
- /** {@inheritDoc} */
- public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(final Cdm cdm,
- final T combinedRadius,
- final double zeroThreshold) {
- final Field<T> field = combinedRadius.getField();
- final CdmRelativeMetadata cdmRelativeMetadata = cdm.getRelativeMetadata();
- final CdmData primaryData = cdm.getDataObject1();
- final CdmData secondaryData = cdm.getDataObject2();
- final CdmMetadata primaryMetadata = cdm.getMetadataObject1();
- final CdmMetadata secondaryMetadata = cdm.getMetadataObject2();
- final DataContext cdmDataContext = cdm.getDataContext();
- // Extract primary data
- final Orbit primaryOrbitFromCdm = getObjectOrbitFromCdm(cdmRelativeMetadata, primaryData,
- primaryMetadata, cdmDataContext);
- final FieldOrbit<T> primaryOrbit = primaryOrbitFromCdm.getType().convertToFieldOrbit(field,
- primaryOrbitFromCdm);
- final FieldStateCovariance<T> primaryCovariance =
- Fieldifier.fieldify(field, getObjectStateCovarianceFromCdm(cdmRelativeMetadata, primaryData));
- // Extract secondary data
- final Orbit secondaryOrbitFromCdm = getObjectOrbitFromCdm(cdmRelativeMetadata, secondaryData,
- secondaryMetadata, cdmDataContext);
- final FieldOrbit<T> secondaryOrbit = secondaryOrbitFromCdm.getType().convertToFieldOrbit(field,
- secondaryOrbitFromCdm);
- final FieldStateCovariance<T> secondaryCovariance =
- Fieldifier.fieldify(field, getObjectStateCovarianceFromCdm(cdmRelativeMetadata, secondaryData));
- return compute(primaryOrbit, primaryCovariance, secondaryOrbit, secondaryCovariance, combinedRadius, zeroThreshold);
- }
- /** {@inheritDoc} */
- public ProbabilityOfCollision compute(final Orbit primaryAtTCA,
- final StateCovariance primaryCovariance,
- final Orbit secondaryAtTCA,
- final StateCovariance secondaryCovariance,
- final double combinedRadius,
- final double zeroThreshold) {
- final ShortTermEncounter2DDefinition shortTermEncounter2DDefinition = new ShortTermEncounter2DDefinition(
- primaryAtTCA, primaryCovariance, secondaryAtTCA, secondaryCovariance,
- combinedRadius, EncounterLOFType.DEFAULT, DEFAULT_TCA_DIFFERENCE_TOLERANCE);
- return compute(shortTermEncounter2DDefinition, zeroThreshold);
- }
- /** {@inheritDoc} */
- public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(
- final FieldOrbit<T> primaryAtTCA, final FieldStateCovariance<T> primaryCovariance,
- final FieldOrbit<T> secondaryAtTCA, final FieldStateCovariance<T> secondaryCovariance,
- final T combinedRadius, final double zeroThreshold) {
- final FieldShortTermEncounter2DDefinition<T> FieldShortTermEncounter2DDefinition =
- new FieldShortTermEncounter2DDefinition<>(
- primaryAtTCA, primaryCovariance, secondaryAtTCA, secondaryCovariance,
- combinedRadius, EncounterLOFType.DEFAULT, DEFAULT_TCA_DIFFERENCE_TOLERANCE);
- return compute(FieldShortTermEncounter2DDefinition, zeroThreshold);
- }
- /** {@inheritDoc} */
- public ProbabilityOfCollision compute(final ShortTermEncounter2DDefinition encounter,
- final double zeroThreshold) {
- final Vector2D otherPositionAfterRotationInCollisionPlane =
- encounter.computeOtherPositionInRotatedCollisionPlane(zeroThreshold);
- final RealMatrix projectedDiagonalizedCombinedPositionalCovarianceMatrix =
- encounter.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();
- return compute(otherPositionAfterRotationInCollisionPlane.getX(),
- otherPositionAfterRotationInCollisionPlane.getY(),
- FastMath.sqrt(projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(0, 0)),
- FastMath.sqrt(projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(1, 1)),
- encounter.getCombinedRadius());
- }
- /** {@inheritDoc} */
- public <T extends CalculusFieldElement<T>> FieldProbabilityOfCollision<T> compute(
- final FieldShortTermEncounter2DDefinition<T> encounter, final double zeroThreshold) {
- final FieldVector2D<T> otherPositionAfterRotationInCollisionPlane =
- encounter.computeOtherPositionInRotatedCollisionPlane(zeroThreshold);
- final FieldMatrix<T> projectedDiagonalizedCombinedPositionalCovarianceMatrix =
- encounter.computeProjectedAndDiagonalizedCombinedPositionalCovarianceMatrix();
- return compute(otherPositionAfterRotationInCollisionPlane.getX(),
- otherPositionAfterRotationInCollisionPlane.getY(),
- projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(0, 0).sqrt(),
- projectedDiagonalizedCombinedPositionalCovarianceMatrix.getEntry(1, 1).sqrt(),
- encounter.getCombinedRadius());
- }
- /** {@inheritDoc} */
- @Override
- public String getName() {
- return name;
- }
- /** {@inheritDoc} */
- @Override
- public boolean isAMaximumProbabilityOfCollisionMethod() {
- return false;
- }
- /**
- * Extract collision object spacecraft state from given {@link Cdm Conjunction Data Message} data.
- *
- * @param cdmRelativeMetadata conjunction data message relative metadata
- * @param cdmData collision object conjunction data message data
- * @param cdmMetadata collision object conjunction data message metadata
- * @param cdmDataContext conjunction data message data context
- *
- * @return basic collision object spacecraft state from conjunction data message
- */
- protected Orbit getObjectOrbitFromCdm(final CdmRelativeMetadata cdmRelativeMetadata,
- final CdmData cdmData,
- final CdmMetadata cdmMetadata,
- final DataContext cdmDataContext) {
- // Extract orbit
- final Frame frame = cdmMetadata.getRefFrame().asFrame();
- final AbsoluteDate tca = cdmRelativeMetadata.getTca();
- final PVCoordinates pvInFrame = new PVCoordinates(cdmData.getStateVectorBlock().getPositionVector(),
- cdmData.getStateVectorBlock().getVelocityVector());
- final double mu = cdmMetadata.getOrbitCenter().getBody().getGM();
- // Simple case where the reference frame is already pseudo-inertial
- if (frame.isPseudoInertial()) {
- return new CartesianOrbit(pvInFrame, frame, tca, mu);
- }
- // Otherwise, convert coordinates to default inertial frame
- final Frame inertial = cdmDataContext.getFrames().getGCRF();
- final Transform toInertial = frame.getTransformTo(inertial, cdmRelativeMetadata.getTca());
- final PVCoordinates pvInInertial = toInertial.transformPVCoordinates(pvInFrame);
- return new CartesianOrbit(pvInInertial, inertial, tca, mu);
- }
- /**
- * Get collision object state covariance from given {@link Cdm Conjunction Data Message} data.
- *
- * @param cdmRelativeMetadata conjunction data message relative metadata
- * @param cdmData collision object conjunction data message data
- *
- * @return collision object state covariance
- */
- protected StateCovariance getObjectStateCovarianceFromCdm(final CdmRelativeMetadata cdmRelativeMetadata,
- final CdmData cdmData) {
- final AbsoluteDate tca = cdmRelativeMetadata.getTca();
- final RealMatrix rtnCovarianceMatrix =
- cdmData.getRTNCovarianceBlock().getRTNCovarianceMatrix().getSubMatrix(0, 5, 0, 5);
- return new StateCovariance(rtnCovarianceMatrix, tca, LOFType.QSW_INERTIAL);
- }
- }