Howto:Implement a Fly-By-Wire System for Airliners
This article is a stub. You can help the wiki by expanding it. |
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 Fly-By-Wire system was developed for the Boeing 787-8, but can be used for other aircraft too. As Boeing wanted to give pilots the upper hand, the fly-by-wire systems CAN be disabled and overridden by pilot inputs. If you would like to use this fly-by-wire script for an Airbus Aircraft, you might want to make a few changes to give the fly-by-wire more power.
The whole idea here is to get the pilot's control inputs through a nasal script, and creating custom output properties which are then read by the FDM. To implement this system, you'll need to work with the following files:
- -set.xml
- fbw.nas
- FDM xml file
Note that as the new 787 uses JSBSim, this tutorial will focus on implementing the FBW to an aircraft running with JSBSim.
B787-8 Fly-By-Wire
Another feature in the Boeing 787-8's Fly By Wire is the automatic control of the trailing edge camber which affects lift and drag. The fly-by-wire automatically adjusts that to get maximum efficiency. Redneck and I am working on that but it's not included in the below nasal code as I don't think any other aircraft has that. And ofcourse, it's not yet completed. The rest of the Fly-By-Wire is stable at the moment and has been tested on the new Boeing 787-8.
Functions
The Boeing 787-8 Fly-By-Wire system executes the following functions which help stabilize the aircraft:
- Accordingly adjusts thrust and elevators to maintain lift during turns
- Helps during turns with rudder movement
- Doesn't allow the plane to turn beyond the specified bank limit (customizable)
- Applies thrust and slightly moves the elevators down when closing in on stall speed
- Reduces thrust when exceeding 250 knots under 10000 ft MSL and when reaching Vne above 10000 ft MSL
- Dampens the controls to prevent sudden movements
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)
- Rudder Control (ALLOWED / DENIED)
- YAW DAMPER (ACTIVE / DISABLED)
- 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 FLIGHTGEAR ##
- Designed by Omega Pilot and Redneck ##
- 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
var fpsfix=1; if (getprop("/sim/frame-rate") != nil) fpsfix = 25 / getprop("/sim/frame-rate");
- 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; } # end of disconnect announce } # end of efis/agl check
}
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; }