-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Still not completely happy with it, but don't want to hold it off
any longer. Wind layer configuration is at the top. You can add
as many as you want, but remember to add them in order from low
to high.

Usage:  nc -vve wind <host> <port>

===[ wind ]==================================================================
#!/bin/sh

exec awk -W interactive '
function initwinds(wN, wE, wU)
{
        toplayer = 0

        # wind layer configuration
        setwind(    0, "foot", 23, "knot", 260, "degree", 0, "foot/minute")
        setwind( 1000, "foot", 40, "knot", 270, "degree", 0, "foot/minute")
        setwind( 2000, "foot", 110, "knot", 280, "degree", 0, "foot/minute")
        setwind( 4000, "foot", 110, "knot", 350, "degree", 0, "foot/minute")
        setwind(10000, "foot", 40, "knot", 050, "degree", 0, "foot/minute")

        if (toplayer <= 0) {
                WIND[0, "altitude"] = 0
                WIND[0, "up"] = wU
                WIND[0, "north"] = wN
                WIND[0, "east"] = wE
                toplayer = 1
        }

        toplayer--
}

function abs(n)
{
        if (n < 0) return -n
        return n
}

function sgn(n)
{
        if (n < 0) return -1
        if (n > 0) return 1
        return 0
}

function msg(m)
{
        print m > "/dev/stderr"
}

function fail(m)
{
        msg(m)
        exitcode = 1
        exit exitcode
}

function datamode()
{
        msg("entering data mode")
        print "data"
        msg("data mode entered")
}

function getproperty(p          , ret)
{
        msg("req: " p)
        print "get " p
        status = getline ret
        msg("result: " ret)

        return ret
}

function setproperty(p, v               , dummy)
{
        msg("set: " p " = " v)
        print "set " p " " v
        status = getline dummy
}

function parse_unit2(u, TOP, BOT                , a, b, s, tobot)
{
        tobot = 0

        while (u != "") {
                a = index(u, "/")
                b = index(u, ".")
                if (a && (b <= 0 || a < b)) {
                        s = substr(u, 1, a - 1)
                        while(s in UNITRANS) s = UNITRANS[s]

                        if (tobot) BOT[s]++
                        else TOP[s]++
                        u = substr(u, a + 1)
                        tobot = 1
                }
                else if (b && (a <= 0 || b < a)) {
                        s = substr(u, 1, b - 1)
                        while(s in UNITRANS) s = UNITRANS[s]

                        if (tobot) BOT[s]++
                        else TOP[s]++
                        u = substr(u, b + 1)
                }
                else {
                        while(u in UNITRANS) u = UNITRANS[u]

                        if (tobot) BOT[u]++
                        else TOP[u]++
                        u = ""
                }
        }
}

function parse_unit(u, TOP, BOT)
{
        delete TOP
        delete BOT

        TOP[""] = 0
        BOT[""] = 0

        parse_unit2(u, TOP, BOT)

        mod = 1
        while(mod) {
                mod = 0

                for (s in TOP) if (TOP[s] > 0 && match(s, "[\./]")) {
                        mod = 1
                        parse_unit2(s, TOP, BOT)
                        TOP[s]--
                }

                for (s in BOT) if (BOT[s] > 0 && match(s, "[\./]")) {
                        mod = 1
                        parse_unit2(s, BOT, TOP)
                        BOT[s]--
                }
        }

        for (s in TOP) {
                while (s in BOT && TOP[s] > 0 && BOT[s] > 0) {
                        TOP[s]--
                        BOT[s]--
                }
        }
}

function unitconvert3(v, from, to)
{
        if (from == to) return v
        else if ( (from, to) in UNICONV)
                return (v + UNICONV[from, to, "offset"]) * UNICONV[from, to]
        else if ( (to, from) in UNICONV)
                return v / UNICONV[to, from] + UNICONV[to, from, "offset"]

        return "err"
}

