commit
b5cde10824
Binary file not shown.
@ -179,7 +179,14 @@ public abstract class AbstractMotorLoader implements MotorLoader {
|
||||
return;
|
||||
|
||||
// Start
|
||||
if (!MathUtil.equals(time.get(0), 0) || !MathUtil.equals(thrust.get(0), 0)) {
|
||||
// If there is no datapoint at t=0, put one there (this is the
|
||||
// normal case for a RASP file). If there is a nonzero thrust
|
||||
// at time 0 it's an error, but not one that calls for not
|
||||
// using the file. We *don't* want to also put a 0-thrust
|
||||
// point at time 0 in that case, as that will cause the
|
||||
// simulation to throw an exception just like in the
|
||||
// commented-out case below.
|
||||
if (!MathUtil.equals(time.get(0), 0)) {
|
||||
time.add(0, 0.0);
|
||||
thrust.add(0, 0.0);
|
||||
for (List l : lists) {
|
||||
@ -188,16 +195,32 @@ public abstract class AbstractMotorLoader implements MotorLoader {
|
||||
}
|
||||
}
|
||||
|
||||
// End
|
||||
int n = time.size() - 1;
|
||||
if (!MathUtil.equals(thrust.get(n), 0)) {
|
||||
time.add(time.get(n));
|
||||
thrust.add(0.0);
|
||||
for (List l : lists) {
|
||||
Object o = l.get(n);
|
||||
l.add(o);
|
||||
}
|
||||
// Not-uncommon issue at start of thrust curves: two points
|
||||
// for t=0, one with thrust zero and one non-zero. We'll throw
|
||||
// out the 0-thrust point and go on.
|
||||
if (MathUtil.equals(time.get(0), 0) && MathUtil.equals(time.get(1), 0)) {
|
||||
time.remove(0);
|
||||
thrust.remove(0);
|
||||
}
|
||||
|
||||
// End
|
||||
// Ah, no, we don't want to do this (I'm leaving the dead code
|
||||
// in case there's a temptation to put it back in). This ends
|
||||
// up putting the new 0-thrust point at the same time as the
|
||||
// previous last datapoint, which will cause
|
||||
// ThrustCurveMotor.getAverageThrust() to fail when it tries
|
||||
// to interpolate (the exception is actually thrown by
|
||||
// MathUtil.map())
|
||||
//
|
||||
// int n = time.size() - 1;
|
||||
// if (!MathUtil.equals(thrust.get(n), 0)) {
|
||||
// time.add(time.get(n));
|
||||
// thrust.add(0.0);
|
||||
// for (List l : lists) {
|
||||
// Object o = l.get(n);
|
||||
// l.add(o);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -166,22 +166,30 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
throw new IllegalArgumentException("Too short thrust-curve, length=" + motor.time.length);
|
||||
}
|
||||
for (int i = 0; i < motor.time.length - 1; i++) {
|
||||
if (motor.time[i + 1] < motor.time[i]) {
|
||||
throw new IllegalArgumentException("Time goes backwards, " +
|
||||
if (motor.time[i + 1] <= motor.time[i]) {
|
||||
throw new IllegalArgumentException("Time stalls or goes backwards, " +
|
||||
"time[" + i + "]=" + motor.time[i] + " " +
|
||||
"time[" + (i + 1) + "]=" + motor.time[i + 1]);
|
||||
"time[" + (i + 1) + "]=" + motor.time[i + 1] +
|
||||
", thrust=(" + motor.thrust[i] + ", " + motor.thrust[i+1] + ")");
|
||||
}
|
||||
}
|
||||
if (!MathUtil.equals(motor.time[0], 0)) {
|
||||
throw new IllegalArgumentException("Curve starts at time " + motor.time[0]);
|
||||
}
|
||||
if (!MathUtil.equals(motor.thrust[0], 0)) {
|
||||
throw new IllegalArgumentException("Curve starts at thrust " + motor.thrust[0]);
|
||||
}
|
||||
if (!MathUtil.equals(motor.thrust[motor.thrust.length - 1], 0)) {
|
||||
throw new IllegalArgumentException("Curve ends at thrust " +
|
||||
motor.thrust[motor.thrust.length - 1]);
|
||||
}
|
||||
|
||||
// these conditions actually are error, but quite a few of
|
||||
// the files on thrustcurvemotor.org have one or the
|
||||
// other of them, and they make less of a difference to
|
||||
// the simulation result than the normal variation between motors.
|
||||
// if (!MathUtil.equals(motor.thrust[0], 0)) {
|
||||
// throw new IllegalArgumentException("Curve starts at thrust " + motor.thrust[0]);
|
||||
// }
|
||||
//
|
||||
// if (!MathUtil.equals(motor.thrust[motor.thrust.length - 1], 0)) {
|
||||
// throw new IllegalArgumentException("Curve ends at thrust " +
|
||||
// motor.thrust[motor.thrust.length - 1]);
|
||||
//}
|
||||
|
||||
for (double t : motor.thrust) {
|
||||
if (t < 0) {
|
||||
throw new IllegalArgumentException("Negative thrust.");
|
||||
@ -630,45 +638,51 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
maxThrust = t;
|
||||
}
|
||||
|
||||
|
||||
// Burn start time
|
||||
double thrustLimit = maxThrust * MARGINAL_THRUST;
|
||||
double burnStart, burnEnd;
|
||||
|
||||
int pos;
|
||||
for (pos = 1; pos < thrust.length; pos++) {
|
||||
if (thrust[pos] >= thrustLimit)
|
||||
break;
|
||||
if (thrust[0] >= thrustLimit)
|
||||
burnStart = time[0];
|
||||
else {
|
||||
int startPos;
|
||||
for (startPos = 1; startPos < thrust.length; startPos++) {
|
||||
if (thrust[startPos] >= thrustLimit)
|
||||
break;
|
||||
}
|
||||
if (startPos >= thrust.length) {
|
||||
throw new BugException("Could not compute burn start time, maxThrust=" + maxThrust +
|
||||
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
|
||||
}
|
||||
if (MathUtil.equals(thrust[startPos - 1], thrust[startPos])) {
|
||||
// For safety
|
||||
burnStart = (time[startPos - 1] + time[startPos]) / 2;
|
||||
} else {
|
||||
burnStart = MathUtil.map(thrustLimit, thrust[startPos - 1], thrust[startPos], time[startPos - 1], time[startPos]);
|
||||
}
|
||||
}
|
||||
if (pos >= thrust.length) {
|
||||
throw new BugException("Could not compute burn start time, maxThrust=" + maxThrust +
|
||||
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
|
||||
}
|
||||
if (MathUtil.equals(thrust[pos - 1], thrust[pos])) {
|
||||
// For safety
|
||||
burnStart = (time[pos - 1] + time[pos]) / 2;
|
||||
} else {
|
||||
burnStart = MathUtil.map(thrustLimit, thrust[pos - 1], thrust[pos], time[pos - 1], time[pos]);
|
||||
}
|
||||
|
||||
|
||||
// Burn end time
|
||||
for (pos = thrust.length - 2; pos >= 0; pos--) {
|
||||
if (thrust[pos] >= thrustLimit)
|
||||
break;
|
||||
if (thrust[thrust.length-1] >= thrustLimit)
|
||||
burnEnd = time[time.length-1];
|
||||
else {
|
||||
int endPos;
|
||||
for (endPos = thrust.length - 2; endPos >= 0; endPos--) {
|
||||
if (thrust[endPos] >= thrustLimit)
|
||||
break;
|
||||
}
|
||||
if (endPos < 0) {
|
||||
throw new BugException("Could not compute burn end time, maxThrust=" + maxThrust +
|
||||
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
|
||||
}
|
||||
if (MathUtil.equals(thrust[endPos], thrust[endPos + 1])) {
|
||||
// For safety
|
||||
burnEnd = (time[endPos] + time[endPos + 1]) / 2;
|
||||
} else {
|
||||
burnEnd = MathUtil.map(thrustLimit, thrust[endPos], thrust[endPos + 1],
|
||||
time[endPos], time[endPos + 1]);
|
||||
}
|
||||
}
|
||||
if (pos < 0) {
|
||||
throw new BugException("Could not compute burn end time, maxThrust=" + maxThrust +
|
||||
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
|
||||
}
|
||||
if (MathUtil.equals(thrust[pos], thrust[pos + 1])) {
|
||||
// For safety
|
||||
burnEnd = (time[pos] + time[pos + 1]) / 2;
|
||||
} else {
|
||||
burnEnd = MathUtil.map(thrustLimit, thrust[pos], thrust[pos + 1],
|
||||
time[pos], time[pos + 1]);
|
||||
}
|
||||
|
||||
|
||||
// Burn time
|
||||
burnTimeEstimate = Math.max(burnEnd - burnStart, 0);
|
||||
@ -677,12 +691,12 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
// Total impulse and average thrust
|
||||
totalImpulse = 0;
|
||||
averageThrust = 0;
|
||||
|
||||
for (pos = 0; pos < time.length - 1; pos++) {
|
||||
double t0 = time[pos];
|
||||
double t1 = time[pos + 1];
|
||||
double f0 = thrust[pos];
|
||||
double f1 = thrust[pos + 1];
|
||||
int impulsePos;
|
||||
for (impulsePos = 0; impulsePos < time.length - 1; impulsePos++) {
|
||||
double t0 = time[impulsePos];
|
||||
double t1 = time[impulsePos + 1];
|
||||
double f0 = thrust[impulsePos];
|
||||
double f1 = thrust[impulsePos + 1];
|
||||
|
||||
totalImpulse += (t1 - t0) * (f0 + f1) / 2;
|
||||
|
||||
|
@ -57,6 +57,8 @@ public class DownloadResponseParser implements ElementHandler {
|
||||
response.add(motorBurnFile);
|
||||
} else if (motor_id_tag.equals(element)) {
|
||||
motorBurnFile.setMotorId(Integer.parseInt(content));
|
||||
} else if (simfile_id_tag.equals(element)) {
|
||||
motorBurnFile.setSimfileId(Integer.parseInt(content));
|
||||
} else if (format_tag.equals(element)) {
|
||||
motorBurnFile.setFiletype(content);
|
||||
} else if (data_tag.equals(element)) {
|
||||
|
@ -11,8 +11,10 @@ import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
public class MotorBurnFile {
|
||||
|
||||
private Integer motorId;
|
||||
private Integer simfileId;
|
||||
private String filetype;
|
||||
private ThrustCurveMotor.Builder thrustCurveMotor;
|
||||
private String data;
|
||||
|
||||
public void init() {
|
||||
this.motorId = null;
|
||||
@ -29,8 +31,9 @@ public class MotorBurnFile {
|
||||
return clone;
|
||||
}
|
||||
|
||||
public void decodeFile(String data) throws IOException {
|
||||
data = Base64Decoder.decodeData(data);
|
||||
public void decodeFile(String _data) throws IOException {
|
||||
_data = Base64Decoder.decodeData(_data);
|
||||
data = _data;
|
||||
try {
|
||||
if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) {
|
||||
RASPMotorLoader loader = new RASPMotorLoader();
|
||||
@ -47,19 +50,33 @@ public class MotorBurnFile {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the motor_id
|
||||
* @return the motor id
|
||||
*/
|
||||
public Integer getMotorId() {
|
||||
return motorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param motor_id the motor_id to set
|
||||
* @param motorId the motor id to set
|
||||
*/
|
||||
public void setMotorId(Integer motorId) {
|
||||
this.motorId = motorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the simfile id
|
||||
*/
|
||||
public Integer getSimfileId() {
|
||||
return simfileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param simfileId the simfileId to set
|
||||
*/
|
||||
public void setSimfileId(Integer simfileId) {
|
||||
this.simfileId = simfileId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the filetype
|
||||
*/
|
||||
@ -81,4 +98,11 @@ public class MotorBurnFile {
|
||||
return thrustCurveMotor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file contents
|
||||
*/
|
||||
public String getContents() {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -115,37 +115,46 @@ public class SerializeThrustcurveMotors {
|
||||
System.out.println(message);
|
||||
|
||||
List<MotorBurnFile> b = getThrustCurvesForMotorId(mi.getMotor_id());
|
||||
|
||||
for (MotorBurnFile burnFile : b) {
|
||||
try {
|
||||
ThrustCurveMotor.Builder builder = burnFile.getThrustCurveMotor();
|
||||
if (builder == null) {
|
||||
continue;
|
||||
}
|
||||
if (mi.getTot_mass_g() != null) {
|
||||
builder.setInitialMass(mi.getTot_mass_g() / 1000.0);
|
||||
}
|
||||
if (mi.getProp_mass_g() != null) {
|
||||
// builder.setPropellantMass(mi.getProp_mass_g() / 1000.0);
|
||||
}
|
||||
|
||||
ThrustCurveMotor.Builder builder = burnFile.getThrustCurveMotor();
|
||||
if (builder == null) {
|
||||
continue;
|
||||
}
|
||||
if (mi.getTot_mass_g() != null) {
|
||||
builder.setInitialMass(mi.getTot_mass_g() / 1000.0);
|
||||
}
|
||||
if (mi.getProp_mass_g() != null) {
|
||||
// builder.setPropellantMass(mi.getProp_mass_g() / 1000.0);
|
||||
}
|
||||
builder.setCaseInfo(mi.getCase_info());
|
||||
builder.setPropellantInfo(mi.getProp_info());
|
||||
builder.setDiameter(mi.getDiameter() / 1000.0);
|
||||
builder.setLength(mi.getLength() / 1000.0);
|
||||
builder.setMotorType(type);
|
||||
|
||||
builder.setCaseInfo(mi.getCase_info());
|
||||
builder.setPropellantInfo(mi.getProp_info());
|
||||
builder.setDiameter(mi.getDiameter() / 1000.0);
|
||||
builder.setLength(mi.getLength() / 1000.0);
|
||||
builder.setMotorType(type);
|
||||
if ("OOP".equals(mi.getAvailiability())) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
builder.setAvailablity(false);
|
||||
} else if (mi.getDesignation().startsWith("Micro")) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
} else {
|
||||
builder.setDesignation(mi.getCommon_name());
|
||||
}
|
||||
|
||||
if ("OOP".equals(mi.getAvailiability())) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
builder.setAvailablity(false);
|
||||
} else if (mi.getDesignation().startsWith("Micro")) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
} else {
|
||||
builder.setDesignation(mi.getCommon_name());
|
||||
allMotors.add(builder.build());
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("\tError in simFile " + burnFile.getSimfileId() + ": " + e.getMessage() + " (continuing)");
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(("simfile-" + burnFile.getSimfileId()).toString());
|
||||
out.write(burnFile.getContents().getBytes());
|
||||
out.close();
|
||||
} catch (IOException i) {
|
||||
System.out.println("unable to write bad file: " + i.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
allMotors.add(builder.build());
|
||||
|
||||
}
|
||||
|
||||
System.out.println("\t curves: " + b.size());
|
||||
@ -160,12 +169,12 @@ public class SerializeThrustcurveMotors {
|
||||
try {
|
||||
b.addAll(ThrustCurveAPI.downloadData(motorId, "RockSim"));
|
||||
} catch (Exception ex) {
|
||||
System.out.println("\tError downloading RockSim");
|
||||
System.out.println("\tError downloading RockSim for motorID=" + motorId);
|
||||
}
|
||||
try {
|
||||
b.addAll(ThrustCurveAPI.downloadData(motorId, "RASP"));
|
||||
} catch (Exception ex) {
|
||||
System.out.println("\tError downloading RASP");
|
||||
System.out.println("\tError downloading RASP for motorID=" + motorId);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
1
openrocket.log
Normal file
1
openrocket.log
Normal file
@ -0,0 +1 @@
|
||||
Error: Unable to access jarfile OpenRocket.jar
|
Loading…
x
Reference in New Issue
Block a user