Merge branch 'master' into ECAM3

This commit is contained in:
Josh Davidson 2019-03-24 00:06:54 -04:00
commit 2a73b57ac5
20 changed files with 1124 additions and 250 deletions

View file

@ -23,7 +23,7 @@
</hud> </hud>
<model> <model>
<pushback> <autopush>
<connected type="bool">0</connected> <connected type="bool">0</connected>
<position-norm type="double">0</position-norm> <position-norm type="double">0</position-norm>
<enabled type="int"/> <enabled type="int"/>
@ -39,18 +39,18 @@
<F_i type="float">0.1</F_i> <F_i type="float">0.1</F_i>
<K_d type="float">0.0</K_d> <K_d type="float">0.0</K_d>
<F_d type="float">0.0</F_d> <F_d type="float">0.0</F_d>
<pitch-deg type="float">0.0</pitch-deg>
<min-turn-radius-m type="float">15</min-turn-radius-m>
<stopping-distance-m type="float">5.0</stopping-distance-m>
<driver> <driver>
<K_V type="float">5.5</K_V>
<F_V type="float">5.5</F_V> <F_V type="float">5.5</F_V>
<D_min-m type="float">5.0</D_min-m>
<K_psi type="float">0.03</K_psi> <K_psi type="float">0.03</K_psi>
<debug type="bool">true</debug>
</driver> </driver>
<route> <route>
<show type="bool"/> <show type="bool"/>
<view type="string">Model View</view>
</route> </route>
</pushback> <debug type="bool">false</debug>
</autopush>
<icing> <icing>
<iceable> <iceable>
<name>Wing</name> <name>Wing</name>
@ -429,9 +429,9 @@
<jsbsim> <jsbsim>
<external_reactions> <external_reactions>
<tractor> <tractor>
<magnitude alias="/sim/model/pushback/force-lbf"/> <magnitude alias="/sim/model/autopush/force-lbf"/>
<x alias="/sim/model/pushback/force-x"/> <x alias="/sim/model/autopush/force-x"/>
<y alias="/sim/model/pushback/force-y"/> <y alias="/sim/model/autopush/force-y"/>
</tractor> </tractor>
</external_reactions> </external_reactions>
</jsbsim> </jsbsim>

View file

@ -94,6 +94,8 @@ setprop("/systems/acconfig/options/nd-rate", 1);
setprop("/systems/acconfig/options/uecam-rate", 1); setprop("/systems/acconfig/options/uecam-rate", 1);
setprop("/systems/acconfig/options/lecam-rate", 1); setprop("/systems/acconfig/options/lecam-rate", 1);
setprop("/systems/acconfig/options/iesi-rate", 1); setprop("/systems/acconfig/options/iesi-rate", 1);
setprop("/systems/acconfig/options/autopush/show-route", 1);
setprop("/systems/acconfig/options/autopush/show-wingtip", 1);
var main_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/main/dialog", "Aircraft/IDG-A32X/AircraftConfig/main.xml"); var main_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/main/dialog", "Aircraft/IDG-A32X/AircraftConfig/main.xml");
var welcome_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/welcome/dialog", "Aircraft/IDG-A32X/AircraftConfig/welcome.xml"); var welcome_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/welcome/dialog", "Aircraft/IDG-A32X/AircraftConfig/welcome.xml");
var ps_load_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/psload/dialog", "Aircraft/IDG-A32X/AircraftConfig/psload.xml"); var ps_load_dlg = gui.Dialog.new("sim/gui/dialogs/acconfig/psload/dialog", "Aircraft/IDG-A32X/AircraftConfig/psload.xml");
@ -215,12 +217,17 @@ var readSettings = func {
setprop("/options/system/keyboard-mode", getprop("/systems/acconfig/options/keyboard-mode")); setprop("/options/system/keyboard-mode", getprop("/systems/acconfig/options/keyboard-mode"));
setprop("/options/system/laptop-mode", getprop("/systems/acconfig/options/laptop-mode")); setprop("/options/system/laptop-mode", getprop("/systems/acconfig/options/laptop-mode"));
setprop("/controls/adirs/skip", getprop("/systems/acconfig/options/adirs-skip")); setprop("/controls/adirs/skip", getprop("/systems/acconfig/options/adirs-skip"));
setprop("/sim/model/autopush/route/show", getprop("/systems/acconfig/options/autopush/show-route"));
setprop("/sim/model/autopush/route/show-wingtip", getprop("/systems/acconfig/options/autopush/show-wingtip"));
} }
var writeSettings = func { var writeSettings = func {
setprop("/systems/acconfig/options/keyboard-mode", getprop("/options/system/keyboard-mode")); setprop("/systems/acconfig/options/keyboard-mode", getprop("/options/system/keyboard-mode"));
setprop("/systems/acconfig/options/laptop-mode", getprop("/options/system/laptop-mode")); setprop("/systems/acconfig/options/laptop-mode", getprop("/options/system/laptop-mode"));
setprop("/systems/acconfig/options/adirs-skip", getprop("/controls/adirs/skip")); setprop("/systems/acconfig/options/adirs-skip", getprop("/controls/adirs/skip"));
setprop("/systems/acconfig/options/autopush/show-route", getprop("/sim/model/autopush/route/show"));
setprop("/systems/acconfig/options/autopush/show-wingtip", getprop("/sim/model/autopush/route/show-wingtip"));
io.write_properties(getprop("/sim/fg-home") ~ "/Export/IDG-A32X-config.xml", "/systems/acconfig/options"); io.write_properties(getprop("/sim/fg-home") ~ "/Export/IDG-A32X-config.xml", "/systems/acconfig/options");
} }

View file

@ -78,15 +78,15 @@ Distribute under the terms of GPLv2.
<animation> <animation>
<type>select</type> <type>select</type>
<condition> <condition>
<!-- SETTING Whether connected: /sim/model/pushback/connected --> <!-- SETTING Whether connected: /sim/model/autopush/connected -->
<property>sim/model/pushback/connected</property> <property>sim/model/autopush/connected</property>
</condition> </condition>
</animation> </animation>
<animation> <animation>
<type>rotate</type> <type>rotate</type>
<property>sim/model/pushback/yaw</property> <property>sim/model/autopush/yaw</property>
<!-- SETTING The value of /sim/model/pushback/yaw-mult. --> <!-- SETTING The value of /sim/model/autopush/yaw-mult. -->
<factor>60.0</factor> <factor>60.0</factor>
<center> <center>
<x-m>0</x-m> <x-m>0</x-m>

View file

@ -21,9 +21,26 @@ Distribute under the terms of GPLv2.
<animation> <animation>
<type>scale</type> <type>scale</type>
<property>/sim/model/pushback/driver/D_min-m</property> <property>/sim/model/autopush/stopping-distance-m</property>
<z-factor>0.0</z-factor> <z-factor>0.0</z-factor>
<z-min>1.0</z-min> <z-min>1.0</z-min>
</animation> </animation>
<animation>
<type>material</type>
<condition>
<property>/sim/model/autopush/route/invalid</property>
</condition>
<diffuse>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</diffuse>
<emission>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</emission>
</animation>
</PropertyList> </PropertyList>

View file

