AttitudeDetermination.java

  1. /* Copyright 2002-2024 Luc Maisonobe
  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.files.ccsds.ndm.adm.acm;

  18. import java.util.ArrayList;
  19. import java.util.Collections;
  20. import java.util.List;

  21. import org.hipparchus.geometry.euclidean.threed.RotationOrder;
  22. import org.orekit.errors.OrekitException;
  23. import org.orekit.errors.OrekitMessages;
  24. import org.orekit.files.ccsds.definitions.AdMethodType;
  25. import org.orekit.files.ccsds.ndm.adm.AttitudeEndpoints;
  26. import org.orekit.files.ccsds.section.CommentsContainer;

  27. /** Attitude determination data.
  28.  * @author Luc Maisonobe
  29.  * @since 12.0
  30.  */
  31. public class AttitudeDetermination extends CommentsContainer {

  32.     /** Endpoints (i.e. frames A, B and their relationship). */
  33.     private final AttitudeEndpoints endpoints;

  34.     /** Identification number. */
  35.     private String id;

  36.     /** Identification of previous orbit determination. */
  37.     private String prevId;

  38.     /** Attitude determination method. */
  39.     private AdMethodType method;

  40.     /** Source of attitude estimate. */
  41.     private String source;

  42.     /** Rotation order for Euler angles. */
  43.     private RotationOrder eulerRotSeq;

  44.     /** Number of states for {@link AdMethodType#EKF}, {@link AdMethodType#BATCH} or {@link AdMethodType#FILTER_SMOOTHER}. */
  45.     private int nbStates;

  46.     /** Attitude states. */
  47.     private AttitudeElementsType attitudeStates;

  48.     /** Type of attitude error state. */
  49.     private AttitudeCovarianceType covarianceType;

  50.     /** Attitude rate states. */
  51.     private RateElementsType rateStates;

  52.     /** Rate random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}. */
  53.     private double sigmaU;

  54.     /** Angle random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}. */
  55.     private double sigmaV;

  56.     /** Process noise standard deviation if {@link #rateStates} is {@link RateElementsType#ANGVEL}. */
  57.     private double rateProcessNoiseStdDev;

  58.     /** Sensors used. */
  59.     private List<AttitudeDeterminationSensor> sensorsUsed;

  60.     /** Simple constructor.
  61.      */
  62.     public AttitudeDetermination() {
  63.         endpoints   = new AttitudeEndpoints();
  64.         sensorsUsed = new ArrayList<>();
  65.         nbStates    = -1;
  66.     }

  67.     /** {@inheritDoc} */
  68.     @Override
  69.     public void validate(final double version) {
  70.         super.validate(version);
  71.         checkNotNull(attitudeStates, AttitudeDeterminationKey.ATTITUDE_STATES.name());
  72.         endpoints.checkExternalFrame(AttitudeDeterminationKey.REF_FRAME_A,
  73.                                      AttitudeDeterminationKey.REF_FRAME_B);

  74.         // check sensors in increasing number
  75.         for (int number = 1; number <= sensorsUsed.size(); ++number) {
  76.             final AttitudeDeterminationSensor sensor = findSensor(number);
  77.             if (sensor != null) {
  78.                 sensor.validate(version);
  79.             } else {
  80.                 // no sensor has the expected index
  81.                 throw new OrekitException(OrekitMessages.CCSDS_MISSING_SENSOR_INDEX, number);
  82.             }

  83.         }

  84.     }

  85.     /** Find sensor by number.
  86.      * @param number number of the sensor
  87.      * @return sensor with specified number, or null if not found
  88.      */
  89.     private AttitudeDeterminationSensor findSensor(final int number) {
  90.         for (final AttitudeDeterminationSensor sensor : sensorsUsed) {
  91.             if (sensor.getSensorNumber() == number) {
  92.                 return sensor;
  93.             }
  94.         }
  95.         return null;
  96.     }

  97.     /** Get the endpoints (i.e. frames A, B and their relationship).
  98.      * @return endpoints
  99.      */
  100.     public AttitudeEndpoints getEndpoints() {
  101.         return endpoints;
  102.     }

  103.     /** Get identification number.
  104.      * @return identification number
  105.      */
  106.     public String getId() {
  107.         return id;
  108.     }

  109.     /** Set identification number.
  110.      * @param id identification number
  111.      */
  112.     public void setId(final String id) {
  113.         this.id = id;
  114.     }

  115.     /** Get identification of previous orbit determination.
  116.      * @return identification of previous orbit determination
  117.      */
  118.     public String getPrevId() {
  119.         return prevId;
  120.     }

  121.     /** Set identification of previous orbit determination.
  122.      * @param prevId identification of previous orbit determination
  123.      */
  124.     public void setPrevId(final String prevId) {
  125.         this.prevId = prevId;
  126.     }

  127.     /** Get attitude determination method.
  128.      * @return attitude determination method
  129.      */
  130.     public AdMethodType getMethod() {
  131.         return method;
  132.     }

  133.     /** Set attitude determination method.
  134.      * @param method attitude determination method
  135.      */
  136.     public void setMethod(final AdMethodType method) {
  137.         this.method = method;
  138.     }

  139.     /** Get source of attitude estimate.
  140.      * @return source of attitude estimate
  141.      */
  142.     public String getSource() {
  143.         return source;
  144.     }

  145.     /** Set source of attitude estimate.
  146.      * @param source source of attitude estimate
  147.      */
  148.     public void setSource(final String source) {
  149.         this.source = source;
  150.     }

  151.     /** Get the rotation order for Euler angles.
  152.      * @return rotation order for Euler angles
  153.      */
  154.     public RotationOrder getEulerRotSeq() {
  155.         return eulerRotSeq;
  156.     }

  157.     /** Set the rotation order for Euler angles.
  158.      * @param eulerRotSeq rotation order for Euler angles
  159.      */
  160.     public void setEulerRotSeq(final RotationOrder eulerRotSeq) {
  161.         this.eulerRotSeq = eulerRotSeq;
  162.     }

  163.     /** Get number of states for {@link AdMethodType#EKF}, {@link AdMethodType#BATCH} or {@link AdMethodType#FILTER_SMOOTHER}.
  164.      * @return number of states
  165.      */
  166.     public int getNbStates() {
  167.         return nbStates;
  168.     }

  169.     /** Set number of states for {@link AdMethodType#EKF}, {@link AdMethodType#BATCH} or {@link AdMethodType#FILTER_SMOOTHER}.
  170.      * @param nbStates number of states
  171.      */
  172.     public void setNbStates(final int nbStates) {
  173.         this.nbStates = nbStates;
  174.     }

  175.     /** Get attitude states.
  176.      * @return attitude states
  177.      */
  178.     public AttitudeElementsType getAttitudeStates() {
  179.         return attitudeStates;
  180.     }

  181.     /** Set attitude states.
  182.      * @param attitudeStates attitude states
  183.      */
  184.     public void setAttitudeStates(final AttitudeElementsType attitudeStates) {
  185.         this.attitudeStates = attitudeStates;
  186.     }

  187.     /** Get type of attitude error state.
  188.      * @return type of attitude error state
  189.      */
  190.     public AttitudeCovarianceType getCovarianceType() {
  191.         return covarianceType;
  192.     }

  193.     /** Set type of attitude error state.
  194.      * @param covarianceType type of attitude error state
  195.      */
  196.     public void setCovarianceType(final AttitudeCovarianceType covarianceType) {
  197.         this.covarianceType = covarianceType;
  198.     }

  199.     /** Get attitude rate states.
  200.      * @return attitude rate states
  201.      */
  202.     public RateElementsType getRateStates() {
  203.         return rateStates;
  204.     }

  205.     /** Set attitude rate states.
  206.      * @param rateStates attitude rate states
  207.      */
  208.     public void setRateStates(final RateElementsType rateStates) {
  209.         this.rateStates = rateStates;
  210.     }

  211.     /** Get rate random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}.
  212.      * @return rate random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}
  213.      */
  214.     public double getSigmaU() {
  215.         return sigmaU;
  216.     }

  217.     /** Set rate random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}.
  218.      * @param sigmaU rate random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}
  219.      */
  220.     public void setSigmaU(final double sigmaU) {
  221.         this.sigmaU = sigmaU;
  222.     }

  223.     /** Get angle random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}.
  224.      * @return angle random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}
  225.      */
  226.     public double getSigmaV() {
  227.         return sigmaV;
  228.     }

  229.     /** Set angle random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}.
  230.      * @param sigmaV angle random walk if {@link #rateStates} is {@link RateElementsType#GYRO_BIAS}
  231.      */
  232.     public void setSigmaV(final double sigmaV) {
  233.         this.sigmaV = sigmaV;
  234.     }

  235.     /** Get process noise standard deviation if {@link #rateStates} is {@link RateElementsType#ANGVEL}.
  236.      * @return process noise standard deviation if {@link #rateStates} is {@link RateElementsType#ANGVEL}
  237.      */
  238.     public double getRateProcessNoiseStdDev() {
  239.         return rateProcessNoiseStdDev;
  240.     }

  241.     /** Set process noise standard deviation if {@link #rateStates} is {@link RateElementsType#ANGVEL}.
  242.      * @param rateProcessNoiseStdDev process noise standard deviation if {@link #rateStates} is {@link RateElementsType#ANGVEL}
  243.      */
  244.     public void setRateProcessNoiseStdDev(final double rateProcessNoiseStdDev) {
  245.         this.rateProcessNoiseStdDev = rateProcessNoiseStdDev;
  246.     }

  247.     /** Get sensors used.
  248.      * @return sensors used
  249.      */
  250.     public List<AttitudeDeterminationSensor> getSensorsUsed() {
  251.         return Collections.unmodifiableList(sensorsUsed);
  252.     }

  253.     /** Add a sensor used.
  254.      * @param sensor sensor to add
  255.      */
  256.     public void addSensor(final AttitudeDeterminationSensor sensor) {
  257.         for (final AttitudeDeterminationSensor existing : sensorsUsed) {
  258.             if (sensor.getSensorNumber() == existing.getSensorNumber()) {
  259.                 throw new OrekitException(OrekitMessages.CCSDS_SENSOR_INDEX_ALREADY_USED, sensor.getSensorNumber());
  260.             }
  261.         }
  262.         sensorsUsed.add(sensor);
  263.     }

  264. }