Reimplement motor handling so the android application relies more heavily on the OR core ThrustCurveMotor class. This involved changing the database schema and querying mechanisms. Rewriting the thrust curve download logic in net.sf.openrocket.android.thrustcurve. Fixing the motor browser, motor details, and burn plot activities. The file parsing now uses the RSE and RSP parsers from OR core.

ExtendedThrustCurveMotor class was created to hold the additional data required by the db ( the id in particular) along with the data which is useful to the browser (case info and impulse class).
This commit is contained in:
Kevin Ruland 2012-01-12 19:51:28 +00:00
parent 4900b84551
commit fe5a8eccfb
20 changed files with 566 additions and 670 deletions

View File

@ -2,7 +2,7 @@
<classpath>
<classpathentry kind="src" path="gen"/>
<classpathentry including="l10n/**/*" kind="src" path="core-resources"/>
<classpathentry excluding="net/sf/openrocket/file/CSVExport.java|net/sf/openrocket/file/motor/|net/sf/openrocket/file/rocksim/export/|net/sf/openrocket/gui/|net/sf/openrocket/startup/Startup.java|net/sf/openrocket/startup/Startup2.java|net/sf/openrocket/startup/VersionHelper.java|net/sf/openrocket/utils/" kind="src" path="core"/>
<classpathentry excluding="net/sf/openrocket/file/CSVExport.java|net/sf/openrocket/file/rocksim/export/|net/sf/openrocket/gui/|net/sf/openrocket/startup/Startup.java|net/sf/openrocket/startup/Startup2.java|net/sf/openrocket/startup/VersionHelper.java|net/sf/openrocket/utils/|net/sf/openrocket/file/motor/MotorLoaderHelper.java" kind="src" path="core"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>

View File

@ -35,6 +35,20 @@
android:editable="false" />
</TableRow>
<TableRow >
<TextView
android:paddingRight="10px"
android:text="Delays" />
<EditText
android:id="@+id/motorDetailsDelays"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.04"
android:editable="false" />
</TableRow>
<TableRow >
<TextView

View File

@ -1,4 +1,4 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:gravity="center_vertical"
@ -8,7 +8,6 @@
android:id="@+id/motorChildManu"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
@ -21,21 +20,48 @@
android:id="@+id/motorChildName"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_toRightOf="@id/motorChildManu"
android:gravity="center_vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:text="Motor Name"
android:textColor="#ffCCCC22"
android:textSize="17dip"
android:textStyle="bold" >
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="45dip"
android:gravity="center_vertical"
android:text="-"
android:paddingLeft="2dip"
android:paddingRight="2dip"
android:textColor="#ffCCCC22"
android:textSize="17dip"
android:textStyle="bold" >
</TextView>
<TextView
android:id="@+id/motorChildDelays"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_weight="0"
android:gravity="center_vertical"
android:paddingRight="5dip"
android:text=""
android:textColor="#ffCCCC22"
android:textSize="17dip"
android:textStyle="bold" >
</TextView>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2" />
<TextView
android:id="@+id/motorChildImpulse"
android:layout_width="wrap_content"
android:layout_height="45dip"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
@ -45,4 +71,4 @@
android:textStyle="bold" >
</TextView>
</RelativeLayout>
</LinearLayout>

View File

