Пример #1
1
    /** {@inheritDoc} */
    @Override
    public SpacecraftState mapArrayToState(final double t, final double[] y, final boolean meanOnly)
        throws OrekitException {

      final AbsoluteDate date = mapDoubleToDate(t);

      // add short periodic variations to mean elements to get osculating elements
      // (the loop may not be performed if there are no force models and in the
      //  case we want to remain in mean parameters only)
      final double[] elements = y.clone();
      if (!meanOnly) {
        for (final DSSTForceModel forceModel : forceModels) {
          final double[] shortPeriodic = forceModel.getShortPeriodicVariations(date, y);
          for (int i = 0; i < shortPeriodic.length; i++) {
            elements[i] += shortPeriodic[i];
          }
        }
      }

      final double mass = elements[6];
      if (mass <= 0.0) {
        throw new PropagationException(OrekitMessages.SPACECRAFT_MASS_BECOMES_NEGATIVE, mass);
      }

      final Orbit orbit =
          OrbitType.EQUINOCTIAL.mapArrayToOrbit(
              elements, PositionAngle.MEAN, date, getMu(), getFrame());
      final Attitude attitude = getAttitudeProvider().getAttitude(orbit, date, getFrame());

      return new SpacecraftState(orbit, attitude, mass);
    }
Пример #2
0
    /** {@inheritDoc} */
    @Override
    public double[] computeDerivatives(final SpacecraftState state) throws OrekitException {

      // compute common auxiliary elements
      final AuxiliaryElements aux = new AuxiliaryElements(state.getOrbit(), I);

      // initialize all perturbing forces
      for (final DSSTForceModel force : mapper.getForceModels()) {
        force.initializeStep(aux);
      }

      Arrays.fill(yDot, 0.0);

      // compute the contributions of all perturbing forces
      for (final DSSTForceModel forceModel : mapper.getForceModels()) {
        final double[] daidt = forceModel.getMeanElementRate(state);
        for (int i = 0; i < daidt.length; i++) {
          yDot[i] += daidt[i];
        }
      }

      // finalize derivatives by adding the Kepler contribution
      final EquinoctialOrbit orbit =
          (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(state.getOrbit());
      orbit.addKeplerContribution(PositionAngle.MEAN, getMu(), yDot);

      return yDot.clone();
    }
Пример #3
0
    /**
     * Compute osculating state from mean state.
     *
     * <p>Compute and add the short periodic variation to the mean {@link SpacecraftState}.
     *
     * @param meanState initial mean state
     * @return osculating state
     * @throws OrekitException if the computation of the short-periodic variation fails
     */
    private Orbit computeOsculatingOrbit(final SpacecraftState meanState) throws OrekitException {

      resetShortPeriodicsCoefficients();
      computeShortPeriodicsCoefficients(meanState);

      final double[] mean = new double[6];
      OrbitType.EQUINOCTIAL.mapOrbitToArray(meanState.getOrbit(), PositionAngle.MEAN, mean);
      final double[] y = mean.clone();
      for (final DSSTForceModel forceModel : this.forceModels) {

        final double[] shortPeriodic =
            forceModel.getShortPeriodicVariations(meanState.getDate(), mean);

        for (int i = 0; i < shortPeriodic.length; i++) {
          y[i] += shortPeriodic[i];
        }
      }
      return OrbitType.EQUINOCTIAL.mapArrayToOrbit(
          y, PositionAngle.MEAN, meanState.getDate(), meanState.getMu(), meanState.getFrame());
    }
Пример #4
0
    /** {@inheritDoc} */
    @Override
    public void mapStateToArray(final SpacecraftState state, final double[] y)
        throws OrekitException {

      final Orbit meanOrbit;
      if (!initialIsOsculating) {
        // the state is considered to be already a mean state
        meanOrbit = state.getOrbit();
      } else {
        // the state is considered to be an osculating state
        meanOrbit = computeMeanState(state, forceModels).getOrbit();
      }

      OrbitType.EQUINOCTIAL.mapOrbitToArray(meanOrbit, PositionAngle.MEAN, y);
      y[6] = state.getMass();
    }
Пример #5
0
  /**
   * Compute the differential effect of J2 on an orbit.
   *
   * @param orbit1 original orbit at t₁, without differential J2
   * @return orbit at t₁, always taking the effect into account
   */
  private Orbit updateOrbit(final Orbit orbit1) {

    // convert current orbital state to equinoctial elements
    final EquinoctialOrbit original = (EquinoctialOrbit) OrbitType.EQUINOCTIAL.convertType(orbit1);

    // compute differential effect
    final AbsoluteDate date = original.getDate();
    final double dt = date.durationFrom(referenceDate);
    final double dPaRaan = (dPaDot + dRaanDot) * dt;
    final double cPaRaan = FastMath.cos(dPaRaan);
    final double sPaRaan = FastMath.sin(dPaRaan);
    final double dRaan = dRaanDot * dt;
    final double cRaan = FastMath.cos(dRaan);
    final double sRaan = FastMath.sin(dRaan);

    final double ex = original.getEquinoctialEx() * cPaRaan - original.getEquinoctialEy() * sPaRaan;
    final double ey = original.getEquinoctialEx() * sPaRaan + original.getEquinoctialEy() * cPaRaan;
    final double hx = original.getHx() * cRaan - original.getHy() * sRaan;
    final double hy = original.getHx() * sRaan + original.getHy() * cRaan;
    final double lambda = original.getLv() + dPaRaan;

    // build updated orbit
    final EquinoctialOrbit updated =
        new EquinoctialOrbit(
            original.getA(),
            ex,
            ey,
            hx,
            hy,
            lambda,
            PositionAngle.TRUE,
            original.getFrame(),
            date,
            original.getMu());

    // convert to required type
    return orbit1.getType().convertType(updated);
  }
Пример #6
0
  /** {@inheritDoc} */
  @Override
  public double[] getShortPeriodicVariations(final AbsoluteDate date, final double[] meanElements)
      throws OrekitException {

    // Initialise the short periodic variations
    final double[] shortPeriodicVariation = new double[] {0., 0., 0., 0., 0., 0.};

    // Compute only if there is at least one non-resonant tesseral or
    // only the m-daily tesseral should be taken into account
    if (!nonResOrders.isEmpty() || mDailiesOnly) {

      // Build an Orbit object from the mean elements
      final Orbit meanOrbit =
          OrbitType.EQUINOCTIAL.mapArrayToOrbit(
              meanElements, PositionAngle.MEAN, date, provider.getMu(), this.frame);

      // Build an auxiliary object
      final AuxiliaryElements aux = new AuxiliaryElements(meanOrbit, I);

      // Central body rotation angle from equation 2.7.1-(3)(4).
      final Transform t = bodyFrame.getTransformTo(aux.getFrame(), aux.getDate());
      final Vector3D xB = t.transformVector(Vector3D.PLUS_I);
      final Vector3D yB = t.transformVector(Vector3D.PLUS_J);
      final double currentTheta =
          FastMath.atan2(
              -f.dotProduct(yB) + I * g.dotProduct(xB), f.dotProduct(xB) + I * g.dotProduct(yB));

      // Add the m-daily contribution
      for (int m = 1; m <= maxOrderMdailyTesseralSP; m++) {
        // Phase angle
        final double jlMmt = -m * currentTheta;
        final double sinPhi = FastMath.sin(jlMmt);
        final double cosPhi = FastMath.cos(jlMmt);

        // compute contribution for each element
        for (int i = 0; i < 6; i++) {
          shortPeriodicVariation[i] +=
              tesseralSPCoefs.getCijm(i, 0, m, date) * cosPhi
                  + tesseralSPCoefs.getSijm(i, 0, m, date) * sinPhi;
        }
      }

      // loop through all non-resonant (j,m) pairs
      for (final Map.Entry<Integer, List<Integer>> entry : nonResOrders.entrySet()) {
        final int m = entry.getKey();
        final List<Integer> listJ = entry.getValue();

        for (int j : listJ) {
          // Phase angle
          final double jlMmt = j * meanElements[5] - m * currentTheta;
          final double sinPhi = FastMath.sin(jlMmt);
          final double cosPhi = FastMath.cos(jlMmt);

          // compute contribution for each element
          for (int i = 0; i < 6; i++) {
            shortPeriodicVariation[i] +=
                tesseralSPCoefs.getCijm(i, j, m, date) * cosPhi
                    + tesseralSPCoefs.getSijm(i, j, m, date) * sinPhi;
          }
        }
      }
    }

    return shortPeriodicVariation;
  }