Howto:Implement a Fly-By-Wire System for Airliners

From FlightGear wiki
Revision as of 09:52, 7 February 2012 by Omega1174 (talk | contribs)
Jump to navigation Jump to search
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">

    1. FLY BY WIRE SYSTEM FOR FLIGHTGEAR ##
    2. Designed by Omega Pilot and Redneck ##
  1. 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;

    1. 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);

    1. 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/";

    1. Fix Damp Rate according to Framerate

var fpsfix=1; if (getprop("/sim/frame-rate") != nil) fpsfix = 25 / getprop("/sim/frame-rate");

    1. Bank Limit Setting

var banklimit = getprop("/controls/fbw/bank-limit");

    1. 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");

    1. 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");

    1. 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");

    1. Engine Throttle Positions

throttle0 = getprop("controls/engines/engine[0]/throttle"); throttle1 = getprop("controls/engines/engine[1]/throttle");

    1. This is where the FBW actually does it's job ;)
      1. 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)
    1. 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;

    1. AILERON CONTROLS
      1. 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 {

      1. 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;

}

    1. 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;

      1. 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;

} }

    1. THROTTLE CONTROLS
      1. Disconnect Throttle fix if manually overridden

if (throttle0 != me.throttle) { me.throttlefix = 0; me.turnthrottlefix = 0; }


      1. 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; }