OrekitStepNormalizer.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF 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.propagation.sampling;

  18. import org.hipparchus.util.FastMath;
  19. import org.orekit.errors.OrekitException;
  20. import org.orekit.propagation.SpacecraftState;
  21. import org.orekit.time.AbsoluteDate;

  22. /**
  23.  * This class wraps an object implementing {@link OrekitFixedStepHandler}
  24.  * into a {@link OrekitStepHandler}.

  25.  * <p>It mirrors the <code>StepNormalizer</code> interface from <a
  26.  * href="https://hipparchus.org/">Hipparchus</a> but
  27.  * provides a space-dynamics interface to the methods.</p>
  28.  * @author Luc Maisonobe
  29.  */
  30. public class OrekitStepNormalizer implements OrekitStepHandler {

  31.     /** Fixed time step. */
  32.     private double h;

  33.     /** Underlying step handler. */
  34.     private OrekitFixedStepHandler handler;

  35.     /** Last State vector. */
  36.     private SpacecraftState lastState;

  37.     /** Integration direction indicator. */
  38.     private boolean forward;

  39.     /** Simple constructor.
  40.      * @param h fixed time step (sign is not used)
  41.      * @param handler fixed time step handler to wrap
  42.      */
  43.     public OrekitStepNormalizer(final double h, final OrekitFixedStepHandler handler) {
  44.         this.h         = FastMath.abs(h);
  45.         this.handler   = handler;
  46.         this.lastState = null;
  47.         this.forward   = true;
  48.     }

  49.     /** Determines whether this handler needs dense output.
  50.      * This handler needs dense output in order to provide data at
  51.      * regularly spaced steps regardless of the steps the propagator
  52.      * uses, so this method always returns true.
  53.      * @return always true
  54.      */
  55.     public boolean requiresDenseOutput() {
  56.         return true;
  57.     }

  58.     /** {@inheritDoc} */
  59.     public void init(final SpacecraftState s0, final AbsoluteDate t)
  60.         throws OrekitException {
  61.         lastState = null;
  62.         forward   = true;
  63.         handler.init(s0, t, h);
  64.     }

  65.     /**
  66.      * Handle the last accepted step.
  67.      * @param interpolator interpolator for the last accepted step. For
  68.      * efficiency purposes, the various propagators reuse the same
  69.      * object on each call, so if the instance wants to keep it across
  70.      * all calls (for example to provide at the end of the propagation a
  71.      * continuous model valid throughout the propagation range), it
  72.      * should build a local copy using the clone method and store this
  73.      * copy.
  74.      * @param isLast true if the step is the last one
  75.      * @throws OrekitException this exception is propagated to the
  76.      * caller if the underlying user function triggers one
  77.      */
  78.     public void handleStep(final OrekitStepInterpolator interpolator, final boolean isLast)
  79.         throws OrekitException {

  80.         if (lastState == null) {
  81.             // initialize lastState in the first step case
  82.             lastState = interpolator.getPreviousState();
  83.         }

  84.         // take the propagation direction into account
  85.         double step = h;
  86.         forward = interpolator.isForward();
  87.         if (!forward) {
  88.             step = -h;
  89.         }


  90.         // use the interpolator to push fixed steps events to the underlying handler
  91.         AbsoluteDate nextTime = lastState.getDate().shiftedBy(step);
  92.         boolean nextInStep = forward ^ (nextTime.compareTo(interpolator.getCurrentState().getDate()) > 0);
  93.         while (nextInStep) {

  94.             // output the stored previous step
  95.             handler.handleStep(lastState, false);

  96.             // store the next step
  97.             lastState = interpolator.getInterpolatedState(nextTime);

  98.             // prepare next iteration
  99.             nextTime = nextTime.shiftedBy(step);
  100.             nextInStep = forward ^ (nextTime.compareTo(interpolator.getCurrentState().getDate()) > 0);

  101.         }

  102.         if (isLast) {
  103.             // there will be no more steps,
  104.             // the stored one should be flagged as being the last
  105.             handler.handleStep(lastState, true);
  106.         }

  107.     }

  108. }