@@ -13,16 +13,22 @@ AirDC::AirDC(int pid)
13
13
_pid = pid;
14
14
// Geometric
15
15
_d=0.008 ;
16
+ _PitotXcog=0.5 ;// Distance alog x body axes of the Pitot tip
17
+ _PitotYcog=0 ;// Distance alog y body axes of the Pitot tip
18
+ _PitotZcog=0 ;// Distance alog z body axes of the Pitot tip
16
19
// Parameter values
17
20
_Rho=1.225 ;
18
- _p=101325 ;
21
+ _p=90000 ;
19
22
_T=288.15 ;
20
23
_RH=0.0 ;
21
24
_qc=0.0 ;
25
+ _pSeaLevel=101325 ; // Value of pressure at sea level
22
26
_AOA=0.17 ;
23
27
_AOS=0.00 ;
24
28
_IAS=0.0 ;
25
29
_TASPCorrected=0.0 ;
30
+ _AOAdot=1 ;
31
+ _AOSdot=0 ;
26
32
// Uncertainty of measurements
27
33
_uRho=0.0 ; // To be calculated, 0 default value
28
34
_up=5.0 ;
@@ -35,9 +41,7 @@ AirDC::AirDC(int pid)
35
41
_Ip=0 ;
36
42
_Iq=3 ;
37
43
_Ir=0 ;
38
- _Ipdot=0.00 ;
39
- _Iqdot=0.00 ;
40
- _Irdot=0.00 ;
44
+
41
45
}
42
46
// RhoAir(Pressure,Temperature,Relative Humidity,mode)
43
47
// Mode 1 is the default BasicAirData routine
@@ -229,7 +233,8 @@ void AirDC::ISAAltitude(int mode)
229
233
{
230
234
switch (mode)
231
235
{
232
- case 1 :
236
+ case 1 : // Uncorrected above mean sea level altitude
237
+ // http://www.basicairdata.eu/altimeter.html
233
238
{
234
239
double Ps,h;
235
240
Ps=_p*0.000295299875080277 ;// Pa to inHg Conversion
@@ -240,6 +245,42 @@ void AirDC::ISAAltitude(int mode)
240
245
_h=_h*0.3048 ;
241
246
// 76189.2339431570*(_p*0.000295299875080277)^0.190255
242
247
_uh=4418.19264813511 *pow (Ps,-0.809745 )*_up*0.000295299875080277 ;
248
+ break ;
249
+ }
250
+ case 2 : // Corrected above mean sea level altitude, pressure at sea level should be available.
251
+ // Sea level pressure should be put into _pSeaLevel
252
+ // Mimics https://en.wikipedia.org/wiki/QNH
253
+ {
254
+ /* Should solve for _h
255
+ 0=_p-pSeaLevel*(1-0.0065*_h/T0)^(g/Rair/0.0065);
256
+ 0=_p-pSeaLevel*(1-2.2557695644629534E-5*_h)^(5.255786239252914);
257
+ Newton method used
258
+ */
259
+ int i;
260
+ double f,fdot,t0,t1,t,erralt;
261
+ i=0 ;
262
+ t0=1000 ; // Newton's initial value
263
+ erralt=0 ; // Newton's initial value
264
+ // while (abs(t1-t0)>(1/100))||(i==0)
265
+ while ((abs (erralt)>(0.01 )) || (i==0 ))
266
+ {
267
+ t=t0;
268
+ f=_p-_pSeaLevel*pow ((1 -0.000022557695644629534 *t),(5.255786239252914 ));
269
+ fdot=_pSeaLevel*0.00011855842635829929 *pow ((1 -0.000022557695644629534 *t),(4.255786239252914 ));
270
+ t1=t0-f/fdot;
271
+ /* Serial.print("Iteration:");
272
+ Serial.println(i);
273
+ Serial.print("Current calculated altitude:");
274
+ Serial.println(t1);*/
275
+ erralt=t1-t0;
276
+ /* Serial.print("Altitude error:");
277
+ Serial.println(erralt);*/
278
+ t0=t1;
279
+ i=i+1 ;
280
+ }
281
+ _h=t1;
282
+ _uh=0 ; // Complete it!
283
+ break ;
243
284
}
244
285
}
245
286
@@ -258,7 +299,7 @@ String AirDC::OutputSerial(int mode)
258
299
String s4 (_qc, 6 );
259
300
String s5 (_AOA, 6 );
260
301
String s6 (_AOS, 6 );
261
- StreamOut=' $TMO,' +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
302
+ StreamOut=" $TMO," +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
262
303
// To read string on the other side
263
304
/*
264
305
if (Serial.find("$TMO,")) {
@@ -282,7 +323,7 @@ String AirDC::OutputSerial(int mode)
282
323
String s8 (_h, 6 );
283
324
String s9 (_mu, 6 );
284
325
String s10 (_Re, 6 );
285
- StreamOut=' $TAD,' +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6+' ,' +s7+' ,' +s8+' ,' +s9+' ,' +s10;
326
+ StreamOut=" $TAD," +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6+' ,' +s7+' ,' +s8+' ,' +s9+' ,' +s10;
286
327
break ;
287
328
}
288
329
case 3 : // Measurements uncertainty output
@@ -292,7 +333,7 @@ String AirDC::OutputSerial(int mode)
292
333
String s2 (_uT, 6 );
293
334
String s3 (_uRH, 6 );
294
335
String s4 (_uqc, 6 );
295
- StreamOut=' $TMU,' +s1+' ,' +s2+' ,' +s3+' ,' +s4;
336
+ StreamOut=" $TMU," +s1+' ,' +s2+' ,' +s3+' ,' +s4;
296
337
break ;
297
338
}
298
339
case 4 : // Air data uncertainty output
@@ -304,7 +345,7 @@ String AirDC::OutputSerial(int mode)
304
345
String s4 (_uTAS, 6 );
305
346
String s5 (_uTAT, 6 );
306
347
String s6 (_uh, 6 );
307
- StreamOut=' $TAU,' +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
348
+ StreamOut=" $TAU," +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
308
349
break ;
309
350
}
310
351
return StreamOut;
@@ -330,12 +371,13 @@ void AirDC::PitotCorrection(int mode)
330
371
float PW[3 ][1 ]; // Position of probe tip in wind ref. frame
331
372
float PWDOT[3 ][1 ]; // Velocity of tip in wind ref. frame
332
373
float VCorrected[3 ][1 ]; // Measured Airspeed
333
- PB[0 ][0 ]=0.5 ; // Installation position respect c.o.g.
334
- PB[1 ][0 ]=0 ;
335
- PB[2 ][0 ]=0 ;
336
- WB[0 ][0 ]=_Ip; // Angular rates . P, q, r from sensors
337
- WB[1 ][0 ]=_Iq;
338
- WB[2 ][0 ]=_Ir;
374
+ PB[0 ][0 ]=_PitotXcog; // Installation position respect c.o.g.
375
+ PB[1 ][0 ]=_PitotYcog;
376
+ PB[2 ][0 ]=_PitotZcog;
377
+ WB[0 ][0 ]=_Ip-_AOSdot*sin (_AOA); // Angular rates . P, q, r from sensors and
378
+ // WB[1][0]=_Iq-_AOAdot;
379
+ WB[1 ][0 ]=0 ;
380
+ WB[2 ][0 ]=_Ir+_AOSdot*cos (_AOA);
339
381
// Matrix.Print((float*)PB,3,1,"PB");
340
382
R[0 ][0 ]=cos (_AOA)*cos (_AOS);
341
383
R[0 ][1 ]=sin (_AOS);
@@ -349,7 +391,7 @@ void AirDC::PitotCorrection(int mode)
349
391
350
392
// Calculation of Position vector in wind axes
351
393
Matrix.Multiply ((float *)R,(float *)PB,3 ,3 ,1 ,(float *)PW);
352
- // Calculation of angular rates at tip in wind frame. Attention, assumed low angular acceleration. High rates in another method.
394
+ // Calculation of angular rates at tip in wind frame.
353
395
354
396
Matrix.Multiply ((float *)R,(float *)WB,3 ,3 ,1 ,(float *)WW);
355
397
// Calculation of velocity vector at tip in wind coordinates
@@ -362,7 +404,6 @@ void AirDC::PitotCorrection(int mode)
362
404
VCorrected[1 ][0 ]= -PWDOT[1 ][0 ];
363
405
VCorrected[2 ][0 ]= -PWDOT[2 ][0 ];
364
406
_TASPCorrected=sqrt (pow (VCorrected[0 ][0 ],2 )+pow (VCorrected[1 ][0 ],2 )+pow (VCorrected[2 ][0 ],2 ));
365
- // _TASPCorrected=0;
366
407
break ;
367
408
}
368
409
}
0 commit comments