Merge pull request #2514 from JoePfeiffer/fix-2443
Reduce redundant acceleration data storage
This commit is contained in:
commit
3f8a118298
@ -70,22 +70,24 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
}
|
||||
|
||||
// Compute drag acceleration
|
||||
store.linearAcceleration = airSpeed.normalize().multiply(-store.dragForce / store.rocketMass.getMass());
|
||||
Coordinate linearAcceleration = airSpeed.normalize().multiply(-store.dragForce / store.rocketMass.getMass());
|
||||
|
||||
// Add effect of gravity
|
||||
store.gravity = modelGravity(status);
|
||||
store.linearAcceleration = store.linearAcceleration.sub(0, 0, store.gravity);
|
||||
linearAcceleration = linearAcceleration.sub(0, 0, store.gravity);
|
||||
|
||||
// Add coriolis acceleration
|
||||
store.coriolisAcceleration = status.getSimulationConditions().getGeodeticComputation().getCoriolisAcceleration(
|
||||
status.getRocketWorldPosition(), status.getRocketVelocity());
|
||||
store.linearAcceleration = store.linearAcceleration.add(store.coriolisAcceleration);
|
||||
linearAcceleration = linearAcceleration.add(store.coriolisAcceleration);
|
||||
|
||||
store.accelerationData = new AccelerationData(null, null, linearAcceleration, Coordinate.NUL, status.getRocketOrientationQuaternion());
|
||||
|
||||
// Select tentative time step
|
||||
store.timeStep = RECOVERY_TIME_STEP;
|
||||
|
||||
// adjust based on acceleration
|
||||
final double absAccel = store.linearAcceleration.length();
|
||||
final double absAccel = linearAcceleration.length();
|
||||
if (absAccel > MathUtil.EPSILON) {
|
||||
store.timeStep = Math.min(store.timeStep, 1.0/absAccel);
|
||||
}
|
||||
@ -105,7 +107,7 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
log.trace("timeStep is " + store.timeStep);
|
||||
|
||||
// Perform Euler integration
|
||||
EulerValues newVals = eulerIntegrate(status.getRocketPosition(), status.getRocketVelocity(), store.linearAcceleration, store.timeStep);
|
||||
EulerValues newVals = eulerIntegrate(status.getRocketPosition(), status.getRocketVelocity(), linearAcceleration, store.timeStep);
|
||||
|
||||
// Check to see if z or either of its first two derivatives have changed sign and recalculate
|
||||
// time step to point of change if so
|
||||
@ -115,7 +117,7 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
// Note that it's virtually impossible for apogee to occur on the same
|
||||
// step as either ground hit or descent rate inflection, and if we get a ground hit
|
||||
// any descent rate inflection won't matter
|
||||
final double a = store.linearAcceleration.z;
|
||||
final double a = linearAcceleration.z;
|
||||
final double v = status.getRocketVelocity().z;
|
||||
final double z = status.getRocketPosition().z;
|
||||
double t = store.timeStep;
|
||||
@ -136,11 +138,11 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
// dA/dT = dA/dV * dV/dT
|
||||
final double dFdV = CdA * store.atmosphericConditions.getDensity() * airSpeed.length();
|
||||
final Coordinate dAdV = airSpeed.normalize().multiply(dFdV / store.rocketMass.getMass());
|
||||
final Coordinate jerk = store.linearAcceleration.multiply(dAdV);
|
||||
final Coordinate newAcceleration = store.linearAcceleration.add(jerk.multiply(store.timeStep));
|
||||
final Coordinate jerk = linearAcceleration.multiply(dAdV);
|
||||
final Coordinate newAcceleration = linearAcceleration.add(jerk.multiply(store.timeStep));
|
||||
|
||||
// Only do this one if acceleration is appreciably different from 0
|
||||
if (newAcceleration.z * store.linearAcceleration.z < -MathUtil.EPSILON) {
|
||||
if (newAcceleration.z * linearAcceleration.z < -MathUtil.EPSILON) {
|
||||
// If acceleration oscillation is building up, the new timestep is the solution of
|
||||
// a + j*t = 0
|
||||
t = Math.abs(a / jerk.z);
|
||||
@ -159,7 +161,7 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
store.timeStep = maxTimeStep;
|
||||
}
|
||||
|
||||
newVals = eulerIntegrate(status.getRocketPosition(), status.getRocketVelocity(), store.linearAcceleration, store.timeStep);
|
||||
newVals = eulerIntegrate(status.getRocketPosition(), status.getRocketVelocity(), linearAcceleration, store.timeStep);
|
||||
|
||||
// If we just landed chop off rounding error
|
||||
if (Math.abs(newVals.pos.z) < MathUtil.EPSILON) {
|
||||
@ -171,7 +173,6 @@ public abstract class AbstractEulerStepper extends AbstractSimulationStepper {
|
||||
|
||||
status.setRocketPosition(newVals.pos);
|
||||
status.setRocketVelocity(newVals.vel);
|
||||
status.setRocketAcceleration(store.linearAcceleration);
|
||||
|
||||
// Update the world coordinate
|
||||
WorldCoordinate w = status.getSimulationConditions().getLaunchSite();
|
||||
|
@ -163,14 +163,12 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
*
|
||||
* @param status the current simulation status.
|
||||
* @param timestep the time step of the current iteration.
|
||||
* @param acceleration the current (approximate) acceleration
|
||||
* @param atmosphericConditions the current atmospheric conditions
|
||||
* @param store the simulation calculation DataStore (contains acceleration, atmosphere)
|
||||
* @param stepMotors whether to step the motors forward or work on a clone object
|
||||
* @return the average thrust during the time step.
|
||||
*/
|
||||
protected double calculateThrust(SimulationStatus status,
|
||||
double acceleration, AtmosphericConditions atmosphericConditions,
|
||||
boolean stepMotors) throws SimulationException {
|
||||
protected double calculateThrust(SimulationStatus status, DataStore store,
|
||||
boolean stepMotors) throws SimulationException {
|
||||
double thrust;
|
||||
|
||||
// Pre-listeners
|
||||
@ -240,16 +238,11 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
|
||||
public FlightConditions flightConditions;
|
||||
|
||||
public double longitudinalAcceleration = Double.NaN;
|
||||
|
||||
public RigidBody rocketMass;
|
||||
|
||||
public RigidBody motorMass;
|
||||
|
||||
public Coordinate coriolisAcceleration;
|
||||
|
||||
public Coordinate linearAcceleration;
|
||||
public Coordinate angularAcceleration;
|
||||
|
||||
public Coordinate launchRodDirection = null;
|
||||
|
||||
@ -264,9 +257,6 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
public double dragForce = Double.NaN;
|
||||
public double lateralPitchRate = Double.NaN;
|
||||
|
||||
public double rollAcceleration = Double.NaN;
|
||||
public double lateralPitchAcceleration = Double.NaN;
|
||||
|
||||
public Rotation2D thetaRotation;
|
||||
|
||||
void storeData(SimulationStatus status) {
|
||||
@ -286,12 +276,12 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
dataBranch.setValue(FlightDataType.TYPE_CORIOLIS_ACCELERATION, coriolisAcceleration.length());
|
||||
}
|
||||
|
||||
if (null != linearAcceleration) {
|
||||
if (null != accelerationData) {
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_XY,
|
||||
MathUtil.hypot(linearAcceleration.x, linearAcceleration.y));
|
||||
MathUtil.hypot(accelerationData.getLinearAccelerationWC().x, accelerationData.getLinearAccelerationWC().y));
|
||||
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_Z, linearAcceleration.z);
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, accelerationData.getLinearAccelerationWC().length());
|
||||
dataBranch.setValue(FlightDataType.TYPE_ACCELERATION_Z, accelerationData.getLinearAccelerationWC().z);
|
||||
}
|
||||
|
||||
if (null != rocketMass) {
|
||||
|
@ -57,7 +57,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
// private static final double MAX_ROLL_STEP_ANGLE = 8.32 * Math.PI/180;
|
||||
|
||||
private static final double MAX_ROLL_RATE_CHANGE = 2 * Math.PI / 180;
|
||||
private static final double MAX_PITCH_CHANGE = 4 * Math.PI / 180;
|
||||
private static final double MAX_PITCH_YAW_CHANGE = 4 * Math.PI / 180;
|
||||
|
||||
private Random random;
|
||||
DataStore store = new DataStore();
|
||||
@ -133,8 +133,10 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
dt[1] = maxTimeStep;
|
||||
dt[2] = status.getSimulationConditions().getMaximumAngleStep() / store.lateralPitchRate;
|
||||
dt[3] = Math.abs(MAX_ROLL_STEP_ANGLE / store.flightConditions.getRollRate());
|
||||
dt[4] = Math.abs(MAX_ROLL_RATE_CHANGE / store.rollAcceleration);
|
||||
dt[5] = Math.abs(MAX_PITCH_CHANGE / store.lateralPitchAcceleration);
|
||||
dt[4] = Math.abs(MAX_ROLL_RATE_CHANGE / store.accelerationData.getRotationalAccelerationRC().z);
|
||||
dt[5] = Math.abs(MAX_PITCH_YAW_CHANGE /
|
||||
MathUtil.max(Math.abs(store.accelerationData.getRotationalAccelerationRC().x),
|
||||
Math.abs(store.accelerationData.getRotationalAccelerationRC().y)));
|
||||
if (!status.isLaunchRodCleared()) {
|
||||
dt[0] /= 5.0;
|
||||
dt[6] = status.getSimulationConditions().getLaunchRodLength() / k1.v.length() / 10;
|
||||
@ -273,8 +275,8 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
// Call post-listeners
|
||||
store.accelerationData = SimulationListenerHelper.firePostAccelerationCalculation(status, store.accelerationData);
|
||||
|
||||
params.a = dataStore.linearAcceleration;
|
||||
params.ra = dataStore.angularAcceleration;
|
||||
params.a = dataStore.accelerationData.getLinearAccelerationWC();
|
||||
params.ra = dataStore.accelerationData.getRotationalAccelerationWC();
|
||||
params.v = status.getRocketVelocity();
|
||||
params.rv = status.getRocketRotationVelocity();
|
||||
|
||||
@ -298,7 +300,9 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
* @throws SimulationException
|
||||
*/
|
||||
private AccelerationData calculateAcceleration(SimulationStatus status, DataStore store) throws SimulationException {
|
||||
|
||||
Coordinate linearAcceleration;
|
||||
Coordinate angularAcceleration;
|
||||
|
||||
// Compute the forces affecting the rocket
|
||||
calculateForces(status, store);
|
||||
|
||||
@ -325,35 +329,33 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
double fN = store.forces.getCN() * dynP * refArea;
|
||||
double fSide = store.forces.getCside() * dynP * refArea;
|
||||
|
||||
store.thrustForce = calculateThrust(status, store.longitudinalAcceleration, store.flightConditions.getAtmosphericConditions(), false);
|
||||
store.thrustForce = calculateThrust(status, store, false);
|
||||
double forceZ = store.thrustForce - store.dragForce;
|
||||
|
||||
store.linearAcceleration = new Coordinate(-fN / store.rocketMass.getMass(),
|
||||
linearAcceleration = new Coordinate(-fN / store.rocketMass.getMass(),
|
||||
-fSide / store.rocketMass.getMass(),
|
||||
forceZ / store.rocketMass.getMass());
|
||||
|
||||
store.linearAcceleration = store.thetaRotation.rotateZ(store.linearAcceleration);
|
||||
linearAcceleration = store.thetaRotation.rotateZ(linearAcceleration);
|
||||
|
||||
// Convert into rocket world coordinates
|
||||
store.linearAcceleration = status.getRocketOrientationQuaternion().rotate(store.linearAcceleration);
|
||||
linearAcceleration = status.getRocketOrientationQuaternion().rotate(linearAcceleration);
|
||||
|
||||
// add effect of gravity
|
||||
store.gravity = modelGravity(status);
|
||||
store.linearAcceleration = store.linearAcceleration.sub(0, 0, store.gravity);
|
||||
linearAcceleration = linearAcceleration.sub(0, 0, store.gravity);
|
||||
|
||||
// add effect of Coriolis acceleration
|
||||
store.coriolisAcceleration = status.getSimulationConditions().getGeodeticComputation()
|
||||
.getCoriolisAcceleration(status.getRocketWorldPosition(), status.getRocketVelocity());
|
||||
store.linearAcceleration = store.linearAcceleration.add(store.coriolisAcceleration);
|
||||
linearAcceleration = linearAcceleration.add(store.coriolisAcceleration);
|
||||
|
||||
// If still on the launch rod, project acceleration onto launch rod direction and
|
||||
// set angular acceleration to zero.
|
||||
if (!status.isLaunchRodCleared()) {
|
||||
|
||||
store.linearAcceleration = store.launchRodDirection.multiply(store.linearAcceleration.dot(store.launchRodDirection));
|
||||
store.angularAcceleration = Coordinate.NUL;
|
||||
store.rollAcceleration = 0;
|
||||
store.lateralPitchAcceleration = 0;
|
||||
linearAcceleration = store.launchRodDirection.multiply(linearAcceleration.dot(store.launchRodDirection));
|
||||
angularAcceleration = Coordinate.NUL;
|
||||
|
||||
} else {
|
||||
|
||||
@ -366,24 +368,18 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
double momY = Cm * dynP * refArea * refLength;
|
||||
double momZ = store.forces.getCroll() * dynP * refArea * refLength;
|
||||
|
||||
// Compute acceleration in rocket coordinates
|
||||
store.angularAcceleration = new Coordinate(momX / store.rocketMass.getLongitudinalInertia(),
|
||||
// Compute angular acceleration in rocket coordinates
|
||||
angularAcceleration = new Coordinate(momX / store.rocketMass.getLongitudinalInertia(),
|
||||
momY / store.rocketMass.getLongitudinalInertia(),
|
||||
momZ / store.rocketMass.getRotationalInertia());
|
||||
|
||||
store.rollAcceleration = store.angularAcceleration.z;
|
||||
// TODO: LOW: This should be hypot, but does it matter?
|
||||
store.lateralPitchAcceleration = MathUtil.max(Math.abs(store.angularAcceleration.x),
|
||||
Math.abs(store.angularAcceleration.y));
|
||||
|
||||
store.angularAcceleration = store.thetaRotation.rotateZ(store.angularAcceleration);
|
||||
angularAcceleration = store.thetaRotation.rotateZ(angularAcceleration);
|
||||
|
||||
// Convert to world coordinates
|
||||
store.angularAcceleration = status.getRocketOrientationQuaternion().rotate(store.angularAcceleration);
|
||||
|
||||
angularAcceleration = status.getRocketOrientationQuaternion().rotate(angularAcceleration);
|
||||
}
|
||||
|
||||
return new AccelerationData(null, null, store.linearAcceleration, store.angularAcceleration, status.getRocketOrientationQuaternion());
|
||||
return new AccelerationData(null, null, linearAcceleration, angularAcceleration, status.getRocketOrientationQuaternion());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user