function unitconvert4(v, d, FROM, TO)
{
        for (s in FROM) if (FROM[s] > 0) {
                w = ""

                for (t in TO) if (TO[t] > 0) {
                        if (d) w = unitconvert3(v, t, s)
                        else w = unitconvert3(v, s, t)
                        if (w != "err") {
                                FROM[s]--
                                TO[t]--
                                v = w
                                break
                        }
                }

                if (w == "err") {
                        msg("Unable to convert:")
                        for (s in FROM) msg(s ": " FROM[s])
                        msg("to")
                        for (s in TO) msg(s ": " TO[s])
                        fail("!")
                }
        }

        return v
}

function unitconvert2(v, from, to)
{
        FTOP[""] = 0
        FBOT[""] = 0
        TTOP[""] = 0
        TBOT[""] = 0

        parse_unit(from, FTOP, FBOT)
        parse_unit(to, TTOP, TBOT)
        v = unitconvert4(v, 0, FTOP, TTOP)
        v = unitconvert4(v, 1, FBOT, TBOT)

        return v
}

function unitconvert(v, from, to                , tmp)
{
        msg("converting: " v " (" from " -> " to ")")
        tmp = unitconvert2(v, from, to)
        msg("converted: " v " " from " = " tmp " " to)
        return tmp
}

function initunits()
{
        # unit conversion table
        UNICONV["foot",         "meter"]        = 0.304801
        UNICONV["seamile",      "kilometer"]    = 1.85
        UNICONV["seamile",      "foot"]         = 6080
        UNICONV["landmile",     "kilometer"]    = 1.61
        UNICONV["radian",       "degree"]       = 180 / PI
        UNICONV["hour",         "minute"]       = 60
        UNICONV["minute",       "second"]       = 60
        UNICONV["hour",         "second"]       = 3600
        UNICONV["Fahrenheit",   "Celcius"]      = 5/9
        UNICONV["Fahrenheit",   "Celcius", "offset"] = -32
        UNICONV["gallon",       "liter"]        = 3.78543

        # synonyms and shorthands
        UNITRANS["statute mile"] = "landmile"
        UNITRANS["nautical mile"] = "seamile"
        UNITRANS["knot"] = "seamile/hour"
}

function setwind(alt, alt_u, spd, spd_u, dir, dir_u, upd, upd_u         , wn, we, wu)
{
        alt = unitconvert(alt, alt_u, altitude_units)
        spd = unitconvert(spd, spd_u, wind_units)

        dir = unitconvert(dir, dir_u, "radian") - PI

        wn = spd * cos(dir)
        we = spd * sin(dir)
        wu = unitconvert(upd, upd_u, wind_units)

        msg("wn: " wn)
        msg("we: " we)
        msg("wu: " wu)

        WIND[toplayer, "altitude"] = alt
        WIND[toplayer, "up"] = wu
        WIND[toplayer, "north"] = wn
        WIND[toplayer, "east"] = we

        toplayer++
}

