[Bugfix] ThrustCurve motor interpolation fixed.
This commit is contained in:
parent
7b2e195392
commit
56463b02fc
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user