@ -2,13 +2,11 @@ package net.sf.openrocket.android;
import java.util.Locale;
import android.preference.PreferenceManager;
import net.sf.openrocket.database.ThrustCurveMotorSetDatabase;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.l10n.DebugTranslator;
import net.sf.openrocket.l10n.ResourceBundleTranslator;
import net.sf.openrocket.l10n.Translator;
import android.preference.PreferenceManager;
public class Application extends android.app.Application {
@ -17,7 +15,7 @@ public class Application extends android.app.Application {
// Big B boolean so I can synchronize on it.
private static Boolean initialized = false;
public static void initialize() {
public void initialize() {
synchronized (initialized) {
if ( initialized == true ) {
return;
@ -30,13 +28,7 @@ public class Application extends android.app.Application {
net.sf.openrocket.startup.Application.setPreferences( new PreferencesAdapter() );
ThrustCurveMotorSetDatabase db = new ThrustCurveMotorSetDatabase(false) {
@Override
protected void loadMotors() {
}
};
db.startLoading();
MotorDatabaseAdapter db = new MotorDatabaseAdapter(this);
net.sf.openrocket.startup.Application.setMotorSetDatabase(db);
@ -53,7 +45,6 @@ public class Application extends android.app.Application {
}
public Application() {
initialize();
}
/* (non-Javadoc)
@ -62,6 +53,7 @@ public class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
initialize();
PreferencesActivity.initializePreferences(this, PreferenceManager.getDefaultSharedPreferences(this));
}

View File

@ -0,0 +1,45 @@
package net.sf.openrocket.android;
import java.util.Collections;
import java.util.List;
import net.sf.openrocket.android.db.DbAdapter;
import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;
import net.sf.openrocket.database.MotorDatabase;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.Motor.Type;
import android.content.Context;
import android.util.Log;
public class MotorDatabaseAdapter implements MotorDatabase {
private final static String TAG = "MotorDatabaseAdapter";
private DbAdapter mDbHelper;
public MotorDatabaseAdapter( Context ctx ) {
mDbHelper = new DbAdapter(ctx);
mDbHelper.open();
}
@Override
public List<? extends Motor> findMotors(Type type, String manufacturer,
String designation, double diameter, double length) {
Log.d(TAG,"find motor: type="+ type.toString());
Log.d(TAG,"find motor: manu="+ manufacturer);
Log.d(TAG,"find motor: designation="+ designation);
Log.d(TAG,"find motor: diameter=" +diameter);
Log.d(TAG,"find motor: length="+ length);
try {
ExtendedThrustCurveMotor m = mDbHelper.getMotorDao().fetchMotor(manufacturer, designation);
if ( m != null ) {
return Collections.singletonList(m.getThrustCurveMotor());
}
} catch ( Exception ex ) {
}
return Collections.<Motor>emptyList();
}
}

View File

@ -0,0 +1,57 @@
package net.sf.openrocket.android.db;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import net.sf.openrocket.util.Coordinate;
abstract class ConversionUtils {
static double[] deserializeArrayOfDouble( byte[] bytes ) throws Exception {
double[] data = null;
if (bytes != null ) {
ObjectInputStream is = new ObjectInputStream( new ByteArrayInputStream(bytes));
data = (double[]) is.readObject();
}
return data;
}
static byte[] serializeArrayOfDouble( double[] data ) throws Exception {
byte[] serObj = null;
if ( data != null ) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(b);
os.writeObject(data);
os.close();
serObj = b.toByteArray();
}
return serObj;
}
static Coordinate[] deserializeArrayOfCoordinate( byte[] bytes ) throws Exception {
Coordinate[] data = null;
if (bytes != null ) {
ObjectInputStream is = new ObjectInputStream( new ByteArrayInputStream(bytes));
data = (Coordinate[]) is.readObject();
}
return data;
}
static byte[] serializeArrayOfCoordinate( Coordinate[] data ) throws Exception {
byte[] serObj = null;
if ( data != null ) {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(b);
os.writeObject(data);
os.close();
serObj = b.toByteArray();
}
return serObj;
}
}

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 = 5;
private static final int DATABASE_VERSION = 2;
private final Context mCtx;

View File

@ -1,12 +1,10 @@
package net.sf.openrocket.android.db;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import net.sf.openrocket.android.motor.Motor;
import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;
import net.sf.openrocket.motor.Manufacturer;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.util.Coordinate;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
@ -25,7 +23,8 @@ public class MotorDao {
"create table "+ DATABASE_TABLE + " ( " +
"_id integer primary key, "+
"unique_name text unique, "+
"name text, "+
"designation text, "+
"delays blob, "+
"diameter number, "+
"tot_impulse_ns number, "+
"avg_thrust_n number, "+
@ -36,8 +35,11 @@ public class MotorDao {
"tot_mass_g number,"+
"case_info text,"+
"manufacturer text," +
"type text," +
"impulse_class text," +
"burndata blob"+
"thrust_data blob,"+
"time_data blob," +
"cg_data blob"+
");";
MotorDao( SQLiteDatabase mDb ) {
@ -52,54 +54,61 @@ public class MotorDao {
public final static String ID = "_id";
public final static String UNIQUE_NAME = "unique_name";
public final static String NAME = "name";
public final static String DESIGNATION = "designation";
public final static String DELAYS = "delays";
public final static String DIAMETER = "diameter";
public final static String TOTAL_IMPULSE = "tot_impulse_ns";
public final static String AVG_THRUST = "avg_thrust_n";
public final static String MAX_THRUST = "max_thrust_n";
public final static String BURN_TIME = "burn_time_s";
public final static String LENGTH = "length";
public final static String PROP_MASS = "prop_mass_g";
public final static String TOT_MASS = "tot_mass_g";
public final static String BURNDATA = "burndata";
public final static String CASE_INFO = "case_info";
public final static String MANUFACTURER = "manufacturer";
public final static String TYPE = "type";
public final static String IMPULSE_CLASS = "impulse_class";
public final static String THRUST_DATA = "thrust_data";
public final static String TIME_DATA = "time_data";
public final static String CG_DATA = "cg_data";
public long insertOrUpdateMotor(Motor mi) {
private final static String[] ALL_COLS = new String[] {
ID,
DESIGNATION ,
DELAYS ,
DIAMETER ,
TOTAL_IMPULSE ,
AVG_THRUST ,
MAX_THRUST ,
BURN_TIME ,
LENGTH,
CASE_INFO,
TYPE,
IMPULSE_CLASS,
MANUFACTURER,
THRUST_DATA,
TIME_DATA,
CG_DATA
};
public long insertOrUpdateMotor(ExtendedThrustCurveMotor mi) throws Exception {
ContentValues initialValues = new ContentValues();
initialValues.put(ID, mi.getMotor_id());
initialValues.put(NAME, mi.getName());
initialValues.put(DIAMETER,mi.getDiameter());
initialValues.put(TOTAL_IMPULSE,mi.getTotalImpulse());
initialValues.put(AVG_THRUST,mi.getAvgThrust());
initialValues.put(MAX_THRUST,mi.getMaxThrust());
initialValues.put(BURN_TIME,mi.getBurnTime());
initialValues.put(LENGTH, mi.getLength());
initialValues.put(PROP_MASS, mi.getPropMass());
initialValues.put(TOT_MASS,mi.getTotMass());
final ThrustCurveMotor tcm = mi.getThrustCurveMotor();
initialValues.put(ID, mi.getId());
initialValues.put(UNIQUE_NAME, tcm.getManufacturer()+tcm.getDesignation());
initialValues.put(DESIGNATION, tcm.getDesignation());
initialValues.put(DELAYS, ConversionUtils.serializeArrayOfDouble(tcm.getStandardDelays()));
initialValues.put(DIAMETER,tcm.getDiameter());
initialValues.put(TOTAL_IMPULSE,tcm.getTotalImpulseEstimate());
initialValues.put(AVG_THRUST,tcm.getAverageThrustEstimate());
initialValues.put(MAX_THRUST,tcm.getMaxThrustEstimate());
initialValues.put(BURN_TIME,tcm.getBurnTimeEstimate());
initialValues.put(LENGTH, tcm.getLength());
initialValues.put(CASE_INFO, mi.getCaseInfo());
initialValues.put(MANUFACTURER,mi.getManufacturer());
initialValues.put(TYPE, tcm.getMotorType().getName());
initialValues.put(IMPULSE_CLASS,mi.getImpulseClass());
initialValues.put(UNIQUE_NAME, mi.getManufacturer()+mi.getName());
{
// Serialize the Vector of burn data
Vector<Double> burndata = mi.getBurndata();
byte[] serObj = null;
if ( burndata != null ) {
try {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(b);
os.writeObject(burndata);
os.close();
serObj = b.toByteArray();
} catch (Exception ex) {
Log.d(TAG,"unable to serialze burndata");
}
}
initialValues.put(BURNDATA, serObj);
}
initialValues.put(MANUFACTURER,tcm.getManufacturer().getSimpleName());
initialValues.put(THRUST_DATA, ConversionUtils.serializeArrayOfDouble(tcm.getThrustPoints()));
initialValues.put(TIME_DATA,ConversionUtils.serializeArrayOfDouble(tcm.getTimePoints()));
initialValues.put(CG_DATA,ConversionUtils.serializeArrayOfCoordinate(tcm.getCGPoints()));
Log.d(TAG,"insertOrUpdate Motor");
long rv = mDb.insertWithOnConflict(DATABASE_TABLE, null, initialValues,SQLiteDatabase.CONFLICT_REPLACE);
@ -126,26 +135,12 @@ public class MotorDao {
*/
public Cursor fetchAllInGroups( String groupCol, String groupVal ) {
return mDb.query(DATABASE_TABLE,
/* columns */new String[] {
ID,
NAME,
DIAMETER ,
TOTAL_IMPULSE,
AVG_THRUST ,
MAX_THRUST ,
BURN_TIME ,
LENGTH,
PROP_MASS,
TOT_MASS,
CASE_INFO,
IMPULSE_CLASS,
MANUFACTURER
},
/* selection */groupCol + "=?",
/* selection args*/new String[] {groupVal},
/* groupby */null,
/* having*/null,
/* orderby*/ NAME );
/* columns */ ALL_COLS,
/* selection */groupCol + "=?",
/* selection args*/new String[] {groupVal},
/* groupby */null,
/* having*/null,
/* orderby*/ DESIGNATION );
}
@ -175,52 +170,61 @@ public class MotorDao {
*/
public Cursor fetchAllMotors() {
return mDb.query(DATABASE_TABLE,
/* columns */new String[] {
ID,
NAME,
DIAMETER ,
TOTAL_IMPULSE,
AVG_THRUST ,
MAX_THRUST ,
BURN_TIME ,
LENGTH,
PROP_MASS,
TOT_MASS,
CASE_INFO,
IMPULSE_CLASS,
MANUFACTURER
},
/* selection */null,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
return mDb.query(DATABASE_TABLE,
/* columns */ ALL_COLS,
/* selection */null,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
}
public Motor fetchMotor(Long id ) throws SQLException {
private ExtendedThrustCurveMotor hydrateMotor( Cursor mCursor ) throws Exception {
ExtendedThrustCurveMotor mi = new ExtendedThrustCurveMotor();
mi.setId(mCursor.getLong(mCursor.getColumnIndex(ID)));
mi.setCaseInfo(mCursor.getString(mCursor.getColumnIndex(CASE_INFO)));
mi.setImpulseClass(mCursor.getString(mCursor.getColumnIndex(IMPULSE_CLASS)));
{
String designation = mCursor.getString(mCursor.getColumnIndex(DESIGNATION));
double[] delays = ConversionUtils.deserializeArrayOfDouble( mCursor.getBlob(mCursor.getColumnIndex(DELAYS)));
double diameter = mCursor.getDouble(mCursor.getColumnIndex(DIAMETER));
double totImpulse = mCursor.getDouble(mCursor.getColumnIndex(TOTAL_IMPULSE));
double avgImpulse = mCursor.getDouble(mCursor.getColumnIndex(AVG_THRUST));
double maxThrust = mCursor.getDouble(mCursor.getColumnIndex(MAX_THRUST));
double length = mCursor.getDouble(mCursor.getColumnIndex(LENGTH));
Motor.Type type = Motor.Type.fromName( mCursor.getString(mCursor.getColumnIndex(TYPE)));
Manufacturer manufacturer = Manufacturer.getManufacturer( mCursor.getString( mCursor.getColumnIndex(MANUFACTURER)));
double[] thrustData = ConversionUtils.deserializeArrayOfDouble( mCursor.getBlob(mCursor.getColumnIndex(THRUST_DATA)));
double[] timeData = ConversionUtils.deserializeArrayOfDouble( mCursor.getBlob(mCursor.getColumnIndex(TIME_DATA)));
Coordinate[] cgData = ConversionUtils.deserializeArrayOfCoordinate( mCursor.getBlob(mCursor.getColumnIndex(CG_DATA)));
ThrustCurveMotor tcm = new ThrustCurveMotor(manufacturer,
designation,
"",
type,
delays,
diameter,
length,
timeData,
thrustData,
cgData
);
mi.setThrustCurveMotor(tcm);
}
return mi;
}
public ExtendedThrustCurveMotor fetchMotor(Long id ) throws Exception {
Cursor mCursor = mDb.query(DATABASE_TABLE,
/* columns */new String[] {
ID,
NAME ,
DIAMETER ,
TOTAL_IMPULSE ,
AVG_THRUST ,
MAX_THRUST ,
BURN_TIME ,
LENGTH,
PROP_MASS,
TOT_MASS,
CASE_INFO,
IMPULSE_CLASS,
MANUFACTURER,
BURNDATA
},
/* selection */ID + "="+id,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
/* columns */ ALL_COLS,
/* selection */ID + "="+id,
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
if ( mCursor == null ) {
return null;
}
@ -229,37 +233,7 @@ public class MotorDao {
return null;
}
mCursor.moveToFirst();
Motor mi = new Motor();
mi.setMotor_id(mCursor.getLong(mCursor.getColumnIndex(ID)));
mi.setName(mCursor.getString(mCursor.getColumnIndex(NAME)));
mi.setDiameter(mCursor.getLong(mCursor.getColumnIndex(DIAMETER)));
mi.setTotalImpulse(mCursor.getFloat(mCursor.getColumnIndex(TOTAL_IMPULSE)));
mi.setAvgThrust(mCursor.getFloat(mCursor.getColumnIndex(AVG_THRUST)));
mi.setMaxThrust(mCursor.getFloat(mCursor.getColumnIndex(MAX_THRUST)));
mi.setBurnTime(mCursor.getFloat(mCursor.getColumnIndex(BURN_TIME)));
mi.setLength(mCursor.getFloat(mCursor.getColumnIndex(LENGTH)));
mi.setPropMass(mCursor.getDouble(mCursor.getColumnIndex(PROP_MASS)));
mi.setCaseInfo(mCursor.getString(mCursor.getColumnIndex(CASE_INFO)));
mi.setTotMass(mCursor.getDouble(mCursor.getColumnIndex(TOT_MASS)));
mi.setManufacturer(mCursor.getString(mCursor.getColumnIndex(MANUFACTURER)));
mi.setImpulseClass(mCursor.getString(mCursor.getColumnIndex(IMPULSE_CLASS)));
{
// Deserialize burndata column
byte[] serObj = mCursor.getBlob(mCursor.getColumnIndex(BURNDATA));
Vector<Double> burndata = null;
if (serObj != null ) {
try {
ObjectInputStream is = new ObjectInputStream( new ByteArrayInputStream(serObj));
burndata = (Vector<Double>) is.readObject();
}
catch (Exception ex) {
Log.d(TAG,"cannot deserialize burndata");
}
}
mi.setBurndata(burndata);
}
return mi;
return hydrateMotor(mCursor);
}
finally {
mCursor.close();
@ -267,4 +241,51 @@ public class MotorDao {
}
public ExtendedThrustCurveMotor fetchMotor(String manufacturerShortName, String designation ) throws Exception {
Cursor mCursor = mDb.query(DATABASE_TABLE,
/* columns */ ALL_COLS,
/* selection */MANUFACTURER + "='"+manufacturerShortName + "' and "+DESIGNATION+"='"+designation+"'",
/* selection args*/null,
/* groupby */null,
/* having*/null,
/* orderby*/null);
if ( mCursor == null ) {
return null;
}
try {
if (mCursor.getCount() == 0) {
return null;
}
mCursor.moveToFirst();
return hydrateMotor(mCursor);
}
finally {
mCursor.close();
}
}
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

@ -1,5 +1,7 @@
package net.sf.openrocket.android.motor;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import net.sf.openrocket.R;
@ -27,28 +29,19 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
private final static String TAG = "BurnPlotFragment";
private ExtendedThrustCurveMotor motor;
private XYPlot mySimpleXYPlot;
private SimpleXYSeries mySeries;
private PointF minXY;
private PointF maxXY;
private float absMinX;
private float absMaxX;
private float minNoError;
private float maxNoError;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public static BurnPlotFragment initializeBurnPlotHelper( Motor motor ) {
BurnPlotFragment h = new BurnPlotFragment();
Bundle args = new Bundle();
args.putSerializable("Motor", motor);
h.setArguments(args);
return h;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
@ -69,42 +62,47 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
mySimpleXYPlot = (XYPlot) v.findViewById(R.id.xyplot);
mySimpleXYPlot.setOnTouchListener(this);
mScaleDetector = new ScaleGestureDetector(v.getContext(), new ScaleListener());
// Motor motor = getMotor();
// init(motor);
return v;
}
void init( Motor motor ) {
private static List<Double> fromArray( double[] arry ) {
List<Double> l = new ArrayList<Double>(arry.length);
for( double d: arry ) {
l.add(d);
}
return l;
}
void init( ExtendedThrustCurveMotor motor ) {
mySimpleXYPlot.setUserDomainOrigin(0);
mySimpleXYPlot.setUserRangeOrigin(0);
mySimpleXYPlot.setRangeLabel("impuse (n)");
mySimpleXYPlot.setDomainLabel("time (s)");
mySimpleXYPlot.addMarker(new YValueMarker(motor.getAvgThrust(),"average" ));
mySimpleXYPlot.addMarker(new YValueMarker(motor.getThrustCurveMotor().getAverageThrustEstimate(),"average" ));
mySimpleXYPlot.disableAllMarkup();
Vector<Double> data = null;
try {
data = motor.getBurndata();
} catch ( Exception ex ) {
}
if ( data == null || data.size() == 0 ) {
data = new Vector<Double>();
data.add(0.0);
data.add(0.0);
data.add(1.0);
data.add(1.0);
}
Log.d("plot","data = " + data.toString());
mySeries = new SimpleXYSeries(data, SimpleXYSeries.ArrayFormat.XY_VALS_INTERLEAVED,motor.getName());
try {
mySeries = new SimpleXYSeries(
fromArray(motor.getThrustCurveMotor().getTimePoints()),
fromArray(motor.getThrustCurveMotor().getThrustPoints()),
motor.getThrustCurveMotor().getDesignation());
} catch ( Exception ex ) {
Vector<Double> data = new Vector<Double>();
data.add(0.0);
data.add(0.0);
data.add(1.0);
data.add(1.0);
mySeries = new SimpleXYSeries(data, SimpleXYSeries.ArrayFormat.XY_VALS_INTERLEAVED,"no data");
}
mySimpleXYPlot.addSeries(mySeries, LineAndPointRenderer.class,
new LineAndPointFormatter(Color.rgb(0, 255, 0), Color.rgb(200, 0, 0), null));
//Set of internal variables for keeping track of the boundaries
mySimpleXYPlot.calculateMinMaxVals();
mySimpleXYPlot.redraw();
minXY=new PointF(mySimpleXYPlot.getCalculatedMinX().floatValue(),mySimpleXYPlot.getCalculatedMinY().floatValue());
@ -112,9 +110,7 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
absMinX = minXY.x;
absMaxX = maxXY.x;
minNoError = Math.round(mySeries.getX(1).floatValue() +2);
maxNoError = Math.round(mySeries.getX(mySeries.size() -1).floatValue()) - 2.0f;
}
private float mPosX;
@ -141,7 +137,7 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
mActivePointerId = event.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = event.findPointerIndex(mActivePointerId);
final float x = event.getX(pointerIndex);
@ -150,29 +146,29 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
scroll(dx);
// do scroll.
}
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = -1;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = -1;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
@ -218,16 +214,16 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
}
private void checkBoundaries() {
if ( minXY.x < absMinX)
minXY.x = absMinX;
// else if ( minXY.x > maxNoError )
// minXY.x = maxNoError;
// else if ( minXY.x > maxNoError )
// minXY.x = maxNoError;
if ( maxXY.x > absMaxX)
maxXY.x = absMaxX;
// else if ( maxXY.x < minNoError)
// maxXY.x = minNoError;
// else if ( maxXY.x < minNoError)
// maxXY.x = minNoError;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override

View File

@ -0,0 +1,62 @@
package net.sf.openrocket.android.motor;
import net.sf.openrocket.motor.ThrustCurveMotor;
public class ExtendedThrustCurveMotor {
private Long id;
private String caseInfo;
private String impulseClass;
private ThrustCurveMotor thrustCurveMotor;
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the caseInfo
*/
public String getCaseInfo() {
return caseInfo;
}
/**
* @param caseInfo the caseInfo to set
*/
public void setCaseInfo(String caseInfo) {
this.caseInfo = caseInfo;
}
/**
* @return the impulseClass
*/
public String getImpulseClass() {
return impulseClass;
}
/**
* @param impulseClass the impulseClass to set
*/
public void setImpulseClass(String impulseClass) {
this.impulseClass = impulseClass;
}
/**
* @return the thrustCurveMotor
*/
public ThrustCurveMotor getThrustCurveMotor() {
return thrustCurveMotor;
}
/**
* @param thrustCurveMotor the thrustCurveMotor to set
*/
public void setThrustCurveMotor(ThrustCurveMotor thrustCurveMotor) {
this.thrustCurveMotor = thrustCurveMotor;
}
}

View File

@ -1,107 +0,0 @@
package net.sf.openrocket.android.motor;
import java.io.Serializable;
import java.util.Vector;
public class Motor implements Serializable {
private Long motor_id;
private String name;
private String impulseClass;
private String manufacturer;
private Long diameter;
private String caseInfo;
private Float avgThrust;
private Float maxThrust;
private Float totalImpulse;
private Float burnTime;
private Float length;
private Double propMass;
private Double totMass;
private Vector<Double> burndata;
public Long getMotor_id() {
return motor_id;
}
public void setMotor_id(Long motor_id) {
this.motor_id = motor_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImpulseClass() {
return impulseClass;
}
public void setImpulseClass(String impulseClass) {
this.impulseClass = impulseClass;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public Long getDiameter() {
return diameter;
}
public void setDiameter(Long diameter) {
this.diameter = diameter;
}
public String getCaseInfo() {
return caseInfo;
}
public void setCaseInfo(String caseInfo) {
this.caseInfo = caseInfo;
}
public Float getAvgThrust() {
return avgThrust;
}
public void setAvgThrust(Float avgThrust) {
this.avgThrust = avgThrust;
}
public Float getMaxThrust() {
return maxThrust;
}
public void setMaxThrust(Float maxThrust) {
this.maxThrust = maxThrust;
}
public Float getTotalImpulse() {
return totalImpulse;
}
public void setTotalImpulse(Float totalImpulse) {
this.totalImpulse = totalImpulse;
}
public Float getBurnTime() {
return burnTime;
}
public void setBurnTime(Float burnTime) {
this.burnTime = burnTime;
}
public Float getLength() {
return length;
}
public void setLength(Float length) {
this.length = length;
}
public Double getPropMass() {
return propMass;
}
public void setPropMass(Double propMass) {
this.propMass = propMass;
}
public Double getTotMass() {
return totMass;
}
public void setTotMass(Double totMass) {
this.totMass = totMass;
}
public Vector<Double> getBurndata() {
return burndata;
}
public void setBurndata(Vector<Double> burndata) {
this.burndata = burndata;
}
}

View File

@ -1,6 +1,7 @@
package net.sf.openrocket.android.motor;
import net.sf.openrocket.R;
import net.sf.openrocket.android.db.DbAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
@ -19,7 +20,7 @@ implements SlidingDrawer.OnDrawerCloseListener, SlidingDrawer.OnDrawerOpenListen
private SlidingDrawer slidingDrawer;
private ImageView handle;
private Motor motor;
private ExtendedThrustCurveMotor motor;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -28,7 +29,18 @@ implements SlidingDrawer.OnDrawerCloseListener, SlidingDrawer.OnDrawerOpenListen
setContentView(R.layout.motor_detail);
Intent i = getIntent();
motor = (Motor) i.getSerializableExtra("Motor");
long motorId = i.getLongExtra("Motor",-1);
DbAdapter mDbHelper = new DbAdapter(this);
mDbHelper.open();
try {
motor = mDbHelper.getMotorDao().fetchMotor(motorId);
} catch ( Exception e ) {
}
mDbHelper.close();
BurnPlotFragment burnPlot = (BurnPlotFragment) getSupportFragmentManager().findFragmentById(R.id.burnPlotFragment);
burnPlot.init(motor);

View File

@ -1,6 +1,9 @@
package net.sf.openrocket.android.motor;
import java.util.Arrays;
import net.sf.openrocket.R;
import net.sf.openrocket.motor.ThrustCurveMotor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
@ -12,6 +15,7 @@ public class MotorDetailsFragment extends Fragment {
EditText manuField;
EditText nameField;
EditText delaysField;
EditText caseField;
EditText impulseClassField;
EditText diameterField;
@ -23,6 +27,7 @@ public class MotorDetailsFragment extends Fragment {
View v = inflater.inflate(R.layout.motor_detail_form, container, false);
manuField = (EditText) v.findViewById(R.id.motorDetailsManufacturer);
nameField = (EditText) v.findViewById(R.id.motorDetailsName);
delaysField = (EditText) v.findViewById(R.id.motorDetailsDelays);
caseField = (EditText) v.findViewById(R.id.motorDetailsCaseInfo);
impulseClassField = (EditText) v.findViewById(R.id.motorDetailsImpuseClass);
diameterField = (EditText) v.findViewById(R.id.motorDetailsDiameter);
@ -30,13 +35,15 @@ public class MotorDetailsFragment extends Fragment {
return v;
}
public void init( Motor m ) {
manuField.setText( m.getManufacturer());
nameField.setText( m.getName() );
public void init( ExtendedThrustCurveMotor m ) {
ThrustCurveMotor tcm = m.getThrustCurveMotor();
manuField.setText( tcm.getManufacturer().getDisplayName());
nameField.setText( tcm.getDesignation() );
delaysField.setText( Arrays.toString(tcm.getStandardDelays()) );
caseField.setText( m.getCaseInfo());
impulseClassField.setText( m.getImpulseClass());
diameterField.setText( m.getDiameter().toString() );
lengthField.setText( m.getLength().toString() );
diameterField.setText( String.valueOf(tcm.getDiameter()*1000.0) );
lengthField.setText( String.valueOf(tcm.getLength()*1000.0) );
}

View File

@ -21,7 +21,8 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.CursorTreeAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.ResourceCursorTreeAdapter;
import android.widget.TextView;
public class MotorHierarchicalBrowser
@ -48,17 +49,15 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
private DbAdapter mDbHelper;
public class MotorHierarchicalListAdapter extends SimpleCursorTreeAdapter
public class MotorHierarchicalListAdapter extends ResourceCursorTreeAdapter
{
// Note that the constructor does not take a Cursor. This is done to avoid querying the
// database on the main thread.
public MotorHierarchicalListAdapter(Context context, Cursor cursor, int groupLayout,
int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
int[] childrenTo) {
int childLayout ) {
super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
childrenTo);
super(context, cursor, groupLayout, childLayout);
}
@Override
@ -77,6 +76,46 @@ 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)
*/
@Override
protected void bindChildView(View arg0, Context arg1, Cursor arg2,
boolean arg3) {
TextView manu = (TextView) arg0.findViewById(R.id.motorChildManu);
manu.setText( arg2.getString(arg2.getColumnIndex(MotorDao.MANUFACTURER)));
TextView desig = (TextView) arg0.findViewById(R.id.motorChildName);
desig.setText( arg2.getString(arg2.getColumnIndex(MotorDao.DESIGNATION)));
TextView delays = (TextView) arg0.findViewById(R.id.motorChildDelays);
delays.setText( MotorDao.extractPrettyDelayString( arg2 ));
TextView totImpulse = (TextView) arg0.findViewById(R.id.motorChildImpulse);
totImpulse.setText( arg2.getString(arg2.getColumnIndex(MotorDao.TOTAL_IMPULSE)));
}
/* (non-Javadoc)
* @see android.widget.CursorTreeAdapter#bindGroupView(android.view.View, android.content.Context, android.database.Cursor, boolean)
*/
@Override
protected void bindGroupView(View view, Context context, Cursor cursor,
boolean isExpanded) {
TextView v = (TextView) view.findViewById(R.id.motorGroup);
if ( MotorDao.DIAMETER.equals(groupColumn)) {
double d = cursor.getDouble( cursor.getColumnIndex(groupColumn));
v.setText( String.valueOf(Math.round(d * 1000.0)) );
} else {
v.setText( cursor.getString( cursor.getColumnIndex(groupColumn)));
}
}
}
@Override
@ -167,10 +206,9 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
super.onChildClick(parent, v, groupPosition, childPosition, id);
Motor m = mDbHelper.getMotorDao().fetchMotor(id);
//Intent i = new Intent(this, BurnPlotActivity.class);
Intent i = new Intent(this,MotorDetails.class);
i.putExtra("Motor", m);
i.putExtra("Motor", id);
startActivity(i);
return true;
}
@ -221,11 +259,7 @@ implements SharedPreferences.OnSharedPreferenceChangeListener
this,
motorCursor,
R.layout.motor_list_group,
R.layout.motor_list_child,
new String[] { groupColumn }, // Name for group layouts
new int[] { R.id.motorGroup },
new String[] { MotorDao.MANUFACTURER, MotorDao.NAME, MotorDao.TOTAL_IMPULSE }, // Number for child layouts
new int[] { R.id.motorChildManu, R.id.motorChildName, R.id.motorChildImpulse });
R.layout.motor_list_child);
setListAdapter(mAdapter);
}
}

View File

@ -12,7 +12,7 @@ public class DownloadResponse {
public void add( MotorBurnFile mbd ) {
MotorBurnFile currentData = data.get(mbd.getMotorId());
if ( currentData == null || currentData.getDatapoints().size() < mbd.getDatapoints().size() ) {
if ( currentData == null || currentData.getThrustCurveMotor() == null ) {
data.put(mbd.getMotorId(),mbd);
}
}

View File

@ -86,7 +86,7 @@ public class DownloadResponseParser {
new EndTextElementListener() {
@Override
public void end(String arg0) {
currentMotor.setMotor_id(Integer.parseInt(arg0));
currentMotor.setMotorId(Integer.parseInt(arg0));
}
}
);

View File

@ -1,89 +1,91 @@
package net.sf.openrocket.android.thrustcurve;
import java.util.Vector;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import net.sf.openrocket.file.motor.RASPMotorLoader;
import net.sf.openrocket.file.motor.RockSimMotorLoader;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor;
public class MotorBurnFile {
private Integer motor_id;
private Integer motorId;
private String filetype;
private Float length;
private String delays;
private Double propWeightG;
private Double totWeightG;
private Vector<Double> datapoints = new Vector<Double>();
private ThrustCurveMotor thrustCurveMotor;
public void init() {
this.motor_id = null;
this.motorId = null;
this.filetype = null;
this.length = null;
this.delays = null;
this.propWeightG = null;
this.totWeightG = null;
this.datapoints = new Vector<Double>();
this.thrustCurveMotor = null;
}
@Override
public MotorBurnFile clone() {
MotorBurnFile clone = new MotorBurnFile();
clone.motor_id = this.motor_id;
clone.motorId = this.motorId;
clone.filetype = this.filetype;
clone.length = this.length;
clone.delays = this.delays;
clone.propWeightG = this.propWeightG;
clone.totWeightG = this.totWeightG;
clone.datapoints = this.datapoints;
clone.thrustCurveMotor = this.thrustCurveMotor;
return clone;
}
public void decodeFile(String data){
if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) {
RaspBurnFile.parse(this,data);
} else if (SupportedFileTypes.ROCKSIM_FORMAT.equals(filetype) ){
RSEBurnFile.parse(this,data);
public void decodeFile(String data) {
try {
if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) {
RASPMotorLoader loader = new RASPMotorLoader();
List<Motor> motors = loader.load( new StringReader(data), "download");
this.thrustCurveMotor = (ThrustCurveMotor) motors.get(0);
} else if (SupportedFileTypes.ROCKSIM_FORMAT.equals(filetype) ){
RockSimMotorLoader loader = new RockSimMotorLoader();
List<Motor> motors = loader.load( new StringReader(data), "download");
this.thrustCurveMotor = (ThrustCurveMotor) motors.get(0);
}
} catch ( IOException ex ) {
this.thrustCurveMotor = null;
}
}
/**
* @return the motor_id
*/
public Integer getMotorId() {
return motor_id;
}
public String getFileType() {
return filetype;
}
public Float getLength() {
return length;
}
public String getDelays() {
return delays;
}
public Double getPropWeightG() {
return propWeightG;
}
public Double getTotWeightG() {
return totWeightG;
}
public Vector<Double> getDatapoints() {
return datapoints;
return motorId;
}
void setMotor_id(Integer motor_id) {
this.motor_id = motor_id;
/**
* @param motor_id the motor_id to set
*/
public void setMotorId(Integer motorId) {
this.motorId = motorId;
}
void setFiletype(String filetype ) {
/**
* @return the filetype
*/
public String getFiletype() {
return filetype;
}
/**
* @param filetype the filetype to set
*/
public void setFiletype(String filetype) {
this.filetype = filetype;
}
void setLength(Float length) {
this.length = length;
/**
* @return the thrustCurveMotor
*/
public ThrustCurveMotor getThrustCurveMotor() {
return thrustCurveMotor;
}
void setDelays(String delays) {
this.delays = delays;
}
void setPropWeightG(Double propWeightG) {
this.propWeightG = propWeightG;
}
void setTotWeightG(Double totWeightG) {
this.totWeightG = totWeightG;
}
void setDatapoints(Vector<Double> datapoints) {
this.datapoints = datapoints;
/**
* @param thrustCurveMotor the thrustCurveMotor to set
*/
public void setThrustCurveMotor(ThrustCurveMotor thrustCurveMotor) {
this.thrustCurveMotor = thrustCurveMotor;
}
}

View File

@ -1,131 +0,0 @@
package net.sf.openrocket.android.thrustcurve;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Vector;
import org.xml.sax.Attributes;
import android.sax.Element;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;
class RSEBurnFile extends MotorBurnFile {
private final static String TAG = "RSEBurnFile";
static void parse( MotorBurnFile that, String filecontents ) {
parse(that, new ByteArrayInputStream(filecontents.getBytes()) );
}
private final static String root_tag = "engine-database";
private final static String engine_list_tag = "engine-list";
private final static String engine_tag = "engine";
private final static String delays_attr = "delays";
private final static String len_attr = "len";
private final static String propwgt_attr = "propWt";
private final static String totwgt_attr = "initWt";
private final static String data_tag = "data";
private final static String eng_data_tag = "eng-data";
private final static String time_attr="t";
private final static String force_attr="f";
static void parse( final MotorBurnFile that, InputStream in ) {
RootElement rootEl = new RootElement(root_tag);
Element engineEl = rootEl.getChild(engine_list_tag).getChild(engine_tag);
final Vector<Double> datapoints = new Vector<Double>();
Log.d(TAG,"parsing start");
engineEl.setStartElementListener(
new StartElementListener() {
@Override
public void start(Attributes arg0) {
Log.d(TAG,"start engineEl");
that.setPropWeightG(Double.parseDouble(arg0.getValue(propwgt_attr)));
that.setTotWeightG(Double.parseDouble(arg0.getValue(totwgt_attr)));
that.setLength(Float.parseFloat(arg0.getValue(len_attr)));
that.setDelays(arg0.getValue(delays_attr));
Log.d(TAG, "me is now " + that.toString());
}
}
);
Element datapointEl = engineEl.getChild(data_tag).getChild(eng_data_tag);
datapointEl.setStartElementListener(
new StartElementListener() {
@Override
public void start(Attributes attributes) {
Double x = Double.parseDouble(attributes.getValue(time_attr));
Double y = Double.parseDouble(attributes.getValue(force_attr));
Log.d(TAG, "add data point " + x + "," + y);
datapoints.add(x);
datapoints.add(y);
}
}
);
try {
Xml.parse(in, Xml.Encoding.UTF_8, rootEl.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
that.setDatapoints(datapoints);
}
}
//
// <engine-database>
// <engine-list>
// <engine FDiv="10" FFix="1" FStep="-1." Isp="202.11" Itot="8.919" Type="single-use" auto-calc-cg="1" auto-calc-mass="1" avgThrust="3.795" burn-time="2.35" cgDiv="10" cgFix="1" cgStep="-1." code="C4" delays="3,5,7" dia="18." exitDia="0." initWt="17." len="50." mDiv="10" mFix="1" mStep="-1." massFrac="26.47" mfg="Apogee" peakThrust="11.31" propWt="4.5" tDiv="10" tFix="1" tStep="-1." throatDia="0.">
// <comments>Apogee C4 RASP.ENG file made from NAR published data
// File produced September 4, 2000
// The total impulse, peak thrust, average thrust and burn time are
// the same as the averaged static test data on the NAR web site in
// the certification file. The curve drawn with these data points is as
// close to the certification curve as can be with such a limited
// number of points (32) allowed with wRASP up to v1.6.
// </comments>
// <data>
// <eng-data cg="25." f="0." m="4.5" t="0."/>
// <eng-data cg="25." f="3.23" m="4.48533" t="0.018"/>
// <eng-data cg="25." f="6.874" m="4.42671" t="0.041"/>
// <eng-data cg="25." f="8.779" m="4.00814" t="0.147"/>
// <eng-data cg="25." f="10.683" m="3.28643" t="0.294"/>
// <eng-data cg="25." f="11.31" m="2.89252" t="0.365"/>
// <eng-data cg="25." f="10.521" m="2.76585" t="0.388"/>
// <eng-data cg="25." f="8.779" m="2.649" t="0.412"/>
// <eng-data cg="25." f="7.04" m="2.53328" t="0.441"/>
// <eng-data cg="25." f="4.555" m="2.46308" t="0.465"/>
// <eng-data cg="25." f="3.479" m="2.33337" t="0.529"/>
// <eng-data cg="25." f="2.981" m="2.1704" t="0.629"/>
// <eng-data cg="25." f="3.23" m="2.1328" t="0.653"/>
// <eng-data cg="25." f="2.816" m="2.03366" t="0.718"/>
// <eng-data cg="25." f="2.733" m="1.84469" t="0.853"/>
// <eng-data cg="25." f="2.65" m="1.5568" t="1.065"/>
// <eng-data cg="25." f="2.567" m="1.30938" t="1.253"/>
// <eng-data cg="25." f="2.401" m="1.05873" t="1.453"/>
// <eng-data cg="25." f="2.484" m="0.761739" t="1.694"/>
// <eng-data cg="25." f="2.484" m="0.636413" t="1.794"/>
// <eng-data cg="25." f="2.733" m="0.612724" t="1.812"/>
// <eng-data cg="25." f="2.401" m="0.575165" t="1.841"/>
// <eng-data cg="25." f="2.401" m="0.446759" t="1.947"/>
// <eng-data cg="25." f="2.401" m="0.246881" t="2.112"/>
// <eng-data cg="25." f="2.401" m="0.0978809" t="2.235"/>
// <eng-data cg="25." f="2.236" m="0.0429024" t="2.282"/>
// <eng-data cg="25." f="1.656" m="0.0134478" t="2.312"/>
// <eng-data cg="25." f="0.662" m="0.003507" t="2.329"/>
// <eng-data cg="25." f="0." m="-0." t="2.35"/>
// </data>
// </engine>
// </engine-list>
// </engine-database>
//

View File

@ -1,85 +0,0 @@
package net.sf.openrocket.android.thrustcurve;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.util.Log;
class RaspBurnFile{
private final static String TAG = "RaspBurnFile";
private final static int HEADER = 0;
private final static int DATA = 1;
private final static Pattern headerPattern = Pattern.compile("(\\S*)\\s+(\\S*)\\s+(\\S*)\\s+(\\S*)\\s+(\\S*)\\s+(\\S*)\\s+(\\S*)");
private final static Pattern dataPattern = Pattern.compile("(\\S*)\\s+(\\S*)");
static void parse( MotorBurnFile that, String filecontents ) {
int state = HEADER;
LineNumberReader reader = new LineNumberReader( new StringReader(filecontents));
Vector<Double> datapoints = new Vector<Double>();
String line;
Matcher m;
try {
while ( (line = reader.readLine()) != null ) {
line = line.trim();
Log.d("RASP",line);
if ( line.startsWith(";")) {
continue;
}
switch (state) {
case HEADER:
Log.d("RASP","header");
m = headerPattern.matcher(line);
if ( m.matches() ) {
Log.d("RASP","header matches");
/*motorName = m.group(1);*/
/*diameter = Integer.decode(m.group(2));*/
that.setLength(Float.parseFloat(m.group(3)) );
String delays = m.group(4);
if ( delays != null ) {
delays = delays.replace("-", ",");
that.setDelays(delays);
}
that.setPropWeightG(Double.parseDouble(m.group(5))*1000.0);
that.setTotWeightG(Double.parseDouble(m.group(6))*1000.0);
/*manufacturer = m.group(7);*/
}
state = DATA;
break;
case DATA:
Log.d("RASP","data");
m = dataPattern.matcher(line);
if ( m.matches() ) {
Log.d("RASP","data matches");
Double x = Double.parseDouble(m.group(1));
Double y = Double.parseDouble(m.group(2));
Log.d("RASP","data matches ("+x+","+y+")");
datapoints.add(x);
datapoints.add(y);
}
break;
}
that.setDatapoints(datapoints);
}
} catch (IOException ex ) {
Log.d(TAG,"Unable to parse Rasp file: " + ex);
}
}
}

View File

@ -1,10 +1,8 @@
package net.sf.openrocket.android.thrustcurve;
import java.util.Vector;
import net.sf.openrocket.R;
import net.sf.openrocket.android.db.DbAdapter;
import net.sf.openrocket.android.motor.Motor;
import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
@ -161,29 +159,12 @@ public class TCQueryActivity extends Activity {
MotorBurnFile b = new ThrustCurveAPI().downloadData(mi.getMotor_id());
if ( b != null ) {
if ( b.getLength() != null ) {
mi.setLength( b.getLength() );
}
if ( b.getPropWeightG() != null ) {
mi.setProp_mass_g(b.getPropWeightG());
}
if ( b.getTotWeightG() != null ) {
mi.setTot_mass_g(b.getTotWeightG());
}
if ( b.getDelays() != null ) {
mi.setDelays(b.getDelays());
}
mi.setBurndata(b.getDatapoints());
}
Log.d(TAG, mi.toString());
// convert to Motors. One per delay.
Motor m = new Motor();
// Base name of motor.
String name = mi.getCommon_name() + "-";
m.setManufacturer(mi.getManufacturer_abbr());
ExtendedThrustCurveMotor m = new ExtendedThrustCurveMotor();
m.setThrustCurveMotor( b.getThrustCurveMotor() );
// Convert impulse class. ThrustCurve puts mmx, 1/4a and 1/2a as A.
m.setImpulseClass(mi.getImpulse_class());
if ( "a".equalsIgnoreCase(mi.getImpulse_class())) {
@ -195,15 +176,7 @@ public class TCQueryActivity extends Activity {
m.setImpulseClass("1/8A");
}
}
m.setAvgThrust(mi.getAvg_thrust_n());
m.setBurndata(mi.getBurndata());
m.setBurnTime(mi.getBurn_time_s());
m.setDiameter(mi.getDiameter() == null ? null : mi.getDiameter().longValue());
m.setLength(mi.getLength());
m.setMaxThrust(mi.getMax_thrust_n());
m.setPropMass(mi.getProp_mass_g());
m.setTotalImpulse(mi.getTot_impulse_ns());
m.setTotMass(mi.getTot_mass_g());
// Convert Case Info.
if ( mi.getCase_info() == null
|| "single use".equalsIgnoreCase(mi.getCase_info())
@ -213,31 +186,9 @@ public class TCQueryActivity extends Activity {
m.setCaseInfo(mi.getCase_info());
}
Vector<String> delays = new Vector<String>();
{
String delaysString = mi.getDelays();
if ( delaysString != null ) {
delaysString = delaysString.trim();
}
if ( delaysString == null || "".equals(delaysString)) {
delays.add("");
} else {
String[] delayString = delaysString.split(",");
for( String d : delayString ) {
delays.add( d.trim() );
}
}
}
for( String d: delays ) {
if ( "100".equals(d) ) {
m.setName(name + "P");
} else {
m.setName(name + d);
}
mDbHelper.getMotorDao().insertOrUpdateMotor(m);
}
Log.d(TAG,"adding motor " + m.toString());
// Write motor.
mDbHelper.getMotorDao().insertOrUpdateMotor(m);
}
if ( total < res.getMatches() ) {
handler.post( new Error( total + " motors downloaded, " + res.getMatches() + " matched. Try restricting the query more.") );