Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent handling of i term windup when pidsum_limit(_yaw) is bellow 50% vs above 50% #13486

Open
tbolin opened this issue Mar 29, 2024 · 5 comments · May be fixed by #13506
Open

Inconsistent handling of i term windup when pidsum_limit(_yaw) is bellow 50% vs above 50% #13486

tbolin opened this issue Mar 29, 2024 · 5 comments · May be fixed by #13506
Labels
BUG Bugs are excluded from automatically being marked as stale

Comments

@tbolin
Copy link
Contributor

tbolin commented Mar 29, 2024

Describe the bug

The handling of windup differs when pidsum_limit(_yaw) is bellow 50% and above 50%.

This is a result of the anti windup system only using getMotorMixRange. If pidsum_limit(_yaw) is set bellow 50% a single axis can not trigger the anti windup mechanism, and the i term will keep increasing despite the axis being saturated.
If pidsum_limit(_yaw) is at or above 50% a single axis can saturate getMotorMixRange and the i term will freeze if the axis is saturated.

To Reproduce

  • Set pidsum_limit_yaw to 40% (the default) and the maximum yaw rate high enough to reach the limit.

  • Execute a few yaws wit full stick deflection

  • The yaw iterm will keep increasing while the yaw pidsum is saturated, resulting in a large overshoot
    image

  • Set pidsum_limit_yaw to 50%

  • Execute a few yaws wit full stick deflection

  • The yaw iterm will freeze while the yaw pidsum is saturated, resulting in a much smaller over shoot
    image

Logs
iterm_yaw_windup.zip

Expected behavior

The i term should freeze if the pid sum is at the limit, or at least be more consistent

Support ID

NA

Flight controller

BETAFPVF411

Other components

No response

How are the different components wired up (including port information)

No response

Add any other context about the problem that you think might be relevant here

No response

@tbolin tbolin added the Template: Bug Set by auto_close_issue. label Mar 29, 2024
@ledvinap
Copy link
Contributor

@tbolin : Ideally, motor output would be propagated back to PIDs (inverse of mixer mapping). Then, it would be quite easy to handle I-term correctly. It was considered long time agon and IIRC deemed too complicated at that time.

@tbolin
Copy link
Contributor Author

tbolin commented Mar 30, 2024

@tbolin : Ideally, motor output would be propagated back to PIDs (inverse of mixer mapping). Then, it would be quite easy to handle I-term correctly. It was considered long time agon and IIRC deemed too complicated at that time.

I have already written a simple fix that appears to work pretty well. The result is in the fixed_limit_400.bbl file. Just wanted to make sure this is actually considered an issue (and add some unit tests) before I make a PR.

@tbolin tbolin linked a pull request Apr 6, 2024 that will close this issue
@ctzsnooze
Copy link
Member

ctzsnooze commented Apr 6, 2024

Thanks for finding this, your advice on how to fix it will be very much appreciated.
I've typically recommended using iterm_windup to control excessive iTerm in yaw.
I never really knew which of the parameters would be 'constrained' by a pidSum limiter.
Looks like only the 'sum' itself is constrained.... leaving iTerm to accumulate 'in the background', with no limit, effectively.
iterm_windup stops the iTerm accumulation itself in this situation. Perhaps we need something like iterm_windup in this situation, to limit the iTerm part, not the Term part.

@tbolin
Copy link
Contributor Author

tbolin commented Apr 6, 2024

I already made a PR with a suggested fix.
The fix applies exactly the same mechanism on the i term change as the mixer range method, but uses the PID-sum on that axis relative to the pid_sum_limit. Then the lowest i-term change from the two methods is used to determine the rate of change.

That way the result is identical if the pid_sum_limit of that axis is 500 or more (assuming the normal quad mixer).

The fixed_limit_400.bbl file in the zip I uploaded have this fix applied. The i-term behaves much more like with pid_sum_limit_yaw set to 500 in this log. The i-term does not wind up nearly as much and the overshoots are smaller than in the dev_limit_400.bbl log.

@haslinghuis haslinghuis added BUG Bugs are excluded from automatically being marked as stale and removed Template: Bug Set by auto_close_issue. labels Apr 6, 2024
@haslinghuis haslinghuis linked a pull request Apr 12, 2024 that will close this issue
@ctzsnooze
Copy link
Member

As you know, I've spent a lot of time thinking about this.
After some considerable effort, I haven't really got anywhere.
However some things I have formed some kind of conceptual basics. To summarise:

  • the only current need for iTermWindup is on yaw
  • it's needed on yaw because we don't apply iTermRelax to yaw. Apart from iterm_windup, yaw has no means to constrain iTerm growth on fast stick inputs.
  • iTermWindup is probably not helpful on roll on pitch; it is a global factor that inhibits the iTerm on all axes just because one axis has saturated the mixer. That's not ideal. For instance, a roll flip that saturates motors will activate iTermWindup and affect iTerm on pitch, just when we want iTerm on pitch to stabilise the cross-axis wobble that we sometimes get in this situation.
  • Hence, maybe what we really is a method for iTermRelax on Yaw, one that works across the full allowed range of values for iTermLimit and pidSumLimitYaw.

The old dynCi method and this method are both 'input gain limiting' methods of constraining iTerm growth. As pointed out by Petr Ledvina, they carry the possibility that if iTerm became the dominant contributor to pidSum, then iTerm could become large, reduce it's input gain factor via pidSum, and then be very slow to go away. In fact I think this was a problem with the dynCi method. It was fortunate that iTermLimit was 400, since that meant one axis could only command 80% of the motorMix, but if two axes went high in iTerm, they could saturate motorMix, and then iTerm could not fall. This possibility is high if iTermLimit is set to a value above pidSumLimit, in particular. And various configuration possibilities exist with our current array of iTerm and pidSum limits - one of which is identified by this PR.

Hence I am now tending to think that input limiting methods for iTerm windup are probably best avoided. And that means, rather than using motorMix / dynCi / iTermWindup methods being applied to all axes, we should focus primarily on an explicit iTermRelax option for yaw.

The main reason why currently there is no iTermRelax on Yaw is that in most 5in and above quads, yaw iTerm must grow, right from the start, to avoid excessive delay in achieving the target value. Particularly for larger quads, there was a need to accumulate a lot of iTerm on yaw. 'Relaxing' iTerm on yaw on these machines can result in long delay reaching the set yaw rate. The price we pay is some overshoot like shown above, which most people don't notice or care about very much.

I think it might be best to explore removing the dynCi method, certainly as a 'global' anti-windup method, and evaluate how best we can solve issues that are specific to yaw, perhaps via the existing iTermRelax code. To me that makes sense, since this specific issue relates only to iTerm related overshoots on commanded yaw inputs, which is exactly what iTerm Relax is about.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BUG Bugs are excluded from automatically being marked as stale
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants