|
4 | 4 | Refer to http:\\www.basicairdata.eu |
5 | 5 | */ |
6 | 6 | #include "AirDC.h" |
| 7 | +#include "MatrixMath.h" |
7 | 8 | #include <math.h> |
8 | 9 |
|
9 | 10 | AirDC::AirDC(int pid) |
10 | 11 | { |
11 | 12 | //Default parameters values |
12 | 13 | _pid = pid; |
| 14 | + //Geometric |
| 15 | + _d=0.008; |
13 | 16 | //Parameter values |
14 | 17 | _Rho=1.225; |
15 | 18 | _p=101325; |
@@ -159,8 +162,9 @@ void AirDC::CAS(int mode) |
159 | 162 | switch (mode) |
160 | 163 | { |
161 | 164 | case 1: |
162 | | - _CAS=_IAS; |
163 | | - _uCAS=_uIAS; |
| 165 | + //Here the calibration table should be lookup. |
| 166 | + _CAS=_IAS; |
| 167 | + _uCAS=_uIAS; |
164 | 168 | break; |
165 | 169 | } |
166 | 170 | } |
@@ -228,28 +232,95 @@ void AirDC::ISAAltitude(int mode) |
228 | 232 | } |
229 | 233 |
|
230 | 234 | } |
231 | | -void AirDC::OutputSerial(int mode){ |
232 | | -switch(mode){ |
233 | | -case 1: //Measurements only output |
| 235 | +void AirDC::OutputSerial(int mode) |
234 | 236 | { |
235 | | - //http://www.tigoe.com/pcomp/code/arduinowiring/1161/ |
| 237 | + switch(mode) |
| 238 | + { |
| 239 | + case 1: //Measurements only output |
| 240 | + { |
| 241 | + //http://www.tigoe.com/pcomp/code/arduinowiring/1161/ |
236 | 242 | //Measurements |
237 | 243 | //sprintf(_StreamOut,"$%f,%f,%f,%f\0",_p,_T,_RH,_qc); |
238 | | - String s1(_p, 6); |
239 | | - String s2(_T, 6); |
240 | | - String s3(_RH, 6); |
241 | | - String s4(_qc, 6); |
242 | | - _StreamOut='$'+s1+','+s2+','+s3+','+s4; |
| 244 | + String s1(_p, 6); |
| 245 | + String s2(_T, 6); |
| 246 | + String s3(_RH, 6); |
| 247 | + String s4(_qc, 6); |
| 248 | + _StreamOut='$'+s1+','+s2+','+s3+','+s4; |
243 | 249 | //To read string on the other side |
244 | | -/* |
245 | | - if (Serial.find("$")) { |
246 | | - _p = Serial.parseFloat(); // |
247 | | - _T = Serial.parseFloat();// |
248 | | - _RH = Serial.parseFloat();// |
249 | | - _qc = Serial.parseFloat();// |
250 | | -*/ |
| 250 | + /* |
| 251 | + if (Serial.find("$")) { |
| 252 | + _p = Serial.parseFloat(); // |
| 253 | + _T = Serial.parseFloat();// |
| 254 | + _RH = Serial.parseFloat();// |
| 255 | + _qc = Serial.parseFloat();// |
| 256 | + */ |
| 257 | + } |
| 258 | + } |
251 | 259 | } |
| 260 | +void AirDC::PitotCorrection(int mode) |
| 261 | +{ |
| 262 | +//Based on |
| 263 | +//http://basicairdata.blogspot.it/2014/07/pitot-correction-for-position-and.html |
| 264 | + switch (mode) |
| 265 | + { |
| 266 | + case 1: //Steady state(no angular acceleration) assumed for this method |
| 267 | + { |
| 268 | + float R[3][3]; |
| 269 | + float PB[3][1]; //Position of probe tip in body coordinates |
| 270 | + float WB[3][1]; //Angular rates in body coordinates [p q r]' |
| 271 | + float WW[3][1];//Angular rates in wind coordinates [p q r]' |
| 272 | + float PW[3][1]; //Position of probe tip in wind ref. frame |
| 273 | + float PWDOT[3][1]; //Velocity of tip in wind ref. frame |
| 274 | + float VCorrected[3][1]; //Measured Airspeed |
| 275 | + PB[1][1]=0.5; //Installation position respect c.o.g. |
| 276 | + PB[2][1]=0; |
| 277 | + PB[3][1]=0; |
| 278 | + R[1][1]=cos(_AOA)*cos(_AOS); |
| 279 | + R[1][2]=sin(_AOS); |
| 280 | + R[1][3]=sin(_AOA)*sin(_AOS); |
| 281 | + R[2][1]=-cos(_AOA)*sin(_AOS); |
| 282 | + R[2][2]=cos(_AOS); |
| 283 | + R[2][3]=-sin(_AOA)*sin(_AOS); |
| 284 | + R[3][1]=-sin(_AOA); |
| 285 | + R[3][2]=0; |
| 286 | + R[3][3]=cos(_AOA); |
| 287 | + |
| 288 | +//Calculation of Position vector in wind axes |
| 289 | + Matrix.Multiply((float*)R,(float*)PB,3,3,1,(float*)PW); |
| 290 | +//Calculation angular rates at tip in wind frame, attention low angular acceleration assumed. High rates in method 2. |
| 291 | + Matrix.Multiply((float*)R,(float*)WB,3,3,1,(float*)WW); |
| 292 | +//Calculation of velocity vector at tip in wind coordinates |
| 293 | +//Cross product WWxPW |
| 294 | + PWDOT[1][1]=WW[2][1]*PW[3][1]-WW[3][1]*PW[2][1]; |
| 295 | + PWDOT[2][1]=WW[3][1]*PW[1][1]-WW[1][1]*PW[3][1]; |
| 296 | + PWDOT[3][1]=WW[1][1]*PW[2][1]-WW[2][1]*PW[1][1]; |
| 297 | +//Airspeed vector |
| 298 | + VCorrected[1][1]=_TAS-PWDOT[1][1]; |
| 299 | + VCorrected[2][1]= -PWDOT[2][1]; |
| 300 | + VCorrected[3][1]= -PWDOT[3][1]; |
| 301 | + _TASPCorrected=sqrt(pow(VCorrected[1][1],2)+pow(VCorrected[2][1],2)+pow(VCorrected[3][1],2)); |
| 302 | + break; |
| 303 | + } |
| 304 | + } |
252 | 305 | } |
| 306 | +void AirDC::Viscosity(int mode) |
| 307 | +{ |
| 308 | + switch(mode) |
| 309 | + { |
| 310 | + case 1: |
| 311 | + { |
| 312 | + //Calculate viscosity. Sutherland's formula, note that unit of measurement [Pas] is multiplied by 10e3 |
| 313 | + _mu= 18.27*(291.15+120)/(_T+120)*pow((_T/291.15),(3/2)); |
| 314 | + } |
| 315 | + } |
| 316 | +} |
| 317 | +void AirDC::Red(int mode) |
| 318 | +{ |
| 319 | + switch(mode) |
| 320 | + { |
| 321 | + case 1: |
| 322 | + { |
| 323 | + _Re=_Rho*_TAS*_d/_mu; |
| 324 | + } |
| 325 | + } |
253 | 326 | } |
254 | | - |
255 | | - |
|
0 commit comments