legoboyvdlp / A320-family

A high-quality Airbus A320 simulation for the open source simulator, FlightGear
GNU General Public License v2.0
133 stars 43 forks source link

Bug - Autopilot auto speed inconsistent behavior #304

Open jojo2357 opened 1 year ago

jojo2357 commented 1 year ago

When flying a procedure, the autopilot will only sometimes set the speed to the procedure's restriction, and never keep it there.

To reproduce

Load this procedure file (note that it intentionally has the wrong runway names to be consistent with fg, if yours are correct, use these procedures) into fg.

Start on 26R, get ready to blast off.

In the flight computer, load the NIITZ3 departure. Proceed to take off. As soon as possible, engage ap, flaps up, gear up, and begin an ap-managed climb to 4k'.

Fly past RUDYY to observe error.

Expected behavior

The ap should, imo, hold 230kt while flying the intercept in order to meet the speed constraint at RUDYY.

I would also expect this sort of behavior to take place on decent, but except for when reaching (decel) or 10k', the ap keeps the accelerator welded to the floor.

Actual behavior

The plane sets a target speed of 250kt, intercepts the radial, and then sets the speed to 230kt until passing RUDYY.

What am I using?

merspieler commented 7 months ago

Can confirm this issue, seen it in plenty of departures and arrivals.

merspieler commented 6 months ago

Got it fixed for SID, STAR is WIP...

merspieler commented 5 months ago

Note: https://forum.flightgear.org/viewtopic.php?p=419111#p419111 flikekoralle wants to continue working on it. patch I gave them as a starting point:

diff --git a/Nasal/FMGC/FMGC.nas b/Nasal/FMGC/FMGC.nas
index 78e5b597..b2585db6 100644
--- a/Nasal/FMGC/FMGC.nas
+++ b/Nasal/FMGC/FMGC.nas
@@ -978,6 +978,27 @@ var ManagedSPD = maketimer(0.25, func {

          if (waypoint != nil) {
             constraintSpeed = flightPlanController.flightplans[2].getWP(FPLN.currentWP.getValue()).speed_cstr;
+            if ((FMGCInternal.phase == 2 or FMGCInternal.phase == 3) and flightPlanController.flightplans[2].getWP(FPLN.currentWP.getValue()).wp_role == "sid") {
+               i = FPLN.currentWP.getValue();
+               while (flightPlanController.flightplans[2].getWP(i).wp_role == "sid") {
+                  if (flightPlanController.flightplans[2].getWP(i).speed_cstr != nil and flightPlanController.flightplans[2].getWP(i).speed_cstr > 100) {
+                     constraintSpeed = flightPlanController.flightplans[2].getWP(i).speed_cstr;
+                     break;
+                  }
+                  i = i + 1;
+               }
+            }
          }

          if ((Modes.PFD.FMA.pitchMode == " " or Modes.PFD.FMA.pitchMode == "SRS") and (FMGCInternal.phase == 0 or FMGCInternal.phase == 1)) {