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:
parent
af2a6ea3c9
commit
fbd80f480d
@ -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()));
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user