diff --git a/Models/Instruments/PFD/PFD.nas b/Models/Instruments/PFD/PFD.nas index b944f3b0..a7a2157a 100644 --- a/Models/Instruments/PFD/PFD.nas +++ b/Models/Instruments/PFD/PFD.nas @@ -708,7 +708,7 @@ var canvas_pfd = { props.UpdateManager.FromHashValue("ASItrgt", 0.1, func(val) { obj["ASI_target"].setTranslation(0, val * -6.6); }), - props.UpdateManager.FromHashList(["speedError","ASItrgtdiff","targetMach","tgt_kts","ktsMach"], 0.5, func(val) { + props.UpdateManager.FromHashList(["speedError","ASItrgtdiff","targetMach","targetKts","ktsMach"], 0.5, func(val) { if (!val.speedError) { if (abs(val.ASItrgtdiff) <= 42) { obj["ASI_digit_UP"].hide(); @@ -722,7 +722,7 @@ var canvas_pfd = { obj["ASI_decimal_UP"].hide(); obj["ASI_decimal_DN"].show(); } else { - obj["ASI_digit_DN"].setText(sprintf("%3.0f", val.tgt_kts)); + obj["ASI_digit_DN"].setText(sprintf("%3.0f", val.targetKts)); obj["ASI_decimal_UP"].hide(); obj["ASI_decimal_DN"].hide(); } @@ -735,7 +735,7 @@ var canvas_pfd = { obj["ASI_decimal_UP"].show(); obj["ASI_decimal_DN"].hide(); } else { - obj["ASI_digit_UP"].setText(sprintf("%3.0f", val.tgt_kts)); + obj["ASI_digit_UP"].setText(sprintf("%3.0f", val.targetKts)); obj["ASI_decimal_UP"].hide(); obj["ASI_decimal_DN"].hide(); } @@ -1342,19 +1342,6 @@ var canvas_pfd = { me.tgt_ias = notification.targetIasPFD; - me.tgt_kts = notification.targetKts; - - if (notification.managedSpd) { - if (fmgc.FMGCInternal.decel) { - me.tgt_ias = fmgc.FMGCInternal.vappSpeedSet ? fmgc.FMGCInternal.vapp_appr : fmgc.FMGCInternal.vapp; - me.tgt_kts = fmgc.FMGCInternal.vappSpeedSet ? fmgc.FMGCInternal.vapp_appr : fmgc.FMGCInternal.vapp; - } else if (fmgc.FMGCInternal.phase == 6) { - me.tgt_ias = fmgc.FMGCInternal.clean; - me.tgt_kts = fmgc.FMGCInternal.clean; - } - } - - notification.tgt_kts = me.tgt_kts; if (me.tgt_ias <= 30) { notification.ASItrgt = 0 - notification.ASI; @@ -1420,7 +1407,6 @@ var canvas_pfd = { notification.SPDv1trgtdiff = 0; notification.SPDvrtrgtdiff = 0; notification.SPDv2trgtdiff = 0; - notification.tgt_kts = 0; notification.V1trgt = 0; notification.VRtrgt = 0; notification.V2trgt = 0; diff --git a/Nasal/FMGC/FMGC.nas b/Nasal/FMGC/FMGC.nas index 8a51e3b9..befbbe94 100644 --- a/Nasal/FMGC/FMGC.nas +++ b/Nasal/FMGC/FMGC.nas @@ -210,6 +210,13 @@ var FMGCInternal = { fuelPredGw: 0, cg: 0, + # VAPP + approachSpeed: 0, + currentWindComponent: 0, + destWindComponent: 0, + gsMini: 0, + headwindComponent: 0, + tailwindComponent: 0, # Managed Speed machSwitchover: 0, @@ -597,6 +604,7 @@ var radios = maketimer(1, func() { }); var newphase = nil; +var windAngleDelta = nil; var masterFMGC = maketimer(0.2, func { n1_left = pts.Engines.Engine.n1Actual[0].getValue(); @@ -755,14 +763,20 @@ var masterFMGC = maketimer(0.2, func { weight_lbs = pts.Fdm.JSBsim.Inertia.weightLbs.getValue() / 1000; altitude = pts.Instrumentation.Altimeter.indicatedFt.getValue(); + if (FMGCInternal.destWindSet and flightPlanController.flightplans[2].destination_runway != nil) { + windAngleDelta = geo.normdeg180(FMGCInternal.destMag - flightPlanController.flightplans[2].destination_runway.heading - magvar(fmgc.flightPlanController.flightplans[2].destination_runway)); + FMGCInternal.destWindComponent = FMGCInternal.destWind * math.cos(abs(windAngleDelta) * D2R); + + FMGCInternal.headwindComponent = math.clamp(FMGCInternal.destWindComponent / 3, 0, 15); + FMGCInternal.tailwindComponent = math.clamp(-FMGCInternal.destWindComponent, 0, 15); + } else { + FMGCInternal.headwindComponent = 0; + FMGCInternal.tailwindComponent = 0; + FMGCInternal.destWindComponent = 0; + } + if (!fmgc.FMGCInternal.vappSpeedSet) { - if (FMGCInternal.destWind < 5) { - FMGCInternal.vapp = FMGCInternal.vls + 5; - } elsif (FMGCInternal.destWind > 15) { - FMGCInternal.vapp = FMGCInternal.vls + 15; - } else { - FMGCInternal.vapp = FMGCInternal.vls + FMGCInternal.destWind; - } + FMGCInternal.vapp = FMGCInternal.vls + math.max(5, FMGCInternal.headwindComponent); } # predicted takeoff speeds @@ -810,16 +824,17 @@ var masterFMGC = maketimer(0.2, func { FMGCInternal.vls_appr = 113; } if (!fmgc.FMGCInternal.vappSpeedSet) { - if (FMGCInternal.destWind < 5) { - FMGCInternal.vapp_appr = FMGCInternal.vls_appr + 5; - } elsif (FMGCInternal.destWind > 15) { - FMGCInternal.vapp_appr = FMGCInternal.vls_appr + 15; - } else { - FMGCInternal.vapp_appr = FMGCInternal.vls_appr + FMGCInternal.destWind; - } + FMGCInternal.vapp_appr = FMGCInternal.vls_appr + math.max(5, FMGCInternal.headwindComponent); } } + + windAngleDelta = geo.normdeg180(pts.Orientation.heading.getValue() - (pts.Instrumentation.PFD.windDirection.getValue() or 0)); + FMGCInternal.currentWindComponent = pts.Instrumentation.PFD.windSpeed.getValue() or 0 * math.cos(abs(windAngleDelta) * D2R); + + FMGCInternal.gsMini = FMGCInternal.vapp_appr - math.max(10, FMGCInternal.headwindComponent); + FMGCInternal.approachSpeed = math.max(FMGCInternal.vapp_appr, FMGCInternal.gsMini + FMGCInternal.currentWindComponent); + aoa_prot = 15; aoa_max = 17.5; aoa_0 = -5; @@ -967,14 +982,14 @@ var ManagedSPD = maketimer(0.25, func { } elsif ((FMGCInternal.phase == 2 or FMGCInternal.phase == 3) and altitude <= FMGCInternal.clbSpdLimAlt) { # Speed is maximum of greendot / climb speed limit FMGCInternal.mngKtsMach = 0; - FMGCInternal.mngSpdCmd = FMGCInternal.decel ? FMGCInternal.minspeed : math.clamp(FMGCInternal.clbSpdLim, FMGCInternal.clean, 999); + FMGCInternal.mngSpdCmd = FMGCInternal.decel ? FMGCInternal.approachSpeed : math.clamp(FMGCInternal.clbSpdLim, FMGCInternal.clean, 999); } elsif ((FMGCInternal.phase == 2 or FMGCInternal.phase == 3) and altitude > (FMGCInternal.clbSpdLimAlt + 20)) { FMGCInternal.mngKtsMach = FMGCInternal.machSwitchover ? 1 : 0; FMGCInternal.mngSpdCmd = FMGCInternal.machSwitchover ? mng_alt_mach : mng_alt_spd; } elsif ((FMGCInternal.phase >= 4 and FMGCInternal.phase <= 6) and altitude > (FMGCInternal.desSpdLimAlt + 20)) { if (FMGCInternal.decel) { FMGCInternal.mngKtsMach = 0; - FMGCInternal.mngSpdCmd = FMGCInternal.minspeed; + FMGCInternal.mngSpdCmd = FMGCInternal.approachSpeed; } else { FMGCInternal.mngKtsMach = FMGCInternal.machSwitchover ? 1 : 0; FMGCInternal.mngSpdCmd = FMGCInternal.machSwitchover ? mng_alt_mach : mng_alt_spd; @@ -982,7 +997,7 @@ var ManagedSPD = maketimer(0.25, func { } elsif ((FMGCInternal.phase >= 4 and FMGCInternal.phase <= 6) and altitude <= FMGCInternal.desSpdLimAlt) { FMGCInternal.mngKtsMach = 0; # Speed is maximum of greendot / descent speed limit - FMGCInternal.mngSpdCmd = FMGCInternal.decel ? FMGCInternal.minspeed : math.clamp(FMGCInternal.desSpdLim, FMGCInternal.clean, 999); + FMGCInternal.mngSpdCmd = FMGCInternal.decel ? FMGCInternal.approachSpeed : math.clamp(FMGCInternal.desSpdLim, FMGCInternal.clean, 999); } # Clamp to minspeed, maxspeed