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

m
→‎/Nasal/fbw.nas: move elevator processing to separate method
m (→‎/Nasal/fbw.nas: use a vector of throttles instead)
m (→‎/Nasal/fbw.nas: move elevator processing to separate method)
Line 110: Line 110:
## Fix Damp Rate according to Framerate
## Fix Damp Rate according to Framerate


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


## Bank Limit Setting
## Bank Limit Setting
Line 134: Line 134:


var aileronin = getprop(fcs~"aileron-cmd-norm");
var aileronin = getprop(fcs~"aileron-cmd-norm");
var elevatorin =  getprop(fcs~"elevator-cmd-norm");
me.elevatorin =  getprop(fcs~"elevator-cmd-norm");
var rudderin = getprop(fcs~"rudder-cmd-norm");
var rudderin = getprop(fcs~"rudder-cmd-norm");


Line 140: Line 140:


var aileronout = getprop(fcs~"aileron-fbw-output");
var aileronout = getprop(fcs~"aileron-fbw-output");
var elevatorout =  getprop(fcs~"elevator-fbw-output");
me.elevatorout =  getprop(fcs~"elevator-fbw-output");
var rudderout = getprop(fcs~"rudder-fbw-output");
var rudderout = getprop(fcs~"rudder-fbw-output");


Line 185: Line 185:
if (((roll <= banklimit) and (roll >= -banklimit)) or (rolldir != ailerondir)) {
if (((roll <= banklimit) and (roll >= -banklimit)) or (rolldir != ailerondir)) {


if (aileronin > aileronout) aileronout += 0.05 * fpsfix;
if (aileronin > aileronout) aileronout += 0.05 * me.fpsfix;


if (aileronin < aileronout) aileronout -= 0.05 * fpsfix;
if (aileronin < aileronout) aileronout -= 0.05 * me.fpsfix;


} else {
} else {
Line 196: Line 196:
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 * me.fpsfix;
if (aileronout > me.targetaileron) aileronout -= 0.025 * fpsfix;
if (aileronout > me.targetaileron) aileronout -= 0.025 * me.fpsfix;


}
}


## ELEVATOR CONTROLS
me.update_elevator();
 
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;  


## AUTO-STABILIZATION
## AUTO-STABILIZATION
Line 213: Line 207:
### Get the aircraft to maintain pitch and roll when stick is at the center
### Get the aircraft to maintain pitch and roll when stick is at the center


