1
0
Fork 0
flightgear/src/FDM/UIUCModel/uiuc_flapdata.cpp

342 lines
12 KiB
C++

/*flapdata.cpp
Implements the flapping data class
Written by Theresa Robinson
robinst@ecf.toronto.edu
*/
//#ifndef flapdata_cpp
//#define flapdata_cpp
#include "uiuc_flapdata.h"
//#include <fstream>
#include <cassert>
///////////////////////////////////////////////////////////
//Implementation of FlapStruct public methods
//////////////////////////////////////////////////////////
flapStruct::flapStruct(){
Lift=0;
Thrust=0;
Inertia=0;
Moment=0;
}
flapStruct::flapStruct(const flapStruct &rhs){
Lift=rhs.getLift();
Thrust=rhs.getThrust();
Inertia=rhs.getInertia();
Moment=rhs.getMoment();
}
flapStruct::flapStruct(double newLift, double newThrust, double newMoment, double newInertia){
Lift=newLift;
Thrust=newThrust;
Inertia=newInertia;
Moment=newMoment;
}
double flapStruct::getLift() const{
return Lift;
}
double flapStruct::getThrust() const{
return Thrust;
}
double flapStruct::getInertia() const{
return Inertia;
}
double flapStruct::getMoment() const{
return Moment;
}
/////////////////////////////////////////////////////////////////
//Implementation of FlapData public methods
////////////////////////////////////////////////////////////////
FlapData::FlapData(){
liftTable=NULL;
thrustTable=NULL;
momentTable=NULL;
inertiaTable=NULL;
alphaArray=NULL;
speedArray=NULL;
freqArray=NULL;
phiArray=NULL;
lastAlphaIndex=0;
lastSpeedIndex=0;
lastPhiIndex=0;
lastFreqIndex=0;
}
//A constructor that takes a file name:
//Opens that file and fills all the arrays from it
//sets the guesses to zero for the speed and halfway
//along the array for the alpha and frequency
//All it does is call init
FlapData::FlapData(const char* filename){
// printf("init flapdata\n");
init(filename);
lastAlphaIndex=0;
lastSpeedIndex=0;
lastPhiIndex=0;
lastFreqIndex=0;
}
//The destructor:
//Frees all memory associated with this object
FlapData::~FlapData(){
// printf("deleting flapdata\n");
int i, j, k;
for(i=0;i<alphaLength;i++){
for(j=0;j<speedLength;j++){
for(k=0;k<freqLength;k++){
delete[] liftTable[i][j][k];
delete[] thrustTable[i][j][k];
delete[] momentTable[i][j][k];
delete[] inertiaTable[i][j][k];
}
delete[] liftTable[i][j];
delete[] thrustTable[i][j];
delete[] momentTable[i][j];
delete[] inertiaTable[i][j];
}
delete[] liftTable[i];
delete[] thrustTable[i];
delete[] momentTable[i];
delete[] inertiaTable[i];
}
delete[] liftTable;
delete[] thrustTable;
delete[] momentTable;
delete[] inertiaTable;
delete alphaArray;
delete speedArray;
delete freqArray;
delete phiArray;
}
//An initialization function that does the same thing
//as the second constructor
//returns zero if it was successful
int FlapData::init(const char* filename){
ifstream* f=new ifstream(filename); //open file for reading in text (ascii) mode
if (f==NULL) { //file open error
return(1);
}
if(readIn(f)){ //read the file, if there's a problem
return(2);
}
delete f;
return 0;
//close the file, return the success of the file close
}
//A function that returns the interpolated values
//for all four associated numbers
//given the angle of attack, speed, and flapping frequency
flapStruct FlapData::flapper(double alpha, double speed, double freq, double phi){
flapStruct results;
int i,j,k,l;
double lift,thrust,moment,inertia;
if(speed<speedArray[0]){
speed=speedArray[0];
}
if(speed>speedArray[speedLength-1]){
speed=speedArray[speedLength-1];
}
if(alpha<alphaArray[0]){
alpha=alphaArray[0];
}
if(alpha>alphaArray[alphaLength-1]){
alpha=alphaArray[alphaLength-1];
}
i=findIndex(alphaArray,alphaLength,alpha,lastAlphaIndex);
j=findIndex(speedArray,speedLength,speed,lastSpeedIndex);
k=findIndex(freqArray,freqLength,freq,lastFreqIndex);
l=findIndex(phiArray,phiLength,phi,lastPhiIndex);
lift=interpolate(liftTable, i, j, k, l, alpha, speed, freq, phi);
thrust=interpolate(thrustTable, i, j, k, l, alpha, speed, freq, phi);
moment=interpolate(momentTable, i, j, k, l, alpha, speed, freq, phi);
inertia=interpolate(inertiaTable, i, j, k, l, alpha, speed, freq, phi);
results=flapStruct(lift,thrust,moment,inertia);
return results;
}
//////////////////////////////////////////////////////////////////
//Implementation of private FlapData methods
//////////////////////////////////////////////////////////////////
//A function that returns an index i such that
// array[i] < value < array[i+1]
//The function returns -1 if
// (value < array[0]) OR (value > array[n-1])
//(i.e. the value is not within the bounds of the array)
//It performs a linear search starting at guess
int FlapData::findIndex(double array[], double n, double value, int i){
while(value<array[i]){ //less than the lower end of interval i
if(i==0){ //if we're at the start of the array
return(-1); //there's a problem
}
i--; //otherwise move to the next lower interval
}
while(value>array[i+1]){ //more than the higher end of interval i
if(i==n-1){ //if we're at the end of the array
return(-1); //there's a problem
}
i++; //otherwise move to the next higher interval
}
// errmsg("In findIndex: array[" << i << "]= " << array[i] << "<=" << value << "<= array[" << (i+1) << "]=" << array[i+1]);
return(i);
}
//A function that performs a linear interpolation based on the
//eight points surrounding the value required
double FlapData::interpolate(double**** table, int i, int j, int k, int l, double alpha, double speed, double freq, double phi){
// errmsg("\t\t\t\t\t\t\t\tGetting Values");
double f0000=table[i][j][k][l];
double f0001=table[i][j][k][l+1];
double f0010=table[i][j][k+1][l];
double f0011=table[i][j][k+1][l+1];
double f0100=table[i][j+1][k][l];
double f0101=table[i][j+1][k][l+1];
double f0110=table[i][j+1][k+1][l];
double f0111=table[i][j+1][k+1][l+1];
double f1000=table[i+1][j][k][l];
double f1001=table[i+1][j][k][l+1];
double f1010=table[i+1][j][k+1][l];
double f1011=table[i+1][j][k+1][l+1];
double f1100=table[i+1][j+1][k][l];
double f1101=table[i+1][j+1][k][l+1];
double f1110=table[i+1][j+1][k+1][l];
double f1111=table[i+1][j+1][k+1][l+1];
// errmsg("\t\t\t\t\t\t\t\t1st pass (3)");
// errmsg("phi[" << l << "]=" << phiArray[l] << "; phi[" << (l+1) <<"]=" << phiArray[l+1]);
// errmsg("Finding " << phi <<endl;
double f000=interpolate(phiArray[l],f0000,phiArray[l+1],f0001,phi);
double f001=interpolate(phiArray[l],f0010,phiArray[l+1],f0011,phi);
double f010=interpolate(phiArray[l],f0100,phiArray[l+1],f0101,phi);
double f011=interpolate(phiArray[l],f0110,phiArray[l+1],f0111,phi);
double f100=interpolate(phiArray[l],f1000,phiArray[l+1],f1001,phi);
double f101=interpolate(phiArray[l],f1010,phiArray[l+1],f1011,phi);
double f110=interpolate(phiArray[l],f1100,phiArray[l+1],f1101,phi);
double f111=interpolate(phiArray[l],f1110,phiArray[l+1],f1111,phi);
// errmsg("\t\t\t\t\t\t\t\t2nd pass (2)");
double f00=interpolate(freqArray[k],f000,freqArray[k+1],f001,freq);
double f01=interpolate(freqArray[k],f010,freqArray[k+1],f011,freq);
double f10=interpolate(freqArray[k],f100,freqArray[k+1],f101,freq);
double f11=interpolate(freqArray[k],f110,freqArray[k+1],f111,freq);
// errmsg("\t\t\t\t\t\t\t\t3rd pass (1)");
double f0=interpolate(speedArray[j],f00,speedArray[j+1],f01,speed);
double f1=interpolate(speedArray[j],f10,speedArray[j+1],f11,speed);
// errmsg("\t\t\t\t\t\t\t\t4th pass (0)");
double f=interpolate(alphaArray[i],f0,alphaArray[i+1],f1,alpha);
return(f);
}
//A function that performs a linear interpolation based
//on the two nearest points
double FlapData::interpolate(double x0, double y0, double x1, double y1, double x){
double slope,y;
assert(x1!=x0);
slope=(y1-y0)/(x1-x0);
y=y0+slope*(x-x0);
return y;
}
//A function called by init that reads in the file
//of the correct format and stores it in the arrays and tables
int FlapData::readIn (ifstream* f){
int i,j,k,l;
int count=0;
char numstr[200];
f->getline(numstr,200);
sscanf(numstr,"%d,%d,%d,%d",&alphaLength,&speedLength,&freqLength,&phiLength);
//Check to see if the first line is 0 0 0 0
//If so, tell user to download data file
//Quits FlightGear
if (alphaLength==0 && speedLength==0 && freqLength==0 && phiLength==0)
uiuc_warnings_errors(7,"");
alphaArray=new double[alphaLength];
speedArray=new double[speedLength];
freqArray=new double[freqLength];
phiArray=new double[phiLength];
for(i=0;i<alphaLength;i++){
f->get(numstr,20,',');
sscanf(numstr,"%lf",&alphaArray[i]);
f->get();
}
f->get();
for(i=0;i<speedLength;i++){
f->get(numstr,20,',');
sscanf(numstr,"%lf",&speedArray[i]);
f->get();
}
f->get();
for(i=0;i<freqLength;i++){
f->get(numstr,20,',');
sscanf(numstr,"%lf",&freqArray[i]);
f->get();
}
f->get();
for(i=0;i<phiLength;i++){
f->get(numstr,20,',');
sscanf(numstr,"%lf",&phiArray[i]);
f->get();
}
f->get();
liftTable=new double***[alphaLength];
thrustTable=new double***[alphaLength];
momentTable=new double***[alphaLength];
inertiaTable=new double***[alphaLength];
for(i=0;i<alphaLength;i++){
liftTable[i]=new double**[speedLength];
thrustTable[i]=new double**[speedLength];
momentTable[i]=new double**[speedLength];
inertiaTable[i]=new double**[speedLength];
for(j=0;j<speedLength;j++){
liftTable[i][j]=new double*[freqLength];
thrustTable[i][j]=new double*[freqLength];
momentTable[i][j]=new double*[freqLength];
inertiaTable[i][j]=new double*[freqLength];
for(k=0;k<freqLength;k++){
liftTable[i][j][k]=new double[phiLength];
thrustTable[i][j][k]=new double[phiLength];
momentTable[i][j][k]=new double[phiLength];
inertiaTable[i][j][k]=new double[phiLength];
}
}
}
for(i=0;i<alphaLength;i++){
for(j=0;j<speedLength;j++){
for(k=0;k<freqLength;k++){
for(l=0;l<phiLength;l++){
f->getline(numstr,200);
sscanf(numstr,"%lf %lf %lf %lf",&liftTable[i][j][k][l],&thrustTable[i][j][k][l],&momentTable[i][j][k][l],&inertiaTable[i][j][k][l]);
}
}
}
}
return 0;
};
//#endif