198 lines
6.4 KiB
Text
198 lines
6.4 KiB
Text
# AOC Flight Log system
|
|
# Basic OOOI system implementation
|
|
|
|
var OOOIReport = {
|
|
new: func(state,time=0,fob="") {
|
|
var report = {parents:[OOOIReport]};
|
|
report.state = state;
|
|
report.fob = (fob != "") ? fob : fmgc.FMGCInternal.fob;
|
|
if (time != 0) {
|
|
report.time = formatSecToHHMM(time);
|
|
report.elapsed = time;
|
|
} else {
|
|
report.time = sprintf("%02d.%02d", getprop("/sim/time/utc/hour"), getprop("/sim/time/utc/minute"));
|
|
report.elapsed = int(getprop("/sim/time/elapsed-sec"));
|
|
}
|
|
report.gmt = getprop("/sim/time/gmt-string");
|
|
report.date = getprop("/sim/time/utc/day");
|
|
report.fltnum = (fmgc.FMGCInternal.flightNumSet == 1) ? fmgc.FMGCInternal.flightNum : "----";
|
|
report.tofrom = (fmgc.FMGCInternal.toFromSet) ? fmgc.FMGCInternal.depApt ~ "-" ~ fmgc.FMGCInternal.arrApt : "----/----";
|
|
return report;
|
|
},
|
|
};
|
|
|
|
# Flight phase states: RESET, BEGIN, WPUSH, OUT, OFF, ON, END
|
|
|
|
var OOOIReportPage = {
|
|
new: func(index) {
|
|
var page = {parents:[OOOIReportPage]};
|
|
page.index = index;
|
|
page.fltstate = ""; #UNDEF state RESET/BEGIN/WPUSH
|
|
page.fltnum = (fmgc.FMGCInternal.flightNumSet == 1) ? fmgc.FMGCInternal.flightNum : "";
|
|
page.date = getprop("/sim/time/utc/day");
|
|
page.tofrom = (fmgc.FMGCInternal.toFromSet) ? fmgc.FMGCInternal.depApt ~ "-" ~ fmgc.FMGCInternal.arrApt : "";
|
|
page.fltstart = 0;
|
|
page.blkstart = 0;
|
|
page.flttime = "--.--";
|
|
page.blktime = "--.--";
|
|
return page;
|
|
},
|
|
};
|
|
|
|
var formatSecToHHMM = func(sec) {
|
|
var mn = int(sec / 60);
|
|
return sprintf("%02d.%02d",int(mn/60),math.mod(mn,60));
|
|
}
|
|
|
|
var FlightLogDatabase = {
|
|
database: std.Vector.new(),
|
|
pages: std.Vector.new(),
|
|
currpageindex: 0,
|
|
addReport: func(report) {
|
|
if (report.state == 0 or me.getPageSize()==0) me.addPage();
|
|
me.database.append(report);
|
|
var pg = me.pages.vector[me.pages.size()-1];
|
|
if (report.state < 3) { # IN states (3/4) don't update page data
|
|
if (report.fltnum != "") pg.fltnum = report.fltnum;
|
|
if (report.tofrom != "") pg.tofrom = report.tofrom;
|
|
}
|
|
if (report.state == 0) {
|
|
pg.fltstate = "OUT";
|
|
pg.blkstart = report.elapsed;
|
|
}
|
|
else if (report.state == 1) {
|
|
pg.fltstate = "OFF";
|
|
pg.fltstart = report.elapsed;
|
|
}
|
|
else if (report.state == 2) {
|
|
pg.fltstate = "ON";
|
|
if (pg.fltstart > 0) pg.flttime = formatSecToHHMM(report.elapsed - pg.fltstart);
|
|
}
|
|
else if (report.state > 2) {
|
|
pg.fltstate = "END";
|
|
if (pg.blkstart > 0) pg.blktime = formatSecToHHMM(report.elapsed - pg.blkstart);
|
|
}
|
|
},
|
|
reset: func() {
|
|
#Actually reset occurs before IN state - I have no solution for this
|
|
#if (me.getPageSize()>0 and me.currpageindex < me.getSize()) me.addPage();
|
|
},
|
|
getSize: func() {
|
|
return me.database.size();
|
|
},
|
|
getPageSize: func() {
|
|
return me.pages.size();
|
|
},
|
|
clearDatabase: func() {
|
|
me.database.clear();
|
|
me.pages.clear();
|
|
},
|
|
getLogs: func() {
|
|
var lst = [];
|
|
foreach (var log; me.database) {
|
|
append(lst,log);
|
|
}
|
|
return lst;
|
|
},
|
|
addPage: func() {
|
|
me.currpageindex = me.getSize();
|
|
me.pages.append( OOOIReportPage.new(me.getSize()) );
|
|
},
|
|
getPage: func(pg) {
|
|
return (pg<=me.getPageSize()) ? me.pages.vector[pg-1] : OOOIReportPage.new(0);
|
|
},
|
|
getLogByPage: func(no) {
|
|
var lst = [nil,nil,nil,nil];
|
|
if (me.getPageSize() == 0) return lst;
|
|
var i = (me.getPageSize()>=no) ? me.pages.vector[no-1].index : 0;
|
|
var len = me.getSize();
|
|
var v = 0;
|
|
var p = 0;
|
|
while (i<len) {
|
|
p = me.database.vector[i].state;
|
|
if (v == 0 or p != 0) lst[v] = me.database.vector[i];
|
|
else i = len;
|
|
i+=1;
|
|
v+=1;
|
|
}
|
|
return lst;
|
|
},
|
|
};
|
|
|
|
var expectedOOOIState = 0; # OOOI states: 0 = out, 1 = OFF, 2 = ON, 3 = IN, 4 = RETURN-IN
|
|
|
|
var doorL1_pos = props.globals.getNode("/sim/model/door-positions/doorl1/position-norm", 1);
|
|
var doorR1_pos = props.globals.getNode("/sim/model/door-positions/doorr1/position-norm", 1);
|
|
var doorL4_pos = props.globals.getNode("/sim/model/door-positions/doorl4/position-norm", 1);
|
|
var doorR4_pos = props.globals.getNode("/sim/model/door-positions/doorr4/position-norm", 1);
|
|
|
|
# Detect OFF without IN
|
|
var lastgs0 = 0;
|
|
var phase = 0;
|
|
var gs = 0;
|
|
var gear0 = 0;
|
|
var lastgsrestart = 0;
|
|
|
|
# Check for A/C state change - advice me for a better method, please :/
|
|
var waitingOOOIChange = maketimer(1, func(){ # 1sec precision
|
|
phase = fmgc.FMGCInternal.phase;
|
|
gs = pts.Velocities.groundspeedKt.getValue();
|
|
gear0 = pts.Gear.wow[0].getBoolValue();
|
|
|
|
#print(sprintf("OOOI check: %d %d %.2f %s",expectedOOOIState,phase,gs,gear0));
|
|
|
|
if (expectedOOOIState == 0) { # OUT
|
|
if (gear0 and phase == 0) {
|
|
if (gs > 9) { # imho - it's useful few speed tollerance, 10kts min speed on taxiways - CHECKME - better with pushback detection?
|
|
FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState));
|
|
expectedOOOIState = 1;
|
|
}
|
|
}
|
|
} else if (expectedOOOIState == 1) { # OFF
|
|
if (!gear0) {
|
|
FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState));
|
|
expectedOOOIState = 2;
|
|
}
|
|
else if (gs < 1) { # RETURN-IN ?? - rejected takeoff, A/C back to apron - CHECKME
|
|
if (doorL1_pos.getValue()>0 or doorR1_pos.getValue()>0 or doorL4_pos.getValue()>0 or doorR4_pos.getValue()>0) {
|
|
FlightLogDatabase.addReport(OOOIReport.new(4)); # RETURN-IN
|
|
expectedOOOIState = 0;
|
|
}
|
|
}
|
|
} else if (expectedOOOIState == 2) { # ON
|
|
if (gear0 and (phase == 7 or phase == 0)) { #done or preflight
|
|
FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState));
|
|
expectedOOOIState = 3;
|
|
lastgs0 = 0;
|
|
lastgsrestart = 0;
|
|
}
|
|
} else if (expectedOOOIState == 3) { # IN
|
|
if (gear0 and gs < 1) {
|
|
if (lastgs0 == 0) {
|
|
lastgs0 = int(getprop("/sim/time/elapsed-sec"));
|
|
lastgsrestart = 0;
|
|
}
|
|
if (doorL1_pos.getValue()>0 or doorR1_pos.getValue()>0 or doorL4_pos.getValue()>0 or doorR4_pos.getValue()>0) {
|
|
FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState));
|
|
expectedOOOIState = 0;
|
|
}
|
|
}
|
|
else if (!gear0) { # OFF without IN -> TO without stop and opening doors
|
|
if (lastgs0>0) FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState,lastgs0)); # IN (estimated)
|
|
FlightLogDatabase.addPage();
|
|
if (lastgsrestart>0) FlightLogDatabase.addReport(OOOIReport.new(0,lastgsrestart)); # OUT (estimated)
|
|
expectedOOOIState = 1; # go on to OFF state
|
|
}
|
|
else if (gs > 9 and lastgsrestart == 0) { # try to detect OFF without IN
|
|
lastgsrestart = int(pts.Sim.Time.elapsedSec.getValue());
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
var engine_one_chk_OOOI = setlistener("/engines/engine[0]/state", func {
|
|
if (pts.Engines.Engine.state[0].getValue() == 3) {
|
|
removelistener(engine_one_chk_OOOI);
|
|
waitingOOOIChange.start();
|
|
}
|
|
},0,0);
|