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