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

Hello list,

I've been playing around with the telnet interface a bit, and
have made a little trim-aid for us poor keyboard-users. More of
that below.

I also discovered some minor issues with fgfs:

 * It is not possible to have more then 1 active telnet
   connection at a time.

 * LaRCSim behaves very badly when setting wind values. It will
   pitch badly even when setting exactly the same value!

 * JSBSim's sense of /environment/wind-down-fps is inverted.
   (Personally I think it would be more intuitive to define
   vertical winds in the same direction as altitude. That is,
   positive is up. But if it has been chosen down, it should be
   down, not up.)


Now on to the script. It is good to have a high degree of
realism, but it would be nice if you could let go of the keyboard
for a few seconds to take a sip of coffee, for example. :)

It is possible to let the script run permanently, in which case
it will keep the aircraft going perfectly straight without
interaction. For added realism, you could start the script in
level flight and disconnect it when it has stabilized.
Experimenting tip: wait until the delay goes over 10 seconds,
disconnect, and see how long it takes for the plane to roll over
to one side.

Unfortunately the script won't work very well with JSBSim.
JSBSim's aileron trim is so insensitive that it can't even
compensate for one notch of rudder. (IANAP, so I don't know how
realistic that is.) YASim's aileron trim seems to behave like a
secondary aileron control wrt to sensitivity. The script works
fine with LaRCSim too, although it isn't really needed with
LaRCSim.


Usage:

nc -vve ./autotrim <host> <port>

(That is NetCat, compiled with GAPING_SECURITY_HOLE defined.
http://freshmeat.net/projects/netcat/ )


Activating the telnet interface on fgfs:

fgfs --props=socket,bi,5,<host>,<port>,tcp


And finally, here it is:

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

exec awk -W interactive '
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
}

BEGIN {
        # user parameters
        req_roll = 0            # requested roll (deg)
        clim = 2                # control limit w/ aileron deflection (deg)
        lim = 3                 # control limit w/ zero aileron (deg)
        min_delay = 0           # minimum iteration delay (sec)
        max_delay = 30          # maximum iteration delay (sec)
        damping = 10            # amount of roll damping (differentiator) effect
        center_pull = 10        # amount of center pull
        center_int = 1          # amount of deflection-off-center integration
        ailcenter = 1           # rate of aileron-to-trim transfer
        rr_limit = 0.002        # roll rate limit for delay increase (deg/iteration)
        dspd = 1                # maximum amount of time increase (sec/iteration)
        k = 1                   # output amplification

        roll_prop = "/orientation/roll-deg"
        ail_prop = "/controls/aileron"
        output_prop = "/controls/aileron-trim"

        datamode()
        control = getproperty(output_prop) / k
        delay = 1 #sec

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

                msg("delay: " delay)

                if (delay >= 1) system("sleep " int(delay))
                last_roll = roll
                roll = getproperty(roll_prop) - req_roll
                if (status <= 0) fail("Connection lost.")

                if (roll > -lim && roll < lim) {
                        ail = getproperty(ail_prop)
                        if (status <= 0) fail("Connection lost.")
                        if (ail > -0.01 && ail < 0.01) {
                                if (manual) {
                                        manual = 0
                                        last_roll = roll
                                }

                                dr = last_roll - roll
                                delay = delay + dspd - dspd * 0.5 * (rr_limit + 
abs(dr)) / rr_limit
                                msg("factor: " 0.5 * (rr_limit + abs(dr)) / rr_limit)
                                msg("delay: " delay)
                                control += dr * damping / 1000
                                tmp_trim = roll / 10000
                                control -= tmp_trim * center_int / 2
                                msg("int: " dr * damping / 100)
                                msg("ctr: " tmp_trim)
                                setproperty(output_prop, (control - tmp_trim * 
center_pull) * k)
                        }
                        else if ( roll > -clim && roll < clim) {
                                if (delay > 2) delay--
                                msg("ail: " ail * ailcenter / 100)
                                control += ail / 10
                                setproperty(output_prop, control * k)
                                manual = 1
                        }
                        else {
                                manual = 1
                        }
                }
                else {
                        manual = 1
                }
        }
}

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

=============================================================================

Final notes:

It was tested with mawk 1.3.3 under Linux. If you get it to work
with gawk (should be compatible but the interactive unbuffered
mode might be a problem) please post the required changes.

Although I wrote it as a trim aid, with some tweaking of values
it seems to perform surprisingly well as an external autopilot.
Anyway, have fun playing with it!


- --
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: Aileron trim aid.
X-S-Issue: [EMAIL PROTECTED] 2002/02/16 00:19:18 
582dcc583820882fe069c53a8f871bb9
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)

iEYEARECAAYFAjxtl34ACgkQN880WP6HRItDywCfdCWnDKFPsA4OudR/1gz0xyFC
MdAAnA8u5Eqq+sQg0AsdyxGaSksOHzrA
=q06E
-----END PGP SIGNATURE-----

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

Reply via email to