Howto:Implement a Fly-By-Wire System for Airliners: Difference between revisions

no edit summary
(Created page with "{{Stub}} Objective: Implement a Nasal based fly-by-wire system for Airliners with fly-by-wire and set configuration properties to get desired results. == Background == The...")
 
No edit summary
Line 23: Line 23:
* Reduces thrust when exceeding 250 knots under 10000 ft MSL and when reaching Vne above 10000 ft MSL
* Reduces thrust when exceeding 250 knots under 10000 ft MSL and when reaching Vne above 10000 ft MSL


The Fly-By-Wire Configs can be set/edit from the property tree. In the Boeing 787-8 (new one coming up soon), you can edit the following FBW Configurations from the FBW CONFIG menu in the CDU"
 
The Fly-By-Wire Configs can be set/edit from the property tree. In the Boeing 787-8 (new one coming up soon), you can edit the following FBW Configurations from the FBW CONFIG menu in the CDU:
* Fly-By-Wire Status (ACTIVE / DISABLED)
* Fly-By-Wire Status (ACTIVE / DISABLED)
* Rudder Control (ALLOWED / DENIED)
* Rudder Control (ALLOWED / DENIED)
* YAW DAMPER (ACTIVE / DISABLED)
* YAW DAMPER (ACTIVE / DISABLED)
* BANK LIMIT (CYCLE BETWEEN 15, 20, 25, 30, 35, 40)
* BANK LIMIT (CYCLE BETWEEN 15, 20, 25, 30, 35, 40)
== Implementation ==
=== /Nasal/fbw.nas ===
Open your aircraft's nasal directory and create a file called 'fbw.nas'. Copy and paste the following code in that file and save it.
<syntaxhighlight lang="php">
#########################################
## FLY BY WIRE SYSTEM FOR BOEING 787-8 ##
#########################################
## Designed by Omega Pilot and Redneck ##
#########################################
# Fly By Wire Functions
## Dampen Surface positions
## Set Bank and Pitch Limits
## Help in turns with rudder
## Apply power while turning
## Maintain vertical speed during turns
# CONSTANTS
var RAD2DEG = 57.2957795;
var DEG2RAD = 0.0174532925;
var fbw = {
init : func {
        me.UPDATE_INTERVAL = 0.001;
        me.loopid = 0;
me.throttle = 0;
me.throttlefix = 0;
me.vsinit = 0;
me.throttleinit = 0;
me.targetthrottle = 0;
me.turnthrottlefix = 0;
me.targetaileron = 0;
me.targetelevator = 0;
me.targetrudder = 0;
me.adjustelevators = 0;
me.disconnectannounce = 0;
## Initialize with FBW Activated
setprop("/controls/fbw/active", 1);
setprop("/controls/fbw/rudder", 1);
setprop("/controls/fbw/yaw-damper", 1);
setprop("/controls/fbw/bank-limit", 35);
## Initialize Control Surfaces
setprop("/fdm/jsbsim/fcs/aileron-fbw-output", 0);
setprop("/fdm/jsbsim/fcs/rudder-fbw-output", 0);
setprop("/fdm/jsbsim/fcs/elevator-fbw-output", 0);
        me.reset();
},
update : func {
var fcs = "/fdm/jsbsim/fcs/";
## Fix Damp Rate according to Framerate
if (getprop("/sim/frame-rate") != nil) var fpsfix = 25 / getprop("/sim/frame-rate");
else fpsfix = 1;
## Bank Limit Setting
var banklimit = getprop("/controls/fbw/bank-limit");
## Position and Orientation
var altitudeagl = getprop("/position/altitude-agl-ft");
var altitudemsl = getprop("/position/altitude-ft");
var pitch = getprop("/orientation/pitch-deg");
var roll = getprop("/orientation/roll-deg");
var airspeedkt = getprop("/velocities/airspeed-kt");
var vsfps = getprop("/velocities/vertical-speed-fps");
## Flight Control System Properties
var aileronin = getprop(fcs~"aileron-cmd-norm");
var elevatorin =  getprop(fcs~"elevator-cmd-norm");
var rudderin = getprop(fcs~"rudder-cmd-norm");
## FBW Output (actual surface positions)
var aileronout = getprop(fcs~"aileron-fbw-output");
var elevatorout =  getprop(fcs~"elevator-fbw-output");
var rudderout = getprop(fcs~"rudder-fbw-output");
## Engine Throttle Positions
throttle0 = getprop("controls/engines/engine[0]/throttle");
throttle1 = getprop("controls/engines/engine[1]/throttle");
## This is where the FBW actually does it's job ;)
### The Fly-by--wire only works when it is active. In the Boeing 787, pilots have the option to disable fly-by-wire and use power-by-wire* in case of emergencies. The Fly By Wire Configuration includes: On/Off, Bank Limit and Rudder Control. The FBW Configs can be set in the FBW CONFIG Page in the CDU(s)
## Turn on Fly By Wire only if we have power
if (getprop("/systems/electrical/outputs/efis") != nil) {
if ((getprop("/systems/electrical/outputs/efis") < 9) and (altitudeagl >= 200)) {
setprop("/controls/fbw/active", 0);
if (me.disconnectannounce == 0) {
screen.log.write("Fly By Wire Disconnected!", 1, 0, 0);
me.disconnectannounce = 1;
} } }
if (getprop("/controls/fbw/active")) {
me.disconnectannounce = 0;
## AILERON CONTROLS
### Set Aileron Direction and Roll Direction
if (roll < 0) var rolldir = -1;
if (roll > 0) var rolldir = 1;
if (roll == 0) var rolldir = 0;
if (aileronin < 0) var ailerondir = -1;
if (aileronin > 0) var ailerondir = 1;
if (aileronin == 0) var ailerondir = 0;
if (((roll <= banklimit) and (roll >= -banklimit)) or (rolldir != ailerondir)) {
if (aileronin > aileronout) aileronout += 0.05 * fpsfix;
if (aileronin < aileronout) aileronout -= 0.05 * fpsfix;
} else {
### Don't let the plane bank past the bank limit
if (roll < -banklimit) me.targetaileron = -(roll + banklimit) * 0.025;
if (roll > banklimit) me.targetaileron = -(roll - banklimit) * 0.025;
if (aileronout < me.targetaileron) aileronout += 0.025 * fpsfix;
if (aileronout > me.targetaileron) aileronout -= 0.025 * fpsfix;
}
## ELEVATOR CONTROLS
if (elevatorin > elevatorout) elevatorout += 0.05 * fpsfix;
if (elevatorin < elevatorout) elevatorout -= 0.05 * fpsfix;
if ((elevatorin - elevatorout < 0.05) and (elevatorin - elevatorout > 0)) elevatorout += 0.01;
if ((elevatorout - elevatorin < 0.05) and (elevatorin - elevatorout < 0)) elevatorout -= 0.01;
### Use elevator to stabilize VS on turns
if ((roll <= -5) or (roll >= 5)) {
if (me.adjustelevators == 0) {
me.adjustelevators = 1;
me.vsinit = vsfps;
}
if (vsfps < me.vsinit) elevatorout -= 0.02;
if (vsfps > me.vsinit) elevatorout += 0.02;
} else {
if (me.adjustelevators == 1) {
if (vsfps < me.vsinit) elevatorout -= 0.02;
elsif (vsfps > me.vsinit) elevatorout += 0.02;
else me.adjustelevators = 0;
}
}
## THROTTLE CONTROLS
### Disconnect Throttle fix if manually overridden
if (throttle0 != me.throttle) {
me.throttlefix = 0;
me.turnthrottlefix = 0;
}
### Adjust throttle while turning
if ((roll <= -5) or (roll >= 5)) {
if (me.turnthrottlefix == 0) {
me.throttleinit = throttle0;
me.turnthrottlefix = 1;
}
me.targetthrottle = me.throttleinit + (me.throttleinit * math.sin(math.abs(roll * DEG2RAD)))/2;
if (me.targetthrottle > throttle0) {
throttle0 += 0.001 * fpsfix;
throttle1 += 0.001 * fpsfix;
} elsif (me.targetthrottle < throttle0) {
throttle0 -= 0.001 * fpsfix;
throttle1 -= 0.001 * fpsfix;
}
}
if ((roll > -5) and (roll <= 5) and (me.turnthrottlefix == 1)) {
if (throttle0 <= me.throttleinit - 0.05) {
throttle0 += 0.001 * fpsfix;
throttle1 += 0.001 * fpsfix;
} elsif (throttle0 > me.throttleinit + 0.05) {
throttle0 -= 0.001 * fpsfix;
throttle1 -= 0.001 * fpsfix;
} else me.turnthrottlefix = 0;
}
### Reduce throttle if aircraft is faster than 250 KIAS under 10000 ft
if ((airspeedkt >= 250) and (altitudemsl <= 10000) and (throttle0 != 0) and (throttle1 != 0)) {
throttle0 -= 0.001 * fpsfix;
throttle1 -= 0.001 * fpsfix;
me.throttlefix = 1;
}
if ((me.throttlefix == 1) and (airspeedkt < 245) and (altitudemsl <= 10000) and (throttle0 != 1) and (throttle1 != 1)) {
throttle0 += 0.001 * fpsfix;
throttle1 += 0.001 * fpsfix;
}
### Adjust Throttle to stay under Vne
if ((airspeedkt >= 350) and (altitudemsl > 10000) and (throttle0 != 0) and (throttle1 != 0)) {
throttle0 -= 0.001 * fpsfix;
throttle1 -= 0.001 * fpsfix;
me.throttlefix = 1;
}
if ((me.throttlefix == 1) and (airspeedkt < 340) and (altitudemsl > 10000) and (throttle0 != 1) and (throttle1 != 1)) {
throttle0 += 0.001 * fpsfix;
throttle1 += 0.001 * fpsfix;
}
### Adjust Throttle to keep from stalling
if ((airspeedkt < 125) and (altitudeagl > 250) and (throttle0 != 1) and (throttle1 != 1)) {
throttle0 += 0.001 * fpsfix;
throttle1 += 0.001 * fpsfix;
### Also help by pushing forward on the stick
elevatorout += 0.02;
}
## RUDDER CONTROLS
if (getprop("/controls/fbw/rudder")) {
if ((roll < -5) or (roll > 5)) {
me.targetrudder = aileronout / 2;
if (me.targetrudder < rudderout) rudderout -= 0.015;
if (me.targetrudder > rudderout) rudderout += 0.015;
} }
## YAW DAMPER
if (getprop("/controls/fbw/yaw-damper")) {
if (rudderin > rudderout) rudderout += 0.05 * fpsfix;
if (rudderin < rudderout) rudderout -= 0.05 * fpsfix;
} else {
rudderout = rudderin;
}
# Transmit output signals to surfaces
setprop(fcs~"aileron-fbw-output", aileronout);
setprop(fcs~"elevator-fbw-output", elevatorout);
setprop(fcs~"rudder-fbw-output", rudderout);
setprop("controls/engines/engine[0]/throttle", throttle0);
setprop("controls/engines/engine[1]/throttle", throttle1);
me.throttle = throttle0; # This is to find out if the pilot moved the throttle
} else {
# Transmit input signals directly to surfaces
setprop(fcs~"aileron-fbw-output", aileronin);
setprop(fcs~"elevator-fbw-output", elevatorin);
setprop(fcs~"rudder-fbw-output", rudderin);
}
},
    reset : func {
        me.loopid += 1;
        me._loop_(me.loopid);
    },
    _loop_ : func(id) {
        id == me.loopid or return;
        me.update();
        settimer(func { me._loop_(id); }, me.UPDATE_INTERVAL);
    }
};
fbw.init();
print("Fly-By-Wire ......... Initialized");
# *Power-by-wire : corresponds to power steering in cars
</syntaxhighlight>
449

edits