【问题标题】:How do I use a PID controller?如何使用 PID 控制器?
【发布时间】:2013-01-30 21:27:41
【问题描述】:

我目前正在研究温度控制器。

我有一个 Temperature_PID() 函数,它返回操纵变量(这是 P、I 和 D 项的总和),但我该如何处理这个输出?

温度由 PWM 控制,因此 0% 占空比 = 加热器关闭,100% 占空比 = 加热器开启。

到目前为止我尝试过

Duty_Cycle += Temperature_PID();
if(Duty_Cycle > 100) Duty_Cycle = 100;
else if(Duty_Cycle < 0) Duty_Cycle = 0;

这对我不起作用,因为 I 术语基本上使这个系统非常不稳定。想象一下整合一个区域,添加另一个小数据点,然后再次整合该区域,然后将它们相加。一遍又一遍。这意味着每个数据点都会使这种控制方案成倍恶化。

我想尝试的另一件事是

Duty_Cycle = Expected_Duty_Cycle + Temperature_PID();

其中 Expected_Duty_Cycle 是控制器达到稳定点且 Temperature_PID() 为 0 时应设置的温度。但是,这也不起作用,因为 Expected_Duty_Cycle 总是会根据加热器的条件而变化,例如不同的天气。

所以我的问题是我究竟如何处理 PID 的输出?我不明白如何根据 PID 输出分配占空比。理想情况下,这将保持 100% 的占空比,直到温度几乎达到设定点并开始下降到较低的占空比。但是使用我的第一种方法(我的增益设置为零)它只会在它已经过冲之后才开始降低占空比。

这是我的第一篇文章。希望我能找到我的答案。谢谢stackoverflow。

编辑: 这是我的 PID 函数。

double TempCtrl_PID(PID_Data *pid)
{
    Thermo_Data tc;
    double error, pTerm, iTerm, dTerm;

    Thermo_Read(CHIP_TC1, &tc);

    pid->last_pv = pid->pv;
    pid->pv = Thermo_Temperature(&tc);
    error = pid->sp - pid->pv;
    if(error/pid->sp < 0.1)
        pid->err_sum += error;

    pTerm = pid->kp * error;
    iTerm = pid->ki * pid->err_sum;
    dTerm = pid->kd * (pid->last_pv - pid->pv);

    return pTerm + iTerm + dTerm;
}

编辑 2: 以前从来没有用过这个,所以如果链接坏了,请告诉我。 https://picasaweb.google.com/113881440334423462633/January302013

抱歉,当我尝试重命名坐标轴或标题时,Excel 崩溃了。注意:系统中还没有风扇,所以我不能尽可能快地冷却加热器,所以与上面相比,它在设定点以下花费的时间很少。 第一张图是一个简单的开关控制器。 第二张图是我的 PD 控制器。正如您所看到的,温度降低需要更长的时间,因为它不会在温度过冲之前减去,它会等到温度过冲后再从占空比中减去,而且这样做太慢了。我该如何告诉我的控制器在达到最高温度之前降低占空比?

【问题讨论】:

  • 欢迎来到 Stack Overflow。很好的第一个问题 (+1)。
  • 所以情况有点复杂。您需要阅读 PID (en.wikipedia.org/wiki/PID_controller)。它是一个反馈回路控制系统。您需要做的是更改占空比,读取实际温度(在该 wiki 文章中称为 PV),将误差计算为目标温度(在 wiki 文章中的 SP)与实际温度之间的差异,然后反馈错误进入PID控制器。请注意,您可以调整参数以根据时间更改 PV 的行为 (en.wikipedia.org/wiki/File:Change_with_Kp.png)。
  • 我想你应该减去输出,因为模型通常包含负反馈。也就是说,如果不了解有关您的系统和代码的更多详细信息,就很难确定。
  • 这就是问题所在。这取决于您的 pid 中实现了什么,但输出实际上应该是 占空比。

标签: c pid-controller


【解决方案1】:

