Issue with constant XTrack error

In a scenario where an aircraft is flying between waypoints that are far apart (>1000m), I assume that the aircraft should converge to follow the line between the two points based on the modified L1 navigation guidance algorithm described in the docs. We are finding that our aircraft converges towards the line but often will remain offset with an xtrack error of anywhere up to approximately 3m. In the case of flying a grid, we find that this offset is roughly the same in magnitude and direction regardless of the direction we are flying (i.e. the aircraft will usually have to an offset to the left or right of the flight path for the whole flight). I would expect the integrator in the NAVL1 controller to reduce this error when flying large distances between waypoints but we do not see this.

My suspicion is that we will have to tune NAVL1_PERIOD, NAVL1_DAMPING and NAVL1_XTRACK_I parameters together. My current thinking is that we perform the initial L1 controller tuning (as per the docs) and then increase NAVL1_XTRACK_I until we induce some oscillation and then back it off a little. I also see on GitHub that there is an issue regarding this type of offset error with the L1 controller which might be related (https://github.com/ArduPilot/ardupilot/pull/101#issuecomment-720003883).

Interestingly, I seem to be able to counteract the track error offset by trimming the aircraft every flight over a long line. Once the aircraft is trimmed it usually remains on track for that flight. However, I would expect the integrator in the controller to take care of this and I feel that trimming the plane to account for the xtrack error is not a proper solution to the problem.

So my questions are as follows:

  1. How should we aim to reduce the constant xtrack error?
  2. Is there a recommended procedure for tuning the “advanced” NAVL1 parameters in conjunction with the other NAVL1 parameters to reduce xtrack error?

I am experiencing the same. It is especially problematic during landing as it never lands within the 15m wide runway unless I manually help with the rudder.
Moreover, if I look at my logs I see NTUN.XT (xtrack error) of around 6-10m but NTUN.XTi (xtrack integrator) is always 0 regardless of the value of NAVL1_XTRACK_I.
This has happened to me in all my logs, with two different autopilot hardware and with all versions of Plane since 3.8 to 4.0.7 (my current version)
What are we missing here?

I’m also seeing this issue with a rover in a very recent (March 16, 2021) version of the master branch.

In my case, I need 2cm accuracy and typically get close to that except for this occasional navigation offset. In those cases, the rover still tracks the offset line with high accuracy (~2cm) but the mere presence of the offset can lead to collisions with obstacles that are >2cm from the desired track. I’ve seen the offset be as large as 60cm but it is typically closer to +/-10cm.

I’m fairly new to ArduPilot but would be very interested in techniques for debugging this issue since there doesn’t seem to be much interest in the larger ArduPilot community.

FYI, you might be interested in ArduPilot issue #2650: https://github.com/ArduPilot/ardupilot/issues/2650

I have been doing some digging and I think I have found the cause for the cross-track error.

Below are some plots showing the cross-track error (XT) and the value of the cross-track error integrator (XTi) from the logs of one of our aircraft. The plot shows a 5 minute segment of the flight where the aircraft was flying in a straight line between two waypoints.

As we can see, the plane has a mean cross-track error of roughly 2.5m and is positive for this entire segment of the flight. I would expect the integrator accumulates the error but as you can see in the second plot, this is not the case. Instead, we can see that the integrator follows the shape of the cross-track error with some noise/jitter.

Zooming in to a 1 minute segment (shown below), it appears as if the integrator is integrating for one or two loop iterations and then being reset.

Looking at the latest ArduPlane code (ArduPlane-4.0.9), specifically the waypoint navigation control loop which deals with the L1 control for waypoint navigation, I didn’t see anything wrong with the guidance logic. However, in the start of the function there is a check to determine whether the update_waypoint() function has been called in the last 100ms (I assume this is due to the scheduler invoking the navigation loop at a frequency of 10Hz).

If the function has not been called in the last 100ms, the integrator is reset to 0. Later in the function, the integration component for the current loop iteration is added to the integrator. Assuming that the logging of the integrator doesn’t interrupt the function midway, it makes sense that we don’t see the integrator having a value of 0 as it will always accumulate the initial integrator component for the current loop iteration if our cross-track error is non-zero.

For interests sake, I have included a plot showing the first two seconds of the above plot. One thing to note are that the logging of these parameters is scheduled to run at a rate of 25Hz. Additionally, one should note that where there are increments/decrements in the data, the relevant parameter could have been updated at any time in-between the two points before and after the increment/decrement occurs in the logs.

With this in mind, it appears to me that the integrator is accumulating as it should when the scheduler is able to run the update_waypoint() function at a rate of 10Hz (within the >100ms limit). However, it is very likely that the scheduler is not always able to call the function within this time as this limit is right on the edge of the frequency at which the function is called. Any amount over the 100ms limit, however small, would cause the integrator to be reset resulting in the above behavior.

Fortunately, it looks like there is already a fix for this implemented in the master branch of ArduPilot; however it hasn’t made its way into the latest ArduPlane release (possibly other variants of ArduPilot too, but I haven’t checked).

1 Like

Are you by any chance viewing the data in the MissionPlanner graph viewer along with any other variables? I also thought that the integrator was zero; however, upon closer inspection it appears that the value was too small to be seen alongside any other variables. See screenshots below and take note of the units for the Y-axis:

You are right!
If you plot XTi alone it is easier to see that is not exactly 0. I don’t usually fly long segments as you do, rather close waypoints and landings, but definitely the behaviour of XTi is strange; it doesn’t look like an integrator at all.
This is what it looks for me:


By the way: Where did you read that there’s a fix for this? Do you know when will it be available for Arduplane?

I’m glad to see that we both seem to have the same error. I went through part of the ArduPilot code on GitHub to see what may be causing the issue and found the error I mentioned above. The fix was implemented by @tridge in November last year and perhaps he knows when it may find its way into the ArduPlane release?

I’ve seen this thread in github about the same issue and I’ve posted there a link to your findings.
Let’s hope they can do something about it.
https://github.com/ArduPilot/ardupilot/issues/2650

Good job guys, looks like you’ve cracked it! Glad it’s been fixed. Can either of you fly master branch to confirm?

Sure - will do a test flight next week.

Does that imply building the code from github myself? If so I’d prefer to wait for Liam’s results and hope for a new beta or stable release.

Hi, just to update everyone. We flew the master branch with the cross-track fix implemented and can confirm that this has solved the problem. I have attached some graphs below which can be compared to the previous plots I posted above. The conditions we flew in were rather windy providing good conditions to test the controller.

@MagicRuB - Is there any chance we can try get this backported to a stable ArduPlane release on GitHub?

Fantastic news, Liam!
I am hoping for a stable version to include this fix as well!!

I see this fix still hasn’t made it’s way into yesterday’s ArduPilot-beta release. @MagicRuB Any ideas on how we can get it included?

@LiamClarkZA Hmm, I’ll have to check that. Thanks for pointing it out! Make sure to ping me here to follow up if you don’t hear back from me

Hi. great job with this. We are more people interested in knowing when this fix will make it into the release.

Hi every one,i have a quadplane and i think i have same problem,when the craft is in auto mode,there flight is like sinus as you can see in the pictures


I tried to increase the L1 period parameter and Damping,but the problem still exist,can you help me in this issue?the wingspan is about 390 cm