예제 #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
  /**
   * Method called just before integration.
   *
   * <p>The default implementation does nothing, it may be specialized in subclasses.
   *
   * @param initialState initial state
   * @param tEnd target date at which state should be propagated
   * @exception OrekitException if hook cannot be run
   */
  @Override
  protected void beforeIntegration(final SpacecraftState initialState, final AbsoluteDate tEnd)
      throws OrekitException {

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

    // check if only mean elements must be used
    final boolean meanOnly = isMeanOrbit();

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

    // if required, insert the special short periodics step handler
    if (!meanOnly) {
      final InterpolationGrid grid =
          new VariableStepInterpolationGrid(INTERPOLATION_POINTS_PER_STEP);
      final ShortPeriodicsHandler spHandler = new ShortPeriodicsHandler(grid);
      final Collection<StepHandler> stepHandlers = new ArrayList<StepHandler>();
      stepHandlers.add(spHandler);
      final AbstractIntegrator integrator = getIntegrator();
      final Collection<StepHandler> existing = integrator.getStepHandlers();
      stepHandlers.addAll(existing);

      integrator.clearStepHandlers();

      // add back the existing handlers after the short periodics one
      for (final StepHandler sp : stepHandlers) {
        integrator.addStepHandler(sp);
      }
    }
  }
예제 #4
0
  /**
   * Conversion from osculating to mean, orbit.
   *
   * <p>Compute osculating state <b>in a DSST sense</b>, corresponding to the mean SpacecraftState
   * in input, and according to the Force models taken into account.
   *
   * <p>Since the osculating state is obtained with the computation of short-periodic variation of
   * each force model, the resulting output will depend on the force models parametrized in input.
   *
   * <p>The computing is done through a fixed-point iteration process.
   *
   * @param osculating Osculating state to convert
   * @param forces Forces to take into account
   * @return mean state in a DSST sense
   * @throws OrekitException if computation of short periodics fails or iteration algorithm does not
   *     converge
   */
  public static SpacecraftState computeMeanState(
      final SpacecraftState osculating, final Collection<DSSTForceModel> forces)
      throws OrekitException {

    // Creation of a DSSTPropagator instance
    final AbstractIntegrator integrator = new ClassicalRungeKuttaIntegrator(43200.);
    final DSSTPropagator dsst = new DSSTPropagator(integrator, false);
    // Create the auxiliary object
    final AuxiliaryElements aux = new AuxiliaryElements(osculating.getOrbit(), I);

    // Set the force models
    for (final DSSTForceModel force : forces) {
      force.initialize(aux, false);
      dsst.addForceModel(force);
    }

    dsst.setInitialState(osculating, true);

    final Orbit meanOrbit = dsst.mapper.computeMeanOrbit(osculating);

    return new SpacecraftState(
        meanOrbit,
        osculating.getAttitude(),
        osculating.getMass(),
        osculating.getAdditionalStates());
  }
예제 #5
0
 /**
  * Launch the computation of short periodics coefficients.
  *
  * @param state input state
  * @throws OrekitException if the computation of a short periodic coefficient fails
  * @see {@link DSSTForceModel#computeShortPeriodicsCoefficients(AuxiliaryElements)}
  */
 private void computeShortPeriodicsCoefficients(final SpacecraftState state)
     throws OrekitException {
   final AuxiliaryElements aux = new AuxiliaryElements(state.getOrbit(), I);
   for (final DSSTForceModel forceModel : forceModels) {
     forceModel.initializeStep(aux);
     forceModel.computeShortPeriodicsCoefficients(state);
   }
 }
예제 #6
0
  /** {@inheritDoc} */
  @Override
  public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
    super.setAttitudeProvider(attitudeProvider);

    // Register the attitude provider for each force model
    for (final DSSTForceModel force : mapper.getForceModels()) {
      force.registerAttitudeProvider(attitudeProvider);
    }
  }
예제 #7
0
    /**
     * Simple constructor.
     *
     * @param integrator numerical integrator to use for propagation.
     */
    Main(final AbstractIntegrator integrator) {
      yDot = new double[7];

      for (final DSSTForceModel forceModel : mapper.getForceModels()) {
        final EventDetector[] modelDetectors = forceModel.getEventsDetectors();
        if (modelDetectors != null) {
          for (final EventDetector detector : modelDetectors) {
            setUpEventDetector(integrator, detector);
          }
        }
      }
    }
예제 #8
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());
    }
예제 #9
0
    /**
     * Replace the instance with a data transfer object for serialization.
     *
     * @return data transfer object that will be serialized
     * @exception NotSerializableException if one of the force models cannot be serialized
     */
    private Object writeReplace() throws NotSerializableException {

      // Check the force models can be serialized
      final DSSTForceModel[] serializableorceModels = new DSSTForceModel[forceModels.size()];
      for (int i = 0; i < serializableorceModels.length; ++i) {
        final DSSTForceModel forceModel = forceModels.get(i);
        if (forceModel instanceof Serializable) {
          serializableorceModels[i] = forceModel;
        } else {
          throw new NotSerializableException(forceModel.getClass().getName());
        }
      }
      return new DataTransferObject(
          getReferenceDate(),
          getMu(),
          getAttitudeProvider(),
          getFrame(),
          initialIsOsculating,
          serializableorceModels,
          satelliteRevolution);
    }
예제 #10
0
 /**
  * Reset the short periodics coefficient for each {@link DSSTForceModel}.
  *
  * @see DSSTForceModel#resetShortPeriodicsCoefficients()
  */
 private void resetShortPeriodicsCoefficients() {
   for (final DSSTForceModel forceModel : forceModels) {
     forceModel.resetShortPeriodicsCoefficients();
   }
 }
예제 #11
0
 /**
  * Add a force model to the global perturbation model.
  *
  * <p>If this method is not called at all, the integrated orbit will follow a keplerian evolution
  * only.
  *
  * @param force perturbing {@link DSSTForceModel force} to add
  * @see #removeForceModels()
  */
 public void addForceModel(final DSSTForceModel force) {
   mapper.addForceModel(force);
   force.registerAttitudeProvider(getAttitudeProvider());
 }