PID的输出占空比。您必须调整 kpkikd 以将 PID 输出置于 Duty_Cycle 的范围内,例如 0 到 100。通常最好在 PID 函数中明确限制输出自己。

您应该通过简单的步骤“调整”您的 PID。

  1. 关闭积分和导数项(将kikd 设置为零)

  2. 慢慢增加您的kp,直到设定点的 10% 阶跃变化使输出振荡

  3. kp 减少 30% 左右,这应该可以消除振荡

  4. ki 设置为kp 的一小部分,并进行调整以在过冲与达到设定点的时间之间取得理想的平衡

  5. 希望你不需要kd,但如果你需要,请让它更小

【讨论】:

  • 哦。好的。你的第一句话解释了一切。这更有意义。谢谢。我将 PID 输出的增益设置为简单的小部分,所以我认为如果我将它们相加,将它们相加以获得占空比是有意义的。我猜我搞砸了哈哈。
【解决方案2】:

您的 PID 控制器输出应该直接设置占空比的值。

基本上,您将根据实际温度与温度设定点的差异来控制加热器设置。

您需要调整 PID 参数的值以获得所需的性能。

首先,将 I 和 D 设置为零,并为 P 输入一个值,例如从 2 开始。

更改设定值,看看您的反应是什么。增加 P 并进行另一个设定值更改,看看会发生什么。最终,您将看到温度持续波动并且永远不会达到任何稳定值。这个值被称为“终极增益”。还要注意振荡的频率。设置 P 等于最终增益的一半。

从 I 的值 1.2(最终增益)/(振荡频率)开始并更改设定值。根据这些值调整 P 和 I 的值以到达您想去的地方,跟踪过程并查看增加或减少值是否会改善事情。

一旦你有了 P 和 I,你就可以在 D 上工作,但取决于过程动态,为 D 赋值可能会让你的生活变得更糟。

The Ziegler-Nichols method 为您提供了一些关于 PID 值的指导方针,这些指导方针应该能让您大致了解。从那里您可以进行调整以获得更好的性能。

您必须权衡过冲选项和温度达到新设定点所需的时间。温度调节得越快,您的过冲就越多。没有超调会大大增加时间。

【讨论】:

  • 谢谢!我猜道格早一点回答了我的问题,所以我投了他最好的票,但仍然支持你。我会记住这一点以进行调整。我绝对想尽量减少过冲,因为没有风扇的当前系统根本无法快速冷却,这意味着最大限度地减少过冲肯定会更快地稳定下来。
  • 不用担心,很乐意为您提供帮助。它基本上归结为反复试验,但上面的链接中有很多不同的方法可以为您提供从哪里开始的指导。
【解决方案3】:

一些建议:

  • 您似乎集成了两次。一次进入你的TempCtrl_PID 函数,一次在外面。 Duty_Cycle += 。所以现在你的 P 词真的是 I。
  • 仅从 P 项开始并不断增加它,直到系统变得不稳定。然后后退(例如,使用 1/2 到 1/4 变得不稳定的值)并开始添加 I 项。从 I 项的非常低的值开始,然后逐渐增加。这个过程是调整循环的一种方式。因为系统可能会有相当长的时间常数,所以这可能很耗时...
  • 您可以按照您的建议添加一些前馈(给定设定点的预期占空比 - 通过设置占空比并让系统稳定来映射它。)。该术语是否不完美并不重要,因为循环将消除剩余的错误。您也可以简单地为占空比添加一些恒定偏差。请记住,常数不会真正产生任何影响,因为积分器会将其取出。它只会影响冷启动。
  • 确保此循环有某种固定的时基。例如。每 10 毫秒进行一次调整。
  • 我暂时不用担心 D 术语。 PI 控制器应该足以满足大多数应用的需求。

【讨论】:

  • 我没想到你的第一颗子弹。这肯定是为什么我的 I 术语系统非常不稳定的原因。您没有回答我最初提出的问题,但我非常感谢您提供的调优建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
相关资源
最近更新 更多