diff --git a/core/src/net/sf/openrocket/file/rasaero/RASAeroCommonConstants.java b/core/src/net/sf/openrocket/file/rasaero/RASAeroCommonConstants.java index da5481ca8..c33965e6d 100644 --- a/core/src/net/sf/openrocket/file/rasaero/RASAeroCommonConstants.java +++ b/core/src/net/sf/openrocket/file/rasaero/RASAeroCommonConstants.java @@ -1,6 +1,7 @@ package net.sf.openrocket.file.rasaero; import net.sf.openrocket.logging.WarningSet; +import net.sf.openrocket.motor.Manufacturer; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; import net.sf.openrocket.rocketcomponent.ExternalComponent; import net.sf.openrocket.rocketcomponent.FinSet; @@ -154,15 +155,29 @@ public class RASAeroCommonConstants { public static final String SIMULATION_LIST = "SimulationList"; public static final String SIMULATION = "Simulation"; public static final String SUSTAINER_ENGINE = "SustainerEngine"; - // TODO: SustainerLaunchWt, SustainerCG? + public static final String SUSTAINER_LAUNCH_WT = "SustainerLaunchWt"; + public static final String SUSTAINER_NOZZLE_DIAMETER = "SustainerNozzleDiameter"; + public static final String SUSTAINER_CG = "SustainerCG"; public static final String SUSTAINER_IGNITION_DELAY = "SustainerIgnitionDelay"; public static final String BOOSTER1_ENGINE = "Booster1Engine"; public static final String BOOSTER1_SEPARATION_DELAY = "Booster1SeparationDelay"; // Delay after booster burnout to separate public static final String BOOSTER1_IGNITION_DELAY = "Booster1IgnitionDelay"; + public static final String BOOSTER1_LAUNCH_WT = "Booster1LaunchWt"; + public static final String BOOSTER1_NOZZLE_DIAMETER = "Booster1NozzleDiameter"; + public static final String BOOSTER1_CG = "Booster1CG"; public static final String INCLUDE_BOOSTER1 = "IncludeBooster1"; public static final String BOOSTER2_ENGINE = "Booster2Engine"; public static final String BOOSTER2_SEPARATION_DELAY = "Booster2Delay"; // Delay after booster burnout to separate + public static final String BOOSTER2_LAUNCH_WT = "Booster2LaunchWt"; + public static final String BOOSTER2_NOZZLE_DIAMETER = "Booster2NozzleDiameter"; + public static final String BOOSTER2_CG = "Booster2CG"; public static final String INCLUDE_BOOSTER2 = "IncludeBooster2"; + public static final String FLIGHT_TIME = "FlightTime"; + public static final String TIME_TO_APOGEE = "TimetoApogee"; + public static final String MAX_ALTITUDE = "MaxAltitude"; + public static final String MAX_VELOCITY = "MaxVelocity"; + public static final String OPTIMUM_WT = "OptimumWt"; + public static final String OPTIMUM_MAX_ALT = "OptimumMaxAlt"; /** @@ -353,6 +368,57 @@ public class RASAeroCommonConstants { } } + public static String OPENROCKET_TO_RASAERO_MANUFACTURER(Manufacturer manufacturer) { + if (manufacturer.matches("AeroTech")) { + return "AT"; + } else if (manufacturer.matches("Estes")) { + return "ES"; + } else if (manufacturer.matches("Apogee")) { + return "AP"; + } else if (manufacturer.matches("Quest")) { + return "QU"; + } else if (manufacturer.matches("Cesaroni")) { + return "CTI"; + } else if (manufacturer.matches("NoThrust")) { + return "NoThrust"; + } else if (manufacturer.matches("Ellis Mountain")) { + return "EM"; + } else if (manufacturer.matches("Contrail")) { + return "Contrail"; + } else if (manufacturer.matches("Rocketvision")) { + return "RV"; + } else if (manufacturer.matches("Roadrunner Rocketry")) { + return "RR"; + } else if (manufacturer.matches("Sky Ripper Systems")) { + return "SRS"; + } else if (manufacturer.matches("Loki Research")) { + return "LR"; + } else if (manufacturer.matches("Public Missiles, Ltd.")) { + return "PML"; + } else if (manufacturer.matches("Kosdon by AeroTech")) { + return "KBA"; + } else if (manufacturer.matches("Gorilla Rocket Motors")) { + return "GM"; + } else if (manufacturer.matches("RATT Works")) { + return "RTW"; + } else if (manufacturer.matches("HyperTEK")) { + return "HT"; + } else if (manufacturer.matches("Animal Motor Works")) { + return "AMW"; + } else if (manufacturer.matches("Loki")) { + return "CT"; + } else if (manufacturer.matches("AMW ProX")) { + return "AMW/ProX"; + } else if (manufacturer.matches("Loki Research EX")) { + return "LR-EX"; + } else if (manufacturer.matches("Derek Deville DEAP EX")) { + return "DEAP-EX"; + } else if (manufacturer.matches("Historical")) { + return "Hist"; + } + return manufacturer.getSimpleName(); + } + public static DeploymentConfiguration.DeployEvent RASAERO_TO_OPENROCKET_DEPLOY_EVENT(String deployEvent, WarningSet warnings) { if (DEPLOYMENT_NONE.equals(deployEvent)) { return DeploymentConfiguration.DeployEvent.NEVER; diff --git a/core/src/net/sf/openrocket/file/rasaero/export/LaunchSiteDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/LaunchSiteDTO.java index 7c8fc83fe..de6b303a0 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/LaunchSiteDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/LaunchSiteDTO.java @@ -1,4 +1,12 @@ package net.sf.openrocket.file.rasaero.export; +import net.sf.openrocket.file.rasaero.RASAeroCommonConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = RASAeroCommonConstants.LAUNCH_SITE) +@XmlAccessorType(XmlAccessType.FIELD) public class LaunchSiteDTO { } diff --git a/core/src/net/sf/openrocket/file/rasaero/export/NoseConeDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/NoseConeDTO.java index cd1e94acd..95c3d5498 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/NoseConeDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/NoseConeDTO.java @@ -22,7 +22,8 @@ public class NoseConeDTO extends BasePartDTO { @XmlElement(name = RASAeroCommonConstants.SHAPE) private String shape; @XmlElement(name = RASAeroCommonConstants.BLUNT_RADIUS) - private double bluntRadius = 0; + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double bluntRadius = 0d; @XmlElement(name = RASAeroCommonConstants.POWER_LAW) @XmlJavaTypeAdapter(CustomDoubleAdapter.class) private Double powerLaw; diff --git a/core/src/net/sf/openrocket/file/rasaero/export/RASAeroDocumentDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/RASAeroDocumentDTO.java index fc5ac0051..ef4420a83 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/RASAeroDocumentDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/RASAeroDocumentDTO.java @@ -29,10 +29,6 @@ public class RASAeroDocumentDTO { @XmlElement(name = RASAeroCommonConstants.MACH_ALT) private String machAlt = ""; // Currently not implemented - /* - @XmlElementWrapper(name=RASAeroCommonConstants.SIMULATION_LIST) - @XmlElement(name=RASAeroCommonConstants.SIMULATION) - */ @XmlElement(name = RASAeroCommonConstants.SIMULATION_LIST) private SimulationListDTO simulationList = null; diff --git a/core/src/net/sf/openrocket/file/rasaero/export/RASAeroSaver.java b/core/src/net/sf/openrocket/file/rasaero/export/RASAeroSaver.java index 110cac778..d418e7ca3 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/RASAeroSaver.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/RASAeroSaver.java @@ -50,9 +50,10 @@ public class RASAeroSaver extends RocketSaver { errors.add(e.getMessage()); } catch (Exception e) { log.error("Could not marshall a design to RASAero format. " + e.getMessage()); + throw new RuntimeException("Could not marshall a design to RASAero format. " + e.getMessage()); } - return null; + throw new RuntimeException("Could not marshall a design to RASAero format."); } @Override @@ -80,7 +81,7 @@ public class RASAeroSaver extends RocketSaver { private RASAeroDocumentDTO toRASAeroDocumentDTO(OpenRocketDocument doc, WarningSet warnings, ErrorSet errors) throws RASAeroExportException { RASAeroDocumentDTO rad = new RASAeroDocumentDTO(); rad.setDesign(toRocketDesignDTO(doc.getRocket(), warnings, errors)); - + rad.setSimulationList(toSimulationListDTO(doc, warnings, errors)); return rad; } @@ -92,4 +93,15 @@ public class RASAeroSaver extends RocketSaver { private RocketDesignDTO toRocketDesignDTO(Rocket rocket, WarningSet warnings, ErrorSet errors) throws RASAeroExportException { return new RocketDesignDTO(rocket, warnings, errors); } + + /** + * Create a list of simulations. + * @param document document that contains simulations + * @param warnings list to add export warnings to + * @param errors list to add export errors to + * @return the RASAero simulation list + */ + private SimulationListDTO toSimulationListDTO(OpenRocketDocument document, WarningSet warnings, ErrorSet errors) { + return new SimulationListDTO(document, warnings, errors); + } } diff --git a/core/src/net/sf/openrocket/file/rasaero/export/RecoveryDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/RecoveryDTO.java index 8cbb8233f..ba79f415b 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/RecoveryDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/RecoveryDTO.java @@ -1,4 +1,12 @@ package net.sf.openrocket.file.rasaero.export; +import net.sf.openrocket.file.rasaero.RASAeroCommonConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = RASAeroCommonConstants.RECOVERY) +@XmlAccessorType(XmlAccessType.FIELD) public class RecoveryDTO { } diff --git a/core/src/net/sf/openrocket/file/rasaero/export/SimulationDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/SimulationDTO.java new file mode 100644 index 000000000..95533d7f1 --- /dev/null +++ b/core/src/net/sf/openrocket/file/rasaero/export/SimulationDTO.java @@ -0,0 +1,384 @@ +package net.sf.openrocket.file.rasaero.export; + +import net.sf.openrocket.document.Simulation; +import net.sf.openrocket.file.rasaero.CustomBooleanAdapter; +import net.sf.openrocket.file.rasaero.CustomDoubleAdapter; +import net.sf.openrocket.file.rasaero.RASAeroCommonConstants; +import net.sf.openrocket.logging.ErrorSet; +import net.sf.openrocket.logging.WarningSet; +import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.motor.MotorConfiguration; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.FlightConfigurationId; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.List; +import java.util.Map; + +@XmlRootElement(name = RASAeroCommonConstants.SIMULATION) +@XmlAccessorType(XmlAccessType.FIELD) +public class SimulationDTO { + @XmlElement(name = RASAeroCommonConstants.SUSTAINER_ENGINE) + private String sustainerEngine; + @XmlElement(name = RASAeroCommonConstants.SUSTAINER_LAUNCH_WT) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double sustainerLaunchWt = 0d; + @XmlElement(name = RASAeroCommonConstants.SUSTAINER_NOZZLE_DIAMETER) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double sustainerNozzleDiameter = 0d; + @XmlElement(name = RASAeroCommonConstants.SUSTAINER_CG) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double sustainerCG = 0d; + @XmlElement(name = RASAeroCommonConstants.SUSTAINER_IGNITION_DELAY) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double sustainerIgnitionDelay = 0d; + + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_ENGINE) + private String booster1Engine; + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_LAUNCH_WT) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster1LaunchWt = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_SEPARATION_DELAY) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster1SeparationDelay = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_IGNITION_DELAY) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster1IgnitionDelay = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_CG) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster1CG = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER1_NOZZLE_DIAMETER) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster1NozzleDiameter = 0d; + @XmlElement(name = RASAeroCommonConstants.INCLUDE_BOOSTER1) + @XmlJavaTypeAdapter(CustomBooleanAdapter.class) + private Boolean includeBooster1 = false; + + @XmlElement(name = RASAeroCommonConstants.BOOSTER2_ENGINE) + private String booster2Engine; + @XmlElement(name = RASAeroCommonConstants.BOOSTER2_LAUNCH_WT) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster2LaunchWt = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER2_SEPARATION_DELAY) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster2Delay = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER2_CG) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster2CG = 0d; + @XmlElement(name = RASAeroCommonConstants.BOOSTER2_NOZZLE_DIAMETER) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double booster2NozzleDiameter = 0d; + @XmlElement(name = RASAeroCommonConstants.INCLUDE_BOOSTER2) + @XmlJavaTypeAdapter(CustomBooleanAdapter.class) + private Boolean includeBooster2 = false; + + @XmlElement(name = RASAeroCommonConstants.FLIGHT_TIME) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double flightTime = 0d; + @XmlElement(name = RASAeroCommonConstants.TIME_TO_APOGEE) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double timetoApogee = 0d; + @XmlElement(name = RASAeroCommonConstants.MAX_ALTITUDE) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double maxAltitude = 0d; + @XmlElement(name = RASAeroCommonConstants.MAX_VELOCITY) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double maxVelocity = 0d; + @XmlElement(name = RASAeroCommonConstants.OPTIMUM_WT) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double optimumWt = 0d; + @XmlElement(name = RASAeroCommonConstants.OPTIMUM_MAX_ALT) + @XmlJavaTypeAdapter(CustomDoubleAdapter.class) + private Double optimumMaxAlt = 0d; + + /** + * We need a default, no-args constructor. + */ + public SimulationDTO() { + } + + /** + * RASAero Simulation object. + * @param rocket the rocket + * @param simulation the simulation to convert + * @param mounts a map of stages and their corresponding motor mount (only 1 mount per stage allowed) + * @param motors a list of RASAero motors + * @param warnings a list to add export warnings to + * @param errors a list to add export errors to + */ + public SimulationDTO(Rocket rocket, Simulation simulation, Map mounts, List motors, + WarningSet warnings, ErrorSet errors) { + FlightConfigurationId fcid = simulation.getFlightConfigurationId(); + if (fcid == null) { + warnings.add(String.format("Empty simulation '%s', ignoring.", simulation.getName())); + return; + } + + for (Map.Entry mountSet : mounts.entrySet()) { + AxialStage stage = mountSet.getKey(); + MotorMount mount = mountSet.getValue(); + if (mount == null || stage == null) { + continue; + } + + MotorConfiguration motorConfig = mount.getMotorConfig(fcid); + StageSeparationConfiguration separationConfig = stage.getSeparationConfigurations().get(fcid); + int stageNr = rocket.getChildPosition(stage); + + switch (stageNr) { + // Sustainer + case 0: + setSustainerEngine(getRASAeroMotor(motors, motorConfig.getMotor(), warnings)); + setSustainerLaunchWt(stage.getSectionMass()); + setSustainerCG(stage.getCG().x); // TODO: use aggregate CG... + setSustainerIgnitionDelay(motorConfig.getIgnitionDelay()); + break; + // Booster 1 + case 1: + setBooster1Engine(getRASAeroMotor(motors, motorConfig.getMotor(), warnings)); + setBooster1LaunchWt(stage.getSectionMass()); + setBooster1CG(stage.getCG().x); // TODO: use aggregate CG... + setBooster1IgnitionDelay(motorConfig.getIgnitionDelay()); + setBooster1SeparationDelay(separationConfig.getSeparationDelay()); // TODO: this could be handled a bit better (look at separation delay, upper stage ignition event etc.) + setIncludeBooster1(mount.isMotorMount()); + break; + // Booster 2 + case 2: + setBooster2Engine(getRASAeroMotor(motors, motorConfig.getMotor(), warnings)); + setBooster2LaunchWt(stage.getSectionMass()); + setBooster2CG(stage.getCG().x); // TODO: use aggregate CG... + setBooster2Delay(separationConfig.getSeparationDelay()); // TODO: this could be handled a bit better (look at separation delay, upper stage ignition event etc.) + setIncludeBooster2(mount.isMotorMount()); + break; + // Invalid + default: + errors.add(String.format("Invalid stage number '%d' for simulation '%s'", + stageNr, simulation.getName())); + } + } + } + + /** + * Format an OpenRocket motor as a RASAero motor. + * @param motors list of available RASAero motors + * @param ORMotor OpenRocket motor + * @return a RASAero String representation of a motor + */ + private String getRASAeroMotor(List motors, Motor ORMotor, WarningSet warnings) { + if (!(ORMotor instanceof ThrustCurveMotor)) { + return null; + } + + for (ThrustCurveMotor motor : motors) { + if (ORMotor.getDesignation().equals(motor.getDesignation()) && + ((ThrustCurveMotor) ORMotor).getManufacturer().matches(motor.getManufacturer().getDisplayName())) { + return motor.getDesignation() + + " (" + RASAeroCommonConstants.OPENROCKET_TO_RASAERO_MANUFACTURER(motor.getManufacturer()) + ")"; + } + } + + warnings.add(String.format("Could not find RASAero motor for '%s'", ORMotor.getDesignation())); + return null; + } + + + public String getSustainerEngine() { + return sustainerEngine; + } + + public void setSustainerEngine(String sustainerEngine) { + this.sustainerEngine = sustainerEngine; + } + + public Double getSustainerLaunchWt() { + return sustainerLaunchWt; + } + + public void setSustainerLaunchWt(Double sustainerLaunchWt) { + this.sustainerLaunchWt = sustainerLaunchWt; + } + + public Double getSustainerNozzleDiameter() { + return sustainerNozzleDiameter; + } + + public void setSustainerNozzleDiameter(Double sustainerNozzleDiameter) { + this.sustainerNozzleDiameter = sustainerNozzleDiameter; + } + + public Double getSustainerCG() { + return sustainerCG; + } + + public void setSustainerCG(Double sustainerCG) { + this.sustainerCG = sustainerCG; + } + + public Double getSustainerIgnitionDelay() { + return sustainerIgnitionDelay; + } + + public void setSustainerIgnitionDelay(Double sustainerIgnitionDelay) { + this.sustainerIgnitionDelay = sustainerIgnitionDelay; + } + + public String getBooster1Engine() { + return booster1Engine; + } + + public void setBooster1Engine(String booster1Engine) { + this.booster1Engine = booster1Engine; + } + + public Double getBooster1LaunchWt() { + return booster1LaunchWt; + } + + public void setBooster1LaunchWt(Double booster1LaunchWt) { + this.booster1LaunchWt = booster1LaunchWt; + } + + public Double getBooster1SeparationDelay() { + return booster1SeparationDelay; + } + + public void setBooster1SeparationDelay(Double booster1SeparationDelay) { + this.booster1SeparationDelay = booster1SeparationDelay; + } + + public Double getBooster1IgnitionDelay() { + return booster1IgnitionDelay; + } + + public void setBooster1IgnitionDelay(Double booster1IgnitionDelay) { + this.booster1IgnitionDelay = booster1IgnitionDelay; + } + + public Double getBooster1CG() { + return booster1CG; + } + + public void setBooster1CG(Double booster1CG) { + this.booster1CG = booster1CG; + } + + public Double getBooster1NozzleDiameter() { + return booster1NozzleDiameter; + } + + public void setBooster1NozzleDiameter(Double booster1NozzleDiameter) { + this.booster1NozzleDiameter = booster1NozzleDiameter; + } + + public Boolean getIncludeBooster1() { + return includeBooster1; + } + + public void setIncludeBooster1(Boolean includeBooster1) { + this.includeBooster1 = includeBooster1; + } + + public String getBooster2Engine() { + return booster2Engine; + } + + public void setBooster2Engine(String booster2Engine) { + this.booster2Engine = booster2Engine; + } + + public Double getBooster2LaunchWt() { + return booster2LaunchWt; + } + + public void setBooster2LaunchWt(Double booster2LaunchWt) { + this.booster2LaunchWt = booster2LaunchWt; + } + + public Double getBooster2Delay() { + return booster2Delay; + } + + public void setBooster2Delay(Double booster2Delay) { + this.booster2Delay = booster2Delay; + } + + public Double getBooster2CG() { + return booster2CG; + } + + public void setBooster2CG(Double booster2CG) { + this.booster2CG = booster2CG; + } + + public Double getBooster2NozzleDiameter() { + return booster2NozzleDiameter; + } + + public void setBooster2NozzleDiameter(Double booster2NozzleDiameter) { + this.booster2NozzleDiameter = booster2NozzleDiameter; + } + + public Boolean getIncludeBooster2() { + return includeBooster2; + } + + public void setIncludeBooster2(Boolean includeBooster2) { + this.includeBooster2 = includeBooster2; + } + + public Double getFlightTime() { + return flightTime; + } + + public void setFlightTime(Double flightTime) { + this.flightTime = flightTime; + } + + public Double getTimetoApogee() { + return timetoApogee; + } + + public void setTimetoApogee(Double timetoApogee) { + this.timetoApogee = timetoApogee; + } + + public Double getMaxAltitude() { + return maxAltitude; + } + + public void setMaxAltitude(Double maxAltitude) { + this.maxAltitude = maxAltitude; + } + + public Double getMaxVelocity() { + return maxVelocity; + } + + public void setMaxVelocity(Double maxVelocity) { + this.maxVelocity = maxVelocity; + } + + public Double getOptimumWt() { + return optimumWt; + } + + public void setOptimumWt(Double optimumWt) { + this.optimumWt = optimumWt; + } + + public Double getOptimumMaxAlt() { + return optimumMaxAlt; + } + + public void setOptimumMaxAlt(Double optimumMaxAlt) { + this.optimumMaxAlt = optimumMaxAlt; + } +} diff --git a/core/src/net/sf/openrocket/file/rasaero/export/SimulationListDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/SimulationListDTO.java index a3af9c971..17dda78d1 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/SimulationListDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/SimulationListDTO.java @@ -1,4 +1,73 @@ package net.sf.openrocket.file.rasaero.export; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.document.Simulation; +import net.sf.openrocket.file.rasaero.RASAeroCommonConstants; +import net.sf.openrocket.file.rasaero.importt.RASAeroMotorsLoader; +import net.sf.openrocket.logging.ErrorSet; +import net.sf.openrocket.logging.WarningSet; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.BodyTube; +import net.sf.openrocket.rocketcomponent.MotorMount; +import net.sf.openrocket.rocketcomponent.Rocket; +import net.sf.openrocket.rocketcomponent.RocketComponent; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +@XmlRootElement(name = RASAeroCommonConstants.SIMULATION_LIST) +@XmlAccessorType(XmlAccessType.FIELD) public class SimulationListDTO { + @XmlElement(name = RASAeroCommonConstants.SIMULATION) + private final List simulations = new LinkedList<>(); + + /** + * We need a default, no-args constructor. + */ + public SimulationListDTO() { + } + + public SimulationListDTO(OpenRocketDocument document, WarningSet warnings, ErrorSet errors) { + Map mounts = new HashMap<>(); + Rocket rocket = document.getRocket(); + + // Fetch all the motor mounts from the design + for (RocketComponent child : rocket.getChildren()) { + AxialStage stage = (AxialStage) child; + if (mounts.containsKey(stage)) { + continue; + } + for (RocketComponent stageChild : stage.getChildren()) { + // We can only really use body tubes as motor mounts, since other stuff (e.g. inner tube) is not supported in RASAero + if (stageChild instanceof BodyTube && ((BodyTube) stageChild).hasMotor()) { + mounts.put(stage, (BodyTube) stageChild); + } + } + } + + // Load all RASAero motors + List motors = RASAeroMotorsLoader.loadAllRASAeroMotors(warnings); + + for (Simulation simulation : document.getSimulations()) { + addSimulation(new SimulationDTO(rocket, simulation, mounts, motors, warnings, errors)); + } + + motors.clear(); + } + + public List getSimulations() { + return simulations; + } + + public void addSimulation(SimulationDTO simulation) { + simulations.add(simulation); + } + } diff --git a/core/src/net/sf/openrocket/file/rasaero/importt/RASAeroMotorsLoader.java b/core/src/net/sf/openrocket/file/rasaero/importt/RASAeroMotorsLoader.java index b24df532f..53676d405 100644 --- a/core/src/net/sf/openrocket/file/rasaero/importt/RASAeroMotorsLoader.java +++ b/core/src/net/sf/openrocket/file/rasaero/importt/RASAeroMotorsLoader.java @@ -1,10 +1,13 @@ package net.sf.openrocket.file.rasaero.importt; +import net.sf.openrocket.file.motor.GeneralMotorLoader; import net.sf.openrocket.logging.WarningSet; import net.sf.openrocket.database.motor.ThrustCurveMotorSet; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.startup.Application; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -22,7 +25,7 @@ public abstract class RASAeroMotorsLoader { return null; } if (allMotors == null) { - loadAllMotors(); + loadAllMotors(warnings); } /* RASAero file motor strings are formatted as " ()" @@ -52,17 +55,18 @@ public abstract class RASAeroMotorsLoader { } } - // Not currently used, because it causes some compatibility issues when e.g. wanting to open the RASAero motor + // Not currently used for importing, because it causes some compatibility issues when e.g. wanting to open the RASAero motor // in the motor selection table (because it is not present there). // It's probably also better to load OR-native motors. // But I'll leave this in, in case it's needed in the future. - /* + /** * Loads all original RASAero motors. * @param warnings The warning set to add import warnings to. + * @return the loaded motors * @throws RuntimeException If the RASAero motors file could not be found. - * - private static void loadAllRASAeroMotors(WarningSet warnings) throws RuntimeException { - allMotors = new ArrayList<>(); + */ + public static List loadAllRASAeroMotors(WarningSet warnings) throws RuntimeException { + List RASAeroMotors = new ArrayList<>(); GeneralMotorLoader loader = new GeneralMotorLoader(); ClassLoader classloader = Thread.currentThread().getContextClassLoader(); @@ -74,22 +78,25 @@ public abstract class RASAeroMotorsLoader { try { List motors = loader.load(is, fileName); for (ThrustCurveMotor.Builder builder : motors) { - allMotors.add(builder.build()); + RASAeroMotors.add(builder.build()); } } catch (IOException e) { warnings.add("Error during motor loading: " + e.getMessage()); } - }*/ + + return RASAeroMotors; + } /** * Loads the OpenRocket motors database. */ - private static void loadAllMotors() { + private static void loadAllMotors(WarningSet warnings) { allMotors = new ArrayList<>(); List database = Application.getThrustCurveMotorSetDatabase().getMotorSets(); for (ThrustCurveMotorSet set : database) { allMotors.addAll(set.getMotors()); } + //allMotors.addAll(loadAllRASAeroMotors(warnings)); } } diff --git a/core/src/net/sf/openrocket/logging/MessageSet.java b/core/src/net/sf/openrocket/logging/MessageSet.java index 98642d1aa..064c52cf5 100644 --- a/core/src/net/sf/openrocket/logging/MessageSet.java +++ b/core/src/net/sf/openrocket/logging/MessageSet.java @@ -74,7 +74,7 @@ public abstract class MessageSet extends AbstractSet imple @Override public Iterator iterator() { final Iterator iterator = messages.iterator(); - return new Iterator<>() { + return new Iterator() { @Override public boolean hasNext() { return iterator.hasNext();