25c46a69bc
Rework of the generic autopilot https://sourceforge.net/p/flightgear/fgdata/merge-requests/284/ Control: Improve FPA engagement smoothness Control: Generic autopilot logical improvement
534 lines
19 KiB
XML
534 lines
19 KiB
XML
<?xml version="1.0"?>
|
|
<PropertyList>
|
|
<name>autopilot</name>
|
|
<layout>vbox</layout>
|
|
<!--
|
|
/autopilot/locks/altitude
|
|
/autopilot/locks/heading
|
|
/autopilot/locks/speed
|
|
/autopilot/settings/heading-bug-deg
|
|
/autopilot/settings/target-roll-deg
|
|
/autopilot/settings/target-agl-ft
|
|
/autopilot/settings/target-altitude-ft
|
|
/autopilot/settings/target-fpa-deg
|
|
/autopilot/settings/target-pitch-deg
|
|
/autopilot/settings/target-speed-kt
|
|
/autopilot/settings/target-speed-mach
|
|
/autopilot/settings/true-heading-deg
|
|
/autopilot/settings/vertical-speed-fpm
|
|
-->
|
|
|
|
<group>
|
|
<layout>hbox</layout>
|
|
<empty><stretch>1</stretch></empty>
|
|
|
|
<text>
|
|
<label>Autopilot Settings</label>
|
|
</text>
|
|
|
|
<empty><stretch>1</stretch></empty>
|
|
|
|
<button>
|
|
<pref-width>16</pref-width>
|
|
<pref-height>16</pref-height>
|
|
<legend></legend>
|
|
<default>1</default>
|
|
<keynum>27</keynum>
|
|
<border>2</border>
|
|
<binding>
|
|
<command>dialog-close</command>
|
|
</binding>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</button>
|
|
</group>
|
|
<hrule/>
|
|
<nasal>
|
|
<open>
|
|
## manage one AP property group with checkbox and radio buttons
|
|
#
|
|
Group = {
|
|
new : func(name, options) {
|
|
var m = { parents: [Group] };
|
|
m.name = name;
|
|
m.enabled = 0;
|
|
m.mode = options[0];
|
|
m.options = [];
|
|
|
|
var locks = props.globals.getNode("/autopilot/locks", 1);
|
|
if (locks.getNode(name) == nil or locks.getNode(name, 1).getValue() == nil) {
|
|
locks.getNode(name, 1).setValue("");
|
|
}
|
|
m.lock = locks.getNode(name);
|
|
m.active = dlg.getNode(name ~ "-active", 1);
|
|
|
|
foreach (var o; options) {
|
|
var node = dlg.getNode(o);
|
|
if (node == nil) {
|
|
node = dlg.getNode(o, 1);
|
|
node.setBoolValue(0);
|
|
}
|
|
append(m.options, node);
|
|
if (m.lock.getValue() == o) {
|
|
m.mode = o;
|
|
}
|
|
}
|
|
m.listener = setlistener(m.lock, func(n) { m.update(n.getValue()) }, 1);
|
|
return m;
|
|
},
|
|
del : func {
|
|
removelistener(me.listener);
|
|
},
|
|
|
|
## handle checkbox
|
|
#
|
|
enable : func {
|
|
me.enabled = me.active.getBoolValue();
|
|
me.lock.setValue(me.enabled ? me.mode : "");
|
|
},
|
|
|
|
## handle radiobuttons
|
|
#
|
|
set : func(mode) {
|
|
me.mode = mode;
|
|
foreach (var o; me.options) {
|
|
o.setBoolValue(o.getName() == mode);
|
|
}
|
|
if (me.enabled) {
|
|
me.lock.setValue(mode);
|
|
}
|
|
},
|
|
|
|
## update checkboxes/radiobuttons state from the AP (listener callback)
|
|
#
|
|
update : func(mode) {
|
|
me.enabled = (mode != "");
|
|
me.active.setBoolValue(me.enabled);
|
|
if (mode == "") {
|
|
mode = me.mode;
|
|
}
|
|
foreach (var o; me.options) {
|
|
o.setBoolValue(o.getName() == mode);
|
|
}
|
|
},
|
|
};
|
|
|
|
|
|
## create and initialize input field properties if necessary
|
|
#
|
|
var apset = props.globals.getNode("/autopilot/settings", 1);
|
|
foreach (var p; ["heading-bug-deg", "target-roll-deg", "true-heading-deg", "vertical-speed-fpm",
|
|
"target-pitch-deg", "target-fpa-deg", "target-altitude-ft",
|
|
"target-agl-ft", "target-speed-kt", "target-speed-mach"]) {
|
|
|
|
if ((var n = apset.getNode(p)) == nil or n.getType() == "NONE") {
|
|
apset.getNode(p, 1).setDoubleValue(0);
|
|
}
|
|
}
|
|
|
|
var dlg = props.globals.getNode("/sim/gui/dialogs/autopilot", 1);
|
|
|
|
# - first entry ("heading" etc.) is the target property in /autopilot/locks/ *and*
|
|
# the checkbox state property name (with "-active" appended);
|
|
# - second entry is a list of available options for the /autopilot/locks/* property
|
|
# and used as radio button state property; the first list entry is used as default
|
|
#
|
|
var hdg = Group.new("heading", ["dg-heading-hold", "wing-leveler", "true-heading-hold", "nav1-hold"]);
|
|
var vel = Group.new("speed", ["speed-with-throttle", "speed-with-pitch-trim"]);
|
|
var alt = Group.new("altitude", ["altitude-hold", "vertical-speed-hold", "pitch-hold",
|
|
"fpa-hold", "agl-hold", "gs1-hold"]);
|
|
</open>
|
|
<close>
|
|
hdg.del();
|
|
vel.del();
|
|
alt.del();
|
|
</close>
|
|
</nasal>
|
|
<group>
|
|
<layout>hbox</layout>
|
|
<default-padding>8</default-padding>
|
|
<group>
|
|
<!-- Heading -->
|
|
<layout>vbox</layout>
|
|
<group>
|
|
<layout>hbox</layout>
|
|
<checkbox>
|
|
<label>Heading Control</label>
|
|
<halign>fill</halign>
|
|
<property>/sim/gui/dialogs/autopilot/heading-active</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>hdg.enable()</script>
|
|
</binding>
|
|
</checkbox>
|
|
</group>
|
|
<group>
|
|
<layout>table</layout>
|
|
<text>
|
|
<label>Wings Level</label>
|
|
<halign>right</halign>
|
|
<row>0</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>0</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/wing-leveler</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>hdg.set("wing-leveler")</script>
|
|
</binding>
|
|
</radio>
|
|
<text>
|
|
<label>Heading Bug</label>
|
|
<halign>right</halign>
|
|
<row>1</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>1</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/dg-heading-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>hdg.set("dg-heading-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>1</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/heading-bug-deg</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>True Heading</label>
|
|
<halign>right</halign>
|
|
<row>2</row>
|
|
<col>0</col>
|
|
<visible>
|
|
<not>
|
|
<property>/autopilot/settings/gps-driving-true-heading</property>
|
|
</not>
|
|
</visible>
|
|
</text>
|
|
<!-- alternate UI for above, when GPS is controlling -->
|
|
<text>
|
|
<visible>
|
|
<property>/autopilot/settings/gps-driving-true-heading</property>
|
|
</visible>
|
|
<label>GPS/FMS Heading</label>
|
|
<halign>right</halign>
|
|
<row>2</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>2</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/true-heading-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>hdg.set("true-heading-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<visible>
|
|
<not>
|
|
<property>/autopilot/settings/gps-driving-true-heading</property>
|
|
</not>
|
|
</visible>
|
|
<row>2</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/true-heading-deg</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<!-- alternate UI for above, when GPS is controlling -->
|
|
<text>
|
|
<visible>
|
|
<property>/autopilot/settings/gps-driving-true-heading</property>
|
|
</visible>
|
|
<halign>right</halign>
|
|
<row>2</row>
|
|
<col>2</col>
|
|
<label>MMMM</label>
|
|
<format>%3.0f*</format>
|
|
<property>/autopilot/settings/true-heading-deg</property>
|
|
<live>true</live>
|
|
</text>
|
|
<text>
|
|
<label>NAV1 CDI Course</label>
|
|
<halign>right</halign>
|
|
<row>3</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>3</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/nav1-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>hdg.set("nav1-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
</group>
|
|
<hrule/>
|
|
<group>
|
|
<layout>hbox</layout>
|
|
<checkbox>
|
|
<label>Velocity Control</label>
|
|
<halign>fill</halign>
|
|
<property>/sim/gui/dialogs/autopilot/speed-active</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>vel.enable()</script>
|
|
</binding>
|
|
</checkbox>
|
|
</group>
|
|
<group>
|
|
<layout>table</layout>
|
|
<text>
|
|
<label>Speed with Throttle</label>
|
|
<halign>right</halign>
|
|
<row>0</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>0</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/speed-with-throttle</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>vel.set("speed-with-throttle")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>0</row>
|
|
<col>2</col>
|
|
<rowspan>2</rowspan>
|
|
<property>/autopilot/settings/target-speed-kt</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>Speed with Pitch</label>
|
|
<halign>right</halign>
|
|
<row>1</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>1</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/speed-with-pitch-trim</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>vel.set("speed-with-pitch-trim")</script>
|
|
</binding>
|
|
</radio>
|
|
</group>
|
|
</group>
|
|
<!-- End of Heading/Speed -->
|
|
<vrule/>
|
|
<group>
|
|
<!-- Pitch/Altitude -->
|
|
<layout>vbox</layout>
|
|
<group>
|
|
<layout>hbox</layout>
|
|
<checkbox>
|
|
<label>Pitch/Altitude Control</label>
|
|
<halign>fill</halign>
|
|
<property>/sim/gui/dialogs/autopilot/altitude-active</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.enable()</script>
|
|
</binding>
|
|
</checkbox>
|
|
</group>
|
|
<group>
|
|
<layout>table</layout>
|
|
<text>
|
|
<label>Vertical Speed</label>
|
|
<halign>right</halign>
|
|
<row>0</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>0</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/vertical-speed-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("vertical-speed-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>0</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/vertical-speed-fpm</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>Pitch Hold</label>
|
|
<halign>right</halign>
|
|
<row>1</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>1</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/pitch-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("pitch-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>1</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/target-pitch-deg</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>FPA Hold</label>
|
|
<halign>right</halign>
|
|
<row>2</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>2</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/fpa-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("fpa-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>2</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/target-fpa-deg</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>Altitude Hold</label>
|
|
<halign>right</halign>
|
|
<row>3</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>3</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/altitude-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("altitude-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>3</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/target-altitude-ft</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>AGL Hold</label>
|
|
<halign>right</halign>
|
|
<row>4</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>4</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/agl-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("agl-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
<input>
|
|
<row>4</row>
|
|
<col>2</col>
|
|
<property>/autopilot/settings/target-agl-ft</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
</input>
|
|
<text>
|
|
<label>NAV1 Glideslope</label>
|
|
<halign>right</halign>
|
|
<row>5</row>
|
|
<col>0</col>
|
|
</text>
|
|
<radio>
|
|
<row>5</row>
|
|
<col>1</col>
|
|
<property>/sim/gui/dialogs/autopilot/gs1-hold</property>
|
|
<live>true</live>
|
|
<binding>
|
|
<command>nasal</command>
|
|
<script>alt.set("gs1-hold")</script>
|
|
</binding>
|
|
</radio>
|
|
</group>
|
|
<empty>
|
|
<stretch>true</stretch>
|
|
</empty>
|
|
</group>
|
|
<!-- End of Pitch/Altitude VBox -->
|
|
</group>
|
|
|
|
<hrule/>
|
|
|
|
<button>
|
|
<legend>Close</legend>
|
|
<default>true</default>
|
|
<key>Esc</key>
|
|
<binding>
|
|
<command>dialog-close</command>
|
|
</binding>
|
|
</button>
|
|
|
|
</PropertyList>
|