diff --git a/A320-main.xml b/A320-main.xml
index 4d4302b1..0667bb75 100644
--- a/A320-main.xml
+++ b/A320-main.xml
@@ -614,6 +614,9 @@
S
+
+ E
4500
4500
@@ -4818,6 +4821,7 @@
Aircraft/A320-family/Nasal/Panels/efis.nas
+ Aircraft/A320-family/Nasal/FMGC/flightplan-delegates.nas
Aircraft/A320-family/Nasal/FMGC/flightplan-waypoints.nas
Aircraft/A320-family/Nasal/FMGC/flightplan.nas
Aircraft/A320-family/Nasal/FMGC/FMGC.nas
diff --git a/Models/Instruments/MCDU/MCDU.nas b/Models/Instruments/MCDU/MCDU.nas
index 987f648b..50a20adc 100644
--- a/Models/Instruments/MCDU/MCDU.nas
+++ b/Models/Instruments/MCDU/MCDU.nas
@@ -170,11 +170,13 @@ var canvas_MCDU_base = {
me["Simple_L6S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_C1S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_C2S"].setFont("HoneywellMCDUSmall.ttf");
+ me["Simple_C3S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_C4S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_C5S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_C6S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_R1S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_R2S"].setFont("HoneywellMCDUSmall.ttf");
+ me["Simple_R3S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_R4S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_R5S"].setFont("HoneywellMCDUSmall.ttf");
me["Simple_R6S"].setFont("HoneywellMCDUSmall.ttf");
@@ -519,9 +521,7 @@ var canvas_MCDU_base = {
me.hideAllArrows();
- me.fontSizeLeft(normal, normal, normal, normal, normal, normal);
- me.fontSizeCenter(normal, normal, normal, normal, normal, normal);
- me.fontSizeRight(normal, normal, normal, normal, normal, normal);
+ me.standardFontSize();
pageSwitch[i].setBoolValue(1);
}
@@ -553,6 +553,7 @@ var canvas_MCDU_base = {
me.colorLeftS("wht", "wht", "wht", "wht", "wht", "wht");
me.colorLeftArrow("wht", "wht", "wht", "wht", "wht", "wht");
+ me.colorCenterS("wht", "wht", "wht", "wht", "wht", "wht");
me.colorRightS("wht", "wht", "wht", "wht", "wht", "wht");
me.colorRightArrow("wht", "wht", "wht", "wht", "wht", "wht");
@@ -2991,6 +2992,19 @@ var canvas_MCDU_base = {
me.colorRightS("wht", "amb", "wht", "wht", "wht", "wht");
me.colorRightArrow("wht", "wht", "wht", "wht", "wht", "wht");
+ me["Simple_L1S"].setText("CO RTE");
+ me["Simple_L2S"].setText("ALTN/CO RTE");
+ me["Simple_L3S"].setText("FLT NBR");
+ me["Simple_L5S"].setText("COST INDEX");
+ me["Simple_L6S"].setText("CRZ FL/TEMP");
+ me["Simple_R1S"].setText("FROM/TO ");
+ me["Simple_R2S"].setText("INIT ");
+ me["Simple_R5S"].setText("TROPO");
+ me["Simple_R6S"].setText("GND TEMP");
+ me["Simple_R2"].setText("REQUEST ");
+ me["Simple_R3"].setText("IRS INIT ");
+ me["Simple_R4"].setText("WIND ");
+
pageSwitch[i].setBoolValue(1);
}
@@ -3023,13 +3037,13 @@ var canvas_MCDU_base = {
} else if (fmgc.FMGCInternal.crzSet and fmgc.FMGCInternal.crzTempSet) {
me["INITA_CruiseFLTemp"].hide();
me["Simple_L6"].setColor(BLUE);
- me["Simple_L6"].setText(sprintf("%s", "FL" ~ fmgc.FMGCInternal.crzFl) ~ sprintf("/%s°", fmgc.FMGCInternal.crzTemp));
+ me["Simple_L6"].setText(sprintf("%s", "FL" ~ fmgc.FMGCInternal.crzFl) ~ sprintf("/%+3.0f°", fmgc.FMGCInternal.crzTemp));
} else if (fmgc.FMGCInternal.crzSet) {
me["INITA_CruiseFLTemp"].hide();
me["Simple_L6"].setColor(BLUE);
fmgc.FMGCInternal.crzTemp = 15 - (2 * fmgc.FMGCInternal.crzFl / 10);
fmgc.FMGCInternal.crzTempSet = 1;
- me["Simple_L6"].setText(sprintf("%s", "FL" ~ fmgc.FMGCInternal.crzFl) ~ sprintf("/%s°", fmgc.FMGCInternal.crzTemp));
+ me["Simple_L6"].setText(sprintf("%s", "FL" ~ fmgc.FMGCInternal.crzFl) ~ sprintf("/%+3.0f°", fmgc.FMGCInternal.crzTemp));
} else {
me["INITA_CruiseFLTemp"].show();
me["Simple_L6"].setColor(AMBER);
@@ -3072,6 +3086,7 @@ var canvas_MCDU_base = {
me["INITA_InitRequest"].hide();
}
}
+
if (ADIRSMCDUBTN.getValue() != 1) {
me["INITA_AlignIRS"].show();
me["Simple_R3"].setColor(AMBER);
@@ -3081,41 +3096,34 @@ var canvas_MCDU_base = {
me["Simple_R3"].setColor(WHITE);
showRightArrow(me,0, 0, 1, 0, 0, 0);
}
+
if (fmgc.FMGCInternal.tropoSet) {
me["Simple_R5"].setFontSize(normal);
} else {
me["Simple_R5"].setFontSize(small);
}
- me["Simple_R6S"].setText("GND TEMP");
- if (fmgc.FMGCInternal.phase == 0 and !fmgc.FMGCInternal.gndTempSet) {
- fmgc.FMGCInternal.gndTemp = 15 - (2 * getprop("/position/gear-agl-ft") / 1000);
- me["Simple_R6"].setText(sprintf("%.0f°", fmgc.FMGCInternal.gndTemp));
- me["Simple_R6"].setFontSize(small);
- } else {
+ if (fmgc.FMGCInternal.phase == 0) {
if (fmgc.FMGCInternal.gndTempSet) {
+ me["Simple_R6"].setText(sprintf("%.0f°", fmgc.FMGCInternal.gndTemp));
me["Simple_R6"].setFontSize(normal);
+ } else if (fmgc.FMGCInternal.toFromSet) {
+ fmgc.FMGCInternal.gndTemp = 15 - (2 * (fmgc.flightPlanController.flightplans[2].departure.elevation * 3.28084) / 1000);
+ me["Simple_R6"].setText(sprintf("%.0f°", fmgc.FMGCInternal.gndTemp));
+ me["Simple_R6"].setFontSize(small);
} else {
+ me["Simple_R6"].setText(sprintf("%.0f°", fmgc.FMGCInternal.gndTemp));
me["Simple_R6"].setFontSize(small);
}
- me["Simple_R6"].setText(sprintf("%.0f°", fmgc.FMGCInternal.gndTemp));
+ } else {
+ me["Simple_R6"].setText("---");
+ me["Simple_R6"].setFontSize(small);
}
- me["Simple_L1S"].setText("CO RTE");
- me["Simple_L2S"].setText("ALTN/CO RTE");
- me["Simple_L3S"].setText("FLT NBR");
- me["Simple_L5S"].setText("COST INDEX");
- me["Simple_L6S"].setText("CRZ FL/TEMP");
#me["Simple_L1"].setText("NONE"); # manage before (coRoute)
me["Simple_L3"].setText(sprintf("%s", fmgc.FMGCInternal.flightNum));
- me["Simple_R1S"].setText("FROM/TO ");
- me["Simple_R2S"].setText("INIT ");
- me["Simple_R5S"].setText("TROPO");
me["Simple_R1"].setText(sprintf("%s", fmgc.FMGCInternal.depApt ~ "/" ~ fmgc.FMGCInternal.arrApt));
- me["Simple_R2"].setText("REQUEST ");
- me["Simple_R3"].setText("IRS INIT ");
- me["Simple_R4"].setText("WIND ");
me["Simple_R5"].setText(sprintf("%5.0f", fmgc.FMGCInternal.tropo));
} else if (page == "IRSINIT") {
if (!pageSwitch[i].getBoolValue()) {
@@ -3189,9 +3197,9 @@ var canvas_MCDU_base = {
degrees = getprop("/FMGC/internal/align-ref-lat-degrees");
minutes = getprop("/FMGC/internal/align-ref-lat-minutes");
sign = getprop("/FMGC/internal/align-ref-lat-sign");
- dms_lat = getprop("/FMGC/flightplan[2]/wp[0]/lat");
- degrees_lat = int(dms_lat);
- minutes_lat = sprintf("%.1f",abs((dms_lat - degrees_lat) * 60));
+ apt = airportinfo(fmgc.FMGCInternal.depApt);
+ degrees_lat = int(apt.lat);
+ minutes_lat = sprintf("%.1f",abs((apt.lat - degrees_lat) * 60));
sign_lat = degrees_lat >= 0 ? "N" : "S";
lat_same = degrees_lat == degrees and minutes_lat == minutes and sign_lat == sign;
me["Simple_L1"].setText(abs(sprintf("%.0f", degrees)) ~ "°" ~ sprintf("%.1f", minutes) ~ sign);
@@ -3199,15 +3207,14 @@ var canvas_MCDU_base = {
degrees = getprop("/FMGC/internal/align-ref-long-degrees");
minutes = getprop("/FMGC/internal/align-ref-long-minutes");
sign = getprop("/FMGC/internal/align-ref-long-sign");
- dms_long = getprop("/FMGC/flightplan[2]/wp[0]/lon");
- degrees_long = int(dms_long);
- minutes_long = sprintf("%.1f",abs((dms_long - degrees_long) * 60));
+ degrees_long = int(apt.lon);
+ minutes_long = sprintf("%.1f",abs((apt.lon - degrees_long) * 60));
sign_long = degrees_long >= 0 ? "E" : "W";
long_same = degrees_long == degrees and minutes_long == minutes and sign_long == sign;
me["Simple_R1"].setText(abs(sprintf("%.0f", degrees)) ~ "°" ~ sprintf("%.1f", minutes) ~ sign);
if (lat_same and long_same) {
- me["Simple_C1"].setText(getprop("/FMGC/flightplan[2]/wp[0]/id"));
+ me["Simple_C1"].setText(getprop("/autopilot/route-manager/route/wp[0]/id"));
me["Simple_C1"].setColor(GREEN);
} else {
me["Simple_C1"].setText("----");
@@ -3837,18 +3844,6 @@ var canvas_MCDU_base = {
me["Simple_L2"].setText(fmgc.FMGCInternal.altAirport);
}
- me["Simple_L1S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_L3S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_L4S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_L5S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_L6S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_C1S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_R1S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_R3S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_R4S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_R5S"].setFont("HoneywellMCDUSmall.ttf");
- me["Simple_R6S"].setFont("HoneywellMCDUSmall.ttf");
-
me["Simple_L1S"].setText("AT");
me["Simple_L3S"].setText("RTE RSV/%");
me["Simple_L4S"].setText("ALTN /TIME");
diff --git a/Models/Instruments/ND/canvas/map/RTE.lcontroller b/Models/Instruments/ND/canvas/map/RTE.lcontroller
index 42343196..4e22ea44 100644
--- a/Models/Instruments/ND/canvas/map/RTE.lcontroller
+++ b/Models/Instruments/ND/canvas/map/RTE.lcontroller
@@ -12,9 +12,9 @@ SymbolLayer.add(name, {
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: { # default configuration options
- active_node: "/FMGC/flightplan[2]/active",
- current_wp_node: "/FMGC/flightplan[2]/current-wp",
- wp_num: "/FMGC/flightplan[2]/num",
+ active_node: "/autopilot/route-manager/active",
+ current_wp_node: "/autopilot/route-manager/current-wp",
+ wp_num: "/autopilot/route-manager/route/num",
display_inactive_rte: 0
}
});
diff --git a/Models/Instruments/ND/canvas/map/WPT-airbus.symbol b/Models/Instruments/ND/canvas/map/WPT-airbus.symbol
index 8320f312..472dd1a2 100644
--- a/Models/Instruments/ND/canvas/map/WPT-airbus.symbol
+++ b/Models/Instruments/ND/canvas/map/WPT-airbus.symbol
@@ -79,7 +79,7 @@ var init = func {
}
var draw = func{
- if (me.model.wp.hidden == 1 or me.model.name == "(DECEL)" or me.model.name == "(T/C)" or me.model.name == "(T/D)" or me.model.name == "(LIM)") {
+ if (me.model.wp.hidden == 1) {
me.wp_sym.hide();
me.text_wps.hide();
if (me.text_alt != nil) {
diff --git a/Models/Instruments/ND/canvas/style.nas b/Models/Instruments/ND/canvas/style.nas
index 00d2f78d..b6cc371c 100644
--- a/Models/Instruments/ND/canvas/style.nas
+++ b/Models/Instruments/ND/canvas/style.nas
@@ -56,12 +56,12 @@ canvas.NDStyles["Airbus"] = {
# that the lateral flight mode is managed.
# You can easily override these options before creating the ND, example:
# canvas.NDStyles["Airbus"].options.defaults.fplan_active = "my/autpilot/f-plan/active"
- fplan_active: "/FMGC/flightplan[2]/active",
+ fplan_active: "/autopilot/route-manager/active",
lat_ctrl: "/it-autoflight/output/lat",
managed_val: 1,
ver_ctrl: "/it-autoflight/output/vert",
spd_ctrl: "/it-autoflight/input/spd-managed",
- current_wp: "/FMGC/flightplan[2]/current-wp",
+ current_wp: "/autopilot/route-manager/current-wp",
ap1: "/it-autoflight/output/ap1",
ap2: "/it-autoflight/output/ap2",
nav1_frq: "/instrumentation/nav[0]/frequencies/selected-mhz",
@@ -72,7 +72,7 @@ canvas.NDStyles["Airbus"] = {
adf2_frq: "/instrumentation/adf[1]/frequencies/selected-khz",
dep_rwy: "/autopilot/route-manager/departure/runway",
dest_rwy: "/autopilot/route-manager/destination/runway",
- wp_count: "/FMGC/flightplan[2]/num",
+ wp_count: "/autopilot/route-manager/route/num",
level_off_alt: "/autopilot/route-manager/vnav/level-off-alt",
athr: "/it-autoflight/output/athr",
app_mode: "/instrumentation/nd/app-mode",
@@ -593,7 +593,7 @@ canvas.NDStyles["Airbus"] = {
{
name: "DECEL",
isMapStructure: 1,
- update_on: ["toggle_display_mode","toggle_range"],
+ update_on: [ {rate_hz: 1}, "toggle_display_mode","toggle_range"],
predicate: func(nd, layer) {
var visible = nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]) and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)) and getprop("/instrumentation/nd/symbols/decel/show");
layer.group.setVisible( visible );
@@ -806,11 +806,10 @@ canvas.NDStyles["Airbus"] = {
id: "wpActiveId",
impl: {
init: func(nd,symbol),
- predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg") != nil and
- getprop("/FMGC/flightplan[2]/active") and
+ predicate: func(nd) getprop("/autopilot/route-manager/wp[0]/id") != nil and getprop("/autopilot/route-manager/active") and
nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]) and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
is_true: func(nd) {
- nd.symbols.wpActiveId.setText(getprop("/FMGC/flightplan[2]/current-leg"));
+ nd.symbols.wpActiveId.setText(getprop("/autopilot/route-manager/wp[0]/id"));
nd.symbols.wpActiveId.show();
},
is_false: func(nd) nd.symbols.wpActiveId.hide(),
@@ -820,16 +819,14 @@ canvas.NDStyles["Airbus"] = {
id: "wpActiveCrs",
impl: {
init: func(nd,symbol),
- predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg") != nil and
- getprop("/FMGC/flightplan[2]/active") and
+ predicate: func(nd) getprop("/autopilot/route-manager/wp[0]/id") != nil and getprop("/autopilot/route-manager/active") and
nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]) and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
is_true: func(nd) {
- #var cur_wp = getprop("/autopilot/route-manager/current-wp");
var deg = nil;
if (nd.get_switch("toggle_true_north")) {
- var deg = math.round(getprop("/FMGC/flightplan[2]/current-leg-course")) or 0;
+ var deg = math.round(getprop("/autopilot/route-manager/wp[0]/true-bearing-deg") or 0);
} else {
- var deg = math.round(getprop("/FMGC/flightplan[2]/current-leg-course-mag")) or 0;
+ var deg = math.round(getprop("/autopilot/route-manager/wp[0]/bearing-deg") or 0);
}
if (deg != nil) {
nd.symbols.wpActiveCrs.setText(sprintf("%03.0f°", deg));
@@ -845,13 +842,11 @@ canvas.NDStyles["Airbus"] = {
id: "wpActiveDist",
impl: {
init: func(nd,symbol),
- predicate: func(nd) (getprop("/FMGC/flightplan[2]/current-leg-dist") != nil and
- getprop("/FMGC/flightplan[2]/active") and
+ predicate: func(nd) (getprop("/autopilot/route-manager/wp[0]/dist") != nil and getprop("/autopilot/route-manager/active") and
nd.in_mode("toggle_display_mode", ["MAP", "PLAN"])
and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting))),
is_true: func(nd) {
- var dst = getprop("/FMGC/flightplan[2]/current-leg-dist");
- nd.symbols.wpActiveDist.setText(sprintf("%3.01f",dst));
+ nd.symbols.wpActiveDist.setText(sprintf("%3.01f", getprop("/autopilot/route-manager/wp[0]/dist")));
nd.symbols.wpActiveDist.show();
},
is_false: func(nd) nd.symbols.wpActiveDist.hide(),
@@ -861,11 +856,11 @@ canvas.NDStyles["Airbus"] = {
id: "wpActiveDistLbl",
impl: {
init: func(nd,symbol),
- predicate: func(nd) getprop("/FMGC/flightplan[2]/current-leg-dist") != nil and getprop("/FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"])
- and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
+ predicate: func(nd) getprop("/autopilot/route-manager/wp[0]/dist") != nil and getprop("/autopilot/route-manager/active") and
+ nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]) and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
is_true: func(nd) {
nd.symbols.wpActiveDistLbl.show();
- if(getprop("/FMGC/flightplan[2]/current-leg-dist") > 1000)
+ if(getprop("/autopilot/route-manager/wp[0]/dist") > 1000)
nd.symbols.wpActiveDistLbl.setText(" NM");
},
is_false: func(nd) nd.symbols.wpActiveDistLbl.hide(),
@@ -875,8 +870,8 @@ canvas.NDStyles["Airbus"] = {
id: "eta",
impl: {
init: func(nd,symbol),
- predicate: func(nd) getprop("/autopilot/route-manager/wp/eta") != nil and getprop("/FMGC/flightplan[2]/active") and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"])
- and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
+ predicate: func(nd) getprop("/autopilot/route-manager/wp/eta") != nil and getprop("/autopilot/route-manager/active")
+ and nd.in_mode("toggle_display_mode", ["MAP", "PLAN"]) and (nd.adirs_property.getValue() == 1 or (adirs_3.getValue() == 1 and att_switch.getValue() == nd.attitude_heading_setting)),
is_true: func(nd) {
var etaSec = getprop("/sim/time/utc/day-seconds")+
getprop("/autopilot/route-manager/wp/eta-seconds");
@@ -1904,7 +1899,7 @@ canvas.NDStyles["Airbus"] = {
init: func(nd,symbol),
predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and !nd.get_switch("toggle_centered")),
is_true: func(nd){
- var active = getprop("/FMGC/flightplan[2]/active");
+ var active = getprop("/autopilot/route-manager/active");
var lat_ctrl = getprop(nd.options.defaults.lat_ctrl);
var managed_v = nd.options.defaults.managed_val;
var is_managed = (lat_ctrl == managed_v);
@@ -1933,7 +1928,7 @@ canvas.NDStyles["Airbus"] = {
init: func(nd,symbol),
predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and !nd.get_switch("toggle_centered")),
is_true: func(nd){
- var active = getprop("/FMGC/flightplan[2]/active");
+ var active = getprop("/autopilot/route-manager/active");
var lat_ctrl = getprop(nd.options.defaults.lat_ctrl);
var managed_v = nd.options.defaults.managed_val;
var is_managed = (lat_ctrl == managed_v);
@@ -1962,7 +1957,7 @@ canvas.NDStyles["Airbus"] = {
init: func(nd,symbol),
predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and nd.get_switch("toggle_centered")),
is_true: func(nd){
- var active = getprop("/FMGC/flightplan[2]/active");
+ var active = getprop("/autopilot/route-manager/active");
var lat_ctrl = getprop(nd.options.defaults.lat_ctrl);
var managed_v = nd.options.defaults.managed_val;
var is_managed = (lat_ctrl == managed_v);
@@ -1991,7 +1986,7 @@ canvas.NDStyles["Airbus"] = {
init: func(nd,symbol),
predicate: func(nd) (nd.get_switch("toggle_display_mode") == "MAP" and nd.get_switch("toggle_centered")),
is_true: func(nd){
- var active = getprop("/FMGC/flightplan[2]/active");
+ var active = getprop("/autopilot/route-manager/active");
var lat_ctrl = getprop(nd.options.defaults.lat_ctrl);
var managed_v = nd.options.defaults.managed_val;
var is_managed = (lat_ctrl == managed_v);
@@ -2020,7 +2015,7 @@ canvas.NDStyles["Airbus"] = {
init: func(nd,symbol),
predicate: func(nd) (nd.in_mode("toggle_display_mode", ["MAP", "PLAN"])),
is_true: func(nd){
- var active = getprop("/FMGC/flightplan[2]/active");
+ var active = getprop("/autopilot/route-manager/active");
var lat_ctrl = getprop(nd.options.defaults.lat_ctrl);
var managed_v = nd.options.defaults.managed_val;
var is_managed = (lat_ctrl == managed_v);
diff --git a/Models/Instruments/PFD/PFD.nas b/Models/Instruments/PFD/PFD.nas
index b1d87283..7db0395d 100644
--- a/Models/Instruments/PFD/PFD.nas
+++ b/Models/Instruments/PFD/PFD.nas
@@ -1702,7 +1702,7 @@ var canvas_pfd = {
}
notification.radioNo = fmgc.FMGCInternal.radioNo;
- if (fmgc.FMGCInternal.phase < 3 or fmgc.flightPlanController.arrivalDist >= 250) {
+ if (fmgc.FMGCInternal.phase < 3 or fmgc.flightPlanController.arrivalDist.getValue() >= 250) {
notification.showDecisionHeight = 0;
} else {
notification.showDecisionHeight = 1;
diff --git a/Nasal/FMGC/FCU.nas b/Nasal/FMGC/FCU.nas
index 7465109c..92d7d427 100644
--- a/Nasal/FMGC/FCU.nas
+++ b/Nasal/FMGC/FCU.nas
@@ -294,7 +294,10 @@ var FCUController = {
HDGPush: func() {
if (me.FCUworking) {
if (fmgc.Output.fd1.getBoolValue() or fmgc.Output.fd2.getBoolValue() or fmgc.Output.ap1.getBoolValue() or fmgc.Output.ap2.getBoolValue()) {
- fmgc.Input.lat.setValue(1);
+ var wp = fmgc.flightPlanController.flightplans[2].getWP(fmgc.flightPlanController.currentToWptIndex.getValue());
+ if (wp != nil and wp.wp_type != "discontinuity" and wp.wp_type != "vectors") {
+ fmgc.Input.lat.setValue(1);
+ }
}
}
},
diff --git a/Nasal/FMGC/FMGC-b.nas b/Nasal/FMGC/FMGC-b.nas
index 5ae91693..713c99f6 100644
--- a/Nasal/FMGC/FMGC-b.nas
+++ b/Nasal/FMGC/FMGC-b.nas
@@ -14,21 +14,21 @@ var Controls = {
};
var FPLN = {
- active: props.globals.getNode("/FMGC/flightplan[2]/active", 1),
+ active: props.globals.getNode("/autopilot/route-manager/active", 1),
activeTemp: 0,
currentCourse: 0,
- currentWp: props.globals.getNode("/FMGC/flightplan[2]/current-wp", 1),
- currentWpTemp: 0,
+ currentWP: props.globals.getNode("/autopilot/route-manager/current-wp", 1),
+ currentWPTemp: 0,
deltaAngle: 0,
deltaAngleRad: 0,
distCoeff: 0,
maxBank: 0,
maxBankLimit: 0,
nextCourse: 0,
- R: 0,
radius: 0,
+ R: 0,
turnDist: 0,
- wp0Dist: props.globals.getNode("/FMGC/flightplan[2]/current-leg-dist", 1),
+ wp0Dist: props.globals.getNode("/autopilot/route-manager/wp[0]/dist", 1),
wpFlyFrom: 0,
wpFlyTo: 0,
};
@@ -367,26 +367,21 @@ var ITAF = {
slowLoop: func() {
Velocities.trueAirspeedKtTemp = Velocities.trueAirspeedKt.getValue();
FPLN.activeTemp = FPLN.active.getValue();
- FPLN.currentWpTemp = FPLN.currentWp.getValue();
+ FPLN.currentWPTemp = FPLN.currentWP.getValue();
# If in LNAV mode and route is not longer active, switch to HDG HLD
if (Output.lat.getValue() == 1) { # Only evaulate the rest of the condition if we are in LNAV mode
- if (flightPlanController.num[2].getValue() == 0 or !FPLN.active.getBoolValue()) {
+ if (flightPlanController.num[2].getValue() == 0 or !FPLN.activeTemp) {
me.setLatMode(3);
}
}
# Waypoint Advance Logic
- if (flightPlanController.num[2].getValue() > 0 and FPLN.activeTemp == 1) {
- if ((FPLN.currentWpTemp + 1) < flightPlanController.num[2].getValue()) {
- Velocities.groundspeedMps = Velocities.groundspeedKt.getValue() * 0.5144444444444;
- FPLN.wpFlyFrom = FPLN.currentWpTemp;
- if (FPLN.wpFlyFrom < 0) {
- FPLN.wpFlyFrom = 0;
- }
- FPLN.currentCourse = fmgc.wpCourse[2][FPLN.wpFlyFrom].getValue();
- FPLN.wpFlyTo = FPLN.currentWpTemp + 1;
- FPLN.nextCourse = fmgc.wpCourse[2][FPLN.wpFlyTo].getValue();
+ if (flightPlanController.num[2].getValue() > 0 and FPLN.activeTemp == 1 and FPLN.currentWPTemp != -1) {
+ if ((FPLN.currentWPTemp + 1) < flightPlanController.num[2].getValue()) {
+ Velocities.groundspeedMps = pts.Velocities.groundspeed.getValue() * 0.5144444444444;
+ FPLN.currentCourse = getprop("/autopilot/route-manager/route/wp[" ~ FPLN.currentWPTemp ~ "]/leg-bearing-true-deg");
+ FPLN.nextCourse = getprop("/autopilot/route-manager/route/wp[" ~ (FPLN.currentWPTemp + 1) ~ "]/leg-bearing-true-deg");
FPLN.maxBankLimit = Internal.bankLimit.getValue();
FPLN.deltaAngle = math.abs(geo.normdeg180(FPLN.currentCourse - FPLN.nextCourse));
@@ -405,11 +400,17 @@ var ITAF = {
if (Gear.wow0.getBoolValue() and FPLN.turnDist < 1) {
FPLN.turnDist = 1;
}
- Internal.lnavAdvanceNm.setValue(FPLN.turnDist);
- if (FPLN.wp0Dist.getValue() <= FPLN.turnDist and !Gear.wow1.getBoolValue() and fmgc.flightPlanController.flightplans[2].getWP(FPLN.currentWpTemp).fly_type == "flyBy") {
+ # This is removed because sequencing is done by the flightplan controller
+ # Internal.lnavAdvanceNm.setValue(FPLN.turnDist);
+
+ # TODO - if the waypoint is the DEST waypoint, crosstrack error must be less than 0.5nm and course error less than 30 deg
+ # TODO - if in HDG mode, if no distance, then crosstrack error must be less than 5nm
+ # TODO - if in nav, no distance condition applies, but DEST course error must be less than 30 (CONFIRM)
+
+ if (abs(FPLN.deltaAngle) < 120 and FPLN.wp0Dist.getValue() <= FPLN.turnDist and !Gear.wow1.getBoolValue() and fmgc.flightPlanController.flightplans[2].getWP(FPLN.currentWPTemp).fly_type == "flyBy") {
flightPlanController.autoSequencing();
- } elsif (FPLN.wp0Dist.getValue() <= 0.15) {
+ } elsif (FPLN.wp0Dist.getValue() <= 0.15 and !Gear.wow1.getBoolValue()) {
flightPlanController.autoSequencing();
}
}
@@ -961,6 +962,12 @@ var ITAF = {
},
};
+setlistener(Gear.wow1, func(val) {
+ if (!val.getBoolValue() and FPLN.currentWP.getValue() == 0) {
+ flightPlanController.autoSequencing();
+ }
+});
+
setlistener("/it-autoflight/input/ap1", func() {
Input.ap1Temp = Input.ap1.getBoolValue();
if (Input.ap1Temp != Output.ap1.getBoolValue()) {
diff --git a/Nasal/FMGC/FMGC.nas b/Nasal/FMGC/FMGC.nas
index befbbe94..9ba21edd 100644
--- a/Nasal/FMGC/FMGC.nas
+++ b/Nasal/FMGC/FMGC.nas
@@ -29,6 +29,8 @@ var mng_alt_spd = 0;
var mng_alt_mach = 0;
var altsel = 0;
var crzFl = 0;
+var xtrkError = 0;
+var courseDistanceDecel = 0;
var windHdg = 0;
var windSpeed = 0;
var windsDidChange = 0;
@@ -444,7 +446,7 @@ var updateFuel = func {
if (FMGCInternal.toFromSet and FMGCInternal.crzSet and FMGCInternal.crzTempSet and FMGCInternal.zfwSet) {
crz = FMGCInternal.crzFl;
temp = FMGCInternal.crzTemp;
- dist = flightPlanController.arrivalDist;
+ dist = flightPlanController.arrivalDist.getValue();
trpWind = FMGCInternal.tripWind;
wind_value = FMGCInternal.tripWindValue;
@@ -458,7 +460,7 @@ var updateFuel = func {
trip_fuel = math.clamp(trip_fuel, 400, 80000);
# cruize temp correction
- trip_fuel = trip_fuel + (0.033 * (temp - 15 + (2 * crz / 10)) * flightPlanController.arrivalDist);
+ trip_fuel = trip_fuel + (0.033 * (temp - 15 + (2 * crz / 10)) * flightPlanController.arrivalDist.getValue());
trip_time = 9.095e-02 + (dist*-3.968e-02) + (dist*dist*4.302e-04) + (dist*dist*dist*2.005e-07) + (dist*dist*dist*dist*-6.876e-11) + (dist*dist*dist*dist*dist*1.432e-14) + (dist*dist*dist*dist*dist*dist*-1.177e-18) + (crz*7.348e-01) + (dist*crz*3.310e-03) + (dist*dist*crz*-8.700e-06) + (dist*dist*dist*crz*-4.214e-10) + (dist*dist*dist*dist*crz*5.652e-14) + (dist*dist*dist*dist*dist*crz*-6.379e-18) + (crz*crz*-1.449e-02) + (dist*crz*crz*-7.508e-06) + (dist*dist*crz*crz*4.529e-08) + (dist*dist*dist*crz*crz*3.699e-13) + (dist*dist*dist*dist*crz*crz*8.466e-18) + (crz*crz*crz*1.108e-04) + (dist*crz*crz*crz*-4.126e-08) + (dist*dist*crz*crz*crz*-9.645e-11) + (dist*dist*dist*crz*crz*crz*-1.544e-16) + (crz*crz*crz*crz*-4.123e-07) + (dist*crz*crz*crz*crz*1.831e-10) + (dist*dist*crz*crz*crz*crz*7.438e-14) + (crz*crz*crz*crz*crz*7.546e-10) + (dist*crz*crz*crz*crz*crz*-1.921e-13) + (crz*crz*crz*crz*crz*crz*-5.453e-13);
trip_time = math.clamp(trip_time, 10, 480);
@@ -643,12 +645,12 @@ var masterFMGC = maketimer(0.2, func {
}
} elsif (FMGCInternal.phase == 3) {
if (FMGCInternal.crzFl >= 200) {
- if ((flightPlanController.arrivalDist <= 200 and altSel < 20000)) {
+ if ((flightPlanController.arrivalDist.getValue() <= 200 or altSel < 20000)) {
newphase = 4;
systems.PNEU.pressMode.setValue("DE");
}
} else {
- if ((flightPlanController.arrivalDist <= 200 and altSel < (FMGCInternal.crzFl * 100))) { # todo - not sure about crzFl condition, investigate what happens!
+ if ((flightPlanController.arrivalDist.getValue() <= 200 or altSel < (FMGCInternal.crzFl * 100))) { # todo - not sure about crzFl condition, investigate what happens!
newphase = 4;
systems.PNEU.pressMode.setValue("DE");
}
@@ -668,11 +670,18 @@ var masterFMGC = maketimer(0.2, func {
newphase = 2;
}
}
+
+ xtrkError = getprop("/instrumentation/gps/wp/wp[1]/course-error-nm");
- if (flightPlanController.num[2].getValue() > 0 and getprop("/FMGC/flightplan[2]/active") == 1 and
- flightPlanController.arrivalDist <= 15 and (Modes.PFD.FMA.rollMode == "NAV" or Modes.PFD.FMA.rollMode == "LOC" or Modes.PFD.FMA.rollMode == "LOC*") and pts.Position.gearAglFt.getValue() < 9500) { #todo decel pseudo waypoint
- FMGCInternal.decel = 1;
- } elsif (FMGCInternal.decel and (FMGCInternal.phase == 0 or FMGCInternal.phase == 6)) {
+ if (flightPlanController.decelPoint != nil) {
+ courseDistanceDecel = courseAndDistance(flightPlanController.decelPoint.lat, flightPlanController.decelPoint.lon);
+ if (flightPlanController.num[2].getValue() > 0 and fmgc.flightPlanController.active.getBoolValue() and flightPlanController.decelPoint != nil and (courseDistanceDecel[1] <= 5 and (math.abs(courseDistanceDecel[0] - pts.Orientation.heading.getValue()) >= 90 and xtrkError <= 5) or courseDistanceDecel[1] <= 0.1) and (Modes.PFD.FMA.rollMode == "NAV" or Modes.PFD.FMA.rollMode == "LOC" or Modes.PFD.FMA.rollMode == "LOC*") and pts.Position.gearAglFt.getValue() < 9500) {
+ FMGCInternal.decel = 1;
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
+ } elsif (FMGCInternal.decel and (FMGCInternal.phase == 0 or FMGCInternal.phase == 6)) {
+ FMGCInternal.decel = 0;
+ }
+ } else {
FMGCInternal.decel = 0;
}
diff --git a/Nasal/FMGC/flightplan-delegates.nas b/Nasal/FMGC/flightplan-delegates.nas
new file mode 100644
index 00000000..553e45fe
--- /dev/null
+++ b/Nasal/FMGC/flightplan-delegates.nas
@@ -0,0 +1,311 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# NOTE! This copyright does *not* cover user models that use these Nasal
+# services by normal function calls - this is merely considered normal use
+# of the code, and does *not* fall under the heading of "derived work."
+#
+# Copyright (C) 2012-202 by James Turner
+
+# route_manager.nas - FlightPlan delegate(s) corresponding to the built-
+# in route-manager dialog and GPS. Intended to provide a sensible default behaviour,
+# but can be disabled by an aircraft-specific FMS / GPS system.
+
+# This delegate corresponds to functionality of the built-in route-manager dialog.
+# if you disable it, the built-in route-manager dialog may not work as expected.
+# Especially, this dialog is responsible for building departure, approach and
+# arrival waypoints corresponding to the requested SID/STAR/approach,
+# and replacing them when the inputs change (eg, user seelcted a different
+# destination or STAR while enroute)
+#
+# You can disable the default GPS behaviour *without* touching this delegate : they are
+# kept seperate since this first one is less likely to need changes
+
+
+var A320RouteManagerDelegate = {
+ new: func(fp) {
+ var m = { parents: [A320RouteManagerDelegate] };
+
+ logprint(LOG_INFO, 'creating A320 Route Manager FPDelegate');
+
+ m.flightplan = fp;
+ return m;
+ },
+
+ departureChanged: func
+ {
+ logprint(LOG_INFO, 'saw departure changed');
+ me.flightplan.clearWPType('sid');
+ if (me.flightplan.departure == nil)
+ return;
+
+ if (me.flightplan.departure_runway == nil) {
+ # no runway, only an airport, use that
+ var wp = createWPFrom(me.flightplan.departure);
+ wp.wp_role = 'sid';
+ me.flightplan.insertWP(wp, 0);
+ return;
+ }
+ # first, insert the runway itself
+ var wp = createWPFrom(me.flightplan.departure_runway);
+ wp.wp_role = 'sid';
+ me.flightplan.insertWP(wp, 0);
+ if (me.flightplan.sid == nil)
+ return;
+
+ # and we have a SID
+ var sid = me.flightplan.sid;
+ logprint(LOG_INFO, 'routing via SID ' ~ sid.id);
+
+ var wps = sid.route(me.flightplan.departure_runway, me.flightplan.sid_trans);
+ var lastWP = wps[-1];
+ var foundIdx = -999;
+
+ for (var wptIdx = 0; wptIdx < me.flightplan.getPlanSize(); wptIdx = wptIdx + 1) {
+ if (me.flightplan.getWP(wptIdx).id == lastWP.id) {
+ foundIdx = wptIdx;
+ break;
+ }
+ }
+
+ if (foundIdx != -999) {
+ while (foundIdx > 0) {
+ me.flightplan.deleteWP(1);
+ foundIdx -= 1;
+ }
+ }
+
+ me.flightplan.insertWaypoints(wps, 1);
+ },
+
+ arrivalChanged: func
+ {
+ me.flightplan.clearWPType('star');
+ me.flightplan.clearWPType('approach');
+ if (me.flightplan.destination == nil)
+ return;
+
+ if (me.flightplan.destination_runway == nil) {
+ # no runway, only an airport, use that
+ var wp = createWPFrom(me.flightplan.destination);
+ wp.wp_role = 'approach';
+ me.flightplan.appendWP(wp);
+ return;
+ }
+
+ var initialApproachFix = nil;
+ if (me.flightplan.star != nil) {
+ logprint(LOG_INFO, 'routing via STAR ' ~ me.flightplan.star.id);
+ var wps = me.flightplan.star.route(me.flightplan.destination_runway, me.flightplan.star_trans);
+ if (wps != nil) {
+ me.flightplan.insertWaypoints(wps, -1);
+ initialApproachFix = wps[-1]; # final waypoint of STAR
+ }
+ }
+
+ if (me.flightplan.approach != nil) {
+ var wps = nil;
+ var approachIdent = me.flightplan.approach.id;
+
+ if (me.flightplan.approach_trans != nil) {
+ # if an approach transition was specified, let's use it explicitly
+ wps = me.flightplan.approach.route(me.flightplan.destination_runway, me.flightplan.approach_trans);
+ if (wps == nil) {
+ logprint(LOG_WARN, "couldn't route approach " ~ approachIdent ~ " based on specified transition:" ~ me.flightplan.approach_trans);
+ }
+ } else if (initialApproachFix != nil) {
+ # no explicit approach transition, let's use the IAF to guess one
+ wps = me.flightplan.approach.route(me.flightplan.destination_runway, initialApproachFix);
+ if (wps == nil) {
+ logprint(LOG_INFO, "couldn't route approach " ~ approachIdent ~ " based on IAF:" ~ initialApproachFix.wp_name);
+ }
+ }
+
+ # depending on the order the user selects the approach or STAR, we might get into
+ # a mess here. If we failed to route so far, just try a direct to the approach
+ if (wps == nil) {
+ # route direct
+ wps = me.flightplan.approach.route(me.flightplan.destination_runway);
+ }
+
+ if (wps == nil) {
+ logprint(LOG_WARN, 'routing via approach ' ~ approachIdent ~ ' failed entirely.');
+ } else {
+ me.flightplan.insertWaypoints(wps, -1);
+ }
+ } else {
+ # no approach, just use the runway waypoint
+ var wp = createWPFrom(me.flightplan.destination_runway);
+ wp.wp_role = 'approach';
+ me.flightplan.appendWP(wp);
+ }
+ },
+
+ cleared: func
+ {
+ logprint(LOG_INFO, "saw active flightplan cleared, deactivating");
+ # see http://https://code.google.com/p/flightgear-bugs/issues/detail?id=885
+ fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
+ },
+
+ endOfFlightPlan: func
+ {
+ logprint(LOG_INFO, "end of flight-plan, deactivating");
+ fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
+ }
+};
+
+var GPSPath = "/instrumentation/gps";
+
+# this delegate corresponds to the default behaviour of the built-in GPS.
+# depending on the real GPS/FMS you are modelling, you probably need to
+# replace this with your own.
+#
+# To do that, just set /autopilot/route-manager/disable-fms to true, which
+# will block creation of this delegate.
+#
+# Of course you are then responsible for many basic FMS functions, such as
+# route sequencing and activation
+#
+
+var A320GPSDelegate = {
+ new: func(fp) {
+ var m = { parents: [A320GPSDelegate], flightplan:fp, landingCheck:nil };
+
+ logprint(LOG_INFO, 'creating A320 GPS FPDelegate');
+
+ # tell the GPS C++ code we will do sequencing ourselves, so it can disable
+ # its legacy logic for this
+
+ setprop(GPSPath ~ '/config/delegate-sequencing', 1);
+
+ # disable turn anticipation
+ setprop(GPSPath ~ '/config/enable-fly-by', 0);
+
+ # flyOver maximum distance
+ setprop(GPSPath ~ '/config/over-flight-arm-distance', 5);
+
+ fp.followLegTrackToFix = 1;
+ fp.aircraftCategory = 'C';
+
+ m._modeProp = props.globals.getNode(GPSPath ~ '/mode');
+ return m;
+ },
+
+ _landingCheckTimeout: func
+ {
+ if (pts.Gear.wow[0].getValue() and pts.Velocities.groundspeed.getValue() < 25) {
+ logprint(LOG_INFO, 'GPS saw speed < 25kts on destination runway, end of route.');
+ me.landingCheck.stop();
+ # record touch-down time?
+ me.flightplan.finish();
+ }
+ },
+
+ _captureCurrentCourse: func
+ {
+ setprop(GPSPath ~ "/selected-course-deg", getprop(GPSPath ~ "/desired-course-deg"));
+ },
+
+ _selectOBSMode: func
+ {
+ setprop(GPSPath ~ "/command", "obs");
+ },
+
+ waypointsChanged: func
+ {
+ },
+
+ activated: func
+ {
+ if (!me.flightplan.active)
+ return;
+
+ logprint(LOG_INFO,'flightplan activated, default GPS to LEG mode');
+ setprop(GPSPath ~ "/command", "leg");
+ },
+
+ deactivated: func
+ {
+ if (me._modeProp.getValue() == 'leg') {
+ logprint(LOG_INFO, 'flightplan deactivated, default GPS to OBS mode');
+ me._captureCurrentCourse();
+ me._selectOBSMode();
+ }
+ },
+
+ endOfFlightPlan: func
+ {
+ if (me._modeProp.getValue() == 'leg') {
+ logprint(LOG_INFO, 'end of flight-plan, switching GPS to OBS mode');
+ me._captureCurrentCourse();
+ me._selectOBSMode();
+ }
+ },
+
+ cleared: func
+ {
+ if (!me.flightplan.active)
+ return;
+
+ if (me._modeProp.getValue() == 'leg') {
+ logprint(LOG_INFO, 'flight-plan cleared, switching GPS to OBS mode');
+ me._captureCurrentCourse();
+ me._selectOBSMode();
+ }
+ },
+
+ sequence: func
+ {
+ if (!me.flightplan.active)
+ return;
+
+ if (me._modeProp.getValue() == 'leg') {
+ if (me.flightplan.current + 1 >= me.flightplan.numWaypoints()) {
+ logprint(LOG_INFO, "default GPS sequencing, finishing flightplan");
+ me.flightplan.finish();
+ } elsif (me.flightplan.nextWP().wp_type != 'discontinuity' and me.flightplan.nextWP().wp_type != 'vectors') {
+ logprint(LOG_INFO, "default GPS sequencing to next WP");
+ me.flightplan.current = me.flightplan.current + 1;
+ } else {
+ logprint(LOG_INFO, "default GPS sequencing to next WP (special)");
+ fmgc.Input.lat.setValue(3);
+ if (me.flightplan.nextWP().wp_type == 'vectors') {
+ me.flightplan.current = me.flightplan.current + 2;
+ }
+ }
+ } else {
+ # OBS, do nothing
+ }
+ },
+
+ currentWaypointChanged: func
+ {
+ if (!me.flightplan.active)
+ return;
+
+ if (me.landingCheck != nil) {
+ me.landingCheck.stop();
+ me.landingCheck = nil; # delete timer
+ }
+
+ var active = me.flightplan.currentWP();
+ if (active == nil) return;
+
+ var activeRunway = active.runway();
+ # this check is needed to avoid problems with circular routes; when
+ # activating the FP we end up here, and without this check, immediately
+ # detect that we've 'landed' and finish the FP again.
+
+ if (!pts.Gear.wow[0].getValue() and
+ (activeRunway != nil) and (me.flightplan.destination_runway != nil) and
+ (activeRunway.id == me.flightplan.destination_runway.id))
+ {
+ me.landingCheck = maketimer(2.0, me, A320GPSDelegate._landingCheckTimeout);
+ me.landingCheck.start();
+ }
+ }
+};
+
+registerFlightPlanDelegate(A320GPSDelegate.new);
+registerFlightPlanDelegate(A320RouteManagerDelegate.new);
+
diff --git a/Nasal/FMGC/flightplan.nas b/Nasal/FMGC/flightplan.nas
index 92b27e50..1be9fe10 100644
--- a/Nasal/FMGC/flightplan.nas
+++ b/Nasal/FMGC/flightplan.nas
@@ -17,50 +17,41 @@ var DEBUG_DISCONT = 0;
var magHDG = props.globals.getNode("/orientation/heading-magnetic-deg", 1);
var trueHDG = props.globals.getNode("/orientation/heading-deg", 1);
-# Props.initNode
-var wpID = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/id", "", "STRING")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/id", "", "STRING")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/id", "", "STRING")]];
-var wpLat = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/lat", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/lat", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/lat", 0, "DOUBLE")]];
-var wpLon = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/lon", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/lon", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/lon", 0, "DOUBLE")]];
-var wpCourse = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/course", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/course", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/course", 0, "DOUBLE")]];
-var wpDistance = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/distance", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/distance", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/distance", 0, "DOUBLE")]];
-var wpCoursePrev = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/course-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/course-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/course-from-prev", 0, "DOUBLE")]];
-var wpDistancePrev = [[props.globals.initNode("/FMGC/flightplan[0]/wp[0]/distance-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[1]/wp[0]/distance-from-prev", 0, "DOUBLE")], [props.globals.initNode("/FMGC/flightplan[2]/wp[0]/distance-from-prev", 0, "DOUBLE")]];
-
var flightPlanController = {
flightplans: [createFlightplan(), createFlightplan(), createFlightplan(), nil],
temporaryFlag: [0, 0],
# These flags are only for the main flgiht-plan
- active: props.globals.initNode("/FMGC/flightplan[2]/active", 0, "BOOL"),
-
- changed: props.globals.initNode("/FMGC/flightplan[2]/changed", 0, "BOOL"),
+ active: props.globals.initNode("/autopilot/route-manager/active", 0, "BOOL"),
+ changed: props.globals.initNode("/autopilot/route-manager/flightplan-changed", 0, "BOOL"),
currentToWpt: nil, # container for the current TO waypoint ghost
- currentToWptIndex: props.globals.initNode("/FMGC/flightplan[2]/current-wp", 0, "INT"),
+ currentToWptIndex: props.globals.initNode("/autopilot/route-manager/current-wp", 1, "INT"),
currentToWptIndexTemp: 0,
- currentToWptID: props.globals.initNode("/FMGC/flightplan[2]/current-leg", "", "STRING"),
- courseToWpt: props.globals.initNode("/FMGC/flightplan[2]/current-leg-course", 0, "DOUBLE"),
- courseMagToWpt: props.globals.initNode("/FMGC/flightplan[2]/current-leg-course-mag", 0, "DOUBLE"),
- distToWpt: props.globals.initNode("/FMGC/flightplan[2]/current-leg-dist", 0, "DOUBLE"),
+ currentToWptIndexTemp2: 0,
+ currentToWptID: props.globals.initNode("/autopilot/route-manager/wp[0]/id", "", "STRING"),
+ courseToWpt: props.globals.initNode("/autopilot/route-manager/wp[0]/true-bearing-deg", 0, "DOUBLE"),
+ courseMagToWpt: props.globals.initNode("/autopilot/route-manager/wp[0]/bearing-deg", 0, "DOUBLE"),
+ distToWpt: props.globals.initNode("/autopilot/route-manager/wp[0]/dist", 0, "DOUBLE"),
wptType: nil,
wptTypeNoAdvanceDelete: 0,
- distanceToDest: [0, 0, 0],
- num: [props.globals.initNode("/FMGC/flightplan[0]/num", 0, "INT"), props.globals.initNode("/FMGC/flightplan[1]/num", 0, "INT"), props.globals.initNode("/FMGC/flightplan[2]/num", 0, "INT")],
+ # Temporary flightplan will use flightplan[0] and flightplan[1]
+ num: [props.globals.initNode("/FMGC/flightplan[0]/num", 0, "INT"), props.globals.initNode("/FMGC/flightplan[1]/num", 0, "INT"), props.globals.initNode("/autopilot/route-manager/route/num", 0, "INT")],
arrivalIndex: [0, 0, 0],
- arrivalDist: 0,
- _arrivalDist: 0,
+ arrivalDist: props.globals.getNode("/autopilot/route-manager/distance-remaining-nm"),
fromWptTime: nil,
fromWptAlt: nil,
_timeTemp: nil,
_altTemp: nil,
+ decelPoint: nil,
init: func() {
me.resetFlightplan(2);
me.insertPPOS(2);
me.addDiscontinuity(1, 2, 1);
- me.currentToWptIndex.setValue(0);
me.flightPlanChanged(2);
+ me.flightplans[2].activate();
},
reset: func() {
@@ -69,6 +60,9 @@ var flightPlanController = {
me.resetFlightplan(0);
me.resetFlightplan(1);
me.resetFlightplan(2);
+ me.decelPoint = nil;
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
+ me.flightplans[2].activate();
},
resetFlightplan: func(n) {
@@ -80,8 +74,11 @@ var flightPlanController = {
mcdu.isNoSid[n] = 0;
mcdu.isNoStar[n] = 0;
mcdu.isNoVia[n] = 0;
+ me.arrivalIndex[n] = 0; # reset arrival index calculations
},
+ oldCurrentWp: 0,
+ lastSequencedCurrentWP: 0,
createTemporaryFlightPlan: func(n) {
me.resetFlightplan(n);
me.flightplans[n] = me.flightplans[2].clone();
@@ -96,11 +93,16 @@ var flightPlanController = {
canvas_mcdu.myAirways[n].updateTmpy();
}
fmgc.windController.createTemporaryWinds(n);
+
+ me.oldCurrentWp = FPLN.currentWP.getValue();
+
me.flightPlanChanged(n);
},
loadFlightPlan: func(path) {
- call(func {me.flightplans[3] = createFlightplan(path);}, nil, var err = []);
+ call(func {
+ me.flightplans[3] = createFlightplan(path);
+ }, nil, var err = []);
if (size(err) or me.flightplans[3] == nil) {
print(err[0]);
print("Load failed.");
@@ -108,12 +110,12 @@ var flightPlanController = {
me.destroyTemporaryFlightPlan(3, 1);
},
- destroyTemporaryFlightPlan: func(n, a) { # a = 1 activate, a = 0 erase
+ destroyTemporaryFlightPlan: func(n, a) { # a = 1 activate, a = 0 erase, s = 0 don't call flightplan changed
if (a == 1) {
flightPlanTimer.stop();
me.resetFlightplan(2);
me.flightplans[2] = me.flightplans[n].clone();
-
+ me.flightplans[2].activate();
if (n != 3) {
if (mcdu.isNoSid[n] == 1) {
mcdu.isNoSid[2] = 1;
@@ -145,17 +147,30 @@ var flightPlanController = {
mcdu.isNoTransArr[2] = 0;
}
}
-
me.flightPlanChanged(2);
flightPlanTimer.start();
}
- if (n == 3) { return; }
- me.resetFlightplan(n);
+ if (n == 3) {
+ me.flightPlanChanged(n);
+ return;
+ }
me.temporaryFlag[n] = 0;
+ me.flightPlanChanged(2);
+ me.resetFlightplan(n);
if (canvas_mcdu.myDirTo[n] != nil) {
canvas_mcdu.myDirTo[n].updateTmpy();
}
+ if (me.DirToIndex != nil) {
+ me.currentToWptIndex.setValue(me.DirToIndex);
+ me.DirToIndex = nil;
+ }
+
fmgc.windController.destroyTemporaryWinds(n, a);
+
+ if (FPLN.currentWP.getValue() != me.oldCurrentWp) {
+ FPLN.currentWP.setValue(me.oldCurrentWp);
+ }
+
me.flightPlanChanged(n);
},
@@ -164,9 +179,8 @@ var flightPlanController = {
me.flightplans[plan].departure = airportinfo(dep);
me.flightplans[plan].destination = airportinfo(arr);
if (plan == 2) {
- me.destroyTemporaryFlightPlan(0, 0);
- me.destroyTemporaryFlightPlan(1, 0);
- me.currentToWptIndex.setValue(0);
+ if (me.temporaryFlag[0]) { me.destroyTemporaryFlightPlan(0, 0); }
+ if (me.temporaryFlag[1]) { me.destroyTemporaryFlightPlan(1, 0); }
me.arrivalIndex = [0, 0, 0]; # reset arrival index calculations
}
me.addDiscontinuity(1, plan);
@@ -177,7 +191,6 @@ var flightPlanController = {
if (canvas_mcdu.myArrival[1] != nil) { canvas_mcdu.myArrival[1].reset(); }
if (canvas_mcdu.myDeparture[0] != nil) { canvas_mcdu.myDeparture[0].reset(); }
if (canvas_mcdu.myDeparture[1] != nil) { canvas_mcdu.myDeparture[1].reset(); }
- #todo if plan = 2, kill any tmpy flightplan
me.flightPlanChanged(plan);
},
@@ -201,45 +214,31 @@ var flightPlanController = {
},
autoSequencing: func() {
- me.calculateTimeAltitudeOnSequence();
+ if (!me.active.getBoolValue()) { return; }
+ if (pts.Sim.pause.getBoolValue()) { return; }
- # todo setlistener on sim/time/warp to recompute predictions
+ me.calculateTimeAltitudeOnSequence();
# Advancing logic
me.currentToWptIndexTemp = me.currentToWptIndex.getValue();
- if (me.currentToWptIndexTemp < 1) {
- me.currentToWptIndex.setValue(1);
- } else if (me.num[2].getValue() > 2) {
- if (me.currentToWptIndexTemp == 2) { # Clean up after a no-sequence waypoint
- me.currentToWptIndex.setValue(1); # MUST be set first
- # TODO: Add support for deleting multiple waypoints at once, this will do for now
- if (me.temporaryFlag[0] == 1 and wpID[0][0] == wpID[2][0]) {
- me.deleteWP(0, 0);
- }
- if (me.temporaryFlag[1] == 1 and wpID[1][0] == wpID[2][0]) {
- me.deleteWP(0, 1);
- }
- me.deleteWP(0, 2, 0, 1);
- if (me.temporaryFlag[0] == 1 and wpID[0][0] == wpID[2][0]) {
- me.deleteWP(0, 0);
- }
- if (me.temporaryFlag[1] == 1 and wpID[1][0] == wpID[2][0]) {
- me.deleteWP(0, 1);
- }
- me.deleteWP(0, 2, 0, 1);
- } else {
- me.wptType = me.flightplans[2].getWP(me.currentToWptIndexTemp).wp_type;
- me.wptTypeNoAdvanceDelete = me.wptType == "radialIntercept" or me.wptType == "vectors" or me.wptType == "dmeIntercept" or me.wptType == "hdgToAlt";
- if (me.wptTypeNoAdvanceDelete) {
- me.currentToWptIndex.setValue(2);
- } else {
- if (me.temporaryFlag[0] == 1 and wpID[0][0] == wpID[2][0]) {
- me.deleteWP(0, 0);
+ # TODO - after sequencing discontinuity, FPLN should show PPOS then DISCONTINUITY
+ # Clearing that discontinuity is not allowed, you must exit using DIRTO, or else using NAV ARM and overfly
+ # TODO - triple click - confirm, is it only with DES disengage, or also with the NAV loss?
+ # TODO - I think that it only goes to VS when in DES mode
+
+ if (me.flightplans[2].getWP(me.currentToWptIndexTemp + 1).wp_type == "discontinuity" or me.flightplans[2].getWP(me.currentToWptIndexTemp + 1).wp_type == "vectors") {
+ fmgc.Input.lat.setValue(3);
+ me.currentToWptIndex.setValue(me.currentToWptIndexTemp + 2);
+ me.lastSequencedCurrentWP = me.currentToWptIndexTemp + 2;
+ } else {
+ me.currentToWptIndex.setValue(me.currentToWptIndexTemp + 1);
+ me.lastSequencedCurrentWP = me.currentToWptIndexTemp + 1;
+
+ if (me.num[2].getValue() > 2 and me.currentToWptIndexTemp >= 1) {
+ for (var i = 0; i <= 2; i += 1) {
+ if (i == 2 or me.temporaryFlag[i]) {
+ me.flightplans[i].getWP(me.currentToWptIndexTemp - 1).hidden = 1;
}
- if (me.temporaryFlag[1] == 1 and wpID[1][0] == wpID[2][0]) {
- me.deleteWP(0, 1);
- }
- me.deleteWP(0, 2, 0, 1);
}
}
}
@@ -262,15 +261,17 @@ var flightPlanController = {
# addDiscontinuity - insert discontinuity at passed index
# args: index, plan
- # index: index to add at
- # plan: plan to add to
+ # index: index to add at
+ # plan: plan to add to
# Check if a discontinuity already exists either immediately before or at that index
# If it does, don't add another one
# Optional flag DEBUG_DISCONT to disable discontinuities totally
addDiscontinuity: func(index, plan, force = 0) {
if (DEBUG_DISCONT) { return; }
+
if (force) {
me.flightplans[plan].insertWP(createDiscontinuity(), index);
+ return;
}
if (me.flightplans[plan].getWP(index) != nil) { # index is not nil
@@ -288,18 +289,15 @@ var flightPlanController = {
me.flightplans[plan].insertWP(createDiscontinuity(), index);
}
} else { # both are nil??
- print("Possible error in discontinuities!");
- me.flightplans[plan].insertWP(createDiscontinuity(), index);
+ debug.dump("Error in discontinuities; won't try to add one");
}
},
# insertTP - insert PPOS waypoint denoted "T-P" at specified index
# args: n, index
- # n: flightplan to which the PPOS waypoint will be inserted
- # index: optional argument, defaults to 1, index which the waypoint will be at.
- # Default to one, as direct to will insert TP, then create leg to DIRTO waypoint, then delete waypoint[0]
-
- insertTP: func(n, index = 1) {
+ # n: flightplan to which the PPOS waypoint will be inserted
+ # index: index which the waypoint will be at.
+ insertTP: func(n, index) {
me.flightplans[n].insertWP(createWP(geo.aircraft_position(), "T-P"), index);
fmgc.windController.insertWind(n, index, 0, "T-P");
},
@@ -309,13 +307,14 @@ var flightPlanController = {
fmgc.windController.insertWind(n, index, 0, "PPOS");
},
+
# childWPBearingDistance - return waypoint at bearing and distance from specified waypoint ghost
# args: wpt, bearing, dist, name, typeStr
- # wpt: waypoint ghost
- # bearing: bearing of waypoint to be created from specified waypoint
- # distance: distance of waypoint to be created from specified waypoint, nautical miles
- # name: name of waypoint to be created
- # typeStr: optional argument to be passed to createWP, must be one of "sid", "star" "approach" "missed" or "pseudo"
+ # wpt: waypoint ghost
+ # bearing: bearing of waypoint to be created from specified waypoint
+ # distance: distance of waypoint to be created from specified waypoint, nautical miles
+ # name: name of waypoint to be created
+ # typeStr: optional argument to be passed to createWP, must be one of "sid", "star" "approach" "missed" or "pseudo"
childWPBearingDistance: func(wpt, bearing, dist) {
var coordinates = greatCircleMove(wpt.lat, wpt.lon, num(bearing), num(dist));
@@ -335,7 +334,9 @@ var flightPlanController = {
}
# fudge the altitude since we cannot create a hdgtoAlt from nasal. Assume 600 feet per mile - 2.5 miles
- me.flightplans[n].insertWP(createWP(me.childWPBearingDistance(wptStore, me.flightplans[n].departure_runway.heading, 2.5), "1500", "sid"), 1);
+ me.flightplans[n].insertWP(createWP(me.childWPBearingDistance(wptStore, me.flightplans[n].departure_runway.heading, 2.5 + (me.flightplans[n].departure_runway.length * M2NM)), "1500", "sid"), 1);
+ me.flightplans[n].getWP(1).fly_type = "flyOver";
+ me.flightplans[n].getWP(1).setAltitude(1500, "at");
fmgc.windController.insertWind(n, 1, 0, "1500");
}
me.flightPlanChanged(n);
@@ -357,6 +358,7 @@ var flightPlanController = {
hdg = hdg - 360;
}
me.flightplans[n].insertWP(createWP(me.childWPBearingDistance(wptStore, hdg, 5), "CF", "star"), me.arrivalIndex[n]);
+ me.flightplans[n].getWP(me.arrivalIndex[n]).fly_type = "flyOver";
fmgc.windController.insertWind(n, me.arrivalIndex[n], 0, "CF");
}
me.flightPlanChanged(n);
@@ -364,8 +366,8 @@ var flightPlanController = {
# directTo - create leg direct from present position to a specified waypoint
# args: waypointGhost, plan
- # waypointGost: waypoint ghost of the waypoint
- # plan: plan on which the direct to leg will be created
+ # waypointGost: waypoint ghost of the waypoint
+ # plan: plan on which the direct to leg will be created
# We first insert a PPOS waypoint at index 1
# We check if the flightplan already contains the waypoint passed to the function
# If it exists, we delete intermediate waypoints
@@ -373,49 +375,50 @@ var flightPlanController = {
# In either case, we delete the current FROM waypoint, index 0, and call flightPlanChanged to recalculate
# We attempt to get the distance from the aircraft current position to the chosen waypoint and update mcdu with it
+ DirToIndex: nil,
directTo: func(waypointGhost, plan) {
if (me.flightplans[plan].indexOfWP(waypointGhost) == -1) {
- me.insertTP(plan, 1);
+ me.insertTP(plan, me.currentToWptIndex.getValue());
# use createWP here as createWPFrom doesn't accept waypoints
# createWPFrom worked before... but be sure!
- me.flightplans[plan].insertWP(createWP(waypointGhost, waypointGhost.id), 2);
- fmgc.windController.insertWind(plan, 2, 0, waypointGhost.id);
- me.addDiscontinuity(3, plan);
+ me.flightplans[plan].insertWP(createWP(waypointGhost, waypointGhost.id), me.currentToWptIndex.getValue() + 1);
+ fmgc.windController.insertWind(plan, me.currentToWptIndex.getValue() + 1, 0, waypointGhost.id);
+ me.addDiscontinuity(me.currentToWptIndex.getValue() + 2, plan);
+ me.DirToIndex = me.currentToWptIndex.getValue() + 1;
} else {
- # we want to delete the intermediate waypoints up to but not including the waypoint. Leave index 0, we delete it later.
- # example - waypoint dirto is index 5, we want to delete indexes 1 -> 4. 5 - 1 = 4.
- # so four individual deletions. Delete index 1 four times.
+ var indexWP = me.flightplans[plan].indexOfWP(waypointGhost);
+ me.insertTP(plan, indexWP);
+ me.deleteTillIndex(waypointGhost, me.currentToWptIndex.getValue(), plan, 1);
- var timesToDelete = me.flightplans[plan].indexOfWP(waypointGhost);
- while (timesToDelete > 1) {
- me.deleteWP(1, plan, 1);
- timesToDelete -= 1;
- }
- # Add TP afterwards, this is essential
- me.insertTP(plan, 1);
+ indexWP = me.flightplans[plan].indexOfWP(waypointGhost);
+ me.hideTillIndex(indexWP - 2, plan);
+ me.DirToIndex = indexWP;
}
var curAircraftPosDirTo = geo.aircraft_position();
- canvas_mcdu.myDirTo[plan].updateDist(me.flightplans[plan].getWP(2).courseAndDistanceFrom(curAircraftPosDirTo)[1]);
- me.deleteWP(0, plan);
- me.flightPlanChanged(plan);
+ canvas_mcdu.myDirTo[plan].updateDist(me.flightplans[plan].getWP(me.currentToWptIndex.getValue() + 1).courseAndDistanceFrom(curAircraftPosDirTo)[1]);
},
- deleteWP: func(index, n, a = 0, s = 0) { # a = 1, means adding a waypoint via deleting intermediate. s = 1, means autosequencing
- var wp = wpID[n][index].getValue();
- if (((s == 0 and left(wp, 4) != FMGCInternal.depApt and left(wp, 4) != FMGCInternal.arrApt) or (s == 1)) and me.flightplans[n].getPlanSize() > 2) {
- if (me.flightplans[n].getWP(index).id != "DISCONTINUITY" and a == 0) { # if it is a discont, don't make a new one
+ deleteWP: func(index, n, a = 0) { # a = 1, means adding a waypoint via deleting intermediate
+ var wp = me.flightplans[n].getWP(index);
+ if ((left(wp.wp_name, 4) != FMGCInternal.depApt and left(wp.wp_name, 4) != FMGCInternal.arrApt) and me.flightplans[n].getPlanSize() > 2) {
+ if (wp.id != "DISCONTINUITY" and a == 0) { # if it is a discont, don't make a new one
me.flightplans[n].deleteWP(index);
fmgc.windController.deleteWind(n, index);
- if (me.flightplans[n].getWP(index) != nil and s == 0) {
+ if (me.flightplans[n].getWP(index) != nil) { # This refers to the next one after the one we deleted
if (me.flightplans[n].getWP(index).id != "DISCONTINUITY") { # else, if the next one isn't a discont, add one
me.addDiscontinuity(index, n);
}
}
} else {
- me.flightplans[n].deleteWP(index);
- fmgc.windController.deleteWind(n, index);
+ if (wp.id == "DISCONTINUITY" and index > 0 and (me.flightplans[n].getWP(index - 1).id == "PPOS" or find("VECTORS", me.flightplans[n].getWP(index - 1).id) != -1)) {
+ return 1;
+ } else {
+ me.flightplans[n].deleteWP(index);
+ fmgc.windController.deleteWind(n, index);
+ }
}
+
me.flightPlanChanged(n);
canvas_nd.A3XXRouteDriver.triggerSignal("fp-removed");
return 2;
@@ -427,8 +430,8 @@ var flightPlanController = {
# deleteTillIndex - helper that deletes waypoints up to a passed waypoint already in flightplan
# uses a while loop to delete a certain number of waypoints between passed index and
# index of waypoint alredy in flightplan
- deleteTillIndex: func(wpGhost, index, plan) {
- var numToDel = me.flightplans[plan].indexOfWP(wpGhost) - index;
+ deleteTillIndex: func(wpGhost, index, plan, offset = 0) {
+ var numToDel = me.flightplans[plan].indexOfWP(wpGhost) - index - offset;
while (numToDel > 0) {
me.deleteWP(index, plan, 1);
numToDel -= 1;
@@ -436,6 +439,15 @@ var flightPlanController = {
return 2;
},
+ hideTillIndex: func(index, plan) {
+ var numToDel = index;
+ while (numToDel >= 0) {
+ me.flightplans[plan].getWP(index - numToDel).hidden = 1;
+ numToDel -= 1;
+ }
+ return 2;
+ },
+
# createDuplicateNames - helper to spawn DUPLICATENAMES page
# args: ghostContainer, index, flag, plan
# ghostContainer: vector of fgPositioned ghosts
@@ -473,7 +485,7 @@ var flightPlanController = {
}
var indexPresent = me.flightplans[plan].indexOfWP(airport[indexToInsert]);
- if (me.flightplans[plan].indexOfWP(airport[indexToInsert]) == -1) {
+ if (indexPresent == -1 or indexPresent > me.arrivalIndex[plan]) {
me.flightplans[plan].insertWP(createWPFrom(airport[indexToInsert]), index);
fmgc.windController.insertWind(plan, index, 0, text);
me.addDiscontinuity(index + 1, plan);
@@ -507,7 +519,7 @@ var flightPlanController = {
}
var indexPresent = me.flightplans[plan].indexOfWP(fix[indexToInsert]);
- if (me.flightplans[plan].indexOfWP(fix[indexToInsert]) == -1) {
+ if (indexPresent == -1 or indexPresent > me.arrivalIndex[plan]) {
me.flightplans[plan].insertWP(createWPFrom(fix[indexToInsert]), index);
fmgc.windController.insertWind(plan, index, 1, text);
me.addDiscontinuity(index + 1, plan);
@@ -541,7 +553,7 @@ var flightPlanController = {
}
var indexPresent = me.flightplans[plan].indexOfWP(navaid[indexToInsert]);
- if (me.flightplans[plan].indexOfWP(navaid[indexToInsert]) == -1) {
+ if (indexPresent == -1 or indexPresent > me.arrivalIndex[plan]) {
me.flightplans[plan].insertWP(createWPFrom(navaid[indexToInsert]), index);
fmgc.windController.insertWind(plan, index, 1, text);
me.addDiscontinuity(index + 1, plan);
@@ -561,7 +573,8 @@ var flightPlanController = {
return 1;
}
- if (me.flightplans[plan].indexOfWP(wpGhost) == -1) {
+ var indexCurr = me.flightplans[plan].indexOfWP(wpGhost);
+ if (indexCurr == -1 or indexCurr > me.arrivalIndex[plan]) {
# use createWP here as createWPFrom doesn't accept waypoints
me.flightplans[plan].insertWP(createWP(wpGhost, wpGhost.wp_name), index);
fmgc.windController.insertWind(plan, index, 1, wpGhost.wp_name);
@@ -602,13 +615,13 @@ var flightPlanController = {
# getWPforPBD - parse scratchpad text to find waypoint ghost for PBD
# args: text, index, plan
- # text: scratchpad text
- # index: index at which waypoint will be inserted
- # plan: plan to which waypoint will be inserted
+ # text: scratchpad text
+ # index: index at which waypoint will be inserted
+ # plan: plan to which waypoint will be inserted
# return:
- # 0: not in database
- # 1: notAllowed
- # 2: o.k.
+ # 0: not in database
+ # 1: notAllowed
+ # 2: o.k.
getWPforPBD: func(text, index, plan, override = 0, overrideIndex = -1) {
if (index == 0) {
@@ -669,7 +682,6 @@ var flightPlanController = {
getNavCount: func(plan) {
var count = 0;
for (var wpt = 0; wpt < me.flightplans[plan].getPlanSize(); wpt += 1) {
- #print(me.flightplans[plan].getWP(wpt).wp_type);
if (me.flightplans[plan].getWP(wpt).wp_type == "navaid") {
count += 1;
}
@@ -680,7 +692,6 @@ var flightPlanController = {
getDepartureCount: func(plan) {
var count = 0;
for (var wpt = 0; wpt < me.flightplans[plan].getPlanSize(); wpt += 1) {
- #print(me.flightplans[plan].getWP(wpt).wp_role);
if (me.flightplans[plan].getWP(wpt).wp_role == "sid") {
count += 1;
}
@@ -698,12 +709,64 @@ var flightPlanController = {
return count;
},
+ getPlanSizeNoDiscont: func(plan) {
+ var count = 0;
+ for (var wpt = 0; wpt < me.flightplans[plan].getPlanSize(); wpt += 1) {
+ if (me.flightplans[plan].getWP(wpt).wp_name != "DISCONTINUITY") {
+ count += 1;
+ }
+ }
+ return count;
+ },
+
+ calculateDecelPoint: func() {
+ if (me.getPlanSizeNoDiscont(2) <= 1 or fmgc.FMGCInternal.decel) {
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
+ return;
+ }
+
+ me.indexDecel = 0;
+ for (var wpt = 0; wpt < me.flightplans[2].getPlanSize(); wpt += 1) {
+ if (me.flightplans[2].getWP(wpt).wp_role == "approach") {
+ me.indexDecel = wpt;
+ break;
+ }
+ if (wpt == me.flightplans[2].getPlanSize()) {
+ me.indexDecel = me.arrivalIndex - 2;
+ break;
+ }
+ }
+
+ me.dist = me.flightplans[2].getWP(me.indexDecel).leg_distance - 7;
+ if (me.dist < 0) {
+ me.dist = 0.1;
+ }
+ me.decelPoint = me.flightplans[2].pathGeod(me.indexDecel - 1, me.dist);
+
+ setprop("/instrumentation/nd/symbols/decel/latitude-deg", me.decelPoint.lat);
+ setprop("/instrumentation/nd/symbols/decel/longitude-deg", me.decelPoint.lon);
+ setprop("/instrumentation/nd/symbols/decel/show", 1);
+
+ me.indexTemp = me.indexDecel;
+ me.distTemp = 7;
+
+ if (me.flightplans[2].getWP(me.indexTemp).leg_distance < 7) {
+ while (me.distTemp > 0 and me.indexTemp > 0) {
+ me.distTemp -= me.flightplans[2].getWP(me.indexTemp).leg_distance;
+ me.indexTemp -= 1;
+ }
+ me.indexTemp += 1;
+ }
+
+ setprop("/instrumentation/nd/symbols/decel/index", me.indexTemp);
+ },
+
# insertPlaceBearingDistance - insert PBD waypoint at specified index,
# at some specified bearing, distance from a specified location
# args: wp, index, plan
- # wpt: waypoint ghost
- # index: index to insert at in plan
- # plan: plan to insert to
+ # wpt: waypoint ghost
+ # index: index to insert at in plan
+ # plan: plan to insert to
insertPlaceBearingDistance: func(wp, bearing, distance, index, plan) {
var waypoint = pilotWaypoint.new(me.childWPBearingDistance(wp, bearing, distance), "PBD");
@@ -724,8 +787,18 @@ var flightPlanController = {
return 3;
}
- if (!fmgc.flightPlanController.temporaryFlag[plan]) {
+ if (index == me.currentToWptIndex.getValue()) {
+ return 1;
+ # TODO - implement the PPOS - DISCONT feature
+ # me.insertPPOS(thePlan, index - 1);
+ # me.addDiscontinuity(index - 1, thePlan, 1);
+ }
+
+ if (!me.temporaryFlag[plan]) {
if (text == "CLR" and me.flightplans[2].getWP(index).wp_name == "DISCONTINUITY") {
+ if (me.flightplans[2].getPlanSize() == 3 and me.flightplans[2].departure_runway == nil and me.flightplans[2].destination_runway == nil and index == 1) {
+ return 1;
+ }
var thePlan = 2;
} else {
fmgc.flightPlanController.createTemporaryFlightPlan(plan);
@@ -735,6 +808,7 @@ var flightPlanController = {
var thePlan = plan;
}
+
# check waypoints database here
var wpFromDB = WaypointDatabase.getWP(text);
if (wpFromDB != nil) {
@@ -761,20 +835,9 @@ var flightPlanController = {
},
flightPlanChanged: func(n) {
- sizeWP = size(wpID[n]);
- for (var counter = sizeWP; counter < me.flightplans[n].getPlanSize(); counter += 1) { # create new properties if they are required
- append(wpID[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/text", "", "STRING"));
- append(wpLat[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/lat", 0, "DOUBLE"));
- append(wpLon[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/lon", 0, "DOUBLE"));
- append(wpCourse[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/course", 0, "DOUBLE"));
- append(wpDistance[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/distance", 0, "DOUBLE"));
- append(wpCoursePrev[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/course-from-prev", 0, "DOUBLE"));
- append(wpDistancePrev[n], props.globals.initNode("/FMGC/flightplan[" ~ n ~ "]/wp[" ~ counter ~ "]/distance-from-prev", 0, "DOUBLE"));
- }
-
- me.updatePlans();
+ me.updatePlans(1);
fmgc.windController.updatePlans();
-
+
# push update to fuel
if (fmgc.FMGCInternal.blockConfirmed) {
fmgc.FMGCInternal.fuelCalculating = 0;
@@ -788,47 +851,36 @@ var flightPlanController = {
canvas_nd.A3XXRouteDriver.triggerSignal("fp-added");
},
- updatePlans: func() {
- me.updateCurrentWaypoint();
- me._arrivalDist = 0;
+ # runDecel - used to ensure that only flightplanchanged will update the decel point
+ updatePlans: func(runDecel = 0) {
+ if (fmgc.FMGCInternal.toFromSet and me.flightplans[2].departure != nil and me.flightplans[2].destination != nil) { # check if flightplan exists
+ if (!me.active.getBoolValue()) {
+ if (me.currentToWptIndex.getValue() < 1) {
+ var errs = [];
+ call(func {
+ if (me.flightplans[2].getWP(1).id != "DISCONTINUITY") {
+ me.currentToWptIndex.setValue(1);
+ }
+ }, nil, nil, nil, errs);
+ if (size(errs) != 0) { debug.printerror(errs); }
+ }
+ me.active.setValue(1);
+ }
+ } elsif (me.active.getBoolValue()) {
+ me.active.setValue(0);
+ }
+
+ if (me.active.getBoolValue() and me.currentToWptIndex.getValue() == -1) {
+ me.currentToWptIndex.setValue(me.lastSequencedCurrentWP);
+ }
+
for (var n = 0; n <= 2; n += 1) {
for (var wpt = 0; wpt < me.flightplans[n].getPlanSize(); wpt += 1) { # Iterate through the waypoints and update their data
- var curAircraftPos = geo.aircraft_position(); # don't want to get this corrupted so make sure it is a local variable
var waypointHashStore = me.flightplans[n].getWP(wpt);
- courseDistanceFrom = waypointHashStore.courseAndDistanceFrom(curAircraftPos);
- wpID[n][wpt].setValue(waypointHashStore.wp_name);
- wpLat[n][wpt].setValue(waypointHashStore.wp_lat);
- wpLon[n][wpt].setValue(waypointHashStore.wp_lon);
-
- wpCourse[n][wpt].setValue(waypointHashStore.courseAndDistanceFrom(curAircraftPos)[0]);
- wpDistance[n][wpt].setValue(waypointHashStore.courseAndDistanceFrom(curAircraftPos)[1]);
-
- if (wpt == 1) {
- if (me.flightplans[n].getWP(wpt).wp_name != "DISCONTINUITY" and me.flightplans[n].getWP(wpt).wp_type != "vectors" and me.flightplans[n].getWP(wpt).wp_type != "hdgToAlt" and wpt <= me.arrivalIndex[n]) {
- # print("Adding " ~ courseDistanceFrom[1] ~ " miles for waypoint " ~ me.flightplans[n].getWP(wpt).wp_name);
- me._arrivalDist += courseDistanceFrom[1]; # distance to next waypoint, therafter to end of flightplan
- }
- }
-
- if (wpt > 0) {
- wpCoursePrev[n][wpt].setValue(me.flightplans[n].getWP(wpt).leg_bearing);
- wpDistancePrev[n][wpt].setValue(me.flightplans[n].getWP(wpt).leg_distance);
- #if (wpt > 1) {
- # if (me.flightplans[n].getWP(wpt - 1).wp_name != "DISCONTINUITY" and me.flightplans[n].getWP(wpt).wp_name != "DISCONTINUITY" and me.flightplans[n].getWP(wpt - 1).wp_type != "vectors" and me.flightplans[n].getWP(wpt - 1).wp_type != "hdgToAlt" and me.flightplans[n].getWP(wpt).wp_type != "vectors" and me.flightplans[n].getWP(wpt).wp_type != "hdgToAlt" and wpt <= me.arrivalIndex[n]) {
- # me._arrivalDist += courseDistanceFromPrev[1];
- # }
- #}
- } else {
- # use PPOS for the first waypoint
- wpCoursePrev[n][wpt].setValue(courseDistanceFrom[0]);
- wpDistancePrev[n][wpt].setValue(courseDistanceFrom[1]);
- }
-
- if (left(wpID[n][wpt].getValue(), 4) == fmgc.FMGCInternal.arrApt and wpt != 0) {
+ if (left(waypointHashStore.wp_name, 4) == fmgc.FMGCInternal.arrApt and wpt != 0) {
if (me.arrivalIndex[n] != wpt) {
me.arrivalIndex[n] = wpt;
-
if (canvas_mcdu.myFpln[0] != nil) {
canvas_mcdu.myFpln[0].destInfo();
}
@@ -837,74 +889,13 @@ var flightPlanController = {
}
}
}
- }
+ }
+ }
+
+ if (runDecel) {
+ me.calculateDecelPoint();
}
- if (me.flightplans[2].getWP(me.arrivalIndex[2]) == nil or me.flightplans[2].getWP(1) == nil) {
- me.arrivalDist = 9999;
- #print(me.arrivalIndex[2]);
- } else {
- me.arrivalDist = me.flightplans[2].getWP(me.arrivalIndex[2]).distance_along_route - me.flightplans[2].getWP(1).leg_distance + me._arrivalDist;
- }
-
- me.updateMCDUDriver(n);
- },
-
- updateCurrentWaypoint: func() {
- for (var india = 0; india <= 2; india += 1) {
- if (FMGCInternal.toFromSet and me.flightplans[india].departure != nil and me.flightplans[india].destination != nil) { # check if flightplan exists
- var curAircraftPos = geo.aircraft_position(); # don't want to get this corrupted so make sure it is a local variable
-
- if (india == 2) { # main plan
- if (!me.active.getBoolValue()) {
- me.active.setValue(1);
- }
-
- if (me.currentToWptIndex.getValue() > me.flightplans[india].getPlanSize()) {
- me.currentToWptIndex.setValue(me.flightplans[india].getPlanSize());
- }
-
- me.currentToWpt = me.flightplans[india].getWP(me.currentToWptIndex.getValue());
-
- if (me.currentToWptID.getValue() != me.currentToWpt.wp_name) {
- me.currentToWptID.setValue(me.currentToWpt.wp_name);
- }
- me.courseToWpt.setValue(me.currentToWpt.courseAndDistanceFrom(curAircraftPos)[0]);
- me.distToWpt.setValue(me.currentToWpt.courseAndDistanceFrom(curAircraftPos)[1]);
-
- magTrueError = magHDG.getValue() - trueHDG.getValue();
-
- storeCourse = me.courseToWpt.getValue() + magTrueError;
- if (storeCourse >= 360) {
- storeCourse -= 360;
- } elsif (storeCourse < 0) {
- storeCourse += 360;
- }
-
- me.courseMagToWpt.setValue(storeCourse);
- }
-
- if (me.num[india].getValue() != me.flightplans[india].getPlanSize()) {
- me.num[india].setValue(me.flightplans[india].getPlanSize());
- }
- } else {
- if (india == 2) {
- if (me.active.getBoolValue()) {
- me.active.setValue(0);
- }
- if (me.currentToWptID.getValue() != "") {
- me.currentToWptID.setValue("");
- }
- }
-
- if (me.num[india].getValue() != 0) {
- me.num[india].setValue(0);
- }
- }
- }
- },
-
- updateMCDUDriver: func() {
for (var i = 0; i <= 1; i += 1) {
if (canvas_mcdu.myFpln[i] != nil) {
canvas_mcdu.myFpln[i].updatePlan();
@@ -916,4 +907,4 @@ var flightPlanController = {
},
};
-var flightPlanTimer = maketimer(0.1, flightPlanController, flightPlanController.updatePlans);
+var flightPlanTimer = maketimer(0.1, flightPlanController, flightPlanController.updatePlans);
\ No newline at end of file
diff --git a/Nasal/Libraries/libraries.nas b/Nasal/Libraries/libraries.nas
index 153a1ad9..d6892efc 100644
--- a/Nasal/Libraries/libraries.nas
+++ b/Nasal/Libraries/libraries.nas
@@ -5,11 +5,13 @@ print("------------------------------------------------");
print("Copyright (c) 2016-2022 Josh Davidson (Octal450)");
print("------------------------------------------------");
+setprop("/autopilot/route-manager/disable-route-manager", 1);
+setprop("/autopilot/route-manager/disable-fms", 1);
+
# Disable specific menubar items
setprop("/sim/menubar/default/menu[0]/item[0]/enabled", 0);
setprop("/sim/menubar/default/menu[2]/item[0]/enabled", 0);
setprop("/sim/menubar/default/menu[2]/item[2]/enabled", 0);
-setprop("/sim/menubar/default/menu[3]/enabled", 0);
setprop("/sim/menubar/default/menu[5]/item[9]/enabled", 0);
setprop("/sim/menubar/default/menu[5]/item[10]/enabled", 0);
setprop("/sim/menubar/default/menu[5]/item[11]/enabled", 0);
diff --git a/Nasal/MCDU/DIRTO.nas b/Nasal/MCDU/DIRTO.nas
index 8fde4c50..ba0194ef 100644
--- a/Nasal/MCDU/DIRTO.nas
+++ b/Nasal/MCDU/DIRTO.nas
@@ -1,3 +1,6 @@
+# A3XX MCDU Direct To Page
+# Copyright (c) 2022 Jonathan Redpath (legoboyvdlp)
+
var dirToFlag = 0;
var dirTo = {
@@ -77,16 +80,14 @@ var dirTo = {
canvas_mcdu.myFpln[me.computer] = fplnPage.new(2, me.computer);
}
- var x = 0;
+ var dirToLeftIndex = 0;
me.vector = [];
for (var i = 1 + (me.scroll); i < size(canvas_mcdu.myFpln[me.computer].planList) - 2; i = i + 1) {
- if (canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "DISCONTINUITY" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "VECTORS" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "T-P" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_type == "hdgToAlt") { continue; }
- if (canvas_mcdu.myFpln[me.computer].planList[i].index > fmgc.flightPlanController.arrivalIndex[2]) {
- continue;
- }
+ if (canvas_mcdu.myFpln[me.computer].planList[i].wp == "PSEUDO" or canvas_mcdu.myFpln[me.computer].planList[i].wp == "STATIC" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "DISCONTINUITY" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "VECTORS" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_name == "T-P" or canvas_mcdu.myFpln[me.computer].planList[i].wp.wp_type == "hdgToAlt") { continue; }
+ if (canvas_mcdu.myFpln[me.computer].planList[i].index > fmgc.flightPlanController.arrivalIndex[2]) { continue; }
append(me.vector, canvas_mcdu.myFpln[me.computer].planList[i].wp);
- x += 1;
- if (x == 4) { break; }
+ dirToLeftIndex += 1;
+ if (dirToLeftIndex == 4) { break; }
}
if (size(me.vector) > 0) {
diff --git a/Nasal/MCDU/F-PLN.nas b/Nasal/MCDU/F-PLN.nas
index 8a1f25b9..9b4d898d 100644
--- a/Nasal/MCDU/F-PLN.nas
+++ b/Nasal/MCDU/F-PLN.nas
@@ -1,3 +1,22 @@
+# A3XX FMGC Flightplan Page
+# Copyright (c) 2022 Josh Davidson (Octal450) and Jonathan Redpath (legoboyvdlp)
+
+# Local vars
+var decelIndex = 0;
+var decelShow = 0;
+var decelOffset = 0;
+var destName = nil;
+
+var getSubTextFunc = func(meRef) {
+ var subText = nil;
+ call(func {
+ subText = me.wp.wp_owner.id;
+ }, nil, meRef, nil,
+ var errs = []
+ );
+ return nil;
+}
+
var fplnItem = {
new: func(wp, index, plan, computer, colour = "grn") {
var fI = {parents:[fplnItem]};
@@ -19,10 +38,14 @@ var fplnItem = {
if (wptName[0] == "VECTORS") {
return ["MANUAL", me.getSubText(), me.colour];
} else {
- if (size(wptName) == 2) {
- return[wptName[0] ~ wptName[1 ~ (me.wp.fly_type == "flyOver" ? "@" : "")], me.getSubText(), me.colour];
+ if (me.wp.fly_type == "Hold") {
+ return ["HOLD " ~ (me.wp.hold_is_left_handed ? "L" : "R"), me.getSubText(), me.colour];
} else {
- return [me.wp.wp_name ~ (me.wp.fly_type == "flyOver" ? "@" : ""), me.getSubText(), me.colour];
+ if (size(wptName) == 2) {
+ return[wptName[0] ~ wptName[1 ~ (me.wp.fly_type == "flyOver" ? "@" : "")], me.getSubText(), me.colour];
+ } else {
+ return [me.wp.wp_name ~ (me.wp.fly_type == "flyOver" ? "@" : ""), me.getSubText(), me.colour];
+ }
}
}
} else {
@@ -33,7 +56,11 @@ var fplnItem = {
}
},
getSubText: func() {
- return nil;
+ if (me.wp.wp_parent_name != nil) {
+ return " " ~ me.wp.wp_parent_name;
+ } else {
+ return nil;
+ }
},
updateCenterText: func() {
if (me.wp != nil) {
@@ -47,9 +74,9 @@ var fplnItem = {
}
if (me.index == fmgc.flightPlanController.currentToWptIndex.getValue()) {
- me.assembledStr[1] = "BRG" ~ me.getBrg() ~ " ";
+ me.assembledStr[1] = "BRG" ~ me.getBrg() ~ "° ";
} elsif (me.index == (fmgc.flightPlanController.currentToWptIndex.getValue() + 1) or me.index == (fmgc.flightPlanController.arrivalIndex[me.plan] + 1)) {
- me.assembledStr[1] = "TRK" ~ me.getTrack() ~ " ";
+ me.assembledStr[1] = "TRK" ~ me.getTrack() ~ "° ";
} else {
me.assembledStr[1] = nil;
}
@@ -67,7 +94,6 @@ var fplnItem = {
if (me.wp.wp_name != "DISCONTINUITY") {
me.spd = me.getSpd();
me.alt = me.getAlt();
- me.dist = me.getDist();
if (me.colour != "yel") { # not temporary flightplan
me._colour = "wht";
#if (me.spd[1] != "wht" or me.alt[1] != "wht") {
@@ -84,7 +110,7 @@ var fplnItem = {
} else { # temporary flightplan
me._colour = "yel";
}
- return [me.spd[0] ~ "/" ~ me.alt[0], " " ~ me.dist ~ "NM ", me._colour];
+ return [me.spd[0] ~ "/" ~ me.alt[0], me.getDist() ~ "NM ", me._colour];
} else {
return [nil, nil, "ack"];
}
@@ -93,17 +119,19 @@ var fplnItem = {
}
},
getBrg: func() {
- me.brg = fmgc.wpCourse[me.plan][me.index].getValue() - magvar();
- if (me.brg < 0) { me.brg += 360; }
- if (me.brg > 360) { me.brg -= 360; }
+ var wp = fmgc.flightPlanController.flightplans[me.plan].getWP(me.index);
+ if (wp.wp_type == "vectors") {
+ me.brg = pts.Orientation.heading.getValue();
+ } else {
+ var courseDistanceFrom = courseAndDistance(wp);
+ me.brg = courseDistanceFrom[0] - magvar();
+ if (me.brg < 0) { me.brg += 360; }
+ if (me.brg > 360) { me.brg -= 360; }
+ }
return sprintf("%03.0f", math.round(me.brg));
},
getTrack: func() {
- if (me.index > (size(fmgc.wpCoursePrev[me.plan]) - 1)) {
- me.trk = me.wp.leg_bearing - magvar(me.wp.lat, me.wp.lon);
- } else {
- me.trk = fmgc.wpCoursePrev[me.plan][me.index].getValue() - magvar(me.wp.lat, me.wp.lon);
- }
+ me.trk = me.wp.leg_bearing - magvar(me.wp.lat, me.wp.lon);
if (me.trk < 0) { me.trk += 360; }
if (me.trk > 360) { me.trk -= 360; }
return sprintf("%03.0f", math.round(me.trk));
@@ -112,7 +140,7 @@ var fplnItem = {
if (me.index == 0 and left(me.wp.wp_name, 4) == fmgc.FMGCInternal.depApt and fmgc.FMGCInternal.v1set) {
return [sprintf("%3.0f", math.round(fmgc.FMGCInternal.v1)), "grn"]; # why "mag"? I think "grn"
} elsif (me.wp.speed_cstr != nil and me.wp.speed_cstr > 0) {
- var tcol = (me.wp.speed_cstr_type == "computed" or me.wp.speed_cstr_type == "computed_mach") ? "grn" : "mag"; # TODO - check if only computed
+ var tcol = (me.wp.speed_cstr_type == "computed" or me.wp.speed_cstr_type == "computed_mach") ? "grn" : "mag";
return [sprintf("%3.0f", me.wp.speed_cstr), tcol];
} else {
return ["---", "wht"];
@@ -124,7 +152,7 @@ var fplnItem = {
} elsif (me.index == (fmgc.flightPlanController.currentToWptIndex.getValue() - 1) and fmgc.flightPlanController.fromWptAlt != nil) {
return [" " ~ fmgc.flightPlanController.fromWptAlt, "mag"];
} elsif (me.wp.alt_cstr != nil and me.wp.alt_cstr > 0) {
- var tcol = (me.wp.alt_cstr_type == "computed" or me.wp.alt_cstr_type == "computed_mach") ? "grn" : "mag"; # TODO - check if only computed
+ var tcol = (me.wp.alt_cstr_type == "computed" or me.wp.alt_cstr_type == "computed_mach") ? "grn" : "mag";
var cstrAlt = "";
if (me.wp.alt_cstr > fmgc.FMGCInternal.transAlt) {
@@ -141,13 +169,19 @@ var fplnItem = {
}
},
getDist: func() {
- if (me.index > size(fmgc.wpDistancePrev[me.plan]) - 1) {
- return math.round(me.wp.leg_distance);
+ decelIndex = getprop("/instrumentation/nd/symbols/decel/index");
+ decelShow = getprop("/instrumentation/nd/symbols/decel/show");
+ var prevwp = fmgc.flightPlanController.flightplans[me.plan].getWP(me.index -1);
+
+ if (me.index == fmgc.flightPlanController.currentToWptIndex.getValue()) {
+ return sprintf("%3.0f", math.round(courseAndDistance(me.wp)[1]));;
} else {
- if (me.index == fmgc.flightPlanController.currentToWptIndex.getValue()) {
- return math.round(fmgc.wpDistance[me.plan][me.index].getValue());
+ if (me.plan == 2 and decelShow and me.index == decelIndex and fmgc.flightPlanController.decelPoint != nil) {
+ return sprintf("%3.0f", courseAndDistance(fmgc.flightPlanController.decelPoint, me.wp)[1]);
+ } else if (prevwp != nil and (prevwp.wp_name != "DISCONTINUITY" or find(prevwp.wp_name, "VECTORS"))) {
+ return sprintf("%3.0f", math.round(me.wp.leg_distance));
} else {
- return math.round(fmgc.wpDistancePrev[me.plan][me.index].getValue());
+ return " --";
}
}
},
@@ -160,7 +194,7 @@ var fplnItem = {
if (me.wp.wp_name == "DISCONTINUITY") {
canvas_mcdu.myLatRev[me.computer] = latRev.new(4, me.wp, me.index, me.computer);
} elsif (fmgc.flightPlanController.temporaryFlag[me.computer]) {
- if (me.wp.wp_name == "PPOS" or me.index == (fmgc.flightPlanController.currentToWptIndex.getValue() - 1)) {
+ if (me.wp.wp_name == "PPOS") {
canvas_mcdu.myLatRev[me.computer] = latRev.new(2, me.wp, me.index, me.computer);
} elsif (me.index == fmgc.flightPlanController.arrivalIndex[me.computer]) {
canvas_mcdu.myLatRev[me.computer] = latRev.new(1, me.wp, me.index, me.computer);
@@ -170,7 +204,7 @@ var fplnItem = {
canvas_mcdu.myLatRev[me.computer] = latRev.new(3, me.wp, me.index, me.computer);
}
} else {
- if (me.wp.wp_name == "PPOS" or me.index == (fmgc.flightPlanController.currentToWptIndex.getValue() - 1)) {
+ if (me.wp.wp_name == "PPOS") {
canvas_mcdu.myLatRev[me.computer] = latRev.new(2, me.wp, me.index, me.computer);
} elsif (me.index == fmgc.flightPlanController.arrivalIndex[2]) {
canvas_mcdu.myLatRev[me.computer] = latRev.new(1, me.wp, me.index, me.computer);
@@ -271,6 +305,7 @@ var staticText = {
var sT = {parents:[staticText]};
sT.computer = computer;
sT.text = text;
+ sT.wp = "STATIC";
return sT;
},
updateLeftText: func() {
@@ -291,21 +326,34 @@ var staticText = {
};
var pseudoItem = {
- new: func(computer, text) {
+ new: func(computer, text, colour) {
var pI = {parents:[pseudoItem]};
pI.computer = computer;
pI.text = text;
pI.colour = colour;
+ pI.wp = "PSEUDO";
return pI;
},
updateLeftText: func() {
return [me.text, nil, me.colour];
},
updateCenterText: func() {
- return ["----", nil, "wht"];
+ return ["---- ", nil, "wht"];
+ },
+ getDist: func() {
+ decelIndex = getprop("/instrumentation/nd/symbols/decel/index");
+ decelShow = getprop("/instrumentation/nd/symbols/decel/show");
+ if (decelShow) {
+ var prevWP = fmgc.flightPlanController.flightplans[2].getWP(decelIndex - 1);
+ if (prevWP != nil and prevWP.wp_name != "DISCONTINUITY") {
+ return sprintf("%3.0f", courseAndDistance(prevWP, fmgc.flightPlanController.decelPoint)[1]);
+ } else {
+ return " --";
+ }
+ }
},
updateRightText: func() {
- return ["---/------", " --NM ", "wht"];
+ return ["---/------", me.getDist() ~ "NM ", "wht"];
},
pushButtonLeft: func() {
mcdu_message(me.computer, "NOT ALLOWED");
@@ -384,31 +432,56 @@ var fplnPage = { # this one is only created once, and then updated - remember th
} else {
colour = "grn";
}
- for (var i = 0; i < me.plan.getPlanSize(); i += 1) {
+
+ decelIndex = getprop("/instrumentation/nd/symbols/decel/index");
+ decelShow = getprop("/instrumentation/nd/symbols/decel/show");
+
+ var startingIndex = fmgc.flightPlanController.currentToWptIndex.getValue() == -1 ? 0 : fmgc.flightPlanController.currentToWptIndex.getValue() - 1;
+
+ # Situation where currentIndex is equal to 0
+ startingIndex = (startingIndex == -1 ? 0 : startingIndex);
+
+ for (var i = startingIndex; i < me.plan.getPlanSize(); i += 1) {
+ if (!me.temporaryFlagFpln and decelShow) {
+ if (i == decelIndex) {
+ append(me.planList, pseudoItem.new(me.computer, me.getText("decel"), colour));
+ }
+ }
+
if (!me.temporaryFlagFpln and i > fmgc.flightPlanController.arrivalIndex[me.planIndex] and fmgc.FMGCInternal.phase != 6) {
append(me.planList, fplnItem.new(me.plan.getWP(i), i, me.planIndex, me.computer, "blu"));
} else {
- append(me.planList, fplnItem.new(me.plan.getWP(i), i, me.planIndex, me.computer, colour));
+ if (i == fmgc.flightPlanController.currentToWptIndex.getValue() and !me.temporaryFlagFpln) {
+ append(me.planList, fplnItem.new(me.plan.getWP(i), i, me.planIndex, me.computer, "wht"));
+ } else {
+ append(me.planList, fplnItem.new(me.plan.getWP(i), i, me.planIndex, me.computer, colour));
+ }
}
}
+
append(me.planList, staticText.new(me.computer, me.getText("fplnEnd")));
if (!fmgc.FMGCInternal.altAirportSet) {
append(me.planList, staticText.new(me.computer, me.getText("noAltnFpln")));
} else {
- var altnApt = findAirportsByICAO(fmgc.FMGCInternal.altAirport)[0];
- append(me.planList, fplnItem.new({
- alt_cstr: nil,
- alt_cstr_type: nil,
- fly_type: "flyBy",
- lat: altnApt.lat,
- leg_bearing: courseAndDistance(findAirportsByICAO(fmgc.FMGCInternal.arrApt)[0], altnApt)[0],
- leg_distance: courseAndDistance(findAirportsByICAO(fmgc.FMGCInternal.arrApt)[0], altnApt)[1],
- lon: altnApt.lon,
- speed_cstr: nil,
- speed_cstr_type: nil,
- wp_name: fmgc.FMGCInternal.altAirport,
- }, i, me.planIndex, me.computer, "blu"));
- append(me.planList, staticText.new(me.computer, me.getText("altnFplnEnd")));
+ var altnApt = findAirportsByICAO(fmgc.FMGCInternal.altAirport);
+ if (size(altnApt) > 0) {
+ append(me.planList, fplnItem.new({
+ alt_cstr: nil,
+ alt_cstr_type: nil,
+ fly_type: "flyBy",
+ lat: altnApt[0].lat,
+ leg_bearing: courseAndDistance(findAirportsByICAO(fmgc.FMGCInternal.arrApt)[0], altnApt[0])[0],
+ leg_distance: courseAndDistance(findAirportsByICAO(fmgc.FMGCInternal.arrApt)[0], altnApt[0])[1],
+ lon: altnApt[0].lon,
+ speed_cstr: nil,
+ speed_cstr_type: nil,
+ wp_name: fmgc.FMGCInternal.altAirport,
+ wp_parent_name: nil,
+ }, i, me.planIndex, me.computer, "blu"));
+ append(me.planList, staticText.new(me.computer, me.getText("altnFplnEnd")));
+ } else {
+ append(me.planList, staticText.new(me.computer, me.getText("noAltnFpln")));
+ }
}
me.basePage();
@@ -468,7 +541,7 @@ var fplnPage = { # this one is only created once, and then updated - remember th
},
destInfo: func() {
if (me.plan.getWP(fmgc.flightPlanController.arrivalIndex[me.planIndex]) != nil) {
- var destName = split("-", me.plan.getWP(fmgc.flightPlanController.arrivalIndex[me.planIndex]).wp_name);
+ destName = split("-", me.plan.getWP(fmgc.flightPlanController.arrivalIndex[me.planIndex]).wp_name);
if (size(destName) == 2) {
me.L6 = [destName[0] ~ destName[1], " DEST", "wht"];
} else {
@@ -478,8 +551,8 @@ var fplnPage = { # this one is only created once, and then updated - remember th
me.L6 = ["----", " DEST", "wht"];
}
me.C6 = ["---- ", "TIME ", "wht"];
- if (fmgc.flightPlanController.arrivalDist != nil) {
- me.R6 = [sprintf("%4.0f", int(fmgc.flightPlanController.arrivalDist)) ~ " --.-", "DIST EFOB", "wht"];
+ if (fmgc.flightPlanController.arrivalDist.getValue() != nil) {
+ me.R6 = [sprintf("%4.0f", int(fmgc.flightPlanController.arrivalDist.getValue())) ~ " --.-", "DIST EFOB", "wht"];
} else {
me.R6 = ["---- --.-", "DIST EFOB", "wht"];
}
@@ -487,15 +560,26 @@ var fplnPage = { # this one is only created once, and then updated - remember th
update: func() {
#me.basePage();
},
+ planIndexFunc: func() {
+ decelIndex = getprop("/instrumentation/nd/symbols/decel/index");
+ decelShow = getprop("/instrumentation/nd/symbols/decel/show");
+ if (me.scroll < me.plan.getPlanSize()) {
+ decelOffset = 0;
+ if (decelShow) {
+ if (me.scroll > decelIndex) {
+ decelOffset = 1;
+ }
+ }
+ setprop("/instrumentation/efis[" ~ me.computer ~ "]/inputs/plan-wpt-index", (fmgc.flightPlanController.currentToWptIndex.getValue() - 1 + me.scroll - decelOffset));
+ }
+ },
scrollUp: func() {
if (size(me.planList) > 1) {
me.scroll += 1;
if (me.scroll > size(me.planList) - 3) {
me.scroll = 0;
}
- if (me.scroll < me.plan.getPlanSize()) {
- setprop("/instrumentation/efis[" ~ me.computer ~ "]/inputs/plan-wpt-index", me.scroll);
- }
+ me.planIndexFunc();
} else {
me.scroll = 0;
setprop("/instrumentation/efis[" ~ me.computer ~ "]/inputs/plan-wpt-index", -1);
@@ -507,9 +591,7 @@ var fplnPage = { # this one is only created once, and then updated - remember th
if (me.scroll < 0) {
me.scroll = size(me.planList) - 3;
}
- if (me.scroll < me.plan.getPlanSize()) {
- setprop("/instrumentation/efis[" ~ me.computer ~ "]/inputs/plan-wpt-index", me.scroll);
- }
+ me.planIndexFunc();
} else {
me.scroll = 0;
setprop("/instrumentation/efis[" ~ me.computer ~ "]/inputs/plan-wpt-index", -1);
@@ -535,17 +617,9 @@ var fplnPage = { # this one is only created once, and then updated - remember th
setprop("MCDU[" ~ me.computer ~ "]/page", "LATREV");
}
} else {
- if ((index - 1 + me.scroll) < size(me.planList) and !mcdu_scratchpad.scratchpads[me.computer].showTypeIMsg and !mcdu_scratchpad.scratchpads[me.computer].showTypeIIMsg) {
+ if ((index - 1 + me.scroll) < size(me.planList) and me.outputList[index - 1].wp != "STATIC" and me.outputList[index - 1].wp != "PSEUDO" and !mcdu_scratchpad.scratchpads[me.computer].showTypeIMsg and !mcdu_scratchpad.scratchpads[me.computer].showTypeIIMsg) {
if (size(mcdu_scratchpad.scratchpads[me.computer].scratchpad) > 0) {
-
# Use outputList.index to correct the index the call goes to after sequencing
-
- if (mcdu_scratchpad.scratchpads[me.computer].scratchpad == "CLR") {
- if (me.outputList[index - 1].wp.wp_name == "(DECEL)") {
- mcdu_message(me.computer, "NOT ALLOWED");
- return;
- }
- }
var returny = fmgc.flightPlanController.scratchpad(mcdu_scratchpad.scratchpads[me.computer].scratchpad, me.outputList[index - 1].index, me.computer);
if (returny == 3) {
mcdu_message(me.computer, "DIR TO IN PROGRESS");
@@ -595,8 +669,9 @@ var decimalToShortString = func(dms, type) {
var degrees = split(".", sprintf(dms))[0];
if (type == "lat") {
var sign = degrees >= 0 ? "N" : "S";
+ return sprintf("%02d", abs(degrees)) ~ sign;
} else {
var sign = degrees >= 0 ? "E" : "W";
+ return sprintf("%03d", abs(degrees)) ~ sign;
}
- return abs(degrees) ~ sign;
}
\ No newline at end of file
diff --git a/Nasal/MCDU/HOLD.nas b/Nasal/MCDU/HOLD.nas
index 1bb16b33..68ed4fbd 100644
--- a/Nasal/MCDU/HOLD.nas
+++ b/Nasal/MCDU/HOLD.nas
@@ -39,38 +39,50 @@ var holdPage = {
_setupPageWithData: func() {
me.title = ["HOLD", " AT ", me.waypoint.wp_name];
me.titleColour = "wht";
- me.arrowsMatrix = [[0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0]];
+ me.arrowsMatrix = [[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0]];
me.arrowsColour = [["ack", "ack", "ack", "ack", "ack", "wht"], ["blu", "blu", "ack", "ack", "ack", "ack"]];
+
if (me.waypoint.fly_type == "Hold") {
- me.makeTmpy();
- me.L1 = [sprintf("%03.0f°", me.waypoint.hold_inbound_radial), "INB CRS", "blu"];
-
- if (me.waypoint.hold_is_left_handed) {
- me.L2 = ["L", " TURN", "blu"];
- } else {
- me.L2 = ["R", " TURN", "blu"];
- }
-
- if (me.waypoint.hold_is_distance) {
- me.L3 = [" -.-/" ~ me.waypoint.hold_time_or_distance, "TIME/DIST", "blu"];
- } else {
- me.L3 = [sprintf("%3.1f", (me.waypoint.hold_time_or_distance / 60)) ~ "/----", "TIME/DIST", "blu"];
- }
- me.R1 = ["COMPUTED ", nil, "blu"];
- me.R2 = ["DATABASE ", nil, "yel"];
+ me.R1 = ["COMPUTED ", nil, "wht"];
+ me.R2 = ["DATABASE ", nil, "blu"];
+ me.arrowsColour[1][0] = "wht";
+ me.arrowsColour[1][1] = "blu";
+ me.arrowsMatrix[1][0] = 1;
me.arrowsMatrix[1][1] = 0;
} else {
- me.L1 = ["100°", "INB CRS", "blu"];
- me.L2 = ["R", " TURN", "blu"];
+ # waypoint is a leg, figure out how to handle it
+ return;
+ me.waypoint.hold_count = 999;
+ me.waypoint.hold_is_left_handed = 0;
+ me.waypoint.hold_is_distance = 0;
+ me.waypoint.hold_inbound_radial = me.waypoint.leg_bearing;
+
if (pts.Instrumentation.Altimeter.indicatedFt.getValue() >= 14000) {
- me.L3 = ["1.5/----", "TIME/DIST", "blu"];
+ me.waypoint.hold_time_or_distance = 90;
} else {
- me.L3 = ["1.0/----", "TIME/DIST", "blu"];
+ me.waypoint.hold_time_or_distance = 60;
}
- me.R1 = ["COMPUTED ", nil, "blu"];
- me.R2 = ["DATABASE ", nil, "blu"];
+
+ me.R1 = ["COMPUTED ", nil, "yel"];
+ me.R2 = ["DATABASE ", nil, "wht"];
+ me.arrowsColour[1][0] = "yel";
+ me.arrowsColour[1][1] = "wht";
+ me.arrowsMatrix[1][0] = 0;
+ me.arrowsMatrix[1][1] = 1;
}
- me.L6 = [" RETURN", nil, "wht"];
+
+ me.L1 = [sprintf("%03.0f°", me.waypoint.hold_inbound_radial), "INB CRS", "blu"];
+ if (me.waypoint.hold_is_left_handed) {
+ me.L2 = ["L", " TURN", "blu"];
+ } else {
+ me.L2 = ["R", " TURN", "blu"];
+ }
+ if (me.waypoint.hold_is_distance) {
+ me.L3 = [" -.-/" ~ me.waypoint.hold_time_or_distance, "TIME/DIST", "blu"];
+ } else {
+ me.L3 = [sprintf("%3.1f", (me.waypoint.hold_time_or_distance / 60)) ~ "/----", "TIME/DIST", "blu"];
+ }
+
me.C4 = ["LAST EXIT", nil, "wht"];
me.C5 = ["---- ---.-", "UTC FUEL", "wht"];
canvas_mcdu.pageSwitch[me.computer].setBoolValue(0);
@@ -82,23 +94,67 @@ var holdPage = {
},
updateTmpy: func() {
if (fmgc.flightPlanController.temporaryFlag[me.computer]) {
- me.L1[2] = "yel";
- me.L2[2] = "yel";
- me.L3[2] = "yel";
me.L6 = [" F-PLN", " TMPY", "yel"];
me.R6 = ["INSERT ", " TMPY", "yel"];
me.arrowsColour[0][5] = "yel";
me.titleColour = "yel";
canvas_mcdu.pageSwitch[me.computer].setBoolValue(0);
} else {
- me.L1[2] = "blu";
- me.L2[2] = "blu";
- me.L3[2] = "blu";
me.L6 = [" RETURN", nil, "wht"];
me.R6 = [nil, nil, "ack"];
me.arrowsColour[0][5] = "wht";
me.titleColour = "wht";
canvas_mcdu.pageSwitch[me.computer].setBoolValue(0);
}
- }
+ },
+ pushbuttonLeft: func(index) {
+ me.scratchpad = mcdu_scratchpad.scratchpads[me.computer].scratchpad;
+ if (index == 1) {
+ if (size(me.scratchpad) <= 3 and num(me.scratchpad) != nil) {
+ me.waypoint.hold_inbound_radial = me.scratchpad;
+ mcdu_scratchpad.scratchpads[me.computer].empty();
+ me._setupPageWithData();
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ } else if (index == 2) {
+ if (me.scratchpad == "L") {
+ me.waypoint.hold_is_left_handed = 1;
+ mcdu_scratchpad.scratchpads[me.computer].empty();
+ me._setupPageWithData();
+ } elsif (me.scratchpad == "R") {
+ me.waypoint.hold_is_left_handed = 0;
+ mcdu_scratchpad.scratchpads[me.computer].empty();
+ me._setupPageWithData();
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ } elsif (index == 3) {
+ if (num(me.scratchpad) != nil) {
+ me.waypoint.hold_time_or_distance = me.scratchpad;
+ mcdu_scratchpad.scratchpads[me.computer].empty();
+ me._setupPageWithData();
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ },
+ pushbuttonRight: func(index) {
+ me.scratchpad = mcdu_scratchpad.scratchpads[me.computer].scratchpad;
+ if (size(me.scratchpad) != 0) {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ } else {
+ if (index == 6) {
+ if (fmgc.flightPlanController.temporaryFlag[me.computer]) {
+ setprop("/MCDU[" ~ me.computer ~ "]/page", "F-PLNA");
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ } else {
+ mcdu_message(me.computer, "NOT ALLOWED");
+ }
+ }
+ },
};
\ No newline at end of file
diff --git a/Nasal/MCDU/INITA.nas b/Nasal/MCDU/INITA.nas
index b1360af9..c6e221f2 100644
--- a/Nasal/MCDU/INITA.nas
+++ b/Nasal/MCDU/INITA.nas
@@ -79,20 +79,23 @@ var initInputA = func(key, i) {
#setprop("MCDU[" ~ i ~ "]/page", "ROUTESELECTION");
} else if (fmgc.FMGCInternal.toFromSet) {
if (!fmgc.flightPlanController.temporaryFlag[i]) {
- var tfs = size(scratchpad);
- if (tfs == 4) {
- fmgc.FMGCInternal.altAirport = scratchpad;
- fmgc.FMGCInternal.altAirportSet = 1;
- atsu.ATISInstances[2].newStation(scratchpad);
- fmgc.windController.updatePlans();
- if (fmgc.FMGCInternal.blockConfirmed) {
- fmgc.FMGCInternal.fuelCalculating = 0;
- fmgc.fuelCalculating.setValue(0);
- fmgc.FMGCInternal.fuelCalculating = 1;
- fmgc.fuelCalculating.setValue(1);
+ if (size(scratchpad) == 4) {
+ if (size(findAirportsByICAO(scratchpad)) > 0) {
+ fmgc.FMGCInternal.altAirport = scratchpad;
+ fmgc.FMGCInternal.altAirportSet = 1;
+ atsu.ATISInstances[2].newStation(scratchpad);
+ fmgc.windController.updatePlans();
+ if (fmgc.FMGCInternal.blockConfirmed) {
+ fmgc.FMGCInternal.fuelCalculating = 0;
+ fmgc.fuelCalculating.setValue(0);
+ fmgc.FMGCInternal.fuelCalculating = 1;
+ fmgc.fuelCalculating.setValue(1);
+ }
+ mcdu_scratchpad.scratchpads[i].empty();
+ fmgc.updateARPT();
+ } else {
+ mcdu_message(i, "NOT IN DATA BASE");
}
- mcdu_scratchpad.scratchpads[i].empty();
- fmgc.updateARPT();
#fmgc.FMGCInternal.altSelected = 1;
#setprop("MCDU[" ~ i ~ "]/page", "ROUTESELECTION");
} else {
@@ -249,25 +252,26 @@ var initInputA = func(key, i) {
#setprop("MCDU[" ~ i ~ "]/page", "ROUTESELECTION");
} else {
if (!fmgc.flightPlanController.temporaryFlag[i]) {
- var tfs = size(scratchpad);
- if (tfs == 9 and find("/", scratchpad) != -1) {
+ if (size(scratchpad) == 9 and find("/", scratchpad) != -1) {
var fromto = split("/", scratchpad);
- var froms = size(fromto[0]);
- var tos = size(fromto[1]);
- if (froms == 4 and tos == 4) {
- resetFlightplan(i);
- fmgc.FMGCInternal.depApt = fromto[0];
- fmgc.FMGCInternal.arrApt = fromto[1];
- atsu.ATISInstances[0].newStation(fromto[0]);
- atsu.ATISInstances[1].newStation(fromto[1]);
- fmgc.FMGCInternal.toFromSet = 1;
- fmgc.FMGCNodes.toFromSet.setValue(1);
- mcdu_scratchpad.scratchpads[i].empty();
-
- fmgc.flightPlanController.updateAirports(fromto[0], fromto[1], 2);
- fmgc.FMGCInternal.altSelected = 0;
- fmgc.updateARPT();
- fmgc.updateArptLatLon();
+ if (size(fromto[0]) == 4 and size(fromto[1]) == 4) {
+ if (size(findAirportsByICAO(fromto[0])) > 0 and size(findAirportsByICAO(fromto[1])) > 0) {
+ resetFlightplan(i);
+ fmgc.FMGCInternal.depApt = fromto[0];
+ fmgc.FMGCInternal.arrApt = fromto[1];
+ atsu.ATISInstances[0].newStation(fromto[0]);
+ atsu.ATISInstances[1].newStation(fromto[1]);
+ fmgc.FMGCInternal.toFromSet = 1;
+ fmgc.FMGCNodes.toFromSet.setValue(1);
+ mcdu_scratchpad.scratchpads[i].empty();
+
+ fmgc.flightPlanController.updateAirports(fromto[0], fromto[1], 2);
+ fmgc.FMGCInternal.altSelected = 0;
+ fmgc.updateARPT();
+ fmgc.updateArptLatLon();
+ } else {
+ mcdu_message(i, "NOT IN DATA BASE");
+ }
#setprop("MCDU[" ~ i ~ "]/page", "ROUTESELECTION");
} else {
mcdu_message(i, "NOT ALLOWED");
diff --git a/Nasal/MCDU/MCDU.nas b/Nasal/MCDU/MCDU.nas
index d83f0619..8797f0ed 100644
--- a/Nasal/MCDU/MCDU.nas
+++ b/Nasal/MCDU/MCDU.nas
@@ -6,6 +6,7 @@
var pageNode = [props.globals.getNode("/MCDU[0]/page"), props.globals.getNode("/MCDU[1]/page")];
var page = nil;
var msg = nil;
+var airportPress = [0,0];
var scratchpadNode = [nil, nil];
var MCDU_init = func(i) {
@@ -68,7 +69,7 @@ var MCDU_reset = func(i) {
fmgc.FMGCInternal.depApt = "";
fmgc.FMGCInternal.flightNum = "";
fmgc.FMGCInternal.flightNumSet = 0;
- fmgc.FMGCInternal.gndTemp = -99;
+ fmgc.FMGCInternal.gndTemp = 15;
fmgc.FMGCInternal.gndTempSet = 0;
fmgc.FMGCInternal.toFromSet = 0;
fmgc.FMGCNodes.toFromSet.setValue(0);
@@ -356,6 +357,8 @@ var lskbutton = func(btn, i) {
mcdu_scratchpad.scratchpads[i].empty();
}
}
+ } else if (page == "HOLD") {
+ canvas_mcdu.myHold[i].pushbuttonLeft(1);
} else if (page == "MCDUTEXT") {
atsu.freeTexts[i].selection = 0;
atsu.freeTexts[i].changed = 1;
@@ -503,6 +506,8 @@ var lskbutton = func(btn, i) {
}
} else if (page == "VERTREV") {
canvas_mcdu.myVertRev[i].pushButtonLeft(2);
+ } else if (page == "HOLD") {
+ canvas_mcdu.myHold[i].pushbuttonLeft(2);
} else if (page == "MCDUTEXT") {
atsu.freeTexts[i].selection = 1;
atsu.freeTexts[i].changed = 1;
@@ -631,6 +636,8 @@ var lskbutton = func(btn, i) {
}
} else if (page == "VERTREV") {
canvas_mcdu.myVertRev[i].pushButtonLeft(3);
+ } else if (page == "HOLD") {
+ canvas_mcdu.myHold[i].pushbuttonLeft(3);
} else if (page == "MCDUTEXT") {
atsu.freeTexts[i].selection = 2;
atsu.freeTexts[i].changed = 1;
@@ -848,6 +855,8 @@ var lskbutton = func(btn, i) {
} else {
if (canvas_mcdu.myDuplicate[i] != nil and canvas_mcdu.myDuplicate[i].flagPROG) {
pagebutton("prog",i);
+ } else {
+ pageNode[i].setValue("F-PLNA");
}
}
} else if (page == "ARRIVAL") {
@@ -1499,25 +1508,32 @@ var pagebutton = func(btn, i) {
} else if (btn == "mcdu") {
mcdu_message(i, "SELECT DESIRED SYSTEM");
pageNode[i].setValue("MCDU");
- } else if (btn == "f-pln" or btn == "airport") {
+ } else if (btn == "f-pln") {
if (canvas_mcdu.myFpln[i] == nil) {
canvas_mcdu.myFpln[i] = fplnPage.new(2, i);
}
- if (btn == "airport") {
- if (fmgc.FMGCInternal.phase == 0 or fmgc.FMGCInternal.phase == 1) {
- canvas_mcdu.myFpln[i].scroll = 0;
- } else {
- if (fmgc.flightPlanController.temporaryFlag[i]) {
- canvas_mcdu.myFpln[i].scroll = fmgc.flightPlanController.arrivalIndex[i];
+ canvas_mcdu.myFpln[i].scroll = 0;
+ pageNode[i].setValue("F-PLNA");
+ } else if (btn == "airport") {
+ if (airportPress[i] == 0 or fmgc.FMGCInternal.phase >= 1) {
+ if (fmgc.flightPlanController.temporaryFlag[i]) {
+ if (fmgc.flightPlanController.currentToWptIndex.getValue() == fmgc.flightPlanController.arrivalIndex[i]) {
+ canvas_mcdu.myFpln[i].scroll = (fmgc.flightPlanController.arrivalIndex[i] - fmgc.flightPlanController.currentToWptIndex.getValue());
} else {
- canvas_mcdu.myFpln[i].scroll = fmgc.flightPlanController.arrivalIndex[2];
+ canvas_mcdu.myFpln[i].scroll = (fmgc.flightPlanController.arrivalIndex[i] - fmgc.flightPlanController.currentToWptIndex.getValue()) - 1;
+ }
+ } else {
+ if (fmgc.flightPlanController.currentToWptIndex.getValue() == fmgc.flightPlanController.arrivalIndex[2]) {
+ canvas_mcdu.myFpln[i].scroll = (fmgc.flightPlanController.arrivalIndex[2] - fmgc.flightPlanController.currentToWptIndex.getValue());
+ } else {
+ canvas_mcdu.myFpln[i].scroll = (fmgc.flightPlanController.arrivalIndex[2] - fmgc.flightPlanController.currentToWptIndex.getValue()) - 1;
}
}
- } else {
+ airportPress[i] = 1;
+ } else if (fmgc.FMGCInternal.phase == 0 or fmgc.FMGCInternal.phase == 1) {
canvas_mcdu.myFpln[i].scroll = 0;
+ airportPress[i] = 0;
}
- pageNode[i].setValue("F-PLNA");
-
} else if (btn == "fuel-pred") {
pageNode[i].setValue("FUELPRED");
} else if (btn == "dirto") {
diff --git a/Nasal/MCDU/PERFCLB.nas b/Nasal/MCDU/PERFCLB.nas
index ee45ead1..cbf4af0a 100644
--- a/Nasal/MCDU/PERFCLB.nas
+++ b/Nasal/MCDU/PERFCLB.nas
@@ -39,6 +39,7 @@ var perfCLBInput = func(key, i) {
setprop("/FMGC/internal/activate-twice", 1);
fmgc.FMGCInternal.phase = 5;
fmgc.FMGCInternal.decel = 1;
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
setprop("MCDU[" ~ i ~ "]/page", "PERFAPPR");
} else {
mcdu_message(i, "NOT ALLOWED");
diff --git a/Nasal/MCDU/PERFCRZ.nas b/Nasal/MCDU/PERFCRZ.nas
index 87d041e7..801bdfb8 100644
--- a/Nasal/MCDU/PERFCRZ.nas
+++ b/Nasal/MCDU/PERFCRZ.nas
@@ -33,6 +33,7 @@ var perfCRZInput = func(key, i) {
setprop("/FMGC/internal/activate-twice", 1);
fmgc.FMGCInternal.phase = 5;
fmgc.FMGCInternal.decel = 1;
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
setprop("MCDU[" ~ i ~ "]/page", "PERFAPPR");
} else {
mcdu_message(i, "NOT ALLOWED");
diff --git a/Nasal/MCDU/PERFDES.nas b/Nasal/MCDU/PERFDES.nas
index def27ef8..ab92bfc5 100644
--- a/Nasal/MCDU/PERFDES.nas
+++ b/Nasal/MCDU/PERFDES.nas
@@ -33,6 +33,7 @@ var perfDESInput = func(key, i) {
setprop("/FMGC/internal/activate-twice", 1);
fmgc.FMGCInternal.phase = 5;
fmgc.FMGCInternal.decel = 1;
+ setprop("/instrumentation/nd/symbols/decel/show", 0);
setprop("MCDU[" ~ i ~ "]/page", "PERFAPPR");
} else {
mcdu_message(i, "NOT ALLOWED");
diff --git a/Nasal/MCDU/RECEIVEDMESSAGES.nas b/Nasal/MCDU/RECEIVEDMESSAGES.nas
index 8c41e118..bf6d9279 100644
--- a/Nasal/MCDU/RECEIVEDMESSAGES.nas
+++ b/Nasal/MCDU/RECEIVEDMESSAGES.nas
@@ -1,3 +1,6 @@
+# A3XX MCDU Received Messages Page
+# Copyright (c) 2022 Jonathan Redpath (legoboyvdlp)
+
var receivedMessagesPage = {
title: nil,
arrowsMatrix: [[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]],
diff --git a/Systems/fmgc-drivers.xml b/Systems/fmgc-drivers.xml
index 0c2fa3e9..fae0bc9b 100644
--- a/Systems/fmgc-drivers.xml
+++ b/Systems/fmgc-drivers.xml
@@ -434,6 +434,24 @@
+
+ Get Back on Magenta
+ gain
+
+
+
+ /fdm/jsbsim/velocities/vc-kts
+ 14050
+ 36020
+
+
+
+ /instrumentation/gps/wp/wp[1]/course-error-nm
+
+ -45
+ 45
+
+
Heading Error Deg
gain
@@ -485,7 +503,8 @@
- /FMGC/flightplan[2]/current-leg-course
+ /instrumentation/gps/wp/leg-true-course-deg
+ /it-autoflight/internal/course-error-deg
/it-autoflight/internal/drift-angle-deg
-1.0