Modify GroundStepper to not add datapoint to simulation status

Modify BasicLandingStepper to recalculate timestep on last step to find
actual landing data
Modify BasicEventSimulationEngine to watch for altitude less than MathUtil.EPSILON rather than 0 (since BasicLandingStepper now finds altitude exactly equal to 0)
This commit is contained in:
JoePfeiffer 2022-05-13 10:32:00 -06:00
parent af2a6ea3c9
commit fbd80f480d
4 changed files with 33 additions and 70 deletions

View File

@ -173,7 +173,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
} else {
// Check ground hit after liftoff
if ((currentStatus.getRocketPosition().z < 0) && !currentStatus.isLanded()) {
if ((currentStatus.getRocketPosition().z < MathUtil.EPSILON) && !currentStatus.isLanded()) {
addEvent(new FlightEvent(FlightEvent.Type.GROUND_HIT, currentStatus.getSimulationTime()));
// addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));

View File

@ -8,7 +8,11 @@ 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);
private static final double RECOVERY_TIME_STEP = 0.5;
@ -65,13 +69,36 @@ public class BasicLandingStepper extends AbstractSimulationStepper {
// Select time step
// Select tentative time step
double timeStep = MathUtil.min(0.5 / linearAcceleration.length(), RECOVERY_TIME_STEP);
// Perform Euler integration
status.setRocketPosition(status.getRocketPosition().add(status.getRocketVelocity().multiply(timeStep)).
add(linearAcceleration.multiply(MathUtil.pow2(timeStep) / 2)));
Coordinate newPosition = status.getRocketPosition().add(status.getRocketVelocity().multiply(timeStep)).
add(linearAcceleration.multiply(MathUtil.pow2(timeStep) / 2));
// If I've hit the ground, recalculate time step and position
if (newPosition.z < 0) {
final double a = linearAcceleration.z;
final double v = status.getRocketVelocity().z;
final double z0 = status.getRocketPosition().z;
final double z = linearAcceleration.x;
// The new timestep is the solution of
// 1/2 at^2 + vt + z0 = 0
timeStep = (-v - Math.sqrt(v*v - 2*a*z0))/a;
newPosition = status.getRocketPosition().add(status.getRocketVelocity().multiply(timeStep)).
add(linearAcceleration.multiply(MathUtil.pow2(timeStep) / 2));
// avoid rounding error in new altitude
newPosition = newPosition.setZ(0);
}
status.setRocketPosition(newPosition);
status.setRocketVelocity(status.getRocketVelocity().add(linearAcceleration.multiply(timeStep)));
airSpeed = status.getRocketVelocity().add(windSpeed);
status.setSimulationTime(status.getSimulationTime() + timeStep);
@ -139,6 +166,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper {
data.setValue(FlightDataType.TYPE_TIME_STEP, timeStep);
data.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
(System.nanoTime() - status.getSimulationStartWallTime()) / 1000000000.0);
log.debug("time " + data.getLast(FlightDataType.TYPE_TIME) + ", altitude " + data.getLast(FlightDataType.TYPE_ALTITUDE) + ", velocity " + data.getLast(FlightDataType.TYPE_VELOCITY_Z));
}
}

View File

@ -20,70 +20,5 @@ public class GroundStepper extends AbstractSimulationStepper {
@Override
public void step(SimulationStatus status, double timeStep) throws SimulationException {
log.trace("step: position=" + status.getRocketPosition() + ", velocity=" + status.getRocketVelocity());
status.setRocketVelocity(Coordinate.ZERO);
status.setRocketRotationVelocity(Coordinate.ZERO);
status.setRocketPosition(status.getRocketPosition().setZ(0));
// Store data
FlightDataBranch data = status.getFlightData();
boolean extra = status.getSimulationConditions().isCalculateExtras();
data.addPoint();
data.setValue(FlightDataType.TYPE_TIME, status.getSimulationTime());
data.setValue(FlightDataType.TYPE_ALTITUDE, status.getRocketPosition().z);
data.setValue(FlightDataType.TYPE_POSITION_X, status.getRocketPosition().x);
data.setValue(FlightDataType.TYPE_POSITION_Y, status.getRocketPosition().y);
if (extra) {
data.setValue(FlightDataType.TYPE_POSITION_XY,
MathUtil.hypot(status.getRocketPosition().x, status.getRocketPosition().y));
data.setValue(FlightDataType.TYPE_POSITION_DIRECTION,
Math.atan2(status.getRocketPosition().y, status.getRocketPosition().x));
data.setValue(FlightDataType.TYPE_VELOCITY_XY,
MathUtil.hypot(status.getRocketVelocity().x, status.getRocketVelocity().y));
data.setValue(FlightDataType.TYPE_ACCELERATION_XY, 0.0);
data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, 0.0);
data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Double.POSITIVE_INFINITY);
}
data.setValue(FlightDataType.TYPE_LATITUDE, status.getRocketWorldPosition().getLatitudeRad());
data.setValue(FlightDataType.TYPE_LONGITUDE, status.getRocketWorldPosition().getLongitudeRad());
data.setValue(FlightDataType.TYPE_GRAVITY, modelGravity(status));
data.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, 0.0);
data.setValue(FlightDataType.TYPE_VELOCITY_Z, status.getRocketVelocity().z);
data.setValue(FlightDataType.TYPE_ACCELERATION_Z, 0.0);
data.setValue(FlightDataType.TYPE_VELOCITY_TOTAL, 0.0);
data.setValue(FlightDataType.TYPE_MACH_NUMBER, 0.0);
// Calculate mass data
double rocketMass = calculateStructureMass(status).getMass();
double motorMass = calculateMotorMass(status).getMass();
double mass = rocketMass + motorMass;
data.setValue(FlightDataType.TYPE_MASS, mass);
data.setValue(FlightDataType.TYPE_MOTOR_MASS, motorMass);
data.setValue(FlightDataType.TYPE_THRUST_FORCE, 0.0);
data.setValue(FlightDataType.TYPE_DRAG_FORCE, 0.0);
data.setValue(FlightDataType.TYPE_WIND_VELOCITY, modelWindVelocity(status).length());
AtmosphericConditions atmosphere = modelAtmosphericConditions(status);
data.setValue(FlightDataType.TYPE_AIR_TEMPERATURE, atmosphere.getTemperature());
data.setValue(FlightDataType.TYPE_AIR_PRESSURE, atmosphere.getPressure());
data.setValue(FlightDataType.TYPE_SPEED_OF_SOUND, atmosphere.getMachSpeed());
data.setValue(FlightDataType.TYPE_TIME_STEP, timeStep);
data.setValue(FlightDataType.TYPE_COMPUTATION_TIME,
(System.nanoTime() - status.getSimulationStartWallTime()) / 1000000000.0);
status.setSimulationTime(status.getSimulationTime() + timeStep);
}
}

@ -1 +1 @@
Subproject commit c9bd1a6f539aab4bb724ecbdb54e65100a33e701
Subproject commit 8304c0fd3dc80d65c40af4da83268ec1b32931d6