Merge pull request #1352 from JoePfeiffer/fix-1349
Get and save correct ground hit velocity
This commit is contained in:
		
						commit
						c315aca9e9
					
				| @ -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,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)); | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
|  | ||||
| @ -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);		 | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user