About the mCDU, I was planning to make a whole new separate Airbus mCDU. I found a pretty good CDU simulator and I'll make this CDU like that.

But first, let me finish the cockpit.

omega95 wrote in Sun Apr 08, 2012 4:31 pm:Hydraulics are fluids in the aircraft which control the surfaces. Pumps move the fluid around and then that moves the surfaces.
polly wrote in Mon Apr 09, 2012 11:30 am:Flight Mode:
G - Load Factor only above 210kt
below 210kt: Pitch Rate
polly wrote in Mon Apr 09, 2012 11:30 am:Pitch Trim is active: the horizontal stabilizer moves to cancel elevator deflection over about 30secs time constant
# CONSTANTS
var RAD2DEG = 57.2957795;
var DEG2RAD = 0.0174532925;
var G_force = 9.80665;
var KT2MS = 0.514444444;
var fbw = {
init : func{
me.mode = 'Ground';
me.law = 'Direct';
me.engaged = 1;
me.active_pitch = 0;
me.activee_bank = 0;
me.stable_pitch = 0;
me.stable_bank = 0;
#Throttles
me.throttle0 = 0;
me.throttle1 = 0;
## Initialize with FBW Activated
me.fcs_root = "/fdm/jsbsim/fcs/";
me.fbw_root = "/autopilot/fbw/";
## Create Vars and Propertyes
props.globals.initNode(me.fbw_root~"engaged", 1, 'BOOL'); # Electronic work
setprop(me.fbw_root~"law", 'Direct');
setprop(me.fbw_root~"mode", 'Ground');
props.globals.initNode(me.fbw_root~"stablemode", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"active_bank", 0, 'BOOL'); # it is operating
props.globals.initNode(me.fbw_root~"active_pitch", 0, 'BOOL'); # it is operating
props.globals.initNode(me.fbw_root~"stable_bank", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"stable_pitch", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"protections/overspeed", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"protections/alpha-prot", 0, 'BOOL'); # max on stick neutral
props.globals.initNode(me.fbw_root~"protections/alpha-floor", 0, 'BOOL'); # TOGA thrust
props.globals.initNode(me.fbw_root~"protections/alpha-max", 0, 'BOOL'); # FULL STICK deflect
props.globals.initNode(me.fbw_root~"protections/alpha-min", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"protections/stall", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"protections/bank", 0, 'BOOL');
props.globals.initNode(me.fbw_root~"protections/windshear", 0, 'BOOL');
#props.globals.initNode(me.fbw_root~"autotrim/elevator", 0, 'BOOL');
#props.globals.initNode(me.fbw_root~"autotrim/rudder", 0, 'BOOL');
#props.globals.initNode(me.fbw_root~"autotrim/ailerons", 0, 'BOOL');
#setprop("/controls/flight/aileron-filtered", '0');
#setprop("/controls/flight/elevator-filtered", '0');
# XML setting limits
setprop("/limits/fbw/max-bank-angle-soft", '33' );
setprop("/limits/fbw/max-bank-angle-hard", '67' );
setprop("/limits/fbw/max-roll-speed", '0.261799387'); # max 0.261799387 rad_sec, 15 deg_sec
setprop("/limits/fbw/alpha-prot", '19');
setprop("/limits/fbw/alpha-floor", '25');
setprop("/limits/fbw/alpha-max", '30');
setprop("/limits/fbw/alpha-min", '-15');
setprop("/autopilot/internal/target-roll-deg", '0');
setprop("/autopilot/internal/target-pitch-deg", '0');
# fcs
setprop(me.fcs_root~"elevator-fbw-output", 0);
setprop(me.fcs_root~"aileron-fbw-output", 0);
setprop(me.fcs_root~"rudder-fbw-output", 0);
# Enter in loop
me.UPDATE_INTERVAL = 0.01;
me.loopid = 0;
me.reset();
},
get_state : func{
# FBW State
me.engaged = getprop(me.fbw_root~"engaged");
me.law = getprop(me.fbw_root~"law");
## AP status
me.autopilot = getprop("/autopilot/settings/engaged");
## stablemode
me.stablemode = getprop(me.fbw_root~"stablemode");
## Alpha Protection Limits
me.alpha_prot = getprop("/limits/fbw/alpha-prot");
me.alpha_floor = getprop("/limits/fbw/alpha-floor");
me.alpha_max = getprop("/limits/fbw/alpha-max");
me.alpha_min = getprop("/limits/fbw/alpha-min");
me.max_roll = getprop("/limits/fbw/max-roll-speed");
## Bank Limit Setting
me.banklimit_soft = getprop("/limits/fbw/max-bank-angle-soft");
me.banklimit_hard = getprop("/limits/fbw/max-bank-angle-hard");
## Position and Orientation
me.altitudeagl = getprop("/position/altitude-agl-ft");
me.altitudemsl = getprop("/position/altitude-ft");
me.pitch = getprop("/orientation/pitch-deg");
me.roll = getprop("/orientation/roll-deg");
me.airspeedkt = getprop("/velocities/airspeed-kt");
me.groundspeedkt = getprop("/velocities/groundspeed-kt");
## Flight Control System Properties
#me.elevtrim = getprop("/controls/flight/elevator-trim");
#me.ailtrim = getprop("/controls/flight/aileron-trim");
#me.aileronin = getprop("/controls/flight/aileron-filtered");
#me.elevatorin = getprop("/controls/flight/elevator-filtered");
me.aileronin = getprop("/controls/flight/aileron");
me.elevatorin = getprop("/controls/flight/elevator");
#me.rudderin = getprop("/controls/flight/rudder");
# rudder need inverted cmd-norm is inverted already
me.rudderin = getprop(me.fcs_root~"rudder-cmd-norm");
## FBW Output (actual surface positions)
# me.aileronout = getprop(me.fcs_root~"aileron-fbw-output");
# me.elevatorout = getprop(me.fcs_root~"elevator-fbw-output");
# me.rudderout = getprop(me.fcs_root~"rudder-fbw-output");
## Engine Throttle Positions
me.throttle0 = getprop("controls/engines/engine[0]/throttle");
me.throttle1 = getprop("controls/engines/engine[1]/throttle");
},
Airbus_law : func {
# Flight mode
#
if (me.altitudeagl >= '100') {
me.mode = 'Flight';
} else {
if (getprop("/gear/gear/wow") and getprop("/gear/gear[1]/wow") and getprop("/gear/gear[2]/wow")) {
me.mode = 'Ground';
} else {
me.mode = 'Transition';
}
}
#LAWS
# Normal, Direct, Autopilot, AOA,
if (!me.autopilot) {
if (me.pitch <= me.alpha_min or me.pitch >= me.alpha_prot){
me.law = 'AOA';
} else {
if (me.mode == 'Ground' or me.mode == 'Transition') {
me.law = 'Direct';
} else {
me.law = 'Normal';
}
}
} else {
me.law = 'AP';
}
},
autostable : func {
## AUTO-STABILIZATION
### Get the aircraft to maintain pitch and roll when stick is at the center
### PID USED
#### PITCH ####
if ((me.elevatorin <= 0.01) and (me.elevatorin >= -0.01) ) { # if pitch joystick neutral
# if previous state was not neutral
if (me.stable_pitch == 0) {
# set PID target DEGREE
setprop(me.fbw_root~"stable_pitch_deg", me.pitch);
# set neutral state
me.stable_pitch = 1;
me.active_pitch = 0;
}
# activate PID
setprop(me.fbw_root~"stable_pitch", 1);
} else {
setprop(me.fbw_root~"stable_pitch", 0);
me.stable_pitch = 0;
me.active_pitch = 1;
}
#### ROLL ####
if ((me.aileronin <= 0.01) and (me.aileronin >= -0.01)) {
if (me.stable_bank == 0) {
setprop(me.fbw_root~"stable_bank_deg", me.roll);
me.stable_bank = 1;
me.active_bank = 0;
}
setprop(me.fbw_root~"stable_bank", 1);
} else {
setprop(me.fbw_root~"stable_bank", 0);
me.stable_bank = 0;
me.active_bank = 1;
}
},
demand_pitch : func{
# pitch rate w=a/v
me.actual_G = getprop("/accelerations/pilot-gdamped") - 1;
me.desired_G = me.elevatorin * -1.5;
me.actual_pitch_rate = (me.actual_G * G_force) / (me.groundspeedkt * KT2MS);
me.desired_pitch_rate = (me.desired_G * G_force) / (me.groundspeedkt * KT2MS);
setprop(me.fbw_root~"actual-pitch-rate_degps", me.actual_pitch_rate);
setprop(me.fbw_root~"target-pitch-rate_degps", me.desired_pitch_rate);
},
demand_roll : func{
#me.actual_roll_rate = getprop("/fdm/jsbsim/velocities/p-aero-rad_sec");
me.desired_roll_rate = me.aileronin * me.max_roll;
setprop(me.fbw_root~"target-roll-rad_sec", me.desired_roll_rate);
},
get_alpha_prot_state : func{
if (me.pitch <= me.alpha_min) return 'alpha_min';
else if (me.pitch >= me.alpha_prot and me.pitch < me.alpha_floor) return 'alpha_prot';
else if (me.pitch >= me.alpha_floor and me.pitch < me.alpha_max) return 'alpha_floor';
else if (me.pitch >= me.alpha_max) return 'alpha_max';
},
set_active_bank : func{
me.stable_bank = 0;
me.active_bank = 1;
setprop(me.fbw_root~"stable_bank", me.stable_bank);
setprop(me.fbw_root~"active_bank",me.active_bank);
},
set_active_pitch : func{
me.stable_pitch = 0;
me.active_pitch = 1;
setprop(me.fbw_root~"stable_pitch",me.stable_pitch);
setprop(me.fbw_root~"active_pitch",me.active_pitch);
},
set_stable_bank : func(deg){
me.stable_bank = 1;
me.active_bank = 0;
me.stable_bank_deg = deg;
setprop(me.fbw_root~"stable_bank", me.stable_bank);
setprop(me.fbw_root~"active_bank",me.active_bank);
setprop(me.fbw_root~"stable_bank_deg", me.stable_bank_deg);
},
set_stable_pitch : func(deg){
me.stable_pitch = 1;
me.active_pitch = 0;
me.stable_pitch_deg = deg;
setprop(me.fbw_root~"stable_pitch",me.stable_pitch);
setprop(me.fbw_root~"active_pitch",me.active_pitch);
setprop(me.fbw_root~"stable_pitch_deg", me.stable_pitch_deg);
},
update : func{
me.get_state(); # update variables
if ( me.engaged ){
me.Airbus_law(); # update engage mode
if ( me.law == 'Normal') {
# <!-- =============================================================== -->
# <!-- "Normal" law when fbw Active -->
# <!-- =============================================================== -->
me.autostable(); # if Joke neutral, Stabilize through PID
if (me.stablemode) {
if (!me.stable_bank) { #when not stable calculate roll
me.demand_roll(); # Set values for PID
}
if (!me.stable_pitch) { #when not stable calculate pitch
me.demand_pitch(); # Set values for PID
}
} else {
me.demand_roll();
me.demand_pitch();
}
setprop(me.fcs_root~"rudder-fbw-output", me.rudderin); #Direct rudder
} else if (me.law == 'AOA') {
# <!-- =============================================================== -->
# <!-- "Angle of Attack" law when out of limits -->
# <!-- =============================================================== -->
# Alpha_prot Triggered
me.alpha_prot_state = me.get_alpha_prot_state();
if (me.alpha_prot_state == 'alpha_min') me.set_stable_bank(me.alpha_min + 2);
else if (me.elevatorin <= -0.8) {
# demanding more alpha
if (me.alpha_prot_state == 'alpha_prot') {
#direct elevator
setprop(me.fcs_root~"elevator-fbw-output", me.elevatorin);
} else if (me.alpha_prot_state == 'alpha_floor') {
#full throttles
me.throttle0 = 1;
me.throttle1 = 1;
setprop("controls/engines/engine[0]/throttle", me.throttle0);
setprop("controls/engines/engine[1]/throttle", me.throttle1);
#direct elevator
setprop(me.fcs_root~"elevator-fbw-output", me.elevatorin);
} else if (me.alpha_prot_state == 'alpha_max') {
#full throttles
me.throttle0 = 1;
me.throttle1 = 1;
setprop("controls/engines/engine[0]/throttle", me.throttle0);
setprop("controls/engines/engine[1]/throttle", me.throttle1);
me.set_stable_bank(me.alpha_max - 2);
}
} else {
me.set_stable_bank(me.alpha_prot + 2);# stick relaxed go inside flight envelope
}
me.set_active_pitch();
} else if (me.law == 'Direct') { # don't overwrite AP
# <!-- =============================================================== -->
# <!-- "Direct" law when fbw not Active -->
# <!-- =============================================================== -->
me.active_bank = 0;
me.active_pitch = 0;
me.stable_bank = 0;
me.stable_pitch = 0;
setprop(me.fcs_root~"aileron-fbw-output", me.aileronin);
setprop(me.fcs_root~"elevator-fbw-output", me.elevatorin);
setprop(me.fcs_root~"rudder-fbw-output", me.rudderin);
} else if (me.law == 'AP') {
# <!-- =============================================================== -->
# <!-- "AP" law stay calmed (shutdown) -->
# <!-- =============================================================== -->
me.active_bank = 0;
me.active_pitch = 0;
me.stable_bank = 0;
me.stable_pitch = 0;
}
setprop(me.fbw_root~"mode",me.mode);
setprop(me.fbw_root~"law",me.law);
setprop(me.fbw_root~"active_pitch",me.active_pitch);
setprop(me.fbw_root~"active_bank",me.active_bank);
setprop(me.fbw_root~"stable_pitch",me.stable_pitch);
setprop(me.fbw_root~"stable_bank",me.stable_bank);
} else { #not engaged
# <!-- =============================================================== -->
# <!-- FBW Shutdown (imposible in real life) -->
# <!-- =============================================================== -->
me.active_bank = 0;
me.active_pitch = 0;
me.stable_bank = 0;
me.stable_pitch = 0;
setprop(me.fbw_root~"active_pitch",me.active_pitch);
setprop(me.fbw_root~"active_bank",me.active_bank);
setprop(me.fbw_root~"stable_pitch",me.stable_pitch);
setprop(me.fbw_root~"stable_bank",me.stable_bank);
setprop(me.fcs_root~"aileron-fbw-output", me.aileronin);
setprop(me.fcs_root~"elevator-fbw-output", me.elevatorin);
setprop(me.fcs_root~"rudder-fbw-output", me.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");
bicyus wrote in Mon Apr 09, 2012 2:50 pm:Omega95 i told you i was working on the FBW... don't re do the work.![]()
omega95 wrote in Mon Apr 09, 2012 1:55 pm:I just looked at a picture of a real A320's Mode Control Panel...
omega95 wrote in Mon Apr 09, 2012 1:55 pm:Where exactly are the VNAV, LNAV and those other buttons?
Can anyone explain how this new MCP works?
<key n="267">
<name>alt-F11</name>
<repeatable type="bool">true</repeatable>
<mod-alt>
<repeatable type="bool">false</repeatable>
<desc>cycle fbw roll over-ride settings</desc>
<binding>
<command>nasal</command>
<script>
var tNode = props.globals.getNode("/autopilot/internal/apid/fbw-roll-override", 1);
var tMode = tNode.getValue();
if ( tMode== nil ) tMode= "NONE";
if (tMode == "NONE") {
tMode = "DIRECT";
} else if (tMode == "DIRECT") {
tMode = "HOLD";
} else if (tMode == "HOLD") {
tMode = "NONE";
}
print("apid fbw-roll-override: ", tMode);
tNode.setValue(tMode);
</script>
</binding>
</mod-alt>
</key>
<key n="268">
<name>alt-F12</name>
<repeatable type="bool">true</repeatable>
<mod-alt>
<repeatable type="bool">false</repeatable>
<desc>cycle fbw pitch over-ride settings </desc>
<binding>
<command>nasal</command>
<script>
var tNode = props.globals.getNode("/autopilot/internal/apid/fbw-pitch-override", 1);
var tMode = tNode.getValue();
if ( tMode== nil ) tMode= "NONE";
if (tMode == "NONE") {
tMode = "DIRECT";
} else if (tMode == "DIRECT") {
tMode = "HOLD";
} else if (tMode == "HOLD") {
tMode = "NONE";
}
print("fbw-pitch-override: ", tMode);
tNode.setValue(tMode);
</script>
</binding>
</mod-alt>
</key>
polly wrote in Mon Apr 09, 2012 4:43 pm:I've been working on PID tuning but the FDM was changed recently, upsetting the PID's . It's a waste of effort to have two separate fbw and PID implementations running in parallel. Whoever wins the Battle of the Titans ...
awexome wrote in Mon Apr 09, 2012 5:01 pm:this is becoming sad ... waste of effort??? Guys, more coordination and collaboration. Be efficient with time and effort.polly wrote in Mon Apr 09, 2012 4:43 pm:It's a waste of effort to have two separate fbw and PID implementations running in parallel.
Does this team need an adminstrator?
Users browsing this forum: No registered users and 2 guests