Take to the skies! Take the skies... recursively.

If the game has been too much fun for you...

I kid. I'll finish it someday. Probably.

In the meantime, I've been taking an Introduction to Aeronautical Engineering course on edx.org. It's a great course (and free) from Delft Technical University. If you are interested in Aerospace, start there. It'll help you determine if you like math enough...

It turns out: I do like math.

So much so, that I programmed this International Standard Atmosphere Calculator. Using the 1976 international standard (which apparently hasn't changed since) you can plug in your geopotential altitude and get the air density and pressure. Very handy if you want check your flight altitude to make sure you won't collide with any other airplanes. Or if you need to do your Aerospace homework.

I added a nice graph, so you can just click the altitude rather than typing it. I hope to add unit conversions and also altitude prediction based on pressure or air density. One thing at a time.

Programming this little job also gave me a good excuse to use a recursive function.

Re...CURSES!

If you have ever taken a programming course, you've been taught about recursion. And then promptly forgotten it thinking, "that's too confusing! I'll just do it a different way..."

And you can solve most problems without ever using recursion. So why bother right?

Because it is so much TIDIER!

In the case of ISA, we have a piece-wise function that stacks on more function pieces as we progress to higher altitudes. Lapse rates change and we glide through isothermal layers... nevermind. Back to recursion!

Without getting too into depth on ISA calculations, let's just say this:
If we want to calculate the air density for an altitude of 40 kilometers, we need to first calculate it for 11 using one equation, then up to 20 with another, then up to 32; all based on the calculations made for lower layers.
If we want to calculate at higher altitudes, we need even MORE equations dependent on all those below.

So how does recursion help?

Recursion allows us to call one function for any altitude, that calls itself for the lower calculations. Then it spits out just the answer we need.

Without recursion, we'd have to write separate if.. then... statements for each case (retyping a lot of the same code). OR (as some ISA calculators do) we could cheat and store the key values for each layer in an array. But what's the fun in that?

Here's the commented code:

//this function takes two parameters:
//alt is altitude in meters
//To is temperature offset in Kelvin
function getAtmosphere(alt,To) {
    // constants!
    var R = 287.058; //gas constant
    var TEMP = 288.15; //in Kelvin
    var ATM1 = 101325; //in Pascals
    var DENSITY = 1.225; //in kg/cubic meter

    // range check (altitude in meters)
    if (alt > 84852) alt = 84852;
    if (alt < 0) alt = 0;

    //this is our OUT. no infinite recursion!
    //it returns 1 standard atmosphere at sea level in an object
    if (alt === 0) { //sea level
        return {"alt":alt,"T":TEMP+To,"To":To,"p":ATM1,"rho":DENSITY};
    } 

    // THIS IS WHERE THE MAGIC HAPPENS!
    // the function calls ITSELF...
    var atm0 = getAtmosphere(getAltRange(alt),To);
    // getAltRange() is a simple function that returns the altitude for
    // the "layer" beneath. This is used to find the correct lapse rate
    // and equation below...

    // lapseRate() returns the rate used to calculate temp for a given layer
    // here is where the calculation is done.
    // notice it uses output from itself (atm0)
    if (lapseRate(alt) != 0) {
        var T1 = atm0.T + lapseRate(alt)*(alt-getAltRange(alt));
        var rho1 = atm0.rho*Math.pow(T1/atm0.T,(-9.80665/(lapseRate(alt)*R)-1));
        var p1 = atm0.p*Math.pow(T1/atm0.T,-9.80665/(lapseRate(alt)*R)); 
    } else { // lapseRate = 0
        var con = Math.pow(Math.E,-9.80665/(R*atm0.T)*(alt-getAltRange(alt)));
        var T1 = atm0.T
        var p1 = atm0.p * con;
        var rho1 = atm0.rho * con;
    }

    // calculations "complete" it returns the data as an object
    return {"alt":alt,"T":T1,"To":To,"p":p1,"rho":rho1};
}
So wait? How can a function call itself and then use its own output to calculate. If it doesn't have the input... how can it give output... wouldn't it fail or return 'undefined'??

Well, no. Let's look at an example:

Let's say we call getAtmosphere(25000).

The function needs input from getAtmosphere(20000), so it calls that and waits...

THAT call needs input from getAtmosphere(11000), so it calls that and waits...

THAT call needs input from getAtmosphere(0), so it calls it and... WAIT! That's the out!

Once it calls that, it gets data returned! This is the KEY to recursion. It hits an end, now it can finish!

Then, getAtmosphere(11000) takes the input from (0) and runs the calculation. It passes that to (20000) which calculates and passes to (25000). And like magic, we get our data.

And no matter what altitude we call it on, it knows just how many times to call itself to get the right answer! Brilliant!

I think I've waited 15 years to have a need for recursion. And I'm proud to say I only froze my browser once...

Don't forget the OUT!

EDIT:

I have updated the calculator to properly return the density when there is a temperature offset. You can now change units and get the temperature up to 1000 km. A few other minor adjustments for accuracy too. Coming soon: density and pressure over 86 km!

Also, feel free to fork on GitHub!

Trevor Gast

Some say he’s half man half fish, others say he’s more of a seventy/thirty split. Either way he’s a fishy bastard.

0 comments: