Merge branch 'master' of git://mapserver.flightgear.org/fgdata
This commit is contained in:
commit
b0e04def6e
52 changed files with 24121 additions and 4225 deletions
22
Aircraft/Generic/DualControl/AUTHORS
Normal file
22
Aircraft/Generic/DualControl/AUTHORS
Normal file
|
@ -0,0 +1,22 @@
|
|||
Anders Gidenstam (anders(at)gidenstam.org)
|
||||
- Dual control Nasal modules
|
||||
- Configuration of dual-control 3d instruments.
|
||||
|
||||
DualControl borrows content from the following authors' contributions
|
||||
to FlightGear:
|
||||
|
||||
Syd Adams - from Aircraft/Instruments-3d/
|
||||
- KY-196 Comm Radio.
|
||||
- VHF 22 Comm Radio.
|
||||
- VIR 32 Nav Radio.
|
||||
- KI-206 VOR Gauge.
|
||||
- KR-97 ADF Radio.
|
||||
- KI-227 ADF Gauge.
|
||||
|
||||
Torsten Dreyer - from Aircraft/SenceaII/Instruments-3d/
|
||||
- KX-165 Nav Comm Radio.
|
||||
- KR-87 ADF Radio.
|
||||
|
||||
Ron Jensen - from Aircraft/Instruments-3d
|
||||
- KAP140 Autopilot 3d.
|
||||
|
BIN
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl-62.png
Normal file
BIN
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl-62.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
380
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62-adf1.xml
Normal file
380
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62-adf1.xml
Normal file
|
@ -0,0 +1,380 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 62 ADF Control for ADF-462 receiver
|
||||
Active and preset displayed +
|
||||
4 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 190.0 - 1800.0 (normal)
|
||||
Strap option 2179.0 - 2185.0
|
||||
500 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl62.nas MUST be loaded as Nasal module ADF462.
|
||||
-->
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<path>ctl62.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>freq.002</object-name>
|
||||
<object-name>freq.003</object-name>
|
||||
<object-name>freq.dec</object-name>
|
||||
<object-name>freq.004</object-name>
|
||||
<object-name>freq.005</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>stby.002</object-name>
|
||||
<object-name>stby.003</object-name>
|
||||
<object-name>stby.dec</object-name>
|
||||
<object-name>stby.004</object-name>
|
||||
<object-name>stby.005</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
<greater-than>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<value>999.5</value>
|
||||
</greater-than>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
<greater-than>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<value>999.5</value>
|
||||
</greater-than>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>mem.annun</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CTL-62.pwr</object-name>
|
||||
<property>instrumentation/adf/serviceable</property>
|
||||
<interpolation>
|
||||
<entry><ind>0</ind><dep>0</dep></entry>
|
||||
<entry><ind>1.0</ind><dep>30</dep></entry>
|
||||
</interpolation>
|
||||
<center>
|
||||
<x-m>0.0</x-m>
|
||||
<y-m>-0.014</y-m>
|
||||
<z-m>-0.018</z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Active Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<factor>0.0001</factor>
|
||||
<step>1000</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.002</object-name>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.003</object-name>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.004</object-name>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.005</object-name>
|
||||
<property>instrumentation/adf/frequencies/selected-khz</property>
|
||||
<factor>1.0</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Preselected Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<factor>0.0001</factor>
|
||||
<step>1000</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.002</object-name>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.003</object-name>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.004</object-name>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.005</object-name>
|
||||
<property>instrumentation/adf/frequencies/standby-khz</property>
|
||||
<factor>1.0</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.05</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- OSG hotspots -->
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CTL-62.xfr</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.swap(0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.off</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>instrumentation/adf/serviceable</property>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.on</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>instrumentation/adf/serviceable</property>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.small</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.large</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, 10.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, -10.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, -10.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>ADF462.adjust_frequency(0, 10.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
2449
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62.ac
Normal file
2449
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62.ac
Normal file
File diff suppressed because it is too large
Load diff
229
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62.nas
Normal file
229
Aircraft/Generic/DualControl/Instruments/ADF-462/ctl62.nas
Normal file
|
@ -0,0 +1,229 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a ADF 462 radio 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 ADF462.
|
||||
#
|
||||
|
||||
# Slave button presses.
|
||||
var swap_btn = "frq-swap-btn";
|
||||
var freq_decS = "freq-decS-clicked";
|
||||
var freq_incS = "freq-incS-clicked";
|
||||
var freq_decL = "freq-decL-clicked";
|
||||
var freq_incL = "freq-incL-clicked";
|
||||
|
||||
# Settings
|
||||
var freq_selected = "frequencies/selected-khz";
|
||||
var freq_standby = "frequencies/standby-khz";
|
||||
|
||||
var adf_base = ["instrumentation/adf[0]",
|
||||
"instrumentation/adf[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_ctl62 = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_ctl62];
|
||||
obj.adf_base = props.globals.getNode(adf_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var tmp = me.adf_base.getNode(freq_selected).getValue();
|
||||
me.adf_base.getNode(freq_selected).setValue
|
||||
(me.adf_base.getNode(freq_standby).getValue());
|
||||
me.adf_base.getNode(freq_standby).setValue(tmp);
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.adf_base.getNode(freq_standby),
|
||||
d,
|
||||
190.0,
|
||||
1800.0);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_ctl62 = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_ctl62];
|
||||
obj.root = airoot;
|
||||
obj.adf_base = props.globals.getNode(adf_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var p = me.adf_base.getNode(swap_btn);
|
||||
print("ADF62[?].SWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 5.0) {
|
||||
p = (d < 0) ? me.adf_base.getNode(freq_decS)
|
||||
: me.adf_base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.adf_base.getNode(freq_decL)
|
||||
: me.adf_base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The ADF 462 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to().
|
||||
# Do NOT change ctl62 directly.
|
||||
var ctl62 = [master_ctl62.new(0), master_ctl62.new(1)];
|
||||
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations and dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - Adf#
|
||||
var make_master = func(n) {
|
||||
ctl62[n] = master_ctl62.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Adf#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
ctl62[n] = slave_ctl62.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Adf#
|
||||
var swap = func(n) {
|
||||
ctl62[n].swap();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Adf#
|
||||
# d - adjustment
|
||||
var adjust_frequency = func(n, d) {
|
||||
ctl62[n].adjust_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a radio 3d model in an AI/MP model.
|
||||
# n - Adf#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = "systems/electrical/outputs/adf["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = "instrumentation/adf["~ n ~"]/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = adf_base[n] ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = adf_base[n] ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - Adf#
|
||||
var master_send_state = func(n) {
|
||||
var b = props.globals.getNode(adf_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(freq_selected),
|
||||
b.getNode(freq_standby)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Adf#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
func (b) {
|
||||
if (b) { swap(n); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -10.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 10.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - Adf#
|
||||
var slave_receive_master_state = func(n) {
|
||||
var b = props.globals.getNode(adf_base[n]);
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
b.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
b.getNode(freq_standby).setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - Adf#
|
||||
var slave_send_buttons = func(n) {
|
||||
var b = props.globals.getNode(adf_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(swap_btn, 1),
|
||||
b.getNode(freq_decS, 1),
|
||||
b.getNode(freq_incS, 1),
|
||||
b.getNode(freq_decL, 1),
|
||||
b.getNode(freq_incL, 1),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
###########################################################################
|
||||
# (Not so) Generic frequency stepper.
|
||||
# f - frequency property
|
||||
# d - change
|
||||
# min - min frequency
|
||||
# max - max frequency
|
||||
var adjust_radio_frequency = func(f, d, min, max) {
|
||||
var old = f.getValue();
|
||||
var new = old + d;
|
||||
if (new < min - 0.05) {
|
||||
new = max + (new - min);
|
||||
if ((max - new) >= -d) new += -d;
|
||||
}
|
||||
if (new > max + 0.05) {
|
||||
new = min + (new - max);
|
||||
if ((new - min) >= d) new -= d;
|
||||
}
|
||||
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
||||
f.setValue(new);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<path>null.ac</path> <!-- A suitably empty AC3D file. -->
|
||||
|
||||
<model>
|
||||
<path>Aircraft/Instruments-3d/kap140/KAP140TwoAxisAlt.xml</path>
|
||||
</model>
|
||||
|
||||
<!-- Override OSG Hotspots for dual control -->
|
||||
<!-- Not even needed at this stage. -->
|
||||
</PropertyList>
|
330
Aircraft/Generic/DualControl/Instruments/KAP-140/kap140.nas
Normal file
330
Aircraft/Generic/DualControl/Instruments/KAP-140/kap140.nas
Normal file
|
@ -0,0 +1,330 @@
|
|||
###############################################################################
|
||||
##
|
||||
## 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)
|
||||
];
|
||||
}
|
3
Aircraft/Generic/DualControl/Instruments/KAP-140/null.ac
Normal file
3
Aircraft/Generic/DualControl/Instruments/KAP-140/null.ac
Normal file
|
@ -0,0 +1,3 @@
|
|||
AC3Db
|
||||
OBJECT poly
|
||||
kids 0
|
823
Aircraft/Generic/DualControl/Instruments/KDI-572/dme.ac
Normal file
823
Aircraft/Generic/DualControl/Instruments/KDI-572/dme.ac
Normal file
|
@ -0,0 +1,823 @@
|
|||
AC3Db
|
||||
MATERIAL "DefaultWhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 spec 0.5 0.5 0.5 shi 64 trans 0
|
||||
MATERIAL "illum" rgb 1 1 1 amb 1 1 1 emis 0.7 0.7 0.7 spec 0 0 0 shi 0 trans 0
|
||||
MATERIAL "glosswhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 spec 0.255556 0.255556 0.255556 shi 32 trans 0
|
||||
MATERIAL "flatpaint" rgb 0.8 0.8 0.8 amb 0.8 0.8 0.8 emis 0.051361 0.051361 0.051361 spec 0 0 0 shi 32 trans 0
|
||||
OBJECT world
|
||||
kids 13
|
||||
OBJECT poly
|
||||
name "DME.kt1"
|
||||
data 9
|
||||
Plane.145
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 0.002169
|
||||
0.001016 0.002312 0.002169
|
||||
0.001016 0.002312 0.007201
|
||||
0.001016 0.011226 0.007201
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.kt2"
|
||||
data 9
|
||||
Plane.146
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 -0.003798
|
||||
0.001016 0.002312 -0.003798
|
||||
0.001016 0.002312 0.001234
|
||||
0.001016 0.011226 0.001234
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.kt3"
|
||||
data 9
|
||||
Plane.147
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 -0.009766
|
||||
0.001016 0.002312 -0.009766
|
||||
0.001016 0.002312 -0.004733
|
||||
0.001016 0.011226 -0.004733
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.mn1"
|
||||
data 9
|
||||
Plane.149
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 -0.024916
|
||||
0.001016 0.002312 -0.024916
|
||||
0.001016 0.002312 -0.019884
|
||||
0.001016 0.011226 -0.019884
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.mn2"
|
||||
data 9
|
||||
Plane.148
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 -0.030883
|
||||
0.001016 0.002312 -0.030883
|
||||
0.001016 0.002312 -0.025851
|
||||
0.001016 0.011226 -0.025851
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.nm"
|
||||
data 9
|
||||
Plane.150
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.000959 0.003707 0.022752
|
||||
0.000959 0.002877 0.022752
|
||||
0.000959 0.002877 0.023547
|
||||
0.000959 0.003707 0.023547
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0709507837892 0.181225210428
|
||||
3 0.0457188934088 0.181225210428
|
||||
2 0.0457188934088 0.166461586952
|
||||
1 0.0709507837892 0.166461586952
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.nm1"
|
||||
data 9
|
||||
Plane.131
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 0.02914
|
||||
0.001016 0.002312 0.02914
|
||||
0.001016 0.002312 0.034172
|
||||
0.001016 0.011226 0.034172
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.nm2"
|
||||
data 9
|
||||
Plane.143
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 0.023676
|
||||
0.001016 0.002312 0.023676
|
||||
0.001016 0.002312 0.028708
|
||||
0.001016 0.011226 0.028708
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DME.nm3"
|
||||
data 9
|
||||
Plane.151
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 4
|
||||
0.001016 0.011226 0.017181
|
||||
0.001016 0.002312 0.017181
|
||||
0.001016 0.002312 0.022214
|
||||
0.001016 0.011226 0.022214
|
||||
numsurf 1
|
||||
SURF 0x00
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.0838298201561 0.199461504817
|
||||
3 0.0236648730934 0.199461504817
|
||||
2 0.0236648730934 0.00404679775238
|
||||
1 0.0838298201561 0.00404679775238
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "DMEswitch"
|
||||
data 8
|
||||
Cylinder
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 40.000000
|
||||
numvert 28
|
||||
0.001039 -0.006427 0.003573
|
||||
0.001039 -0.005119 0.001308
|
||||
0.001039 -0.005119 -0.001308
|
||||
0.001039 -0.006427 -0.003573
|
||||
0.001039 -0.008692 -0.004881
|
||||
0.001039 -0.011308 -0.004881
|
||||
0.001039 -0.013573 -0.003573
|
||||
0.001039 -0.014881 -0.001308
|
||||
0.001039 -0.014881 0.001308
|
||||
0.001039 -0.013573 0.003573
|
||||
0.001039 -0.011308 0.004881
|
||||
0.001039 -0.008692 0.004881
|
||||
0.004499 -0.006686 0.003314
|
||||
0.004499 -0.005473 0.001213
|
||||
0.004499 -0.005473 -0.001213
|
||||
0.004499 -0.006686 -0.003314
|
||||
0.004499 -0.008787 -0.004527
|
||||
0.004499 -0.011213 -0.004527
|
||||
0.004499 -0.013314 -0.003314
|
||||
0.004499 -0.014527 -0.001213
|
||||
0.004499 -0.014527 0.001213
|
||||
0.004499 -0.013314 0.003314
|
||||
0.004499 -0.011213 0.004527
|
||||
0.004499 -0.008787 0.004527
|
||||
0.007779 -0.008787 -0.004193
|
||||
0.007779 -0.011213 -0.004193
|
||||
0.007779 -0.011213 0.004193
|
||||
0.007779 -0.008787 0.004193
|
||||
numsurf 21
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
0 0.535729765892 0.453892558813
|
||||
12 0.53325176239 0.448936551809
|
||||
13 0.544875144958 0.408671677113
|
||||
1 0.548260271549 0.410485655069
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
1 0.548260271549 0.410485655069
|
||||
13 0.544875144958 0.408671677113
|
||||
14 0.544875144958 0.362177878618
|
||||
2 0.548260271549 0.36036375165
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
2 0.548260271549 0.36036375165
|
||||
14 0.544875144958 0.362177878618
|
||||
15 0.533251881599 0.321913033724
|
||||
3 0.535729765892 0.316956788301
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
3 0.535729765892 0.316956788301
|
||||
15 0.533251881599 0.321913033724
|
||||
16 0.513119459152 0.298666030169
|
||||
4 0.514026403427 0.291895896196
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
4 0.514026403427 0.291895896196
|
||||
16 0.513119459152 0.298666030169
|
||||
17 0.489872395992 0.298665940762
|
||||
5 0.488965392113 0.291895896196
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
5 0.488965392113 0.291895896196
|
||||
17 0.489872395992 0.298665940762
|
||||
18 0.46974003315 0.321912825108
|
||||
6 0.467261910439 0.316956788301
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
6 0.467261910439 0.316956788301
|
||||
18 0.46974003315 0.321912825108
|
||||
19 0.458116590977 0.3621776402
|
||||
7 0.454731464386 0.360363692045
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
7 0.454731464386 0.360363692045
|
||||
19 0.458116590977 0.3621776402
|
||||
20 0.458116590977 0.408671438694
|
||||
8 0.454731464386 0.410485595465
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
8 0.454731464386 0.410485595465
|
||||
20 0.458116590977 0.408671438694
|
||||
21 0.46974003315 0.448936372995
|
||||
9 0.467261910439 0.453892499208
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
9 0.467261910439 0.453892499208
|
||||
21 0.46974003315 0.448936372995
|
||||
22 0.489872336388 0.472183257341
|
||||
10 0.488965272903 0.478953510523
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
10 0.488965272903 0.463854044676
|
||||
22 0.489872336388 0.457083791494
|
||||
23 0.513119280338 0.457083910704
|
||||
11 0.514026403427 0.463854044676
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
12 0.53325176239 0.448936551809
|
||||
0 0.535729765892 0.453892558813
|
||||
11 0.514026403427 0.478953510523
|
||||
23 0.513119280338 0.472183376551
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
18 0.46974003315 0.321912825108
|
||||
21 0.46974003315 0.448936372995
|
||||
20 0.458116590977 0.408671438694
|
||||
19 0.458116590977 0.3621776402
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
17 0.489872395992 0.298665940762
|
||||
22 0.489872336388 0.472183257341
|
||||
21 0.46974003315 0.448936372995
|
||||
18 0.46974003315 0.321912825108
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
12 0.53325176239 0.448936551809
|
||||
15 0.533251881599 0.321913033724
|
||||
14 0.544875144958 0.362177878618
|
||||
13 0.544875144958 0.408671677113
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
12 0.53325176239 0.448936551809
|
||||
23 0.513119280338 0.472183376551
|
||||
16 0.513119459152 0.298666030169
|
||||
15 0.533251881599 0.321913033724
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
17 0.489872395992 0.298665940762
|
||||
16 0.513119459152 0.298666030169
|
||||
24 0.513119459152 0.30507221818
|
||||
25 0.489872395992 0.305072128773
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
23 0.513119280338 0.457083910704
|
||||
22 0.489872336388 0.457083791494
|
||||
26 0.489872336388 0.450677603483
|
||||
27 0.513119280338 0.450677722692
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
22 0.489872336388 0.472183257341
|
||||
17 0.489872395992 0.298665940762
|
||||
25 0.489872395992 0.305072128773
|
||||
26 0.489872336388 0.46577706933
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
16 0.513119459152 0.298666030169
|
||||
23 0.513119280338 0.472183376551
|
||||
27 0.513119280338 0.46577718854
|
||||
24 0.513119459152 0.30507221818
|
||||
SURF 0x10
|
||||
mat 2
|
||||
refs 4
|
||||
25 0.489872395992 0.305072128773
|
||||
24 0.513119459152 0.30507221818
|
||||
27 0.513119280338 0.46577718854
|
||||
26 0.489872336388 0.46577706933
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "dmebezel"
|
||||
data 8
|
||||
Mesh.079
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 56
|
||||
0.000842 0.007242 -0.039319
|
||||
0.000842 -0.007229 -0.039331
|
||||
0.000842 -0.014511 -0.032798
|
||||
0.000842 -0.014515 0.032738
|
||||
0.000842 -0.007242 0.039319
|
||||
0.000842 0.007229 0.039331
|
||||
0.000843 0.01451 0.032798
|
||||
0.000842 0.014515 -0.032738
|
||||
0.002247 0.007242 -0.039319
|
||||
0.002247 0.014515 -0.032738
|
||||
0.002247 0.01451 0.032798
|
||||
0.002246 0.007229 0.039331
|
||||
0.002246 -0.007242 0.039319
|
||||
0.002247 -0.007229 -0.039331
|
||||
0.002247 -0.014516 0.032738
|
||||
0.002247 -0.014511 -0.032798
|
||||
0.002246 0.01607 -0.033721
|
||||
0.002247 0.008025 -0.04088
|
||||
0.002246 0.016065 0.033782
|
||||
0.002247 0.00801 0.040893
|
||||
0.002247 -0.008025 0.04088
|
||||
0.002247 -0.00801 -0.040894
|
||||
0.002247 -0.01607 0.03372
|
||||
0.002247 -0.016065 -0.033782
|
||||
0.000843 -6e-06 0.039325
|
||||
0.000842 7e-06 -0.039325
|
||||
0.00165 0.01607 -0.033721
|
||||
0.00165 0.008025 -0.04088
|
||||
0.00165 0.016065 0.033782
|
||||
0.00165 0.00801 0.040893
|
||||
0.00165 -0.008025 0.04088
|
||||
0.00165 -0.00801 -0.040894
|
||||
0.00165 -0.01607 0.03372
|
||||
0.00165 -0.016065 -0.033782
|
||||
0.00165 0.017447 -0.043733
|
||||
0.00165 0.016138 -0.044932
|
||||
0.00165 0.017442 0.043812
|
||||
0.00165 0.016107 0.044946
|
||||
0.00165 -0.016138 0.044932
|
||||
0.00165 -0.016108 -0.044947
|
||||
0.00165 -0.017448 0.043732
|
||||
0.00165 -0.017442 -0.043812
|
||||
0.000147 0.017447 -0.043733
|
||||
0.000147 0.016138 -0.044932
|
||||
0.000147 0.017442 0.043812
|
||||
0.000147 0.016107 0.044946
|
||||
0.000147 -0.016138 0.044932
|
||||
0.000147 -0.016108 -0.044947
|
||||
0.000147 -0.017448 0.043732
|
||||
0.000147 -0.017442 -0.043812
|
||||
0.000842 -0.007229 -0.039331
|
||||
0.000842 -0.014511 -0.032798
|
||||
0.000842 -0.014515 0.032738
|
||||
0.000842 -0.007242 0.039319
|
||||
0.000843 -6e-06 0.039325
|
||||
0.000842 7e-06 -0.039325
|
||||
numsurf 46
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
7 0.752499580383 0.500000059605
|
||||
0 0.752499580383 0.400000065565
|
||||
8 0.852499604225 0.400000065565
|
||||
9 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
6 0.752499580383 0.500000059605
|
||||
7 0.752499580383 0.400000065565
|
||||
9 0.852499604225 0.400000065565
|
||||
10 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
5 0.752499580383 0.500000059605
|
||||
6 0.752499580383 0.400000065565
|
||||
10 0.852499604225 0.400000065565
|
||||
11 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
4 0.752499580383 0.500000059605
|
||||
24 0.752499580383 0.400000065565
|
||||
12 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
3 0.752499580383 0.500000059605
|
||||
4 0.752499580383 0.400000065565
|
||||
12 0.852499604225 0.400000065565
|
||||
14 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
2 0.752499580383 0.500000059605
|
||||
3 0.752499580383 0.400000065565
|
||||
14 0.852499604225 0.400000065565
|
||||
15 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
1 0.752499580383 0.500000059605
|
||||
2 0.752499580383 0.400000065565
|
||||
15 0.852499604225 0.400000065565
|
||||
13 0.852499604225 0.500000059605
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
9 0.516570031643 0.94054287672
|
||||
8 0.516570031643 0.927807867527
|
||||
17 0.529305040836 0.927807867527
|
||||
16 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
10 0.516570031643 0.94054287672
|
||||
9 0.516570031643 0.927807867527
|
||||
16 0.529305040836 0.927807867527
|
||||
18 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
11 0.516570031643 0.94054287672
|
||||
10 0.516570031643 0.927807867527
|
||||
18 0.529305040836 0.927807867527
|
||||
19 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
12 0.516570031643 0.94054287672
|
||||
11 0.516570031643 0.927807867527
|
||||
19 0.529305040836 0.927807867527
|
||||
20 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
8 0.516570031643 0.94054287672
|
||||
13 0.516570031643 0.927807867527
|
||||
21 0.529305040836 0.927807867527
|
||||
17 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
14 0.516570031643 0.94054287672
|
||||
12 0.516570031643 0.927807867527
|
||||
20 0.529305040836 0.927807867527
|
||||
22 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
15 0.516570031643 0.94054287672
|
||||
14 0.516570031643 0.927807867527
|
||||
22 0.529305040836 0.927807867527
|
||||
23 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
13 0.516570031643 0.94054287672
|
||||
15 0.516570031643 0.927807867527
|
||||
23 0.529305040836 0.927807867527
|
||||
21 0.529305040836 0.94054287672
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
0 0.752499580383 0.500000059605
|
||||
25 0.752499580383 0.400000065565
|
||||
13 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
0 0.752499580383 0.500000059605
|
||||
13 0.752499580383 0.400000065565
|
||||
8 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
5 0.752499580383 0.500000059605
|
||||
11 0.752499580383 0.400000065565
|
||||
12 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
25 0.752499580383 0.500000059605
|
||||
1 0.752499580383 0.400000065565
|
||||
13 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 3
|
||||
24 0.752499580383 0.500000059605
|
||||
5 0.752499580383 0.400000065565
|
||||
12 0.852499604225 0.400000065565
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
16 0.928124308586 0.311250269413
|
||||
17 0.928124308586 0.27125030756
|
||||
27 0.968124330044 0.27125030756
|
||||
26 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
18 0.928124308586 0.311250269413
|
||||
16 0.928124308586 0.27125030756
|
||||
26 0.968124330044 0.27125030756
|
||||
28 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
19 0.928124308586 0.311250269413
|
||||
18 0.928124308586 0.27125030756
|
||||
28 0.968124330044 0.27125030756
|
||||
29 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
20 0.928124308586 0.311250269413
|
||||
19 0.928124308586 0.27125030756
|
||||
29 0.968124330044 0.27125030756
|
||||
30 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
17 0.928124308586 0.311250269413
|
||||
21 0.928124308586 0.27125030756
|
||||
31 0.968124330044 0.27125030756
|
||||
27 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
22 0.928124308586 0.311250269413
|
||||
20 0.928124308586 0.27125030756
|
||||
30 0.968124330044 0.27125030756
|
||||
32 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
23 0.928124308586 0.311250269413
|
||||
22 0.928124308586 0.27125030756
|
||||
32 0.968124330044 0.27125030756
|
||||
33 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
21 0.928124308586 0.311250269413
|
||||
23 0.928124308586 0.27125030756
|
||||
33 0.968124330044 0.27125030756
|
||||
31 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
26 0.928124308586 0.311250269413
|
||||
27 0.928124308586 0.27125030756
|
||||
35 0.968124330044 0.27125030756
|
||||
34 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
28 0.928124308586 0.311250269413
|
||||
26 0.928124308586 0.27125030756
|
||||
34 0.968124330044 0.27125030756
|
||||
36 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
29 0.928124308586 0.311250269413
|
||||
28 0.928124308586 0.27125030756
|
||||
36 0.968124330044 0.27125030756
|
||||
37 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
30 0.928124308586 0.311250269413
|
||||
29 0.928124308586 0.27125030756
|
||||
37 0.968124330044 0.27125030756
|
||||
38 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
27 0.928124308586 0.311250269413
|
||||
31 0.928124308586 0.27125030756
|
||||
39 0.968124330044 0.27125030756
|
||||
35 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
32 0.928124308586 0.311250269413
|
||||
30 0.928124308586 0.27125030756
|
||||
38 0.968124330044 0.27125030756
|
||||
40 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
33 0.928124308586 0.311250269413
|
||||
32 0.928124308586 0.27125030756
|
||||
40 0.968124330044 0.27125030756
|
||||
41 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
31 0.928124308586 0.311250269413
|
||||
33 0.928124308586 0.27125030756
|
||||
41 0.968124330044 0.27125030756
|
||||
39 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
34 0.928124308586 0.311250269413
|
||||
35 0.928124308586 0.27125030756
|
||||
43 0.968124330044 0.27125030756
|
||||
42 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
36 0.928124308586 0.311250269413
|
||||
34 0.928124308586 0.27125030756
|
||||
42 0.968124330044 0.27125030756
|
||||
44 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
37 0.928124308586 0.311250269413
|
||||
36 0.928124308586 0.27125030756
|
||||
44 0.968124330044 0.27125030756
|
||||
45 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
38 0.928124308586 0.311250269413
|
||||
37 0.928124308586 0.27125030756
|
||||
45 0.968124330044 0.27125030756
|
||||
46 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
35 0.928124308586 0.311250269413
|
||||
39 0.928124308586 0.27125030756
|
||||
47 0.968124330044 0.27125030756
|
||||
43 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
40 0.928124308586 0.311250269413
|
||||
38 0.928124308586 0.27125030756
|
||||
46 0.968124330044 0.27125030756
|
||||
48 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
41 0.928124308586 0.311250269413
|
||||
40 0.928124308586 0.27125030756
|
||||
48 0.968124330044 0.27125030756
|
||||
49 0.968124330044 0.311250269413
|
||||
SURF 0x00
|
||||
mat 3
|
||||
refs 4
|
||||
39 0.928124308586 0.311250269413
|
||||
41 0.928124308586 0.27125030756
|
||||
49 0.968124330044 0.27125030756
|
||||
47 0.968124330044 0.311250269413
|
||||
SURF 0x10
|
||||
mat 3
|
||||
refs 4
|
||||
50 0.920733690262 0.440070271492
|
||||
53 0.0834924578667 0.439790010452
|
||||
52 0.153548210859 0.284956693649
|
||||
51 0.851188838482 0.285044133663
|
||||
SURF 0x10
|
||||
mat 3
|
||||
refs 4
|
||||
50 0.920733690262 0.440070271492
|
||||
55 0.920669853687 0.594127893448
|
||||
54 0.0834285616875 0.593843877316
|
||||
53 0.0834924578667 0.439790010452
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "dmeface"
|
||||
data 8
|
||||
Mesh.094
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 6
|
||||
0.000842 7e-06 -0.039325
|
||||
0.000843 -6e-06 0.039325
|
||||
0.000842 0.014515 -0.032738
|
||||
0.000843 0.01451 0.032798
|
||||
0.000842 0.007229 0.039331
|
||||
0.000842 0.007242 -0.039319
|
||||
numsurf 2
|
||||
SURF 0x10
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.922852396965 0.604025781155
|
||||
5 0.922788202763 0.758947312832
|
||||
4 0.0807167291641 0.758664429188
|
||||
1 0.0807809233665 0.603740155697
|
||||
SURF 0x10
|
||||
mat 1
|
||||
refs 4
|
||||
5 0.922788202763 0.758947312832
|
||||
2 0.848569154739 0.914694130421
|
||||
3 0.154421895742 0.914586186409
|
||||
4 0.0807167291641 0.758664429188
|
||||
kids 0
|
||||
OBJECT poly
|
||||
name "dmeface.001"
|
||||
data 8
|
||||
Mesh.354
|
||||
texture "dme.png"
|
||||
texrep 1 1
|
||||
crease 30.000000
|
||||
numvert 6
|
||||
0.000706 1.1e-05 -0.039929
|
||||
0.000707 -3e-06 0.039929
|
||||
0.000768 0.015102 -0.03324
|
||||
0.000768 0.015097 0.033301
|
||||
0.000737 0.007523 0.039935
|
||||
0.000737 0.007536 -0.039922
|
||||
numsurf 2
|
||||
SURF 0x10
|
||||
mat 1
|
||||
refs 4
|
||||
0 0.610067427158 0.813914358616
|
||||
5 0.61005282402 0.849155306816
|
||||
4 0.41850155592 0.849090993404
|
||||
1 0.418516159058 0.813849389553
|
||||
SURF 0x10
|
||||
mat 1
|
||||
refs 4
|
||||
5 0.61005282402 0.849155306816
|
||||
2 0.593169748783 0.884584009647
|
||||
3 0.435267746449 0.884559452534
|
||||
4 0.41850155592 0.849090993404
|
||||
kids 0
|
BIN
Aircraft/Generic/DualControl/Instruments/KDI-572/dme.png
Normal file
BIN
Aircraft/Generic/DualControl/Instruments/KDI-572/dme.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
66
Aircraft/Generic/DualControl/Instruments/KDI-572/kdi572.nas
Normal file
66
Aircraft/Generic/DualControl/Instruments/KDI-572/kdi572.nas
Normal file
|
@ -0,0 +1,66 @@
|
|||
###############################################################################
|
||||
## $Id$
|
||||
##
|
||||
## Nasal for KDI 572 DME.
|
||||
##
|
||||
## Copyright (C) 2006 - 2008 Syd Adams
|
||||
## Adapted for dual control by Anders Gidenstam
|
||||
##
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
# Note:
|
||||
# This module MUST be loaded as KDI572.
|
||||
#
|
||||
|
||||
var base = ["instrumentation/dme[0]",
|
||||
"instrumentation/dme[1]"];
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations.
|
||||
###########################################################################
|
||||
|
||||
var dme_step = func(stp) {
|
||||
var switch= getprop("instrumentation/dme/switch-position");
|
||||
switch += stp;
|
||||
if (switch >3) switch=3;
|
||||
if (switch <0) switch=0;
|
||||
setprop("instrumentation/dme/switch-position", switch);
|
||||
|
||||
if (switch==0) {
|
||||
setprop("instrumentation/dme/frequencies/source",
|
||||
"instrumentation/dme/frequencies/selected-mhz");
|
||||
} elsif (switch==1) {
|
||||
setprop("instrumentation/dme/frequencies/source",
|
||||
"instrumentation/nav[0]/frequencies/selected-mhz");
|
||||
} elsif (switch==2) {
|
||||
setprop("instrumentation/dme/frequencies/source",
|
||||
"instrumentation/dme/frequencies/selected-mhz");
|
||||
} elsif (switch==3) {
|
||||
setprop("instrumentation/dme/frequencies/source",
|
||||
"instrumentation/nav[1]/frequencies/selected-mhz");
|
||||
}
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# API for dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a KDI-572 3d model in an AI/MP model.
|
||||
# n - unit#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = "systems/electrical/outputs/dme";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/switch-position";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/in-range";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/indicated-distance-nm";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/indicated-ground-speed-kt";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/indicated-time-min";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
228
Aircraft/Generic/DualControl/Instruments/KDI-572/kdi572.xml
Normal file
228
Aircraft/Generic/DualControl/Instruments/KDI-572/kdi572.xml
Normal file
|
@ -0,0 +1,228 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Author : Syd Adams
|
||||
KDI-572 DME Indicator
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>dme.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>dmeface</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/dme</property>
|
||||
<value>8</value>
|
||||
</greater-than>
|
||||
<greater-than>
|
||||
<property>instrumentation/dme/switch-position</property>
|
||||
<value>0</value>
|
||||
</greater-than>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>DME.nm</object-name>
|
||||
<object-name>DME.nm1</object-name>
|
||||
<object-name>DME.nm2</object-name>
|
||||
<object-name>DME.nm3</object-name>
|
||||
<object-name>DME.kt1</object-name>
|
||||
<object-name>DME.kt2</object-name>
|
||||
<object-name>DME.kt3</object-name>
|
||||
<object-name>DME.mn1</object-name>
|
||||
<object-name>DME.mn2</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/dme</property>
|
||||
<value>8</value>
|
||||
</greater-than>
|
||||
<property>instrumentation/dme/in-range</property>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>DMEswitch</object-name>
|
||||
<property>instrumentation/dme/switch-position</property>
|
||||
<interpolation>
|
||||
<entry>
|
||||
<ind>0</ind><dep>0.0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>1</ind><dep>35.0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>2</ind><dep>90.0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>3</ind><dep>150.0</dep>
|
||||
</entry>
|
||||
</interpolation>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0</x-m>
|
||||
<y-m>0</y-m>
|
||||
<z-m>-0.010</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<!-- distance-->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.nm1</object-name>
|
||||
<property>instrumentation/dme/indicated-distance-nm</property>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.nm2</object-name>
|
||||
<property>instrumentation/dme/indicated-distance-nm</property>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.nm3</object-name>
|
||||
<property>instrumentation/dme/indicated-distance-nm</property>
|
||||
<factor>1.0</factor>
|
||||
<step>0.1</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- speed-->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.kt1</object-name>
|
||||
<property>instrumentation/dme/indicated-ground-speed-kt</property>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.kt2</object-name>
|
||||
<property>instrumentation/dme/indicated-ground-speed-kt</property>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.kt3</object-name>
|
||||
<property>instrumentation/dme/indicated-ground-speed-kt</property>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- time-->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.mn1</object-name>
|
||||
<property>instrumentation/dme/indicated-time-min</property>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>DME.mn2</object-name>
|
||||
<property>instrumentation/dme/indicated-time-min</property>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Pick animations -->
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>DMEswitch</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KDI572.dme_step(1)</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KDI572.dme_step(-1)</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KDI572.dme_step(-1)</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KDI572.dme_step(1)</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
176
Aircraft/Generic/DualControl/Instruments/KI-206/ki206-1.xml
Normal file
176
Aircraft/Generic/DualControl/Instruments/KI-206/ki206-1.xml
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- KI 206
|
||||
Bendix/King VOR / LOC / Glideslope Indicator
|
||||
Syd Adams
|
||||
Anders Gidenstam (pick animations)
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>Aircraft/Instruments-3d/ki206/ki206.ac</path>
|
||||
<texture-path>Aircraft/Instruments-3d/ki206/</texture-path>
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>KI206.gsflag</object-name>
|
||||
<object-name>KI206.toflag</object-name>
|
||||
<object-name>KI206.fromflag</object-name>
|
||||
<object-name>KI206.navflag</object-name>
|
||||
<object-name>KI206.face</object-name>
|
||||
<object-name>KI206card</object-name>
|
||||
<object-name>KI206.locneedle</object-name>
|
||||
<object-name>KI206.gsneedle</object-name>
|
||||
<object-name>KI206.knob</object-name>
|
||||
<emission>
|
||||
<red>0.8</red>
|
||||
<green>0.4</green>
|
||||
<blue>0.2</blue>
|
||||
<factor-prop>/systems/electrical/outputs/instrument-lights</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.navflag</object-name>
|
||||
<condition>
|
||||
<or>
|
||||
<not>
|
||||
<property>instrumentation/nav[0]/data-is-valid</property>
|
||||
</not>
|
||||
<less-than>
|
||||
<property>systems/electrical/outputs/nav[0]</property>
|
||||
<value>0.1</value>
|
||||
</less-than>
|
||||
<not>
|
||||
<property>instrumentation/nav[0]/in-range</property>
|
||||
</not>
|
||||
</or>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.gsflag</object-name>
|
||||
<condition>
|
||||
<or>
|
||||
<not>
|
||||
<property>instrumentation/nav[0]/has-gs</property>
|
||||
</not>
|
||||
<less-than>
|
||||
<property>systems/electrical/outputs/nav[0]</property>
|
||||
<value>0.1</value>
|
||||
</less-than>
|
||||
<greater-than>
|
||||
<property>instrumentation/nav[0]/in-range</property>
|
||||
<value>30000</value>
|
||||
</greater-than>
|
||||
</or>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.toflag</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/nav[0]/to-flag</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.fromflag</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/nav[0]/from-flag</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>KI206card</object-name>
|
||||
<property>instrumentation/nav[0]/radials/selected-deg</property>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>KI206.locneedle</object-name>
|
||||
<property>instrumentation/nav[0]/heading-needle-deflection</property>
|
||||
<interpolation>
|
||||
<entry><ind>-10.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>0.0</ind><dep>0.0</dep></entry>
|
||||
<entry><ind>10.0</ind><dep>0.0113</dep></entry>
|
||||
</interpolation>
|
||||
<axis>
|
||||
<x>0.0</x>
|
||||
<y>1.0</y>
|
||||
<z>0.0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>KI206.gsneedle</object-name>
|
||||
<property>instrumentation/nav[0]/gs-needle-deflection</property>
|
||||
<interpolation>
|
||||
<entry><ind>-9999.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>-10.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>0.0</ind><dep>0.0</dep></entry>
|
||||
<entry><ind>10.0</ind><dep>0.0113</dep></entry>
|
||||
<entry><ind>9999.0</ind><dep>0.0113</dep></entry>
|
||||
</interpolation>
|
||||
<axis>
|
||||
<x>0.0</x>
|
||||
<y>0.0</y>
|
||||
<z>1.0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>KI206.knob</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
176
Aircraft/Generic/DualControl/Instruments/KI-206/ki206-2.xml
Normal file
176
Aircraft/Generic/DualControl/Instruments/KI-206/ki206-2.xml
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- KI 206
|
||||
Bendix/King VOR / LOC / Glideslope Indicator
|
||||
Syd Adams
|
||||
Anders Gidenstam (pick animations)
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>Aircraft/Instruments-3d/ki206/ki206.ac</path>
|
||||
<texture-path>Aircraft/Instruments-3d/ki206/</texture-path>
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>KI206.gsflag</object-name>
|
||||
<object-name>KI206.toflag</object-name>
|
||||
<object-name>KI206.fromflag</object-name>
|
||||
<object-name>KI206.navflag</object-name>
|
||||
<object-name>KI206.face</object-name>
|
||||
<object-name>KI206card</object-name>
|
||||
<object-name>KI206.locneedle</object-name>
|
||||
<object-name>KI206.gsneedle</object-name>
|
||||
<object-name>KI206.knob</object-name>
|
||||
<emission>
|
||||
<red>0.8</red>
|
||||
<green>0.4</green>
|
||||
<blue>0.2</blue>
|
||||
<factor-prop>/systems/electrical/outputs/instrument-lights</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.navflag</object-name>
|
||||
<condition>
|
||||
<or>
|
||||
<not>
|
||||
<property>instrumentation/nav[1]/data-is-valid</property>
|
||||
</not>
|
||||
<less-than>
|
||||
<property>systems/electrical/outputs/nav[1]</property>
|
||||
<value>0.1</value>
|
||||
</less-than>
|
||||
<not>
|
||||
<property>instrumentation/nav[1]/in-range</property>
|
||||
</not>
|
||||
</or>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.gsflag</object-name>
|
||||
<condition>
|
||||
<or>
|
||||
<not>
|
||||
<property>instrumentation/nav[1]/has-gs</property>
|
||||
</not>
|
||||
<less-than>
|
||||
<property>systems/electrical/outputs/nav[1]</property>
|
||||
<value>0.1</value>
|
||||
</less-than>
|
||||
<greater-than>
|
||||
<property>instrumentation/nav[1]/in-range</property>
|
||||
<value>30000</value>
|
||||
</greater-than>
|
||||
</or>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.toflag</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/nav[1]/to-flag</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>KI206.fromflag</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/nav[1]/from-flag</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>KI206card</object-name>
|
||||
<property>instrumentation/nav[1]/radials/selected-deg</property>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>KI206.locneedle</object-name>
|
||||
<property>instrumentation/nav[1]/heading-needle-deflection</property>
|
||||
<interpolation>
|
||||
<entry><ind>-10.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>0.0</ind><dep>0.0</dep></entry>
|
||||
<entry><ind>10.0</ind><dep>0.0113</dep></entry>
|
||||
</interpolation>
|
||||
<axis>
|
||||
<x>0.0</x>
|
||||
<y>1.0</y>
|
||||
<z>0.0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>KI206.gsneedle</object-name>
|
||||
<property>instrumentation/nav[1]/gs-needle-deflection</property>
|
||||
<interpolation>
|
||||
<entry><ind>-9999.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>-10.0</ind><dep>-0.0113</dep></entry>
|
||||
<entry><ind>0.0</ind><dep>0.0</dep></entry>
|
||||
<entry><ind>10.0</ind><dep>0.0113</dep></entry>
|
||||
<entry><ind>9999.0</ind><dep>0.0113</dep></entry>
|
||||
</interpolation>
|
||||
<axis>
|
||||
<x>0.0</x>
|
||||
<y>0.0</y>
|
||||
<z>1.0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>KI206.knob</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<name>click</name>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<interval-sec>0.1</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KI206.adjust_radial(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
166
Aircraft/Generic/DualControl/Instruments/KI-206/ki206.nas
Normal file
166
Aircraft/Generic/DualControl/Instruments/KI-206/ki206.nas
Normal file
|
@ -0,0 +1,166 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a KI-206 VOR indicator over the multiplayer
|
||||
## network.
|
||||
##
|
||||
## Copyright (C) 2007 - 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 KI206.
|
||||
|
||||
# Slave button presses.
|
||||
var radial_decS = "radial-decS-clicked";
|
||||
var radial_incS = "radial-incS-clicked";
|
||||
# Only one step size implemented.
|
||||
|
||||
var selected_radial = "radials/selected-deg";
|
||||
var base = ["instrumentation/nav[0]",
|
||||
"instrumentation/nav[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_ki206 = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_ki206];
|
||||
obj.base = props.globals.getNode(base[n]);
|
||||
return obj;
|
||||
},
|
||||
adjust_radial : func(d) {
|
||||
p = me.base.getNode(selected_radial);
|
||||
var v = p.getValue() + d;
|
||||
if (v < 0) { v += 360; };
|
||||
if (v > 360) { v -= 360; };
|
||||
p.setValue(v);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_ki206 = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_ki206];
|
||||
obj.root = airoot;
|
||||
obj.base = props.globals.getNode(base[n]);
|
||||
return obj;
|
||||
},
|
||||
adjust_radial : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 0.99) {
|
||||
p = (d < 0) ? me.base.getNode(radial_decS)
|
||||
: me.base.getNode(radial_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.base.getNode(radial_decS)
|
||||
: me.base.getNode(radial_incS);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The KI-206 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to(). Do NOT change ki206 directly.
|
||||
var ki206 = [master_ki206.new(0), master_ki206.new(1)];
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations and dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
var make_master = func(n) {
|
||||
ki206[n] = master_ki206.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
ki206[n] = KI206.slave_ki206.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
# d - adjustment delta
|
||||
var adjust_radial = func(n, d) {
|
||||
ki206[n].adjust_radial(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive the KI 206 3d model in an AI/MP model.
|
||||
# n - Nav#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = base[n] ~ "/data-is-valid";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/in-range";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/has-gs";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/to-flag";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/from-flag";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/" ~ selected_radial;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/heading-needle-deflection";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/gs-needle-deflection";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - Nav#
|
||||
var master_send_state = func(n) {
|
||||
return
|
||||
[
|
||||
props.globals.getNode(base[n] ~ "/" ~ selected_radial)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Nav#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
func (b) {
|
||||
if (b) { KI206.adjust_radial(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { KI206.adjust_radial(n, 1.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - Nav#
|
||||
var slave_receive_master_state = func(n) {
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
props.globals.getNode(base[n] ~ "/" ~ selected_radial).setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - Nav#
|
||||
var slave_send_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
props.globals.getNode(base[n] ~ "/" ~ radial_decS, 1),
|
||||
props.globals.getNode(base[n] ~ "/" ~ radial_incS, 1),
|
||||
];
|
||||
}
|
362
Aircraft/Generic/DualControl/Instruments/KR87/kr87-1.xml
Normal file
362
Aircraft/Generic/DualControl/Instruments/KR87/kr87-1.xml
Normal file
|
@ -0,0 +1,362 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- KR-87 ADF receiver
|
||||
|
||||
3d model by Torsten Dreyer
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: kr87.nas MUST be loaded as Nasal module KR87.
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>kr87.ac</path>
|
||||
<texture-path>Aircraft/Generic/DualControl/Instruments/KX165/</texture-path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/adf[0]/serviceable</property>
|
||||
<property>instrumentation/adf[0]/power-btn</property>
|
||||
<greater-than>
|
||||
<property>systems/electrical/outputs/adf[0]</property>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>kr87.knobs.ADF</object-name>
|
||||
<object-name>kr87.knobs.BFO</object-name>
|
||||
<object-name>kr87.knobs.FRQ</object-name>
|
||||
<object-name>kr87.knobs.FLT</object-name>
|
||||
<object-name>kr87.knobs.SET</object-name>
|
||||
<emission>
|
||||
<red-prop>sim/model/instrument-lighting/emission/red</red-prop>
|
||||
<green-prop>sim/model/instrument-lighting/emission/green</green-prop>
|
||||
<blue-prop>sim/model/instrument-lighting/emission/blue</blue-prop>
|
||||
<factor-prop>controls/lighting/instruments-norm</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.ANT</object-name>
|
||||
<condition>
|
||||
<not>
|
||||
<property>instrumentation/adf[0]/adf-btn</property>
|
||||
</not>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.ADF</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/adf[0]/adf-btn</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.BFO</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/adf[0]/bfo-btn</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.FRQ</object-name>
|
||||
<condition>
|
||||
<equals>
|
||||
<property>instrumentation/adf[0]/display-mode</property>
|
||||
<value type="int">0</value>
|
||||
</equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.FLT</object-name>
|
||||
<condition>
|
||||
<equals>
|
||||
<property>instrumentation/adf[0]/display-mode</property>
|
||||
<value type="int">1</value>
|
||||
</equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.ET</object-name>
|
||||
<condition>
|
||||
<equals>
|
||||
<property>instrumentation/adf[0]/display-mode</property>
|
||||
<value type="int">2</value>
|
||||
</equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<!-- Use FREQ -->
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.Use.1000</object-name>
|
||||
<condition>
|
||||
<greater-than-equals>
|
||||
<property>instrumentation/adf[0]/frequencies/selected-khz</property>
|
||||
<value type="int">1000</value>
|
||||
</greater-than-equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Use.1000</object-name>
|
||||
<property>instrumentation/adf[0]/frequencies/selected-khz</property>
|
||||
<step>1000</step>
|
||||
<factor>0.0001</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Use.100</object-name>
|
||||
<property>instrumentation/adf[0]/frequencies/selected-khz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Use.10</object-name>
|
||||
<property>instrumentation/adf[0]/frequencies/selected-khz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Use.1</object-name>
|
||||
<property>instrumentation/adf[0]/frequencies/selected-khz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- STBY FREQ -->
|
||||
<animation>
|
||||
<condition>
|
||||
<not-equals>
|
||||
<property>instrumentation/adf[0]/display-mode</property>
|
||||
<value type="int">0</value>
|
||||
</not-equals>
|
||||
</condition>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.dots</object-name>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.Stby.1000</object-name>
|
||||
<condition>
|
||||
<greater-than-equals>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<value type="int">1000</value>
|
||||
</greater-than-equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>kr87.indicators.Stby.100</object-name>
|
||||
<condition>
|
||||
<greater-than-equals>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<value type="int">100</value>
|
||||
</greater-than-equals>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Stby.1000</object-name>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<step>1000</step>
|
||||
<factor>0.0001</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Stby.100</object-name>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Stby.10</object-name>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>kr87.indicators.Stby.1</object-name>
|
||||
<property>instrumentation/adf[0]/right-display</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>noshadow</type>
|
||||
</animation>
|
||||
|
||||
<!-- OSG Hotspots for dual control -->
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>kr87.knobs.FRQ</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.swap(0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>kr87.knobs.FRQOuter</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, 100);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, -100);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, -100.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, 100.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>kr87.knobs.FRQInner</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.adjust_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>kr87.knobs.BFO</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KR87.toggle_BFO(0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
1040
Aircraft/Generic/DualControl/Instruments/KR87/kr87.ac
Normal file
1040
Aircraft/Generic/DualControl/Instruments/KR87/kr87.ac
Normal file
File diff suppressed because it is too large
Load diff
266
Aircraft/Generic/DualControl/Instruments/KR87/kr87.nas
Normal file
266
Aircraft/Generic/DualControl/Instruments/KR87/kr87.nas
Normal file
|
@ -0,0 +1,266 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a KR-87 ADF radio over the multiplayer
|
||||
## network.
|
||||
##
|
||||
## Copyright (C) 2007 - 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 KR87.
|
||||
#
|
||||
|
||||
# Slave button presses.
|
||||
var swap_btn = "frq-btn";
|
||||
var freq_decS = "freq-decS-clicked";
|
||||
var freq_incS = "freq-incS-clicked";
|
||||
var freq_decL = "freq-decL-clicked";
|
||||
var freq_incL = "freq-incL-clicked";
|
||||
|
||||
var bfo_btn = "bfo-btn";
|
||||
|
||||
# Settings
|
||||
var freq_selected = "frequencies/selected-khz";
|
||||
var freq_standby = "frequencies/standby-khz";
|
||||
|
||||
var base = ["instrumentation/adf[0]",
|
||||
"instrumentation/adf[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_kr87 = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_kr87];
|
||||
obj.base = props.globals.getNode(base[n]);
|
||||
if (obj.base == nil) return;
|
||||
obj.base.getNode("right-display", 1).
|
||||
setValue(obj.base.getNode(freq_standby).getValue());
|
||||
# Always show the standby frequency.
|
||||
obj.base.getNode("display-mode", 1).setValue(0);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var tmp = me.base.getNode(freq_selected).getValue();
|
||||
me.base.getNode(freq_selected).setValue
|
||||
(me.base.getNode(freq_standby).getValue());
|
||||
me.base.getNode(freq_standby).setValue(tmp);
|
||||
me.base.getNode("right-display").setValue(tmp);
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.base.getNode(freq_standby),
|
||||
d,
|
||||
200,
|
||||
1800);
|
||||
me.base.getNode("right-display").
|
||||
setValue(me.base.getNode(freq_standby).getValue());
|
||||
},
|
||||
toggle_BFO : func {
|
||||
var p = me.base.getNode(bfo_btn).getValue() ? 0 : 1;
|
||||
me.base.getNode(bfo_btn).setValue(p);
|
||||
me.base.getNode("ident-audible").setValue(p);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_kr87 = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_kr87];
|
||||
obj.airoot = airoot;
|
||||
obj.base = props.globals.getNode(base[n]);
|
||||
if (obj.base == nil) return;
|
||||
obj.base.getNode("right-display", 1).
|
||||
setValue(obj.base.getNode(freq_standby).getValue());
|
||||
# Always show the standby frequency.
|
||||
obj.base.getNode(base[n] ~ "/display-mode", 1).setValue(0);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var p = me.base.getNode(swap_btn);
|
||||
# print("KR87[?].SWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 50) {
|
||||
p = (d < 0) ? me.base.getNode(freq_decS)
|
||||
: me.base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.base.getNode(freq_decL)
|
||||
: me.base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The KR-87 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to().
|
||||
# Do NOT change kr87 directly.
|
||||
var kr87 = [master_kr87.new(0), master_kr87.new(1)];
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - ADF#
|
||||
swap = func(n) {
|
||||
kr87[n].swap();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - ADF#
|
||||
# d - adjustment
|
||||
adjust_frequency = func(n, d) {
|
||||
kr87[n].adjust_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - ADF#
|
||||
# p - pressed
|
||||
toggle_BFO = func(n) {
|
||||
kr87[n].toggle_BFO();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# API for dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - ADF#
|
||||
var make_master = func(n) {
|
||||
kr87[n] = master_kr87.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - ADF#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
kr87[n] = slave_kr87.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a KR-87 3d model in an AI/MP model.
|
||||
# n - ADF#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = "systems/electrical/outputs/adf["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = "instrumentation/adf["~ n ~"]/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/display-mode";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/right-display";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base[n] ~ "/power-btn";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - Adf#
|
||||
var master_send_state = func(n) {
|
||||
var b = props.globals.getNode(base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(freq_selected),
|
||||
b.getNode(freq_standby)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Adf#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
func (b) {
|
||||
if (b) { swap(n); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -100.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 100.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - Adf#
|
||||
var slave_receive_master_state = func(n) {
|
||||
var b = props.globals.getNode(base[n]);
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
b.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
b.getNode(freq_standby).setValue(v);
|
||||
b.getNode("right-display").setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - Adf#
|
||||
var slave_send_buttons = func(n) {
|
||||
var b = props.globals.getNode(base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(swap_btn, 1),
|
||||
b.getNode(freq_decS, 1),
|
||||
b.getNode(freq_incS, 1),
|
||||
b.getNode(freq_decL, 1),
|
||||
b.getNode(freq_incL, 1),
|
||||
# b.getNode(bfo_btn, 1)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# (Not so) Generic frequency stepper.
|
||||
# f - frequency property
|
||||
# d - change
|
||||
# min - min frequency
|
||||
# max - max frequency
|
||||
var adjust_radio_frequency = func(f, d, min, max) {
|
||||
var old = f.getValue();
|
||||
var new = old + d;
|
||||
if (new < min - 0.05) {
|
||||
new = max + (new - min);
|
||||
if ((max - new) >= -d) new += -d;
|
||||
}
|
||||
if (new > max + 0.05) {
|
||||
new = min + (new - max);
|
||||
if ((new - min) >= d) new -= d;
|
||||
}
|
||||
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
||||
f.setValue(new);
|
||||
}
|
||||
|
1961
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.ac
Normal file
1961
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.ac
Normal file
File diff suppressed because it is too large
Load diff
335
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.nas
Normal file
335
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.nas
Normal file
|
@ -0,0 +1,335 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a KX165 NavComm radio over the multiplayer
|
||||
## network.
|
||||
##
|
||||
## Copyright (C) 2007 - 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 KX165.
|
||||
#
|
||||
|
||||
# Slave button presses.
|
||||
var swap_btn = "frq-swap-btn";
|
||||
var freq_decS = "freq-decS-clicked";
|
||||
var freq_incS = "freq-incS-clicked";
|
||||
var freq_decL = "freq-decL-clicked";
|
||||
var freq_incL = "freq-incL-clicked";
|
||||
|
||||
# Settings
|
||||
var freq_selected = "frequencies/selected-mhz";
|
||||
var freq_standby = "frequencies/standby-mhz";
|
||||
|
||||
var comm_base = ["instrumentation/comm[0]",
|
||||
"instrumentation/comm[1]"];
|
||||
var nav_base = ["instrumentation/nav[0]",
|
||||
"instrumentation/nav[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_kx165tso = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_kx165tso];
|
||||
obj.nav_base = props.globals.getNode("instrumentation/nav[" ~ n ~ "]");
|
||||
obj.comm_base = props.globals.getNode("instrumentation/comm[" ~ n ~ "]");
|
||||
return obj;
|
||||
},
|
||||
swap_nav : func() {
|
||||
var tmp = me.nav_base.getNode(freq_selected).getValue();
|
||||
me.nav_base.getNode(freq_selected).setValue
|
||||
(me.nav_base.getNode(freq_standby).getValue());
|
||||
me.nav_base.getNode(freq_standby).setValue(tmp);
|
||||
},
|
||||
swap_comm : func() {
|
||||
var tmp = me.comm_base.getNode(freq_selected).getValue();
|
||||
me.comm_base.getNode(freq_selected).setValue
|
||||
(me.comm_base.getNode(freq_standby).getValue());
|
||||
me.comm_base.getNode(freq_standby).setValue(tmp);
|
||||
},
|
||||
adjust_nav_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.nav_base.getNode(freq_standby),
|
||||
d,
|
||||
108,
|
||||
117.95);
|
||||
},
|
||||
adjust_comm_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.comm_base.getNode(freq_standby),
|
||||
d,
|
||||
118,
|
||||
135.975);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_kx165tso = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_kx165tso];
|
||||
obj.root = airoot;
|
||||
obj.nav_base = props.globals.getNode("instrumentation/nav[" ~ n ~ "]");
|
||||
obj.comm_base = props.globals.getNode("instrumentation/comm[" ~ n ~ "]");
|
||||
return obj;
|
||||
},
|
||||
swap_nav : func() {
|
||||
var p = me.nav_base.getNode(swap_btn);
|
||||
# print("KX165tso[?].NAVSWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
swap_comm : func() {
|
||||
var p = me.comm_base.getNode(swap_btn);
|
||||
# print("KX165tso[?].COMMSWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_nav_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 0.99) {
|
||||
p = (d < 0) ? me.nav_base.getNode(freq_decS)
|
||||
: me.nav_base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.nav_base.getNode(freq_decL)
|
||||
: me.nav_base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_comm_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 0.99) {
|
||||
p = (d < 0) ? me.comm_base.getNode(freq_decS)
|
||||
: me.comm_base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.comm_base.getNode(freq_decL)
|
||||
: me.comm_base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The KX-165 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to().
|
||||
# Do NOT change kx165tso directly.
|
||||
var kx165tso = [master_kx165tso.new(0), master_kx165tso.new(1)];
|
||||
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations and dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
var make_master = func(n) {
|
||||
kx165tso[n] = master_kx165tso.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
kx165tso[n] = slave_kx165tso.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
swap_nav = func(n) {
|
||||
kx165tso[n].swap_nav();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
swap_comm = func(n, b) {
|
||||
kx165tso[n].comm_base.getNode(swap_btn, 1).setValue(b);
|
||||
if (b) kx165tso[n].swap_comm();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
# d - adjustment
|
||||
adjust_nav_frequency = func(n, d) {
|
||||
kx165tso[n].adjust_nav_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - NavComm#
|
||||
# d - adjustment
|
||||
adjust_comm_frequency = func(n, d) {
|
||||
kx165tso[n].adjust_comm_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a radio 3d model in an AI/MP model.
|
||||
# n - NavComm#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
# Comm
|
||||
var base = comm_base[n];
|
||||
var p = "systems/electrical/outputs/comm["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = "instrumentation/comm["~ n ~"]/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ swap_btn;
|
||||
props.globals.getNode(p, 1).alias(airoot.getNode(p));
|
||||
# Nav
|
||||
base = nav_base[n];
|
||||
p = "systems/electrical/outputs/nav["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = "instrumentation/nav["~ n ~"]/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = base ~ "/" ~ swap_btn;
|
||||
props.globals.getNode(p, 1).alias(airoot.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - NavComm#
|
||||
var master_send_state = func(n) {
|
||||
var cb = props.globals.getNode(comm_base[n]);
|
||||
var nb = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
cb.getNode(freq_selected),
|
||||
cb.getNode(freq_standby),
|
||||
nb.getNode(freq_selected),
|
||||
nb.getNode(freq_standby)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Comm#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
# Comm
|
||||
func (b) {
|
||||
if (b) {
|
||||
swap_comm(n, 1);
|
||||
settimer(func { swap_comm(n, 0); }, 1.0)
|
||||
}
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_comm_frequency(n, -0.025); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_comm_frequency(n, 0.025); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_comm_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_comm_frequency(n, 1.0); }
|
||||
},
|
||||
# Nav
|
||||
func (b) {
|
||||
if (b) { swap_nav(n); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_nav_frequency(n, -0.05); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_nav_frequency(n, 0.05); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_nav_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_nav_frequency(n, 1.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - NavComm#
|
||||
var slave_receive_master_state = func(n) {
|
||||
var cb = props.globals.getNode(comm_base[n]);
|
||||
var nb = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
cb.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
cb.getNode(freq_standby).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
nb.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
nb.getNode(freq_standby).setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - NavComm#
|
||||
var slave_send_buttons = func(n) {
|
||||
var cb = props.globals.getNode(comm_base[n]);
|
||||
var nb = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
# Comm
|
||||
cb.getNode(swap_btn, 1),
|
||||
cb.getNode(freq_decS, 1),
|
||||
cb.getNode(freq_incS, 1),
|
||||
cb.getNode(freq_decL, 1),
|
||||
cb.getNode(freq_incL, 1),
|
||||
# Nav
|
||||
nb.getNode(swap_btn, 1),
|
||||
nb.getNode(freq_decS, 1),
|
||||
nb.getNode(freq_incS, 1),
|
||||
nb.getNode(freq_decL, 1),
|
||||
nb.getNode(freq_incL, 1)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Generic frequency stepper.
|
||||
# f - frequency property
|
||||
# d - change
|
||||
# min - min frequency
|
||||
# max - max frequency
|
||||
var adjust_radio_frequency = func(f, d, min, max) {
|
||||
var old = f.getValue();
|
||||
var new = old + d;
|
||||
if (new < min - 0.005) { new = int(max) + (new - int(new)); }
|
||||
if (new > max + 0.005) {
|
||||
new = int(min) + (new - int(new));
|
||||
if (int(new + 0.005) > min) new -= 1;
|
||||
}
|
||||
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
||||
f.setValue(new);
|
||||
}
|
BIN
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.png
Normal file
BIN
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
599
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso1.xml
Normal file
599
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso1.xml
Normal file
|
@ -0,0 +1,599 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<path>kx165tso.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>CommUse</object-name>
|
||||
<object-name>CommStby</object-name>
|
||||
<object-name>NavUse</object-name>
|
||||
<object-name>NavStby</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/comm[0]/serviceable</property>
|
||||
<property>instrumentation/nav[0]/serviceable</property>
|
||||
<!-- property>instrumentation/nav[0]/power-btn</property -->
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<!-- comm part -->
|
||||
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<object-name>NavToggle</object-name>
|
||||
<emission>
|
||||
<red-prop>sim/model/instrument-lighting/emission/red</red-prop>
|
||||
<green-prop>sim/model/instrument-lighting/emission/green</green-prop>
|
||||
<blue-prop>sim/model/instrument-lighting/emission/blue</blue-prop>
|
||||
<factor-prop>controls/lighting/instruments-norm</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<property>instrumentation/comm[0]/frq-swap-btn</property>
|
||||
<factor>-0.004</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse100M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/selected-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse10M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/selected-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse1M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/selected-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse100K</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/selected-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse10K</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/selected-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby100M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby10M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby1M</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby100K</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby10K</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- NAV part -->
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>NavToggle</object-name>
|
||||
<property>instrumentation/nav[0]/frq-swap-btn</property>
|
||||
<factor>-0.004</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse100M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/selected-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse10M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/selected-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse1M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/selected-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse100K</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/selected-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse10K</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/selected-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby100M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/standby-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby10M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/standby-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby1M</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/standby-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby100K</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/standby-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby10K</object-name>
|
||||
<property>instrumentation/nav[0]/frequencies/standby-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- knobs and buttons -->
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CommVolume</object-name>
|
||||
<property>instrumentation/comm[0]/volume</property>
|
||||
<factor>-270</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0188947</x-m>
|
||||
<y-m>-0.0620002</y-m>
|
||||
<z-m>-0.0139999</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>CommVolume</object-name>
|
||||
<property>instrumentation/comm[0]/volume</property>
|
||||
<factor>0.002</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CommKHz</object-name>
|
||||
<property>instrumentation/comm[0]/frequencies/standby-mhz</property>
|
||||
<factor>-1200</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0320882</x-m>
|
||||
<y-m>-0.022</y-m>
|
||||
<z-m>-0.012</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>NavVolume</object-name>
|
||||
<property>instrumentation/nav[0]/volume</property>
|
||||
<factor>-270</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0188946</x-m>
|
||||
<y-m>0.0180001</y-m>
|
||||
<z-m>-0.0139999</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>NavVolume</object-name>
|
||||
<property>instrumentation/nav[0]/volume</property>
|
||||
<factor>0.002</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- OSG Hotspots for dual control -->
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_comm(0, 1);</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_comm(0, 0);</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommKHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, 0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, -0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, -0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, 0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommMHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavToggle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_nav(0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavKHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, 0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, -0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, -0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, 0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavMHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(0, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>noshadow</type>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>range</type>
|
||||
<min-m>0</min-m>
|
||||
<max-m>10</max-m>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
599
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso2.xml
Normal file
599
Aircraft/Generic/DualControl/Instruments/KX165/kx165tso2.xml
Normal file
|
@ -0,0 +1,599 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<path>kx165tso.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>CommUse</object-name>
|
||||
<object-name>CommStby</object-name>
|
||||
<object-name>NavUse</object-name>
|
||||
<object-name>NavStby</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/comm[1]/serviceable</property>
|
||||
<property>instrumentation/nav[1]/serviceable</property>
|
||||
<!-- property>instrumentation/nav[1]/power-btn</property -->
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<!-- comm part -->
|
||||
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<object-name>NavToggle</object-name>
|
||||
<emission>
|
||||
<red-prop>sim/model/instrument-lighting/emission/red</red-prop>
|
||||
<green-prop>sim/model/instrument-lighting/emission/green</green-prop>
|
||||
<blue-prop>sim/model/instrument-lighting/emission/blue</blue-prop>
|
||||
<factor-prop>controls/lighting/instruments-norm</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<property>instrumentation/comm[1]/frq-swap-btn</property>
|
||||
<factor>-0.004</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse100M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/selected-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse10M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/selected-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse1M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/selected-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse100K</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/selected-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommUse10K</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/selected-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby100M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby10M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby1M</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby100K</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>CommStby10K</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- NAV part -->
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>NavToggle</object-name>
|
||||
<property>instrumentation/nav[1]/frq-swap-btn</property>
|
||||
<factor>-0.004</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse100M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/selected-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse10M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/selected-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse1M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/selected-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse100K</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/selected-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavUse10K</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/selected-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby100M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/standby-mhz</property>
|
||||
<step>100</step>
|
||||
<factor>0.001</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby10M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/standby-mhz</property>
|
||||
<step>10</step>
|
||||
<factor>0.01</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby1M</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/standby-mhz</property>
|
||||
<step>1</step>
|
||||
<factor>0.1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby100K</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/standby-mhz</property>
|
||||
<step>0.1</step>
|
||||
<factor>1</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>NavStby10K</object-name>
|
||||
<property>instrumentation/nav[1]/frequencies/standby-mhz</property>
|
||||
<step>0.01</step>
|
||||
<factor>10</factor>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- knobs and buttons -->
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CommVolume</object-name>
|
||||
<property>instrumentation/comm[1]/volume</property>
|
||||
<factor>-270</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0188947</x-m>
|
||||
<y-m>-0.0620002</y-m>
|
||||
<z-m>-0.0139999</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>CommVolume</object-name>
|
||||
<property>instrumentation/comm[1]/volume</property>
|
||||
<factor>0.002</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CommKHz</object-name>
|
||||
<property>instrumentation/comm[1]/frequencies/standby-mhz</property>
|
||||
<factor>-1200</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0320882</x-m>
|
||||
<y-m>-0.022</y-m>
|
||||
<z-m>-0.012</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>NavVolume</object-name>
|
||||
<property>instrumentation/nav[1]/volume</property>
|
||||
<factor>-270</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<center>
|
||||
<x-m>0.0188946</x-m>
|
||||
<y-m>0.0180001</y-m>
|
||||
<z-m>-0.0139999</z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>NavVolume</object-name>
|
||||
<property>instrumentation/nav[1]/volume</property>
|
||||
<factor>0.002</factor>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- OSG Hotspots for dual control -->
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommToggle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_comm(1, 1);</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_comm(1, 0);</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommKHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, 0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, -0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, -0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, 0.025);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CommMHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_comm_frequency(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavToggle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.swap_nav(1);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavKHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, 0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, -0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, -0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, 0.05);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>NavMHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, -1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>KX165.adjust_nav_frequency(1, 1.0);</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>noshadow</type>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>range</type>
|
||||
<min-m>0</min-m>
|
||||
<max-m>10</max-m>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
BIN
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl-22.png
Normal file
BIN
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl-22.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
387
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22-com.xml
Normal file
387
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22-com.xml
Normal file
|
@ -0,0 +1,387 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 22 Comm1 Control for VHF-22 tranceiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 118.000 - 135.975 (normal) @ 25 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl22.nas MUST be loaded as Nasal module VHF22.
|
||||
-->
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<!-- Overlay these for the second etc radio. -->
|
||||
<params>
|
||||
<serviceable>instrumentation/comm[0]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/comm[0]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/comm[0]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/comm[0]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VHF22.swap(0);</swap-script>
|
||||
<small-inc-script>VHF22.adjust_frequency(0, 0.025);</small-inc-script>
|
||||
<small-dec-script>VHF22.adjust_frequency(0, -0.025);</small-dec-script>
|
||||
<big-inc-script>VHF22.adjust_frequency(0, 1.0);</big-inc-script>
|
||||
<big-dec-script>VHF22.adjust_frequency(0, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
<path>ctl22.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<object-name>freq.002</object-name>
|
||||
<object-name>freq.003</object-name>
|
||||
<object-name>freq.dec</object-name>
|
||||
<object-name>freq.004</object-name>
|
||||
<object-name>freq.005</object-name>
|
||||
<object-name>freq.006</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<object-name>stby.002</object-name>
|
||||
<object-name>stby.003</object-name>
|
||||
<object-name>stby.dec</object-name>
|
||||
<object-name>stby.004</object-name>
|
||||
<object-name>stby.005</object-name>
|
||||
<object-name>stby.006</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>mem.annun</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CTL-22.pwr</object-name>
|
||||
<property alias="../../params/serviceable"/>
|
||||
<interpolation>
|
||||
<entry><ind>0</ind><dep>0</dep></entry>
|
||||
<entry><ind>1.0</ind><dep>30</dep></entry>
|
||||
</interpolation>
|
||||
<center>
|
||||
<x-m>0.0</x-m>
|
||||
<y-m>-0.014</y-m>
|
||||
<z-m>-0.018</z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Active Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.002</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.003</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.004</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>1.0</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.005</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>10.0</factor>
|
||||
<step>0.01</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.006</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>100.0</factor>
|
||||
<step>0.001</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Preselected Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.002</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.003</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.004</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>1.0</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.005</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>10.0</factor>
|
||||
<step>0.01</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.006</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>100</factor>
|
||||
<step>0.001</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CTL-22.xfr</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/swap-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.off</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property alias="../../../../params/serviceable"/>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.on</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property alias="../../../../params/serviceable"/>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.kHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.MHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 22 Comm1 Control for VHF-22 tranceiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 118.000 - 135.975 (normal) @ 25 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl22.nas MUST be loaded as Nasal module VHF22.
|
||||
-->
|
||||
|
||||
<PropertyList include="ctl22-com.xml">
|
||||
|
||||
<params>
|
||||
<serviceable>instrumentation/comm[0]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/comm[0]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/comm[0]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/comm[0]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VHF22.swap(0);</swap-script>
|
||||
<small-inc-script>VHF22.adjust_frequency(0, 0.025);</small-inc-script>
|
||||
<small-dec-script>VHF22.adjust_frequency(0, -0.025);</small-dec-script>
|
||||
<big-inc-script>VHF22.adjust_frequency(0, 1.0);</big-inc-script>
|
||||
<big-dec-script>VHF22.adjust_frequency(0, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
</PropertyList>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 22 Comm1 Control for VHF-22 tranceiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 118.000 - 135.975 (normal) @ 25 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl22.nas MUST be loaded as Nasal module VHF22.
|
||||
-->
|
||||
|
||||
<PropertyList include="ctl22-com.xml">
|
||||
|
||||
<params>
|
||||
<serviceable>instrumentation/comm[1]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/comm[1]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/comm[1]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/comm[1]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VHF22.swap(1);</swap-script>
|
||||
<small-inc-script>VHF22.adjust_frequency(1, 0.025);</small-inc-script>
|
||||
<small-dec-script>VHF22.adjust_frequency(1, -0.025);</small-dec-script>
|
||||
<big-inc-script>VHF22.adjust_frequency(1, 1.0);</big-inc-script>
|
||||
<big-dec-script>VHF22.adjust_frequency(1, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
</PropertyList>
|
2491
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22.ac
Normal file
2491
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22.ac
Normal file
File diff suppressed because it is too large
Load diff
226
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22.nas
Normal file
226
Aircraft/Generic/DualControl/Instruments/VHF-22/ctl22.nas
Normal file
|
@ -0,0 +1,226 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a VHF 22 Comm radio over the multiplayer
|
||||
## network.
|
||||
##
|
||||
## Copyright (C) 2008 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
# Note:
|
||||
# This module MUST be loaded as VHF22.
|
||||
#
|
||||
|
||||
# Slave button presses.
|
||||
var swap_btn = "frq-swap-btn";
|
||||
var freq_decS = "freq-decS-clicked";
|
||||
var freq_incS = "freq-incS-clicked";
|
||||
var freq_decL = "freq-decL-clicked";
|
||||
var freq_incL = "freq-incL-clicked";
|
||||
|
||||
# Settings
|
||||
var freq_selected = "frequencies/selected-mhz";
|
||||
var freq_standby = "frequencies/standby-mhz";
|
||||
|
||||
var comm_base = ["instrumentation/comm[0]",
|
||||
"instrumentation/comm[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_ctl22 = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_ctl22];
|
||||
obj.comm_base = props.globals.getNode(comm_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var tmp = me.comm_base.getNode(freq_selected).getValue();
|
||||
me.comm_base.getNode(freq_selected).setValue
|
||||
(me.comm_base.getNode(freq_standby).getValue());
|
||||
me.comm_base.getNode(freq_standby).setValue(tmp);
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.comm_base.getNode(freq_standby),
|
||||
d,
|
||||
118,
|
||||
135.975);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_ctl22 = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_ctl22];
|
||||
obj.root = airoot;
|
||||
obj.comm_base = props.globals.getNode(comm_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var p = me.comm_base.getNode(swap_btn);
|
||||
print("VHF22[?].SWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 0.99) {
|
||||
p = (d < 0) ? me.comm_base.getNode(freq_decS)
|
||||
: me.comm_base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.comm_base.getNode(freq_decL)
|
||||
: me.comm_base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The VHF-22 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to().
|
||||
# Do NOT change ctl22 directly.
|
||||
var ctl22 = [master_ctl22.new(0), master_ctl22.new(1)];
|
||||
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations and dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - Comm#
|
||||
var make_master = func(n) {
|
||||
ctl22[n] = master_ctl22.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Comm#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
ctl22[n] = slave_ctl22.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Comm#
|
||||
var swap = func(n) {
|
||||
ctl22[n].swap();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Comm#
|
||||
# d - adjustment
|
||||
var adjust_frequency = func(n, d) {
|
||||
ctl22[n].adjust_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a radio 3d model in an AI/MP model.
|
||||
# n - Comm#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = "systems/electrical/outputs/comm["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = comm_base[n] ~ "/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = comm_base[n] ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = comm_base[n] ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - Comm#
|
||||
var master_send_state = func(n) {
|
||||
var b = props.globals.getNode(comm_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(freq_selected),
|
||||
b.getNode(freq_standby)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Comm#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
func (b) {
|
||||
if (b) { swap(n); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -0.025); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 0.025); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 1.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - Comm#
|
||||
var slave_receive_master_state = func(n) {
|
||||
var b = props.globals.getNode(comm_base[n]);
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
b.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
b.getNode(freq_standby).setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - Comm#
|
||||
var slave_send_buttons = func(n) {
|
||||
var b = props.globals.getNode(comm_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(swap_btn, 1),
|
||||
b.getNode(freq_decS, 1),
|
||||
b.getNode(freq_incS, 1),
|
||||
b.getNode(freq_decL, 1),
|
||||
b.getNode(freq_incL, 1),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Generic frequency stepper.
|
||||
# f - frequency property
|
||||
# d - change
|
||||
# min - min frequency
|
||||
# max - max frequency
|
||||
var adjust_radio_frequency = func(f, d, min, max) {
|
||||
var old = f.getValue();
|
||||
var new = old + d;
|
||||
if (new < min - 0.005) { new = int(max) + (new - int(new)); }
|
||||
if (new > max + 0.005) {
|
||||
new = int(min) + (new - int(new));
|
||||
if (int(new + 0.005) > min) new -= 1;
|
||||
}
|
||||
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
||||
f.setValue(new);
|
||||
}
|
BIN
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl-32.png
Normal file
BIN
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl-32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
358
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32-nav.xml
Normal file
358
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32-nav.xml
Normal file
|
@ -0,0 +1,358 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 32 Nav1 Control for VIR-32 receiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 108.000 - 117.975 (normal)
|
||||
Strap option 133.00 - 135.95
|
||||
05 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl32.nas MUST be loaded as Nasal module VIR32.
|
||||
-->
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<params>
|
||||
<serviceable>instrumentation/nav[0]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/nav[0]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/nav[0]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/nav[0]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VIR32.swap(0);</swap-script>
|
||||
<small-inc-script>VIR32.adjust_frequency(0, 0.05);</small-inc-script>
|
||||
<small-dec-script>VIR32.adjust_frequency(0, -0.05);</small-dec-script>
|
||||
<big-inc-script>VIR32.adjust_frequency(0, 1.0);</big-inc-script>
|
||||
<big-dec-script>VIR32.adjust_frequency(0, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
<path>ctl32.ac</path>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<object-name>freq.002</object-name>
|
||||
<object-name>freq.003</object-name>
|
||||
<object-name>freq.dec</object-name>
|
||||
<object-name>freq.004</object-name>
|
||||
<object-name>freq.005</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<object-name>stby.002</object-name>
|
||||
<object-name>stby.003</object-name>
|
||||
<object-name>stby.dec</object-name>
|
||||
<object-name>stby.004</object-name>
|
||||
<object-name>stby.005</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>mem.annun</object-name>
|
||||
<condition>
|
||||
<greater-than>
|
||||
<property alias="../../../../params/electrical-supply"/>
|
||||
<value>1</value>
|
||||
</greater-than>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>CTL-32.pwr</object-name>
|
||||
<property alias="../../params/serviceable"/>
|
||||
<interpolation>
|
||||
<entry><ind>0</ind><dep>0</dep></entry>
|
||||
<entry><ind>1.0</ind><dep>30</dep></entry>
|
||||
</interpolation>
|
||||
<center>
|
||||
<x-m>0.0</x-m>
|
||||
<y-m>-0.014</y-m>
|
||||
<z-m>-0.018</z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Active Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.001</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.002</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.003</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.004</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>1</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>freq.005</object-name>
|
||||
<property alias="../../params/selected-freq-mhz"/>
|
||||
<factor>10</factor>
|
||||
<step>0.01</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- Preselected Frequency -->
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.001</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.001</factor>
|
||||
<step>100</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.002</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.01</factor>
|
||||
<step>10</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.003</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>0.1</factor>
|
||||
<step>1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.004</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>1</factor>
|
||||
<step>0.1</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>textranslate</type>
|
||||
<object-name>stby.005</object-name>
|
||||
<property alias="../../params/standby-freq-mhz"/>
|
||||
<factor>10</factor>
|
||||
<step>0.01</step>
|
||||
<bias>0.0005</bias>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>CTL-32.xfr</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/swap-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.off</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property alias="../../../../params/serviceable"/>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>pwr.on</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property alias="../../../../params/serviceable"/>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.kHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/small-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>freq.knob.MHz</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<interval-sec>0.2</interval-sec>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-dec-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script alias="../../../../params/big-inc-script"/>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 32 Nav1 Control for VIR-32 receiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 108.000 - 117.975 (normal)
|
||||
Strap option 133.00 - 135.95
|
||||
05 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl32.nas MUST be loaded as Nasal module VIR32.
|
||||
-->
|
||||
|
||||
<PropertyList include="ctl32-nav.xml">
|
||||
|
||||
<params>
|
||||
<serviceable>instrumentation/nav[0]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/nav[0]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/nav[0]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/nav[0]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VIR32.swap(0);</swap-script>
|
||||
<small-inc-script>VIR32.adjust_frequency(0, 0.05);</small-inc-script>
|
||||
<small-dec-script>VIR32.adjust_frequency(0, -0.05);</small-dec-script>
|
||||
<big-inc-script>VIR32.adjust_frequency(0, 1.0);</big-inc-script>
|
||||
<big-dec-script>VIR32.adjust_frequency(0, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
</PropertyList>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- CTL 32 Nav1 Control for VIR-32 receiver
|
||||
Active and preset displayed +
|
||||
6 frequency memory storage
|
||||
2.375"W x 2.625"H
|
||||
Freq. range 108.000 - 117.975 (normal)
|
||||
Strap option 133.00 - 135.95
|
||||
05 khz spacing
|
||||
Syd Adams
|
||||
|
||||
Adapted for dual control by Anders Gidenstam
|
||||
|
||||
NOTE: ctl32.nas MUST be loaded as Nasal module VIR32.
|
||||
-->
|
||||
|
||||
<PropertyList include="ctl32-nav.xml">
|
||||
|
||||
<params>
|
||||
<serviceable>instrumentation/nav[1]/serviceable</serviceable>
|
||||
<electrical-supply>systems/electrical/outputs/nav[1]</electrical-supply>
|
||||
<selected-freq-mhz>instrumentation/nav[1]/frequencies/selected-mhz</selected-freq-mhz>
|
||||
<standby-freq-mhz>instrumentation/nav[1]/frequencies/standby-mhz</standby-freq-mhz>
|
||||
<swap-script>VIR32.swap(1);</swap-script>
|
||||
<small-inc-script>VIR32.adjust_frequency(1, 0.05);</small-inc-script>
|
||||
<small-dec-script>VIR32.adjust_frequency(1, -0.05);</small-dec-script>
|
||||
<big-inc-script>VIR32.adjust_frequency(1, 1.0);</big-inc-script>
|
||||
<big-dec-script>VIR32.adjust_frequency(1, -1.0);</big-dec-script>
|
||||
</params>
|
||||
|
||||
</PropertyList>
|
2407
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32.ac
Normal file
2407
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32.ac
Normal file
File diff suppressed because it is too large
Load diff
226
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32.nas
Normal file
226
Aircraft/Generic/DualControl/Instruments/VIR-32/ctl32.nas
Normal file
|
@ -0,0 +1,226 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal for dual control of a VIR 32 Nav radio 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 VIR32.
|
||||
#
|
||||
|
||||
# Slave button presses.
|
||||
var swap_btn = "frq-swap-btn";
|
||||
var freq_decS = "freq-decS-clicked";
|
||||
var freq_incS = "freq-incS-clicked";
|
||||
var freq_decL = "freq-decL-clicked";
|
||||
var freq_incL = "freq-incL-clicked";
|
||||
|
||||
# Settings
|
||||
var freq_selected = "frequencies/selected-mhz";
|
||||
var freq_standby = "frequencies/standby-mhz";
|
||||
|
||||
var nav_base = ["instrumentation/nav[0]",
|
||||
"instrumentation/nav[1]"];
|
||||
|
||||
###########################################################################
|
||||
var master_ctl32 = {
|
||||
new : func(n) {
|
||||
var obj = {};
|
||||
obj.parents = [master_ctl32];
|
||||
obj.nav_base = props.globals.getNode(nav_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var tmp = me.nav_base.getNode(freq_selected).getValue();
|
||||
me.nav_base.getNode(freq_selected).setValue
|
||||
(me.nav_base.getNode(freq_standby).getValue());
|
||||
me.nav_base.getNode(freq_standby).setValue(tmp);
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
adjust_radio_frequency(
|
||||
me.nav_base.getNode(freq_standby),
|
||||
d,
|
||||
108,
|
||||
117.975);
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
var slave_ctl32 = {
|
||||
new : func(n, airoot) {
|
||||
var obj = {};
|
||||
obj.parents = [slave_ctl32];
|
||||
obj.root = airoot;
|
||||
obj.nav_base = props.globals.getNode(nav_base[n]);
|
||||
return obj;
|
||||
},
|
||||
swap : func() {
|
||||
var p = me.nav_base.getNode(swap_btn);
|
||||
print("VIR32[?].SWAP");
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
},
|
||||
adjust_frequency : func(d) {
|
||||
var p = 0;
|
||||
if (abs(d) < 0.99) {
|
||||
p = (d < 0) ? me.nav_base.getNode(freq_decS)
|
||||
: me.nav_base.getNode(freq_incS);
|
||||
} else {
|
||||
p = (d < 0) ? me.nav_base.getNode(freq_decL)
|
||||
: me.nav_base.getNode(freq_incL);
|
||||
}
|
||||
if (!p.getValue()) {
|
||||
p.setValue(1);
|
||||
settimer(func { p.setValue(0); },
|
||||
1.0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
###########################################################################
|
||||
# The VIR-32 pick animations default to master.
|
||||
# NOTE: Use make_master() and make_slave_to().
|
||||
# Do NOT change ctl32 directly.
|
||||
var ctl32 = [master_ctl32.new(0), master_ctl32.new(1)];
|
||||
|
||||
|
||||
###########################################################################
|
||||
# API for pick animations and dual control setup.
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
var make_master = func(n) {
|
||||
ctl32[n] = master_ctl32.new(n);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
var make_slave_to = func(n, airoot) {
|
||||
ctl32[n] = slave_ctl32.new(n, airoot);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
var swap = func(n) {
|
||||
ctl32[n].swap();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# n - Nav#
|
||||
# d - adjustment
|
||||
var adjust_frequency = func(n, d) {
|
||||
ctl32[n].adjust_frequency(d);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create aliases to drive a radio 3d model in an AI/MP model.
|
||||
# n - Nav#
|
||||
var animate_aimodel = func(n, airoot) {
|
||||
var p = "systems/electrical/outputs/nav["~ n ~"]";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = "instrumentation/nav["~ n ~"]/serviceable";
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = nav_base[n] ~ "/" ~ freq_selected;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
p = nav_base[n] ~ "/" ~ freq_standby;
|
||||
airoot.getNode(p, 1).alias(props.globals.getNode(p));
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMEncoder node array for sending the current radio state to
|
||||
# slaves.
|
||||
# n - Nav#
|
||||
var master_send_state = func(n) {
|
||||
var b = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(freq_selected),
|
||||
b.getNode(freq_standby)
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchDecoder action array for processing button presses
|
||||
# from a slave.
|
||||
# n - Nav#
|
||||
var master_receive_slave_buttons = func(n) {
|
||||
return
|
||||
[
|
||||
func (b) {
|
||||
if (b) { swap(n); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -0.05); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 0.05); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, -1.0); }
|
||||
},
|
||||
func (b) {
|
||||
if (b) { adjust_frequency(n, 1.0); }
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a TDMDecoder action array for processing the radio state
|
||||
# from the master.
|
||||
# n - Nav#
|
||||
var slave_receive_master_state = func(n) {
|
||||
var b = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
func (v) {
|
||||
b.getNode(freq_selected).setValue(v);
|
||||
},
|
||||
func (v) {
|
||||
b.getNode(freq_standby).setValue(v);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Create a SwitchEncoder node array for sending button presses
|
||||
# to the master
|
||||
# n - Nav#
|
||||
var slave_send_buttons = func(n) {
|
||||
var b = props.globals.getNode(nav_base[n]);
|
||||
return
|
||||
[
|
||||
b.getNode(swap_btn, 1),
|
||||
b.getNode(freq_decS, 1),
|
||||
b.getNode(freq_incS, 1),
|
||||
b.getNode(freq_decL, 1),
|
||||
b.getNode(freq_incL, 1),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Generic frequency stepper.
|
||||
# f - frequency property
|
||||
# d - change
|
||||
# min - min frequency
|
||||
# max - max frequency
|
||||
var adjust_radio_frequency = func(f, d, min, max) {
|
||||
var old = f.getValue();
|
||||
var new = old + d;
|
||||
if (new < min - 0.005) { new = int(max) + (new - int(new)); }
|
||||
if (new > max + 0.005) {
|
||||
new = int(min) + (new - int(new));
|
||||
if (int(new + 0.005) > min) new -= 1;
|
||||
}
|
||||
# print("Old: " ~ old ~ " Intermediate: " ~ (old + d) ~ " New: " ~ new);
|
||||
f.setValue(new);
|
||||
}
|
51
Aircraft/Generic/DualControl/Instruments/ki227-1.xml
Normal file
51
Aircraft/Generic/DualControl/Instruments/ki227-1.xml
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- KI 227-01
|
||||
Bendix/King Slaved Magnetic Heading Indicator
|
||||
Syd Adams
|
||||
Anders Gidenstam (changed to gyro slaved compass card)
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>Aircraft/Instruments-3d/kr87-adf/ki227.ac</path>
|
||||
<texture-path>Aircraft/Instruments-3d/kr87-adf/</texture-path>
|
||||
|
||||
<animation>
|
||||
<type>material</type>
|
||||
<object-name>KI227card</object-name>
|
||||
<object-name>KI227.needle</object-name>
|
||||
<object-name>KI227.knob</object-name>
|
||||
<object-name>KI227.face</object-name>
|
||||
<emission>
|
||||
<red>0.8</red>
|
||||
<green>0.4</green>
|
||||
<blue>0.2</blue>
|
||||
<factor-prop>/systems/electrical/outputs/instrument-lights</factor-prop>
|
||||
</emission>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>KI227card</object-name>
|
||||
<!-- Slave the compass card to the HSI gyro - a single needle RMI. -->
|
||||
<property>/instrumentation/heading-indicator/indicated-heading-deg</property>
|
||||
<factor>-1</factor>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>KI227.needle</object-name>
|
||||
<property>/instrumentation/adf/indicated-bearing-deg</property>
|
||||
<axis>
|
||||
<x>-1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
||||
|
90
Aircraft/Generic/DualControl/README.dual-control
Normal file
90
Aircraft/Generic/DualControl/README.dual-control
Normal file
|
@ -0,0 +1,90 @@
|
|||
Dual control for FlightGear/CVS (copilot OSG only)
|
||||
--------------------------------------------------
|
||||
|
||||
Anders Gidenstam (anders at gidenstam dot org)
|
||||
|
||||
This collection of Nasal code and instruments enables a pilot and
|
||||
copilot to jointly fly an aircraft over the FlightGear multiplayer
|
||||
network. Pilot and copilot can have shared control over primary
|
||||
flight controls, throttle, mixture, elevator trim, flaps, brakes,
|
||||
cockpit switches, part of the radio stack and instrument settings
|
||||
and so on.
|
||||
|
||||
To use the system two "aircraft" needs to be created:
|
||||
- The pilot uses the original aircraft (or a variant thereof).
|
||||
The pilot need to specify the callsign of the copilot (other copilots
|
||||
will be ignored).
|
||||
|
||||
Usage example:
|
||||
fgfs --aircraft=ZLT-NT --prop:/sim/remote/pilot-callsign="copilot"
|
||||
|
||||
- The copilot uses a special "aircraft", <aircraft>-copilot, which
|
||||
piggybacks on the designated pilot and captures the local control
|
||||
inputs. A current limitation is that only the cockpit view
|
||||
is jitter free. There is also a noticeable delay between control inputs
|
||||
and effect, since they are passed via the the multiplayer protocol.
|
||||
The severity of this delay depend on round trip time and some other
|
||||
factors - the delay seems significantly longer than the round trip time
|
||||
itself which is due to buffering in the MP protocol receiver.
|
||||
That said, I have flown successfully as copilot in a setup with
|
||||
100-120ms round trip time between both pilot and server and copilot and
|
||||
server (total delay >500ms). Landing is a bit exciting in that
|
||||
case, however.
|
||||
|
||||
Usage example:
|
||||
fgfs --aircraft=ZLT-NT-copilot --prop:/sim/remote/pilot-callsign="pilot"
|
||||
|
||||
Visit http://www.gidenstam.org/FlightGear/DualControl/ for the latest
|
||||
information.
|
||||
|
||||
|
||||
Developer notes
|
||||
---------------
|
||||
|
||||
The dual control mechanism is divided into to several parts:
|
||||
- the generic core modules in DualControl/ ;
|
||||
- the 3d instrument sharing wrappers in DualControl/instruments/ ; and
|
||||
- the aircraft specific configuration in Systems/ZLT-NT-dual-control.nas
|
||||
and the ZLT-NT/-set/-copilot-set files.
|
||||
|
||||
See the ZLT-NT aircraft for an example how everything come together.
|
||||
|
||||
aircraft_dual_control
|
||||
---------------------
|
||||
|
||||
The aircraft specific dual control Nasal module MUST be loaded as
|
||||
aircraft_dual_control and MUST define the following variables and
|
||||
functions:
|
||||
|
||||
pilot_connect_copilot(copilot) : returns a list of DCT components
|
||||
Does whatever initialization needed to connect the copilot and
|
||||
returns a list of dual-control-tools components whose update() method will
|
||||
be called (in list order) once per frame.
|
||||
copilot is the node hash for the base of the multiplayer tree for the
|
||||
copilot user.
|
||||
|
||||
pilot_disconnect_copilot() : void
|
||||
Does whatever cleanup needed when the copilot disconnects.
|
||||
|
||||
copilot_connect_pilot(pilot) : returns a list of DCT components
|
||||
Does whatever initialization needed to connect to the pilot and
|
||||
returns a list of dual-control-tools components whose update() method will
|
||||
be called (in list order) once per frame.
|
||||
pilot is the node hash for the base of the multiplayer tree for the
|
||||
pilot user.
|
||||
|
||||
copilot_disconnect_pilot() :
|
||||
Does whatever cleanup needed when the pilot disconnects.
|
||||
|
||||
|
||||
pilot_type : string
|
||||
The identifying string of the pilot aircraft is the path of the
|
||||
3d model XML file of the pilot aircraft (as found in sim/model/path
|
||||
under the multiplayer entry).
|
||||
|
||||
copilot_type : string
|
||||
The identifying string of the copilot aircraft is the path of the
|
||||
3d model XML file of the copilot aircraft (as found in sim/model/path
|
||||
under the multiplayer entry).
|
||||
|
||||
|
255
Aircraft/Generic/DualControl/copilot-dual-control.nas
Normal file
255
Aircraft/Generic/DualControl/copilot-dual-control.nas
Normal file
|
@ -0,0 +1,255 @@
|
|||
###############################################################################
|
||||
## $Id$
|
||||
##
|
||||
## Nasal for copilot for dual control over the multiplayer network.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
# Renaming (almost :)
|
||||
var DCT = dual_control_tools;
|
||||
var ADC = aircraft_dual_control;
|
||||
# NOTE: By loading the aircraft specific dual control module
|
||||
# as <aircraft_dual_control> this file is generic.
|
||||
# The aircraft specific modul must set the variables
|
||||
# pilot_type and copilot_type to the name (with full path) of
|
||||
# main 3d model XML for the pilot and copilot aircraft.
|
||||
# This module should be loades under the name dual_control.
|
||||
|
||||
# Allow aircraft to override the copilot view name. Deprecated.
|
||||
if (!contains(ADC, "copilot_view")) {
|
||||
ADC.copilot_view = "Copilot View";
|
||||
}
|
||||
|
||||
# Properties for position and orientation of local aircraft.
|
||||
var l_lat = "/position/latitude-deg";
|
||||
var l_lon = "/position/longitude-deg";
|
||||
var l_alt = "/position/altitude-ft";
|
||||
var l_heading = "/orientation/heading-deg";
|
||||
var l_pitch = "/orientation/pitch-deg";
|
||||
var l_roll = "/orientation/roll-deg";
|
||||
|
||||
# Replicate remote state.
|
||||
var r_airspeed = "velocities/true-airspeed-kt";
|
||||
var l_airspeed = "/velocities/airspeed-kt";
|
||||
var vertspeed = "velocities/vertical-speed-fps";
|
||||
|
||||
# Default external views to slave to the MP pilot.
|
||||
var views = {};
|
||||
views["Helicopter View"] = 2;
|
||||
views["Chase View"] = 3;
|
||||
views["Tower View"] = 0;
|
||||
views["Fly-By View"] = 1;
|
||||
views["Chase View Without Yaw"] = 1;
|
||||
|
||||
######################################################################
|
||||
# Connect to new pilot
|
||||
var process_data = 0;
|
||||
|
||||
var connect = func (pilot) {
|
||||
# Set external view eye and target paths.
|
||||
foreach (var vn; keys(views)) {
|
||||
var view_cfg = "/sim/view[" ~ view.indexof(vn) ~ "]/config";
|
||||
setprop(view_cfg ~ "/at-model", 0);
|
||||
|
||||
if (views[vn] > 0) {
|
||||
setprop(view_cfg ~ "/eye-lat-deg-path",
|
||||
pilot.getNode(DCT.lat_mpp).getPath());
|
||||
setprop(view_cfg ~ "/eye-lon-deg-path",
|
||||
pilot.getNode(DCT.lon_mpp).getPath());
|
||||
setprop(view_cfg ~ "/eye-alt-ft-path",
|
||||
pilot.getNode(DCT.alt_mpp).getPath());
|
||||
}
|
||||
if (views[vn] > 1) {
|
||||
setprop(view_cfg ~ "/eye-heading-deg-path",
|
||||
pilot.getNode(DCT.heading_mpp).getPath());
|
||||
}
|
||||
if (views[vn] > 2) {
|
||||
setprop(view_cfg ~ "/eye-pitch-deg-path",
|
||||
pilot.getNode(DCT.pitch_mpp).getPath());
|
||||
setprop(view_cfg ~ "/eye-roll-deg-path",
|
||||
pilot.getNode(DCT.roll_mpp).getPath());
|
||||
}
|
||||
|
||||
setprop(view_cfg ~ "/target-lat-deg-path",
|
||||
pilot.getNode(DCT.lat_mpp).getPath());
|
||||
setprop(view_cfg ~ "/target-lon-deg-path",
|
||||
pilot.getNode(DCT.lon_mpp).getPath());
|
||||
setprop(view_cfg ~ "/target-alt-ft-path",
|
||||
pilot.getNode(DCT.alt_mpp).getPath());
|
||||
setprop(view_cfg ~ "/target-heading-deg-path",
|
||||
pilot.getNode(DCT.heading_mpp).getPath());
|
||||
setprop(view_cfg ~ "/target-pitch-deg-path",
|
||||
pilot.getNode(DCT.pitch_mpp).getPath());
|
||||
setprop(view_cfg ~ "/target-roll-deg-path",
|
||||
pilot.getNode(DCT.roll_mpp).getPath());
|
||||
}
|
||||
|
||||
# Tweak MP/AI filters
|
||||
pilot.getNode("controls/allow-extrapolation").setBoolValue(1);
|
||||
pilot.getNode("controls/lag-adjust-system-speed").setValue(5.0);
|
||||
|
||||
# Set up property aliases
|
||||
|
||||
# Set up property mappings.
|
||||
process_data =
|
||||
[
|
||||
# Map /postition/*
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.lat_mpp), props.globals.getNode(l_lat)),
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.lon_mpp), props.globals.getNode(l_lon)),
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.alt_mpp), props.globals.getNode(l_alt)),
|
||||
# Map /orientation/*
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.heading_mpp),
|
||||
props.globals.getNode(l_heading)),
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.pitch_mpp),
|
||||
props.globals.getNode(l_pitch)),
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(DCT.roll_mpp),
|
||||
props.globals.getNode(l_roll)),
|
||||
# Map /velocities/*
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(r_airspeed),
|
||||
props.globals.getNode(l_airspeed)),
|
||||
DCT.Translator.new
|
||||
(pilot.getNode(vertspeed),
|
||||
props.globals.getNode(vertspeed)),
|
||||
] ~ ADC.copilot_connect_pilot(pilot);
|
||||
|
||||
print("Dual control ... connected to pilot.");
|
||||
setprop("/sim/messages/copilot", "Welcome aboard.");
|
||||
}
|
||||
|
||||
var disconnect = func {
|
||||
# Reset external view eye and target paths.
|
||||
foreach (var vn; keys(views)) {
|
||||
var view_cfg = "/sim/view[" ~ view.indexof(vn) ~ "]/config";
|
||||
|
||||
if (views[vn] > 0) {
|
||||
setprop(view_cfg ~ "/eye-lat-deg-path",
|
||||
"/position/latitude-deg");
|
||||
setprop(view_cfg ~ "/eye-lon-deg-path",
|
||||
"/position/longitude-deg");
|
||||
setprop(view_cfg ~ "/eye-alt-ft-path",
|
||||
"/position/altitude-ft");
|
||||
}
|
||||
if (views[vn] > 1) {
|
||||
setprop(view_cfg ~ "/eye-heading-deg-path",
|
||||
"/orientation/heading-deg");
|
||||
}
|
||||
if (views[vn] > 2) {
|
||||
setprop(view_cfg ~ "/eye-pitch-deg-path",
|
||||
"/orientation/pitch-deg");
|
||||
setprop(view_cfg ~ "/eye-roll-deg-path",
|
||||
"/orientation/roll-deg");
|
||||
}
|
||||
setprop(view_cfg ~ "/target-lat-deg-path",
|
||||
"/sim/viewer/target/latitude-deg");
|
||||
setprop(view_cfg ~ "/target-lon-deg-path",
|
||||
"/sim/viewer/target/longitude-deg");
|
||||
setprop(view_cfg ~ "/target-alt-ft-path",
|
||||
"/sim/viewer/target/altitude-ft");
|
||||
setprop(view_cfg ~ "/target-heading-deg-path",
|
||||
"/sim/viewer/target/heading-deg");
|
||||
setprop(view_cfg ~ "/target-pitch-deg-path",
|
||||
"/sim/viewer/target/pitch-deg");
|
||||
setprop(view_cfg ~ "/target-roll-deg-path",
|
||||
"/sim/viewer/target/roll-deg");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
######################################################################
|
||||
# Main loop singleton class.
|
||||
var main = {
|
||||
init : func {
|
||||
me.loopid = 0;
|
||||
me.active = 0;
|
||||
setlistener("/ai/models/model-added", func {
|
||||
settimer(func { me.activate(); }, 2);
|
||||
});
|
||||
print("Copilot dual control ... initialized");
|
||||
settimer(func { me.activate(); }, 5);
|
||||
},
|
||||
reset : func {
|
||||
if (me.active) {
|
||||
print("Dual control ... disconnected from pilot.");
|
||||
disconnect();
|
||||
ADC.copilot_disconnect_pilot();
|
||||
}
|
||||
me.active = 0;
|
||||
me.loopid += 1;
|
||||
me._loop_(me.loopid);
|
||||
},
|
||||
activate : func {
|
||||
if (!me.active) {
|
||||
me.reset();
|
||||
}
|
||||
},
|
||||
update : func {
|
||||
var mpplayers =
|
||||
props.globals.getNode("/ai/models").getChildren("multiplayer");
|
||||
var r_callsign = getprop("/sim/remote/pilot-callsign");
|
||||
|
||||
foreach (var pilot; mpplayers) {
|
||||
if ((pilot.getChild("valid").getValue()) and
|
||||
(pilot.getChild("callsign") != nil) and
|
||||
(pilot.getChild("callsign").getValue() == r_callsign)) {
|
||||
|
||||
if (me.active == 0) {
|
||||
# Note: sim/model/path contains the model XML file.
|
||||
if ((pilot.getNode("sim/model/path") != nil) and
|
||||
(pilot.getNode("sim/model/path").getValue() ==
|
||||
ADC.pilot_type)) {
|
||||
me.active = 1;
|
||||
connect(pilot);
|
||||
} else {
|
||||
print("Dual control ... pilot rejected - wrong aircraft type.");
|
||||
me.loopid += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Mess with the MP filters. Highly experimental.
|
||||
if (pilot.getNode("controls/lag-time-offset") != nil) {
|
||||
var v = pilot.getNode("controls/lag-time-offset").getValue();
|
||||
#pilot.getNode("controls/lag-time-offset").setValue(0.99 * v);
|
||||
}
|
||||
|
||||
foreach (var w; process_data) {
|
||||
w.update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
# The pilot player is not around. Idle loop.
|
||||
if (me.active) {
|
||||
print("Dual control ... disconnected from pilot.");
|
||||
disconnect();
|
||||
ADC.copilot_disconnect_pilot();
|
||||
}
|
||||
me.active = 0;
|
||||
me.loopid += 1;
|
||||
},
|
||||
_loop_ : func(id) {
|
||||
id == me.loopid or return;
|
||||
me.update();
|
||||
settimer(func { me._loop_(id); }, 0);
|
||||
}
|
||||
};
|
||||
|
||||
###############################################################################
|
||||
# Initialization.
|
||||
|
||||
var last_view = 0;
|
||||
|
||||
setlistener("/sim/signals/fdm-initialized", func {
|
||||
main.init();
|
||||
});
|
||||
|
644
Aircraft/Generic/DualControl/dual-control-tools.nas
Normal file
644
Aircraft/Generic/DualControl/dual-control-tools.nas
Normal file
|
@ -0,0 +1,644 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Nasal module for dual control over the multiplayer network.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
## MP properties
|
||||
var lat_mpp = "position/latitude-deg";
|
||||
var lon_mpp = "position/longitude-deg";
|
||||
var alt_mpp = "position/altitude-ft";
|
||||
var heading_mpp = "orientation/true-heading-deg";
|
||||
var pitch_mpp = "orientation/pitch-deg";
|
||||
var roll_mpp = "orientation/roll-deg";
|
||||
|
||||
# Import components from the mp_broadcast module.
|
||||
var Binary = mp_broadcast.Binary;
|
||||
var MessageChannel = mp_broadcast.MessageChannel;
|
||||
|
||||
###############################################################################
|
||||
# Utility classes
|
||||
|
||||
############################################################
|
||||
# Translate a property into another.
|
||||
# Factor and offsets are only used for numeric values.
|
||||
# src - source : property node
|
||||
# dest - destination : property node
|
||||
# factor - : double
|
||||
# offset - : double
|
||||
var Translator = {};
|
||||
Translator.new = func (src = nil, dest = nil, factor = 1, offset = 0) {
|
||||
var obj = { parents : [Translator],
|
||||
src : src,
|
||||
dest : dest,
|
||||
factor : factor,
|
||||
offset : offset };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("Translator[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Translator.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (is_num(v)) {
|
||||
me.dest.setValue(me.factor * v + me.offset);
|
||||
} else {
|
||||
if (typeof(v) == "scalar")
|
||||
me.dest.setValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Detects flanks on two insignals encoded in a property.
|
||||
# - positive signal up/down flank
|
||||
# - negative signal up/down flank
|
||||
# n - source : property node
|
||||
# on_positive_flank - action : func (v)
|
||||
# on_negative_flank - action : func (v)
|
||||
var EdgeTrigger = {};
|
||||
EdgeTrigger.new = func (n, on_positive_flank, on_negative_flank) {
|
||||
var obj = { parents : [EdgeTrigger],
|
||||
old : 0,
|
||||
node : n,
|
||||
pos_flank : on_positive_flank,
|
||||
neg_flank : on_negative_flank };
|
||||
if (obj.node == nil) {
|
||||
print("EdgeTrigger[");
|
||||
print(" ", debug.string(obj.node));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
EdgeTrigger.update = func {
|
||||
# NOTE: float MP properties get interpolated.
|
||||
# This detector relies on that steady state is reached between
|
||||
# flanks.
|
||||
var val = me.node.getValue();
|
||||
if (!is_num(val)) return;
|
||||
if (me.old == 1) {
|
||||
if (val < me.old) {
|
||||
me.pos_flank(0);
|
||||
}
|
||||
} elsif (me.old == 0) {
|
||||
if (val > me.old) {
|
||||
me.pos_flank(1);
|
||||
} elsif (val < me.old) {
|
||||
me.neg_flank(1);
|
||||
}
|
||||
} elsif (me.old == -1) {
|
||||
if (val > me.old) {
|
||||
me.neg_flank(0);
|
||||
}
|
||||
}
|
||||
me.old = val;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# StableTrigger: Triggers an action when a MPP property
|
||||
# becomes stable (i.e. doesn't change for
|
||||
# MIN_STABLE seconds).
|
||||
# src - MP prop : property node
|
||||
# action - action to take when the value becomes stable : [func(v)]
|
||||
# An action is triggered when value has stabilized.
|
||||
var StableTrigger = {};
|
||||
StableTrigger.new = func (src, action) {
|
||||
var obj = { parents : [StableTrigger],
|
||||
src : src,
|
||||
action : action,
|
||||
old : 0,
|
||||
stable_since : 0,
|
||||
wait : 0,
|
||||
MIN_STABLE : 0.01 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil) or (action = nil);
|
||||
|
||||
if (bad) {
|
||||
print("StableTrigger[");
|
||||
print(" ", debug.string(obj.src));
|
||||
print(" ", debug.string(obj.action));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
StableTrigger.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
|
||||
if ((me.old == v) and
|
||||
((t - me.stable_since) > me.MIN_STABLE) and (me.wait == 1)) {
|
||||
# Trigger action.
|
||||
me.action(v);
|
||||
|
||||
me.wait = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the signal is stable or after the action.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Selects the most recent value of two properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
# threshold - : double
|
||||
var MostRecentSelector = {};
|
||||
MostRecentSelector.new = func (src1, src2, dest, threshold) {
|
||||
var obj = { parents : [MostRecentSelector],
|
||||
old1 : 0,
|
||||
old2 : 0,
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest,
|
||||
thres : threshold };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("MostRecentSelector[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
MostRecentSelector.update = func {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) and !is_num(v2)) return;
|
||||
elsif (!is_num(v1)) me.dest.setValue(v2);
|
||||
elsif (!is_num(v2)) me.dest.setValue(v1);
|
||||
else {
|
||||
if (abs (v2 - me.old2) > me.thres) {
|
||||
me.old2 = v2;
|
||||
me.dest.setValue(me.old2);
|
||||
}
|
||||
if (abs (v1 - me.old1) > me.thres) {
|
||||
me.old1 = v1;
|
||||
me.dest.setValue(me.old1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds two input properties.
|
||||
# src1 - : property node
|
||||
# src2 - : property node
|
||||
# dest - : property node
|
||||
var Adder = {};
|
||||
Adder.new = func (src1, src2, dest) {
|
||||
var obj = { parents : [DeltaAccumulator],
|
||||
src1 : src1,
|
||||
src2 : src2,
|
||||
dest : dest };
|
||||
if (obj.src1 == nil or obj.src2 == nil or obj.dest == nil) {
|
||||
print("Adder[");
|
||||
print(" ", debug.string(obj.src1));
|
||||
print(" ", debug.string(obj.src2));
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
Adder.update = func () {
|
||||
var v1 = me.src1.getValue();
|
||||
var v2 = me.src2.getValue();
|
||||
if (!is_num(v1) or !is_num(v2)) return;
|
||||
me.dest.setValue(v1 + v2);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Adds the delta of src to dest.
|
||||
# src - : property node
|
||||
# dest - : property node
|
||||
var DeltaAdder = {};
|
||||
DeltaAdder.new = func (src, dest) {
|
||||
var obj = { parents : [DeltaAdder],
|
||||
old : 0,
|
||||
src : src,
|
||||
dest : dest };
|
||||
if (obj.src == nil or obj.dest == nil) {
|
||||
print("DeltaAdder[", debug.string(obj.src), ", ",
|
||||
debug.string(obj.dest), "]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
DeltaAdder.update = func () {
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
me.dest.setValue((v - me.old) + me.dest.getValue());
|
||||
me.old = v;
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch encoder: Encodes upto 32 boolean properties in one
|
||||
# int property.
|
||||
# inputs - list of property nodes
|
||||
# dest - where the bitmask is stored : property node
|
||||
var SwitchEncoder = {};
|
||||
SwitchEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [SwitchEncoder],
|
||||
inputs : inputs,
|
||||
dest : dest };
|
||||
# Error checking.
|
||||
var bad = (obj.dest == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(obj.dest));
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchEncoder.update = func () {
|
||||
var v = 0;
|
||||
var b = 1;
|
||||
forindex (var i; me.inputs) {
|
||||
if (me.inputs[i].getBoolValue()) {
|
||||
v = v + b;
|
||||
}
|
||||
b *= 2;
|
||||
}
|
||||
me.dest.setIntValue(v);
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Switch decoder: Decodes a bitmask in an int property.
|
||||
# src - : property node
|
||||
# actions - list of actions : [func(b)]
|
||||
# Actions are triggered when their input bit change.
|
||||
# Due to interpolation the decoder needs to wait for a
|
||||
# stable input value.
|
||||
var SwitchDecoder = {};
|
||||
SwitchDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [SwitchDecoder],
|
||||
wait : 0,
|
||||
old : 0,
|
||||
old_stable : 0,
|
||||
stable_since : 0,
|
||||
reset : 1,
|
||||
src : src,
|
||||
actions : actions,
|
||||
MIN_STABLE : 0.1 };
|
||||
# Error checking.
|
||||
var bad = (obj.src == nil);
|
||||
foreach (var a; obj.actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("SwitchDecoder[");
|
||||
print(" ", debug.string(obj.src));
|
||||
foreach (var a; obj.actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
SwitchDecoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
var v = me.src.getValue();
|
||||
if (!is_num(v)) return;
|
||||
|
||||
if ((me.old == v) and ((t - me.stable_since) > me.MIN_STABLE) and
|
||||
(me.wait == 1)) {
|
||||
var ov = me.old_stable;
|
||||
# Use this to improve.
|
||||
#<cptf> here's the boring version: var bittest = func(u, b) { while (b) { u = int(u / 2); b -= 1; } u != int(u / 2) * 2; }
|
||||
forindex (var i; me.actions) {
|
||||
var m = math.mod(v, 2);
|
||||
var om = math.mod(ov, 2);
|
||||
if ((m != om or me.reset)) { me.actions[i](m?1:0); }
|
||||
v = (v - m)/2;
|
||||
ov = (ov - om)/2;
|
||||
}
|
||||
me.old_stable = me.src.getValue();
|
||||
me.wait = 0;
|
||||
me.reset = 0;
|
||||
} elsif (me.old == v) {
|
||||
# Wait. This is either before the bitmask is stable or after
|
||||
# it has been processed.
|
||||
} else {
|
||||
me.stable_since = t;
|
||||
me.wait = 1;
|
||||
me.old = me.src.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing encoder: Transmits a list of
|
||||
# properties over a MP enabled string property.
|
||||
# inputs - input properties : [property node]
|
||||
# dest - MP string prop : property node
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMEncoder = {};
|
||||
TDMEncoder.new = func (inputs, dest) {
|
||||
var obj = { parents : [TDMEncoder],
|
||||
inputs : inputs,
|
||||
channel : MessageChannel.new(dest,
|
||||
func (msg) {
|
||||
print("This should not happen!");
|
||||
}),
|
||||
MIN_INT : 0.25,
|
||||
last_time : 0,
|
||||
next_item : 0,
|
||||
old : [] };
|
||||
# Error checking.
|
||||
var bad = (dest == nil) or (obj.channel == nil);
|
||||
foreach (var i; inputs) {
|
||||
if (i == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMEncoder[");
|
||||
foreach (var i; inputs) {
|
||||
print(" ", debug.string(i));
|
||||
}
|
||||
print(" ", debug.string(dest));
|
||||
print("]");
|
||||
}
|
||||
|
||||
setsize(obj.old, size(obj.inputs));
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMEncoder.update = func () {
|
||||
var t = getprop("/sim/time/elapsed-sec"); # NOTE: simulated time.
|
||||
if (t > me.last_time + me.MIN_INT) {
|
||||
var n = size(me.inputs);
|
||||
while (1) {
|
||||
var v = me.inputs[me.next_item].getValue();
|
||||
|
||||
if ((n <= 0) or (me.old[me.next_item] != v)) {
|
||||
# Set the MP properties to send the next item.
|
||||
me.channel.send(Binary.encodeByte(me.next_item) ~
|
||||
Binary.encodeDouble(v));
|
||||
|
||||
me.old[me.next_item] = v;
|
||||
|
||||
me.last_time = t;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
return;
|
||||
} else {
|
||||
# Search for changed property.
|
||||
n -= 1;
|
||||
me.next_item += 1;
|
||||
if (me.next_item >= size(me.inputs)) { me.next_item = 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
############################################################
|
||||
# Time division multiplexing decoder: Receives a list of
|
||||
# properties over a MP enabled string property.
|
||||
# src - MP string prop : property node
|
||||
# actions - list of actions : [func(v)]
|
||||
# An action is triggered when its value is received.
|
||||
# Note: TDM can have high latency so it is best used for
|
||||
# non-time critical properties.
|
||||
var TDMDecoder = {};
|
||||
TDMDecoder.new = func (src, actions) {
|
||||
var obj = { parents : [TDMDecoder],
|
||||
actions : actions };
|
||||
obj.channel = MessageChannel.new(src,
|
||||
func (msg) {
|
||||
obj.process(msg);
|
||||
});
|
||||
|
||||
# Error checking.
|
||||
var bad = (src == nil) or (obj.channel == nil);
|
||||
foreach (var a; actions) {
|
||||
if (a == nil) { bad = 1; }
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
print("TDMDecoder[");
|
||||
print(" ", debug.string(src));
|
||||
foreach (var a; actions) {
|
||||
print(" ", debug.string(a));
|
||||
}
|
||||
print("]");
|
||||
fail();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
TDMDecoder.process = func (msg) {
|
||||
var v1 = Binary.decodeByte(msg);
|
||||
var v2 = Binary.decodeDouble(substr(msg, 1));
|
||||
# Trigger action.
|
||||
me.actions[v1](v2);
|
||||
}
|
||||
TDMDecoder.update = func {
|
||||
me.channel.update();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Internal utility functions
|
||||
|
||||
var is_num = func (v) {
|
||||
return num(v) != nil;
|
||||
}
|
||||
|
||||
# fail causes a Nasal runtime error so we get a backtrace.
|
||||
var fail = func {
|
||||
error_detected_in_calling_context();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Copilot selection dialog.
|
||||
#
|
||||
# Usage: dual_control_tools.copilot_dialog.show(<copilot type string>);
|
||||
#
|
||||
var COPILOT_DLG = 0;
|
||||
var copilot_dialog = {};
|
||||
############################################################
|
||||
copilot_dialog.init = func (copilot_type, x = nil, y = nil) {
|
||||
me.x = x;
|
||||
me.y = y;
|
||||
me.bg = [0, 0, 0, 0.3]; # background color
|
||||
me.fg = [[1.0, 1.0, 1.0, 1.0]];
|
||||
#
|
||||
# "private"
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
me.title = "Pilot selection";
|
||||
} else {
|
||||
me.title = "Copilot selection";
|
||||
}
|
||||
me.basenode = props.globals.getNode("/sim/remote", 1);
|
||||
me.dialog = nil;
|
||||
me.namenode = props.Node.new({"dialog-name" : me.title });
|
||||
me.listeners = [];
|
||||
me.copilot_type = copilot_type;
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.create = func {
|
||||
if (me.dialog != nil)
|
||||
me.close();
|
||||
|
||||
me.dialog = gui.Widget.new();
|
||||
me.dialog.set("name", me.title);
|
||||
if (me.x != nil)
|
||||
me.dialog.set("x", me.x);
|
||||
if (me.y != nil)
|
||||
me.dialog.set("y", me.y);
|
||||
|
||||
me.dialog.set("layout", "vbox");
|
||||
me.dialog.set("default-padding", 0);
|
||||
var titlebar = me.dialog.addChild("group");
|
||||
titlebar.set("layout", "hbox");
|
||||
titlebar.addChild("empty").set("stretch", 1);
|
||||
if (contains(aircraft_dual_control, "copilot_view")) {
|
||||
titlebar.addChild("text").set("label", "Pilots online");
|
||||
} else {
|
||||
titlebar.addChild("text").set("label", "Copilots online");
|
||||
}
|
||||
var w = titlebar.addChild("button");
|
||||
w.set("pref-width", 16);
|
||||
w.set("pref-height", 16);
|
||||
w.set("legend", "");
|
||||
w.set("default", 0);
|
||||
w.set("key", "esc");
|
||||
w.setBinding("nasal", "dual_control_tools.copilot_dialog.destroy(); ");
|
||||
w.setBinding("dialog-close");
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
var content = me.dialog.addChild("group");
|
||||
content.set("layout", "vbox");
|
||||
content.set("halign", "center");
|
||||
content.set("default-padding", 5);
|
||||
|
||||
# Generate the dialog contents.
|
||||
me.players = me.find_copilot_players();
|
||||
var i = 0;
|
||||
var tmpbase = me.basenode.getNode("dialog", 1);
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
foreach (var p; me.players) {
|
||||
var tmp = tmpbase.getNode("b[" ~ i ~ "]", 1);
|
||||
tmp.setBoolValue(streq(selected, p));
|
||||
var w = content.addChild("checkbox");
|
||||
w.node.setValues({"label" : p,
|
||||
"halign" : "left",
|
||||
"property" : tmp.getPath()});
|
||||
w.setBinding
|
||||
("nasal",
|
||||
"dual_control_tools.copilot_dialog.select_action(" ~ i ~ ");");
|
||||
i = i + 1;
|
||||
}
|
||||
me.dialog.addChild("hrule");
|
||||
|
||||
# Display the dialog.
|
||||
fgcommand("dialog-new", me.dialog.prop());
|
||||
fgcommand("dialog-show", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.close = func {
|
||||
fgcommand("dialog-close", me.namenode);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.destroy = func {
|
||||
COPILOT_DLG = 0;
|
||||
me.close();
|
||||
foreach(var l; me.listeners)
|
||||
removelistener(l);
|
||||
delete(gui.dialog, "\"" ~ me.title ~ "\"");
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.show = func (copilot_type) {
|
||||
# print("Showing MPCopilots dialog!");
|
||||
if (!COPILOT_DLG) {
|
||||
COPILOT_DLG = int(getprop("/sim/time/elapsed-sec"));
|
||||
me.init(copilot_type);
|
||||
me.create();
|
||||
me._update_(COPILOT_DLG);
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._redraw_ = func {
|
||||
if (me.dialog != nil) {
|
||||
me.close();
|
||||
me.create();
|
||||
}
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog._update_ = func (id) {
|
||||
if (COPILOT_DLG != id) return;
|
||||
me._redraw_();
|
||||
settimer(func { me._update_(id); }, 4.1);
|
||||
}
|
||||
############################################################
|
||||
copilot_dialog.select_action = func (n) {
|
||||
var selected = me.basenode.getNode("pilot-callsign").getValue();
|
||||
var bs = me.basenode.getNode("dialog").getChildren();
|
||||
# Assumption: There are two true b:s or none. The one not matching selected
|
||||
# is the new selection.
|
||||
var i = 0;
|
||||
me.basenode.getNode("pilot-callsign").setValue("");
|
||||
foreach (var b; bs) {
|
||||
if (!b.getValue() and (i == n)) {
|
||||
b.setValue(1);
|
||||
me.basenode.getNode("pilot-callsign").setValue(me.players[i]);
|
||||
} else {
|
||||
b.setValue(0);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
dual_control.main.reset();
|
||||
me._redraw_();
|
||||
}
|
||||
############################################################
|
||||
# Return a list containing all nearby copilot players of the right type.
|
||||
copilot_dialog.find_copilot_players = func {
|
||||
var mpplayers =
|
||||
props.globals.getNode("/ai/models").getChildren("multiplayer");
|
||||
|
||||
var res = [];
|
||||
foreach (var pilot; mpplayers) {
|
||||
if ((pilot.getNode("valid") != nil) and
|
||||
(pilot.getNode("valid").getValue()) and
|
||||
(pilot.getNode("sim/model/path") != nil)) {
|
||||
var type = pilot.getNode("sim/model/path").getValue();
|
||||
|
||||
if (type == me.copilot_type) {
|
||||
append(res, pilot.getNode("callsign").getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
# debug.dump(res);
|
||||
return res;
|
||||
}
|
||||
###############################################################################
|
116
Aircraft/Generic/DualControl/pilot-dual-control.nas
Normal file
116
Aircraft/Generic/DualControl/pilot-dual-control.nas
Normal file
|
@ -0,0 +1,116 @@
|
|||
###############################################################################
|
||||
## $Id$
|
||||
##
|
||||
## Nasal for main pilot for dual control over the multiplayer network.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
# Renaming (almost :)
|
||||
var DCT = dual_control_tools;
|
||||
var ADC = aircraft_dual_control;
|
||||
# NOTE: By loading the aircraft specific dual control module
|
||||
# as <aircraft_dual_control> this file is generic.
|
||||
# The aircraft specific modul must set the variables
|
||||
# pilot_type and copilot_type to the name (with full path) of
|
||||
# main 3d model XML for the pilot and copilot aircraft.
|
||||
# This module should be loades under the name dual_control.
|
||||
|
||||
######################################################################
|
||||
# Connect new copilot
|
||||
var process_data = 0;
|
||||
|
||||
var connect = func (copilot) {
|
||||
# Tweak MP/AI filters
|
||||
copilot.getNode("controls/allow-extrapolation").setBoolValue(0);
|
||||
copilot.getNode("controls/lag-adjust-system-speed").setValue(5);
|
||||
|
||||
process_data = ADC.pilot_connect_copilot(copilot);
|
||||
|
||||
print("Dual control ... copilot connected.");
|
||||
setprop("/sim/messages/copilot", "Hi.");
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Main loop singleton class.
|
||||
var main = {
|
||||
init : func {
|
||||
me.loopid = 0;
|
||||
me.active = 0;
|
||||
setlistener("/ai/models/model-added", func {
|
||||
settimer(func { me.activate(); }, 2);
|
||||
});
|
||||
settimer(func { me.activate(); }, 5);
|
||||
print("Pilot dual control ... initialized");
|
||||
},
|
||||
reset : func {
|
||||
if (me.active) {
|
||||
print("Dual control ... copilot disconnected.");
|
||||
ADC.pilot_disconnect_copilot();
|
||||
}
|
||||
me.active = 0;
|
||||
me.loopid += 1;
|
||||
me._loop_(me.loopid);
|
||||
},
|
||||
activate : func {
|
||||
if (!me.active) {
|
||||
me.reset();
|
||||
}
|
||||
},
|
||||
update : func {
|
||||
var mpplayers =
|
||||
props.globals.getNode("/ai/models").getChildren("multiplayer");
|
||||
var r_callsign = getprop("/sim/remote/pilot-callsign");
|
||||
|
||||
foreach (var copilot; mpplayers) {
|
||||
if ((copilot.getChild("valid").getValue()) and
|
||||
(copilot.getChild("callsign") != nil) and
|
||||
(copilot.getChild("callsign").getValue() == r_callsign)) {
|
||||
|
||||
if (me.active == 0) {
|
||||
# Note: sim/model/path tells the 3d XML file of the model.
|
||||
if ((copilot.getNode("sim/model/path") != nil) and
|
||||
(copilot.getNode("sim/model/path").getValue() ==
|
||||
ADC.copilot_type)) {
|
||||
connect(copilot);
|
||||
me.active = 1;
|
||||
} else {
|
||||
print("Dual control ... copilot rejected - wrong aircraft type.");
|
||||
me.loopid += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# Mess with the MP filters. Highly experimental.
|
||||
if (copilot.getNode("controls/lag-time-offset") != nil) {
|
||||
var v = copilot.getNode("controls/lag-time-offset").getValue();
|
||||
copilot.getNode("controls/lag-time-offset").setValue(0.97 * v);
|
||||
}
|
||||
|
||||
foreach (var w; process_data) {
|
||||
w.update();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (me.active) {
|
||||
print("Dual control ... copilot disconnected.");
|
||||
ADC.pilot_disconnect_copilot();
|
||||
}
|
||||
me.loopid += 1;
|
||||
me.active = 0;
|
||||
},
|
||||
_loop_ : func(id) {
|
||||
id == me.loopid or return;
|
||||
me.update();
|
||||
settimer(func { me._loop_(id); }, 0);
|
||||
}
|
||||
};
|
||||
|
||||
######################################################################
|
||||
# Initialization.
|
||||
setlistener("/sim/signals/fdm-initialized", func {
|
||||
main.init();
|
||||
});
|
155
Aircraft/Generic/Oxygen/oxygen.nas
Normal file
155
Aircraft/Generic/Oxygen/oxygen.nas
Normal file
|
@ -0,0 +1,155 @@
|
|||
###############################################################################
|
||||
##
|
||||
## Oxygen system module for FlightGear.
|
||||
##
|
||||
## Copyright (C) 2010 Vivian Meazza (vivia.meazza(at)lineone.net)
|
||||
## This file is licensed under the GPL license v2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
|
||||
# Properties under /consumables/fuel/tank[n]:
|
||||
# + level_cu_ft - Current free oxygen content. Must be set by user code.
|
||||
# + capacity_cu_ft - Tank volume
|
||||
# + selected - boolean indicating tank selection.
|
||||
# + name ...........- string
|
||||
# + pressure - OUTPUT ONLY property, do not try to set
|
||||
|
||||
# Properties under /controls/oxygen/
|
||||
# + altitude-norm - the selected supply altitude normalized 0 - 100% oxygen
|
||||
# + flowrate_cu_ft_ps - Max (100%) Oxygen flow rate
|
||||
|
||||
# + flowrate considerations:
|
||||
# ref http://en.wikipedia.org/wiki/Human_lung
|
||||
#
|
||||
# when maximum (100%) oxygen is selected, we wish to deliver enough oxygen to fill
|
||||
# the pilot's lungs, with slight overpressure.
|
||||
#
|
||||
# let the tidal flow volume - that is the amount of gas which flows
|
||||
# into and out of the lungs on each breath = T ft^3;
|
||||
# and the number of breaths per minute at rest= N min^-1;
|
||||
# but we need to consider a pilot under stress factor = 1.5
|
||||
#
|
||||
# so flowrate (ft^3.sec^-1) = (T*1.5*N)/60
|
||||
#
|
||||
# substituting the values from the reference
|
||||
#
|
||||
# flowrate = 0.01765 * 1.5 * 20 / 60 = 0.008828
|
||||
#
|
||||
# rounding up to provide overpressure
|
||||
#
|
||||
# flowrate = 0.01 (ft^3.sec^-1)
|
||||
|
||||
|
||||
#========================= Initialize ===============================
|
||||
var MAXTANKS = 20;
|
||||
var INHG2PSI = 0.491154077497;
|
||||
|
||||
var initialize = func {
|
||||
|
||||
print( "Initializing Oxygen System ..." );
|
||||
|
||||
props.globals.initNode("/systems/oxygen/serviceable", 1, "BOOL");
|
||||
props.globals.initNode("/sim/freeze/oxygen", 0, "BOOL");
|
||||
props.globals.initNode("/controls/oxygen/altitude-norm", 0.0, "DOUBLE");
|
||||
props.globals.initNode("/controls/oxygen/flowrate-cu-ft-ps", 0.01, "DOUBLE");
|
||||
|
||||
for (var i = 0; i < MAXTANKS; i += 1){
|
||||
props.globals.initNode("/consumables/oxygen/tank["~ i ~ "]/capacity-cu-ft", 0.01, "DOUBLE");
|
||||
props.globals.initNode("/consumables/oxygen/tank["~ i ~ "]/level-cu-ft", 0, "DOUBLE");
|
||||
props.globals.initNode("/consumables/oxygen/tank["~ i ~ "]/selected", 0, "BOOL");
|
||||
props.globals.initNode("/consumables/oxygen/tank["~ i ~ "]/pressure-psi", 50, "DOUBLE");
|
||||
}
|
||||
|
||||
oxygen();
|
||||
|
||||
} #end init
|
||||
|
||||
#========================= Oxygen System ============================
|
||||
var oxygen = func {
|
||||
|
||||
var freeze = getprop("/sim/freeze/oxygen");
|
||||
var serviceable =getprop("/systems/oxygen/serviceable");
|
||||
|
||||
if(freeze or !serviceable) { return; }
|
||||
|
||||
var dt = getprop("sim/time/delta-sec");
|
||||
var oxygen_alt = getprop("controls/oxygen/altitude-norm");
|
||||
var flowrate_cu_ft_ps = getprop("controls/oxygen/flowrate-cu-ft-ps");
|
||||
var Pa = getprop("environment/pressure-inhg") * INHG2PSI;
|
||||
|
||||
var flow_cu_ft = flowrate_cu_ft_ps * oxygen_alt * dt;
|
||||
|
||||
var contents = 0;
|
||||
var cap = 0;
|
||||
var availableTanks = [];
|
||||
var selected = 0;
|
||||
var pressure = 2000;
|
||||
|
||||
# Build a list of available tanks. An available tank is both selected, has
|
||||
# oxygen remaining.and pressure < ambient.
|
||||
var AllTanks = props.globals.getNode("consumables/oxygen").getChildren("tank");
|
||||
|
||||
foreach( var t; AllTanks) {
|
||||
cap = t.getNode("capacity-cu-ft", 1).getValue();
|
||||
contents = t.getNode("level-cu-ft", 1).getValue();
|
||||
selected = t.getNode("selected", 1).getBoolValue();
|
||||
pressure = t.getNode("pressure-psi", 1).getValue();
|
||||
|
||||
if(cap != nil and cap > 0.01 ) {
|
||||
# print ("Pressure ", pressure, " " , Pa);
|
||||
|
||||
if(selected and pressure > Pa) {
|
||||
append(availableTanks, t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# print("flow_cu_ft ", flow_cu_ft," " ,size(availableTanks));
|
||||
|
||||
# Subtract flow_cu_ft from tanks, set auxilliary properties. Set out-of-gas
|
||||
# when all tanks are empty.
|
||||
var outOfGas = 0;
|
||||
|
||||
if(size(availableTanks) == 0) {
|
||||
outOfGas = 1;
|
||||
} else {
|
||||
flowPerTank = flow_cu_ft / size(availableTanks);
|
||||
foreach( var t; availableTanks ) {
|
||||
cu_ft = t.getNode("level-cu-ft").getValue();
|
||||
cu_ft -= flowPerTank;
|
||||
cap = t.getNode("capacity-cu-ft", 1).getValue();
|
||||
|
||||
if(cu_ft < 0) { cu_ft = 0;}
|
||||
|
||||
# print ("pressure ", calcPressure(cu_ft, cap));
|
||||
|
||||
t.getNode("level-cu-ft").setDoubleValue(cu_ft);
|
||||
t.getNode("pressure-psi").setDoubleValue(calcPressure(cu_ft, cap));
|
||||
}
|
||||
}
|
||||
|
||||
settimer(oxygen, 0.3);
|
||||
|
||||
} #end oxygen
|
||||
|
||||
# We apply Boyle's Law to derive the pressure in the tank fom the capacity of the
|
||||
# tank and the contents. We ignore the effects of temperature.
|
||||
|
||||
var calcPressure = func (cu_ft, cap){
|
||||
var Vc = cap;
|
||||
var Va = cu_ft;
|
||||
var Pa = 14.7;
|
||||
|
||||
# print (Vc, " ", Va, " ", Pa);
|
||||
|
||||
Pc = (Pa * Va)/Vc;
|
||||
return Pc;
|
||||
} #end calcPressure
|
||||
|
||||
setlistener("sim/signals/fdm-initialized", initialize);
|
||||
|
||||
# end
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1728,6 +1728,141 @@
|
|||
</center>
|
||||
</animation>
|
||||
|
||||
<!-- Fuel Selector -->
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>FuelSelectorOff</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<not>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
</not>
|
||||
<not>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>FuelSelectorLeft</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<not>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>FuelSelectorRight</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<not>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
</not>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>FuelSelectorBoth</object-name>
|
||||
<condition>
|
||||
<and>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
</and>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>FuelHotspotOff</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>FuelHotspotLeft</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>FuelHotspotRight</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<value>false</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>FuelHotspotBoth</object-name>
|
||||
<visible>true</visible>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[0]/selected</property>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>consumables/fuel/tank[1]/selected</property>
|
||||
<value>true</value>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<!-- Switches -->
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
|
@ -1918,23 +2053,6 @@
|
|||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>spin</type>
|
||||
<object-name>Propeller.Slow</object-name>
|
||||
<property>engines/engine[0]/rpm</property>
|
||||
<factor>-0.1</factor>
|
||||
<center>
|
||||
<x-m>-1.79</x-m>
|
||||
<y-m>0</y-m>
|
||||
<z-m>-0.05</z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x>1.0</x>
|
||||
<y>0.0</y>
|
||||
<z>-0.05240773494</z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>spin</type>
|
||||
<object-name>Propeller.Fast</object-name>
|
||||
|
|
BIN
Aircraft/c172p/Models/fuel-selector.png
Normal file
BIN
Aircraft/c172p/Models/fuel-selector.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
|
@ -51,7 +51,7 @@ var init_actions = func {
|
|||
filteredGS1.setDoubleValue(0.0);
|
||||
|
||||
# Make sure that init_actions is called when the sim is reset
|
||||
setlistener("sim/signals/reset", init_actions);
|
||||
setlistener("sim/signals/reset", init_actions);
|
||||
|
||||
# Request that the update fuction be called next frame
|
||||
settimer(update_actions, 0);
|
||||
|
@ -113,15 +113,25 @@ var update_actions = func {
|
|||
|
||||
var scissor_angle = func(H,C,L,phi) {
|
||||
var a = (H - C)/2/L;
|
||||
# Use 2 iterates of Newton's method and 4th order Taylor series to
|
||||
# Use 2 iterates of Newton's method and 4th order Taylor series to
|
||||
# approximate theta where sin(phi - theta) = a
|
||||
var theta = phi - 2*a/3 - a/3/(1-a*a/2);
|
||||
return theta;
|
||||
}
|
||||
|
||||
# Setup listener call to start update loop once the fdm is initialized
|
||||
#
|
||||
setlistener("sim/signals/fdm-initialized", init_actions);
|
||||
#
|
||||
setlistener("sim/signals/fdm-initialized", init_actions);
|
||||
|
||||
#
|
||||
# Listeners to tie the /consumables/fuels/tank[]/selected to
|
||||
# /fdm/jsbsim/propulsion/tank[]/priority
|
||||
|
||||
setlistener("consumables/fuel/tank[0]/selected", func(selected) {
|
||||
setprop("/fdm/jsbsim/propulsion/tank[0]/priority", selected.getBoolValue() ? 1 : 0);
|
||||
});
|
||||
|
||||
setlistener("consumables/fuel/tank[1]/selected", func(selected) {
|
||||
setprop("/fdm/jsbsim/propulsion/tank[1]/priority", selected.getBoolValue() ? 1 : 0);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,18 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/material-diffuse</name>
|
||||
<parameters>
|
||||
<material>
|
||||
<color-mode-uniform>1</color-mode-uniform> <!-- DIFFUSE -->
|
||||
</material>
|
||||
</parameters>
|
||||
<inherits-from>Effects/model-default</inherits-from>
|
||||
<technique n="10">
|
||||
<pass>
|
||||
<program>
|
||||
<vertex-shader>Shaders/default.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/default.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>colorMode</name>
|
||||
<type>int</type>
|
||||
<value>1</value> <!-- DIFFUSE -->
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/material-off</name>
|
||||
<parameters>
|
||||
<material>
|
||||
<color-mode-uniform>0</color-mode-uniform> <!-- OFF -->
|
||||
</material>
|
||||
</parameters>
|
||||
<inherits-from>Effects/model-default</inherits-from>
|
||||
<technique n="10">
|
||||
<pass>
|
||||
<uniform>
|
||||
<name>colorMode</name>
|
||||
<type>int</type>
|
||||
<value>0</value> <!-- OFF -->
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
</PropertyList>
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<type>white</type>
|
||||
</texture>
|
||||
<vertex-program-two-side type="bool">false</vertex-program-two-side>
|
||||
<material>
|
||||
<color-mode-uniform>1</color-mode-uniform> <!-- DIFFUSE -->
|
||||
</material>
|
||||
</parameters>
|
||||
<technique n="10">
|
||||
<predicate>
|
||||
|
@ -76,7 +79,7 @@
|
|||
<uniform>
|
||||
<name>colorMode</name>
|
||||
<type>int</type>
|
||||
<value>1</value> <!-- DIFFUSE -->
|
||||
<value><use>material/color-mode-uniform</use></value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
|
|
|
@ -112,6 +112,40 @@
|
|||
<output>/environment/config/aloft/entry[0]/visibility-m</output>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<!--
|
||||
transfer the rain intensity to the target environment
|
||||
-->
|
||||
<name>MetarController:rain-norm</name>
|
||||
<type>noise-spike</type>
|
||||
<max-rate-of-change>1.0</max-rate-of-change>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
<property>/environment/params/metar-updates-environment</property>
|
||||
</condition>
|
||||
</enable>
|
||||
<input>/environment/metar/rain-norm</input>
|
||||
<output>/environment/rain-norm</output>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<!--
|
||||
transfer the snow intensity to the target environment
|
||||
-->
|
||||
<name>MetarController:snow-norm</name>
|
||||
<type>noise-spike</type>
|
||||
<max-rate-of-change>1.0</max-rate-of-change>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
<property>/environment/params/metar-updates-environment</property>
|
||||
</condition>
|
||||
</enable>
|
||||
<input>/environment/metar/snow-norm</input>
|
||||
<output>/environment/snow-norm</output>
|
||||
</filter>
|
||||
|
||||
<!-- interpolate the wind vector's components -->
|
||||
<filter>
|
||||
<name>MetarController:wind-from-north-fps</name>
|
||||
|
|
268
Input/Joysticks/Genius/f31.xml
Normal file
268
Input/Joysticks/Genius/f31.xml
Normal file
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
************************************************************************
|
||||
Genius F-31U VIBRATION USB Joystick
|
||||
|
||||
Axes:
|
||||
0 - Aileron
|
||||
1 - Elevator
|
||||
2 - Rudder
|
||||
3 - Throttle
|
||||
4 - View left-right Hat
|
||||
5 - View up-down Hat
|
||||
|
||||
Buttons:
|
||||
0 - Brakes
|
||||
1 - Cycle view
|
||||
2 - Elevator trim up
|
||||
3 - Elevator trim down
|
||||
4 - Flaps down
|
||||
5 - Flaps up
|
||||
6 - Brakes
|
||||
7 - Mixture richer
|
||||
8 - Mixture leaner
|
||||
9 - Landing Gear Toggle
|
||||
************************************************************************
|
||||
-->
|
||||
<PropertyList>
|
||||
<name type="string">Padix Co. Ltd. 10-Button USB Joystick</name> <!-- GNU/Linux. -->
|
||||
<name type="string">10-Button USB Joystick with Vibration</name> <!-- Windows with vibration driver.-->
|
||||
<name type="string">10-Button USB Joystick</name> <!-- Windows without vibration driver.-->
|
||||
|
||||
<axis n="0">
|
||||
<desc>Aileron</desc>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/aileron</property>
|
||||
<power type="int">2</power>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis n="1">
|
||||
<desc>Elevator</desc>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/elevator</property>
|
||||
<power type="int">2</power>
|
||||
<factor type="double">-1.0</factor> <!-- Reverse axis. -->
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis>
|
||||
<desc>Rudder</desc>
|
||||
<number>
|
||||
<unix>2</unix>
|
||||
<windows>3</windows>
|
||||
</number>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/rudder</property>
|
||||
<power type="int">2</power>
|
||||
<factor type="double">-1.0</factor> <!-- Reverse axis. -->
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis>
|
||||
<desc>Throttle</desc>
|
||||
<number>
|
||||
<unix>3</unix>
|
||||
<windows>2</windows>
|
||||
</number>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.throttleAxis()</script>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis>
|
||||
<desc>View Direction</desc>
|
||||
<number>
|
||||
<unix>4</unix>
|
||||
<windows>6</windows>
|
||||
</number>
|
||||
<low>
|
||||
<desc>View left</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<!--
|
||||
This also works, but LookAt views has inverted left/right.
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-heading-offset-deg</property>
|
||||
<step type="double">3.0</step>
|
||||
-->
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
var valueDelta = -3.0;
|
||||
if (getprop("/sim/current-view/type") == "lookat")
|
||||
{
|
||||
valueDelta = 3.0;
|
||||
}
|
||||
setprop("/sim/current-view/heading-offset-deg", getprop("/sim/current-view/heading-offset-deg") - valueDelta);
|
||||
</script>
|
||||
</binding>
|
||||
</low>
|
||||
<high>
|
||||
<desc>View right</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<!--
|
||||
This also works, but LookAt views has inverted left/right.
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-heading-offset-deg</property>
|
||||
<step type="double">-3.0</step>
|
||||
-->
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
var valueDelta = -3.0;
|
||||
if (getprop("/sim/current-view/type") == "lookat")
|
||||
{
|
||||
valueDelta = 3.0;
|
||||
}
|
||||
setprop("/sim/current-view/heading-offset-deg", getprop("/sim/current-view/heading-offset-deg") + valueDelta);
|
||||
</script>
|
||||
</binding>
|
||||
</high>
|
||||
</axis>
|
||||
|
||||
<axis>
|
||||
<desc>View Elevation</desc>
|
||||
<number>
|
||||
<unix>5</unix>
|
||||
<windows>7</windows>
|
||||
</number>
|
||||
<low>
|
||||
<desc>View down</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-pitch-offset-deg</property>
|
||||
<step type="double">3.0</step> <!-- Use -3.0 for Windows. -->
|
||||
</binding>
|
||||
</low>
|
||||
<high>
|
||||
<desc>View up</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-pitch-offset-deg</property>
|
||||
<step type="double">-3.0</step> <!-- Use 3.0 for Windows. -->
|
||||
</binding>
|
||||
</high>
|
||||
</axis>
|
||||
|
||||
|
||||
<button n="0">
|
||||
<desc>Brakes</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="1">
|
||||
<desc>Cycle View</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
view.stepView(1);
|
||||
#gui.popupTip(sprintf("View index: %d, view type: %s", getprop("sim/current-view/view-number"), getprop("/sim/current-view/type")));
|
||||
</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="2">
|
||||
<desc>Elevator trim up</desc>
|
||||
<repeatable type="bool">true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.elevatorTrim(1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="3">
|
||||
<desc>Elevator trim down</desc>
|
||||
<repeatable type="bool">true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.elevatorTrim(-1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="4">
|
||||
<desc>Flaps down</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="5">
|
||||
<desc>Flaps up</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(-1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="6">
|
||||
<desc>Brakes</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="7">
|
||||
<desc>Mixture richer</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.adjMixture(1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="8">
|
||||
<desc>Mixture leaner</desc>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.adjMixture(-1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="9">
|
||||
<desc>Landing Gear Toggle</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.gearToggle()</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
</PropertyList>
|
|
@ -442,7 +442,7 @@
|
|||
<col>0</col>
|
||||
<live>true</live>
|
||||
<halign>fill</halign>
|
||||
<property>/environment/metar/rain-norm</property>
|
||||
<property>/environment/rain-norm</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
|
@ -459,7 +459,7 @@
|
|||
<row>1</row>
|
||||
<col>1</col>
|
||||
<halign>fill</halign>
|
||||
<property>/environment/metar/snow-norm</property>
|
||||
<property>/environment/snow-norm</property>
|
||||
<live>true</live>
|
||||
<pref-height>30</pref-height>
|
||||
<binding>
|
||||
|
@ -1601,7 +1601,7 @@
|
|||
combo.getChild("value", i, 1).setValue(scenarios[i].getNode("name").getValue());
|
||||
}
|
||||
|
||||
me.scenarioListenerId = setlistener( me.base ~ "/source-selection", func(n) { me.scenarioListener(n); } );
|
||||
me.scenarioListenerId = setlistener( me.base ~ "/source-selection", func(n) { me.scenarioListener(n); }, 1, 1 );
|
||||
me.metarListenerId = setlistener( "environment/metar/valid", func(n) { me.metarListener(n); }, 1, 1 );
|
||||
},
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<script>gui.save_flight()</script>
|
||||
</binding>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<label>Scenario</label>
|
||||
<binding>
|
||||
|
@ -44,7 +44,7 @@
|
|||
setprop(d, f < 0 ? 0 : f > 2 ? 0 : f);
|
||||
</script>
|
||||
</binding>
|
||||
</item>
|
||||
</item>
|
||||
<label>High-Res Snapshot</label>
|
||||
<enabled>false</enabled>
|
||||
<binding>
|
||||
|
@ -459,13 +459,13 @@
|
|||
<menu>
|
||||
<label>AI</label>
|
||||
<item>
|
||||
<label>AI Options</label>
|
||||
<label>Traffic Options</label>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>ai</dialog-name>
|
||||
</binding>
|
||||
</item>
|
||||
<!-- Not working at present
|
||||
<!-- Not working at present
|
||||
<item>
|
||||
<label>ATC Services in range</label>
|
||||
<binding>
|
||||
|
@ -475,7 +475,7 @@
|
|||
|
||||
-->
|
||||
<item>
|
||||
<label>AI Formation</label>
|
||||
<label>Wingman Controls</label>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>formation</dialog-name>
|
||||
|
@ -483,7 +483,7 @@
|
|||
</item>
|
||||
|
||||
<item>
|
||||
<label>AI Tanker</label>
|
||||
<label>Tanker Controls</label>
|
||||
<name>tanker</name>
|
||||
<enabled>false</enabled>
|
||||
<binding>
|
||||
|
@ -493,7 +493,7 @@
|
|||
</item>
|
||||
|
||||
<item>
|
||||
<label>AI Carrier Options</label>
|
||||
<label>Carrier Controls</label>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>AIcarrier</dialog-name>
|
||||
|
@ -501,7 +501,7 @@
|
|||
</item>
|
||||
|
||||
<item>
|
||||
<label>AI Scenario Select - takes effect on next run </label>
|
||||
<label>Scenario Select - takes effect on next run</label>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>scenario</dialog-name>
|
||||
|
@ -702,6 +702,14 @@
|
|||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<label>Aircraft Help (?)</label>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>gui.showHelpDialog("/sim/help")</script>
|
||||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<label>Joystick Information</label>
|
||||
<name>joystick-info</name>
|
||||
|
@ -724,23 +732,7 @@
|
|||
</item>
|
||||
|
||||
<item>
|
||||
<label>Common Aircraft Keys</label>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>gui.showHelpDialog("/sim/help/common")</script>
|
||||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<label> Current Aircraft Keys (?)</label>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>gui.showHelpDialog("/sim/help")</script>
|
||||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<label> ---------------------</label>
|
||||
<label> ------------------</label>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
|
|
Loading…
Reference in a new issue