Module to calculate Lift and Drag Coefficients for airplane wings over the whole range of Angle of Attack (AoA). The standard values are for an A320 with a CL / CD = 18 ratio.
function rad(x) { return x * Math.PI / 180; }
var ClModel = {
aoa1: -5,
aoa2: 18,
cl1: 0.2,
cl2: 5.16,
cd1: 0.02,
cd2: 0.026,
clpOffset: 0.1,
q: 25,
graph: null,
Init: function( g ) {
this.graph = g;
},
CL: function( aoa ) {
// lift coefficient for wing profile
var result = this.cl1 + this.cl2 * aoa;
return result;
},
CD: function( aoa ) {
// drag coefficient for wing profile
var result = this.cd1 + this.cd2 * Math.pow( this.CL(aoa), 2 );
return result;
},
CLP: function( aoa ) {
// lift coefficient for flat wing
var result = Math.sin( 2 * aoa ) + this.clpOffset;
return result;
},
CDP: function( aoa ) {
// drag coefficient for flat wing
var result = 1 - Math.cos( 2 * aoa );
return result;
},
Up: function( x, pos ) {
// ramp up from 0 to 1 at pos
var result = 1 / (1 + Math.exp( -this.q * (x - pos)));
return result;
},
Down: function( x, pos ) {
// ramp down from 0 to 1 at pos
var result = 1 / (1 + Math.exp( this.q * (x - pos)));
return result;
},
Win: function( x, pos1, pos2 ) {
// ramp up from 0 to 1 at pos1 and down again at pos 2
var result = this.Up( x, pos1 ) * this.Down( x, pos2 );
return result;
},
// public
CLT: function( aoa ) {
// lift coefficient for whole range of AoA
// aoa in rad
if (aoa > Math.PI/2) aoa -= Math.PI;
if (aoa < -Math.PI/2) aoa += Math.PI;
var aoa1 = rad(this.aoa1);
var aoa2 = rad(this.aoa2);
var result =
this.Down( aoa, aoa1 ) * this.CLP( aoa ) +
this.Win( aoa, aoa1, aoa2 ) * this.CL( aoa ) +
this.Up( aoa, aoa2) * this.CLP( aoa );
return result;
},
CLT_deg: function( aoaDeg ) {
// lift coefficient for whole range of AoA
return this.CLT( rad(aoaDeg) );
},
CDT: function( aoa ) {
// drag coefficient for whole range of AoA
// aoa in rad
if (aoa > Math.PI/2) aoa -= Math.PI;
if (aoa < -Math.PI/2) aoa += Math.PI;
var aoa1 = rad(this.aoa1);
var aoa2 = rad(this.aoa2);
var result =
this.Down( aoa, aoa1 ) * this.CDP( aoa ) +
this.Win( aoa, aoa1, aoa2 ) * this.CD( aoa ) +
this.Up( aoa, aoa2) * this.CDP( aoa );
return result;
},
CDT_deg: function( aoaDeg ) {
return this.CDT( rad(aoaDeg) );
},
Update: function( field ) {
ControlPanels.Update();
this.Draw( this.graph );
},
Draw: function( g ) {
g.Reset();
g.SetWindowWH( -180, -2.5, 360, 5 );
g.SetLineAttr( 'lightgray', 1 );
g.Grid( 15, 0.2, true, false );
g.SetLineAttr( 'black', 1 );
g.Axes( 0, 0, 'Arrow1', 10 );
g.TicsX( 0, 15, 3, 3, true, true );
g.TicLabelsX( 0, 15, -4, 1, 0, true, true, '°' );
g.TicsY( 0, 0.2, 3, 3, true, true );
g.TicLabelsY( 0, 0.2, -4, 1, 1, true, true );
g.SetLineAttr( 'blue', 2 );
g.NewPoly();
var deltaAoa = 360 / 360;
var lastAoa = 180 + deltaAoa;
for (aoa = -180; aoa <= lastAoa; aoa += deltaAoa) {
g.AddPointToPoly( aoa, this.CLT_deg(aoa) );
}
g.DrawPoly( 1 );
g.SetLineAttr( 'red', 2 );
g.NewPoly();
var deltaAoa = 360 / 360;
var lastAoa = 180 + deltaAoa;
for (aoa = -180; aoa <= lastAoa; aoa += deltaAoa) {
g.AddPointToPoly( aoa, this.CDT_deg(aoa) );
}
g.DrawPoly( 1 );
},
};
var graph = NewGraph2D( {
Id: 'JsGraph1',
Width: '100%',
Height: '75%',
DrawFunc: function(g){ ClModel.Draw(g); },
AutoReset: true,
AutoClear: false,
AutoScalePix: false,
} );
ClModel.Init( graph );
xOnLoad( function() { ClModel.Update(); } );