Change handling of Motor Digests. The computed digest value is now stored as a member variable in the ThrustCurveMotor and avaliable through the getDigest() method. getDigest() was added to the Motor interface. All references to MotorDigest.digestMotor() were removed from the application.

The android db now stores the digest.  Also changed persistance mechanism for delays to store as comma delimited string.

The TestMotorLoader is now failing because the digests have changed.
This commit is contained in:
Kevin Ruland 2012-01-15 02:46:13 +00:00
parent 8d90a540e8
commit 398f302dfc
19 changed files with 86 additions and 70 deletions

View File

@ -5,10 +5,47 @@ import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.util.Coordinate;
abstract class ConversionUtils {
static double[] stringToDelays( String value ) {
if (value == null || "".equals(value) ) {
return new double[0];
}
String[] parts = value.split(",");
double[] values = new double[parts.length];
for( int i =0; i<parts.length; i++ ) {
String p = parts[i];
if ( "P".equals(p) ) {
values[i] = Motor.PLUGGED;
} else {
double d = Double.parseDouble(p);
values[i] = d;
}
}
return values;
}
static String delaysToString( double[] delays ) {
StringBuilder s = new StringBuilder();
boolean first = true;
for( double d:delays ) {
if (!first) {
s .append(",");
} else {
first = false;
}
if ( d == Motor.PLUGGED ) {
s.append("P");
} else {
s.append(Math.round(d));
}
}
return s.toString();
}
static double[] deserializeArrayOfDouble( byte[] bytes ) throws Exception {
double[] data = null;
if (bytes != null ) {

View File

@ -13,7 +13,7 @@ public class DbAdapter {
private SQLiteDatabase mDb;
private static final String DATABASE_NAME = "rocketflightnotebook";
private static final int DATABASE_VERSION = 2;
private static final int DATABASE_VERSION = 3;
private final Context mCtx;

View File

@ -23,8 +23,9 @@ public class MotorDao {
"create table "+ DATABASE_TABLE + " ( " +
"_id integer primary key, "+
"unique_name text unique, "+
"digest string, " +
"designation text, "+
"delays blob, "+
"delays text, "+
"diameter number, "+
"tot_impulse_ns number, "+
"avg_thrust_n number, "+
@ -54,6 +55,7 @@ public class MotorDao {
public final static String ID = "_id";
public final static String UNIQUE_NAME = "unique_name";
public final static String DIGEST = "digest";
public final static String DESIGNATION = "designation";
public final static String DELAYS = "delays";
public final static String DIAMETER = "diameter";
@ -72,6 +74,7 @@ public class MotorDao {
private final static String[] ALL_COLS = new String[] {
ID,
DIGEST,
DESIGNATION ,
DELAYS ,
DIAMETER ,
@ -94,8 +97,9 @@ public class MotorDao {
final ThrustCurveMotor tcm = mi.getThrustCurveMotor();
initialValues.put(ID, mi.getId());
initialValues.put(UNIQUE_NAME, tcm.getManufacturer()+tcm.getDesignation());
initialValues.put(DIGEST, tcm.getDigest());
initialValues.put(DESIGNATION, tcm.getDesignation());
initialValues.put(DELAYS, ConversionUtils.serializeArrayOfDouble(tcm.getStandardDelays()));
initialValues.put(DELAYS, ConversionUtils.delaysToString(tcm.getStandardDelays()));
initialValues.put(DIAMETER,tcm.getDiameter());
initialValues.put(TOTAL_IMPULSE,tcm.getTotalImpulseEstimate());
initialValues.put(AVG_THRUST,tcm.getAverageThrustEstimate());
@ -187,8 +191,10 @@ public class MotorDao {
mi.setImpulseClass(mCursor.getString(mCursor.getColumnIndex(IMPULSE_CLASS)));
{
String digest = mCursor.getString(mCursor.getColumnIndex(DIGEST));
String designation = mCursor.getString(mCursor.getColumnIndex(DESIGNATION));
double[] delays = ConversionUtils.deserializeArrayOfDouble( mCursor.getBlob(mCursor.getColumnIndex(DELAYS)));
String delayString = mCursor.getString(mCursor.getColumnIndex(DELAYS));
double[] delays = ConversionUtils.stringToDelays(delayString);
double diameter = mCursor.getDouble(mCursor.getColumnIndex(DIAMETER));
double totImpulse = mCursor.getDouble(mCursor.getColumnIndex(TOTAL_IMPULSE));
double avgImpulse = mCursor.getDouble(mCursor.getColumnIndex(AVG_THRUST));
@ -209,7 +215,8 @@ public class MotorDao {
length,
timeData,
thrustData,
cgData
cgData,
digest
);
mi.setThrustCurveMotor(tcm);
}
@ -265,27 +272,4 @@ public class MotorDao {
}
public static String extractPrettyDelayString( Cursor c ) {
byte[] blob = c.getBlob(c.getColumnIndex(MotorDao.DELAYS));
String s = "";
try {
double[] delayarry = ConversionUtils.deserializeArrayOfDouble(blob);
boolean first = true;
for( double d:delayarry ) {
if (!first) {
s += ",";
} else {
first = false;
}
if ( d == Motor.PLUGGED ) {
s+= "P";
} else {
s += Math.round(d);
}
}
} catch ( Exception ex ) {
}
return s;
}
}

View File

@ -76,9 +76,6 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
return groupPosition;
}
//new String[] { MotorDao.MANUFACTURER, MotorDao.DESIGNATION, MotorDao.CASE_INFO, MotorDao.TOTAL_IMPULSE }, // Number for child layouts
//new int[] { R.id.motorChildManu, R.id.motorChildName, R.id.motorChildDelays, R.id.motorChildImpulse }
/* (non-Javadoc)
* @see android.widget.CursorTreeAdapter#bindChildView(android.view.View, android.content.Context, android.database.Cursor, boolean)
*/
@ -93,7 +90,7 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
desig.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DESIGNATION)));
TextView delays = (TextView) arg0.findViewById(R.id.motorChildDelays);
delays.setText( MotorDao.extractPrettyDelayString( arg2 ));
delays.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DELAYS)));
TextView totImpulse = (TextView) arg0.findViewById(R.id.motorChildImpulse);
totImpulse.setText( arg2.getString(arg2.getColumnIndex(MotorDao.TOTAL_IMPULSE)));

View File

@ -14,7 +14,6 @@ import net.sf.openrocket.motor.DesignationComparator;
import net.sf.openrocket.motor.Manufacturer;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.Motor.Type;
import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.MathUtil;
@ -95,7 +94,7 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
// Check whether to add as new motor or overwrite existing
final String digest = MotorDigest.digestMotor(motor);
final String digest = motor.getDigest();
for (int index = 0; index < motors.size(); index++) {
Motor m = motors.get(index);

View File

@ -196,15 +196,13 @@ public class RASPMotorLoader extends AbstractMotorLoader {
motorDigest.update(DataType.TIME_ARRAY, timeArray);
motorDigest.update(DataType.MASS_SPECIFIC, totalW, totalW - propW);
motorDigest.update(DataType.FORCE_PER_TIME, thrustArray);
// TODO: HIGH: Motor digest?
// final String digest = motorDigest.getDigest();
final String digest = motorDigest.getDigest();
try {
Manufacturer m = Manufacturer.getManufacturer(manufacturer);
return new ThrustCurveMotor(m, designation, comment, m.getMotorType(),
delays, diameter, length, timeArray, thrustArray, cgArray);
delays, diameter, length, timeArray, thrustArray, cgArray, digest);
} catch (IllegalArgumentException e) {

View File

@ -353,8 +353,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
motorDigest.update(DataType.CG_PER_TIME, toArray(cg));
}
motorDigest.update(DataType.FORCE_PER_TIME, thrustArray);
// TODO: HIGH: Motor digest?
// final String digest = motorDigest.getDigest();
final String digest = motorDigest.getDigest();
try {
@ -372,7 +371,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
}
return new ThrustCurveMotor(m, designation, description, t,
delays, diameter, length, timeArray, thrustArray, cgArray);
delays, diameter, length, timeArray, thrustArray, cgArray, digest);
} catch (IllegalArgumentException e) {
throw new SAXException("Illegal motor data", e);
}

View File

@ -23,8 +23,6 @@ import net.sf.openrocket.file.simplesax.SimpleSAX;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.rocketcomponent.BodyComponent;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.Bulkhead;
@ -1015,7 +1013,7 @@ class MotorHandler extends ElementHandler {
// One motor
if (motors.size() == 1) {
Motor m = motors.get(0);
if (digest != null && !MotorDigest.digestMotor(m).equals(digest)) {
if (digest != null && !digest.equals(m.getDigest())) {
String str = "Motor with designation '" + designation + "'";
if (manufacturer != null)
str += " for manufacturer '" + manufacturer + "'";
@ -1030,7 +1028,7 @@ class MotorHandler extends ElementHandler {
// Check for motor with correct digest
for (Motor m : motors) {
if (MotorDigest.digestMotor(m).equals(digest)) {
if (digest.equals(m.getDigest())) {
return m;
}
}
@ -1045,7 +1043,7 @@ class MotorHandler extends ElementHandler {
// No digest, check for preferred digest (OpenRocket <= 1.1.0)
// TODO: MEDIUM: This should only be done for document versions 1.1 and below
for (Motor m : motors) {
if (PreferredMotorDigests.DIGESTS.contains(MotorDigest.digestMotor(m))) {
if (PreferredMotorDigests.DIGESTS.contains(m.getDigest())) {
return m;
}
}

View File

@ -7,7 +7,6 @@ import java.util.List;
import net.sf.openrocket.file.RocketSaver;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.MotorMount;
@ -128,7 +127,7 @@ public class RocketComponentSaver {
ThrustCurveMotor m = (ThrustCurveMotor) motor;
elements.add(" <manufacturer>" + RocketSaver.escapeXML(m.getManufacturer().getSimpleName()) +
"</manufacturer>");
elements.add(" <digest>" + MotorDigest.digestMotor(m) + "</digest>");
elements.add(" <digest>" + m.getDigest() + "</digest>");
}
elements.add(" <designation>" + RocketSaver.escapeXML(motor.getDesignation()) + "</designation>");
elements.add(" <diameter>" + motor.getDiameter() + "</diameter>");

View File

@ -589,7 +589,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
// Store selected motor in preferences node, set all others to false
Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE);
for (ThrustCurveMotor m : set.getMotors()) {
String digest = MotorDigest.digestMotor(m);
String digest = m.getDigest();
prefs.putBoolean(digest, m == motor);
}
}
@ -689,7 +689,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
selectedMotor.getEmptyCG().weight));
dataPointsLabel.setText("" + (selectedMotor.getTimePoints().length - 1));
if (digestLabel != null) {
digestLabel.setText(MotorDigest.digestMotor(selectedMotor));
digestLabel.setText(selectedMotor.getDigest());
}
setComment(selectedMotor.getDescription());
@ -819,7 +819,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
List<ThrustCurveMotor> list = set.getMotors();
Preferences prefs = ((SwingPreferences) Application.getPreferences()).getNode(net.sf.openrocket.startup.Preferences.PREFERRED_THRUST_CURVE_MOTOR_NODE);
for (ThrustCurveMotor m : list) {
String digest = MotorDigest.digestMotor(m);
String digest = m.getDigest();
if (prefs.getBoolean(digest, false)) {
return m;
}

View File

@ -128,6 +128,7 @@ public interface Motor {
*/
public double getLength();
public String getDigest();
public MotorInstance getInstance();

View File

@ -1,6 +1,5 @@
package net.sf.openrocket.motor;
import java.io.Serializable;
import java.text.Collator;
import java.util.Arrays;
import java.util.Locale;
@ -26,7 +25,7 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor> {
}
private static final DesignationComparator DESIGNATION_COMPARATOR = new DesignationComparator();
private final String digest;
private final Manufacturer manufacturer;
private final String designation;
@ -61,8 +60,8 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor> {
*/
public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description,
Motor.Type type, double[] delays, double diameter, double length,
double[] time, double[] thrust, Coordinate[] cg) {
double[] time, double[] thrust, Coordinate[] cg, String digest) {
this.digest = digest;
// Check argument validity
if ((time.length != thrust.length) || (time.length != cg.length)) {
throw new IllegalArgumentException("Array lengths do not match, " +
@ -253,6 +252,10 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor> {
return totalImpulse;
}
@Override
public String getDigest() {
return digest;
}
/**

View File

@ -129,7 +129,7 @@ public class MotorCorrelation {
// Output motor digests
final int count = motors.size();
for (int i = 0; i < count; i++) {
System.out.println(files.get(i) + ": " + MotorDigest.digestMotor((ThrustCurveMotor) motors.get(i)));
System.out.println(files.get(i) + ": " + ((ThrustCurveMotor) motors.get(i)).getDigest());
}
// Cross-correlate every pair

View File

@ -47,7 +47,7 @@ public class MotorDigester {
continue;
}
String digest = MotorDigest.digestMotor((ThrustCurveMotor) m);
String digest = ((ThrustCurveMotor) m).getDigest();
if (printFileNames) {
System.out.print(file + ": ");
}

View File

@ -39,7 +39,7 @@ public class MotorPrinter {
System.out.printf(" Total impulse: %.2f Ns\n", m.getTotalImpulseEstimate());
System.out.println(" Diameter: " + m.getDiameter() * 1000 + " mm");
System.out.println(" Length: " + m.getLength() * 1000 + " mm");
System.out.println(" Digest: " + MotorDigest.digestMotor(m));
System.out.println(" Digest: " + m.getDigest());
if (m instanceof ThrustCurveMotor) {
ThrustCurveMotor tc = (ThrustCurveMotor) m;

View File

@ -28,15 +28,15 @@ public class MotorSetDatabaseTest {
this.addMotor(new ThrustCurveMotor(Manufacturer.getManufacturer("A"),
"Foo", "Desc", Motor.Type.SINGLE, new double[] { 0 },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}));
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestA"));
this.addMotor(new ThrustCurveMotor(Manufacturer.getManufacturer("A"),
"Bar", "Desc", Motor.Type.SINGLE, new double[] { 0 },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}));
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestB"));
this.addMotor(new ThrustCurveMotor(Manufacturer.getManufacturer("A"),
"Foo", "Desc", Motor.Type.UNKNOWN, new double[] { 0 },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}));
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestA"));
}
};

View File

@ -19,25 +19,25 @@ public class ThrustCurveMotorSetTest {
Manufacturer.getManufacturer("A"),
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] { },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL});
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestA");
private static final ThrustCurveMotor motor2 = new ThrustCurveMotor(
Manufacturer.getManufacturer("A"),
"F12H", "Desc", Motor.Type.SINGLE, new double[] { 5 },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL});
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestB");
private static final ThrustCurveMotor motor3 = new ThrustCurveMotor(
Manufacturer.getManufacturer("A"),
"F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 2, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL});
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestC");
private static final ThrustCurveMotor motor4 = new ThrustCurveMotor(
Manufacturer.getManufacturer("A"),
"F12", "Desc", Motor.Type.HYBRID, new double[] { 0 },
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 2, 0},
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL});
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestD");
@Test

View File

@ -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;
@ -8,7 +10,6 @@ import java.util.Arrays;
import java.util.List;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.ThrustCurveMotor;
import org.junit.Test;
@ -52,12 +53,12 @@ public class TestMotorLoader {
String[] d = new String[digests.length];
for (int i = 0; i < motors.size(); i++) {
d[i] = MotorDigest.digestMotor((ThrustCurveMotor) motors.get(i));
d[i] = ((ThrustCurveMotor) motors.get(i)).getDigest();
}
Arrays.sort(digests);
Arrays.sort(d);
assertTrue(Arrays.equals(d, digests));
assertTrue("d = " + Arrays.toString(d) + " digests = " + Arrays.toString(digests), Arrays.equals(d, digests));
}
}

View File

@ -26,7 +26,7 @@ public class ThrustCurveMotorTest {
new Coordinate(0.02,0,0,0.05),
new Coordinate(0.02,0,0,0.05),
new Coordinate(0.03,0,0,0.03)
});
}, "digestA");
@Test
public void testMotorData() {