updates
This commit is contained in:
parent
0bd3b1630e
commit
8aac8594d3
@ -13,7 +13,7 @@ public abstract class Error extends Message {
|
||||
* @return an Error with the specific text.
|
||||
*/
|
||||
public static Error fromString(String text) {
|
||||
return new Error.Other(text);
|
||||
return new Other(text);
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ public abstract class Warning extends Message {
|
||||
* @return a Warning with the specific text.
|
||||
*/
|
||||
public static Warning fromString(String text) {
|
||||
return new Warning.Other(text);
|
||||
return new Other(text);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class CustomBooleanAdapter extends XmlAdapter<String, Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean unmarshal(String s) throws Exception {
|
||||
return "true".equalsIgnoreCase(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(Boolean b) throws Exception {
|
||||
if (b) {
|
||||
return "True";
|
||||
}
|
||||
return "False";
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
|
||||
public class CustomDoubleAdapter extends XmlAdapter<String, Double> {
|
||||
@Override
|
||||
public Double unmarshal(String s) throws Exception {
|
||||
return Double.parseDouble(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(Double aDouble) throws Exception {
|
||||
if (aDouble == null) {
|
||||
return null;
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat("#.####", new DecimalFormatSymbols(Locale.US)); // RASAero has 4 decimal precision
|
||||
return df.format(aDouble);
|
||||
}
|
||||
}
|
@ -1,517 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero;
|
||||
|
||||
import net.sf.openrocket.file.motor.AbstractMotorLoader;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.motor.Manufacturer;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* List of constants used in RASAero files + helper functions to read parameters from it.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class RASAeroCommonConstants {
|
||||
// File settings
|
||||
public static final String FILE_EXTENSION = "CDX1";
|
||||
|
||||
// General settings
|
||||
public static final String RASAERO_DOCUMENT = "RASAeroDocument";
|
||||
public static final String FILE_VERSION = "FileVersion";
|
||||
public static final String ROCKET_DESIGN = "RocketDesign";
|
||||
|
||||
// RASAeroDocument settings
|
||||
public static final String MACH_ALT = "MachAlt";
|
||||
|
||||
// Base part settings
|
||||
public static final String PART_TYPE = "PartType";
|
||||
public static final String LENGTH = "Length";
|
||||
public static final String DIAMETER = "Diameter";
|
||||
public static final String LOCATION = "Location";
|
||||
public static final String COLOR = "Color";
|
||||
public static final String SURFACE_FINISH = "Surface";
|
||||
public static final String COMMENTS = "Comments";
|
||||
|
||||
// Components
|
||||
public static final String NOSE_CONE = "NoseCone";
|
||||
public static final String BODY_TUBE = "BodyTube";
|
||||
public static final String TRANSITION = "Transition";
|
||||
public static final String FIN = "Fin";
|
||||
public static final String BOOSTER = "Booster";
|
||||
public static final String FIN_CAN = "FinCan";
|
||||
public static final String BOATTAIL = "BoatTail";
|
||||
|
||||
// Body tube settings
|
||||
public static final String OVERHANG = "Overhang";
|
||||
|
||||
// Nose cone settings
|
||||
public static final String SHAPE = "Shape";
|
||||
public static final String POWER_LAW = "PowerLaw";
|
||||
public static final String BLUNT_RADIUS = "BluntRadius";
|
||||
private static final Map<String, Transition.Shape> RASAeroNoseConeShapeMap = new HashMap<>();
|
||||
|
||||
//// Nose cone shapes
|
||||
private static final String SHAPE_CONICAL = "Conical";
|
||||
private static final String SHAPE_TANGENT_OGIVE = "Tangent Ogive";
|
||||
private static final String SHAPE_VON_KARMAN_OGIVE = "Von Karman Ogive";
|
||||
private static final String SHAPE_POWER_LAW = "Power Law";
|
||||
private static final String SHAPE_LVHAACK = "LV-Haack";
|
||||
private static final String SHAPE_PARABOLIC = "Parabolic";
|
||||
private static final String SHAPE_ELLIPTICAL = "Elliptical";
|
||||
|
||||
// Transition settings
|
||||
public static final String REAR_DIAMETER = "RearDiameter";
|
||||
|
||||
// Fin settings
|
||||
public static final String FIN_COUNT = "Count";
|
||||
public static final String FIN_CHORD = "Chord";
|
||||
public static final String FIN_SPAN = "Span";
|
||||
public static final String FIN_SWEEP_DISTANCE = "SweepDistance";
|
||||
public static final String FIN_TIP_CHORD = "TipChord";
|
||||
public static final String FIN_THICKNESS = "Thickness";
|
||||
public static final String FIN_LE_RADIUS = "LERadius";
|
||||
public static final String FIN_AIRFOIL_SECTION = "AirfoilSection";
|
||||
public static final String FIN_FX1 = "FX1";
|
||||
public static final String FIN_FX3 = "FX3";
|
||||
public static final String AIRFOIL_SECTION = "AirfoilSection";
|
||||
//// LERadius, FX1 and FX3 not used
|
||||
public static final String CROSS_SECTION_SQUARE = "Square";
|
||||
public static final String CROSS_SECTION_ROUNDED = "Rounded";
|
||||
public static final String CROSS_SECTION_SUBSONIC_NACA = "Subsonic NACA";
|
||||
|
||||
// Launch lug settings
|
||||
public static final String LAUNCH_LUG_DIAMETER = "LaunchLugDiameter";
|
||||
public static final String LAUNCH_LUG_LENGTH = "LaunchLugLength";
|
||||
|
||||
// Rail guide settings
|
||||
public static final String RAIL_GUIDE_DIAMETER = "RailGuideDiameter";
|
||||
public static final String RAIL_GUIDE_HEIGHT = "RailGuideHeight";
|
||||
|
||||
// Launch shoe settings
|
||||
public static final String LAUNCH_SHOE_AREA = "LaunchShoeArea";
|
||||
|
||||
// Fin can settings
|
||||
public static final String INSIDE_DIAMETER = "InsideDiameter";
|
||||
public static final String SHOULDER_LENGTH = "ShoulderLength";
|
||||
|
||||
// Surface finishes
|
||||
public static final String FINISH_SMOOTH = "Smooth (Zero Roughness)";
|
||||
public static final String FINISH_POLISHED = "Polished";
|
||||
public static final String FINISH_SHEET_METAL = "Sheet Metal";
|
||||
public static final String FINISH_SMOOTH_PAINT = "Smooth Paint";
|
||||
public static final String FINISH_CAMOUFLAGE = "Camouflage Paint";
|
||||
public static final String FINISH_ROUGH_CAMOUFLAGE = "Rough Camouflage Paint";
|
||||
public static final String FINISH_GALVANIZED = "Galvanized Metal";
|
||||
public static final String FINISH_CAST_IRON = "Cast Iron (Very Rough)";
|
||||
|
||||
// Booster settings
|
||||
public static final String BOATTAIL_LENGTH = "BoattailLength";
|
||||
public static final String BOATTAIL_REAR_DIAMETER = "BoattailRearDiameter";
|
||||
public static final String BOATTAIL_OFFSET = "BoattailOffset";
|
||||
public static final String NOZZLE_EXIT_DIAMETER = "NozzleExitDiameter";
|
||||
|
||||
// RocketDesign settings
|
||||
public static final String CD = "CD";
|
||||
public static final String MODIFIED_BARROWMAN = "ModifiedBarrowman";
|
||||
public static final String TURBULENCE = "Turbulence";
|
||||
public static final String SUSTAINER_NOZZLE = "SustainerNozzle";
|
||||
public static final String BOOSTER1_NOZZLE = "Booster1Nozzle";
|
||||
public static final String BOOSTER2_NOZZLE = "Booster2Nozzle";
|
||||
public static final String USE_BOOSTER1 = "UseBooster1";
|
||||
public static final String USE_BOOSTER2 = "UseBooster2";
|
||||
|
||||
// Launch site settings
|
||||
public static final String LAUNCH_SITE = "LaunchSite";
|
||||
public static final String LAUNCH_ALTITUDE = "Altitude";
|
||||
public static final String LAUNCH_PRESSURE = "Pressure";
|
||||
public static final String LAUNCH_ROD_ANGLE = "RodAngle";
|
||||
public static final String LAUNCH_ROD_LENGTH = "RodLength";
|
||||
public static final String LAUNCH_TEMPERATURE = "Temperature";
|
||||
public static final String LAUNCH_WIND_SPEED = "WindSpeed";
|
||||
|
||||
// Recovery settings
|
||||
public static final String RECOVERY = "Recovery";
|
||||
public static final String RECOVERY_ALTITUDE = "Altitude";
|
||||
public static final String RECOVERY_DEVICE_TYPE = "DeviceType";
|
||||
public static final String RECOVERY_EVENT = "Event";
|
||||
public static final String RECOVERY_SIZE = "Size";
|
||||
public static final String RECOVERY_EVENT_TYPE = "EventType";
|
||||
public static final String RECOVERY_CD = "CD";
|
||||
|
||||
// Deployment settings
|
||||
public static final String DEPLOYMENT_NONE = "None";
|
||||
public static final String DEPLOYMENT_APOGEE = "Apogee";
|
||||
public static final String DEPLOYMENT_ALTITUDE = "Altitude";
|
||||
|
||||
// Simulation settings
|
||||
public static final String SIMULATION_LIST = "SimulationList";
|
||||
public static final String SIMULATION = "Simulation";
|
||||
public static final String SUSTAINER_ENGINE = "SustainerEngine";
|
||||
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";
|
||||
|
||||
|
||||
/**
|
||||
* Length conversion from OpenRocket units to RASAero units. RASAero is in inches, OpenRocket in meters.
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_LENGTH = 39.37;
|
||||
/**
|
||||
* Altitude conversion from OpenRocket units to RASAero units. RASAero is in feet, OpenRocket in meters.
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_ALTITUDE = 3.28084;
|
||||
/**
|
||||
* Speed conversion from OpenRocket units to RASAero units. RASAero is in mph, OpenRocket in m/s.
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_SPEED = 2.23694;
|
||||
/**
|
||||
* Pressure conversion from OpenRocket units to RASAero units. RASAero is in in-hg, OpenRocket in Pa.
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_PRESSURE = 0.000295301;
|
||||
/**
|
||||
* Angle conversion from OpenRocket units to RASAero units. RASAero is in degrees, OpenRocket in rad.
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_ANGLE = 180 / Math.PI;
|
||||
/**
|
||||
* Weight conversion from OpenRocket units to RASAero units. RASAero is in pounds (lb), OpenRocket in kilograms (kg).
|
||||
*/
|
||||
public static final double OPENROCKET_TO_RASAERO_WEIGHT = 2.20462262;
|
||||
/**
|
||||
* Temperature conversion from OpenRocket units to RASAero units. RASAero is in Fahrenheit, OpenRocket in Kelvin.
|
||||
*/
|
||||
public static final double RASAERO_TO_OPENROCKET_TEMPERATURE(Double input) {
|
||||
return (input + 459.67) * 5.0 / 9.0;
|
||||
}
|
||||
public static final double OPENROCKET_TO_RASAERO_TEMPERATURE(Double input) {
|
||||
return input * 9.0 / 5.0 - 459.67;
|
||||
}
|
||||
|
||||
static {
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_CONICAL, Transition.Shape.CONICAL);
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_TANGENT_OGIVE, Transition.Shape.OGIVE); // = Ogive with shape parameter = 1
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_VON_KARMAN_OGIVE, Transition.Shape.HAACK); // = Haack series with shape parameter = 0
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_POWER_LAW, Transition.Shape.POWER);
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_LVHAACK, Transition.Shape.HAACK); // = Haack series with shape parameter = 1/3
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_PARABOLIC, Transition.Shape.POWER); // = Power law with shape parameter = 1/2
|
||||
RASAeroNoseConeShapeMap.put(SHAPE_ELLIPTICAL, Transition.Shape.ELLIPSOID);
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RASAeroCommonConstants.class);
|
||||
|
||||
/**
|
||||
* Returns the OpenRocket nose cone shape from the RASAero shape string.
|
||||
* @param shape The RASAero shape string.
|
||||
* @return The OpenRocket nose cone shape.
|
||||
*/
|
||||
public static Transition.Shape RASAERO_TO_OPENROCKET_SHAPE(String shape) {
|
||||
return RASAeroNoseConeShapeMap.get(shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OpenRocket nose cone shape from the RASAero shape string.
|
||||
* @param shape The RASAero shape string.
|
||||
* @return The OpenRocket nose cone shape object.
|
||||
*/
|
||||
public static NoseConeShapeSettings OPENROCKET_TO_RASAERO_SHAPE(Transition.Shape shape, double shapeParameter)
|
||||
throws RASAeroExportException {
|
||||
if (shape.equals(Transition.Shape.CONICAL)) {
|
||||
return new NoseConeShapeSettings(SHAPE_CONICAL);
|
||||
} else if (shape.equals(Transition.Shape.OGIVE) && MathUtil.equals(shapeParameter, 1)) {
|
||||
return new NoseConeShapeSettings(SHAPE_TANGENT_OGIVE);
|
||||
} else if (shape.equals(Transition.Shape.HAACK) && MathUtil.equals(shapeParameter, 0)) {
|
||||
return new NoseConeShapeSettings(SHAPE_VON_KARMAN_OGIVE);
|
||||
} else if (shape.equals(Transition.Shape.POWER) && MathUtil.equals(shapeParameter, 0.5, 0.01)) {
|
||||
return new NoseConeShapeSettings(SHAPE_PARABOLIC);
|
||||
} else if (shape.equals(Transition.Shape.POWER)) {
|
||||
return new NoseConeShapeSettings(SHAPE_POWER_LAW, shapeParameter);
|
||||
} else if (shape.equals(Transition.Shape.HAACK) && MathUtil.equals(shapeParameter, 0.33, 0.01)) {
|
||||
return new NoseConeShapeSettings(SHAPE_LVHAACK);
|
||||
} else if (shape.equals(Transition.Shape.ELLIPSOID)) {
|
||||
return new NoseConeShapeSettings(SHAPE_ELLIPTICAL);
|
||||
}
|
||||
|
||||
// Special cases
|
||||
else if (shape.equals(Transition.Shape.OGIVE)) {
|
||||
throw new RASAeroExportException(
|
||||
String.format("RASAero only supports Ogive nose cones with shape parameter 1, not %.2f", shapeParameter));
|
||||
} else if (shape.equals(Transition.Shape.HAACK)) {
|
||||
throw new RASAeroExportException(
|
||||
String.format("RASAero only supports Haack nose cones with shape parameter 0 or 0.33, not %.2f", shapeParameter));
|
||||
} else if (shape.equals(Transition.Shape.PARABOLIC)) {
|
||||
throw new RASAeroExportException("RASAero does not support Parabolic nose cones");
|
||||
}
|
||||
|
||||
throw new RASAeroExportException(
|
||||
String.format("Invalid shape and shape parameter combination: %s, %.2f", shape.getName(), shapeParameter));
|
||||
}
|
||||
|
||||
/**
|
||||
* RASAero has a slightly different way of specifying shapes compared to OpenRocket. For instance
|
||||
* RASAero has an "LV-Haack" shape, which is the same as the OpenRocket "Haack" shape with a shape
|
||||
* parameter of 1/3.
|
||||
* This method returns the shape parameter for the RASAero shape to get the correct OpenRocket nose cone shape.
|
||||
* @param shape The RASAero shape string.
|
||||
* @return The shape parameter for the OpenRocket nose cone.
|
||||
*/
|
||||
public static double RASAERO_TO_OPENROCKET_SHAPE_PARAMETER(String shape) {
|
||||
if (SHAPE_CONICAL.equals(shape)) {
|
||||
return 0.0; // Not really needed, but just to be explicit
|
||||
} else if (SHAPE_TANGENT_OGIVE.equals(shape)) {
|
||||
return 1.0;
|
||||
} else if (SHAPE_VON_KARMAN_OGIVE.equals(shape)) {
|
||||
return 0.0;
|
||||
} else if (SHAPE_POWER_LAW.equals(shape)) {
|
||||
return 0.0; // Not really needed, but just to be explicit (will be overwritten later)
|
||||
} else if (SHAPE_LVHAACK.equals(shape)) {
|
||||
return 0.33;
|
||||
} else if (SHAPE_PARABOLIC.equals(shape)) {
|
||||
return 0.5;
|
||||
} else if (SHAPE_ELLIPTICAL.equals(shape)) {
|
||||
return 0.0; // Not really needed, but just to be explicit
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
public static FinSet.CrossSection RASAERO_TO_OPENROCKET_FIN_CROSSSECTION(String crossSection, WarningSet warnings) {
|
||||
if (CROSS_SECTION_SQUARE.equals(crossSection)) {
|
||||
return FinSet.CrossSection.SQUARE;
|
||||
} else if (CROSS_SECTION_ROUNDED.equals(crossSection)) {
|
||||
return FinSet.CrossSection.ROUNDED;
|
||||
} else if (CROSS_SECTION_SUBSONIC_NACA.equals(crossSection)) {
|
||||
return FinSet.CrossSection.AIRFOIL;
|
||||
} else {
|
||||
String msg = "Unknown fin cross section: " + crossSection + ", defaulting to Airfoil.";
|
||||
warnings.add(msg);
|
||||
log.debug(msg);
|
||||
return FinSet.CrossSection.AIRFOIL;
|
||||
}
|
||||
}
|
||||
|
||||
public static String OPENROCKET_TO_RASAERO_FIN_CROSSSECTION(FinSet.CrossSection crossSection, WarningSet warnings) {
|
||||
if (FinSet.CrossSection.SQUARE.equals(crossSection)) {
|
||||
return CROSS_SECTION_SQUARE;
|
||||
} else if (FinSet.CrossSection.ROUNDED.equals(crossSection)) {
|
||||
return CROSS_SECTION_ROUNDED;
|
||||
} else if (FinSet.CrossSection.AIRFOIL.equals(crossSection)) {
|
||||
return CROSS_SECTION_SUBSONIC_NACA;
|
||||
} else {
|
||||
String msg = "Unknown fin cross section: " + crossSection + ".";
|
||||
warnings.add(msg);
|
||||
log.warn(msg);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ExternalComponent.Finish RASAERO_TO_OPENROCKET_SURFACE(String surfaceFinish, WarningSet warnings) {
|
||||
// NOTE: the RASAero surface finishes are not really the same as the OpenRocket surface finishes. There are some
|
||||
// approximations here.
|
||||
if (FINISH_SMOOTH.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.MIRROR;
|
||||
} else if (FINISH_POLISHED.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.FINISHPOLISHED;
|
||||
} else if (FINISH_SHEET_METAL.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.OPTIMUM;
|
||||
} else if (FINISH_SMOOTH_PAINT.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.OPTIMUM;
|
||||
} else if (FINISH_CAMOUFLAGE.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.SMOOTH;
|
||||
} else if (FINISH_ROUGH_CAMOUFLAGE.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.NORMAL;
|
||||
} else if (FINISH_GALVANIZED.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.UNFINISHED;
|
||||
} else if (FINISH_CAST_IRON.equals(surfaceFinish)) {
|
||||
return ExternalComponent.Finish.ROUGHUNFINISHED;
|
||||
} else {
|
||||
String msg = "Unknown surface finish: " + surfaceFinish + ", defaulting to Regular Paint.";
|
||||
warnings.add(msg);
|
||||
log.debug(msg);
|
||||
return ExternalComponent.Finish.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public static String OPENROCKET_TO_RASAERO_SURFACE(ExternalComponent.Finish finish, WarningSet warnings) {
|
||||
if (finish.equals(ExternalComponent.Finish.MIRROR)) {
|
||||
return FINISH_SMOOTH;
|
||||
} else if (finish.equals(ExternalComponent.Finish.FINISHPOLISHED)) {
|
||||
return FINISH_POLISHED;
|
||||
} else if (finish.equals(ExternalComponent.Finish.OPTIMUM)) {
|
||||
return FINISH_SHEET_METAL;
|
||||
} else if (finish.equals(ExternalComponent.Finish.SMOOTH)) {
|
||||
return FINISH_CAMOUFLAGE;
|
||||
} else if (finish.equals(ExternalComponent.Finish.NORMAL)) {
|
||||
return FINISH_ROUGH_CAMOUFLAGE;
|
||||
} else if (finish.equals(ExternalComponent.Finish.UNFINISHED)) {
|
||||
return FINISH_GALVANIZED;
|
||||
} else if (finish.equals(ExternalComponent.Finish.ROUGHUNFINISHED)) {
|
||||
return FINISH_CAST_IRON;
|
||||
} else {
|
||||
String msg = "Unknown surface finish: " + finish + ", defaulting to Smooth.";
|
||||
warnings.add(msg);
|
||||
log.debug(msg);
|
||||
return FINISH_SMOOTH;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an OpenRocket motor as a RASAero motor.
|
||||
* @param RASAeroMotors list of available RASAero motors
|
||||
* @param ORMotor OpenRocket motor
|
||||
* @return a RASAero String representation of a motor
|
||||
*/
|
||||
public static String OPENROCKET_TO_RASAERO_MOTOR(List<ThrustCurveMotor> RASAeroMotors, Motor ORMotor,
|
||||
WarningSet warnings) {
|
||||
if (!(ORMotor instanceof ThrustCurveMotor)) {
|
||||
log.debug("RASAero motor not found: not a thrust curve motor");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (ThrustCurveMotor RASAeroMotor : RASAeroMotors) {
|
||||
String RASAeroDesignation = AbstractMotorLoader.removeDelay(RASAeroMotor.getDesignation());
|
||||
if (ORMotor.getDesignation().equals(RASAeroDesignation) &&
|
||||
((ThrustCurveMotor) ORMotor).getManufacturer().matches(RASAeroMotor.getManufacturer().getDisplayName())) {
|
||||
String motorName = RASAeroMotor.getDesignation();
|
||||
log.debug(String.format("RASAero RASAeroMotor found: %s", motorName));
|
||||
return motorName + " (" + OPENROCKET_TO_RASAERO_MANUFACTURER(RASAeroMotor.getManufacturer()) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
String msg = String.format("Could not find RASAero motor for '%s'", ORMotor.getDesignation());
|
||||
warnings.add(msg);
|
||||
log.debug(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
} else if (DEPLOYMENT_APOGEE.equals(deployEvent)) {
|
||||
return DeploymentConfiguration.DeployEvent.APOGEE;
|
||||
} else if (DEPLOYMENT_ALTITUDE.equals(deployEvent)) {
|
||||
return DeploymentConfiguration.DeployEvent.ALTITUDE;
|
||||
}
|
||||
warnings.add("Unknown deployment event: " + deployEvent + ", defaulting to apogee.");
|
||||
return DeploymentConfiguration.DeployEvent.APOGEE;
|
||||
}
|
||||
|
||||
public static String OPENROCKET_TO_RASAERO_COLOR(Color color) {
|
||||
if (color != null) {
|
||||
if (color.equals(Color.BLACK)) {
|
||||
return "Black"; // Currently the only officially supported color by RASAero
|
||||
}
|
||||
}
|
||||
return "Blue"; // But we can also apply our own color hehe
|
||||
}
|
||||
|
||||
/**
|
||||
* Class containing the RASAero nose cone shape and shape parameter settings
|
||||
*/
|
||||
public static class NoseConeShapeSettings {
|
||||
private final String shape;
|
||||
private final Double shapeParameter;
|
||||
|
||||
public NoseConeShapeSettings(String shape, double shapeParameter) {
|
||||
this.shape = shape;
|
||||
this.shapeParameter = shapeParameter;
|
||||
}
|
||||
|
||||
public NoseConeShapeSettings(String shape) {
|
||||
this.shape = shape;
|
||||
this.shapeParameter = null;
|
||||
}
|
||||
|
||||
public String getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
public Double getShapeParameter() {
|
||||
return shapeParameter;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero;
|
||||
|
||||
import net.sf.openrocket.file.motor.GeneralMotorLoader;
|
||||
import net.sf.openrocket.file.motor.RASPMotorLoader;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.database.motor.ThrustCurveMotorSet;
|
||||
import net.sf.openrocket.file.motor.AbstractMotorLoader;
|
||||
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;
|
||||
|
||||
public abstract class RASAeroMotorsLoader {
|
||||
private static List<ThrustCurveMotor> allMotors = null;
|
||||
|
||||
/**
|
||||
* Returns a RASAero motor from the motor string of its RASAero file.
|
||||
* @param motorString The motor string of the RASAero file, e.g. "1/4A2 (AP)".
|
||||
* @param warnings The warning set to add import warnings to.
|
||||
* @return The motor, or null if not found.
|
||||
*/
|
||||
public static ThrustCurveMotor getMotorFromRASAero(String motorString, WarningSet warnings) {
|
||||
if (motorString == null) {
|
||||
return null;
|
||||
}
|
||||
if (allMotors == null) {
|
||||
loadAllMotors(warnings);
|
||||
}
|
||||
/*
|
||||
RASAero file motor strings are formatted as "<motorName> (<manufacturer>)"
|
||||
*/
|
||||
String[] split = motorString.split("\\s{2}");
|
||||
if (split.length != 2) {
|
||||
return null;
|
||||
}
|
||||
String motorName = AbstractMotorLoader.removeDelay(split[0]);
|
||||
String manufacturer = split[1].replaceAll("^\\(|\\)$", ""); // Remove beginning and ending parenthesis
|
||||
for (ThrustCurveMotor motor : allMotors) {
|
||||
if (motorName.equals(motor.getDesignation()) && motor.getManufacturer().matches(manufacturer)) {
|
||||
return motor;
|
||||
}
|
||||
}
|
||||
warnings.add("Could not find motor '" + motorString + "' in the OpenRocket motors database. Please add it manually.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method when you don't need the RASAero motors anymore to free memory.
|
||||
*/
|
||||
public static void clearAllMotors() {
|
||||
if (allMotors != null) {
|
||||
allMotors.clear();
|
||||
allMotors = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
*/
|
||||
public static List<ThrustCurveMotor> loadAllRASAeroMotors(WarningSet warnings) throws RuntimeException {
|
||||
List<ThrustCurveMotor> RASAeroMotors = new ArrayList<>();
|
||||
|
||||
RASPMotorLoader loader = new RASPMotorLoader();
|
||||
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
||||
String fileName = "RASAero_Motors.eng";
|
||||
InputStream is = classloader.getResourceAsStream("datafiles/thrustcurves/RASAero/" + fileName);
|
||||
if (is == null) {
|
||||
throw new RuntimeException("Could not find " + fileName);
|
||||
}
|
||||
try {
|
||||
List<ThrustCurveMotor.Builder> motors = loader.load(is, fileName, false);
|
||||
for (ThrustCurveMotor.Builder builder : motors) {
|
||||
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(WarningSet warnings) {
|
||||
allMotors = new ArrayList<>();
|
||||
List<ThrustCurveMotorSet> database = Application.getThrustCurveMotorSetDatabase().getMotorSets();
|
||||
for (ThrustCurveMotorSet set : database) {
|
||||
allMotors.addAll(set.getMotors());
|
||||
}
|
||||
//allMotors.addAll(loadAllRASAeroMotors(warnings));
|
||||
}
|
||||
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
/**
|
||||
* The base class for most RASAero components.
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlType(name="RASAeroBasePartDTO")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlTransient
|
||||
public class BasePartDTO {
|
||||
@XmlElement(name = RASAeroCommonConstants.PART_TYPE)
|
||||
private String partType;
|
||||
@XmlElement(name = RASAeroCommonConstants.LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double length;
|
||||
@XmlElement(name = RASAeroCommonConstants.DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double diameter;
|
||||
@XmlElement(name = RASAeroCommonConstants.LOCATION)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double location;
|
||||
@XmlElement(name = RASAeroCommonConstants.COLOR)
|
||||
private String color;
|
||||
|
||||
@XmlTransient
|
||||
private final RocketComponent component;
|
||||
@XmlTransient
|
||||
private final WarningSet warnings;
|
||||
@XmlTransient
|
||||
private final ErrorSet errors;
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public BasePartDTO() {
|
||||
this.component = null;
|
||||
this.warnings = null;
|
||||
this.errors = null;
|
||||
}
|
||||
|
||||
protected BasePartDTO(RocketComponent component, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
this.component = component;
|
||||
this.warnings = warnings;
|
||||
this.errors = errors;
|
||||
|
||||
if (component instanceof BodyTube) {
|
||||
setPartType(RASAeroCommonConstants.BODY_TUBE);
|
||||
setDiameter(((BodyTube) component).getOuterRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else if (component instanceof NoseCone) {
|
||||
setPartType(RASAeroCommonConstants.NOSE_CONE);
|
||||
NoseCone noseCone = (NoseCone) component;
|
||||
if (noseCone.isFlipped()) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.warning1"));
|
||||
}
|
||||
setDiameter(((NoseCone) component).getAftRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else if (component instanceof Transition) {
|
||||
setPartType(RASAeroCommonConstants.TRANSITION);
|
||||
// This is a bit strange: I would expect diameter to be the fore radius, since you also have a rearDiamter
|
||||
// field for transitions, but okay
|
||||
setDiameter(((Transition) component).getAftRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else if (component instanceof AxialStage) {
|
||||
setPartType(RASAeroCommonConstants.BOOSTER);
|
||||
AxialStage stage = (AxialStage) component;
|
||||
if (stage.getChildCount() == 0 || !(stage.getChild(0) instanceof BodyTube)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.warning2"));
|
||||
}
|
||||
setDiameter(stage.getBoundingRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error1"), component.getComponentName()));
|
||||
}
|
||||
|
||||
setLength(component.getLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setLocation(component.getAxialOffset(AxialMethod.ABSOLUTE) * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setColor(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_COLOR(component.getColor()));
|
||||
}
|
||||
|
||||
public String getPartType() {
|
||||
return partType;
|
||||
}
|
||||
|
||||
public void setPartType(String partType) {
|
||||
this.partType = partType;
|
||||
}
|
||||
|
||||
public Double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Double length) throws RASAeroExportException {
|
||||
if (MathUtil.equals(length, 0)) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error2"), component.getName()));
|
||||
}
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Double getDiameter() {
|
||||
return diameter;
|
||||
}
|
||||
|
||||
public void setDiameter(Double diameter) throws RASAeroExportException {
|
||||
if (MathUtil.equals(diameter, 0)) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error3"), component.getName()));
|
||||
}
|
||||
this.diameter = diameter;
|
||||
}
|
||||
|
||||
public Double getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Double location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.BOATTAIL)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class BoattailDTO extends TransitionDTO {
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public BoattailDTO() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BoattailDTO(Transition boattail, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
super(boattail, warnings, errors);
|
||||
|
||||
setPartType(RASAeroCommonConstants.BOATTAIL);
|
||||
}
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementRef;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.BODY_TUBE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(propOrder = {
|
||||
"partType",
|
||||
"length",
|
||||
"diameter",
|
||||
"launchLugDiameter",
|
||||
"launchLugLength",
|
||||
"railGuideDiameter",
|
||||
"railGuideHeight",
|
||||
"launchShoeArea",
|
||||
"location",
|
||||
"color",
|
||||
"boattailLength",
|
||||
"boattailRearDiameter",
|
||||
"boattailOffset",
|
||||
"overhang",
|
||||
"fin"
|
||||
})
|
||||
public class BodyTubeDTO extends BasePartDTO implements BodyTubeDTOAdapter {
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_LUG_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchLugDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_LUG_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchLugLength = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RAIL_GUIDE_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double railGuideDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RAIL_GUIDE_HEIGHT)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double railGuideHeight = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_SHOE_AREA)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchShoeArea = 0d; // Currently not available in OR
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.BOATTAIL_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double boattailLength = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOATTAIL_REAR_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double boattailRearDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOATTAIL_OFFSET)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double boattailOffset = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.OVERHANG)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double overhang = 0d;
|
||||
|
||||
@XmlElementRef(name = RASAeroCommonConstants.FIN, type = FinDTO.class)
|
||||
private FinDTO fin;
|
||||
|
||||
|
||||
@XmlTransient
|
||||
private final WarningSet warnings;
|
||||
@XmlTransient
|
||||
private final ErrorSet errors;
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public BodyTubeDTO() {
|
||||
this.warnings = null;
|
||||
this.errors = null;
|
||||
}
|
||||
|
||||
public BodyTubeDTO(BodyTube bodyTube, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
super(bodyTube, warnings, errors);
|
||||
this.warnings = warnings;
|
||||
this.errors = errors;
|
||||
applyBodyTubeSettings(bodyTube, warnings, errors);
|
||||
}
|
||||
|
||||
public Double getLaunchLugDiameter() {
|
||||
return launchLugDiameter;
|
||||
}
|
||||
|
||||
public void setLaunchLugDiameter(Double launchLugDiameter) throws RASAeroExportException {
|
||||
if (MathUtil.equals(launchLugDiameter, 0)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error4"));
|
||||
}
|
||||
this.launchLugDiameter = launchLugDiameter;
|
||||
}
|
||||
|
||||
public Double getLaunchLugLength() {
|
||||
return launchLugLength;
|
||||
}
|
||||
|
||||
public void setLaunchLugLength(Double launchLugLength) throws RASAeroExportException {
|
||||
if (MathUtil.equals(launchLugLength, 0)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error5"));
|
||||
}
|
||||
this.launchLugLength = launchLugLength;
|
||||
}
|
||||
|
||||
public Double getRailGuideDiameter() {
|
||||
return railGuideDiameter;
|
||||
}
|
||||
|
||||
public void setRailGuideDiameter(Double railGuideDiameter) throws RASAeroExportException {
|
||||
if (MathUtil.equals(railGuideDiameter, 0)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error6"));
|
||||
}
|
||||
this.railGuideDiameter = railGuideDiameter;
|
||||
}
|
||||
|
||||
public Double getRailGuideHeight() {
|
||||
return railGuideHeight;
|
||||
}
|
||||
|
||||
public void setRailGuideHeight(Double railGuideHeight) throws RASAeroExportException {
|
||||
if (MathUtil.equals(railGuideHeight, 0)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error7"));
|
||||
}
|
||||
this.railGuideHeight = railGuideHeight;
|
||||
}
|
||||
|
||||
public Double getLaunchShoeArea() {
|
||||
return launchShoeArea;
|
||||
}
|
||||
|
||||
public void setLaunchShoeArea(Double launchShoeArea) throws RASAeroExportException {
|
||||
if (MathUtil.equals(launchShoeArea, 0)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error8"));
|
||||
}
|
||||
this.launchShoeArea = launchShoeArea;
|
||||
}
|
||||
|
||||
public Double getBoattailLength() {
|
||||
return boattailLength;
|
||||
}
|
||||
|
||||
public void setBoattailLength(Double boattailLength) {
|
||||
this.boattailLength = boattailLength;
|
||||
}
|
||||
|
||||
public Double getBoattailRearDiameter() {
|
||||
return boattailRearDiameter;
|
||||
}
|
||||
|
||||
public void setBoattailRearDiameter(Double boattailRearDiameter) {
|
||||
this.boattailRearDiameter = boattailRearDiameter;
|
||||
}
|
||||
|
||||
public Double getBoattailOffset() {
|
||||
return boattailOffset;
|
||||
}
|
||||
|
||||
public void setBoattailOffset(Double boattailOffset) {
|
||||
this.boattailOffset = boattailOffset;
|
||||
}
|
||||
|
||||
public Double getOverhang() {
|
||||
return overhang;
|
||||
}
|
||||
|
||||
public void setOverhang(Double overhang) {
|
||||
this.overhang = overhang;
|
||||
}
|
||||
|
||||
public FinDTO getFin() {
|
||||
return fin;
|
||||
}
|
||||
|
||||
public void setFin(FinDTO fin) {
|
||||
this.fin = fin;
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
import net.sf.openrocket.rocketcomponent.RailButton;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
public interface BodyTubeDTOAdapter {
|
||||
@XmlTransient
|
||||
Translator trans = Application.getTranslator();
|
||||
|
||||
default void applyBodyTubeSettings(BodyTube bodyTube, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
for (RocketComponent child : bodyTube.getChildren()) {
|
||||
if (child instanceof TrapezoidFinSet) {
|
||||
setFin(new FinDTO((TrapezoidFinSet) child, warnings, errors));
|
||||
} else if (child instanceof LaunchLug) {
|
||||
if (!MathUtil.equals(getRailGuideDiameter(), 0) || !MathUtil.equals(getRailGuideHeight(), 0)) { // only one check on diameter or length should be sufficient, but just to be safe
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning3"), child.getName()));
|
||||
continue;
|
||||
}
|
||||
if (!MathUtil.equals(getLaunchShoeArea(), 0)) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning4"), child.getName()));
|
||||
continue;
|
||||
}
|
||||
|
||||
LaunchLug lug = (LaunchLug) child;
|
||||
setLaunchLugDiameter(lug.getOuterRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
if (lug.getInstanceCount() == 2) {
|
||||
setLaunchLugLength(lug.getLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning5"), lug.getName()));
|
||||
setLaunchLugLength(lug.getLength() * lug.getInstanceCount() / 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
}
|
||||
} else if (child instanceof RailButton) {
|
||||
if (!MathUtil.equals(getLaunchLugDiameter(), 0) || !MathUtil.equals(getLaunchLugLength(), 0)) { // only one check on diameter or length should be sufficient, but just to be safe
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning6"), child.getName()));
|
||||
continue;
|
||||
}
|
||||
if (!MathUtil.equals(getLaunchShoeArea(), 0)) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning7"), child.getName()));
|
||||
continue;
|
||||
}
|
||||
|
||||
RailButton button = (RailButton) child;
|
||||
setRailGuideDiameter(button.getOuterDiameter() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setRailGuideHeight(button.getTotalHeight() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
|
||||
if (button.getInstanceCount() != 2) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning8"), button.getName(), button.getInstanceCount()));
|
||||
}
|
||||
} else if (child instanceof Parachute) {
|
||||
// Do nothing, is handled by RecoveryDTO
|
||||
} else {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning9"), child.getComponentName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Double getLaunchLugDiameter();
|
||||
|
||||
void setLaunchLugDiameter(Double launchLugDiameter) throws RASAeroExportException;
|
||||
|
||||
Double getLaunchLugLength();
|
||||
|
||||
void setLaunchLugLength(Double launchLugLength) throws RASAeroExportException;
|
||||
|
||||
Double getRailGuideDiameter();
|
||||
|
||||
void setRailGuideDiameter(Double railGuideDiameter) throws RASAeroExportException;
|
||||
|
||||
Double getRailGuideHeight();
|
||||
|
||||
void setRailGuideHeight(Double railGuideHeight) throws RASAeroExportException;
|
||||
|
||||
Double getLaunchShoeArea();
|
||||
|
||||
void setLaunchShoeArea(Double launchShoeArea) throws RASAeroExportException;
|
||||
|
||||
Double getBoattailLength();
|
||||
|
||||
void setBoattailLength(Double boattailLength) throws RASAeroExportException;
|
||||
|
||||
Double getBoattailRearDiameter();
|
||||
|
||||
void setBoattailRearDiameter(Double boattailRearDiameter) throws RASAeroExportException;
|
||||
|
||||
FinDTO getFin();
|
||||
|
||||
void setFin(FinDTO fin);
|
||||
}
|
@ -1,369 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
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.XmlElementRef;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.BOOSTER)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class BoosterDTO implements BodyTubeDTOAdapter {
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.PART_TYPE)
|
||||
private String partType;
|
||||
@XmlElement(name = RASAeroCommonConstants.LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double length;
|
||||
@XmlElement(name = RASAeroCommonConstants.DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double diameter;
|
||||
@XmlElement(name = RASAeroCommonConstants.INSIDE_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double insideDiameter;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_LUG_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchLugDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_LUG_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchLugLength = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RAIL_GUIDE_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double railGuideDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RAIL_GUIDE_HEIGHT)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double railGuideHeight = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_SHOE_AREA)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double launchShoeArea = 0d; // Currently not available in OR
|
||||
@XmlElement(name = RASAeroCommonConstants.LOCATION)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double location;
|
||||
@XmlElement(name = RASAeroCommonConstants.COLOR)
|
||||
private String color;
|
||||
@XmlElement(name = RASAeroCommonConstants.SHOULDER_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double shoulderLength;
|
||||
@XmlElement(name = RASAeroCommonConstants.NOZZLE_EXIT_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double nozzleExitDiameter = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOATTAIL_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double boattailLength;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOATTAIL_REAR_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double boattailRearDiameter;
|
||||
|
||||
@XmlElementRef(name = RASAeroCommonConstants.FIN, type = FinDTO.class)
|
||||
private FinDTO fin;
|
||||
|
||||
|
||||
@XmlTransient
|
||||
private final RocketComponent component;
|
||||
@XmlTransient
|
||||
private final WarningSet warnings;
|
||||
@XmlTransient
|
||||
private final ErrorSet errors;
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
/**
|
||||
* We need a default, no-args constructor.
|
||||
*/
|
||||
public BoosterDTO() {
|
||||
this.component = null;
|
||||
this.warnings = null;
|
||||
this.errors = null;
|
||||
}
|
||||
|
||||
protected BoosterDTO(Rocket rocket, AxialStage stage, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
this.component = stage;
|
||||
this.warnings = warnings;
|
||||
this.errors = errors;
|
||||
|
||||
int stageNr = rocket.getChildPosition(stage); // Use this instead of stage.getStageNumber() in case there are parallel stages in the design
|
||||
if (stageNr != 1 && stageNr != 2) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error9"), stageNr, stage.getName()));
|
||||
}
|
||||
|
||||
if (stage.getChildCount() == 0) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error10"), stage.getName()));
|
||||
}
|
||||
|
||||
RocketComponent firstChild = stage.getChild(0);
|
||||
if (!(firstChild instanceof BodyTube) &&
|
||||
!(firstChild instanceof Transition && !(firstChild instanceof NoseCone))) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error11"), stage.getName()));
|
||||
}
|
||||
|
||||
final BodyTube firstTube;
|
||||
if (firstChild instanceof Transition) {
|
||||
if (stage.getChildCount() == 1 || !(stage.getChild(1) instanceof BodyTube)) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error12"), stage.getName()));
|
||||
}
|
||||
|
||||
Transition transition = (Transition) firstChild;
|
||||
SymmetricComponent previousComponent = transition.getPreviousSymmetricComponent();
|
||||
if (previousComponent == null) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error13"),
|
||||
firstChild.getName(), stage.getName()));
|
||||
}
|
||||
|
||||
if (!MathUtil.equals(transition.getForeRadius(), previousComponent.getAftRadius())) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error14"),
|
||||
transition.getName(), stage.getName(), previousComponent.getName()));
|
||||
}
|
||||
|
||||
firstTube = (BodyTube) stage.getChild(1);
|
||||
if (!MathUtil.equals(firstTube.getOuterRadius(), transition.getAftRadius())) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error15"),
|
||||
firstTube.getName(), stage.getName(), transition.getName()));
|
||||
}
|
||||
|
||||
setShoulderLength(firstChild.getLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setDiameter(firstTube.getOuterRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setInsideDiameter(transition.getForeRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
} else {
|
||||
firstTube = (BodyTube) stage.getChild(0);
|
||||
}
|
||||
|
||||
TrapezoidFinSet finSet = getFinSetFromBodyTube(firstTube);
|
||||
|
||||
double tubeLength = firstTube.getLength();
|
||||
double finLocationOffset = 0;
|
||||
// Aggregate same-sized body tubes
|
||||
for (int i = stage.getChildPosition(firstTube) + 1; i < stage.getChildCount(); i++) {
|
||||
RocketComponent comp = stage.getChild(i);
|
||||
if (comp instanceof BodyTube &&
|
||||
MathUtil.equals(((BodyTube) comp).getOuterRadius(), firstTube.getOuterRadius())) {
|
||||
// Aggregate the tubes by combining the lengths
|
||||
tubeLength += comp.getLength();
|
||||
|
||||
// If no fin set in firstTube, add fin from new tube
|
||||
if (finSet == null) {
|
||||
finSet = getFinSetFromBodyTube((BodyTube) comp);
|
||||
}
|
||||
// We need an offset to the fin location, since the fin axial offset is referenced to its parent tube,
|
||||
// which can be different from the bottom of the aggregate tubes
|
||||
else {
|
||||
finLocationOffset += comp.getLength();
|
||||
}
|
||||
} else {
|
||||
// If this booster is the last stage, and the last component is a transition, it could be a boattail
|
||||
boolean isBoattail = (comp instanceof Transition && !(comp instanceof NoseCone)) && i == stage.getChildCount() - 1;
|
||||
if (stageNr == rocket.getChildCount() - 1 && isBoattail) {
|
||||
Transition transition = (Transition) comp;
|
||||
setBoattailLength(transition.getLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setBoattailRearDiameter(transition.getAftRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
break;
|
||||
}
|
||||
|
||||
String msg = String.format(trans.get("RASAeroExport.error31"), stage.getName());
|
||||
|
||||
if (isBoattail) {
|
||||
msg = "<html>" + msg + "<br> " + trans.get("RASAeroExport.error32") + "</html>";
|
||||
}
|
||||
|
||||
errors.add(msg);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
applyBodyTubeSettings(firstTube, warnings, errors);
|
||||
|
||||
if (finSet == null) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error16"),
|
||||
firstTube.getName(), stage.getName()));
|
||||
}
|
||||
FinDTO finDTO = new FinDTO(finSet, warnings, errors);
|
||||
double finLocation = finDTO.getLocation();
|
||||
finDTO.setLocation(finLocation + finLocationOffset * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setFin(finDTO);
|
||||
|
||||
setPartType(RASAeroCommonConstants.BOOSTER);
|
||||
setLength(tubeLength * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setDiameter(firstTube.getOuterRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setLocation(firstChild.getAxialOffset(AxialMethod.ABSOLUTE) * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setColor(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_COLOR(firstTube.getColor()));
|
||||
}
|
||||
|
||||
private TrapezoidFinSet getFinSetFromBodyTube(BodyTube bodyTube) {
|
||||
for (RocketComponent child : bodyTube.getChildren()) {
|
||||
if (child instanceof TrapezoidFinSet) {
|
||||
return (TrapezoidFinSet) child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getPartType() {
|
||||
return partType;
|
||||
}
|
||||
|
||||
public void setPartType(String partType) {
|
||||
this.partType = partType;
|
||||
}
|
||||
|
||||
public Double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Double length) {
|
||||
if (MathUtil.equals(length, 0)) {
|
||||
errors.add(String.format(trans.get("RASAeroExport.error17"), component.getName()));
|
||||
return;
|
||||
}
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Double getDiameter() {
|
||||
return diameter;
|
||||
}
|
||||
|
||||
public void setDiameter(Double diameter) throws RASAeroExportException {
|
||||
if (MathUtil.equals(diameter, 0)) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error18"), component.getName()));
|
||||
}
|
||||
this.diameter = diameter;
|
||||
}
|
||||
|
||||
public Double getInsideDiameter() {
|
||||
return insideDiameter;
|
||||
}
|
||||
|
||||
public void setInsideDiameter(Double insideDiameter) throws RASAeroExportException {
|
||||
if (MathUtil.equals(insideDiameter, 0)) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error19"), component.getName()));
|
||||
}
|
||||
this.insideDiameter = insideDiameter;
|
||||
}
|
||||
|
||||
public Double getLaunchLugDiameter() {
|
||||
return launchLugDiameter;
|
||||
}
|
||||
|
||||
public void setLaunchLugDiameter(Double launchLugDiameter) {
|
||||
this.launchLugDiameter = launchLugDiameter;
|
||||
}
|
||||
|
||||
public Double getLaunchLugLength() {
|
||||
return launchLugLength;
|
||||
}
|
||||
|
||||
public void setLaunchLugLength(Double launchLugLength) {
|
||||
this.launchLugLength = launchLugLength;
|
||||
}
|
||||
|
||||
public Double getRailGuideDiameter() {
|
||||
return railGuideDiameter;
|
||||
}
|
||||
|
||||
public void setRailGuideDiameter(Double railGuideDiameter) {
|
||||
this.railGuideDiameter = railGuideDiameter;
|
||||
}
|
||||
|
||||
public Double getRailGuideHeight() {
|
||||
return railGuideHeight;
|
||||
}
|
||||
|
||||
public void setRailGuideHeight(Double railGuideHeight) {
|
||||
this.railGuideHeight = railGuideHeight;
|
||||
}
|
||||
|
||||
public Double getLaunchShoeArea() {
|
||||
return launchShoeArea;
|
||||
}
|
||||
|
||||
public void setLaunchShoeArea(Double launchShoeArea) {
|
||||
this.launchShoeArea = launchShoeArea;
|
||||
}
|
||||
|
||||
public Double getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Double location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Double getShoulderLength() {
|
||||
return shoulderLength;
|
||||
}
|
||||
|
||||
public void setShoulderLength(Double shoulderLength) {
|
||||
this.shoulderLength = shoulderLength;
|
||||
}
|
||||
|
||||
public Double getNozzleExitDiameter() {
|
||||
return nozzleExitDiameter;
|
||||
}
|
||||
|
||||
public void setNozzleExitDiameter(Double nozzleExitDiameter) {
|
||||
this.nozzleExitDiameter = nozzleExitDiameter;
|
||||
}
|
||||
|
||||
public Double getBoattailLength() {
|
||||
return boattailLength;
|
||||
}
|
||||
|
||||
public void setBoattailLength(Double boattailLength) throws RASAeroExportException {
|
||||
if (boattailLength == 0) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error29"));
|
||||
}
|
||||
this.boattailLength = boattailLength;
|
||||
}
|
||||
|
||||
public Double getBoattailRearDiameter() {
|
||||
return boattailRearDiameter;
|
||||
}
|
||||
|
||||
public void setBoattailRearDiameter(Double boattailRearDiameter) throws RASAeroExportException {
|
||||
if (boattailRearDiameter == 0) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error30"));
|
||||
}
|
||||
this.boattailRearDiameter = boattailRearDiameter;
|
||||
}
|
||||
|
||||
public FinDTO getFin() {
|
||||
return fin;
|
||||
}
|
||||
|
||||
public void setFin(FinDTO fin) {
|
||||
this.fin = fin;
|
||||
}
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
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.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.FIN)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class FinDTO {
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_COUNT)
|
||||
private int count;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_CHORD)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double chord;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_SPAN)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double span;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_SWEEP_DISTANCE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double sweepDistance;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_TIP_CHORD)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double tipChord;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_THICKNESS)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double thickness;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_LE_RADIUS)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double LERadius = 0d; // Leading edge radius
|
||||
@XmlElement(name = RASAeroCommonConstants.LOCATION)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double location;
|
||||
@XmlElement(name = RASAeroCommonConstants.AIRFOIL_SECTION)
|
||||
private String airfoilSection;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_FX1)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double FX1 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.FIN_FX3)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double FX3 = 0d;
|
||||
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public FinDTO() {
|
||||
}
|
||||
|
||||
public FinDTO(TrapezoidFinSet fin, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
int finCount = fin.getFinCount();
|
||||
if (finCount < 3 || finCount > 8) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error20"), fin.getName()));
|
||||
}
|
||||
|
||||
setCount(fin.getFinCount());
|
||||
setChord(fin.getRootChord() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setTipChord(fin.getTipChord() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setSpan(fin.getSpan() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setSweepDistance(fin.getSweep() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setThickness(fin.getThickness() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setAirfoilSection(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_FIN_CROSSSECTION(fin.getCrossSection(), warnings));
|
||||
setLocation((-fin.getAxialOffset(AxialMethod.BOTTOM) + fin.getLength()) * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Double getChord() {
|
||||
return chord;
|
||||
}
|
||||
|
||||
public void setChord(Double chord) {
|
||||
this.chord = chord;
|
||||
}
|
||||
|
||||
public Double getSpan() {
|
||||
return span;
|
||||
}
|
||||
|
||||
public void setSpan(Double span) {
|
||||
this.span = span;
|
||||
}
|
||||
|
||||
public Double getSweepDistance() {
|
||||
return sweepDistance;
|
||||
}
|
||||
|
||||
public void setSweepDistance(Double sweepDistance) {
|
||||
this.sweepDistance = sweepDistance;
|
||||
}
|
||||
|
||||
public Double getTipChord() {
|
||||
return tipChord;
|
||||
}
|
||||
|
||||
public void setTipChord(Double tipChord) {
|
||||
this.tipChord = tipChord;
|
||||
}
|
||||
|
||||
public Double getThickness() {
|
||||
return thickness;
|
||||
}
|
||||
|
||||
public void setThickness(Double thickness) {
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
public Double getLERadius() {
|
||||
return LERadius;
|
||||
}
|
||||
|
||||
public void setLERadius(Double LERadius) {
|
||||
this.LERadius = LERadius;
|
||||
}
|
||||
|
||||
public Double getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Double location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getAirfoilSection() {
|
||||
return airfoilSection;
|
||||
}
|
||||
|
||||
public void setAirfoilSection(String airfoilSection) {
|
||||
this.airfoilSection = airfoilSection;
|
||||
}
|
||||
|
||||
public Double getFX1() {
|
||||
return FX1;
|
||||
}
|
||||
|
||||
public void setFX1(Double FX1) {
|
||||
this.FX1 = FX1;
|
||||
}
|
||||
|
||||
public Double getFX3() {
|
||||
return FX3;
|
||||
}
|
||||
|
||||
public void setFX3(Double FX3) {
|
||||
this.FX3 = FX3;
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
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.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.simulation.SimulationOptions;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Preferences;
|
||||
|
||||
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;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.LAUNCH_SITE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class LaunchSiteDTO {
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_ALTITUDE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double altitude = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_PRESSURE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double pressure = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_ROD_ANGLE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double rodAngle = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_ROD_LENGTH)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double rodLength = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_TEMPERATURE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double temperature = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_WIND_SPEED)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double windSpeed = 0d;
|
||||
|
||||
/**
|
||||
* We need a default, no-args constructor.
|
||||
*/
|
||||
public LaunchSiteDTO() {
|
||||
}
|
||||
|
||||
public LaunchSiteDTO(OpenRocketDocument document, WarningSet warnings, ErrorSet errors) {
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
SimulationOptions options = sim.getSimulatedConditions();
|
||||
if (options == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
setAltitude(options.getLaunchAltitude() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ALTITUDE);
|
||||
setPressure(options.getLaunchPressure() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_PRESSURE);
|
||||
setTemperature(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_TEMPERATURE(options.getLaunchTemperature()));
|
||||
setRodAngle(options.getLaunchRodAngle() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ANGLE);
|
||||
setRodLength(options.getLaunchRodLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setWindSpeed(options.getWindSpeedAverage() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_SPEED);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we can't get settings from the sims, use the launch site settings from the preferences
|
||||
Preferences prefs = Application.getPreferences();
|
||||
setAltitude(prefs.getLaunchAltitude() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ALTITUDE);
|
||||
setPressure(prefs.getLaunchPressure() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_PRESSURE);
|
||||
setTemperature(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_TEMPERATURE(prefs.getLaunchTemperature()));
|
||||
setRodAngle(prefs.getLaunchRodAngle() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ANGLE);
|
||||
setRodLength(prefs.getLaunchRodLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
setWindSpeed(prefs.getWindSpeedAverage() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_SPEED);
|
||||
}
|
||||
|
||||
public Double getAltitude() {
|
||||
return altitude;
|
||||
}
|
||||
|
||||
public void setAltitude(Double altitude) {
|
||||
this.altitude = altitude;
|
||||
}
|
||||
|
||||
public Double getPressure() {
|
||||
return pressure;
|
||||
}
|
||||
|
||||
public void setPressure(Double pressure) {
|
||||
this.pressure = pressure;
|
||||
}
|
||||
|
||||
public Double getRodAngle() {
|
||||
return rodAngle;
|
||||
}
|
||||
|
||||
public void setRodAngle(Double rodAngle) {
|
||||
this.rodAngle = rodAngle;
|
||||
}
|
||||
|
||||
public Double getRodLength() {
|
||||
return rodLength;
|
||||
}
|
||||
|
||||
public void setRodLength(Double rodLength) {
|
||||
this.rodLength = rodLength;
|
||||
}
|
||||
|
||||
public Double getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(Double temperature) {
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
public Double getWindSpeed() {
|
||||
return windSpeed;
|
||||
}
|
||||
|
||||
public void setWindSpeed(Double windSpeed) {
|
||||
this.windSpeed = windSpeed;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
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.rocketcomponent.NoseCone;
|
||||
|
||||
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.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants.NoseConeShapeSettings;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.NOSE_CONE)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(propOrder = {
|
||||
"partType",
|
||||
"length",
|
||||
"diameter",
|
||||
"shape",
|
||||
"bluntRadius",
|
||||
"location",
|
||||
"color",
|
||||
"powerLaw"
|
||||
})
|
||||
public class NoseConeDTO extends BasePartDTO {
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.SHAPE)
|
||||
private String shape;
|
||||
@XmlElement(name = RASAeroCommonConstants.BLUNT_RADIUS)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double bluntRadius = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.POWER_LAW)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double powerLaw;
|
||||
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public NoseConeDTO() {
|
||||
}
|
||||
|
||||
public NoseConeDTO(NoseCone noseCone, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
super(noseCone, warnings, errors);
|
||||
|
||||
NoseConeShapeSettings shapeSettings =
|
||||
RASAeroCommonConstants.OPENROCKET_TO_RASAERO_SHAPE(noseCone.getShapeType(), noseCone.getShapeParameter());
|
||||
|
||||
setShape(shapeSettings.getShape());
|
||||
Double shapeParameter = shapeSettings.getShapeParameter();
|
||||
if (shapeParameter != null) {
|
||||
setPowerLaw(shapeParameter);
|
||||
}
|
||||
}
|
||||
|
||||
public String getShape() {
|
||||
return shape;
|
||||
}
|
||||
|
||||
public void setShape(String shape) {
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
public Double getPowerLaw() {
|
||||
return powerLaw;
|
||||
}
|
||||
|
||||
public void setPowerLaw(Double powerLaw) {
|
||||
this.powerLaw = powerLaw;
|
||||
}
|
||||
|
||||
public double getBluntRadius() {
|
||||
return bluntRadius;
|
||||
}
|
||||
|
||||
public void setBluntRadius(double bluntRadius) {
|
||||
this.bluntRadius = bluntRadius;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
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.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* The top level RASAero document.
|
||||
*/
|
||||
@XmlRootElement(name = RASAeroCommonConstants.RASAERO_DOCUMENT)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RASAeroDocumentDTO {
|
||||
@XmlElement(name = RASAeroCommonConstants.FILE_VERSION)
|
||||
private final String version = "2";
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.ROCKET_DESIGN)
|
||||
private RocketDesignDTO design;
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.LAUNCH_SITE)
|
||||
private LaunchSiteDTO launchSite;
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY)
|
||||
private RecoveryDTO recovery;
|
||||
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.MACH_ALT)
|
||||
private String machAlt = ""; // Currently not implemented
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.SIMULATION_LIST)
|
||||
private SimulationListDTO simulationList = null;
|
||||
|
||||
/**
|
||||
* Get the subordinate design DTO.
|
||||
*
|
||||
* @return the RocketDesignDTO
|
||||
*/
|
||||
public RocketDesignDTO getDesign() {
|
||||
return design;
|
||||
}
|
||||
|
||||
public void setDesign(RocketDesignDTO theDesign) {
|
||||
this.design = theDesign;
|
||||
}
|
||||
|
||||
public LaunchSiteDTO getLaunchSite() {
|
||||
return launchSite;
|
||||
}
|
||||
|
||||
public void setLaunchSite(LaunchSiteDTO launchSite) {
|
||||
this.launchSite = launchSite;
|
||||
}
|
||||
|
||||
public RecoveryDTO getRecovery() {
|
||||
return recovery;
|
||||
}
|
||||
|
||||
public void setRecovery(RecoveryDTO recovery) {
|
||||
this.recovery = recovery;
|
||||
}
|
||||
|
||||
public SimulationListDTO getSimulationList() {
|
||||
return simulationList;
|
||||
}
|
||||
|
||||
public void setSimulationList(SimulationListDTO simulationList) {
|
||||
this.simulationList = simulationList;
|
||||
}
|
||||
|
||||
public String getMachAlt() {
|
||||
return this.machAlt;
|
||||
}
|
||||
|
||||
public void setMachAlt(String machAlt) {
|
||||
this.machAlt = machAlt;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.StorageOptions;
|
||||
import net.sf.openrocket.file.RocketSaver;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* This class is responsible for marshalling an OpenRocketDocument (OR design) to RASAero-compliant XML.
|
||||
* Big thanks to hcraigmiller for testing and providing feedback.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class RASAeroSaver extends RocketSaver {
|
||||
/**
|
||||
* The logger.
|
||||
*/
|
||||
private static final Logger log = LoggerFactory.getLogger(RASAeroSaver.class);
|
||||
|
||||
public static class RASAeroExportException extends Exception {
|
||||
public RASAeroExportException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method marshals an OpenRocketDocument (OR design) to RASAero-compliant XML.
|
||||
*
|
||||
* @param doc the OR design
|
||||
* @return RASAero-compliant XML
|
||||
*/
|
||||
public String marshalToRASAero(OpenRocketDocument doc, WarningSet warnings, ErrorSet errors) {
|
||||
try {
|
||||
JAXBContext binder = JAXBContext.newInstance(RASAeroDocumentDTO.class);
|
||||
Marshaller marshaller = binder.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||
StringWriter sw = new StringWriter();
|
||||
|
||||
marshaller.marshal(toRASAeroDocumentDTO(doc, warnings, errors), sw);
|
||||
return sw.toString();
|
||||
} catch (RASAeroExportException e) {
|
||||
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());
|
||||
}
|
||||
|
||||
throw new RuntimeException("Could not marshall a design to RASAero format.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(OutputStream dest, OpenRocketDocument doc, StorageOptions options, WarningSet warnings, ErrorSet errors) throws IOException {
|
||||
log.info("Saving .CDX1 file");
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, StandardCharsets.UTF_8));
|
||||
writer.write(marshalToRASAero(doc, warnings, errors));
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateFileSize(OpenRocketDocument doc, StorageOptions options) {
|
||||
return marshalToRASAero(doc, new WarningSet(), new ErrorSet()).length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Root conversion method. It iterates over all subcomponents.
|
||||
*
|
||||
* @param doc the OR design
|
||||
* @param warnings list to add export warnings to
|
||||
* @param errors list to add export errors to
|
||||
* @return a corresponding RASAero representation
|
||||
*/
|
||||
private RASAeroDocumentDTO toRASAeroDocumentDTO(OpenRocketDocument doc, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
RASAeroDocumentDTO rad = new RASAeroDocumentDTO();
|
||||
rad.setDesign(toRocketDesignDTO(doc.getRocket(), warnings, errors));
|
||||
rad.setLaunchSite(toLaunchSiteDTO(doc, warnings, errors));
|
||||
rad.setRecovery(toRecoveryDTO(doc.getRocket(), warnings, errors));
|
||||
rad.setSimulationList(toSimulationListDTO(doc, warnings, errors));
|
||||
|
||||
return rad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the RASAero rocket design (containing all the actual rocket components).
|
||||
* @param rocket the OR rocket to export the components from
|
||||
* @return the RASAero rocket design
|
||||
*/
|
||||
private RocketDesignDTO toRocketDesignDTO(Rocket rocket, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
return new RocketDesignDTO(rocket, warnings, errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create RASAero launch site settings.
|
||||
* @param document document that contains simulations to take the launch site settings from
|
||||
* @param warnings list to add export warnings to
|
||||
* @param errors list to add export errors to
|
||||
* @return the RASAero launch site settings
|
||||
*/
|
||||
private LaunchSiteDTO toLaunchSiteDTO(OpenRocketDocument document, WarningSet warnings, ErrorSet errors) {
|
||||
return new LaunchSiteDTO(document, warnings, errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create RASAero recovery settings.
|
||||
* @param rocket rocket to fetch the recovery devices from
|
||||
* @param warnings list to add export warnings to
|
||||
* @param errors list to add export errors to
|
||||
* @return the RASAero launch site settings
|
||||
*/
|
||||
private RecoveryDTO toRecoveryDTO(Rocket rocket, WarningSet warnings, ErrorSet errors) {
|
||||
return new RecoveryDTO(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);
|
||||
}
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
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.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.RECOVERY)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RecoveryDTO {
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_ALTITUDE + 1)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double altitude1 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_ALTITUDE + 2)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double altitude2 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_DEVICE_TYPE + 1)
|
||||
private String deviceType1 = "None";
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_DEVICE_TYPE + 2)
|
||||
private String deviceType2 = "None";
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_EVENT + 1)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean event1 = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_EVENT + 2)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean event2 = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_SIZE + 1)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double size1 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_SIZE + 2)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double size2 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_EVENT_TYPE + 1)
|
||||
private String eventType1 = "None";
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_EVENT_TYPE + 2)
|
||||
private String eventType2 = "None";
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_CD + 1)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double CD1 = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.RECOVERY_CD + 2)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double CD2 = 0d;
|
||||
|
||||
|
||||
@XmlTransient
|
||||
private static final Logger log = LoggerFactory.getLogger(RecoveryDTO.class);
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* We need a default, no-args constructor.
|
||||
*/
|
||||
public RecoveryDTO() {
|
||||
}
|
||||
|
||||
public RecoveryDTO(Rocket rocket, WarningSet warnings, ErrorSet errors) {
|
||||
List<Parachute> parachutes = getParachutesFromRocket(rocket);
|
||||
|
||||
switch (parachutes.size()) {
|
||||
case 0:
|
||||
log.debug("No parachutes present");
|
||||
break;
|
||||
case 1:
|
||||
configureRecoveryDevice1(parachutes.get(0), errors);
|
||||
break;
|
||||
case 2:
|
||||
configureRecoveryDevice1(parachutes.get(0), errors);
|
||||
configureRecoveryDevice2(parachutes.get(1), errors);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Parachute> getParachutesFromRocket(Rocket rocket) {
|
||||
List<Parachute> parachutes = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < Math.min(rocket.getChildCount(), 3); i++) {
|
||||
AxialStage stage = (AxialStage) rocket.getChild(i);
|
||||
|
||||
for (RocketComponent stageChild : stage.getChildren()) {
|
||||
if (stageChild instanceof BodyTube) {
|
||||
for (RocketComponent child : stageChild) {
|
||||
if (child instanceof Parachute) {
|
||||
parachutes.add((Parachute) child);
|
||||
if (parachutes.size() == 2) {
|
||||
return parachutes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parachutes;
|
||||
}
|
||||
|
||||
private void configureRecoveryDevice1(Parachute device1, ErrorSet errors) {
|
||||
setCD1(device1.getCD());
|
||||
setDeviceType1("Parachute");
|
||||
DeploymentConfiguration deployConfig = device1.getDeploymentConfigurations().getDefault();
|
||||
setAltitude1(deployConfig.getDeployAltitude() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ALTITUDE);
|
||||
if (deployConfig.getDeployEvent() == DeploymentConfiguration.DeployEvent.APOGEE) {
|
||||
setEventType1(RASAeroCommonConstants.DEPLOYMENT_APOGEE);
|
||||
} else if (deployConfig.getDeployEvent() == DeploymentConfiguration.DeployEvent.ALTITUDE) {
|
||||
setEventType1(RASAeroCommonConstants.RECOVERY_ALTITUDE);
|
||||
} else {
|
||||
errors.add(String.format(trans.get("RASAeroExport.error21"),
|
||||
device1.getName(), deployConfig.getDeployEvent().toString()));
|
||||
}
|
||||
setEvent1(true);
|
||||
setSize1(device1.getDiameter() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
}
|
||||
|
||||
private void configureRecoveryDevice2(Parachute device2, ErrorSet errors) {
|
||||
setCD1(device2.getCD());
|
||||
setDeviceType2("Parachute");
|
||||
DeploymentConfiguration deployConfig = device2.getDeploymentConfigurations().getDefault();
|
||||
setAltitude2(deployConfig.getDeployAltitude() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_ALTITUDE);
|
||||
if (deployConfig.getDeployEvent() == DeploymentConfiguration.DeployEvent.APOGEE) {
|
||||
setEventType2(RASAeroCommonConstants.DEPLOYMENT_APOGEE);
|
||||
} else if (deployConfig.getDeployEvent() == DeploymentConfiguration.DeployEvent.ALTITUDE) {
|
||||
setEventType2(RASAeroCommonConstants.RECOVERY_ALTITUDE);
|
||||
} else {
|
||||
errors.add(String.format(trans.get("RASAeroExport.error21"),
|
||||
device2.getName(), deployConfig.getDeployEvent().toString()));
|
||||
}
|
||||
setEvent2(true);
|
||||
setSize2(device2.getDiameter() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
}
|
||||
|
||||
public Double getAltitude1() {
|
||||
return altitude1;
|
||||
}
|
||||
|
||||
public void setAltitude1(Double altitude1) {
|
||||
this.altitude1 = altitude1;
|
||||
}
|
||||
|
||||
public Double getAltitude2() {
|
||||
return altitude2;
|
||||
}
|
||||
|
||||
public void setAltitude2(Double altitude2) {
|
||||
this.altitude2 = altitude2;
|
||||
}
|
||||
|
||||
public String getDeviceType1() {
|
||||
return deviceType1;
|
||||
}
|
||||
|
||||
public void setDeviceType1(String deviceType1) {
|
||||
this.deviceType1 = deviceType1;
|
||||
}
|
||||
|
||||
public String getDeviceType2() {
|
||||
return deviceType2;
|
||||
}
|
||||
|
||||
public void setDeviceType2(String deviceType2) {
|
||||
this.deviceType2 = deviceType2;
|
||||
}
|
||||
|
||||
public Boolean getEvent1() {
|
||||
return event1;
|
||||
}
|
||||
|
||||
public void setEvent1(Boolean event1) {
|
||||
this.event1 = event1;
|
||||
}
|
||||
|
||||
public Boolean getEvent2() {
|
||||
return event2;
|
||||
}
|
||||
|
||||
public void setEvent2(Boolean event2) {
|
||||
this.event2 = event2;
|
||||
}
|
||||
|
||||
public Double getSize1() {
|
||||
return size1;
|
||||
}
|
||||
|
||||
public void setSize1(Double size1) {
|
||||
this.size1 = size1;
|
||||
}
|
||||
|
||||
public Double getSize2() {
|
||||
return size2;
|
||||
}
|
||||
|
||||
public void setSize2(Double size2) {
|
||||
this.size2 = size2;
|
||||
}
|
||||
|
||||
public String getEventType1() {
|
||||
return eventType1;
|
||||
}
|
||||
|
||||
public void setEventType1(String eventType1) {
|
||||
this.eventType1 = eventType1;
|
||||
}
|
||||
|
||||
public String getEventType2() {
|
||||
return eventType2;
|
||||
}
|
||||
|
||||
public void setEventType2(String eventType2) {
|
||||
this.eventType2 = eventType2;
|
||||
}
|
||||
|
||||
public Double getCD1() {
|
||||
return CD1;
|
||||
}
|
||||
|
||||
public void setCD1(Double CD1) {
|
||||
this.CD1 = CD1;
|
||||
}
|
||||
|
||||
public Double getCD2() {
|
||||
return CD2;
|
||||
}
|
||||
|
||||
public void setCD2(Double CD2) {
|
||||
this.CD2 = CD2;
|
||||
}
|
||||
}
|
@ -1,229 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
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.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementRef;
|
||||
import javax.xml.bind.annotation.XmlElementRefs;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class RocketDesignDTO {
|
||||
@XmlElementRefs({
|
||||
@XmlElementRef(name = RASAeroCommonConstants.BODY_TUBE, type = BodyTubeDTO.class),
|
||||
@XmlElementRef(name = RASAeroCommonConstants.NOSE_CONE, type = NoseConeDTO.class),
|
||||
@XmlElementRef(name = RASAeroCommonConstants.TRANSITION, type = TransitionDTO.class),
|
||||
@XmlElementRef(name = RASAeroCommonConstants.BOOSTER, type = BoosterDTO.class)
|
||||
})
|
||||
private final List<BasePartDTO> externalPart = new ArrayList<>();
|
||||
|
||||
@XmlElementRefs({
|
||||
@XmlElementRef(name = RASAeroCommonConstants.BOOSTER, type = BoosterDTO.class),
|
||||
})
|
||||
private final List<BoosterDTO> boosters = new ArrayList<>();
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.SURFACE_FINISH)
|
||||
private String surface = RASAeroCommonConstants.FINISH_SMOOTH;
|
||||
@XmlElement(name = RASAeroCommonConstants.CD)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double CD = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.MODIFIED_BARROWMAN)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean modifiedBarrowman = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.TURBULENCE)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean turbulence = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.SUSTAINER_NOZZLE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double sustainerNozzle = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOOSTER1_NOZZLE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double booster1Nozzle = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.BOOSTER2_NOZZLE)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double booster2Nozzle = 0d;
|
||||
@XmlElement(name = RASAeroCommonConstants.USE_BOOSTER1)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean useBooster1 = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.USE_BOOSTER2)
|
||||
@XmlJavaTypeAdapter(CustomBooleanAdapter.class)
|
||||
private Boolean useBooster2 = false;
|
||||
@XmlElement(name = RASAeroCommonConstants.COMMENTS)
|
||||
private String comments = "";
|
||||
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
public RocketDesignDTO(Rocket rocket, WarningSet warnings, ErrorSet errors) {
|
||||
setComments(rocket.getComment());
|
||||
if (rocket.getChildCount() > 3) {
|
||||
warnings.add(trans.get("RASAeroExport.warning10"));
|
||||
}
|
||||
setUseBooster1(rocket.getChildCount() >= 2);
|
||||
setUseBooster2(rocket.getChildCount() == 3);
|
||||
|
||||
AxialStage sustainer = rocket.getStage(0);
|
||||
|
||||
// Export components from sustainer
|
||||
for (int i = 0; i < sustainer.getChildCount(); i++) {
|
||||
try {
|
||||
RocketComponent component = sustainer.getChild(i);
|
||||
if (i == 0 && !(component instanceof NoseCone)) {
|
||||
errors.add(trans.get("RASAeroExport.error22"));
|
||||
return;
|
||||
} else if (i == 1 && !(component instanceof BodyTube ||
|
||||
(component instanceof Transition && !(component instanceof NoseCone) && (i == sustainer.getChildCount() - 1)))) {
|
||||
errors.add(trans.get("RASAeroExport.error23"));
|
||||
return;
|
||||
}
|
||||
if (component instanceof BodyTube) {
|
||||
addExternalPart(new BodyTubeDTO((BodyTube) component, warnings, errors));
|
||||
} else if (component instanceof NoseCone) {
|
||||
if (i != 0) {
|
||||
errors.add(trans.get("RASAeroExport.error24"));
|
||||
return;
|
||||
}
|
||||
addExternalPart(new NoseConeDTO((NoseCone) component, warnings, errors));
|
||||
// Set the global surface finish to that of the first nose cone
|
||||
setSurface(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_SURFACE(((NoseCone) component).getFinish(),
|
||||
warnings));
|
||||
} else if (component instanceof Transition) {
|
||||
// If there is only a sustainer & this is the last child of the sustainer, it's a boattail
|
||||
if (rocket.getChildCount() == 1 && (i == sustainer.getChildCount() - 1)) {
|
||||
addExternalPart(new BoattailDTO((Transition) component, warnings, errors));
|
||||
} else {
|
||||
addExternalPart(new TransitionDTO((Transition) component, warnings, errors));
|
||||
}
|
||||
} else {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error33"), component.getComponentName()));
|
||||
}
|
||||
} catch (RASAeroExportException e) {
|
||||
errors.add(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Export components from other stages
|
||||
for (int i = 1; i < Math.min(rocket.getChildCount(), 3); i++) {
|
||||
try {
|
||||
addBooster(new BoosterDTO(rocket, (AxialStage) rocket.getChild(i), warnings, errors));
|
||||
} catch (RASAeroExportException e) {
|
||||
errors.add(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getSurface() {
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void setSurface(String surface) {
|
||||
this.surface = surface;
|
||||
}
|
||||
|
||||
public double getCD() {
|
||||
return CD;
|
||||
}
|
||||
|
||||
public void setCD(double CD) {
|
||||
this.CD = CD;
|
||||
}
|
||||
|
||||
public boolean isModifiedBarrowman() {
|
||||
return modifiedBarrowman;
|
||||
}
|
||||
|
||||
public void setModifiedBarrowman(boolean modifiedBarrowman) {
|
||||
this.modifiedBarrowman = modifiedBarrowman;
|
||||
}
|
||||
|
||||
public Boolean isTurbulence() {
|
||||
return turbulence;
|
||||
}
|
||||
|
||||
public void setTurbulence(Boolean turbulence) {
|
||||
this.turbulence = turbulence;
|
||||
}
|
||||
|
||||
public Double getSustainerNozzle() {
|
||||
return sustainerNozzle;
|
||||
}
|
||||
|
||||
public void setSustainerNozzle(Double sustainerNozzle) {
|
||||
this.sustainerNozzle = sustainerNozzle;
|
||||
}
|
||||
|
||||
public Double getBooster1Nozzle() {
|
||||
return booster1Nozzle;
|
||||
}
|
||||
|
||||
public void setBooster1Nozzle(Double booster1Nozzle) {
|
||||
this.booster1Nozzle = booster1Nozzle;
|
||||
}
|
||||
|
||||
public Double getBooster2Nozzle() {
|
||||
return booster2Nozzle;
|
||||
}
|
||||
|
||||
public void setBooster2Nozzle(Double booster2Nozzle) {
|
||||
this.booster2Nozzle = booster2Nozzle;
|
||||
}
|
||||
|
||||
public Boolean isUseBooster1() {
|
||||
return useBooster1;
|
||||
}
|
||||
|
||||
public void setUseBooster1(Boolean useBooster1) {
|
||||
this.useBooster1 = useBooster1;
|
||||
}
|
||||
|
||||
public Boolean isUseBooster2() {
|
||||
return useBooster2;
|
||||
}
|
||||
|
||||
public void setUseBooster2(Boolean useBooster2) {
|
||||
this.useBooster2 = useBooster2;
|
||||
}
|
||||
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public List<BasePartDTO> getExternalPart() {
|
||||
return externalPart;
|
||||
}
|
||||
|
||||
public void addExternalPart(BasePartDTO theExternalPartDTO) {
|
||||
externalPart.add(theExternalPartDTO);
|
||||
}
|
||||
|
||||
public List<BoosterDTO> getBoosters() {
|
||||
return boosters;
|
||||
}
|
||||
|
||||
public void addBooster(BoosterDTO boosterDTO) {
|
||||
boosters.add(boosterDTO);
|
||||
}
|
||||
}
|
@ -1,496 +0,0 @@
|
||||
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.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.RigidBody;
|
||||
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.FlightConfiguration;
|
||||
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 net.sf.openrocket.startup.Application;
|
||||
|
||||
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.XmlTransient;
|
||||
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;
|
||||
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* if a motor mount is null, it means that stage does not have any motors, but mass/CG export should still take place
|
||||
* @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<AxialStage, MotorMount> mounts, List<ThrustCurveMotor> motors,
|
||||
WarningSet warnings, ErrorSet errors) {
|
||||
String simulationName = simulation != null ? simulation.getName() : "DEFAULT";
|
||||
FlightConfigurationId fcid = simulation != null ? simulation.getFlightConfigurationId() : null;
|
||||
|
||||
if (simulation != null && fcid == null) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning11"), simulationName));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mounts.isEmpty()) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning12"), simulationName));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get sustainer motor mass
|
||||
MotorMount sustainerMount = mounts.get((AxialStage) rocket.getChild(0));
|
||||
Motor sustainerMotor = null;
|
||||
double sustainerMotorMass = 0;
|
||||
if (sustainerMount != null) {
|
||||
MotorConfiguration sustainerConfig = sustainerMount.getMotorConfig(fcid);
|
||||
sustainerMotor = sustainerConfig.getMotor();
|
||||
sustainerMotorMass = sustainerMotor != null ? sustainerMotor.getLaunchMass() : 0;
|
||||
}
|
||||
|
||||
for (Map.Entry<AxialStage, MotorMount> mountSet : mounts.entrySet()) {
|
||||
AxialStage stage = mountSet.getKey();
|
||||
MotorMount mount = mountSet.getValue();
|
||||
if (stage == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the motor info for this stage
|
||||
MotorConfiguration motorConfig = mount != null ? mount.getMotorConfig(fcid) : null;
|
||||
Motor motor = null;
|
||||
StageSeparationConfiguration separationConfig = null;
|
||||
double motorMass = 0;
|
||||
if (motorConfig != null) {
|
||||
motor = motorConfig.getMotor();
|
||||
motorMass = motor != null ? motor.getLaunchMass() : 0;
|
||||
separationConfig = stage.getSeparationConfigurations().get(fcid);
|
||||
}
|
||||
int stageNr = rocket.getChildPosition(stage);
|
||||
|
||||
// Add friendly reminder to user
|
||||
if (motor == null) {
|
||||
warnings.add(String.format(trans.get("RASAeroExport.warning13"), stage.getName()));
|
||||
}
|
||||
|
||||
// Add the simulation info for each stage
|
||||
FlightConfiguration CGCalcConfig = new FlightConfiguration(rocket);
|
||||
RigidBody calc;
|
||||
double ignitionDelay, totalCG, separationDelay;
|
||||
switch (stageNr) {
|
||||
// Sustainer
|
||||
case 0:
|
||||
setSustainerEngine(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_MOTOR(motors, motor, warnings));
|
||||
|
||||
// Calculate mass & CG of sustainer
|
||||
CGCalcConfig.setOnlyStage(0);
|
||||
calc = MassCalculator.calculateStructure(CGCalcConfig);
|
||||
|
||||
// Set mass
|
||||
double sustainerMass = calc.getMass() + motorMass;
|
||||
setSustainerLaunchWt(sustainerMass * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_WEIGHT);
|
||||
|
||||
// Set CG
|
||||
double sustainerCG = calc.getCM().x; // = sutainer CG with no motors
|
||||
sustainerCG = addMotorCGToStageCG(sustainerCG, calc.getMass(), mount, motor, fcid);
|
||||
setSustainerCG(sustainerCG * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
|
||||
// Set ignition delay
|
||||
ignitionDelay = motorConfig != null ? motorConfig.getIgnitionDelay() : 0;
|
||||
setSustainerIgnitionDelay(ignitionDelay);
|
||||
|
||||
break;
|
||||
// Booster 1
|
||||
case 1:
|
||||
setBooster1Engine(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_MOTOR(motors, motor, warnings));
|
||||
|
||||
// Calculate mass & CG of sustainer + booster 1 combined
|
||||
CGCalcConfig.setOnlyStage(0);
|
||||
for (int i = 1; i <= stage.getStageNumber(); i++) {
|
||||
CGCalcConfig._setStageActive(i, true);
|
||||
}
|
||||
calc = MassCalculator.calculateStructure(CGCalcConfig);
|
||||
|
||||
// Set mass
|
||||
double booster1Mass = calc.getMass() + motorMass + sustainerMotorMass;
|
||||
setBooster1LaunchWt(booster1Mass * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_WEIGHT);
|
||||
|
||||
// Set CG
|
||||
totalCG = calc.getCM().x; // = sustainer + booster 1 CG with no sustainer & booster & motors
|
||||
totalCG = addMotorCGToStageCG(totalCG, calc.getMass(), sustainerMount, sustainerMotor, fcid);
|
||||
totalCG = addMotorCGToStageCG(totalCG, calc.getMass() + sustainerMotorMass, mount, motor, fcid);
|
||||
setBooster1CG(totalCG * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
|
||||
// Set ignition delay
|
||||
ignitionDelay = motorConfig != null ? motorConfig.getIgnitionDelay() : 0;
|
||||
setBooster1IgnitionDelay(ignitionDelay);
|
||||
|
||||
// Set separation delay
|
||||
separationDelay = separationConfig != null ? separationConfig.getSeparationDelay() : 0;
|
||||
setBooster1SeparationDelay(separationDelay); // TODO: this could be handled a bit better (look at separation delay, upper stage ignition event etc.)
|
||||
|
||||
setIncludeBooster1(mount != null && mount.isMotorMount());
|
||||
|
||||
break;
|
||||
// Booster 2
|
||||
case 2:
|
||||
setBooster2Engine(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_MOTOR(motors, motor, warnings));
|
||||
|
||||
// Calculate mass & CG of sustainer + booster 1 + booster 2 combined
|
||||
CGCalcConfig.setOnlyStage(0);
|
||||
for (int i = 1; i <= stage.getStageNumber(); i++) {
|
||||
CGCalcConfig._setStageActive(i, true);
|
||||
}
|
||||
calc = MassCalculator.calculateStructure(CGCalcConfig);
|
||||
|
||||
// Get booster1 motor mass
|
||||
double booster1MotorMass = 0;
|
||||
MotorMount booster1Mount = mounts.get((AxialStage) rocket.getChild(1));
|
||||
Motor booster1Motor = null;
|
||||
if (booster1Mount != null) {
|
||||
MotorConfiguration booster1Config = booster1Mount.getMotorConfig(fcid);
|
||||
booster1Motor = booster1Config.getMotor();
|
||||
booster1MotorMass = booster1Motor != null ? booster1Motor.getLaunchMass() : 0;
|
||||
}
|
||||
|
||||
// Set mass
|
||||
double booster2Mass = calc.getMass() + motorMass + sustainerMotorMass + booster1MotorMass;
|
||||
setBooster2LaunchWt(booster2Mass * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_WEIGHT);
|
||||
|
||||
// Set CG
|
||||
totalCG = calc.getCM().x; // CG of sustainer + booster 1 + booster 2 combined, with no sustainer, booster1 and booster2 motors!
|
||||
totalCG = addMotorCGToStageCG(totalCG, calc.getMass(), sustainerMount, sustainerMotor, fcid);
|
||||
totalCG = addMotorCGToStageCG(totalCG, calc.getMass() + sustainerMotorMass, booster1Mount, booster1Motor, fcid);
|
||||
totalCG = addMotorCGToStageCG(totalCG, calc.getMass() + sustainerMotorMass + booster1MotorMass, mount, motor, fcid);
|
||||
setBooster2CG(totalCG * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
|
||||
// Set separation delay
|
||||
separationDelay = separationConfig != null ? separationConfig.getSeparationDelay() : 0;
|
||||
setBooster2Delay(separationDelay); // TODO: this could be handled a bit better (look at separation delay, upper stage ignition event etc.)
|
||||
|
||||
setIncludeBooster2(mount != null && mount.isMotorMount());
|
||||
|
||||
break;
|
||||
// Invalid
|
||||
default:
|
||||
errors.add(String.format(trans.get("RASAeroExport.error25"), stageNr, simulationName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines the stage CG with the CG of the motor in that stage.
|
||||
* @param stageCG The CG of the stage
|
||||
* @param mount The motor mount of the stage
|
||||
* @param motor The motor in the stage
|
||||
* @return The combined CG
|
||||
*/
|
||||
private double addMotorCGToStageCG(double stageCG, double stageMass, MotorMount mount, Motor motor, FlightConfigurationId fcid) {
|
||||
if (mount == null || !(motor instanceof ThrustCurveMotor)) {
|
||||
return stageCG;
|
||||
}
|
||||
|
||||
// Calculate the motor CG
|
||||
double motorPositionXRel = mount.getMotorPosition(fcid).x; // Motor position relative to the mount
|
||||
double mountLocationX = mount.getLocations()[0].x;
|
||||
double motorLocationX = mountLocationX + motorPositionXRel;
|
||||
double motorCG = ((ThrustCurveMotor) motor).getCGPoints()[0].x + motorLocationX;
|
||||
|
||||
double motorMass = motor.getLaunchMass();
|
||||
|
||||
return (stageCG*stageMass + motorCG*motorMass) / (stageMass + motorMass);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
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.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<SimulationDTO> simulations = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* We need a default, no-args constructor.
|
||||
*/
|
||||
public SimulationListDTO() {
|
||||
}
|
||||
|
||||
public SimulationListDTO(OpenRocketDocument document, WarningSet warnings, ErrorSet errors) {
|
||||
Map<AxialStage, MotorMount> 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()) {
|
||||
if (stageChild instanceof BodyTube) {
|
||||
// First check if the body tube itself has a motor
|
||||
if (((BodyTube) stageChild).hasMotor()) {
|
||||
mounts.put(stage, (BodyTube) stageChild);
|
||||
break;
|
||||
}
|
||||
// Then check if it has an inner tube with a motor
|
||||
else {
|
||||
boolean addedMount = false;
|
||||
for (RocketComponent tubeChild : stageChild.getChildren()) {
|
||||
if (tubeChild instanceof MotorMount && ((MotorMount) tubeChild).hasMotor()) {
|
||||
mounts.put(stage, (MotorMount) tubeChild);
|
||||
addedMount = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addedMount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If at this point, we still don't have a mount, there is probably a mount without a motor.
|
||||
// In that case, add a null mount, so that mass/CG export happens.
|
||||
if (!mounts.containsKey(stage)) {
|
||||
mounts.put(stage, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Load all RASAero motors
|
||||
List<ThrustCurveMotor> motors = RASAeroMotorsLoader.loadAllRASAeroMotors(warnings);
|
||||
|
||||
// Add all the simulations
|
||||
for (Simulation simulation : document.getSimulations()) {
|
||||
addSimulation(new SimulationDTO(rocket, simulation, mounts, motors, warnings, errors));
|
||||
}
|
||||
|
||||
// If there are no simulations, add a default simulation (to have the mass/CG export)
|
||||
if (document.getSimulations().size() == 0) {
|
||||
addSimulation(new SimulationDTO(rocket, null, mounts, motors, warnings, errors));
|
||||
}
|
||||
|
||||
motors.clear();
|
||||
}
|
||||
|
||||
public List<SimulationDTO> getSimulations() {
|
||||
return simulations;
|
||||
}
|
||||
|
||||
public void addSimulation(SimulationDTO simulation) {
|
||||
simulations.add(simulation);
|
||||
}
|
||||
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package net.sf.openrocket.file.rasaero.export;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.CustomDoubleAdapter;
|
||||
import net.sf.openrocket.file.rasaero.RASAeroCommonConstants;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
|
||||
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.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
@XmlRootElement(name = RASAeroCommonConstants.TRANSITION)
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(propOrder = {
|
||||
"partType",
|
||||
"length",
|
||||
"diameter",
|
||||
"rearDiameter",
|
||||
"location",
|
||||
"color"
|
||||
})
|
||||
@XmlSeeAlso({BoattailDTO.class})
|
||||
public class TransitionDTO extends BasePartDTO {
|
||||
|
||||
@XmlElement(name = RASAeroCommonConstants.REAR_DIAMETER)
|
||||
@XmlJavaTypeAdapter(CustomDoubleAdapter.class)
|
||||
private Double rearDiameter;
|
||||
|
||||
@XmlTransient
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
@XmlTransient
|
||||
private static Transition component = null;
|
||||
|
||||
/**
|
||||
* We need a default no-args constructor.
|
||||
*/
|
||||
public TransitionDTO() {
|
||||
}
|
||||
|
||||
public TransitionDTO(Transition transition, WarningSet warnings, ErrorSet errors) throws RASAeroExportException {
|
||||
super(transition, warnings, errors);
|
||||
|
||||
component = transition;
|
||||
|
||||
if (!transition.getShapeType().equals(Transition.Shape.CONICAL)) {
|
||||
throw new RASAeroExportException(trans.get("RASAeroExport.error26"));
|
||||
}
|
||||
|
||||
SymmetricComponent previousComp = transition.getPreviousSymmetricComponent();
|
||||
if (previousComp == null) {
|
||||
throw new RASAeroExportException(String.format(trans.get("RASAeroExport.error27"), transition.getName()));
|
||||
}
|
||||
if (!MathUtil.equals(transition.getForeRadius(), previousComp.getAftRadius())) {
|
||||
throw new RASAeroExportException(
|
||||
String.format(trans.get("RASAeroExport.error28"),
|
||||
transition.getName(), previousComp.getAftRadius(), transition.getForeRadius()));
|
||||
}
|
||||
|
||||
setRearDiameter(transition.getAftRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH);
|
||||
}
|
||||
|
||||
public Double getRearDiameter() {
|
||||
return rearDiameter;
|
||||
}
|
||||
|
||||
public void setRearDiameter(Double rearDiameter) throws RASAeroExportException {
|
||||
if (rearDiameter < 0.0001) {
|
||||
throw new RASAeroExportException(String.format("'%s' rear diameter must be greater than 0.0001 inch", component));
|
||||
}
|
||||
this.rearDiameter = rearDiameter;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
/**
|
||||
* An error message wrapper.
|
||||
*/
|
||||
public abstract class Error extends Message {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* @return an Error with the specific text.
|
||||
*/
|
||||
public static Error fromString(String text) {
|
||||
return new Error.Other(text);
|
||||
}
|
||||
|
||||
|
||||
///////////// Specific Error classes /////////////
|
||||
|
||||
|
||||
/**
|
||||
* An unspecified error type. This error type holds a <code>String</code>
|
||||
* describing it. Two errors of this type are considered equal if the strings
|
||||
* are identical.
|
||||
*/
|
||||
public static class Other extends Error {
|
||||
private final String description;
|
||||
|
||||
public Other(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof Other))
|
||||
return false;
|
||||
|
||||
Other o = (Other) other;
|
||||
return (o.description.equals(this.description));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return description.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
import net.sf.openrocket.util.BugException;
|
||||
|
||||
public class ErrorSet extends MessageSet<Error> {
|
||||
/**
|
||||
* Add an <code>Error</code> with the specified text to the set. The Error object
|
||||
* is created using the {@link Error#fromString(String)} method. If an error of the
|
||||
* same type exists in the set, the error that is left in the set is defined by the
|
||||
* method {@link Error#replaceBy(Message)}.
|
||||
*
|
||||
* @param s the message text.
|
||||
* @throws IllegalStateException if this message set has been made immutable.
|
||||
*/
|
||||
public boolean add(String s) {
|
||||
mutable.check();
|
||||
return add(Error.fromString(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorSet clone() {
|
||||
try {
|
||||
ErrorSet newSet = (ErrorSet) super.clone();
|
||||
newSet.messages = this.messages.clone();
|
||||
newSet.mutable = this.mutable.clone();
|
||||
return newSet;
|
||||
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new BugException("CloneNotSupportedException occurred, report bug!", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
/**
|
||||
* Baseclass for logging messages (warnings, errors...)
|
||||
*/
|
||||
public abstract class Message {
|
||||
/**
|
||||
* @return a Message with the specific text.
|
||||
*/
|
||||
public static Message fromString(String text) {
|
||||
return new Warning.Other(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if the <code>other</code> warning should replace
|
||||
* this message. The method should return <code>true</code> if the other
|
||||
* indicates a "worse" condition than the current warning.
|
||||
*
|
||||
* @param other the message to compare to
|
||||
* @return whether this message should be replaced
|
||||
*/
|
||||
public abstract boolean replaceBy(Message other);
|
||||
|
||||
|
||||
/**
|
||||
* Two <code>Message</code>s are by default considered equal if they are of
|
||||
* the same class. Therefore only one instance of a particular message type
|
||||
* is stored in a {@link MessageSet}. Subclasses may override this method for
|
||||
* more specific functionality.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o != null && (o.getClass() == this.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* A <code>hashCode</code> method compatible with the <code>equals</code> method.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getClass().hashCode();
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Monitorable;
|
||||
import net.sf.openrocket.util.Mutable;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A set that contains multiple <code>Message</code>s. When adding a
|
||||
* {@link Message} to this set, the contents is checked for a message of the
|
||||
* same type. If one is found, then the message left in the set is determined
|
||||
* by the method {@link Message#replaceBy(Message)}.
|
||||
* <p>
|
||||
* A MessageSet can be made immutable by calling {@link #immute()}.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public abstract class MessageSet<E extends Message> extends AbstractSet<E> implements Cloneable, Monitorable {
|
||||
/** the actual array of messages */
|
||||
protected ArrayList<E> messages = new ArrayList<>();
|
||||
|
||||
protected Mutable mutable = new Mutable();
|
||||
private int modID = 0;
|
||||
|
||||
/**
|
||||
* Add a <code>Message</code> to the set. If a message of the same type
|
||||
* exists in the set, the message that is left in the set is defined by the
|
||||
* method {@link Message#replaceBy(Message)}.
|
||||
*
|
||||
* @throws IllegalStateException if this message set has been made immutable.
|
||||
*/
|
||||
@Override
|
||||
public boolean add(E m) {
|
||||
mutable.check();
|
||||
|
||||
modID++;
|
||||
int index = messages.indexOf(m);
|
||||
|
||||
if (index < 0) {
|
||||
messages.add(m);
|
||||
return false;
|
||||
}
|
||||
|
||||
E old = messages.get(index);
|
||||
if (old.replaceBy(m)) {
|
||||
messages.set(index, m);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a <code>Message</code> with the specified text to the set.
|
||||
*
|
||||
* @param s the message text.
|
||||
* @throws IllegalStateException if this message set has been made immutable.
|
||||
*/
|
||||
public abstract boolean add(String s);
|
||||
|
||||
/**
|
||||
* Add a <code>Message</code> of the specified type with the specified discriminator to the
|
||||
* set.
|
||||
* @param m the message
|
||||
* @param d the extra discriminator
|
||||
*
|
||||
*/
|
||||
public boolean add (E m, String d) {
|
||||
return this.add(m.toString() + ": \"" + d + "\"");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
final Iterator<E> iterator = messages.iterator();
|
||||
return new Iterator<E>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
mutable.check();
|
||||
iterator.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return messages.size();
|
||||
}
|
||||
|
||||
|
||||
public void immute() {
|
||||
mutable.immute();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
for (Message m : messages) {
|
||||
if (s.length() > 0)
|
||||
s.append(",");
|
||||
s.append(m.toString());
|
||||
}
|
||||
return "Messages[" + s + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModID() {
|
||||
return modID;
|
||||
}
|
||||
}
|
@ -1,392 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
/**
|
||||
* A warning message wrapper.
|
||||
*/
|
||||
public abstract class Warning extends Message {
|
||||
|
||||
/** support to multiple languages warning */
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
/**
|
||||
* @return a Warning with the specific text.
|
||||
*/
|
||||
public static Warning fromString(String text) {
|
||||
return new Warning.Other(text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////// Specific warning classes /////////////
|
||||
|
||||
|
||||
/**
|
||||
* A <code>Warning</code> indicating a large angle of attack was encountered.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public static class LargeAOA extends Warning {
|
||||
private final double aoa;
|
||||
|
||||
/**
|
||||
* Sole constructor. The argument is the AOA that caused this warning.
|
||||
*
|
||||
* @param aoa the angle of attack that caused this warning
|
||||
*/
|
||||
public LargeAOA(double aoa) {
|
||||
this.aoa = aoa;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (Double.isNaN(aoa))
|
||||
//// Large angle of attack encountered.
|
||||
return trans.get("Warning.LargeAOA.str1");
|
||||
//// Large angle of attack encountered (
|
||||
return (trans.get("Warning.LargeAOA.str2") +
|
||||
UnitGroup.UNITS_ANGLE.getDefaultUnit().toString(aoa) + ").");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
if (!(other instanceof LargeAOA))
|
||||
return false;
|
||||
|
||||
LargeAOA o = (LargeAOA) other;
|
||||
if (Double.isNaN(this.aoa)) // If this has value NaN then replace
|
||||
return true;
|
||||
return (o.aoa > this.aoa);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A <code>Warning</code> indicating recovery device deployment at high speed was encountered.
|
||||
*
|
||||
* @author Craig Earls <enderw88@gmail.com>
|
||||
*/
|
||||
public static class HighSpeedDeployment extends Warning {
|
||||
private final double recoverySpeed;
|
||||
|
||||
/**
|
||||
* Sole constructor. The argument is the speed that caused this warning.
|
||||
*
|
||||
* @param speed the speed that caused this warning
|
||||
*/
|
||||
public HighSpeedDeployment(double speed) {
|
||||
this.recoverySpeed = speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (Double.isNaN(recoverySpeed)) {
|
||||
return trans.get("Warning.RECOVERY_HIGH_SPEED");
|
||||
}
|
||||
return trans.get("Warning.RECOVERY_HIGH_SPEED") + " (" + UnitGroup.UNITS_VELOCITY.toStringUnit(recoverySpeed) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A <code>Warning</code> indicating flight events occurred after ground hit
|
||||
*
|
||||
*/
|
||||
public static class EventAfterLanding extends Warning {
|
||||
private final FlightEvent event;
|
||||
|
||||
/**
|
||||
* Sole constructor. The argument is an event which has occurred after landing
|
||||
*
|
||||
* @param _event the event that caused this warning
|
||||
*/
|
||||
public EventAfterLanding(FlightEvent _event) {
|
||||
this.event = _event;
|
||||
}
|
||||
|
||||
// I want a warning on every event that occurs after we land,
|
||||
// so severity of problem is clear to the user
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return trans.get("Warning.EVENT_AFTER_LANDING") + event.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MissingMotor extends Warning {
|
||||
|
||||
private Motor.Type type = null;
|
||||
private String manufacturer = null;
|
||||
private String designation = null;
|
||||
private String digest = null;
|
||||
private double diameter = Double.NaN;
|
||||
private double length = Double.NaN;
|
||||
private double delay = Double.NaN;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = "No motor with designation '" + designation + "'";
|
||||
if (manufacturer != null)
|
||||
str += " for manufacturer '" + manufacturer + "'";
|
||||
str += " found.";
|
||||
return str;
|
||||
}
|
||||
|
||||
public Motor.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public void setType(Motor.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
|
||||
public void setManufacturer(String manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
|
||||
public String getDesignation() {
|
||||
return designation;
|
||||
}
|
||||
|
||||
|
||||
public void setDesignation(String designation) {
|
||||
this.designation = designation;
|
||||
}
|
||||
|
||||
|
||||
public String getDigest() {
|
||||
return digest;
|
||||
}
|
||||
|
||||
|
||||
public void setDigest(String digest) {
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
|
||||
public double getDiameter() {
|
||||
return diameter;
|
||||
}
|
||||
|
||||
|
||||
public void setDiameter(double diameter) {
|
||||
this.diameter = diameter;
|
||||
}
|
||||
|
||||
|
||||
public double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
public void setLength(double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
|
||||
public double getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
|
||||
public void setDelay(double delay) {
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(delay);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
result = prime * result
|
||||
+ ((designation == null) ? 0 : designation.hashCode());
|
||||
temp = Double.doubleToLongBits(diameter);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
result = prime * result
|
||||
+ ((digest == null) ? 0 : digest.hashCode());
|
||||
temp = Double.doubleToLongBits(length);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
result = prime * result
|
||||
+ ((manufacturer == null) ? 0 : manufacturer.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MissingMotor other = (MissingMotor) obj;
|
||||
if (Double.doubleToLongBits(delay) != Double
|
||||
.doubleToLongBits(other.delay))
|
||||
return false;
|
||||
if (designation == null) {
|
||||
if (other.designation != null)
|
||||
return false;
|
||||
} else if (!designation.equals(other.designation))
|
||||
return false;
|
||||
if (Double.doubleToLongBits(diameter) != Double
|
||||
.doubleToLongBits(other.diameter))
|
||||
return false;
|
||||
if (digest == null) {
|
||||
if (other.digest != null)
|
||||
return false;
|
||||
} else if (!digest.equals(other.digest))
|
||||
return false;
|
||||
if (Double.doubleToLongBits(length) != Double
|
||||
.doubleToLongBits(other.length))
|
||||
return false;
|
||||
if (manufacturer == null) {
|
||||
if (other.manufacturer != null)
|
||||
return false;
|
||||
} else if (!manufacturer.equals(other.manufacturer))
|
||||
return false;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An unspecified warning type. This warning type holds a <code>String</code>
|
||||
* describing it. Two warnings of this type are considered equal if the strings
|
||||
* are identical.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public static class Other extends Warning {
|
||||
private final String description;
|
||||
|
||||
public Other(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof Other))
|
||||
return false;
|
||||
|
||||
Other o = (Other) other;
|
||||
return (o.description.equals(this.description));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return description.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceBy(Message other) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** A <code>Warning</code> that the body diameter is discontinuous. */
|
||||
////Discontinuity in rocket body diameter.
|
||||
public static final Warning DIAMETER_DISCONTINUITY = new Other(trans.get("Warning.DISCONTINUITY"));
|
||||
|
||||
/** A <code>Warning</code> that a ComponentAssembly has an open forward end */
|
||||
public static final Warning OPEN_AIRFRAME_FORWARD = new Other(trans.get("Warning.OPEN_AIRFRAME_FORWARD"));
|
||||
|
||||
/** A <code>Warning</code> that there is a gap in the airframe */
|
||||
public static final Warning AIRFRAME_GAP = new Other(trans.get("Warning.AIRFRAME_GAP"));
|
||||
|
||||
/** A <code>Warning</code> that there are overlapping airframe components */
|
||||
public static final Warning AIRFRAME_OVERLAP = new Other(trans.get("Warning.AIRFRAME_OVERLAP"));
|
||||
|
||||
/** A <code>Warning</code> that an inline podset is completely forward of its parent component */
|
||||
public static final Warning PODSET_FORWARD = new Other(trans.get("Warning.PODSET_FORWARD"));
|
||||
|
||||
/** A <code>Warning</code> that an inline podset overlaps its parent component */
|
||||
public static final Warning PODSET_OVERLAP = new Other(trans.get("Warning.PODSET_OVERLAP"));
|
||||
|
||||
/** A <code>Warning</code> that the fins are thick compared to the rocket body. */
|
||||
////Thick fins may not be modeled accurately.
|
||||
public static final Warning THICK_FIN = new Other(trans.get("Warning.THICK_FIN"));
|
||||
|
||||
/** A <code>Warning</code> that the fins have jagged edges. */
|
||||
////Jagged-edged fin predictions may be inaccurate.
|
||||
public static final Warning JAGGED_EDGED_FIN = new Other(trans.get("Warning.JAGGED_EDGED_FIN"));
|
||||
|
||||
/** A <code>Warning</code> that the fins have a zero area. */
|
||||
////Fins with no area will not affect aerodynamics
|
||||
public static final Warning ZERO_AREA_FIN = new Other(trans.get("Warning.ZERO_AREA_FIN"));
|
||||
|
||||
/** A <code>Warning</code> that simulation listeners have affected the simulation */
|
||||
////Listeners modified the flight simulation
|
||||
public static final Warning LISTENERS_AFFECTED = new Other(trans.get("Warning.LISTENERS_AFFECTED"));
|
||||
|
||||
////Recovery device opened while motor still burning.
|
||||
public static final Warning RECOVERY_DEPLOYMENT_WHILE_BURNING = new Other(trans.get("Warning.RECOVERY_DEPLOYMENT_WHILE_BURNING"));
|
||||
|
||||
////No recovery device for simulation
|
||||
public static final Warning NO_RECOVERY_DEVICE = new Other(trans.get("Warning.NO_RECOVERY_DEVICE"));
|
||||
|
||||
//// Invalid parameter encountered, ignoring.
|
||||
public static final Warning FILE_INVALID_PARAMETER = new Other(trans.get("Warning.FILE_INVALID_PARAMETER"));
|
||||
|
||||
public static final Warning PARALLEL_FINS = new Other(trans.get("Warning.PARALLEL_FINS"));
|
||||
|
||||
public static final Warning SUPERSONIC = new Other(trans.get("Warning.SUPERSONIC"));
|
||||
|
||||
public static final Warning RECOVERY_LAUNCH_ROD = new Other(trans.get("Warning.RECOVERY_LAUNCH_ROD"));
|
||||
|
||||
public static final Warning TUMBLE_UNDER_THRUST = new Other(trans.get("Warning.TUMBLE_UNDER_THRUST"));
|
||||
|
||||
public static final Warning EVENT_AFTER_LANDING = new Other(trans.get("Warning.EVENT_AFTER_LANDING"));
|
||||
|
||||
public static final Warning ZERO_VOLUME_BODY = new Other(trans.get("Warning.ZERO_VOLUME_BODY"));
|
||||
|
||||
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
|
||||
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
|
||||
|
||||
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
|
||||
|
||||
public static final Warning EMPTY_BRANCH = new Other(trans.get("Warning.EMPTY_BRANCH"));
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package net.sf.openrocket.logging;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Monitorable;
|
||||
import net.sf.openrocket.util.Mutable;
|
||||
|
||||
/**
|
||||
* A set that contains multiple <code>Warning</code>s. When adding a
|
||||
* {@link Warning} to this set, the contents is checked for a warning of the
|
||||
* same type. If one is found, then the warning left in the set is determined
|
||||
* by the method {@link Warning#replaceBy(Message)}.
|
||||
* <p>
|
||||
* A WarningSet can be made immutable by calling {@link #immute()}.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class WarningSet extends MessageSet<Warning> {
|
||||
/**
|
||||
* Add a <code>Warning</code> with the specified text to the set. The Warning object
|
||||
* is created using the {@link Message#fromString(String)} method. If a warning of the
|
||||
* same type exists in the set, the warning that is left in the set is defined by the
|
||||
* method {@link Warning#replaceBy(Message)}.
|
||||
*
|
||||
* @param s the message text.
|
||||
* @throws IllegalStateException if this message set has been made immutable.
|
||||
*/
|
||||
public boolean add(String s) {
|
||||
mutable.check();
|
||||
return add(Warning.fromString(s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WarningSet clone() {
|
||||
try {
|
||||
WarningSet newSet = (WarningSet) super.clone();
|
||||
newSet.messages = this.messages.clone();
|
||||
newSet.mutable = this.mutable.clone();
|
||||
return newSet;
|
||||
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new BugException("CloneNotSupportedException occurred, report bug!", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package net.sf.openrocket.gui.dialogs;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.util.BetterListCellRenderer;
|
||||
import net.sf.openrocket.logging.Error;
|
||||
import net.sf.openrocket.logging.ErrorSet;
|
||||
import net.sf.openrocket.logging.Warning;
|
||||
import net.sf.openrocket.logging.WarningSet;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* A message dialog displaying errors and warnings.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class ErrorWarningDialog {
|
||||
public static void showErrorsAndWarnings(Component parent, Object message, String title, ErrorSet errors, WarningSet warnings) {
|
||||
JPanel content = new JPanel(new MigLayout("ins 0, fillx"));
|
||||
|
||||
StyledLabel label = new StyledLabel("Errors");
|
||||
label.setFontColor(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
|
||||
content.add(label, "wrap, gaptop 15lp");
|
||||
|
||||
Error[] e = errors.toArray(new Error[0]);
|
||||
final JList<Error> errorList = new JList<>(e);
|
||||
errorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
errorList.setCellRenderer(new ErrorListCellRenderer());
|
||||
JScrollPane errorPane = new JScrollPane(errorList);
|
||||
content.add(errorPane, "wrap, growx");
|
||||
|
||||
// Deselect items if clicked on blank region
|
||||
errorList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
int selectedIndex = errorList.locationToIndex(e.getPoint());
|
||||
if (selectedIndex < 0 || !errorList.getCellBounds(0, errorList.getLastVisibleIndex()).contains(e.getPoint())) {
|
||||
errorList.clearSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
content.add(new JSeparator(JSeparator.HORIZONTAL), "wrap");
|
||||
|
||||
content.add(new JLabel("Warnings:"), "wrap");
|
||||
|
||||
Warning[] w = warnings.toArray(new Warning[0]);
|
||||
final JList<Warning> warningList = new JList<>(w);
|
||||
warningList.setCellRenderer(new BetterListCellRenderer());
|
||||
JScrollPane warningPane = new JScrollPane(warningList);
|
||||
content.add(warningPane, "wrap, growx");
|
||||
|
||||
// Deselect items if clicked on blank region
|
||||
warningList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
int selectedIndex = warningList.locationToIndex(e.getPoint());
|
||||
if (selectedIndex < 0 || !warningList.getCellBounds(0, warningList.getLastVisibleIndex()).contains(e.getPoint())) {
|
||||
warningList.clearSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JOptionPane.showMessageDialog(parent, new Object[] { message, content },
|
||||
title, JOptionPane.WARNING_MESSAGE);
|
||||
|
||||
}
|
||||
|
||||
private static class ErrorListCellRenderer extends BetterListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
|
||||
// Text color
|
||||
if (isSelected) {
|
||||
label.setForeground(Color.WHITE);
|
||||
} else {
|
||||
label.setForeground(net.sf.openrocket.util.Color.DARK_RED.toAWTColor());
|
||||
}
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package net.sf.openrocket.gui.util;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
|
||||
/**
|
||||
* An improved list cell renderer, with alternating row background colors.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class BetterListCellRenderer extends DefaultListCellRenderer {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
|
||||
// Alternating row colors
|
||||
if (!isSelected) {
|
||||
if (index % 2 == 0) {
|
||||
label.setBackground(Color.WHITE);
|
||||
} else {
|
||||
label.setBackground(new Color(245, 245, 245));
|
||||
}
|
||||
}
|
||||
// Text color
|
||||
if (isSelected) {
|
||||
label.setForeground(Color.WHITE);
|
||||
} else {
|
||||
label.setForeground(Color.BLACK);
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user