commit
b5cde10824
Binary file not shown.
@ -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);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
1
openrocket.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
Error: Unable to access jarfile OpenRocket.jar
|
Loading…
x
Reference in New Issue
Block a user