java - 为什么较低的 delta 会导致我的 PID Controller 调整精度较低?

标签 java algorithm

我不确定在这里问这个问题是否合适。好吧,我想这是一个编程问题。


我正在尝试用 Java 创建一个简单的 PID Controller 模拟。

简而言之,有一个目标值和一个当前值。当前值由数字修改。您向 PID Controller 提供当前值,它会尝试返回一个数字,希望该数字会使当前值接近目标值。随着时间的推移,您使用 PID Controller 的次数越多,它就会“学习”(使用积分和微分),最终会返回越来越准确的值。例如,这对于通过控制轮子运动来保持船的平衡很有用。


PID Controller 使用的公式非常通用且非常简单 - 至少我是这么认为的。在下面的示例中,PID Controller 返回的值只是简单地添加到当前值。我假设它适用于更复杂的应用程序(涉及乘法或除法等)。这是我的程序:

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 Controller 最终设法使当前值非常非常接近目标值。

这很酷。现在,我想更快地看到我的结果(因为我打算制作某种交互式图表),所以我决定将增量 dt 更改为 0.1

唉,结果值不再接近 100!现在它似乎达到 105,然后非常缓慢地减少到 100。这不好!

现在想象 dt0.01!现在达到102特别慢,现在连100都回不去了,一直在增加!

所以我的问题是:为什么较低的增量会导致这种情况?

我的代码基于 this PDF document他们使用 0.01 就好了。

最佳答案

这很容易,您将得到一个积分结束。

看,“积分”在增长中不受限制,但您将输出的影响限制在 [-5, 5] 范围内

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

通过该修复,循环时间为 0.5、0.1 和 0.01(但也限制导数)时,不会出现大于数字的超调

限制导数可以通过使用用于防止“导数踢”的相同技巧来修复:使用先例值和实际值之间的差异而不是错误之间的差异。只是注意你还需要反转符号

但是如果你需要尽可能快地模拟一个具有任意值的dt的PID,只需注释掉sleep即可!

关于java - 为什么较低的 delta 会导致我的 PID Controller 调整精度较低?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33726694/

相关文章:

java - 使用数据库中的信息作为变量值

java - 使用 Amazon Athena 从 S3 读取多个 json 文件

c++ - 具有共享边界的最小连接区域的图论算法

c++ - 如何用循环编写这个递归

algorithm - 计算每个点的最远点

java - 如何提取字母数字字符串中的前四位连续数字?

java - 保持类独立性或避免类型检查

java - 无法调用网络服务

javascript - 寻找一种迭代具有此约束的项目的算法

c++ - 最长公共(public)连续子序列 - 算法