@ -0,0 +1,133 @@
AC3Db
MATERIAL "autopush cursor" rgb 0.0000 0.0000 0.0000 amb 0.0000 0.0000 0.0000 emis 1.000 0.173 0.545 spec 0.0000 0.0000 0.0000 shi 50 trans 0.0000
OBJECT world
name "Blender_exporter_v2.26__cursor_reverse.ac"
kids 1
OBJECT poly
name "Circle"
data 11
Circle.mesh
crease 40.0
numvert 36
-0.86603 0.2 0.15
-0.64952 0.2 0.15
-0.64952 0.2 -0.375
-0.86603 0.2 -0.15
-0.64952 0.2 -0.15
-0.86603 0.2 -0.5
-0.56292 0.2 -0.675
-0.45466 0.2 -0.4875
-0 0.2 -0.75
-0 0.2 -1
-0.30311 0.2 -0.825
-0.19486 0.2 -0.6375
0.30311 0.2 -0.825
0.19486 0.2 -0.6375
0.64952 0.2 -0.375
0.86603 0.2 -0.5
0.56292 0.2 -0.675
0.45466 0.2 -0.4875
0.86603 0.2 -0.15
0.64952 0.2 -0.15
0.86603 0.2 0.5
0.86603 0.2 0.15
0.64952 0.2 0.15
0.64952 0.2 0.375
0.56292 0.2 0.675
0.45466 0.2 0.4875
0.30311 0.2 0.825
0.19486 0.2 0.6375
-0 0.2 0.75
-0 0.2 1
-0.30311 0.2 0.825
-0.19486 0.2 0.6375
-0.64952 0.2 0.375
-0.86603 0.2 0.5
-0.56292 0.2 0.675
-0.45466 0.2 0.4875
numsurf 12
SURF 0X10
mat 0
refs 4
2 0.078125 0.40625
5 0.0625 0.375
3 0.0625 0.5
4 0.078125 0.5
SURF 0X10
mat 0
refs 4
32 0.078125 0.40625
1 0.078125 0.5
0 0.0625 0.5
33 0.0625 0.375
SURF 0X10
mat 0
refs 4
8 0.078125 0.40625
9 0.0625 0.375
10 0.0625 0.5
11 0.078125 0.5
SURF 0X10
mat 0
refs 4
2 0.078125 0.40625
7 0.078125 0.5
6 0.0625 0.5
5 0.0625 0.375
SURF 0X10
mat 0
refs 4
14 0.078125 0.40625
15 0.0625 0.375
16 0.0625 0.5
17 0.078125 0.5
SURF 0X10
mat 0
refs 4
8 0.078125 0.40625
13 0.078125 0.5
12 0.0625 0.5
9 0.0625 0.375
SURF 0X10
mat 0
refs 4
23 0.078125 0.40625
20 0.0625 0.375
21 0.0625 0.5
22 0.078125 0.5
SURF 0X10
mat 0
refs 4
14 0.078125 0.40625
19 0.078125 0.5
18 0.0625 0.5
15 0.0625 0.375
SURF 0X10
mat 0
refs 4
28 0.078125 0.40625
29 0.0625 0.375
26 0.0625 0.5
27 0.078125 0.5
SURF 0X10
mat 0
refs 4
23 0.078125 0.40625
25 0.078125 0.5
24 0.0625 0.5
20 0.0625 0.375
SURF 0X10
mat 0
refs 4
32 0.078125 0.40625
33 0.0625 0.375
34 0.0625 0.5
35 0.078125 0.5
SURF 0X10
mat 0
refs 4
28 0.078125 0.40625
31 0.078125 0.5
30 0.0625 0.5
29 0.0625 0.375
kids 0

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
AUTOPUSH
Cursor model.
Copyright (c) 2018 Autopush authors:
Michael Danilov <mike.d.ft402 -eh- gmail.com>
Joshua Davidson http://github.com/it0uchpods
Merspieler http://gitlab.com/merspieler
Distribute under the terms of GPLv2.
-->
<PropertyList>
<path>cursor_reverse.ac</path>
<animation>
<enable-hot>false</enable-hot>
</animation>
<animation>
<type>scale</type>
<property>/sim/model/autopush/stopping-distance-m</property>
<z-factor>0.0</z-factor>
<z-min>1.0</z-min>
</animation>
<animation>
<type>material</type>
<condition>
<property>/sim/model/autopush/route/invalid</property>
</condition>
<diffuse>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</diffuse>
<emission>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</emission>
</animation>
</PropertyList>

View file

@ -21,9 +21,26 @@ Distribute under the terms of GPLv2.
<animation> <animation>
<type>scale</type> <type>scale</type>
<property>/sim/model/pushback/driver/D_min-m</property> <property>/sim/model/autopush/stopping-distance-m</property>
<z-factor>0.0</z-factor> <z-factor>0.0</z-factor>
<z-min>1.0</z-min> <z-min>1.0</z-min>
</animation> </animation>
<animation>
<type>material</type>
<condition>
<property>/sim/model/autopush/route/invalid</property>
</condition>
<diffuse>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</diffuse>
<emission>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</emission>
</animation>
</PropertyList> </PropertyList>

View file

@ -2,9 +2,9 @@ AC3Db
MATERIAL "autopush cursor" rgb 0.0000 0.0000 0.0000 amb 0.0000 0.0000 0.0000 emis 1.000 0.173 0.545 spec 0.0000 0.0000 0.0000 shi 50 trans 0.0000 MATERIAL "autopush cursor" rgb 0.0000 0.0000 0.0000 amb 0.0000 0.0000 0.0000 emis 1.000 0.173 0.545 spec 0.0000 0.0000 0.0000 shi 50 trans 0.0000
OBJECT world OBJECT world
name "Blender_exporter_v2.26__waypoint.ac" name "Blender_exporter_v2.26__waypoint.ac"
kids 1 kids 3
OBJECT poly OBJECT poly
name "Circle" name "Waypoint"
data 11 data 11
Circle.mesh Circle.mesh
crease 40.0 crease 40.0
@ -16,7 +16,7 @@ numvert 33
0.16629 0.2 -0.11111 0.16629 0.2 -0.11111
0.18478 0.2 -0.07654 0.18478 0.2 -0.07654
0.19616 0.2 -0.03902 0.19616 0.2 -0.03902
0.2 0.2 -0 0.2 0.2 0
0.19616 0.2 0.03902 0.19616 0.2 0.03902
0.18478 0.2 0.07654 0.18478 0.2 0.07654
0.16629 0.2 0.11111 0.16629 0.2 0.11111
@ -236,3 +236,41 @@ refs 3
5 0.182742 0.595671 5 0.182742 0.595671
4 0.176967 0.638893 4 0.176967 0.638893
kids 0 kids 0
OBJECT poly
name "WingtipL"
data 15
Circle.mesh.001
crease 40.0
numvert 4
-0.1 0.2 -0.1
-0.1 0.2 0.1
0.1 0.2 -0.1
0.1 0.2 0.1
numsurf 1
SURF 0X0
mat 0
refs 4
0 0 0
1 0 0
3 0 0
2 0 0
kids 0
OBJECT poly
name "WingtipR"
data 15
Circle.mesh.007
crease 40.0
numvert 4
-0.1 0.2 -0.1
-0.1 0.2 0.1
0.1 0.2 -0.1
0.1 0.2 0.1
numsurf 1
SURF 0X0
mat 0
refs 4
0 0 0
1 0 0
3 0 0
2 0 0
kids 0

View file

