From 4954099b403911cb0feae0719b9d7fd8b3120eb9 Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Fri, 21 Apr 2023 16:30:49 -0600 Subject: [PATCH] incorporate adaptive time step in tumble stepper --- .../simulation/BasicLandingStepper.java | 9 ++++----- .../simulation/BasicTumbleStepper.java | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java b/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java index bdd92d8dd..909871732 100644 --- a/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java +++ b/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java @@ -1,5 +1,8 @@ package net.sf.openrocket.simulation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.sf.openrocket.models.atmosphere.AtmosphericConditions; import net.sf.openrocket.rocketcomponent.InstanceMap; import net.sf.openrocket.rocketcomponent.RecoveryDevice; @@ -9,9 +12,6 @@ import net.sf.openrocket.util.GeodeticComputationStrategy; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.WorldCoordinate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - public class BasicLandingStepper extends AbstractSimulationStepper { private static final Logger log = LoggerFactory.getLogger(BasicLandingStepper.class); @@ -77,8 +77,6 @@ public class BasicLandingStepper extends AbstractSimulationStepper { Coordinate coriolisAcceleration = status.getSimulationConditions().getGeodeticComputation().getCoriolisAcceleration( status.getRocketWorldPosition(), status.getRocketVelocity()); linearAcceleration = linearAcceleration.add(coriolisAcceleration); - - // Select tentative time step double timeStep = RECOVERY_TIME_STEP; @@ -88,6 +86,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper { if (jerk > MathUtil.EPSILON) { timeStep = Math.min(timeStep, 1.0/jerk); } + // but don't let it get *too* small timeStep = Math.max(timeStep, MIN_TIME_STEP); log.trace("timeStep is " + timeStep); diff --git a/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java b/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java index c22c327dc..a378b1529 100644 --- a/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java +++ b/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.InstanceContext; @@ -20,6 +23,7 @@ import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.WorldCoordinate; public class BasicTumbleStepper extends AbstractSimulationStepper { + private static final Logger log = LoggerFactory.getLogger(BasicTumbleStepper.class); private static final double RECOVERY_TIME_STEP = 0.5; @@ -124,8 +128,18 @@ public class BasicTumbleStepper extends AbstractSimulationStepper { - // Select time step + // Select tentative time step double timeStep = MathUtil.min(0.5 / linearAcceleration.length(), RECOVERY_TIME_STEP); + + // adjust based on change in acceleration (ie jerk) + final double jerk = Math.abs(linearAcceleration.sub(status.getRocketAcceleration()).multiply(1.0/status.getPreviousTimeStep()).length()); + if (jerk > MathUtil.EPSILON) { + timeStep = Math.min(timeStep, 1.0/jerk); + } + + // but don't let it get *too* small + timeStep = Math.max(timeStep, MIN_TIME_STEP); + log.trace("timeStep is " + timeStep); // Perform Euler integration Coordinate newPosition = status.getRocketPosition().add(status.getRocketVelocity().multiply(timeStep)).