Merge pull request #519 from JoePfeiffer/fix-516

fix issue 516
This commit is contained in:
Wes Cravens 2019-05-29 10:25:33 -05:00 committed by GitHub
commit b5cde10824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 168 additions and 95 deletions

View File

@ -179,7 +179,14 @@ public abstract class AbstractMotorLoader implements MotorLoader {
return; return;
// Start // 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); time.add(0, 0.0);
thrust.add(0, 0.0); thrust.add(0, 0.0);
for (List l : lists) { for (List l : lists) {
@ -188,16 +195,32 @@ public abstract class AbstractMotorLoader implements MotorLoader {
} }
} }
// 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 // End
int n = time.size() - 1; // Ah, no, we don't want to do this (I'm leaving the dead code
if (!MathUtil.equals(thrust.get(n), 0)) { // in case there's a temptation to put it back in). This ends
time.add(time.get(n)); // up putting the new 0-thrust point at the same time as the
thrust.add(0.0); // previous last datapoint, which will cause
for (List l : lists) { // ThrustCurveMotor.getAverageThrust() to fail when it tries
Object o = l.get(n); // to interpolate (the exception is actually thrown by
l.add(o); // 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);
// }
// }
} }
} }

View File

@ -166,22 +166,30 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
throw new IllegalArgumentException("Too short thrust-curve, length=" + motor.time.length); throw new IllegalArgumentException("Too short thrust-curve, length=" + motor.time.length);
} }
for (int i = 0; i < motor.time.length - 1; i++) { for (int i = 0; i < motor.time.length - 1; i++) {
if (motor.time[i + 1] < motor.time[i]) { if (motor.time[i + 1] <= motor.time[i]) {
throw new IllegalArgumentException("Time goes backwards, " + throw new IllegalArgumentException("Time stalls or goes backwards, " +
"time[" + i + "]=" + motor.time[i] + " " + "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)) { if (!MathUtil.equals(motor.time[0], 0)) {
throw new IllegalArgumentException("Curve starts at time " + motor.time[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]); // these conditions actually are error, but quite a few of
} // the files on thrustcurvemotor.org have one or the
if (!MathUtil.equals(motor.thrust[motor.thrust.length - 1], 0)) { // other of them, and they make less of a difference to
throw new IllegalArgumentException("Curve ends at thrust " + // the simulation result than the normal variation between motors.
motor.thrust[motor.thrust.length - 1]); // 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) { for (double t : motor.thrust) {
if (t < 0) { if (t < 0) {
throw new IllegalArgumentException("Negative thrust."); throw new IllegalArgumentException("Negative thrust.");
@ -630,45 +638,51 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
maxThrust = t; maxThrust = t;
} }
// Burn start time // Burn start time
double thrustLimit = maxThrust * MARGINAL_THRUST; double thrustLimit = maxThrust * MARGINAL_THRUST;
double burnStart, burnEnd; double burnStart, burnEnd;
int pos; if (thrust[0] >= thrustLimit)
for (pos = 1; pos < thrust.length; pos++) { burnStart = time[0];
if (thrust[pos] >= thrustLimit) else {
int startPos;
for (startPos = 1; startPos < thrust.length; startPos++) {
if (thrust[startPos] >= thrustLimit)
break; break;
} }
if (pos >= thrust.length) { if (startPos >= thrust.length) {
throw new BugException("Could not compute burn start time, maxThrust=" + maxThrust + throw new BugException("Could not compute burn start time, maxThrust=" + maxThrust +
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust)); " limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
} }
if (MathUtil.equals(thrust[pos - 1], thrust[pos])) { if (MathUtil.equals(thrust[startPos - 1], thrust[startPos])) {
// For safety // For safety
burnStart = (time[pos - 1] + time[pos]) / 2; burnStart = (time[startPos - 1] + time[startPos]) / 2;
} else { } else {
burnStart = MathUtil.map(thrustLimit, thrust[pos - 1], thrust[pos], time[pos - 1], time[pos]); burnStart = MathUtil.map(thrustLimit, thrust[startPos - 1], thrust[startPos], time[startPos - 1], time[startPos]);
}
} }
// Burn end time // Burn end time
for (pos = thrust.length - 2; pos >= 0; pos--) { if (thrust[thrust.length-1] >= thrustLimit)
if (thrust[pos] >= thrustLimit) burnEnd = time[time.length-1];
else {
int endPos;
for (endPos = thrust.length - 2; endPos >= 0; endPos--) {
if (thrust[endPos] >= thrustLimit)
break; break;
} }
if (pos < 0) { if (endPos < 0) {
throw new BugException("Could not compute burn end time, maxThrust=" + maxThrust + throw new BugException("Could not compute burn end time, maxThrust=" + maxThrust +
" limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust)); " limit=" + thrustLimit + " thrust=" + Arrays.toString(thrust));
} }
if (MathUtil.equals(thrust[pos], thrust[pos + 1])) { if (MathUtil.equals(thrust[endPos], thrust[endPos + 1])) {
// For safety // For safety
burnEnd = (time[pos] + time[pos + 1]) / 2; burnEnd = (time[endPos] + time[endPos + 1]) / 2;
} else { } else {
burnEnd = MathUtil.map(thrustLimit, thrust[pos], thrust[pos + 1], burnEnd = MathUtil.map(thrustLimit, thrust[endPos], thrust[endPos + 1],
time[pos], time[pos + 1]); time[endPos], time[endPos + 1]);
}
} }
// Burn time // Burn time
burnTimeEstimate = Math.max(burnEnd - burnStart, 0); burnTimeEstimate = Math.max(burnEnd - burnStart, 0);
@ -677,12 +691,12 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
// Total impulse and average thrust // Total impulse and average thrust
totalImpulse = 0; totalImpulse = 0;
averageThrust = 0; averageThrust = 0;
int impulsePos;
for (pos = 0; pos < time.length - 1; pos++) { for (impulsePos = 0; impulsePos < time.length - 1; impulsePos++) {
double t0 = time[pos]; double t0 = time[impulsePos];
double t1 = time[pos + 1]; double t1 = time[impulsePos + 1];
double f0 = thrust[pos]; double f0 = thrust[impulsePos];
double f1 = thrust[pos + 1]; double f1 = thrust[impulsePos + 1];
totalImpulse += (t1 - t0) * (f0 + f1) / 2; totalImpulse += (t1 - t0) * (f0 + f1) / 2;

View File

@ -57,6 +57,8 @@ public class DownloadResponseParser implements ElementHandler {
response.add(motorBurnFile); response.add(motorBurnFile);
} else if (motor_id_tag.equals(element)) { } else if (motor_id_tag.equals(element)) {
motorBurnFile.setMotorId(Integer.parseInt(content)); motorBurnFile.setMotorId(Integer.parseInt(content));
} else if (simfile_id_tag.equals(element)) {
motorBurnFile.setSimfileId(Integer.parseInt(content));
} else if (format_tag.equals(element)) { } else if (format_tag.equals(element)) {
motorBurnFile.setFiletype(content); motorBurnFile.setFiletype(content);
} else if (data_tag.equals(element)) { } else if (data_tag.equals(element)) {

View File

@ -11,8 +11,10 @@ import net.sf.openrocket.motor.ThrustCurveMotor;
public class MotorBurnFile { public class MotorBurnFile {
private Integer motorId; private Integer motorId;
private Integer simfileId;
private String filetype; private String filetype;
private ThrustCurveMotor.Builder thrustCurveMotor; private ThrustCurveMotor.Builder thrustCurveMotor;
private String data;
public void init() { public void init() {
this.motorId = null; this.motorId = null;
@ -29,8 +31,9 @@ public class MotorBurnFile {
return clone; return clone;
} }
public void decodeFile(String data) throws IOException { public void decodeFile(String _data) throws IOException {
data = Base64Decoder.decodeData(data); _data = Base64Decoder.decodeData(_data);
data = _data;
try { try {
if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) { if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) {
RASPMotorLoader loader = new RASPMotorLoader(); RASPMotorLoader loader = new RASPMotorLoader();
@ -47,19 +50,33 @@ public class MotorBurnFile {
} }
/** /**
* @return the motor_id * @return the motor id
*/ */
public Integer getMotorId() { public Integer getMotorId() {
return motorId; return motorId;
} }
/** /**
* @param motor_id the motor_id to set * @param motorId the motor id to set
*/ */
public void setMotorId(Integer motorId) { public void setMotorId(Integer motorId) {
this.motorId = 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 * @return the filetype
*/ */
@ -81,4 +98,11 @@ public class MotorBurnFile {
return thrustCurveMotor; return thrustCurveMotor;
} }
/**
* @return the file contents
*/
public String getContents() {
return data;
}
} }

View File

@ -115,9 +115,8 @@ public class SerializeThrustcurveMotors {
System.out.println(message); System.out.println(message);
List<MotorBurnFile> b = getThrustCurvesForMotorId(mi.getMotor_id()); List<MotorBurnFile> b = getThrustCurvesForMotorId(mi.getMotor_id());
for (MotorBurnFile burnFile : b) { for (MotorBurnFile burnFile : b) {
try {
ThrustCurveMotor.Builder builder = burnFile.getThrustCurveMotor(); ThrustCurveMotor.Builder builder = burnFile.getThrustCurveMotor();
if (builder == null) { if (builder == null) {
continue; continue;
@ -126,7 +125,7 @@ public class SerializeThrustcurveMotors {
builder.setInitialMass(mi.getTot_mass_g() / 1000.0); builder.setInitialMass(mi.getTot_mass_g() / 1000.0);
} }
if (mi.getProp_mass_g() != null) { if (mi.getProp_mass_g() != null) {
// builder.setPropellantMass(mi.getProp_mass_g() / 1000.0); // builder.setPropellantMass(mi.getProp_mass_g() / 1000.0);
} }
builder.setCaseInfo(mi.getCase_info()); builder.setCaseInfo(mi.getCase_info());
@ -145,6 +144,16 @@ public class SerializeThrustcurveMotors {
} }
allMotors.add(builder.build()); 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());
}
}
} }
@ -160,12 +169,12 @@ public class SerializeThrustcurveMotors {
try { try {
b.addAll(ThrustCurveAPI.downloadData(motorId, "RockSim")); b.addAll(ThrustCurveAPI.downloadData(motorId, "RockSim"));
} catch (Exception ex) { } catch (Exception ex) {
System.out.println("\tError downloading RockSim"); System.out.println("\tError downloading RockSim for motorID=" + motorId);
} }
try { try {
b.addAll(ThrustCurveAPI.downloadData(motorId, "RASP")); b.addAll(ThrustCurveAPI.downloadData(motorId, "RASP"));
} catch (Exception ex) { } catch (Exception ex) {
System.out.println("\tError downloading RASP"); System.out.println("\tError downloading RASP for motorID=" + motorId);
} }
return b; return b;
} }

1
openrocket.log Normal file
View File

@ -0,0 +1 @@
Error: Unable to access jarfile OpenRocket.jar