Merge pull request #1352 from JoePfeiffer/fix-1349

Get and save correct ground hit velocity
This commit is contained in:
Joe Pfeiffer 2022-05-14 08:43:35 -06:00 committed by GitHub
commit c315aca9e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 72 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,35 @@ 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;
// 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 +165,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);
}
}

View File

@ -331,13 +331,13 @@ public class MathUtil {
}
int length = domain.size();
if (length <= 1 || t < domain.get(0) || t > domain.get(length - 1)) {
if (length <= 1 || t < domain.get(0) || t > domain.get(length - 1) + EPSILON) {
return Double.NaN;
}
// Look for the index of the right end point.
int right = 1;
while (t > domain.get(right)) {
while (t > domain.get(right) + EPSILON) {
right++;
}
int left = right - 1;

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