[Bugfix] ThrustCurve motor interpolation fixed.

This commit is contained in:
Daniel_M_Williams 2016-06-25 11:11:28 -04:00
parent 7b2e195392
commit 56463b02fc
2 changed files with 46 additions and 44 deletions

View File

@ -215,44 +215,51 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
* @return a pseudo index to this motor's data. * @return a pseudo index to this motor's data.
*/ */
protected double getPseudoIndex( final double motorTime ){ protected double getPseudoIndex( final double motorTime ){
final double SNAP_DISTANCE = 0.001; if(( time.length == 0 )||( 0 > motorTime )){
if( time.length == 0 ){
return Double.NaN; return Double.NaN;
} }
if( 0 > motorTime ){ final int lowerIndex = getIndex( motorTime);
return 0.0; final double fraction = getIndexFraction( motorTime, lowerIndex );
return ((double)lowerIndex)+fraction;
} }
private int getIndex( final double motorTime ){
int lowerBoundIndex=0; int lowerBoundIndex=0;
int upperBoundIndex=0; int upperBoundIndex=0;
while( ( upperBoundIndex < time.length ) && ( motorTime >= time[upperBoundIndex] )){ while( ( upperBoundIndex < time.length ) && ( motorTime >= time[upperBoundIndex] )){
lowerBoundIndex = upperBoundIndex;
++upperBoundIndex; ++upperBoundIndex;
} }
lowerBoundIndex = upperBoundIndex-1;
return lowerBoundIndex;
}
private double getIndexFraction( final double motorTime, final int index ){
final double SNAP_DISTANCE = 0.0001;
final int lowerBoundIndex= index;
final int upperBoundIndex= index+1;
// we are already at the end of the time array.
if( upperBoundIndex == time.length ){ if( upperBoundIndex == time.length ){
return lowerBoundIndex; // == time.length-1; return 0.;
} }
if ( SNAP_DISTANCE > Math.abs( motorTime - time[lowerBoundIndex])){ final double lowerBoundTime = time[lowerBoundIndex];
return lowerBoundIndex; final double upperBoundTime = time[upperBoundIndex];
} final double timeFraction = motorTime - lowerBoundTime;
final double indexFraction = ( timeFraction ) / ( upperBoundTime - lowerBoundTime );
double lowerBoundTime = time[lowerBoundIndex]; if( SNAP_DISTANCE > indexFraction ){
double upperBoundTime = time[upperBoundIndex]; // round down to previous index
double timeFraction = motorTime - lowerBoundTime; return 0.;
double indexFraction = ( timeFraction ) / ( upperBoundTime - lowerBoundTime ); }else if( (1-SNAP_DISTANCE)< indexFraction ){
if( indexFraction < SNAP_DISTANCE ){
// round down to last index
return lowerBoundIndex;
}else if( indexFraction > (1-SNAP_DISTANCE)){
// round up to next index // round up to next index
return ++lowerBoundIndex; return 1.;
}else{ }else{
// general case // general case
return lowerBoundIndex + indexFraction; return indexFraction;
} }
} }
@ -304,7 +311,9 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
@Override @Override
public double getThrust( final double motorTime ){ public double getThrust( final double motorTime ){
double pseudoIndex = getPseudoIndex( motorTime ); double pseudoIndex = getPseudoIndex( motorTime );
return ThrustCurveMotor.interpolateAtIndex( thrust, pseudoIndex);
final double thrustAtTime= ThrustCurveMotor.interpolateAtIndex( thrust, pseudoIndex);
return thrustAtTime;
} }
@Override @Override
@ -370,18 +379,6 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
return this.unitRotationalInertia; return this.unitRotationalInertia;
} }
public double getIxx( final double searchTime) {
final double pseudoIndex = getPseudoIndex( searchTime);
//return this.unitLongitudinalInertia * this.getMassAtIndex( index);
return this.unitLongitudinalInertia * interpolateCenterOfMassAtIndex( pseudoIndex).weight;
}
public double getIyy( final double searchTime) {
final double pseudoIndex = getPseudoIndex( searchTime);
//return this.unitRotationalInertia * this.getMassAtIndex( index);
return this.unitRotationalInertia * interpolateCenterOfMassAtIndex( pseudoIndex).weight;
}
@Override @Override
public String getDesignation() { public String getDesignation() {
return designation; return designation;
@ -443,11 +440,12 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
private static double interpolateAtIndex( final double[] values, final double pseudoIndex ){ private static double interpolateAtIndex( final double[] values, final double pseudoIndex ){
final double SNAP_TOLERANCE = 0.0001; final double SNAP_TOLERANCE = 0.0001;
// assumes that pseudoIndex > 1
final double upperFrac = pseudoIndex%1;
final double lowerFrac = 1-upperFrac;
final int lowerIndex = (int)pseudoIndex; final int lowerIndex = (int)pseudoIndex;
final int upperIndex= lowerIndex+1; final int upperIndex= lowerIndex+1;
//
final double lowerFrac = pseudoIndex - ((double) lowerIndex);
final double upperFrac = 1-lowerFrac;
// if the pseudo // if the pseudo
if( SNAP_TOLERANCE > lowerFrac ){ if( SNAP_TOLERANCE > lowerFrac ){
@ -460,8 +458,8 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
final double lowerValue = values[lowerIndex]; final double lowerValue = values[lowerIndex];
final double upperValue = values[upperIndex]; final double upperValue = values[upperIndex];
// return simple linear interpolation // return simple linear inverse interpolation
return ( lowerValue*lowerFrac + upperValue*upperFrac ); return ( lowerValue*upperFrac + upperValue*lowerFrac );
} }

View File

@ -1,6 +1,7 @@
package net.sf.openrocket.motor; package net.sf.openrocket.motor;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
@ -116,8 +117,11 @@ public class ThrustCurveMotorTest {
}; };
for( Pair<Double,Double> testCase : testPairs ){ for( Pair<Double,Double> testCase : testPairs ){
final double time = testCase.getV(); final double motorTime = testCase.getV();
final double expThrust = testCase.getU(); final double expThrust = testCase.getU();
final double actThrust = mtr.getThrust(motorTime);
assertEquals( "Error in interpolating thrust: ", expThrust, actThrust, 0.001 );
} }
} }
@ -133,7 +137,7 @@ public class ThrustCurveMotorTest {
public void testTimeIndexingNegative(){ public void testTimeIndexingNegative(){
final ThrustCurveMotor mtr = motorX6; final ThrustCurveMotor mtr = motorX6;
// attempt to retrieve for a time before the motor ignites // attempt to retrieve for a time before the motor ignites
assertEquals( 0.0, mtr.getTime( -1 ), 0.00000001 ); assertTrue( "Fault in negative time indexing: ", Double.isNaN( mtr.getTime( -1 )) );
} }
@Test @Test