@@ -13,16 +13,22 @@ AirDC::AirDC(int pid)
1313 _pid = pid;
1414 // Geometric
1515 _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
1619 // Parameter values
1720 _Rho=1.225 ;
18- _p=101325 ;
21+ _p=90000 ;
1922 _T=288.15 ;
2023 _RH=0.0 ;
2124 _qc=0.0 ;
25+ _pSeaLevel=101325 ; // Value of pressure at sea level
2226 _AOA=0.17 ;
2327 _AOS=0.00 ;
2428 _IAS=0.0 ;
2529 _TASPCorrected=0.0 ;
30+ _AOAdot=1 ;
31+ _AOSdot=0 ;
2632 // Uncertainty of measurements
2733 _uRho=0.0 ; // To be calculated, 0 default value
2834 _up=5.0 ;
@@ -35,9 +41,7 @@ AirDC::AirDC(int pid)
3541 _Ip=0 ;
3642 _Iq=3 ;
3743 _Ir=0 ;
38- _Ipdot=0.00 ;
39- _Iqdot=0.00 ;
40- _Irdot=0.00 ;
44+
4145}
4246// RhoAir(Pressure,Temperature,Relative Humidity,mode)
4347// Mode 1 is the default BasicAirData routine
@@ -229,7 +233,8 @@ void AirDC::ISAAltitude(int mode)
229233{
230234 switch (mode)
231235 {
232- case 1 :
236+ case 1 : // Uncorrected above mean sea level altitude
237+ // http://www.basicairdata.eu/altimeter.html
233238 {
234239 double Ps,h;
235240 Ps=_p*0.000295299875080277 ;// Pa to inHg Conversion
@@ -240,6 +245,42 @@ void AirDC::ISAAltitude(int mode)
240245 _h=_h*0.3048 ;
241246 // 76189.2339431570*(_p*0.000295299875080277)^0.190255
242247 _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 ;
243284 }
244285 }
245286
@@ -258,7 +299,7 @@ String AirDC::OutputSerial(int mode)
258299 String s4 (_qc, 6 );
259300 String s5 (_AOA, 6 );
260301 String s6 (_AOS, 6 );
261- StreamOut=' $TMO,' +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
302+ StreamOut=" $TMO," +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
262303// To read string on the other side
263304 /*
264305 if (Serial.find("$TMO,")) {
@@ -282,7 +323,7 @@ String AirDC::OutputSerial(int mode)
282323 String s8 (_h, 6 );
283324 String s9 (_mu, 6 );
284325 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;
286327 break ;
287328 }
288329 case 3 : // Measurements uncertainty output
@@ -292,7 +333,7 @@ String AirDC::OutputSerial(int mode)
292333 String s2 (_uT, 6 );
293334 String s3 (_uRH, 6 );
294335 String s4 (_uqc, 6 );
295- StreamOut=' $TMU,' +s1+' ,' +s2+' ,' +s3+' ,' +s4;
336+ StreamOut=" $TMU," +s1+' ,' +s2+' ,' +s3+' ,' +s4;
296337 break ;
297338 }
298339 case 4 : // Air data uncertainty output
@@ -304,7 +345,7 @@ String AirDC::OutputSerial(int mode)
304345 String s4 (_uTAS, 6 );
305346 String s5 (_uTAT, 6 );
306347 String s6 (_uh, 6 );
307- StreamOut=' $TAU,' +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
348+ StreamOut=" $TAU," +s1+' ,' +s2+' ,' +s3+' ,' +s4+' ,' +s5+' ,' +s6;
308349 break ;
309350 }
310351 return StreamOut;
@@ -330,12 +371,13 @@ void AirDC::PitotCorrection(int mode)
330371 float PW[3 ][1 ]; // Position of probe tip in wind ref. frame
331372 float PWDOT[3 ][1 ]; // Velocity of tip in wind ref. frame
332373 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);
339381// Matrix.Print((float*)PB,3,1,"PB");
340382 R[0 ][0 ]=cos (_AOA)*cos (_AOS);
341383 R[0 ][1 ]=sin (_AOS);
@@ -349,7 +391,7 @@ void AirDC::PitotCorrection(int mode)
349391
350392// Calculation of Position vector in wind axes
351393 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.
353395
354396 Matrix.Multiply ((float *)R,(float *)WB,3 ,3 ,1 ,(float *)WW);
355397// Calculation of velocity vector at tip in wind coordinates
@@ -362,7 +404,6 @@ void AirDC::PitotCorrection(int mode)
362404 VCorrected[1 ][0 ]= -PWDOT[1 ][0 ];
363405 VCorrected[2 ][0 ]= -PWDOT[2 ][0 ];
364406 _TASPCorrected=sqrt (pow (VCorrected[0 ][0 ],2 )+pow (VCorrected[1 ][0 ],2 )+pow (VCorrected[2 ][0 ],2 ));
365- // _TASPCorrected=0;
366407 break ;
367408 }
368409 }
0 commit comments