为什么一个较低的三角洲导致我的PID控制器调整少precision?我的、较低、控制器、PID

2023-09-11 23:03:02 作者:你怎么那么懂事,连崩溃都是悄无声息的。今日小编带来的是一看一

我不能完全肯定,如果这是正确的地方要问这个。那么,它的是的编程问题,我想。

I'm not entirely sure if this is the right place to ask this. Well, it is a programming problem I suppose.

我想在Java中创建一个简单的PID控制器的模拟。

I am trying to create a simple PID Controller simulation in Java.

在短,有一个目标值和当前值。电流值是由许多修改。您提供的PID控制器的电流值,它会尝试返回的希望了许多这样的数字将导致当前值接近目标值。加时赛中,越用PID控制器,它会学习(使用积分和导数),并最终将返回更多,更准确的值。此,比如说是有用的,通过控制车轮的运动保持船的平衡。

In short, there is a target value and a current value. The current value is modified by a number. You provide the PID Controller the current value and it will try to return a number in the hopes that such number will cause the current value to approximate the target value. Overtime, the more you use the PID controller, it will "learn" (using integrals and derivatives), and will eventually return more and more accurate values. This is useful for, say, maintaining the equilibrium of a boat by controlling the wheel movement.

采用PID控制器的计算公式为pretty的一般很简单 - 我这样想着。在下面的例子中,由PID控制器返回的值被简单地加到当前值。我相信它会工作,更复杂的应用(涉及乘法或除法,等)。这是我的计划:

The formula used by a PID controller is pretty general and quite straightforward - or so I thought. In the below example, the value that is returned by the PID Controller is simply added to the current value. I assume it would work with more complex applications (that involve multiplication or division, etc). This is my program:

public class PID {

    private static double Kp = 0.1;
    private static double Kd = 0.01;
    private static double Ki = 0.005;

    private static double targetValue = 100.0;
    private static double currentValue = 1.0;

    private static double integral = 0.0;
    private static double previousError = 0.0;

    private static double dt = 0.5;

    private static double max = 5;
    private static double min = -5;

    public static void main(String[] args) throws Exception {
        while (true) {
            Thread.sleep((long) (1000.0 * dt));
            double error        = targetValue - currentValue;
            double derivative   = 0.0;
            double output       = 0.0;
            integral = integral + error * dt;
            derivative          = (error - previousError) / dt;
            output              = Kp * error + Ki * integral + Kd * derivative;
            previousError         = error;
            if (output > max) output = max;
            if (output < min) output = min;

            // Apply the output to the current value:
            System.out.println(currentValue + " + " + output + " = " + (currentValue + output));
            currentValue += output;
        }
    }

}

如果你运行它,你会看到PID控制器最终设法使电流值是非常非常接近目标值。

If you run this, you will see that the PID controller eventually manages to cause the current value to be very very close to the target value.

这是pretty的凉爽。现在,我想看看我的成绩快了些(因为我打算做某种互动图形),所以我决定三角洲 DT 更改为 0.1

It's pretty cool. Now, I wanted to see my results a bit faster (because I plan to make some sort of interactive graph), so I decided to change the delta dt to 0.1.

唉,所产生的价值不再是接近100!现在看来,达到105,然后,很慢慢,减少到100这不是好!

Alas, the resulting value is no longer close to 100! Now it appears to reach 105 and then, very slowly, decrease to 100. That's not good!

现在设想一下有 DT 0.01 !现在,这是非常缓慢的,达到102,而现在它甚至不回100,现在它只是不断增加!

Now imagine having dt at 0.01! Now it is extremely slow to reach 102, and now it doesn't even go back to 100, now it just keeps increasing!

所以我的问题是:为什么一个较低的三角洲导致此

So my question is: why does a lower delta cause this?

我的code是根据this PDF文档和他们使用 0.01 就好了。

My code is based on this PDF document and they use 0.01 just fine.

推荐答案

它很容易,你得到一个积分饱和。

its very easy, you are getting a integral windup.

请参阅,积分不限于生长,但是可以限制输出的效果是在范围[-5,5]

See, "integral" is not limited in grow, BUT you limit the effect of the output to be in range [-5, 5]

有很多的解决方案,我的转储的解决方法是限制积分的最小值和最大值之间。

There are many solution, my dump fix is to limit integral between min and max.

与固定有没有用0.5,0.1和0.01的环路时间上颚大于一个位(也限制性衍生物)

with that fix there is no overshot bigger than a digit with a loop time of 0.5, 0.1 and 0.01 (but also limiting derivative)

限制衍生物可以是通过使用用于prevent衍生物踢同一特技修正:使用之间precedent和实际值,而不是误差之差的差。只是要注意,你还需要反转迹象

Limiting derivative may be fix by using the same trick used to prevent "derivative kick": use the difference between precedent and actual value instead of difference between error. Just pay attention that you also need to invert the sign

但是,如果你需要模拟与DT的任何值PID尽可能快,只是评论睡眠!

But if you need to simulate a PID with dt of any value as fast as possible, just comment the sleep!