Library globals

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();
});