BEGIN {
        # config parameters
        dspd = 1                # maximum amount of time increase (sec/iteration)
        diff_limit = 0.2        # wind change rate limit for delay increase 
(fps/iteration)
        min_delay = 0           # minimum iteration delay (sec)
        max_delay = 3           # maximum iteration delay (sec)
        smooth = 1              # maximum difference per change (fps)
        min_change = 0.05       # change threshold before sending new value

        # properties
        wind_north_prop = "/environment/wind-north-fps"
        wind_east_prop = "/environment/wind-east-fps"
        wind_up_prop = "/environment/wind-down-fps"
        altitude_msl_prop = "/position/altitude-ft"
        altitude_agl_prop = "/position/altitude-agl-ft"

        # target units
        wind_units = "foot/second"
        altitude_units = "foot"

        # constants
        PI = 3.14159265358979323846

        initunits()
        datamode()

        prev_wind_up = -getproperty(wind_up_prop)
        prev_wind_north = getproperty(wind_north_prop)
        prev_wind_east = getproperty(wind_east_prop)

        initwinds(prev_wind_north, prev_wind_east, prev_wind_up)

        delay = 1

        while(status >= 0) {
                if (delay > max_delay) delay = max_delay
                if (delay < min_delay) delay = min_delay
                if (delay < 0) delay = 0

                msg("delay: " delay)
                system("sleep " int(delay))

                alt = getproperty(altitude_msl_prop)

                while (wl >= 0 && alt < WIND[wl, "altitude"]) wl--
                while (wl < toplayer && alt >= WIND[wl + 1, "altitude"]) wl++

                msg("layer: " wl)

                if (wl < 0) {
                        wind_north = WIND[0, "north"]
                        wind_east = WIND[0, "east"]
                        wind_up = WIND[0, "up"]
                }
                else if (wl >= toplayer) {
                        wind_north = WIND[toplayer, "north"]
                        wind_east = WIND[toplayer, "east"]
                        wind_up = WIND[toplayer, "up"]
                }
                else {
                        c1 = (WIND[wl + 1, "altitude"] - alt) \
                                / (WIND[wl + 1, "altitude"] - WIND[wl, "altitude"])

                        c2 = (alt - WIND[wl, "altitude"]) \
                                / (WIND[wl + 1, "altitude"] - WIND[wl, "altitude"])

                        wind_north = WIND[wl, "north"] * c1 + WIND[wl + 1, "north"] * 
c2
                        wind_east = WIND[wl, "east"] * c1 + WIND[wl + 1, "east"] * c2
                        wind_up = WIND[wl, "up"] * c1 + WIND[wl + 1, "up"] * c2

                        msg("floor: " WIND[wl, "altitude"])
                        msg("ceil: " WIND[wl + 1, "altitude"])
                        msg("c1: " c1)
                        msg("c2: " c2)
                }

                dN = prev_wind_north - wind_north
                dE = prev_wind_east - wind_east
                dU = prev_wind_up - wind_up

                delay = delay + dspd \
                        - dspd * (diff_limit + abs(dN)) / diff_limit / 6 \
                        - dspd * (diff_limit + abs(dE)) / diff_limit / 6 \
                        - dspd * (diff_limit + abs(dU)) / diff_limit / 6

                while (abs(prev_wind_north - wind_north) > min_change) {
                        if (abs(prev_wind_north - wind_north) > smooth)
                                prev_wind_north += sgn(wind_north - prev_wind_north) * 
smooth
                        else
                                prev_wind_north = wind_north

                        setproperty(wind_north_prop, prev_wind_north)
                }

                while (abs(prev_wind_east - wind_east) > min_change) {
                        if (abs(prev_wind_east - wind_east) > smooth)
                                prev_wind_east += sgn(wind_east - prev_wind_east) * 
smooth
                        else
                                prev_wind_east = wind_east

                        setproperty(wind_east_prop, prev_wind_east)
                }

                while (abs(prev_wind_up - wind_up) > min_change) {
                        if (abs(prev_wind_up - wind_up) > smooth)
                                prev_wind_up += sgn(wind_up - prev_wind_up) * smooth
                        else
                                prev_wind_up = wind_up

                        setproperty(wind_up_prop, -prev_wind_up)
                }
        }
}

#END {
#       if (exitcode) exit exitcode
#       # other code
#}
' 2> /dev/tty
=============================================================================


- --
Regards,          "I RADIS, do you?"
=Martin=        http://www.iradis.org/

PGP:  FE87448B  DDF8 677C 9244 D119 4FE0  AE3A 37CF 3458 FE87 448B


From: Martin van Beilen <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: Layered wind.
X-S-Issue: [EMAIL PROTECTED] 2002/02/19 01:23:53 
55a7fe351251fb8e34a1a827e23278c0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)

iEYEARECAAYFAjxxmykACgkQN880WP6HRIu2kgCdE7qEBrrMqZ+CcfxVi8VqLpiy
1G4An2Ru0yMCV/RB/pesvs3dwvfwO+MC
=R0q4
-----END PGP SIGNATURE-----

_______________________________________________
Flightgear-devel mailing list
[EMAIL PROTECTED]
http://mail.flightgear.org/mailman/listinfo/flightgear-devel

Reply via email to