diff --git a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
index 365a47d53..842ce41fd 100644
--- a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java
@@ -15,7 +15,7 @@ import net.sf.openrocket.util.MathUtil;
public abstract class AbstractMotorLoader implements MotorLoader {
-
+
/**
* {@inheritDoc}
*
@@ -40,7 +40,6 @@ public abstract class AbstractMotorLoader implements MotorLoader {
protected abstract List load(Reader reader, String filename) throws IOException;
-
/**
* Return the default charset to use when loading rocket files of this type.
*
@@ -52,11 +51,11 @@ public abstract class AbstractMotorLoader implements MotorLoader {
protected abstract Charset getDefaultCharset();
-
-
+
+
////////// Helper methods //////////
-
+
/**
* Calculate the mass of a motor at distinct points in time based on the
* initial total mass, propellant weight and thrust.
@@ -88,6 +87,7 @@ public abstract class AbstractMotorLoader implements MotorLoader {
double f1 = thrust.get(i);
double dm = 0.5 * (f0 + f1) * (t1 - t0);
+
deltam.add(dm);
totalMassChange += dm;
t0 = t1;
@@ -99,13 +99,16 @@ public abstract class AbstractMotorLoader implements MotorLoader {
scale = prop / totalMassChange;
for (double dm : deltam) {
total -= dm * scale;
+ // to correct negative mass error condition: (caused by rounding errors in the above loop)
+ if (total < 0) {
+ total = 0;
+ }
mass.add(total);
+
}
-
return mass;
}
-
/**
* Helper method to remove a delay (or plugged) from the end of a motor designation,
* if present.
@@ -121,7 +124,6 @@ public abstract class AbstractMotorLoader implements MotorLoader {
}
-
/**
* Helper method to tokenize a string using whitespace as the delimiter.
*/
@@ -168,7 +170,7 @@ public abstract class AbstractMotorLoader implements MotorLoader {
}
-
+
@SuppressWarnings("unchecked")
protected static void finalizeThrustCurve(List time, List thrust,
List... lists) {
diff --git a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
index ec1bd3156..838e2d8fa 100644
--- a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
+++ b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
@@ -135,8 +135,8 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
private final double initMass;
private final double propMass;
private final Motor.Type type;
- private boolean calculateMass;
- private boolean calculateCG;
+ private boolean calculateMass = false;
+ private boolean calculateCG = false;
private String description = "";
@@ -324,8 +324,8 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
if (time == null || time.size() == 0)
throw new SAXException("Illegal motor data");
-
finalizeThrustCurve(time, force, mass, cg);
+
final int n = time.size();
if (hasIllegalValue(mass))
@@ -336,6 +336,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
if (calculateMass) {
mass = calculateMass(time, force, initMass, propMass);
}
+
if (calculateCG) {
for (int i = 0; i < n; i++) {
cg.set(i, length / 2);
diff --git a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java
index 3a0e71a2a..888882af9 100644
--- a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java
+++ b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java
@@ -134,11 +134,14 @@ public class ThrustCurveMotor implements Motor, Comparable, Se
if (c.isNaN()) {
throw new IllegalArgumentException("Invalid CG " + c);
}
- if (c.x < 0 || c.x > length) {
- throw new IllegalArgumentException("Invalid CG position " + c.x);
+ if (c.x < 0) {
+ throw new IllegalArgumentException("Invalid CG position " + String.format("%f", c.x) + ": CG is below the start of the motor.");
+ }
+ if (c.x > length) {
+ throw new IllegalArgumentException("Invalid CG position: " + String.format("%f", c.x) + ": CG is above the end of the motor.");
}
if (c.weight < 0) {
- throw new IllegalArgumentException("Negative mass " + c.weight);
+ throw new IllegalArgumentException("Negative mass " + c.weight + "at time=" + time[Arrays.asList(cg).indexOf(c)]);
}
}
diff --git a/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java b/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java
index dbc23e745..ee8e47978 100644
--- a/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java
+++ b/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java
@@ -1,6 +1,8 @@
package net.sf.openrocket.file.motor;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
@@ -16,6 +18,7 @@ public class TestMotorLoader {
private static final String DIGEST1 = "e523030bc96d5e63313b5723aaea267d";
private static final String DIGEST2 = "6a41f0f10b7283793eb0e6b389753729";
+ private static final String DIGEST3 = "e3164a735f9a50500f2725f0a33d246b";
@Test
@@ -25,7 +28,7 @@ public class TestMotorLoader {
test(loader, "test1.eng", DIGEST1);
test(loader, "test2.rse", DIGEST2);
test(loader, "test.zip", DIGEST2, DIGEST1);
-
+ test(loader, "test3.rse", DIGEST3);
}
@Test
@@ -38,6 +41,11 @@ public class TestMotorLoader {
test(new RockSimMotorLoader(), "test2.rse", DIGEST2);
}
+ @Test
+ public void testRocksimMotorLoader3() throws IOException {
+ test(new RockSimMotorLoader(), "test3.rse", DIGEST3);
+ }
+
@Test
public void testZipMotorLoader() throws IOException {
test(new ZipFileMotorLoader(), "test.zip", DIGEST2, DIGEST1);
diff --git a/core/test/net/sf/openrocket/file/motor/test3.rse b/core/test/net/sf/openrocket/file/motor/test3.rse
new file mode 100644
index 000000000..95a86c555
--- /dev/null
+++ b/core/test/net/sf/openrocket/file/motor/test3.rse
@@ -0,0 +1,27 @@
+
+
+
+ Water Rocket, 90 psi, 800g
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+