if ((elevatorin <= 0.1) and (elevatorin >= -0.1) and (aileronin <= 0.1) and (aileronin >= -0.1)) {
if ((me.elevatorin <= 0.1) and (me.elevatorin >= -0.1) and (aileronin <= 0.1) and (aileronin >= -0.1)) {


if (me.stabilize == 0) {
if (me.stabilize == 0) {
Line 253: Line 247:


if (me.targetthrottle > throttles[0]) {
if (me.targetthrottle > throttles[0]) {
throttles[0] += 0.001 * fpsfix;
throttles[0] += 0.001 * me.fpsfix;
throttles[1] += 0.001 * fpsfix;
throttles[1] += 0.001 * me.fpsfix;
} elsif (me.targetthrottle < throttles[0]) {
} elsif (me.targetthrottle < throttles[0]) {
throttles[0] -= 0.001 * fpsfix;
throttles[0] -= 0.001 * me.fpsfix;
throttles[1] -= 0.001 * fpsfix;
throttles[1] -= 0.001 * me.fpsfix;
}  
}  


Line 265: Line 259:


if (throttles[0] <= me.throttleinit - 0.05) {
if (throttles[0] <= me.throttleinit - 0.05) {
throttles[0] += 0.001 * fpsfix;
throttles[0] += 0.001 * me.fpsfix;
throttles[1] += 0.001 * fpsfix;
throttles[1] += 0.001 * me.fpsfix;
} elsif (throttles[0] > me.throttleinit + 0.05) {
} elsif (throttles[0] > me.throttleinit + 0.05) {
throttles[0] -= 0.001 * fpsfix;
throttles[0] -= 0.001 * me.fpsfix;
throttles[1] -= 0.001 * fpsfix;
throttles[1] -= 0.001 * me.fpsfix;
} else me.turnthrottlefix = 0;
} else me.turnthrottlefix = 0;
}
}
Line 276: Line 270:


if ((airspeedkt >= 250) and (altitudemsl <= 10000) and (throttles[0] != 0) and (throttles[1] != 0)) {
if ((airspeedkt >= 250) and (altitudemsl <= 10000) and (throttles[0] != 0) and (throttles[1] != 0)) {
throttles[0] -= 0.001 * fpsfix;
throttles[0] -= 0.001 * me.fpsfix;
throttles[1] -= 0.001 * fpsfix;
throttles[1] -= 0.001 * me.fpsfix;
me.throttlefix = 1;
me.throttlefix = 1;
}
}


if ((me.throttlefix == 1) and (airspeedkt < 245) and (altitudemsl <= 10000) and (throttles[0] != 1) and (throttles[1] != 1)) {
if ((me.throttlefix == 1) and (airspeedkt < 245) and (altitudemsl <= 10000) and (throttles[0] != 1) and (throttles[1] != 1)) {
throttles[0] += 0.001 * fpsfix;
throttles[0] += 0.001 * me.fpsfix;
throttles[1] += 0.001 * fpsfix;
throttles[1] += 0.001 * me.fpsfix;
}
}


Line 289: Line 283:


if ((airspeedkt >= 350) and (altitudemsl > 10000) and (throttles[0] != 0) and (throttles[1] != 0)) {
if ((airspeedkt >= 350) and (altitudemsl > 10000) and (throttles[0] != 0) and (throttles[1] != 0)) {
throttles[0] -= 0.001 * fpsfix;
throttles[0] -= 0.001 * me.fpsfix;
throttles[1] -= 0.001 * fpsfix;
throttles[1] -= 0.001 * me.fpsfix;
me.throttlefix = 1;
me.throttlefix = 1;
}
}


if ((me.throttlefix == 1) and (airspeedkt < 340) and (altitudemsl > 10000) and (throttles[0] != 1) and (throttles[1] != 1)) {
if ((me.throttlefix == 1) and (airspeedkt < 340) and (altitudemsl > 10000) and (throttles[0] != 1) and (throttles[1] != 1)) {
throttles[0] += 0.001 * fpsfix;
throttles[0] += 0.001 * me.fpsfix;
throttles[1] += 0.001 * fpsfix;
throttles[1] += 0.001 * me.fpsfix;
}
}


Line 302: Line 296:


if ((airspeedkt < 125) and (altitudeagl > 250) and (throttles[0] != 1) and (throttles[1] != 1)) {
if ((airspeedkt < 125) and (altitudeagl > 250) and (throttles[0] != 1) and (throttles[1] != 1)) {
throttles[0] += 0.001 * fpsfix;
throttles[0] += 0.001 * me.fpsfix;
throttles[1] += 0.001 * fpsfix;
throttles[1] += 0.001 * me.fpsfix;


### Also help by pushing forward on the stick
### Also help by pushing forward on the stick


elevatorout += 0.02;
me.elevatorout += 0.02;


}
}
Line 327: Line 321:
if (getprop("/controls/fbw/yaw-damper")) {
if (getprop("/controls/fbw/yaw-damper")) {


if (rudderin > rudderout) rudderout += 0.05 * fpsfix;
if (rudderin > rudderout) rudderout += 0.05 * me.fpsfix;


if (rudderin < rudderout) rudderout -= 0.05 * fpsfix;
if (rudderin < rudderout) rudderout -= 0.05 * me.fpsfix;


} else {
} else {
Line 340: Line 334:


setprop(fcs~"aileron-fbw-output", aileronout);
setprop(fcs~"aileron-fbw-output", aileronout);
setprop(fcs~"elevator-fbw-output", elevatorout);
setprop(fcs~"elevator-fbw-output", me.elevatorout);
setprop(fcs~"rudder-fbw-output", rudderout);
setprop(fcs~"rudder-fbw-output", rudderout);


Line 353: Line 347:


setprop(fcs~"aileron-fbw-output", aileronin);
setprop(fcs~"aileron-fbw-output", aileronin);
setprop(fcs~"elevator-fbw-output", elevatorin);
setprop(fcs~"elevator-fbw-output", me.elevatorin);
setprop(fcs~"rudder-fbw-output", rudderin);
setprop(fcs~"rudder-fbw-output", rudderin);


}
}


},
    update_elevator: func {
    ## ELEVATOR CONTROLS
    if (me.elevatorin > me.elevatorout) me.elevatorout += 0.05 * me.fpsfix;
    if (me.elevatorin < me.elevatorout) me.elevatorout -= 0.05 * me.fpsfix;
    if ((me.elevatorin - me.elevatorout < 0.05) and (me.elevatorin - me.elevatorout > 0)) me.elevatorout += 0.01;
    if ((me.elevatorout - me.elevatorin < 0.05) and (me.elevatorin - me.elevatorout < 0)) me.elevatorout -= 0.01;
},
},
     reset : func {
     reset : func {