Source fuel.nas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Fuel handling for the YASim FDM. Note that other FDMs (e.g. JSBSim)
# handle fuel within the FDM itself.
#
# Properties under /consumables/fuel/tank[n]:
# + level-lbs - Current fuel load. Can be set by user code.
# + selected - boolean indicating tank selection.
# + capacity-gal_us - Tank capacity
#
# Properties under /engines/engine[n]:
# + fuel-consumed-lbs - Output from the FDM, zeroed by this script
# + out-of-fuel - boolean, set by this code.
var UPDATE_PERIOD = 0.3;
var update = func {
if (fuel_freeze)
return;
var consumed_fuel = 0;
foreach (var e; engines) {
var fuel = e.getNode("fuel-consumed-lbs");
consumed_fuel += fuel.getValue();
fuel.setDoubleValue(0);
}
var selected_tanks = [];
foreach (var t; tanks) {
var cap = t.getNode("capacity-gal_us",0);
var selected = t.getNode("selected");
if ((cap!=nil) and (cap.getValue() > 0.01) and (t.getNode("level-lbs") != nil) and
(selected != nil) and selected.getBoolValue())
append(selected_tanks, t);
}
# Subtract fuel from tanks, set auxiliary properties. Set out-of-fuel
# when any one tank is dry.
var out_of_fuel = 0;
if (size(selected_tanks) == 0) {
out_of_fuel = 1;
} else {
var fuel_per_tank = consumed_fuel / size(selected_tanks);
foreach (var t; selected_tanks) {
var lbs = t.getNode("level-lbs");
lbs.setDoubleValue(lbs.getValue() - fuel_per_tank);
var empty = t.getNode("empty");
if (empty == nil)
empty = (lbs.getValue() <= 0);
else
empty = empty.getBoolValue();
if( empty ) {
# Kill the engines if we're told to, otherwise simply
# deselect the tank.
if (t.getNode("kill-when-empty", 1).getBoolValue())
out_of_fuel = 1;
else
t.getNode("selected").setBoolValue(0);
}
}
}
foreach (var e; engines)
e.getNode("out-of-fuel").setBoolValue(out_of_fuel);
}
var loop = func {
update();
settimer(loop, UPDATE_PERIOD);
}
var tanks = [];
var engines = [];
var fuel_freeze = nil;
var freeze_fuel_listener = nil;
var initialized = 0;
_setlistener("/sim/signals/fdm-initialized", func {
if (freeze_fuel_listener == nil)
{
freeze_fuel_listener = setlistener("/sim/freeze/fuel", func(n) { fuel_freeze = n.getBoolValue() }, 1);
}
# Fuel sub-system is only used by YASim. Other FDMs (e.g. JSBSim)
# handle fuel themselves.
if (getprop("/sim/flight-model") != "yasim") { return; }
engines = props.globals.getNode("engines", 1).getChildren("engine");
foreach (var e; engines) {
e.getNode("fuel-consumed-lbs", 1).setDoubleValue(0);
e.getNode("out-of-fuel", 1).setBoolValue(0);
}
# do the following stuff once only
if (initialized)
return;
initialized = 1;
foreach (var t; props.globals.getNode("/consumables/fuel", 1).getChildren("tank")) {
if (!t.getAttribute("children"))
continue; # skip native_fdm.cxx generated zombie tanks
append(tanks, t);
t.initNode("selected", 1, "BOOL");
}
loop();
});