This is the source code of the page Centrifugal and Gravitational Acceleration in an Aircraft and Zentrifugal- und Gravitationsbeschleunigung in einem Flugzeug. See the math of that page that describes all variables used in this code.
#INCLUDE ControlPanel.inc
<style>
#InputPanel-calLat, #InputPanel-calAlt, #OutputPanel-g0cal { background-color: #fed; }
#OutputPanel-grel { background-color: #ddf; }
#OutputPanel-w0, #OutputPanel-dw { background-color: #fed; }
#OutputPanel-g0, #OutputPanel-gh, #OutputPanel-dg { background-color: #dfd; }
#InputPanel-wCal, #OutputPanel-wh { background-color: #ffd }
</style>
<jscript>
function CModel() {
// input
this.vGS = 308.64; // m/s, magnitude of ground speed
this.dir = 90; // deg, aircraft heading wrt. north
this.lat = -35; // deg, aircraft latitude
this.alt = 12496.8; // m, aircraft altitude
this.calLat = -35; // deg, weight calibration latitude
this.calAlt = 50; // m, weight calibration altitude
this.wCal = 500; // units, weight mass in any mass units
this.Model = 0; // 0 -> ellipsoid, 1 -> spehere
this.alpha = 0; // rad, aircraft heading wrt. rotating grat circle (->dir)
this.phi = 0; // rad, aircraft latitude (->lat)
this.theta = 0; // rad, heading wrt. non-rotating grat circle
// output, all values in metric units
this.grel = 0; // gh / g0, relative effective acceleration
this.g0 = 0; // effective acceleration on ground
this.g0G = 0; // gravitational acceleration on ground
this.g0Gx = 0; // x component of g0G
this.g0Gz = 0; // z component of g0G
this.a0Z = 0; // centrifugal acceleration on ground
this.a0Zx = 0; // x component of a0Z
this.a0Zz = 0; // z component of a0Z
this.g0cal = 0; // effective acceleration on weight calibratin location
this.w0 = 0; // weight of mass at sea level
this.wh = 0; // weight of mass at aircraft altitude
this.dw = 0; // wh - wCal
this.gh = 0; // effective acceleration at ac altitude
this.ghG = 0; // gravitational acceleration at ac altitude
this.ghGx = 0; // x component of ghG
this.ghGz = 0; // z component of ghG
this.ahZ = 0; // centrifugal acceleration at ac alt
this.ahZx = 0; // x component of ahZ
this.ahZz = 0; // z component of ahZ
this.dg = 0; // gh - g0
this.P0x = 0; // x component of ac pos at sea level
this.P0z = 0; // z component of ac pos at sea level
this.Phx = 0; // x component of ac pos at alt
this.Phz = 0; // z component of ac pos at alt
this.R = 0; // dist of ac pos at sea level from earth center
this.rho = 0; // radius of ac great circle path on sea level
this.rhoh = 0; // radius of ac great circle path at alt
this.rho1 = 0; // radius of red ellipse at ac pos and alt
this.rho2 = 0; // radius of blue ellipse at ac pos and alt
this.v = 0; // ac speed wrt geocentric coord sys
this.vx = 0; // x component of v
this.vy = 0; // y component of v
this.vRot = 0; // tangential earth rotation speed at ac pos and alt
this.vRotx = 0; // x component of vRot
this.vRoty = 0; // y component of vRot
this.vRelx = 0; // x component of ac speed wrt ground at alt
this.vRely = 0; // y component of ac speed wrt ground at alt
this.vEq = 0; // tangential speed of earth surface at equator
this.omega = 0; // = 2 * pi / T [rad/s], rotation speed of earth
// contstants
// GM = G * Mass of earth without mass of atmosphere:
this.GM = 3.986004418e14; // m^3/s^2, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
this.G = 6.67408e-11;
this.M = this.GM / this.G;
this.T = 86164.098903691; // s, https://en.wikipedia.org/wiki/Earth
this.Ra = 6378137; // m, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
this.Rb = 6356752.314245; // m, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
this.RMean = 6371008.7714; // m, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
this.ge = 9.7803253359; // m/s^2, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
this.gp = 9.8321849378; // m/s^2, http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf
// units
this.SpeedUnits = [ 'm/s', 'km/h', 'kt', 'mph' ];
this.SpeedMults = [ 1, 1/3.6, 0.5144, 0.44704 ];
this.SpeedUnitIx = 2;
this.SpeedUnit = 'kt';
this.SpeedMult = 0.5144;
this.AltUnits = [ 'm', 'ft', 'FL' ];
this.AltMults = [ 1, 0.3048, 30.48 ];
this.AltUnitIx = 1;
this.AltUnit = 'ft';
this.AltMult = 0.3048;
}
CModel.prototype.Clear = function() {
this.vGS = 0; // m/s
this.dir = 0; // deg
this.lat = 0; // deg
this.alt = 0; // m
this.calLat = 0;
this.calAlt = 0;
this.wCal = 0; // kg
this.Model = 0; // 0 -> ellipsoid, 1 -> spehere
}
CModel.prototype.Update = function() {
// functions
var sin = Math.sin;
var cos = Math.cos;
var sqrt = Math.sqrt;
function sqr( x ) { return x * x; }
function len( x, y ) { return sqrt( sqr(x) + sqr(y) ); }
function rad( a ) { return a * Math.PI / 180; }
function sp( x1, y1, x2, y2 ) { return x1 * x2 + y1 * y2; } // scalar product
function isSameDir( x1, y1, x2, y2 ) { return sp(x1,y1,x2,y2) >= 0; }
// setup units
this.SpeedUnit = this.SpeedUnits[this.SpeedUnitIx];
this.SpeedMult = this.SpeedMults[this.SpeedUnitIx]
this.AltUnit = this.AltUnits[this.AltUnitIx];
this.AltMult = this.AltMults[this.AltUnitIx];
// limit inputs
if (this.dir < -180) this.dir = -180;
if (this.dir > 360) this.dir = 360;
if (this.lat < -90) this.lat = -90;
if (this.lat > 90) this.lat = 90;
// angles in radian, omega, GM
this.alpha = rad( this.dir );
this.phi = rad( this.lat );
if (this.T == 0) {
this.omega = 0;
} else {
this.omega = 2 * Math.PI / this.T;
}
this.GM = this.G * this.M;
var a = this.Ra;
var b = this.Rb;
if (this.Model == 1) {
// globe model
a = this.RMean;
b = this.RMean;
}
var cosp = cos( this.phi );
var sinp = sin( this.phi );
var cosp2 = sqr( cosp );
var sinp2 = sqr( sinp );
var a2 = sqr( a );
var b2 = sqr( b );
// positions
// if globe model then a = b = this.RMean -> eps = 0 and Nphi = this.RMean
var eps = sqrt( a2 - b2 ) / a;
var Nphi = a / sqrt(1 - sqr(eps * sinp));
this.P0x = Nphi * cosp;
this.P0z = Nphi * (1 - sqr(eps)) * sinp;
this.Phx = (Nphi + this.alt) * cosp;
this.Phz = (Nphi * (1 - sqr(eps)) + this.alt) * sinp;
this.R = len( this.P0x, this.P0z );
// earth accelerations
this.a0Zx = sqr(this.omega) * this.P0x;
this.a0Zz = 0;
this.a0Z = len( this.a0Zx, this.a0Zz );
if (this.Model == 1) {
// globe model
this.g0G = this.GM / sqr(this.RMean);
this.g0Gx = - this.g0G * cosp;
this.g0Gz = - this.g0G * sinp;
var gx = this.g0Gx + this.a0Zx;
var gz = this.g0Gz + this.a0Zz;
this.g0 = len( gx, gz );
} else {
// ellipsoid model
this.g0 = ( a * this.ge * cosp2 + b * this.gp * sinp2 ) / sqrt( a2 * cosp2 + b2 * sinp2 );
var gx = - this.g0 * cosp;
var gz = - this.g0 * sinp;
this.g0Gx = gx - this.a0Zx;
this.g0Gz = gz - this.a0Zz;
this.g0G = len( this.g0Gx, this.g0Gz );
}
// geodesic radii for alpha
// red ellipse
var sx = cosp;
var sz = sinp;
var A = ( sqr(sx) / a2 ) + ( sqr(sz) / b2 );
var B = ( 2 * this.P0x * sx / a2 ) + ( 2 * this.P0z * sz / b2 );
var lambda = - B / A;
var Ox = this.P0x + 0.5 * lambda * sx;
var Oz = this.P0z + 0.5 * lambda * sz;
var Opx = Ox;
var Opz = (a / b) * Oz;
var m = len( Opx, Opz );
var as = sqrt( a2 - sqr(m) );
var bs = Math.abs( lambda ) / 2;
this.rho1 = sqr(as) / bs;
// blue ellipse
var as = a;
var bs = b;
this.rho2 = sqrt(Math.pow(Math.pow(as,4) * sqr(this.P0z) + Math.pow(bs,4) * sqr(this.P0x), 3)) / (Math.pow(as,4) * Math.pow(bs,4));
// use rho(alpha) for correction of ground speed vGS to vRel
this.rho = (this.rho1 + this.rho2) / 2 - (this.rho1 - this.rho2) / 2 * cos(2 * this.alpha);
this.rhoh = this.rho + this.alt;
// plane speed
this.vEq = this.omega * a;
this.vRotx = this.omega * this.Phx;
this.vRoty = 0;
this.vRot = this.vRotx;
var vrel = this.vGS * this.rhoh / this.rho;
this.vRelx = vrel * sin( this.alpha );
this.vRely = vrel * cos( this.alpha );
this.vx = this.vRotx + this.vRelx;
this.vy = this.vRoty + this.vRely;
this.v = len( this.vx, this.vy );
// use rho(theta(v)) for centrifugal acceleration in plane
if (this.v == 0) {
this.theta = 0;
} else {
this.theta = Math.acos( this.vy / this.v );
}
this.rho = (this.rho1 + this.rho2) / 2 - (this.rho1 - this.rho2) / 2 * cos(2 * this.theta);
this.rhoh = this.rho + this.alt;
// plane accelerations
var ahRot = sqr(this.omega) * this.Phx;
if (this.vGS != 0) {
// plane is moving independent of earth
this.ahZ = sqr(this.v) / this.rhoh;
this.ahZx = this.ahZ * cosp;
this.ahZz = this.ahZ * sinp;
} else {
// plane is bound to the earth
this.ahZ = ahRot;
this.ahZx = this.ahZ;
this.ahZz = 0;
}
if (this.Model == 1) {
// globe model
this.ghG = this.GM / sqr(this.RMean + this.alt);
this.ghGx = - this.ghG * cosp;
this.ghGz = - this.ghG * sinp;
var gx = this.ghGx + this.ahZx;
var gz = this.ghGz + this.ahZz;
this.gh = len( gx, gz );
} else {
// ellipsoid model
var f = (a - b) / a;
var m = sqr(this.omega * a) * b / this.GM;
var ghRot = this.g0 * ( 1 - (2 / a) * ( 1 + f + m - 2 * f * sinp2 ) * this.alt + (3 / a2) * sqr(this.alt) );
var ghRotx = - ghRot * cosp;
var ghRotz = - ghRot * sinp;
this.ghGx = ghRotx - ahRot;
this.ghGz = ghRotz;
this.ghG = len( this.ghGx, this.ghGz );
var gx = this.ghGx + this.ahZx;
var gz = this.ghGz + this.ahZz;
this.gh = len( gx, gz );
if (!isSameDir( this.ghGx, this.ghGz, gx, gz )) {
// g points outward!
this.gh *= -1;
}
}
this.dg = this.gh - this.g0;
// acceleration at calibration localtion
var phiCal = rad( this.calLat );
var cospCal = cos( phiCal );
var sinpCal = sin( phiCal );
var cosp2Cal = sqr( cospCal );
var sinp2Cal = sqr( sinpCal );
if (this.Model == 1) {
// globe model
var hcal = this.RMean + this.calAlt;
var g0Gcal = this.GM / sqr(hcal);
var g0Gcalx = - g0Gcal * cospCal;
var g0Gcalz = - g0Gcal * sinpCal;
var a0cal = sqr(this.omega) * hcal * cospCal;
this.g0cal = len( g0Gcalx + a0cal, g0Gcalz );
} else {
// ellipsoid model
// requires f and m are computed above
var gCal0 = ( a * this.ge * cosp2Cal + b * this.gp * sinp2Cal ) / sqrt( a2 * cosp2Cal + b2 * sinp2Cal );
this.g0cal = gCal0 * ( 1 - (2 / a) * ( 1 + f + m - 2 * f * sinp2Cal ) * this.calAlt + (3 / a2) * sqr(this.calAlt) );
}
// relative acceleration
this.grel = this.gh / this.g0;
// weights
this.w0 = this.wCal * this.g0 / this.g0cal;
this.wh = this.w0 * this.grel;
this.dw = this.wh - this.wCal;
}
var Model = new CModel();
function UpdateAll() {
Model.Update();
ControlPanels.Update();
}
function Reset() {
ControlPanels.Reset();
UpdateAll();
}
function Clear() {
Model.Clear();
UpdateAll();
}
ControlPanels.NewPanel( {
Name: 'InputPanel',
ModelRef: 'Model',
OnModelChange: UpdateAll,
Format: 'std',
Digits: 7,
NCols: 2
}
).AddHeader( {
Text: 'Flight and Test Mass Data',
ColSpan: 3
}
).AddHeader( {
Text: ControlPanels.ResetButtonR() + ControlPanels.SmallButtonR('Clear','Clear()')
}
).AddTextField( {
Name: 'vGS',
Label: 'GS',
UnitsRef: 'SpeedUnit',
MultRef: 'SpeedMult'
}
).AddTextField( {
Name: 'dir',
Label: 'Course',
Units: '°N'
}
).AddTextField( {
Name: 'lat',
Label: 'Lat',
Units: '°',
ConvToModelFunc: function(s) { return NumFormatter.DmsStrToNum( s ); },
}
).AddTextField( {
Name: 'alt',
Label: 'Alt',
UnitsRef: 'AltUnit',
MultRef: 'AltMult'
}
).AddTextField( {
Name: 'calLat',
Label: 'Lat<sub>cal</sub>',
Units: '°',
ConvToModelFunc: function(s) { return NumFormatter.DmsStrToNum( s ); },
}
).AddTextField( {
Name: 'calAlt',
Label: 'Alt<sub>cal</sub>',
UnitsRef: 'AltUnit',
MultRef: 'AltMult'
}
).AddTextField( {
Name: 'wCal',
Label: 'W<sub>cal</sub>',
Units: 'units',
}
).AddRadiobuttonField( {
Name: 'Model',
ValueType: 'int',
Items: [
{
Name: 'Ellipsoid',
Value: '0'
}, {
Name: 'Sphere',
Value: '1'
}
]
}
).Render();
ControlPanels.NewPanel( {
Name: 'OutputPanel',
ModelRef: 'Model',
NCols: 2,
Format: 'std',
Digits: 7,
ReadOnly: true
}
).AddHeader( {
Text: 'Results',
ColSpan: 4
}
).AddTextField( {
Name: 'grel',
Label: 'g<sub>rel</sub>',
Units: 'g<sub>o</sub>'
}
).AddTextField( {
Name: 'dw',
Label: 'W<sub>h</sub>-W<sub>cal</sub>',
Units: 'units'
}
).AddTextField( {
Name: 'w0',
Label: 'W<sub>o</sub>',
Units: 'units'
}
).AddTextField( {
Name: 'wh',
Label: 'W<sub>h</sub>',
Units: 'units'
}
).AddTextField( {
Name: 'g0cal',
Label: 'g<sub>o,cal</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'dg',
Label: 'g<sub>h</sub>-g<sub>o</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'g0',
Label: 'g<sub>o</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'gh',
Label: 'g<sub>h</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'g0G',
Label: 'g<sub>oG</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'ghG',
Label: 'g<sub>hG</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'a0Z',
Label: 'a<sub>oZ</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'ahZ',
Label: 'a<sub>hZ</sub>',
Units: 'm/s<sup>2</sup>'
}
).AddTextField( {
Name: 'R',
Label: 'R',
Units: 'km',
Mult: 1000
}
).AddTextField( {
Name: 'rhoh',
Label: 'ρ<sub>h</sub>',
Units: 'km',
Mult: 1000
}
).AddTextField( {
Name: 'rho1',
Label: 'ρ<sub>1</sub>',
Units: 'km',
Mult: 1000
}
).AddTextField( {
Name: 'rho2',
Label: 'ρ<sub>2</sub>',
Units: 'km',
Mult: 1000
}
).AddTextField( {
Name: 'vEq',
Label: 'v<sub>eq</sub>',
UnitsRef: 'SpeedUnit',
MultRef: 'SpeedMult'
}
).AddTextField( {
Name: 'v',
Label: 'v',
UnitsRef: 'SpeedUnit',
MultRef: 'SpeedMult'
}
).AddTextField( {
Name: 'vRot',
Label: 'v<sub>rot</sub>',
UnitsRef: 'SpeedUnit',
MultRef: 'SpeedMult'
}
).Render();
ControlPanels.NewPanel( {
Name: 'UnitsPanel',
ModelRef: 'Model',
OnModelChange: UpdateAll,
NCols: 2
}
).AddHeader( {
Text: 'Units',
ColSpan: 4
}
).AddRadiobuttonField( {
Name: 'SpeedUnitIx',
ValueType: 'int',
Label: 'Speed',
NCols: 4,
Items: [
{ Name: 'm/s', Value: '0' },
{ Name: 'km/h', Value: '1' },
{ Name: 'kt', Value: '2' },
{ Name: 'mph', Value: '3' }
]
}
).AddRadiobuttonField( {
Name: 'AltUnitIx',
ValueType: 'int',
Label: 'Alt',
NCols: 3,
Items: [
{ Name: 'm', Value: '0' },
{ Name: 'ft', Value: '1' },
{ Name: 'FL', Value: '2' }
]
}
).Render();
xOnLoad( UpdateAll );