1 /*flapdata.cpp
2 Implements the flapping data class
3 Written by Theresa Robinson
4 robinst@ecf.toronto.edu
5 */
6 
7 //#ifndef flapdata_cpp
8 //#define flapdata_cpp
9 #include "uiuc_flapdata.h"
10 //#include <fstream>
11 #include <cassert>
12 
13 ///////////////////////////////////////////////////////////
14 //Implementation of FlapStruct public methods
15 //////////////////////////////////////////////////////////
16 
flapStruct()17 flapStruct::flapStruct(){
18         Lift=0;
19         Thrust=0;
20         Inertia=0;
21         Moment=0;
22 }
23 
flapStruct(const flapStruct & rhs)24 flapStruct::flapStruct(const flapStruct &rhs){
25         Lift=rhs.getLift();
26         Thrust=rhs.getThrust();
27         Inertia=rhs.getInertia();
28         Moment=rhs.getMoment();
29 }
30 
flapStruct(double newLift,double newThrust,double newMoment,double newInertia)31 flapStruct::flapStruct(double newLift, double newThrust,  double newMoment, double newInertia){
32         Lift=newLift;
33         Thrust=newThrust;
34         Inertia=newInertia;
35         Moment=newMoment;
36 }
37 
getLift() const38 double flapStruct::getLift() const{
39         return Lift;
40 }
41 
getThrust() const42 double flapStruct::getThrust() const{
43         return Thrust;
44 }
45 
getInertia() const46 double flapStruct::getInertia() const{
47         return Inertia;
48 }
49 
getMoment() const50 double flapStruct::getMoment() const{
51         return Moment;
52 }
53 
54 
55 /////////////////////////////////////////////////////////////////
56 //Implementation of FlapData public methods
57 ////////////////////////////////////////////////////////////////
58 
FlapData()59 FlapData::FlapData(){
60         liftTable=NULL;
61         thrustTable=NULL;
62         momentTable=NULL;
63         inertiaTable=NULL;
64 
65         alphaArray=NULL;
66         speedArray=NULL;
67         freqArray=NULL;
68         phiArray=NULL;
69 
70         lastAlphaIndex=0;
71         lastSpeedIndex=0;
72         lastPhiIndex=0;
73         lastFreqIndex=0;
74 }
75 
76 //A constructor that takes a file name:
77 //Opens that file and fills all the arrays from it
78 //sets the guesses to zero for the speed and halfway
79 //along the array for the alpha and frequency
80 //All it does is call init
81 
FlapData(const char * filename)82 FlapData::FlapData(const char* filename){
83   //  printf("init flapdata\n");
84         init(filename);
85         lastAlphaIndex=0;
86         lastSpeedIndex=0;
87         lastPhiIndex=0;
88         lastFreqIndex=0;
89 }
90 
91 //The destructor:
92 //Frees all memory associated with this object
~FlapData()93 FlapData::~FlapData(){
94   //  printf("deleting flapdata\n");
95   int i, j, k;
96   for(i=0;i<alphaLength;i++){
97     for(j=0;j<speedLength;j++){
98       for(k=0;k<freqLength;k++){
99         delete[] liftTable[i][j][k];
100         delete[] thrustTable[i][j][k];
101         delete[] momentTable[i][j][k];
102         delete[] inertiaTable[i][j][k];
103       }
104       delete[] liftTable[i][j];
105       delete[] thrustTable[i][j];
106       delete[] momentTable[i][j];
107       delete[] inertiaTable[i][j];
108     }
109     delete[] liftTable[i];
110     delete[] thrustTable[i];
111     delete[] momentTable[i];
112     delete[] inertiaTable[i];
113   }
114   delete[] liftTable;
115   delete[] thrustTable;
116   delete[] momentTable;
117   delete[] inertiaTable;
118   delete[] alphaArray;
119   delete[] speedArray;
120   delete[] freqArray;
121   delete[] phiArray;
122 }
123 
124 //An initialization function that does the same thing
125 //as the second constructor
126 //returns zero if it was successful
init(const char * filename)127 int FlapData::init(const char* filename){
128 
129         ifstream* f=new ifstream(filename);     //open file for reading in text (ascii) mode
130         if (f==NULL) {  //file open error
131                 return(1);
132         }
133         if(readIn(f)){ //read the file, if there's a problem
134                 return(2);
135         }
136         delete f;
137         return 0;
138   //close the file, return the success of the file close
139 }
140 
141 //A function that returns the interpolated values
142 //for all four associated numbers
143 //given the angle of attack, speed, and flapping frequency
flapper(double alpha,double speed,double freq,double phi)144 flapStruct FlapData::flapper(double alpha, double speed, double freq, double phi){
145 
146         flapStruct results;
147         int i,j,k,l;
148         double lift,thrust,moment,inertia;
149         if(speed<speedArray[0]){
150                 speed=speedArray[0];
151         }
152         if(speed>speedArray[speedLength-1]){
153                 speed=speedArray[speedLength-1];
154         }
155         if(alpha<alphaArray[0]){
156                 alpha=alphaArray[0];
157         }
158         if(alpha>alphaArray[alphaLength-1]){
159                 alpha=alphaArray[alphaLength-1];
160         }
161         i=findIndex(alphaArray,alphaLength,alpha,lastAlphaIndex);
162         j=findIndex(speedArray,speedLength,speed,lastSpeedIndex);
163         k=findIndex(freqArray,freqLength,freq,lastFreqIndex);
164         l=findIndex(phiArray,phiLength,phi,lastPhiIndex);
165 
166         lift=interpolate(liftTable, i, j, k, l, alpha, speed, freq, phi);
167         thrust=interpolate(thrustTable, i, j, k, l, alpha, speed, freq, phi);
168         moment=interpolate(momentTable, i, j, k, l, alpha, speed, freq, phi);
169         inertia=interpolate(inertiaTable, i, j, k, l, alpha, speed, freq, phi);
170         results=flapStruct(lift,thrust,moment,inertia);
171         return results;
172 }
173 
174 //////////////////////////////////////////////////////////////////
175 //Implementation of private  FlapData methods
176 //////////////////////////////////////////////////////////////////
177 
178 //A function that returns an index i such that
179 // array[i] < value < array[i+1]
180 //The function returns -1 if
181 // (value < array[0]) OR (value > array[n-1])
182 //(i.e. the value is not within the bounds of the array)
183 //It performs a linear search starting at guess
findIndex(double array[],double n,double value,int i)184 int FlapData::findIndex(double array[], double n, double value, int i){
185 
186         while(value<array[i]){  //less than the lower end of interval i
187                 if(i==0){            //if we're at the start of the array
188                         return(-1);                     //there's a problem
189                 }
190                 i--;                 //otherwise move to the next lower interval
191         }
192         while(value>array[i+1]){        //more than the higher end of interval i
193                 if(i==n-1){             //if we're at the end of the array
194                         return(-1);                             //there's a problem
195                 }
196                 i++;                    //otherwise move to the next higher interval
197         }
198 //        errmsg("In findIndex: array[" << i << "]= " << array[i] << "<=" << value << "<= array[" << (i+1) << "]=" << array[i+1]);
199         return(i);
200 }
201 
202 //A function that performs a linear interpolation based on the
203 //eight points surrounding the value required
interpolate(double **** table,int i,int j,int k,int l,double alpha,double speed,double freq,double phi)204 double FlapData::interpolate(double**** table, int i, int j, int k, int l, double alpha, double speed, double freq, double phi){
205 //        errmsg("\t\t\t\t\t\t\t\tGetting Values");
206         double f0000=table[i][j][k][l];
207         double f0001=table[i][j][k][l+1];
208         double f0010=table[i][j][k+1][l];
209         double f0011=table[i][j][k+1][l+1];
210         double f0100=table[i][j+1][k][l];
211         double f0101=table[i][j+1][k][l+1];
212         double f0110=table[i][j+1][k+1][l];
213         double f0111=table[i][j+1][k+1][l+1];
214         double f1000=table[i+1][j][k][l];
215         double f1001=table[i+1][j][k][l+1];
216         double f1010=table[i+1][j][k+1][l];
217         double f1011=table[i+1][j][k+1][l+1];
218         double f1100=table[i+1][j+1][k][l];
219         double f1101=table[i+1][j+1][k][l+1];
220         double f1110=table[i+1][j+1][k+1][l];
221         double f1111=table[i+1][j+1][k+1][l+1];
222 
223   //      errmsg("\t\t\t\t\t\t\t\t1st pass (3)");
224     //    errmsg("phi[" << l << "]=" << phiArray[l] << "; phi[" << (l+1) <<"]=" << phiArray[l+1]);
225       //  errmsg("Finding " << phi <<endl;
226         double f000=interpolate(phiArray[l],f0000,phiArray[l+1],f0001,phi);
227         double f001=interpolate(phiArray[l],f0010,phiArray[l+1],f0011,phi);
228         double f010=interpolate(phiArray[l],f0100,phiArray[l+1],f0101,phi);
229         double f011=interpolate(phiArray[l],f0110,phiArray[l+1],f0111,phi);
230         double f100=interpolate(phiArray[l],f1000,phiArray[l+1],f1001,phi);
231         double f101=interpolate(phiArray[l],f1010,phiArray[l+1],f1011,phi);
232         double f110=interpolate(phiArray[l],f1100,phiArray[l+1],f1101,phi);
233         double f111=interpolate(phiArray[l],f1110,phiArray[l+1],f1111,phi);
234 
235 //        errmsg("\t\t\t\t\t\t\t\t2nd pass (2)");
236         double f00=interpolate(freqArray[k],f000,freqArray[k+1],f001,freq);
237         double f01=interpolate(freqArray[k],f010,freqArray[k+1],f011,freq);
238         double f10=interpolate(freqArray[k],f100,freqArray[k+1],f101,freq);
239         double f11=interpolate(freqArray[k],f110,freqArray[k+1],f111,freq);
240 
241   //      errmsg("\t\t\t\t\t\t\t\t3rd pass (1)");
242         double f0=interpolate(speedArray[j],f00,speedArray[j+1],f01,speed);
243         double f1=interpolate(speedArray[j],f10,speedArray[j+1],f11,speed);
244 
245     //    errmsg("\t\t\t\t\t\t\t\t4th pass (0)");
246         double f=interpolate(alphaArray[i],f0,alphaArray[i+1],f1,alpha);
247         return(f);
248 }
249 
250 //A function that performs a linear interpolation based
251 //on the two nearest points
interpolate(double x0,double y0,double x1,double y1,double x)252 double FlapData::interpolate(double x0, double y0, double x1, double y1, double x){
253         double slope,y;
254         assert(x1!=x0);
255         slope=(y1-y0)/(x1-x0);
256         y=y0+slope*(x-x0);
257         return y;
258 }
259 
260 //A function called by init that reads in the file
261 //of the correct format and stores it in the arrays and tables
readIn(ifstream * f)262 int FlapData::readIn (ifstream* f){
263 
264         int i,j,k,l;
265         //int count=0;
266         char numstr[200];
267 
268         f->getline(numstr,200);
269         sscanf(numstr,"%d,%d,%d,%d",&alphaLength,&speedLength,&freqLength,&phiLength);
270 
271         //Check to see if the first line is 0 0 0 0
272         //If so, tell user to download data file
273         //Quits FlightGear
274         if (alphaLength==0 && speedLength==0 && freqLength==0 && phiLength==0)
275           uiuc_warnings_errors(7,"");
276 
277         alphaArray=new double[alphaLength];
278         speedArray=new double[speedLength];
279         freqArray=new double[freqLength];
280         phiArray=new double[phiLength];
281 
282         for(i=0;i<alphaLength;i++){
283                 f->get(numstr,20,',');
284                 sscanf(numstr,"%lf",&alphaArray[i]);
285                 f->get();
286         }
287         f->get();
288         for(i=0;i<speedLength;i++){
289                 f->get(numstr,20,',');
290                 sscanf(numstr,"%lf",&speedArray[i]);
291                 f->get();
292         }
293         f->get();
294         for(i=0;i<freqLength;i++){
295                 f->get(numstr,20,',');
296                 sscanf(numstr,"%lf",&freqArray[i]);
297                 f->get();
298         }
299         f->get();
300         for(i=0;i<phiLength;i++){
301                 f->get(numstr,20,',');
302                 sscanf(numstr,"%lf",&phiArray[i]);
303                 f->get();
304         }
305         f->get();
306         liftTable=new double***[alphaLength];
307         thrustTable=new double***[alphaLength];
308         momentTable=new double***[alphaLength];
309         inertiaTable=new double***[alphaLength];
310         for(i=0;i<alphaLength;i++){
311                 liftTable[i]=new double**[speedLength];
312                 thrustTable[i]=new double**[speedLength];
313                 momentTable[i]=new double**[speedLength];
314                 inertiaTable[i]=new double**[speedLength];
315                 for(j=0;j<speedLength;j++){
316                         liftTable[i][j]=new double*[freqLength];
317                         thrustTable[i][j]=new double*[freqLength];
318                         momentTable[i][j]=new double*[freqLength];
319                         inertiaTable[i][j]=new double*[freqLength];
320                         for(k=0;k<freqLength;k++){
321                                  liftTable[i][j][k]=new double[phiLength];
322                                  thrustTable[i][j][k]=new double[phiLength];
323                                  momentTable[i][j][k]=new double[phiLength];
324                                  inertiaTable[i][j][k]=new double[phiLength];
325                         }
326                 }
327         }
328 
329         for(i=0;i<alphaLength;i++){
330                 for(j=0;j<speedLength;j++){
331                         for(k=0;k<freqLength;k++){
332                                 for(l=0;l<phiLength;l++){
333                                         f->getline(numstr,200);
334                                         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]);
335                                 }
336                         }
337                 }
338         }
339         return 0;
340 };
341 
342 //#endif
343