PID 基础公式及程序

仅用于备份本人所写笔记,如有错误或不完善之处还请包含。转载请注明出处!

一、位置式离散 PID#

  • Pwm=Kp×e(k)+Ki×e(k)+Kd×[e(k)e(k1)]
  • e(k) : 本次偏差
  • e(k1) : 上次偏差
  • e(k) : e(k) 以及之前的偏差的累计和,其中 k1,2,3k
  • Pwm : 代表输出

C 语言的实现:

// 位置式离散 PID
// P = Kp * err;
// I = Ki * integral_err;
// D = Kd * (err - last_err);
// Pwm = P + I + D;
float PositionPid(int encoder, int target) {
    static float err = 0, last_err = 0, integral_err = 0, pwm = 0;
    float kp = 1, ki = 1, kd = 1;

    err = encoder - target;  // 计算偏差
    integral_err += err;  // 求出偏差积分
    pwm = kp * err + ki * integral_err + kd * (err - last_err);
    last_err = err;  // 保存上一次偏差

    return pwm;  // 输出
}

在舵机角度控制闭环系统里,只使用 PD 控制,因此可将 PID 控制简化为此公式:

Pwm=Kp×e(k)+Kd×[e(k)e(k1)]

代码更改如下:

// 位置式离散 PD
// P = Kp * err;
// D = Kd * (err - last_err);
// Pwm = P + D;
float PositionPid(int encoder, int target) {
    static float err = 0, last_err = 0, integral_err = 0, pwm = 0;
    float kp = 1, ki = 1, kd = 1;

    err = encoder - target;  // 计算偏差
    pwm = kp * err + kd * (err - last_err);
    last_err = err;  // 保存上一次偏差

    return pwm;  // 输出
}

PID 参数整定:

  • P:用于提高相应速度
  • I:用于减小静差
  • D:用于抑制震荡

二、增量式离散 PID#

  • Pwm+=Kp×[e(k)e(k1)]+Ki×e(k)+Kd×[e(k)2e(k1)+e(k2)]
  • e(k) : 本次偏差
  • e(k1) : 上次的偏差
  • e(k2) : 上上次的偏差
  • Pwm : 代表增量输出

C 语言实现:

// 增量式离散 PID
// P = Kp * (err - last_err);
// I = Ki * err;
// D = Kd * (err - 2 * last_err + before_err);
// Pwm += P + I + D;
float IncrementalPid(int encoder, int target) {
    static float err = 0, last_err = 0, before_err = 0, pwm = 0;
    float kp = 1, ki = 1, kd = 1;

    err = encoder - target;  // 计算偏差
    pwm += kp * (err - last_err) + ki * err +
          kd * (err - 2 * last_err + before_err);  // 增量式 PI 控制器
    before_err = last_err;  // 保存上上次偏差
    last_err = err;  // 保存上一次偏差

    return pwm;  // 增量输出
}

在速度控制闭环系统里,只使用 PI 控制,因此可将 PID 控制简化为此公式:

Pwm+=Kp×[e(k)e(k1)]+Ki×e(k)

代码更改如下:

// 增量式离散 PI
// P = Kp * (err - last_err);
// I = Ki * err;
// Pwm += P + I;
float IncrementalPid(int encoder, int target) {
    static float err = 0, last_err = 0, pwm = 0;
    float kp = 1, ki = 1, kd = 1;

    err = encoder - target;  // 计算偏差
    pwm += kp * (err - last_err) + ki * err;  // 增量式 PI 控制器
    last_err = err;  // 保存上一次偏差

    return pwm;  // 增量输出
}

作者:xiaoaug

出处:https://www.cnblogs.com/xiaoaug/p/12209817.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   滑稽果  阅读(4331)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
浏览器标题切换
浏览器标题切换end
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示