Howto:A system engine in Nasal
Jump to navigation
Jump to search
This page describes an engine for aircraft systems, or rather for staging an impression of such a system. It doesn’t handle potentials, pressures or Kirchhoff's laws. It checks if switches are on or off and if minimum criterion’s are met.
# Potemkin system
# Connections
#dep: depends on this property.
#limit: lower limit for true. dep > limit eq. true
#in: input property eg. orientation/pitch-deg or number constant.
# Use . to copy dep value to out.
#out output property eg.instruments/ai/pitch-deg
#off: value if not dep true, can be a property to be read
#ramp: max change per second of out, 0 no limit
var Connection = {
new : func(cv) {
var m = {parents:[Connection] };
m.dep=cv[0];
m.limit=cv[1];
m.in=cv[2];
m.out=cv[3];
m.off=cv[4];
m.ramp=num(cv[5]);
return m;
},
};
var System_P = {
new : func(system_file) {
var m = {parents:[System_P] };
m.file=system_file;
m.connections = [];
m.verbose = 2;
m.running=0;
m.dt=0;
m.oldtime=0;
return m;
},
read_connections : func {
if (me.verbose > 0) print("Reading connections");
var fh = io.open(getprop("/sim/aircraft-dir")~"/"~me.file, "r");
var line="";
while (line != nil) {
line = io.readln(fh);
if (line != nil) {
var c_arr=split(",", line);
if (size(c_arr) == 6) {
append(me.connections, Connection.new(c_arr));
if (me.verbose > 1) print("Adding: "~line);
} else if (me.verbose > 1) print("Skipping: "~line);
}
}
io.close(fh);
if (me.verbose > 0) print("Read connections");
},
change_value : func(prop, value, ramp) {
if (ramp == 0) setprop(prop, value);
else {
var ov=num(getprop(prop));
if (ov<value and value-ov > ramp*me.dt) setprop(prop, ov+ramp*me.dt);
else if (ov>value and ov-value > ramp*me.dt) setprop(prop, ov-ramp*me.dt);
else setprop(prop, value);
}
},
update : func {
if (!me.running) return;
var time=getprop("/sim/time/elapsed-sec");
me.dt= time-me.oldtime;
foreach (con; me.connections) {
dp=getprop(con.dep);
if (dp != nil) {
if (con.in == ".") me.change_value(con.out, dp, con.ramp); #copy dep value to out
else if (dp <= con.limit) {
if (num(con.off) != nil) me.change_value(con.out, num(con.off), con.ramp);
else me.change_value(con.out, getprop(con.off), con.ramp);
} else {
if (num(con.in) != nil) me.change_value(con.out, num(con.in), con.ramp);
else me.change_value(con.out, getprop(con.in), con.ramp);
}
}
}
me.oldtime=time;
settimer( func me.update(), 0.05);
},
init : func {
me.read_connections();
foreach (con; me.connections) {
if (num(con.off) != nil) setprop(con.out, num(con.off));
else setprop(con.out, getprop(con.off));
}
me.running=1;
me.oldtime= getprop("/sim/time/elapsed-sec");
if (me.verbose > 0) print("Initialized system");
me.update();
},
};