@ -20,10 +20,68 @@ Distribute under the terms of GPLv2.
</animation> </animation>
<animation> <animation>
<type>scale</type> <type>select</type>
<property>/sim/model/pushback/driver/D_min-m</property> <object-name>WingtipL</object-name>
<object-name>WingtipR</object-name>
<condition>
<property>/sim/model/autopush/route/show-wingtip</property>
</condition>
</animation>
<animation>
<type>translate</type>
<object-name>WingtipL</object-name>
<property>/sim/model/autopush/route/wingspan-m</property>
<factor>0.5</factor>
<axis>
<x>0</x>
<y>1</y>
<z>0</z>
</axis>
<z-factor>0.0</z-factor> <z-factor>0.0</z-factor>
<z-min>1.0</z-min> <z-min>1.0</z-min>
</animation> </animation>
<animation>
<type>translate</type>
<object-name>WingtipR</object-name>
<property>/sim/model/autopush/route/wingspan-m</property>
<factor>-0.5</factor>
<axis>
<x>0</x>
<y>1</y>
<z>0</z>
</axis>
<z-factor>0.0</z-factor>
<z-min>1.0</z-min>
</animation>
<animation>
<type>scale</type>
<!-- Object names must be here, because we need to scale each separately, not the the whole thing at once. -->
<object-name>Waypoint</object-name>
<object-name>WingtipL</object-name>
<object-name>WingtipR</object-name>
<property>/sim/model/autopush/stopping-distance-m</property>
<z-factor>0.0</z-factor>
<z-min>1.0</z-min>
</animation>
<animation>
<type>material</type>
<condition>
<property>/sim/model/autopush/route/invalid</property>
</condition>
<diffuse>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</diffuse>
<emission>
<red>1.0</red>
<green>0.0</green>
<blue>0.0</blue>
</emission>
</animation>
</PropertyList> </PropertyList>

View file

@ -1,14 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!-- Copyright (c) 2019 Joshua Davidson (it0uchpods) -->
##############################################
# Copyright (c) Joshua Davidson (it0uchpods) #
##############################################
-->
<PropertyList> <PropertyList>
<path>res/Audio1.ac</path> <path>res/Audio.ac</path>
<!-- INT/RAD switch --> <!-- INT/RAD switch -->
<animation> <animation>
@ -118,10 +114,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>vhf1</value> <value>vhf1</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>vhf1</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>vhf1</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -139,10 +162,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>vhf2</value> <value>vhf2</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>vhf2</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>vhf2</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -160,10 +210,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>vhf3</value> <value>vhf3</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>vhf3</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>vhf3</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -181,10 +258,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>hf1</value> <value>hf1</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>hf1</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>hf1</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -202,10 +306,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>hf2</value> <value>hf2</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>hf2</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>hf2</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -223,10 +354,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>mech</value> <value>mech</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>mech</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>mech</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -244,10 +402,37 @@
<property>systems/audio/acp[0]/call_chan</property> <property>systems/audio/acp[0]/call_chan</property>
<value>att</value> <value>att</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[0]/call_chan</property>
</greater-than-equals> <value>att</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[0]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[0]/call_chan</property>
<value>att</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -1471,4 +1656,4 @@
<object-name>audio_adf2.axis</object-name> <object-name>audio_adf2.axis</object-name>
</axis> </axis>
</animation> </animation>
</PropertyList> </PropertyList>

View file

@ -1,14 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!-- Copyright (c) 2019 Joshua Davidson (it0uchpods) -->
##############################################
# Copyright (c) Joshua Davidson (it0uchpods) #
##############################################
-->
<PropertyList> <PropertyList>
<path>res/Audio1.ac</path> <path>res/Audio.ac</path>
<!-- INT/RAD switch --> <!-- INT/RAD switch -->
<animation> <animation>
@ -118,10 +114,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>vhf1</value> <value>vhf1</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>vhf1</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>vhf1</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -139,10 +162,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>vhf2</value> <value>vhf2</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>vhf2</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>vhf2</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -160,10 +210,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>vhf3</value> <value>vhf3</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>vhf3</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>vhf3</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -181,10 +258,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>hf1</value> <value>hf1</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>hf1</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>hf1</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -202,10 +306,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>hf2</value> <value>hf2</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>hf2</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>hf2</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -223,10 +354,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>mech</value> <value>mech</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>mech</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>mech</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -244,10 +402,37 @@
<property>systems/audio/acp[1]/call_chan</property> <property>systems/audio/acp[1]/call_chan</property>
<value>att</value> <value>att</value>
<condition> <condition>
<greater-than-equals> <and>
<property>systems/electrical/bus/dc-ess</property> <not-equals>
<value>25</value> <property>systems/audio/acp[1]/call_chan</property>
</greater-than-equals> <value>att</value>
</not-equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition>
</binding>
</action>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-assign</command>
<property>systems/audio/acp[1]/call_chan</property>
<value></value>
<condition>
<and>
<equals>
<property>systems/audio/acp[1]/call_chan</property>
<value>att</value>
</equals>
<greater-than-equals>
<property>systems/electrical/bus/dc-ess</property>
<value>25</value>
</greater-than-equals>
</and>
</condition> </condition>
</binding> </binding>
</action> </action>
@ -957,7 +1142,7 @@
<factor-prop>sim/model/lights/dome-light</factor-prop> <factor-prop>sim/model/lights/dome-light</factor-prop>
</emission> </emission>
</animation> </animation>
<effect> <effect>
<inherits-from>Aircraft/IDG-A32X/Models/Effects/cockpit-irradiance</inherits-from> <inherits-from>Aircraft/IDG-A32X/Models/Effects/cockpit-irradiance</inherits-from>
<object-name>audio_body</object-name> <object-name>audio_body</object-name>
@ -1471,5 +1656,4 @@
<object-name>audio_adf2.axis</object-name> <object-name>audio_adf2.axis</object-name>
</axis> </axis>
</animation> </animation>
</PropertyList>
</PropertyList>

View file

@ -10,7 +10,7 @@
<!-- switch to night/day textures --> <!-- switch to night/day textures -->
<animation> <animation>
<type>textranslate</type> <type>textranslate</type>
<property>/sim/time/sun-angle-rad</property> <property>sim/time/sun-angle-rad</property>
<step>1.60</step> <step>1.60</step>
<factor>0.318471338</factor> <factor>0.318471338</factor>
<center> <center>
@ -29,7 +29,7 @@
<type>material</type> <type>material</type>
<condition> <condition>
<greater-than> <greater-than>
<property>/sim/time/sun-angle-rad</property> <property>sim/time/sun-angle-rad</property>
<value>1.60</value> <value>1.60</value>
</greater-than> </greater-than>
</condition> </condition>
@ -44,7 +44,7 @@
<type>material</type> <type>material</type>
<condition> <condition>
<less-than-equals> <less-than-equals>
<property>/sim/time/sun-angle-rad</property> <property>sim/time/sun-angle-rad</property>
<value>1.60</value> <value>1.60</value>
</less-than-equals> </less-than-equals>
</condition> </condition>
@ -58,7 +58,7 @@
<animation> <animation>
<type>select</type> <type>select</type>
<condition> <condition>
<property>sim/model/pushback/enabled</property> <property>sim/model/autopush/enabled</property>
<property>gear/gear[0]/wow</property> <property>gear/gear[0]/wow</property>
</condition> </condition>
</animation> </animation>

View file

