New fuel management code. Only works with YASim currently. It's a benign
no-op under other FDMs.
This commit is contained in:
parent
88d1598ab9
commit
e2cf6d90d2
2 changed files with 121 additions and 2 deletions
119
Nasal/fuel.nas
Normal file
119
Nasal/fuel.nas
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
# Properties under /consumables/fuel/tank[n]:
|
||||||
|
# + level-gal_us - Current fuel load. Can be set by user code.
|
||||||
|
# + level-lbs - OUTPUT ONLY property, do not try to set
|
||||||
|
# + selected - boolean indicating tank selection.
|
||||||
|
# + density-ppg - Fuel density, in lbs/gallon.
|
||||||
|
# + 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.
|
||||||
|
|
||||||
|
UPDATE_PERIOD = 0.3;
|
||||||
|
|
||||||
|
fuelUpdate = func {
|
||||||
|
if(getprop("/sim/freeze/fuel")) { return registerTimer(); }
|
||||||
|
|
||||||
|
AllEngines = props.globals.getNode("engines").getChildren("engine");
|
||||||
|
|
||||||
|
# Sum the consumed fuel
|
||||||
|
total = 0;
|
||||||
|
foreach(e; AllEngines) {
|
||||||
|
fuel = e.getNode("fuel-consumed-lbs", 1);
|
||||||
|
consumed = fuel.getValue();
|
||||||
|
if(consumed == nil) { consumed = 0; }
|
||||||
|
total = total + consumed;
|
||||||
|
fuel.setDoubleValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unfortunately, FDM initialization hasn't happened when we start
|
||||||
|
# running. Wait for the FDM to start running before we set any output
|
||||||
|
# properties. This also prevents us from mucking with FDMs that
|
||||||
|
# don't support this fuel scheme.
|
||||||
|
if(total == 0) { return registerTimer(); }
|
||||||
|
if(!initialized) { initialize(); }
|
||||||
|
|
||||||
|
AllTanks = props.globals.getNode("consumables/fuel").getChildren("tank");
|
||||||
|
|
||||||
|
# Build a list of selected tanks
|
||||||
|
selectedTanks = [];
|
||||||
|
foreach(t; AllTanks) {
|
||||||
|
if(t.getNode("selected", 1).getBoolValue()) {
|
||||||
|
append(selectedTanks, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Subtract fuel from tanks, set auxilliary properties. Set out-of-fuel
|
||||||
|
# when any one tank is dry.
|
||||||
|
outOfFuel = 0;
|
||||||
|
if(size(selectedTanks) == 0) {
|
||||||
|
outOfFuel = 1;
|
||||||
|
} else {
|
||||||
|
fuelPerTank = total / size(selectedTanks);
|
||||||
|
foreach(t; selectedTanks) {
|
||||||
|
ppg = t.getNode("density-ppg").getValue();
|
||||||
|
lbs = t.getNode("level-gal_us").getValue() * ppg;
|
||||||
|
lbs = lbs - fuelPerTank;
|
||||||
|
if(lbs < 0) { lbs = 0; outOfFuel = 1; }
|
||||||
|
gals = lbs / ppg;
|
||||||
|
t.getNode("level-gal_us").setDoubleValue(gals);
|
||||||
|
t.getNode("level-lbs").setDoubleValue(lbs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Total fuel properties
|
||||||
|
gals = lbs = cap = 0;
|
||||||
|
foreach(t; AllTanks) {
|
||||||
|
cap = cap + t.getNode("capacity-gal_us").getValue();
|
||||||
|
gals = gals + t.getNode("level-gal_us").getValue();
|
||||||
|
lbs = lbs + t.getNode("level-lbs").getValue();
|
||||||
|
}
|
||||||
|
setprop("/consumables/fuel/total-fuel-gals", gals);
|
||||||
|
setprop("/consumables/fuel/total-fuel-lbs", lbs);
|
||||||
|
setprop("/consumables/fuel/total-fuel-norm", gals/cap);
|
||||||
|
|
||||||
|
foreach(e; AllEngines) {
|
||||||
|
e.getNode("out-of-fuel").setBoolValue(outOfFuel);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initalize: Make sure all needed properties are present and accounted
|
||||||
|
# for, and that they have sane default values.
|
||||||
|
initialized = 0;
|
||||||
|
initialize = func {
|
||||||
|
AllEngines = props.globals.getNode("engines").getChildren("engine");
|
||||||
|
AllTanks = props.globals.getNode("consumables/fuel").getChildren("tank");
|
||||||
|
|
||||||
|
foreach(e; AllEngines) {
|
||||||
|
e.getNode("fuel-consumed-lbs", 1).setDoubleValue(0);
|
||||||
|
e.getNode("out-of-fuel", 1).setBoolValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(t; AllTanks) {
|
||||||
|
initDoubleProp(t, "level-gal_us", 0);
|
||||||
|
initDoubleProp(t, "level-lbs", 0);
|
||||||
|
initDoubleProp(t, "capacity-gal_us", 1); # Not zero (div/zero issue)
|
||||||
|
initDoubleProp(t, "density-ppg", 6.0); # gasoline
|
||||||
|
|
||||||
|
if(t.getNode("selected") == nil) {
|
||||||
|
t.getNode("selected", 1).setBoolValue(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
initDoubleProp = func {
|
||||||
|
node = arg[0]; prop = arg[1]; val = arg[2];
|
||||||
|
if(node.getNode(prop) != nil) {
|
||||||
|
val = num(node.getNode(prop).getValue());
|
||||||
|
}
|
||||||
|
node.getNode(prop, 1).setDoubleValue(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fire it up
|
||||||
|
registerTimer = func {
|
||||||
|
settimer(fuelUpdate, UPDATE_PERIOD);
|
||||||
|
}
|
||||||
|
registerTimer();
|
|
@ -29,8 +29,8 @@ Node = {
|
||||||
getNode : func { wrap(_getNode(me._g, arg)) },
|
getNode : func { wrap(_getNode(me._g, arg)) },
|
||||||
|
|
||||||
getBoolValue : func {
|
getBoolValue : func {
|
||||||
val = getValue();
|
val = me.getValue();
|
||||||
if(getType() == "STRING" and val == "false") { 0 }
|
if(me.getType() == "STRING" and val == "false") { 0 }
|
||||||
else { val }
|
else { val }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue