7253f8633b
"I have been working with Torsten Dryer to model these three autopilots that are very common in aircraft manufactured in the 1960s through the late 1980s. The Altimatic IIIc in the SenecaII is a variation on the Century III and uses the same nasal model." mf: these should be in cvs since a while; somehow I missed them, sorry
737 lines
20 KiB
Text
737 lines
20 KiB
Text
##
|
|
# Century III Autopilot System
|
|
# Tries to behave like the Century III autopilot
|
|
# two axis
|
|
#
|
|
# One would also need the autopilot configuration file
|
|
# CENTURYIII.xml and the panel instrument configuration file
|
|
#
|
|
# Written by Dave Perry to match functionality described in
|
|
#
|
|
# CENTURY III
|
|
# AUTOPILOT FLIGHT SYSTEM
|
|
# PILOT'S OPERATING HANDBOOK
|
|
# NOVEMBER 1998 68S25
|
|
#
|
|
# Draws heavily from the kap140 system written by Roy Vegard Ovesen
|
|
##
|
|
|
|
# Properties
|
|
|
|
locks = "/autopilot/CENTURYIII/locks";
|
|
settings = "/autopilot/CENTURYIII/settings";
|
|
internal = "/autopilot/internal";
|
|
flightControls = "/controls/flight";
|
|
autopilotControls = "/autopilot/CENTURYIII/controls";
|
|
|
|
# locks
|
|
propLocks = props.globals.getNode(locks, 1);
|
|
|
|
lockAltHold = propLocks.getNode("alt-hold", 1);
|
|
lockPitchHold = propLocks.getNode("pitch-hold", 1);
|
|
lockAprHold = propLocks.getNode("apr-hold", 1);
|
|
lockGsHold = propLocks.getNode("gs-hold", 1);
|
|
lockHdgHold = propLocks.getNode("hdg-hold", 1);
|
|
lockNavHold = propLocks.getNode("nav-hold", 1);
|
|
lockOmniHold = propLocks.getNode("omni-hold", 1);
|
|
lockRevHold = propLocks.getNode("rev-hold", 1);
|
|
lockRollAxis = propLocks.getNode("roll-axis", 1);
|
|
lockRollMode = propLocks.getNode("roll-mode", 1);
|
|
lockPitchAxis = propLocks.getNode("pitch-axis", 1);
|
|
lockPitchMode = propLocks.getNode("pitch-mode", 1);
|
|
lockRollArm = propLocks.getNode("roll-arm", 1);
|
|
lockPitchArm = propLocks.getNode("pitch-arm", 1);
|
|
|
|
|
|
rollModes = { "OFF" : 0, "ROL" : 1, "HDG" : 2, "OMNI" : 3, "NAV" : 4, "REV" : 5, "APR" : 6 };
|
|
pitchModes = { "OFF" : 0, "VS" : 1, "ALT" : 2, "GS" : 3, "AOA" : 4 };
|
|
rollArmModes = { "OFF" : 0, "NAV" : 1, "OMNI" : 2, "APR" : 3, "REV" : 4 };
|
|
pitchArmModes = { "OFF" : 0, "ALT" : 1, "GS" : 2 };
|
|
|
|
# settings
|
|
propSettings = props.globals.getNode(settings, 1);
|
|
|
|
settingTargetAltPressure = propSettings.getNode("target-alt-pressure", 1);
|
|
settingTargetInterceptAngle = propSettings.getNode("target-intercept-angle", 1);
|
|
settingTargetPressureRate = propSettings.getNode("target-pressure-rate", 1);
|
|
settingTargetRollDeg = propSettings.getNode("target-roll-deg", 1);
|
|
settingRollKnobDeg = propSettings.getNode("roll-knob-deg", 1);
|
|
settingTargetPitchDeg = propSettings.getNode("target-pitch-deg", 1);
|
|
settingPitchWheelDeg = propSettings.getNode("pitch-wheel-deg", 1);
|
|
settingAutoPitchTrim = propSettings.getNode("auto-pitch-trim", 1);
|
|
settingGScaptured = propSettings.getNode("gs-captured", 1);
|
|
settingDeltaPitch = propSettings.getNode("delta-pitch", 1);
|
|
|
|
#Flight controls
|
|
propFlightControls = props.globals.getNode(flightControls, 1);
|
|
|
|
elevatorControl = propFlightControls.getNode("elevator", 1);
|
|
elevatorTrimControl = propFlightControls.getNode("elevator-trim", 1);
|
|
|
|
#Autopilot controls
|
|
propAutopilotControls = props.globals.getNode(autopilotControls, 1);
|
|
|
|
rollControl = propAutopilotControls.getNode("roll", 1);
|
|
# values 0 (ROLL switch off) 1 (ROLL switch on)
|
|
|
|
hdgControl = propAutopilotControls.getNode("hdg", 1);
|
|
# values 0 (HDG switch off) 1 (HDG switch on)
|
|
|
|
modeControl = propAutopilotControls.getNode("mode", 1);
|
|
|
|
altControl = propAutopilotControls.getNode("alt", 1);
|
|
# values 0 (ALT switch off) 1 (ALT switch on)
|
|
|
|
pitchControl = propAutopilotControls.getNode("pitch", 1);
|
|
# values 0 (PITCH switch off) 1 (PITCH switch on)
|
|
|
|
headingNeedleDeflection = "/instrumentation/nav/heading-needle-deflection";
|
|
gsNeedleDeflection = "/instrumentation/nav/gs-needle-deflection";
|
|
indicatedPitchDeg = "/instrumentation/attitude-indicator/indicated-pitch-deg";
|
|
staticPressure = "/systems/static/pressure-inhg";
|
|
altitudePressure = "/autopilot/CENTURYIII/settings/target-alt-pressure";
|
|
power="/systems/electrical/outputs/autopilot";
|
|
enableAutoTrim = "/sim/model/enable-auto-trim";
|
|
filteredHeadingNeedleDeflection = "/autopilot/internal/filtered-heading-needle-deflection";
|
|
|
|
pressureUnits = { "inHg" : 0, "hPa" : 1 };
|
|
altPressure = 0.0;
|
|
gsTimeCheck = 0.0;
|
|
valueTest = 0;
|
|
lastValue = 0;
|
|
newValue = 0;
|
|
minVoltageLimit = 8.0;
|
|
oldMode = 2;
|
|
rollControl.setDoubleValue(0.0);
|
|
hdgControl.setDoubleValue(0.0);
|
|
altControl.setDoubleValue(0.0);
|
|
pitchControl.setDoubleValue(0.0);
|
|
modeControl.setDoubleValue(2.0);
|
|
settingTargetPitchDeg.setDoubleValue(0.0);
|
|
settingPitchWheelDeg.setDoubleValue(0.0);
|
|
settingDeltaPitch.setDoubleValue(0.0);
|
|
settingTargetPressureRate.setDoubleValue(0.0);
|
|
settingGScaptured.setDoubleValue(0.0);
|
|
# If you need to be able to enable/disable auto trim, make is a menue toggle.
|
|
# Auto trim enabled by default
|
|
setprop(enableAutoTrim, 1);
|
|
autoPitchTrim = 0.0;
|
|
|
|
apInit = func {
|
|
##print("ap init");
|
|
|
|
##
|
|
# Initialises the autopilot.
|
|
##
|
|
|
|
lockAltHold.setBoolValue(0);
|
|
lockAprHold.setBoolValue(0);
|
|
lockGsHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(0);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(0);
|
|
lockRollMode.setIntValue(rollModes["OFF"]);
|
|
lockPitchAxis.setBoolValue(0);
|
|
lockPitchHold.setBoolValue(0);
|
|
lockPitchMode.setIntValue(pitchModes["OFF"]);
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
lockPitchArm.setIntValue(pitchArmModes["OFF"]);
|
|
# Reset the memory for power down or power up
|
|
settingTargetAltPressure.setDoubleValue(0.0);
|
|
settingTargetPitchDeg.setDoubleValue(0.0);
|
|
settingTargetPressureRate.setDoubleValue(0.0);
|
|
settingTargetInterceptAngle.setDoubleValue(0.0);
|
|
settingTargetRollDeg.setDoubleValue(0.0);
|
|
settingAutoPitchTrim.setDoubleValue(0.0);
|
|
settingGScaptured.setDoubleValue(0.0);
|
|
settingRollKnobDeg.setDoubleValue(0.0);
|
|
|
|
}
|
|
|
|
apPower = func {
|
|
|
|
## Monitor autopilot power
|
|
## Call apInit if the power is too low
|
|
|
|
if (getprop(power) < minVoltageLimit) {
|
|
newValue = 0;
|
|
} else {
|
|
newValue = 1;
|
|
}
|
|
|
|
valueTest = newValue - lastValue;
|
|
# print("v_test = ", v_test);
|
|
if (valueTest > 0.5) {
|
|
# autopilot just powered up
|
|
print("power up");
|
|
apInit();
|
|
} elsif (valueTest < -0.5) {
|
|
# autopilot just lost power
|
|
print("power lost");
|
|
apInit();
|
|
# note: all button and knobs disabled in functions below
|
|
}
|
|
lastValue = newValue;
|
|
|
|
# Update difference between pitch wheel target and indicated pitch.
|
|
# Used to animate the Pitch Trim meter to the left of pitch wheel
|
|
if (rollControl.getValue() ) {
|
|
settingDeltaPitch.setDoubleValue(settingPitchWheelDeg.getValue()
|
|
- getprop(indicatedPitchDeg));
|
|
} else {
|
|
settingDeltaPitch.setDoubleValue(0.0);
|
|
}
|
|
inrange0 = getprop("/instrumentation/nav[0]/in-range");
|
|
# Shut off autopilot if HDG switch on and mode != 2 when NAV flag is on
|
|
if ( !inrange0 ) {
|
|
if ( hdgControl.getValue() and (modeControl.getValue() != 2)) {
|
|
rollControl.setDoubleValue(0.0);
|
|
apRollControl();
|
|
}
|
|
}
|
|
settimer(apPower, 0.5);
|
|
}
|
|
|
|
apRollControl = func {
|
|
|
|
if (rollControl.getValue() ) {
|
|
rollButton(1);
|
|
} else {
|
|
# A/P on/off switch was turned off, so turn off other AP switches
|
|
hdgControl.setDoubleValue(0.0); #hdgButton(0);
|
|
altControl.setDoubleValue(0.0); #altButton(0);
|
|
pitchControl.setDoubleValue(0.0); #pitchButton(0);
|
|
# rollButton(0);
|
|
apInit();
|
|
}
|
|
}
|
|
|
|
apHdgControl = func {
|
|
|
|
if (hdgControl.getValue() ) {
|
|
# hdg switch turned on sets roll
|
|
rollControl.setDoubleValue(1.0);
|
|
rollButton(1);
|
|
##
|
|
# hdg switch is on so check which roll mode is set
|
|
##
|
|
apModeControlsSet();
|
|
} else {
|
|
# hdg switch turned off resets alt and pitch
|
|
hdgControl.setDoubleValue(0.0); hdgButton(0);
|
|
altControl.setDoubleValue(0.0); altButton(0);
|
|
pitchControl.setDoubleValue(0.0); pitchButton(0);
|
|
}
|
|
}
|
|
|
|
apAltControl = func {
|
|
|
|
if ( altControl.getValue() ){
|
|
# Alt switch on so set ROLL, HDG, and PITCH
|
|
rollControl.setDoubleValue(1.0);
|
|
rollButton(1);
|
|
hdgControl.setDoubleValue(1.0);
|
|
# roll and hdg switches on so check which roll mode is set
|
|
apModeControlsSet();
|
|
pitchControl.setDoubleValue(1.0);
|
|
pitchButton(1);
|
|
altButton(1);
|
|
} else {
|
|
altButton(0);
|
|
}
|
|
}
|
|
|
|
apPitchControl = func {
|
|
|
|
if ( pitchControl.getValue() ) {
|
|
# Pitch switch on so set ROLL and HDG
|
|
rollControl.setDoubleValue(1.0);
|
|
rollButton(1);
|
|
hdgControl.setDoubleValue(1.0);
|
|
# roll and hdg switches on so check which roll mode is set
|
|
apModeControlsSet();
|
|
pitchButton(1);
|
|
} else {
|
|
altControl.setDoubleValue(0.0);
|
|
altButton(0);
|
|
pitchButton(0);
|
|
}
|
|
}
|
|
|
|
rollKnobUpdate = func {
|
|
if ( rollControl.getValue() and !hdgControl.getValue() ) {
|
|
settingTargetRollDeg.setDoubleValue( settingRollKnobDeg.getValue() );
|
|
}
|
|
}
|
|
|
|
|
|
pitchWheelUpdate = func {
|
|
if ( rollControl.getValue() and !altControl.getValue() ) {
|
|
settingTargetPitchDeg.setDoubleValue( settingPitchWheelDeg.getValue() );
|
|
}
|
|
}
|
|
|
|
|
|
apModeControlsChange = func {
|
|
##
|
|
# Delay mode change to allow time for multi-mode rotation
|
|
##
|
|
settimer(apModeControlsSet, 2);
|
|
}
|
|
|
|
apModeControlsSet = func {
|
|
newMode = modeControl.getValue();
|
|
|
|
##
|
|
# Decouple GS if the mode selector is switched from LOC NORM
|
|
##
|
|
if (oldMode == rollModes["APR"] and newMode != rollModes["APR"])
|
|
{
|
|
if (lockPitchMode.getValue() == pitchModes["GS"])
|
|
{
|
|
lockPitchMode.setIntValue(pitchModes["OFF"]);
|
|
}
|
|
if (lockPitchArmModes.getValue() == pitchArmModes["GS"])
|
|
{
|
|
lockPitchArmMode.setIntValue(pitchModes["OFF"]);
|
|
}
|
|
lockGsHold.setBoolValue(0);
|
|
settingGScoupled.setDoubleValue(0.0);
|
|
}
|
|
|
|
oldMode = newMode;
|
|
|
|
#All modes entered from hdg mode
|
|
if ( hdgControl.getValue() ) {
|
|
hdgButton(1);
|
|
if (newMode == 0 ){
|
|
navButton();
|
|
} elsif (newMode == 1 ) {
|
|
omniButton();
|
|
} elsif (newMode == 3 ) {
|
|
aprButton();
|
|
} elsif(newMode == 4 ) {
|
|
revButton();
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
rollButton = func(switch_on) {
|
|
##print("rollButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
if ( switch_on ) {
|
|
##
|
|
# Engage the autopilot in Wings level mode (ROL) and set the turn rate
|
|
# from the "ROLL Knob".
|
|
##
|
|
|
|
lockAprHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(0);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollMode.setIntValue(rollModes["ROL"]);
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
} else {
|
|
lockAprHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(0);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(0);
|
|
lockRollMode.setIntValue(rollModes["OFF"]);
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
}
|
|
}
|
|
|
|
|
|
hdgButton = func(switch_on) {
|
|
##print("hdgButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
if (switch_on) {
|
|
##
|
|
# Engage the heading mode (HDG).
|
|
##
|
|
lockAprHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollMode.setIntValue(rollModes["HDG"]);
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
|
|
settingTargetInterceptAngle.setDoubleValue(0.0);
|
|
|
|
} else {
|
|
lockHdgHold.setBoolValue(0);
|
|
rollKnobUpdate();
|
|
if ( rollControl.getValue() ) {
|
|
lockRollMode.setIntValue(rollModes["ROL"]);
|
|
} else {
|
|
lockRollMode.setIntValue(rollModes["OFF"]);
|
|
}
|
|
}
|
|
}
|
|
|
|
navButton = func {
|
|
##print("navButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
##
|
|
# The Mode Selector and DG Course Selector should be set before switching the HDG
|
|
# rocker switch to "on". The DG Course Selector should be set to the OBS "to" or
|
|
# "from" bearing.
|
|
# Set up NAV mode and switch to the 45 degree angle intercept NAV mode
|
|
##
|
|
lockAprHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollArm.setIntValue(rollArmModes["NAV"]);
|
|
lockRollMode.setIntValue(rollModes["NAV"]);
|
|
|
|
navArmFromHdg();
|
|
}
|
|
|
|
navArmFromHdg = func
|
|
{
|
|
##
|
|
# Abort the NAV-ARM mode if something has changed the arm mode to something
|
|
# else than NAV-ARM.
|
|
##
|
|
if (lockRollArm.getValue() != rollArmModes["NAV"])
|
|
{
|
|
return;
|
|
}
|
|
|
|
##
|
|
# Activate the nav-hold controller and check the needle deviation.
|
|
##
|
|
lockNavHold.setBoolValue(1);
|
|
deviation = getprop(headingNeedleDeflection);
|
|
##
|
|
# If the deflection is more than 9.95 degrees wait 5 seconds and check again.
|
|
##
|
|
if (abs(deviation) > 9.95)
|
|
{
|
|
#print("deviation");
|
|
settimer(navArmFromHdg, 5);
|
|
return;
|
|
}
|
|
##
|
|
# If the deviation is less than 10 degrees turn off the NAV-ARM. End of NAV-ARM sequence.
|
|
##
|
|
elsif (abs(deviation) < 10.0)
|
|
{
|
|
#print("capture");
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
}
|
|
}
|
|
|
|
omniButton = func {
|
|
##print("navButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
##
|
|
# The Mode Selector and DG Course Selector should be set before switching the HDG
|
|
# rocker switch to "on". The DG Course Selector should be set to the OBS "to" or
|
|
# "from" bearing.
|
|
# Set up OMNI mode and switch to the 45 degree angle intercept OMNI mode
|
|
##
|
|
lockAprHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollArm.setIntValue(rollArmModes["OMNI"]);
|
|
lockRollMode.setIntValue(rollModes["OMNI"]);
|
|
|
|
omniArmFromHdg();
|
|
}
|
|
|
|
|
|
omniArmFromHdg = func
|
|
{
|
|
##
|
|
# Abort the OMNI-ARM mode if something has changed the arm mode to something
|
|
# else than OMNI-ARM.
|
|
##
|
|
if (lockRollArm.getValue() != rollArmModes["OMNI"])
|
|
{
|
|
return;
|
|
}
|
|
|
|
##
|
|
# Activate the omni-hold controller and check the needle deviation.
|
|
##
|
|
lockOmniHold.setBoolValue(1);
|
|
deviation = getprop(filteredHeadingNeedleDeflection);
|
|
##
|
|
# If the deflection is more than 9.95 degrees wait 5 seconds and check again.
|
|
##
|
|
if (abs(deviation) > 9.95)
|
|
{
|
|
#print("deviation");
|
|
settimer(omniArmFromHdg, 5);
|
|
return;
|
|
}
|
|
##
|
|
# If the deviation is less than 10 degrees turn off the OMNI-ARM. End of OMNI-ARM sequence.
|
|
##
|
|
elsif (abs(deviation) < 10.0)
|
|
{
|
|
#print("capture");
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
}
|
|
}
|
|
|
|
|
|
aprButton = func {
|
|
##print("aprButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
##
|
|
# The Mode Selector and DG Course Selector should be set before switching the HDG
|
|
# rocker switch to "on". Set the DG Course Selector to the LOC inbound heading.
|
|
# Set up APR mode and switch to the 45 degree angle intercept APR mode
|
|
##
|
|
lockAprHold.setBoolValue(1);
|
|
lockRevHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollArm.setIntValue(rollArmModes["APR"]);
|
|
lockRollMode.setIntValue(rollModes["APR"]);
|
|
gsTimeCheck = -1;
|
|
|
|
aprArmFromHdg();
|
|
}
|
|
|
|
aprArmFromHdg = func
|
|
{
|
|
##
|
|
# Abort the APR-ARM mode if something has changed the arm mode to something
|
|
# else than APR-ARM.
|
|
##
|
|
if (lockRollArm.getValue() != rollArmModes["APR"]
|
|
or !lockAltHold.getValue()
|
|
or getprop(gsNeedleDeflection) < 0.0)
|
|
{
|
|
return;
|
|
}
|
|
gsTimeCheck = gsTimeCheck + 1;
|
|
if (gsTimeCheck < 20)
|
|
{
|
|
settimer(aprArmFromHdg, 1.0);
|
|
}
|
|
|
|
##
|
|
# Activate the apr-hold controller and check the needle deviation.
|
|
##
|
|
lockAprHold.setBoolValue(1);
|
|
deviation = getprop(headingNeedleDeflection);
|
|
##
|
|
# If the deflection is more than 2.5 degrees wait 5 seconds and check again.
|
|
##
|
|
if (abs(deviation) > 2.495)
|
|
{
|
|
#print("deviation");
|
|
settimer(aprArmFromHdg, 5);
|
|
return;
|
|
}
|
|
##
|
|
# If the deviation is less than 2.5 degrees, start the GS-ARM sequence
|
|
##
|
|
elsif (abs(deviation) < 2.5)
|
|
{
|
|
lockPitchArm.setIntValue(pitchArmModes["GS"]);
|
|
gsArm();
|
|
}
|
|
}
|
|
|
|
gsArm = func {
|
|
##
|
|
# Abort the GS-ARM mode if something has changed the arm mode to something
|
|
# else than GS-ARM.
|
|
##
|
|
if (lockPitchArm.getValue() != pitchArmModes["GS"])
|
|
{
|
|
return;
|
|
}
|
|
|
|
deviation = getprop(gsNeedleDeflection);
|
|
##
|
|
# If the deflection is more than 0.25 degrees wait 5 seconds and check again.
|
|
##
|
|
if (abs(deviation) > 0.25)
|
|
{
|
|
#print("deviation");
|
|
settimer(gsArm, 5);
|
|
return;
|
|
}
|
|
##
|
|
# If the deviation is less than 1 then activate the GS pitch mode.
|
|
##
|
|
elsif (abs(deviation) < 0.251)
|
|
{
|
|
#print("capture");
|
|
lockAltHold.setBoolValue(0);
|
|
lockGsHold.setBoolValue(1);
|
|
lockPitchMode.setIntValue(pitchModes["GS"]);
|
|
lockPitchArm.setIntValue(pitchArmModes["OFF"]);
|
|
settingGScaptured.setDoubleValue(1.0);
|
|
}
|
|
}
|
|
|
|
|
|
revButton = func {
|
|
##print("revButton");
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
##
|
|
# The Mode Selector and DG Course Selector should be set before switching the HDG
|
|
# rocker switch to "on". Set the DG Course Selector to the LOC outbound
|
|
# (or reverse) heading.
|
|
# Set up REV mode and switch to the 45 degree angle intercept REV mode
|
|
##
|
|
lockAprHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(0);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollArm.setIntValue(rollArmModes["REV"]);
|
|
|
|
revArmFromHdg();
|
|
}
|
|
|
|
|
|
revArmFromHdg = func
|
|
{
|
|
##
|
|
# Abort the REV-ARM mode if something has changed the arm mode to something
|
|
# else than REV-ARM.
|
|
##
|
|
if (lockRollArm.getValue() != rollArmModes["REV"])
|
|
{
|
|
return;
|
|
}
|
|
|
|
##
|
|
# Activate the rev-hold controller and check the needle deviation.
|
|
##
|
|
lockRevHold.setBoolValue(1);
|
|
deviation = getprop(headingNeedleDeflection);
|
|
##
|
|
# If the deflection is more than 2.5 degrees wait 5 seconds and check again.
|
|
##
|
|
if (abs(deviation) > 2.495)
|
|
{
|
|
#print("deviation");
|
|
settimer(revArmFromHdg, 5);
|
|
return;
|
|
}
|
|
##
|
|
# If the deviation is less than 2.5 - End of REV-ARM sequence.
|
|
##
|
|
elsif (abs(deviation) < 2.5)
|
|
{
|
|
#print("capture");
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
lockAprHold.setBoolValue(0);
|
|
lockRevHold.setBoolValue(1);
|
|
lockHdgHold.setBoolValue(1);
|
|
lockNavHold.setBoolValue(0);
|
|
lockOmniHold.setBoolValue(0);
|
|
lockRollAxis.setBoolValue(1);
|
|
lockRollMode.setIntValue(rollModes["REV"]);
|
|
lockRollArm.setIntValue(rollArmModes["OFF"]);
|
|
}
|
|
}
|
|
|
|
|
|
altButton = func(switch_on) {
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
if (switch_on) {
|
|
lockAltHold.setBoolValue(1);
|
|
lockPitchAxis.setBoolValue(1);
|
|
# lockPitchMode.setIntValue(pitchModes["ALT"]);
|
|
|
|
altPressure = getprop(staticPressure);
|
|
settingTargetAltPressure.setDoubleValue(altPressure);
|
|
# print("enableAutoTrim = ", getprop(enableAutoTrim));
|
|
if ( getprop(enableAutoTrim) ) {
|
|
settingAutoPitchTrim.setDoubleValue(1);
|
|
}
|
|
} else {
|
|
lockAltHold.setBoolValue(0);
|
|
lockPitchAxis.setBoolValue(0);
|
|
lockPitchMode.setIntValue(pitchModes["OFF"]);
|
|
lockPitchArm.setIntValue(pitchArmModes["OFF"]);
|
|
pitchWheelUpdate();
|
|
settingTargetPressureRate.setDoubleValue(0.0);
|
|
# alt switch is off so make sure the glide slope is disabled
|
|
settingGScaptured.setDoubleValue(0.0);
|
|
lockGsHold.setBoolValue(0);
|
|
}
|
|
}
|
|
|
|
pitchButton = func(switch_on) {
|
|
# Disable button if too little power
|
|
if (getprop(power) < minVoltageLimit) { return; }
|
|
|
|
if (switch_on) {
|
|
lockPitchHold.setBoolValue(1);
|
|
# lockPitchAxis.setBoolValue(1);
|
|
# lockPitchMode.setIntValue(pitchModes["AOA"]);
|
|
# print("enableAutoTrim = ", getprop(enableAutoTrim));
|
|
if ( getprop(enableAutoTrim) ) {
|
|
settingAutoPitchTrim.setDoubleValue(1);
|
|
}
|
|
} else {
|
|
lockPitchHold.setBoolValue(0);
|
|
lockPitchAxis.setBoolValue(0);
|
|
lockPitchMode.setIntValue(pitchModes["OFF"]);
|
|
settingAutoPitchTrim.setDoubleValue(0);
|
|
}
|
|
}
|
|
|
|
touchPower = func{
|
|
setprop(power,apVolts);
|
|
}
|
|
|
|
apVolts = getprop(power);
|
|
|
|
if ( apVolts == nil or apVolts < minVoltageLimit ) {
|
|
# Wait for autopilot to be powered up
|
|
var L = setlistener(power, func {
|
|
apPower();
|
|
removelistener(L);
|
|
});
|
|
} else {
|
|
# Skip the setlistener since autopilot is already powered up
|
|
settimer(touchPower ,10);
|
|
apPower();
|
|
}
|
|
|
|
|