@ -380,7 +380,7 @@ var messages_right_memo = func {
rat.colour = "g"; rat.colour = "g";
} }
if (getprop("/sim/model/pushback/enabled") == 1) { # this message is only on when towing - not when disc with switch if (getprop("/sim/model/autopush/enabled") == 1) { # this message is only on when towing - not when disc with switch
nw_strg_disc.active = 1; nw_strg_disc.active = 1;
} else { } else {
nw_strg_disc.active = 0; nw_strg_disc.active = 0;

View file

@ -27,30 +27,30 @@ var _unitconv = M2FT / 3.6;
var _debug = nil; var _debug = nil;
var _loop = func() { var _loop = func() {
if (!getprop("/sim/model/pushback/available")) { if (!getprop("/sim/model/autopush/available")) {
_stop(); _stop();
return; return;
} }
var force = 0.0; var force = 0.0;
var x = 0.0; var x = 0.0;
var y = 0.0; var y = 0.0;
var z = 0.0;
# Rollspeed is only adequate if the wheel is touching the ground. # Rollspeed is only adequate if the wheel is touching the ground.
if (getprop("/gear/gear[0]/wow")) { if (getprop("/gear/gear[0]/wow")) {
var V = getprop("/gear/gear[0]/rollspeed-ms") * 3.6; var V = getprop("/gear/gear[0]/rollspeed-ms") * 3.6;
var deltaV = getprop("/sim/model/pushback/target-speed-km_h") - V; var deltaV = getprop("/sim/model/autopush/target-speed-km_h") - V;
var dV = V - _V; var minus_dV = _V - V;
var time = getprop("/sim/time/elapsed-sec"); var time = getprop("/sim/time/elapsed-sec");
var prop = math.min(math.max(_K_p * deltaV, -_F_p), _F_p); var prop = math.min(math.max(_K_p * deltaV, -_F_p), _F_p);
var speedup = getprop("/sim/speed-up"); var dt = time - _time;
var deriv = 0.0; var deriv = 0.0;
dt = time - _time;
# XXX Sanitising dt. Smaller chance of freakout on lag spike. # XXX Sanitising dt. Smaller chance of freakout on lag spike.
if(dt > 0.0) { if(dt > 0.0) {
if(dt < 0.05) { if(dt < 0.05) {
_int = math.min(math.max(_int + _K_i * deltaV * dt, -_F_i), _F_i); _int = math.min(math.max(_int + _K_i * deltaV * dt, -_F_i), _F_i);
} }
if(dt > 0.002) { if(dt > 0.002) {
deriv = math.min(math.max(_K_d * dV / dt, -_F_d), _F_d); deriv = math.min(math.max(_K_d * minus_dV / dt, -_F_d), _F_d);
} }
} }
var accel = prop + _int + deriv; var accel = prop + _int + deriv;
@ -64,18 +64,24 @@ var _loop = func() {
} else { } else {
force = accel * getprop("/fdm/yasim/gross-weight-lbs") * _unitconv; force = accel * getprop("/fdm/yasim/gross-weight-lbs") * _unitconv;
} }
var yaw = getprop("/sim/model/pushback/yaw") * _K_yaw; var pitch = getprop("/sim/model/autopush/pitch-deg") * D2R;
x = math.cos(yaw); z = math.sin(pitch);
y = math.sin(yaw); var pz = math.cos(pitch);
setprop("/sim/model/pushback/force-x", x); var yaw = getprop("/sim/model/autopush/yaw") * _K_yaw;
setprop("/sim/model/pushback/force-y", y); x = math.cos(yaw) * pz;
y = math.sin(yaw) * pz;
setprop("/sim/model/autopush/force-x", x);
setprop("/sim/model/autopush/force-y", y);
# JSBSim force's z is down.
setprop("/sim/model/autopush/force-z", -z);
} }
setprop("/sim/model/pushback/force-lbf", force); setprop("/sim/model/autopush/force-lbf", force);
if (_yasim) { if (_yasim) {
# The force is divided by YASim thrust="100000.0" setting. # The force is divided by YASim thrust="100000.0" setting.
setprop("/sim/model/pushback/force-x-yasim", x * force * 0.00001); setprop("/sim/model/autopush/force-x-yasim", x * force * 0.00001);
# YASim's y is to the left. # YASim force's y is to the left.
setprop("/sim/model/pushback/force-y-yasim", -y * force * 0.00001); setprop("/sim/model/autopush/force-y-yasim", -y * force * 0.00001);
setprop("/sim/model/autopush/force-z-yasim", z * force * 0.00001);
} }
} }
@ -84,26 +90,26 @@ var _timer = maketimer(0.0167, func{_loop()});
var _start = func() { var _start = func() {
# Else overwritten by dialog. # Else overwritten by dialog.
settimer(func() { settimer(func() {
setprop("/sim/model/pushback/target-speed-km_h", 0.0) setprop("/sim/model/autopush/target-speed-km_h", 0.0)
}, 0.1); }, 0.1);
_K_p = getprop("/sim/model/pushback/K_p"); _K_p = getprop("/sim/model/autopush/K_p");
_F_p = getprop("/sim/model/pushback/F_p"); _F_p = getprop("/sim/model/autopush/F_p");
_K_i = getprop("/sim/model/pushback/K_i"); _K_i = getprop("/sim/model/autopush/K_i");
_F_i = getprop("/sim/model/pushback/F_i"); _F_i = getprop("/sim/model/autopush/F_i");
_K_d = getprop("/sim/model/pushback/K_d"); _K_d = getprop("/sim/model/autopush/K_d");
_F_d = getprop("/sim/model/pushback/F_d"); _F_d = getprop("/sim/model/autopush/F_d");
_F = getprop("/sim/model/pushback/F"); _F = getprop("/sim/model/autopush/F");
_T_f = getprop("/sim/model/pushback/T_f"); _T_f = getprop("/sim/model/autopush/T_f");
_K_yaw = getprop("/sim/model/pushback/yaw-mult") * D2R; _K_yaw = getprop("/sim/model/autopush/yaw-mult") * D2R;
_yasim = (getprop("/sim/flight-model") == "yasim"); _yasim = (getprop("/sim/flight-model") == "yasim");
_debug = getprop("/sim/model/pushback/debug") or 0; _debug = getprop("/sim/model/autopush/debug") or 0;
_int = 0.0; _int = 0.0;
_V = 0.0; _V = 0.0;
_time = getprop("/sim/time/elapsed-sec"); _time = getprop("/sim/time/elapsed-sec");
setprop("/sim/model/pushback/connected", 1); setprop("/sim/model/autopush/connected", 1);
if (!_timer.isRunning) { if (!_timer.isRunning) {
if (getprop("/sim/model/pushback/chocks")) { if (getprop("/sim/model/autopush/chocks")) {
setprop("/sim/model/pushback/chocks", 0); setprop("/sim/model/autopush/chocks", 0);
screen.log.write("(pushback): Pushback connected, chocks removed. Please release brakes."); screen.log.write("(pushback): Pushback connected, chocks removed. Please release brakes.");
} else { } else {
screen.log.write("(pushback): Pushback connected, please release brakes."); screen.log.write("(pushback): Pushback connected, please release brakes.");
@ -117,18 +123,18 @@ var _stop = func() {
screen.log.write("(pushback): Pushback and bypass pin removed."); screen.log.write("(pushback): Pushback and bypass pin removed.");
} }
_timer.stop(); _timer.stop();
setprop("/sim/model/pushback/force-lbf", 0.0); setprop("/sim/model/autopush/force-lbf", 0.0);
if (_yasim) { if (_yasim) {
setprop("/sim/model/pushback/force-x-yasim", 0.0); setprop("/sim/model/autopush/force-x-yasim", 0.0);
setprop("/sim/model/pushback/force-y-yasim", 0.0); setprop("/sim/model/autopush/force-y-yasim", 0.0);
} }
setprop("/sim/model/pushback/connected", 0); setprop("/sim/model/autopush/connected", 0);
setprop("/sim/model/pushback/enabled", 0); setprop("/sim/model/autopush/enabled", 0);
} }
setlistener("/sim/model/pushback/enabled", func(p) { setlistener("/sim/model/autopush/enabled", func(p) {
var enabled = p.getValue(); var enabled = p.getValue();
if ((enabled > _enabled) and getprop("/sim/model/pushback/available")) { if ((enabled > _enabled) and getprop("/sim/model/autopush/available")) {
_start(); _start();
} else if (enabled < _enabled) { } else if (enabled < _enabled) {
_stop(); _stop();

View file

@ -12,90 +12,131 @@
var _K_V = nil; var _K_V = nil;
var _F_V = nil; var _F_V = nil;
var _D_min = nil; var _R_turn_min = nil;
var _D_stop = nil;
var _K_psi = nil; var _K_psi = nil;
var _debug = nil; var _debug = nil;
var _route = nil; var _route = nil;
var _route_reverse = nil;
var _push = nil; var _push = nil;
var _sign = nil; var _sign = nil;
var _psi_park = nil;
var _to_wp = nil; var _to_wp = 1;
var _is_last_wp = 0;
var _is_reverse_wp = 0;
var _advance_wp = func(flip_sign = 0) {
_to_wp += 1;
_is_last_wp = (_to_wp == (size(_route) - 1));
_is_reverse_wp = (_route_reverse[_to_wp]);
if (flip_sign) {
_sign *= -1;
_push = !_push;
}
if (_debug == 1) {
print("autopush_driver to_wp " ~ _to_wp);
}
}
var _loop = func() { var _loop = func() {
if (!getprop("/sim/model/pushback/connected")) { if (!getprop("/sim/model/autopush/connected")) {
stop(); stop();
return; return;
} }
var psi = getprop("/orientation/heading-deg") + _push * 180.0; var psi = getprop("/orientation/heading-deg") + _push * 180.0;
var (A, D) = courseAndDistance(_route[_to_wp]); var (A, D) = courseAndDistance(_route[_to_wp]);
D *= NM2M; D *= NM2M;
# FIXME Use _K_V and total remaining distance. var (psi_leg, D_leg) = courseAndDistance(_route[_to_wp - 1], _route[_to_wp]);
var deltapsi = geo.normdeg180(A - psi_leg);
var deltaA = geo.normdeg180(A - psi);
# TODO Either use _K_V and total remaining distance or turn radius to calculate speed.
# TODO Make slider input override speed.
var V = _F_V; var V = _F_V;
if ((D < _D_min) or (abs(geo.normdeg180(A - psi) > 45.0))) { if (_is_reverse_wp or _is_last_wp) {
_to_wp += 1; if ((D < _D_stop) or (abs(deltapsi) > 90.0)) {
if (_to_wp == size(_route)) { if (_is_last_wp) {
_done(); _done();
autopush_route.clear(); return;
return; }
if (_is_reverse_wp) {
_advance_wp(1);
}
} }
if (_debug) { } else {
print("pushback_driver wp " ~ _to_wp); if ((D < _R_turn_min) or (abs(deltapsi) > 90.0)) {
_advance_wp();
} }
} }
if (_debug > 1) { if (_debug > 1) {
print("pushback_driver psi_target " ~ geo.normdeg(A) ~ ", deltapsi " ~ _sign * geo.normdeg180(A - psi)); print("autopush_driver to_wp " ~ _to_wp ~ ", psi_target " ~ geo.normdeg(A) ~ ", deltapsi " ~ deltapsi ~ ", deltapsi_steer " ~ _sign * deltaA);
} }
setprop("/sim/model/pushback/target-speed-km_h", _sign * V); setprop("/sim/model/autopush/target-speed-km_h", _sign * V);
steering = math.min(math.max(_sign * _K_psi * geo.normdeg180(A - psi), -1.0), 1.0); steering = math.min(math.max(_sign * _K_psi * deltaA, -1.0), 1.0);
setprop("/sim/model/pushback/steer-cmd-norm", steering); setprop("/sim/model/autopush/steer-cmd-norm", steering);
} }
var _timer = maketimer(0.051, func{_loop()}); var _timer = maketimer(0.051, func{_loop()});
var _done = func() { var _done = func() {
stop(); stop();
autopush_route.clear();
screen.log.write("(pushback): Pushback complete, please set parking brake."); screen.log.write("(pushback): Pushback complete, please set parking brake.");
} }
var start = func() { var start = func() {
if (_timer.isRunning) { if (_timer.isRunning) {
stop(); gui.popupTip("Already moving");
return;
} }
if (!getprop("/sim/model/pushback/connected")) { if (!getprop("/sim/model/autopush/connected")) {
gui.popupTip("Pushback must be connected"); gui.popupTip("Pushback not connected");
return; return;
} }
_route = autopush_route.route(); _route = autopush_route.route();
_route_reverse = autopush_route.route_reverse();
if ((_route == nil) or size(_route) < 2) { if ((_route == nil) or size(_route) < 2) {
autopush_route.enter(1); gui.popupTip("Pushback route empty or invalid");
return; return;
}else{ }else{
autopush_route.done(); autopush_route.done();
} }
_K_V = getprop("/sim/model/pushback/driver/K_V"); _K_V = getprop("/sim/model/autopush/driver/K_V");
_F_V = getprop("/sim/model/pushback/driver/F_V"); _F_V = getprop("/sim/model/autopush/driver/F_V");
_D_min = getprop("/sim/model/pushback/driver/D_min-m"); _R_turn_min = getprop("/sim/model/autopush/min-turn-radius-m");
_K_psi = getprop("/sim/model/pushback/driver/K_psi"); _D_stop = getprop("/sim/model/autopush/stopping-distance-m");
_debug = getprop("/sim/model/pushback/debug") or 0; _K_psi = getprop("/sim/model/autopush/driver/K_psi");
var (psi_park, D_park) = courseAndDistance(_route[0], _route[1]); _debug = getprop("/sim/model/autopush/debug") or 0;
var (psi_twy, D_twy) = courseAndDistance(_route[size(_route) - 2], _route[size(_route) - 1]); if (_to_wp == 1) {
_psi_park = psi_park; var (psi_park, D_park) = courseAndDistance(_route[0], _route[1]);
_push = (abs(geo.normdeg180(getprop("/orientation/heading-deg") - psi_park)) > 90.0); _push = (abs(geo.normdeg180(getprop("/orientation/heading-deg") - psi_park)) > 90.0);
_sign = 1.0 - 2.0 * _push; _sign = 1.0 - 2.0 * _push;
_to_wp = 0; }
_timer.start(); _timer.start();
if (_sign < 0.0) { var endsign = _sign;
for (ii = _to_wp; ii < size(_route_reverse); ii += 1) {
if (_route_reverse[ii]) {
endsign = -endsign;
}
}
var (psi_twy, D_twy) = courseAndDistance(_route[size(_route) - 2], _route[size(_route) - 1]);
if (endsign < 0.0) {
screen.log.write("(pushback): Push back facing " ~ int(geo.normdeg(psi_twy + 180.0 - magvar())) ~ "."); screen.log.write("(pushback): Push back facing " ~ int(geo.normdeg(psi_twy + 180.0 - magvar())) ~ ".");
} else { } else {
screen.log.write("(pushback): Tow facing " ~ int(geo.normdeg(psi_twy - magvar())) ~ "."); screen.log.write("(pushback): Tow facing " ~ int(geo.normdeg(psi_twy - magvar())) ~ ".");
} }
} }
var stop = func() { var pause = func() {
_timer.stop(); _timer.stop();
setprop("/sim/model/pushback/target-speed-km_h", 0.0); setprop("/sim/model/autopush/target-speed-km_h", 0.0);
autopush_route.clear(); }
var stop = func() {
pause();
_to_wp = 1;
_is_last_wp = 0;
_is_reverse_wp = 0;
} }

View file

@ -11,26 +11,28 @@
var _listener = nil; var _listener = nil;
var _view_listener = nil; var _view_listener = nil;
var _user_points = dynarr.dynarr.new(4); var _user_points = dynarr.dynarr.new(4);
var _user_point_modes = dynarr.dynarr.new(4); # Modes: 0 = Bezier node, 1 = Bezier end/start node var _user_point_modes = dynarr.dynarr.new(4); # Modes: 0 = Bezier node, 1 = Bezier end/start node, 2 = Reverse
var _route = []; var _route = [];
var _route_hdg = [];
var _route_reverse = [];
var _view_index = nil; var _view_index = nil;
var _user_point_models = []; var _user_point_models = [];
var _waypoint_models = []; var _waypoint_models = [];
var _N = 0; var _N = 0;
var _show = 0; var _show = 0;
var _view_changed_or_external = 0; var _view_changed_or_external = 0;
var _start_immediately = nil; var _R_turn_min = 0;
var _D_min = nil; var _invalid = 0;
var _add = func(pos) { var _add = func(pos) {
if (_N) { if (_N) {
var (A, S) = courseAndDistance(_user_points.arr[_N - 1], pos); var (A, S) = courseAndDistance(_user_points.arr[_N - 1], pos);
S *= NM2M; S *= NM2M;
if (S < 3 * _D_min) { if (S < _R_turn_min) {
gui.popupTip("Too close to the previous point,\ntry again"); gui.popupTip("Too close to the previous point,\ntry again");
return; return;
}else if (S > 10000.0) { }else if (S > 10000.0) {
gui.popupTip("Too far from the previous point,\ntry again"); gui.popupTip("Too far from the previous point,\ntry again");
return; return;
} }
@ -76,11 +78,7 @@ var _stop = func(fail = 0) {
if (!fail) { if (!fail) {
settimer(func() { settimer(func() {
_reset_view(); _reset_view();
if (_start_immediately) { gui.popupTip("Done");
autopush_driver.start();
} else {
gui.popupTip("Done");
}
}, 1.0); }, 1.0);
} else { } else {
_reset_view(); _reset_view();
@ -96,6 +94,8 @@ var _place_user_point_models = func() {
var model = "Models/Autopush/cursor.xml"; var model = "Models/Autopush/cursor.xml";
if (_user_point_modes.arr[ii] == 1) { if (_user_point_modes.arr[ii] == 1) {
model = "Models/Autopush/cursor_sharp.xml"; model = "Models/Autopush/cursor_sharp.xml";
} else if (_user_point_modes.arr[ii] == 2) {
model = "Models/Autopush/cursor_reverse.xml";
} }
_user_point_models[ii] = geo.put_model(model, user_points[ii], 0.0); _user_point_models[ii] = geo.put_model(model, user_points[ii], 0.0);
} }
@ -115,7 +115,7 @@ var _place_waypoint_models = func() {
_clear_waypoint_models(); _clear_waypoint_models();
setsize(_waypoint_models, size(_route)); setsize(_waypoint_models, size(_route));
for (var ii = 0; ii < size(_route); ii += 1) { for (var ii = 0; ii < size(_route); ii += 1) {
_waypoint_models[ii] = geo.put_model("Models/Autopush/waypoint.xml", _route[ii], 0.0); _waypoint_models[ii] = geo.put_model("Models/Autopush/waypoint.xml", _route[ii], _route_hdg[ii]);
} }
} }
@ -135,7 +135,11 @@ var _set_view = func() {
return; return;
} }
_view_index = getprop("/sim/current-view/view-number"); _view_index = getprop("/sim/current-view/view-number");
# While "Chase View Without Yaw" would have looked better, only "Model View" resets its z-offset back to normal by itself.
setprop("/sim/current-view/view-number", view.indexof("Model View")); setprop("/sim/current-view/view-number", view.indexof("Model View"));
setprop("/sim/current-view/z-offset-m", -500.0);
setprop("/sim/current-view/pitch-offset-deg", 90.0);
setprop("/sim/current-view/heading-offset-deg", 0.0);
_view_changed_or_external = 0; _view_changed_or_external = 0;
_view_listener = setlistener("/sim/current-view/name", func { _view_listener = setlistener("/sim/current-view/name", func {
_view_changed_or_external = 1; _view_changed_or_external = 1;
@ -158,36 +162,66 @@ var _reset_view = func() {
var _calculate_route = func() { var _calculate_route = func() {
_route = []; _route = [];
user_points = _user_points.get_sliced(); _route_reverse = [];
var user_points = _user_points.get_sliced();
var route = dynarr.dynarr.new(); var route = dynarr.dynarr.new();
# add the first point cause it will be fix at this pos # add the first point cause it will be fix at this pos
route.add(geo.Coord.new(user_points[0])); route.add(geo.Coord.new(user_points[0]));
n = size(user_points); n = size(user_points);
var base = 0; var base = 0;
# Detect points where push/pull direction is reversed.
for (var i = 0; i < n; i += 1) { for (var i = 0; i < n; i += 1) {
if (_user_point_modes.arr[i] == 1 or i == n - 1) { if (i and (i < n - 1)) {
if((_user_point_modes.arr[i] == 1) or (_user_point_modes.arr[i] == 2)) {
var newmode = 1;
var deltaA = abs(geo.normdeg180(user_points[i - 1].course_to(user_points[i]) - user_points[i].course_to(user_points[i + 1])));
if (deltaA > 91.0) {
newmode = 2;
}
if(newmode != _user_point_modes.arr[i]){
_set_userpoint_mode(i, newmode);
}
}
} else {
# Clear reverse for first and last points.
if(_user_point_modes.arr[i] == 2) {
if(_user_point_modes.arr[i] != 1){
_set_userpoint_mode(i, 1);
}
}
}
}
for (var i = 0; i < n; i += 1) {
if (_user_point_modes.arr[i] or (i == n - 1)) {
if (i - base > 0) { if (i - base > 0) {
var bezier = _calculate_bezier(user_points[base:i]); var bezier = _calculate_bezier(user_points[base:i]);
if (bezier != nil) {
var m = size(bezier); var m = size(bezier);
for (var j = 0; j < m; j += 1) { for (var j = 0; j < m; j += 1) {
route.add(geo.Coord.new(bezier[j])); route.add(geo.Coord.new(bezier[j]));
}
} }
} }
base = i; base = i;
route.add(geo.Coord.new(user_points[i])); route.add(geo.Coord.new(user_points[i]));
if (_user_point_modes.arr[i] == 2) {
var route_size = size(route.get_sliced());
setsize(_route_reverse, route_size);
_route_reverse[route_size - 1] = 1;
}
} }
} }
var PNumber = size(user_points);
PNumber = size(user_points);
_route = route.get_sliced(); _route = route.get_sliced();
setsize(_route_reverse, size(_route));
_check_turn_radius();
_calculate_hdg();
} }
var _calculate_bezier = func(user_points) { var _calculate_bezier = func(user_points) {
var route = dynarr.dynarr.new(); var route = dynarr.dynarr.new();
PNumber = size(user_points); var PNumber = size(user_points);
if (PNumber > 1) { if (PNumber > 1) {
var pointList = []; var pointList = [];
@ -204,7 +238,7 @@ var _calculate_bezier = func(user_points) {
len += user_points[i].distance_to(user_points[i + 1]); len += user_points[i].distance_to(user_points[i + 1]);
} }
var step = _D_min / len; var step = _R_turn_min / len;
for (var i = step; i < 1 - step; i+= step) { for (var i = step; i < 1 - step; i+= step) {
# start iterating from 1 cause we don't need to iterate over Pn # start iterating from 1 cause we don't need to iterate over Pn
@ -224,7 +258,63 @@ var _calculate_bezier = func(user_points) {
return route.get_sliced(); return route.get_sliced();
} }
setlistener("/sim/model/pushback/route/show", func(p) { var _calculate_hdg = func() {
_route_hdg = [];
var route_hdg = dynarr.dynarr.new();
var ilast = size(_route) - 1;
for (i = 0; i < ilast; i += 1) {
var hdg = _route[i].course_to(_route[i + 1]);
route_hdg.add(hdg);
}
# Last heading would be undefined, so just repeat the one before the last.
route_hdg.add(route_hdg.get_sliced()[ilast - 1]);
_route_hdg = route_hdg.get_sliced();
}
# Checks each waypoint's turn radius and marks the route invalid if
# it is smaller than the aircraft's turn radius.
var _check_turn_radius = func() {
# A waypoint's turn radius is the radius of a circle circumscribed around the waypoint, previous and next waypoints.
# Formula source: https://math.stackexchange.com/questions/947882/radius-of-circumscribed-circle-of-triangle-as-function-of-the-sides
var len = size(_route);
_invalid = 0;
# We can't calculate the radius for the first and last point
for (i = 1; i < len - 2; i += 1) {
# Disable check for push and pull points
if (_route_reverse[i] != 1) {
var a = _route[i].distance_to(_route[i + 1]);
var b = _route[i].distance_to(_route[i - 1]);
var c = _route[i - 1].distance_to(_route[i + 1]);
var margin = _R_turn_min / 5000;
# Stright line check with marging to prevent floating point error
if (a + b + margin >= c and a + b - margin <= c) {
var r = - 1;
} else {
var r = (a * b * c) / math.sqrt(
2 * a * a * b * b
+ 2 * a * a * c * c
+ 2 * b * b * c * c
- a * a * a * a
- b * b * b * b
- c * c * c * c
);
}
if ((r < _R_turn_min) and (r != -1)) {
_invalid = 1;
}
}
}
setprop("/sim/model/autopush/route/invalid", _invalid);
}
setlistener("/sim/model/autopush/route/show", func(p) {
var show = p.getValue(); var show = p.getValue();
if (_listener == nil) { if (_listener == nil) {
if (show > _show) { if (show > _show) {
@ -239,10 +329,10 @@ setlistener("/sim/model/pushback/route/show", func(p) {
}); });
var enter = func(start_immediately = 0) { var enter = func() {
clear(); clear();
_set_view(); _set_view();
_D_min = getprop("/sim/model/pushback/driver/D_min-m"); _R_turn_min = getprop("/sim/model/autopush/min-turn-radius-m");
var wp = geo.aircraft_position(); var wp = geo.aircraft_position();
var H = geo.elevation(wp.lat(), wp.lon()); var H = geo.elevation(wp.lat(), wp.lon());
if (H != nil) { if (H != nil) {
@ -252,25 +342,46 @@ var enter = func(start_immediately = 0) {
_listener = setlistener("/sim/signals/click", func { _listener = setlistener("/sim/signals/click", func {
_add(geo.click_position()); _add(geo.click_position());
}); });
_start_immediately = start_immediately; # This property can be overridden manually, if needed.
var wingspan = getprop("/sim/model/autopush/route/wingspan-m");
if ((wingspan == nil) or (wingspan == 0.0)) {
# JSBSim
wingspan = getprop("/fdm/jsbsim/metrics/bw-ft");
if (wingspan != nil) {
wingspan *= FT2M;
} else {
# YAsim
wingspan = getprop("/fdm/yasim/model/wings/wing/wing-span");
}
setprop("/sim/model/autopush/route/wingspan-m", wingspan);
}
} }
var toggle_node = func() { var _set_userpoint_mode = func(id, mode) {
if (_user_point_modes.arr[id] != mode) {
_user_point_modes.arr[id] = mode;
}
if (_user_point_models[id] != nil) {
_user_point_models[id].remove();
var model = "Models/Autopush/cursor.xml";
if (_user_point_modes.arr[id] == 1) {
model = "Models/Autopush/cursor_sharp.xml";
} else if (_user_point_modes.arr[id] == 2) {
model = "Models/Autopush/cursor_reverse.xml";
}
_user_point_models[id] = geo.put_model(model, _user_points.get_sliced()[id], 0.0);
}
}
var toggle_sharp = func() {
if (_listener == nil) { if (_listener == nil) {
return; return;
} }
if (_user_point_modes.arr[_N - 1] == 0) { id = _N - 1;
_user_point_modes.arr[_N - 1] = 1; if (_user_point_modes.arr[id]) {
_set_userpoint_mode(id, 0);
} else { } else {
_user_point_modes.arr[_N - 1] = 0; _set_userpoint_mode(id, 1);
}
if (_user_point_models[_N - 1] != nil) {
_user_point_models[_N - 1].remove();
var model = "Models/Autopush/cursor.xml";
if (_user_point_modes.arr[_N - 1] == 1) {
model = "Models/Autopush/cursor_sharp.xml";
}
_user_point_models[_N - 1] = geo.put_model(model, _user_points.get_sliced()[_N - 1], 0.0);
} }
} }
@ -279,6 +390,7 @@ var done = func() {
} }
var clear = func() { var clear = func() {
autopush_driver.stop();
_stop(1); _stop(1);
_clear_user_point_models(); _clear_user_point_models();
_clear_waypoint_models(); _clear_waypoint_models();
@ -288,9 +400,15 @@ var clear = func() {
} }
var route = func() { var route = func() {
if (_N < 2) { if (_invalid or (_N < 2)) {
return nil; return nil;
} }
_calculate_route();
return _route; return _route;
} }
var route_reverse = func() {
if (_invalid or (_N < 2)) {
return nil;
}
return _route_reverse;
}

View file

@ -2022,26 +2022,6 @@
</test> </test>
</switch> </switch>
<switch name="hydraulics/tiller/hyd-pwr">
<default value="0"/>
<test logic="AND" value="1">
position/wow eq 1
hydraulics/tiller/elec-pwr eq 1
/systems/hydraulic/yellow-psi ge 1500
/sim/model/pushback/connected eq 0
/controls/gear/nws-switch eq 1
/engines/engine[0]/state eq 3
</test>
<test logic="AND" value="1">
position/wow eq 1
hydraulics/tiller/elec-pwr eq 1
/systems/hydraulic/yellow-psi ge 1500
/sim/model/pushback/connected eq 0
/controls/gear/nws-switch eq 1
/engines/engine[1]/state eq 3
</test>
</switch>
<switch name="hydraulics/tiller/elec-pwr"> <switch name="hydraulics/tiller/elec-pwr">
<default value="0"/> <default value="0"/>
<test logic="OR" value="1"> <test logic="OR" value="1">
@ -2052,11 +2032,31 @@
</test> </test>
</switch> </switch>
<switch name="hydraulics/tiller/hyd-pwr">
<default value="0"/>
<test logic="AND" value="1">
position/wow eq 1
hydraulics/tiller/elec-pwr eq 1
/systems/hydraulic/yellow-psi ge 1500
/sim/model/autopush/connected eq 0
/controls/gear/nws-switch eq 1
/engines/engine[0]/state eq 3
</test>
<test logic="AND" value="1">
position/wow eq 1
hydraulics/tiller/elec-pwr eq 1
/systems/hydraulic/yellow-psi ge 1500
/sim/model/autopush/connected eq 0
/controls/gear/nws-switch eq 1
/engines/engine[1]/state eq 3
</test>
</switch>
<fcs_function name="hydraulics/tiller/function"> <fcs_function name="hydraulics/tiller/function">
<function> <function>
<ifthen> <ifthen>
<eq> <eq>
<property>/sim/model/pushback/connected</property> <property>/sim/model/autopush/connected</property>
<value>1</value> <value>1</value>
</eq> </eq>
<product> <product>
@ -2067,7 +2067,7 @@
<independentVar lookup="row">/velocities/groundspeed-kt</independentVar> <independentVar lookup="row">/velocities/groundspeed-kt</independentVar>
<independentVar lookup="column">hydraulics/tiller/switch</independentVar> <independentVar lookup="column">hydraulics/tiller/switch</independentVar>
<tableData> <tableData>
-1 0 1 -1 0 1
0.500 0 0 0 0.500 0 0 0
1.000 -75 0 75 1.000 -75 0 75
30.000 -47 0 47 30.000 -47 0 47
@ -2083,7 +2083,7 @@
<default value="0"/> <default value="0"/>
<test logic="OR" value="75"> <test logic="OR" value="75">
hydraulics/tiller/hyd-pwr eq 1 hydraulics/tiller/hyd-pwr eq 1
/sim/model/pushback/connected eq 1 /sim/model/autopush/connected eq 1
/systems/acconfig/autoconfig-running eq 1 /systems/acconfig/autoconfig-running eq 1
</test> </test>
</switch> </switch>
@ -2097,7 +2097,7 @@
<switch name="fcs/pushback-steer-deg"> <switch name="fcs/pushback-steer-deg">
<default value="0"/> <default value="0"/>
<test value="fcs/steer-deg"> <test value="fcs/steer-deg">
/sim/model/pushback/connected eq 1 /sim/model/autopush/connected eq 1
</test> </test>
</switch> </switch>

View file

@ -2,11 +2,11 @@
<!-- <!--
AUTOPUSH AUTOPUSH
Waypoint model. Pushback dialog.
Copyright (c) 2018 Autopush authors: Copyright (c) 2018 Autopush authors:
Michael Danilov <mike.d.ft402 -eh- gmail.com> Michael Danilov <mike.d.ft402 -eh- gmail.com>
Joshua Davidson http://github.com/it0uchpods Joshua Davidson http://github.com/it0uchpods
Merspieler http://github.com/merspieler Merspieler http://gitlab.com/merspieler
Distribute under the terms of GPLv2. Distribute under the terms of GPLv2.
--> -->
@ -52,7 +52,7 @@ Distribute under the terms of GPLv2.
<checkbox> <checkbox>
<halign>left</halign> <halign>left</halign>
<label>Connect</label> <label>Connect</label>
<property>/sim/model/pushback/enabled</property> <property>/sim/model/autopush/enabled</property>
<live>true</live> <live>true</live>
<binding> <binding>
<command>dialog-apply</command> <command>dialog-apply</command>
@ -77,7 +77,7 @@ Distribute under the terms of GPLv2.
<legend>&lt;</legend> <legend>&lt;</legend>
<binding> <binding>
<command>property-adjust</command> <command>property-adjust</command>
<property>/sim/model/pushback/steer-cmd-norm</property> <property>/sim/model/autopush/steer-cmd-norm</property>
<min>-1.0</min> <min>-1.0</min>
<max>1.0</max> <max>1.0</max>
<step>-0.02</step> <step>-0.02</step>
@ -91,7 +91,7 @@ Distribute under the terms of GPLv2.
<min>-1.0</min> <min>-1.0</min>
<max>1.0</max> <max>1.0</max>
<step>0.1</step> <step>0.1</step>
<property>/sim/model/pushback/steer-cmd-norm</property> <property>/sim/model/autopush/steer-cmd-norm</property>
<live>true</live> <live>true</live>
<binding> <binding>
<command>dialog-apply</command> <command>dialog-apply</command>
@ -106,7 +106,7 @@ Distribute under the terms of GPLv2.
<legend>&gt;</legend> <legend>&gt;</legend>
<binding> <binding>
<command>property-adjust</command> <command>property-adjust</command>
<property>/sim/model/pushback/steer-cmd-norm</property> <property>/sim/model/autopush/steer-cmd-norm</property>
<min>-1.0</min> <min>-1.0</min>
<max>1.0</max> <max>1.0</max>
<step>0.02</step> <step>0.02</step>
@ -122,7 +122,7 @@ Distribute under the terms of GPLv2.
<legend>Center</legend> <legend>Center</legend>
<binding> <binding>
<command>property-assign</command> <command>property-assign</command>
<property>/sim/model/pushback/steer-cmd-norm</property> <property>/sim/model/autopush/steer-cmd-norm</property>
<value>0</value> <value>0</value>
</binding> </binding>
</button> </button>
@ -142,7 +142,7 @@ Distribute under the terms of GPLv2.
<legend>&lt;</legend> <legend>&lt;</legend>
<binding> <binding>
<command>property-adjust</command> <command>property-adjust</command>
<property>/sim/model/pushback/target-speed-km_h</property> <property>/sim/model/autopush/target-speed-km_h</property>
<min>-25</min> <min>-25</min>
<max>25</max> <max>25</max>
<step>-1</step> <step>-1</step>
@ -155,7 +155,7 @@ Distribute under the terms of GPLv2.
<col>2</col> <col>2</col>
<min>-25</min> <min>-25</min>
<max>25</max> <max>25</max>
<property>/sim/model/pushback/target-speed-km_h</property> <property>/sim/model/autopush/target-speed-km_h</property>
<step>1.0</step> <step>1.0</step>
<live>true</live> <live>true</live>
<binding> <binding>
@ -171,7 +171,7 @@ Distribute under the terms of GPLv2.
<legend>&gt;</legend> <legend>&gt;</legend>
<binding> <binding>
<command>property-adjust</command> <command>property-adjust</command>
<property>/sim/model/pushback/target-speed-km_h</property> <property>/sim/model/autopush/target-speed-km_h</property>
<min>-25</min> <min>-25</min>
<max>25</max> <max>25</max>
<step>1</step> <step>1</step>
@ -187,16 +187,20 @@ Distribute under the terms of GPLv2.
<legend>Stop</legend> <legend>Stop</legend>
<binding> <binding>
<command>property-assign</command> <command>property-assign</command>
<property>/sim/model/pushback/target-speed-km_h</property> <property>/sim/model/autopush/target-speed-km_h</property>
<value>0</value> <value>0</value>
</binding> </binding>
<binding>
<command>nasal</command>
<script>autopush_driver.pause();</script>
</binding>
</button> </button>
<text> <text>
<row>1</row> <row>1</row>
<col>5</col> <col>5</col>
<pref-width>16</pref-width> <pref-width>16</pref-width>
<property>/sim/model/pushback/target-speed-km_h</property> <property>/sim/model/autopush/target-speed-km_h</property>
<format>%3.0f</format> <format>%3.0f</format>
<live>true</live> <live>true</live>
<halign>right</halign> <halign>right</halign>
@ -240,10 +244,10 @@ Distribute under the terms of GPLv2.
<col>2</col> <col>2</col>
<pref-width>50</pref-width> <pref-width>50</pref-width>
<pref-height>25</pref-height> <pref-height>25</pref-height>
<legend>Stop</legend> <legend>Pause</legend>
<binding> <binding>
<command>nasal</command> <command>nasal</command>
<script>autopush_driver.stop();</script> <script>autopush_driver.pause();</script>
</binding> </binding>
</button> </button>
@ -284,10 +288,14 @@ Distribute under the terms of GPLv2.
<halign>left</halign> <halign>left</halign>
<label>Always Show</label> <label>Always Show</label>
<live>true</live> <live>true</live>
<property>/sim/model/pushback/route/show</property> <property>/sim/model/autopush/route/show</property>
<binding> <binding>
<command>dialog-apply</command> <command>dialog-apply</command>
</binding> </binding>
<binding>
<command>nasal</command>
<script>acconfig.writeSettings();</script>
</binding>
</checkbox> </checkbox>
<text> <text>
@ -305,7 +313,7 @@ Distribute under the terms of GPLv2.
<legend>Sharp</legend> <legend>Sharp</legend>
<binding> <binding>
<command>nasal</command> <command>nasal</command>
<script>autopush_route.toggle_node();</script> <script>autopush_route.toggle_sharp();</script>
</binding> </binding>
</button> </button>
@ -321,6 +329,22 @@ Distribute under the terms of GPLv2.
</binding> </binding>
</button> </button>
<checkbox>
<row>2</row>
<col>3</col>
<halign>left</halign>
<label>Show Wingtip</label>
<live>true</live>
<property>/sim/model/autopush/route/show-wingtip</property>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>acconfig.writeSettings();</script>
</binding>
</checkbox>
</group> </group>
</group> </group>

View file

@ -1 +1 @@
4785 4787