[Bugfix] Fixed Simulations bugs - Sim should be operational now.
Motors are now cloned for each new simulation (including background and foreground runs) -> motors are now cloned within the configuration clone method. -> MotorInstance.reset() resets instance to launch state Removed spurious negative time-step check in ThrustCurveMotorInstance:154 -> was triggered during normal simulation operations. Added MotorInstance time updates to AbstractSimulationStepper: -> moved from MotorInstanceConfiguration.step(...) Misc variable name changes to be more descriptive
This commit is contained in:
parent
65ddd1b2a2
commit
1988ee4266
@ -1,5 +1,6 @@
|
||||
package net.sf.openrocket.document;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
@ -281,10 +282,9 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
}
|
||||
|
||||
FlightConfiguration config = rocket.getFlightConfiguration(options.getId());
|
||||
List<MotorInstance> motorList = config.getActiveMotors();
|
||||
|
||||
|
||||
//Make sure this simulation has motors.
|
||||
if (0 == motorList.size()){
|
||||
if ( ! config.hasMotors() ){
|
||||
status = Status.CANT_RUN;
|
||||
}
|
||||
|
||||
@ -337,14 +337,11 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
|
||||
// Set simulated info after simulation, will not be set in case of exception
|
||||
simulatedConditions = options.clone();
|
||||
final FlightConfiguration configuration = this.rocket.getFlightConfiguration( options.getId());
|
||||
|
||||
simulatedConfigurationDescription = descriptor.format(configuration.getRocket(), configuration.getFlightConfigurationID());
|
||||
simulatedConfigurationDescription = descriptor.format( this.rocket, options.getId());
|
||||
simulatedRocketID = rocket.getFunctionalModID();
|
||||
|
||||
status = Status.UPTODATE;
|
||||
fireChangeEvent();
|
||||
configuration.release();
|
||||
} finally {
|
||||
mutex.unlock("simulate");
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ public abstract class BaseHandler<C extends RocketComponent> extends AbstractEle
|
||||
*
|
||||
* @return the Method instance, or null
|
||||
*/
|
||||
private static Method getMethod(RocketComponent component, String name, Class[] args) {
|
||||
private static Method getMethod(RocketComponent component, String name, Class<?>[] args) {
|
||||
Method method = null;
|
||||
try {
|
||||
method = component.getClass().getMethod(name, args);
|
||||
|
@ -155,7 +155,7 @@ public abstract class MotorInstance implements FlightConfigurableParameter<Motor
|
||||
* @param acceleration the average acceleration during the step.
|
||||
* @param cond the average atmospheric conditions during the step.
|
||||
*/
|
||||
public abstract void step(double time, double acceleration, AtmosphericConditions cond);
|
||||
public abstract void step(double newTime, double acceleration, AtmosphericConditions cond);
|
||||
|
||||
|
||||
/**
|
||||
@ -254,6 +254,8 @@ public abstract class MotorInstance implements FlightConfigurableParameter<Motor
|
||||
((StateChangeListener) l).stateChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
public String toDebug(){ return toString();}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
@ -263,5 +265,9 @@ public abstract class MotorInstance implements FlightConfigurableParameter<Motor
|
||||
public int getModID() {
|
||||
return modID;
|
||||
}
|
||||
|
||||
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,17 +41,12 @@ public class ThrustCurveMotorInstance extends MotorInstance {
|
||||
|
||||
public ThrustCurveMotorInstance(final ThrustCurveMotor source) {
|
||||
//log.debug( Creating motor instance of " + ThrustCurveMotor.this);
|
||||
timeIndex = 0;
|
||||
prevTime = 0;
|
||||
instThrust = 0;
|
||||
stepThrust = 0;
|
||||
instCG = source.getLaunchCG();
|
||||
stepCG = source.getLaunchCG();
|
||||
this.motor = source;
|
||||
this.reset();
|
||||
|
||||
unitRotationalInertia = Inertia.filledCylinderRotational(source.getDiameter() / 2);
|
||||
unitLongitudinalInertia = Inertia.filledCylinderLongitudinal(source.getDiameter() / 2, source.getLength());
|
||||
|
||||
this.motor = source;
|
||||
this.id = MotorInstanceId.ERROR_ID;
|
||||
}
|
||||
|
||||
@ -153,12 +148,6 @@ public class ThrustCurveMotorInstance extends MotorInstance {
|
||||
|
||||
@Override
|
||||
public void step(double nextTime, double acceleration, AtmosphericConditions cond) {
|
||||
|
||||
if (!(nextTime >= prevTime)) {
|
||||
// Also catches NaN
|
||||
throw new IllegalArgumentException("Stepping backwards in time, current=" +
|
||||
prevTime + " new=" + nextTime);
|
||||
}
|
||||
if (MathUtil.equals(prevTime, nextTime)) {
|
||||
return;
|
||||
}
|
||||
@ -241,11 +230,37 @@ public class ThrustCurveMotorInstance extends MotorInstance {
|
||||
clone.ignitionDelay = this.ignitionDelay;
|
||||
clone.ejectionDelay = this.ejectionDelay;
|
||||
clone.position = this.position;
|
||||
this.ignitionTime = Double.POSITIVE_INFINITY;
|
||||
clone.ignitionTime = Double.POSITIVE_INFINITY;
|
||||
//clone.ignitionTime = this.ignitionTime;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(){
|
||||
timeIndex = 0;
|
||||
prevTime = 0;
|
||||
instThrust = 0;
|
||||
stepThrust = 0;
|
||||
instCG = motor.getLaunchCG();
|
||||
stepCG = instCG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDebug(){
|
||||
String prefix = " ";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final RocketComponent mountComp = (RocketComponent)this.mount;
|
||||
|
||||
sb.append(String.format("%sMotor= %s(%s)(in %s)\n", prefix, this.motor.getDesignation(), this.id.toShortKey(), mountComp.getName()));
|
||||
sb.append(String.format("%s Ignite: %s at %+f\n",prefix, this.ignitionEvent.name, this.ignitionDelay));
|
||||
//sb.append(String.format("%s Eject at: %+f\n",prefix, this.ejectionDelay));
|
||||
sb.append(String.format("%s L:%f W:%f @:%f mm\n",prefix, motor.getLength(), motor.getDiameter(), this.position.multiply(1000).x ));
|
||||
sb.append(String.format("%s currentTimem: %f\n", prefix, this.prevTime));
|
||||
sb.append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return this.id.toString();
|
||||
|
@ -5,7 +5,6 @@ import java.util.Collection;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
@ -14,7 +13,6 @@ import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
||||
import net.sf.openrocket.motor.MotorInstance;
|
||||
import net.sf.openrocket.motor.MotorInstanceId;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
@ -68,8 +66,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
|
||||
private int modID = 0;
|
||||
|
||||
private boolean debug = false;
|
||||
|
||||
/**
|
||||
* Create a new configuration with the specified <code>Rocket</code>.
|
||||
*
|
||||
@ -91,10 +87,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
rocket.addComponentChangeListener(this);
|
||||
}
|
||||
|
||||
public void enableDebugging(){
|
||||
this.debug=true;
|
||||
}
|
||||
|
||||
public Rocket getRocket() {
|
||||
return rocket;
|
||||
}
|
||||
@ -305,9 +297,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
private void updateStages() {
|
||||
if( debug){
|
||||
System.err.println("updating config stages");
|
||||
}
|
||||
if (this.rocket.getStageCount() == this.stages.size()) {
|
||||
// no changes needed
|
||||
return;
|
||||
@ -364,7 +353,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
// DEBUG / DEVEL
|
||||
public String toMotorDetail(){
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.append(String.format("\nDumping %2d Motors for configuration %s: \n", this.motors.size(), this.fcid.toShortKey()));
|
||||
buff.append(String.format("\nDumping %2d Motors for configuration %s: \n", this.motors.size(), this));
|
||||
for( MotorInstance curMotor : this.motors.values() ){
|
||||
if( curMotor.isEmpty() ){
|
||||
buff.append( String.format( " ..[%8s] <empty> \n", curMotor.getID().toShortKey()));
|
||||
@ -490,21 +479,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
return (0 < motors.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Step all of the motor instances to the specified time minus their ignition time.
|
||||
* @param time the "global" time
|
||||
*/
|
||||
public void step(double time, double acceleration, AtmosphericConditions cond) {
|
||||
for (MotorInstance inst : motors.values()) {
|
||||
double t = time - inst.getIgnitionTime();
|
||||
if (t >= 0) {
|
||||
inst.step(t, acceleration, cond);
|
||||
}
|
||||
}
|
||||
modID++;
|
||||
}
|
||||
|
||||
public List<MotorInstance> getActiveMotors() {
|
||||
public Collection<MotorInstance> getActiveMotors() {
|
||||
List<MotorInstance> activeList = new ArrayList<MotorInstance>();
|
||||
for( MotorInstance inst : this.motors.values() ){
|
||||
if( inst.isActive() ){
|
||||
@ -516,47 +491,35 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
public void updateMotors() {
|
||||
if( debug){
|
||||
System.err.println("updating config motors");
|
||||
}
|
||||
this.motors.clear();
|
||||
|
||||
for ( RocketComponent comp : getActiveComponents() ){
|
||||
if (( comp instanceof MotorMount )&&( ((MotorMount)comp).isMotorMount())){
|
||||
MotorMount mount = (MotorMount)comp;
|
||||
MotorInstance inst = mount.getMotorInstance( fcid);
|
||||
if( inst.isEmpty()){
|
||||
for ( RocketComponent compMount : getActiveComponents() ){
|
||||
if (( compMount instanceof MotorMount )&&( ((MotorMount)compMount).isMotorMount())){
|
||||
MotorMount mount = (MotorMount)compMount;
|
||||
MotorInstance sourceInstance = mount.getMotorInstance( fcid);
|
||||
if( sourceInstance.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// this merely accounts for instancing of *this* component:
|
||||
// int instancCount = comp.getInstanceCount();
|
||||
|
||||
// this includes *all* the instancing between here and the rocket root.
|
||||
Coordinate[] instanceLocations= comp.getLocations();
|
||||
Coordinate[] instanceLocations= compMount.getLocations();
|
||||
|
||||
if( debug){
|
||||
System.err.println(String.format(",,,,,,,, %s (%s)",
|
||||
inst.getMotor().getDigest(), inst.getID() ));
|
||||
}
|
||||
sourceInstance.reset();
|
||||
int instanceNumber = 1;
|
||||
final int instanceCount = instanceLocations.length;
|
||||
//final int instanceCount = instanceLocations.length;
|
||||
for ( Coordinate curMountLocation : instanceLocations ){
|
||||
MotorInstance curInstance = inst.clone();
|
||||
curInstance.setID( new MotorInstanceId( comp.getName(), instanceNumber) );
|
||||
|
||||
// motor location w/in mount: parent.refpoint -> motor.refpoint
|
||||
Coordinate curMotorOffset = curInstance.getOffset();
|
||||
curInstance.setPosition( curMountLocation.add(curMotorOffset) );
|
||||
this.motors.put( curInstance.getID(), curInstance);
|
||||
|
||||
// vvvv DEVEL vvvv
|
||||
if(debug){
|
||||
System.err.println(String.format(",,,,,,,, [%2d/%2d]: %s. (%s)",
|
||||
instanceNumber, instanceCount, curInstance.getMotor().getDigest(), curInstance));
|
||||
}
|
||||
// ^^^^ DEVEL ^^^^
|
||||
instanceNumber ++;
|
||||
MotorInstance cloneInstance = sourceInstance.clone();
|
||||
cloneInstance.setID( new MotorInstanceId( compMount.getName(), instanceNumber) );
|
||||
|
||||
// motor location w/in mount: parent.refpoint -> motor.refpoint
|
||||
Coordinate curMotorOffset = cloneInstance.getOffset();
|
||||
cloneInstance.setPosition( curMountLocation.add(curMotorOffset) );
|
||||
this.motors.put( cloneInstance.getID(), cloneInstance);
|
||||
|
||||
instanceNumber ++;
|
||||
}
|
||||
|
||||
}
|
||||
@ -629,7 +592,9 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
clone.setName(this.fcid.toShortKey()+" - clone");
|
||||
clone.listenerList = new ArrayList<EventListener>();
|
||||
clone.stages.putAll( (Map<Integer, StageFlags>) this.stages);
|
||||
clone.motors.putAll( (Map<MotorInstanceId, MotorInstance>) this.motors);
|
||||
for( MotorInstance mi : this.motors.values()){
|
||||
clone.motors.put( mi.getID(), mi.clone());
|
||||
}
|
||||
clone.cachedBounds = this.cachedBounds.clone();
|
||||
clone.modID = this.modID;
|
||||
clone.boundsModID = -1;
|
||||
@ -662,5 +627,5 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
this.isNamed = true;
|
||||
this.configurationName = newName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public enum IgnitionEvent {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
public final String name;
|
||||
private final String key;
|
||||
private final String translationKey;
|
||||
protected String description=null;
|
||||
|
||||
//public static final IgnitionEvent[] events = {AUTOMATIC, LAUNCH, EJECTION_CHARGE, BURNOUT, NEVER};
|
||||
@ -67,7 +67,7 @@ public enum IgnitionEvent {
|
||||
|
||||
private IgnitionEvent(final String _name, final String _key) {
|
||||
this.name = _name;
|
||||
this.key = _key;
|
||||
this.translationKey = _key;
|
||||
}
|
||||
|
||||
public boolean equals( final String content){
|
||||
@ -82,7 +82,7 @@ public enum IgnitionEvent {
|
||||
@Override
|
||||
public String toString() {
|
||||
if( null == this.description ){
|
||||
this.description = trans.get(this.key);
|
||||
this.description = trans.get(this.translationKey);
|
||||
}
|
||||
return this.description;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.sf.openrocket.simulation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
@ -170,22 +170,17 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
return thrust;
|
||||
}
|
||||
|
||||
FlightConfiguration configuration = status.getConfiguration();
|
||||
|
||||
//MotorInstanceConfiguration mic = status.getMotorConfiguration();
|
||||
// Iterate over the motors and calculate combined thrust
|
||||
//if (!stepMotors) {
|
||||
// mic = mic.clone();
|
||||
//}
|
||||
//mic.step(status.getSimulationTime() + timestep, acceleration, atmosphericConditions);
|
||||
|
||||
// now this is a valid reason for the MotorConfiguration :P
|
||||
configuration.step(status.getSimulationTime() + timestep, acceleration, atmosphericConditions);
|
||||
thrust = 0;
|
||||
|
||||
//?? needs to instance the motors...
|
||||
List<MotorInstance> activeMotors = configuration.getActiveMotors();
|
||||
for (MotorInstance currentMotorInstance : activeMotors) {
|
||||
final double currentTime = status.getSimulationTime() + timestep;
|
||||
Collection<MotorInstance> activeMotorList = status.getConfiguration().getActiveMotors();
|
||||
for (MotorInstance currentMotorInstance : activeMotorList ) {
|
||||
// old: transplanted from MotorInstanceConfiguration
|
||||
double instanceTime = currentTime - currentMotorInstance.getIgnitionTime();
|
||||
if (instanceTime >= 0) {
|
||||
currentMotorInstance.step(instanceTime, acceleration, atmosphericConditions);
|
||||
}
|
||||
|
||||
// old: from here
|
||||
thrust += currentMotorInstance.getThrust();
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.sf.openrocket.simulation;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -56,15 +56,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
private FlightConfigurationID fcid;
|
||||
|
||||
// old: protected Stack<SimulationStatus> stages = new Stack<SimulationStatus>();
|
||||
// this variable was class member stack, but parallel staging breaks metaphor:
|
||||
// parallel stages may ignite before OR after their 'inner' stages
|
||||
|
||||
|
||||
// this is just a list of simulation branches to
|
||||
Deque<SimulationStatus> toSimulate = new ArrayDeque<SimulationStatus>();
|
||||
|
||||
|
||||
@Override
|
||||
public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
|
||||
|
||||
@ -72,21 +66,17 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
FlightData flightData = new FlightData();
|
||||
|
||||
// Set up rocket configuration
|
||||
this.fcid = simulationConditions.getConfigurationID();
|
||||
FlightConfiguration configuration = simulationConditions.getRocket().getFlightConfiguration( this.fcid);
|
||||
|
||||
List<MotorInstance> activeMotors = configuration.getActiveMotors();
|
||||
if ( activeMotors.isEmpty() ) {
|
||||
final String errorMessage = trans.get("BasicEventSimulationEngine.error.noMotorsDefined");
|
||||
log.info(errorMessage);
|
||||
throw new MotorIgnitionException(errorMessage);
|
||||
this.fcid = simulationConditions.getFlightConfigurationID();
|
||||
FlightConfiguration simulationConfig = simulationConditions.getRocket().getFlightConfiguration( this.fcid).clone();
|
||||
if ( ! simulationConfig.hasMotors() ) {
|
||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
|
||||
}
|
||||
|
||||
currentStatus = new SimulationStatus(configuration, simulationConditions);
|
||||
currentStatus = new SimulationStatus(simulationConfig, simulationConditions);
|
||||
currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
|
||||
{
|
||||
// main simulation branch
|
||||
final String branchName = configuration.getRocket().getTopmostStage().getName();
|
||||
final String branchName = simulationConfig.getRocket().getTopmostStage().getName();
|
||||
currentStatus.setFlightData(new FlightDataBranch( branchName, FlightDataType.TYPE_TIME));
|
||||
}
|
||||
toSimulate.add(currentStatus);
|
||||
@ -103,19 +93,18 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
flightData.addBranch(dataBranch);
|
||||
flightData.getWarningSet().addAll(currentStatus.getWarnings());
|
||||
|
||||
log.info(String.format("<<Finished simulating branch: %s at:%s",
|
||||
currentStatus.getFlightData().getBranchName(),
|
||||
currentStatus.getFlightData().getLast(FlightDataType.TYPE_TIME)));
|
||||
log.info(String.format("<<Finished simulating branch: %s curTime:%s finTime:%s",
|
||||
dataBranch.getBranchName(),
|
||||
currentStatus.getSimulationTime(),
|
||||
dataBranch.getLast(FlightDataType.TYPE_TIME)));
|
||||
}while( ! toSimulate.isEmpty());
|
||||
|
||||
SimulationListenerHelper.fireEndSimulation(currentStatus, null);
|
||||
|
||||
configuration.release();
|
||||
|
||||
if (!flightData.getWarningSet().isEmpty()) {
|
||||
log.info("Warnings at the end of simulation: " + flightData.getWarningSet());
|
||||
}
|
||||
|
||||
simulationConfig.release();
|
||||
return flightData;
|
||||
}
|
||||
|
||||
@ -130,12 +119,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
Coordinate originVelocity = currentStatus.getRocketVelocity();
|
||||
|
||||
try {
|
||||
log.info(String.format(" >> Starting simulate loop."));
|
||||
|
||||
// Start the simulation
|
||||
while (handleEvents()) {
|
||||
log.info(String.format(" >> Events Handled."));
|
||||
|
||||
// Take the step
|
||||
double oldAlt = currentStatus.getRocketPosition().z;
|
||||
|
||||
@ -286,7 +272,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
log.trace("BasicEventSimulationEngine: Handling event " + event);
|
||||
}
|
||||
|
||||
log.trace(String.format(" >> about to ignite motors events"));
|
||||
if (event.getType() == FlightEvent.Type.IGNITION) {
|
||||
MotorMount mount = (MotorMount) event.getSource();
|
||||
MotorInstanceId motorId = (MotorInstanceId) event.getData();
|
||||
@ -295,7 +280,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
log.trace(String.format(" >> about to fire motors (?) events"));
|
||||
if (event.getType() == FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT) {
|
||||
RecoveryDevice device = (RecoveryDevice) event.getSource();
|
||||
if (!SimulationListenerHelper.fireRecoveryDeviceDeployment(currentStatus, device)) {
|
||||
@ -303,8 +287,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
}
|
||||
}
|
||||
|
||||
log.trace(String.format(" >> about to check for motors ignite events"));
|
||||
|
||||
// Check for motor ignition events, add ignition events to queue
|
||||
for (MotorInstance motor : currentStatus.getFlightConfiguration().getActiveMotors() ){
|
||||
MotorInstanceId mid = motor.getID();
|
||||
@ -322,7 +304,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
|
||||
// Check for stage separation event
|
||||
|
||||
for (AxialStage stage : currentStatus.getConfiguration().getActiveStages()) {
|
||||
int stageNo = stage.getStageNumber();
|
||||
if (stageNo == 0)
|
||||
@ -348,8 +329,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
}
|
||||
}
|
||||
|
||||
log.trace(String.format(" >> about to handle events"));
|
||||
|
||||
// Handle event
|
||||
switch (event.getType()) {
|
||||
|
||||
@ -445,7 +424,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
// TODO: HIGH: Check stage activeness for other events as well?
|
||||
|
||||
// Check whether any motor in the active stages is active anymore
|
||||
List<MotorInstance> activeMotors = currentStatus.getConfiguration().getActiveMotors();
|
||||
Collection<MotorInstance> activeMotors = currentStatus.getConfiguration().getActiveMotors();
|
||||
for (MotorInstance curMotor : activeMotors) {
|
||||
RocketComponent comp = ((RocketComponent) curMotor.getMount());
|
||||
int stageNumber = comp.getStageNumber();
|
||||
@ -471,6 +450,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
// to determine the optimum altitude.
|
||||
if (currentStatus.getSimulationConditions().isCalculateExtras() && !currentStatus.isApogeeReached()) {
|
||||
FlightData coastStatus = computeCoastTime();
|
||||
|
||||
currentStatus.getFlightData().setOptimumAltitude(coastStatus.getMaxAltitude());
|
||||
currentStatus.getFlightData().setTimeToOptimumAltitude(coastStatus.getTimeToApogee());
|
||||
}
|
||||
@ -580,7 +560,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
SimulationConditions conds = currentStatus.getSimulationConditions().clone();
|
||||
conds.getSimulationListenerList().add(OptimumCoastListener.INSTANCE);
|
||||
BasicEventSimulationEngine e = new BasicEventSimulationEngine();
|
||||
|
||||
// log.error(" cloned simConditions: "+conds.toString()
|
||||
// +" ... "+conds.getRocket().getName()
|
||||
// +" ... "+conds.getFlightConfigurationID().toShortKey());
|
||||
// FlightConfigurationID dbid = conds.getFlightConfigurationID();
|
||||
// FlightConfiguration cloneConfig = conds.getRocket().getFlightConfiguration( dbid );
|
||||
// System.err.println(" configId: "+dbid.toShortKey());
|
||||
// System.err.println(" motors detail: "+cloneConfig.toMotorDetail());
|
||||
|
||||
FlightData d = e.simulate(conds);
|
||||
return d;
|
||||
} catch (Exception e) {
|
||||
|
@ -265,6 +265,10 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
w = status.getSimulationConditions().getGeodeticComputation().addCoordinate(w, status.getRocketPosition());
|
||||
status.setRocketWorldPosition(w);
|
||||
|
||||
if (!(0 <= store.timestep)) {
|
||||
// Also catches NaN
|
||||
throw new IllegalArgumentException("Stepping backwards in time, timestep=" +store.timestep);
|
||||
}
|
||||
status.setSimulationTime(status.getSimulationTime() + store.timestep);
|
||||
|
||||
status.setPreviousTimeStep(store.timestep);
|
||||
|
@ -28,7 +28,7 @@ import net.sf.openrocket.util.WorldCoordinate;
|
||||
public class SimulationConditions implements Monitorable, Cloneable {
|
||||
|
||||
private Rocket rocket;
|
||||
private FlightConfigurationID configID= null;
|
||||
private FlightConfigurationID configId= null;
|
||||
|
||||
private Simulation simulation; // The parent simulation
|
||||
|
||||
@ -116,15 +116,15 @@ public class SimulationConditions implements Monitorable, Cloneable {
|
||||
|
||||
|
||||
public FlightConfigurationID getMotorConfigurationID() {
|
||||
return configID;
|
||||
return configId;
|
||||
}
|
||||
|
||||
public FlightConfigurationID getConfigurationID() {
|
||||
return configID;
|
||||
public FlightConfigurationID getFlightConfigurationID() {
|
||||
return configId;
|
||||
}
|
||||
|
||||
public void setFlightConfigurationID(FlightConfigurationID _fcid) {
|
||||
this.configID = _fcid;
|
||||
this.configId = _fcid;
|
||||
this.modID++;
|
||||
}
|
||||
|
||||
@ -327,6 +327,9 @@ public class SimulationConditions implements Monitorable, Cloneable {
|
||||
for (SimulationListener listener : this.simulationListeners) {
|
||||
clone.simulationListeners.add(listener.clone());
|
||||
}
|
||||
clone.rocket = this.rocket; // the rocket should be read-only from this point
|
||||
clone.configId = this.configId; // configIds are read-only
|
||||
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new BugException(e);
|
||||
|
@ -19,6 +19,9 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
import javax.swing.event.TableModelListener;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
@ -35,9 +38,8 @@ import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.Chars;
|
||||
|
||||
public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount> {
|
||||
|
||||
private static final long serialVersionUID = -5046535300435793744L;
|
||||
|
||||
|
||||
private static final String NONE = trans.get("edtmotorconfdlg.tbl.None");
|
||||
|
||||
private final JButton selectMotorButton, removeMotorButton, selectIgnitionButton, resetIgnitionButton;
|
||||
@ -250,13 +252,12 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
return;
|
||||
}
|
||||
|
||||
// this call also performs the update changes
|
||||
IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog(
|
||||
SwingUtilities.getWindowAncestor(this.flightConfigurationPanel),
|
||||
fcid,
|
||||
curMount);
|
||||
ignitionDialog.setVisible(true);
|
||||
|
||||
// changes performed automatically within "new IgnitionSelectionDialog(...)"
|
||||
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user