331 lines
7.9 KiB
Text
331 lines
7.9 KiB
Text
|
###############################################################################
|
||
|
##
|
||
|
## Nasal for dual control of a KAP 140 autopilot over the multiplayer
|
||
|
## network.
|
||
|
##
|
||
|
## Copyright (C) 2008 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||
|
## This file is licensed under the GPL license version 2 or later.
|
||
|
##
|
||
|
###############################################################################
|
||
|
|
||
|
# Note:
|
||
|
# This module MUST be loaded as kap140.
|
||
|
#
|
||
|
|
||
|
# Load the real KAP 140 module as kap140_implementation.
|
||
|
if (!contains(globals, "kap140_implementation")) {
|
||
|
io.load_nasal(getprop("/sim/fg-root") ~
|
||
|
"/Aircraft/Generic/kap140.nas",
|
||
|
"kap140_implementation");
|
||
|
}
|
||
|
|
||
|
# Slave button presses.
|
||
|
var ap_btn = "ap-btn";
|
||
|
var hdg_btn = "hdg-btn";
|
||
|
var nav_btn = "nav-btn";
|
||
|
var apr_btn = "apr-btn";
|
||
|
var alt_btn = "alt-btn";
|
||
|
var rev_btn = "rev-btn";
|
||
|
var down_btn = "down-btn";
|
||
|
var up_btn = "up-btn";
|
||
|
var arm_btn = "arm-btn";
|
||
|
var baro_press_btn = "baro-press-btn";
|
||
|
var baro_release_btn = "baro-release-btn";
|
||
|
|
||
|
var base = "autopilot/kap140/";
|
||
|
var buttons = base ~ "buttons/";
|
||
|
|
||
|
###############################################################################
|
||
|
# API function wrappers.
|
||
|
|
||
|
var apButton = func {
|
||
|
kap140.apButton();
|
||
|
}
|
||
|
|
||
|
var hdgButton = func {
|
||
|
kap140.hdgButton();
|
||
|
}
|
||
|
|
||
|
var navButton = func {
|
||
|
kap140.navButton();
|
||
|
}
|
||
|
|
||
|
var aprButton = func {
|
||
|
kap140.aprButton();
|
||
|
}
|
||
|
|
||
|
var altButton = func {
|
||
|
kap140.altButton();
|
||
|
}
|
||
|
|
||
|
var revButton = func {
|
||
|
kap140.revButton();
|
||
|
}
|
||
|
|
||
|
var downButton = func {
|
||
|
kap140.downButton();
|
||
|
}
|
||
|
|
||
|
var upButton = func {
|
||
|
kap140.upButton();
|
||
|
}
|
||
|
|
||
|
var armButton = func {
|
||
|
kap140.armButton();
|
||
|
}
|
||
|
|
||
|
var baroButtonPress = func {
|
||
|
kap140.baroButtonPress();
|
||
|
}
|
||
|
|
||
|
var baroButtonRelease = func {
|
||
|
kap140.baroButtonRelease();
|
||
|
}
|
||
|
|
||
|
var knobSmallDown = func {
|
||
|
kap140.knobSmallDown();
|
||
|
}
|
||
|
|
||
|
var knobSmallUp = func {
|
||
|
kap140.knobSmallUp();
|
||
|
}
|
||
|
|
||
|
var knobLargeDown = func {
|
||
|
kap140.knobLargeDown();
|
||
|
}
|
||
|
|
||
|
var knobLargeUp = func {
|
||
|
kap140.knobLargeUp();
|
||
|
}
|
||
|
|
||
|
###############################################################################
|
||
|
|
||
|
###########################################################################
|
||
|
# The master is just the standard implementation.
|
||
|
var master_kap140 =
|
||
|
contains(globals, "kap140_implementation") ? kap140_implementation : nil;
|
||
|
|
||
|
###########################################################################
|
||
|
var slave_kap140 = {
|
||
|
new : func(airoot) {
|
||
|
var obj = {};
|
||
|
obj.parents = [slave_kap140];
|
||
|
obj.root = airoot;
|
||
|
obj.base = props.globals.getNode("/autopilot/kap140/buttons", 1);
|
||
|
return obj;
|
||
|
},
|
||
|
apButton : func {
|
||
|
var p = me.base.getNode(ap_btn);
|
||
|
print("KAP140.AP");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
hdgButton : func {
|
||
|
var p = me.base.getNode(hdg_btn);
|
||
|
print("KAP140.HDG");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
navButton : func {
|
||
|
var p = me.base.getNode(nav_btn);
|
||
|
print("KAP140.NAV");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
aprButton : func {
|
||
|
var p = me.base.getNode(apr_btn);
|
||
|
print("KAP140.APR");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
altButton : func {
|
||
|
var p = me.base.getNode(alt_btn);
|
||
|
print("KAP140.ALT");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
revButton : func {
|
||
|
var p = me.base.getNode(rev_btn);
|
||
|
print("KAP140.REV");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
downButton : func {
|
||
|
var p = me.base.getNode(down_btn);
|
||
|
print("KAP140.DN");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
upButton : func {
|
||
|
var p = me.base.getNode(up_btn);
|
||
|
print("KAP140.UP");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
armButton : func {
|
||
|
var p = me.base.getNode(arm_btn);
|
||
|
print("KAP140.ARM");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
baroButtonPress : func {
|
||
|
var p = me.base.getNode(baro_press_btn);
|
||
|
print("KAP140.BARO_PRESS");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
baroButtonRelease : func {
|
||
|
var p = me.base.getNode(baro_release_btn);
|
||
|
print("KAP140.BARO_RELEASE");
|
||
|
if (!p.getValue()) {
|
||
|
p.setValue(1);
|
||
|
settimer(func { p.setValue(0); },
|
||
|
1.0);
|
||
|
}
|
||
|
},
|
||
|
knobSmallDown : func {
|
||
|
},
|
||
|
knobSmallUp : func {
|
||
|
},
|
||
|
knobLargeDown : func {
|
||
|
},
|
||
|
knobLargeUp : func {
|
||
|
},
|
||
|
};
|
||
|
|
||
|
###########################################################################
|
||
|
# The KAP140 pick animations default to master.
|
||
|
var kap140 = master_kap140;
|
||
|
|
||
|
###########################################################################
|
||
|
# API for dual control setup.
|
||
|
###########################################################################
|
||
|
|
||
|
###########################################################################
|
||
|
var make_master = func {
|
||
|
master_kap140 =
|
||
|
contains(globals, "kap140_implementation") ? kap140_implementation : nil;
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
var make_slave_to = func(airoot) {
|
||
|
kap140 = slave_kap140.new(airoot);
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
# Create aliases to drive the KAP 140 3d model in an AI/MP model.
|
||
|
var animate_aimodel = func(airoot) {
|
||
|
# var p = base ~ "/data-is-valid";
|
||
|
# airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
# Create a TDMEncoder node array for sending the current state to
|
||
|
# slaves.
|
||
|
var master_send_state = func {
|
||
|
return
|
||
|
[
|
||
|
];
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
# Create a SwitchDecoder action array for processing button presses
|
||
|
# from a slave.
|
||
|
var master_receive_slave_buttons = func {
|
||
|
return
|
||
|
[
|
||
|
func (b) {
|
||
|
if (b) { kap140.apButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.hdgButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.navButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.aprButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.altButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.revButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.downButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.upButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.armButton(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.baroButtonPress(); }
|
||
|
},
|
||
|
func (b) {
|
||
|
if (b) { kap140.baroButtonRelease(); }
|
||
|
}
|
||
|
];
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
# Create a TDMDecoder action array for processing the state
|
||
|
# from the master.
|
||
|
var slave_receive_master_state = func {
|
||
|
return
|
||
|
[
|
||
|
];
|
||
|
}
|
||
|
|
||
|
###########################################################################
|
||
|
# Create a SwitchEncoder node array for sending button presses
|
||
|
# to the master
|
||
|
var slave_send_buttons = func {
|
||
|
return
|
||
|
[
|
||
|
props.globals.getNode(buttons ~ ap_btn, 1),
|
||
|
props.globals.getNode(buttons ~ hdg_btn, 1),
|
||
|
props.globals.getNode(buttons ~ nav_btn, 1),
|
||
|
props.globals.getNode(buttons ~ apr_btn, 1),
|
||
|
props.globals.getNode(buttons ~ alt_btn, 1),
|
||
|
props.globals.getNode(buttons ~ rev_btn, 1),
|
||
|
props.globals.getNode(buttons ~ down_btn, 1),
|
||
|
props.globals.getNode(buttons ~ up_btn, 1),
|
||
|
props.globals.getNode(buttons ~ arm_btn, 1),
|
||
|
props.globals.getNode(buttons ~ baro_press_btn, 1),
|
||
|
props.globals.getNode(buttons ~ baro_release_btn, 1)
|
||
|
];
|
||
|
}
|