打印
[开发资料]

C语言增量式PID通用算法

[复制链接]
1198|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Lovemcu2212|  楼主 | 2023-2-27 10:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
C语言增量式PID通用算法
控制算法中PID使用的非常广泛,但是在网上找代码的时候发现好多代码都不够通用,需要自己改好多东西,而且当一个项目需要使用多个PID控制器时也颇为麻烦,这里设计一个通用的增量式PID算法,可以直接使用,不用更改什么东西,顶多改一下初始化时候的几个参数限制范围。
该算法的思想是设计一个PID控制器类,使用的时候直接实例化一个PID对象即可,也可以实例化多个,每个都是独立的PID控制器。
该库留出来PID控制器的所用有接口,对于调试来说非常方便,不需要外部再定义一堆函数来调用。该库实现了PID参数设置与修改,控制器控制函数接口,可以说是十分方便易用,且完全做到了代码隔离。这其实是面向对象的思维模式,相当于实现一个PID控制的类以及方法,使用时只需使用该类来定义一个对象即可。


使用特权

评论回复
沙发
Lovemcu2212|  楼主 | 2023-2-27 10:53 | 只看该作者
头文件:
#ifndef _PID_H
#define _PID_H

typedef struct pid_structure {
    float kp, ki, kd;
    float kp_max, kp_min;
    float ki_max, ki_min;
    float kd_max, kd_min;
    float err_k, err_k1, err_k2;
    float u_k, u_k1;
    float delta_u_k;
} PidObj;

typedef enum {
    KP,
    KI,
    KD
} PidParam;

void pid_init(PidObj* obj,
              float kp, float ki, float kd,
              float kp_min, float kp_max,
              float ki_min, float ki_max,
              float kd_min, float kd_max);
void pid_set_param(PidObj* obj, float kp, float ki, float kd);
void pid_get_param(PidObj* obj, float* kp, float* ki, float* kd);
void pid_set_param_limit(PidObj* obj, PidParam param, float min, float max);
void pid_get_param_limit(PidObj* obj, PidParam param, float* min, float* max);
float pid_control(PidObj* obj, float err);

#endif

使用特权

评论回复
板凳
Lovemcu2212|  楼主 | 2023-2-27 10:54 | 只看该作者
C文件:
#include "./pid.h"

void pid_init(PidObj* obj,
              float kp, float ki, float kd,
              float kp_min, float kp_max,
              float ki_min, float ki_max,
              float kd_min, float kd_max)
{
    obj->delta_u_k  = 0.0f;
    obj->err_k2     = 0.0f;
    obj->err_k1     = 0.0f;
    obj->err_k      = 0.0f;
    obj->u_k1       = 0.0f;
    obj->u_k        = 0.0f;
    obj->kp         = kp;
    obj->ki         = ki;
    obj->kd         = kd;
    obj->kp_min     = kp_min;
    obj->kp_max     = kp_max;
    obj->ki_min     = ki_min;
    obj->ki_max     = ki_max;
    obj->kd_min     = kd_min;
    obj->kd_max     = kd_max;
}

void pid_set_param(PidObj *obj, float kp, float ki, float kd)
{
    obj->kp = (obj->kp_min == 0 && obj->kp_max == 0) ? kp : \
               ((kp > obj->kp_max) ? obj->kp_max : \
               ((kp < obj->kp_min) ? obj->kp_min : kp));

    obj->ki = (obj->ki_min == 0 && obj->ki_max == 0) ? ki : \
               ((ki > obj->ki_max) ? obj->ki_max : \
               ((ki < obj->ki_min) ? obj->ki_min : ki));

    obj->kd = (obj->kd_min == 0 && obj->kd_max == 0) ? kd : \
               ((kd > obj->kd_max) ? obj->kd_max : \
               ((kd < obj->kd_min) ? obj->kd_min : kd));
}

void pid_get_param(PidObj *obj, float *kp, float *ki, float *kd)
{
    *kp = obj->kp;
    *ki = obj->ki;
    *kd = obj->kd;
}

void pid_set_param_limit(PidObj *obj, PidParam param, float min, float max)
{
    switch (param)
    {
    case KP:
        obj->kp_min = min;
        obj->kp_max = max;
        break;
    case KI:
        obj->ki_min = min;
        obj->ki_max = max;
        break;
    case KD:
        obj->kd_min = min;
        obj->kd_max = max;
        break;
    }
}

void pid_get_param_limit(PidObj *obj, PidParam param, float *min, float *max)
{
    switch (param)
    {
    case KP:
        *min = obj->kp_min;
        *max = obj->kp_max;
        break;
    case KI:
        *min = obj->ki_min;
        *max = obj->ki_max;
        break;
    case KD:
        *min = obj->kd_min;
        *max = obj->kd_max;
        break;
    }
}

float pid_control(PidObj *obj, float err)
{
    obj->err_k2 = obj->err_k1;
    obj->err_k1 = obj->err_k;
    obj->err_k = err;
    obj->u_k1 = obj->u_k;

    obj->delta_u_k = obj->kp * (obj->err_k - obj->err_k1) +
                     obj->ki * obj->err_k +
                     obj->kd * (obj->err_k - 2 * obj->err_k1 + obj->err_k2);

    obj->u_k = obj->u_k1 + obj->delta_u_k;
    return obj->u_k;
}

使用特权

评论回复
地板
hudi008| | 2023-3-10 17:21 | 只看该作者
求一下增量式和位置式PID的C语言程序

使用特权

评论回复
5
sheflynn| | 2023-3-10 17:29 | 只看该作者
PID控制的增量型公式是什么?              

使用特权

评论回复
6
1988020566| | 2023-3-10 17:41 | 只看该作者
直流电机控制用位置式还是增量式pid算法

使用特权

评论回复
7
youtome| | 2023-3-11 19:31 | 只看该作者
如何用c语言实现PID算法的参数计算

使用特权

评论回复
8
ccook11| | 2023-3-11 19:47 | 只看该作者
目前包含几种PID控制算**               

使用特权

评论回复
9
jackcat| | 2023-3-11 20:24 | 只看该作者
单片机PID控制PWM的算法如何实现,C语言计算?

使用特权

评论回复
10
jonas222| | 2023-3-11 20:57 | 只看该作者
模拟PID与数字位置型PID算法转换是否等效?

使用特权

评论回复
11
plsbackup| | 2023-3-11 21:04 | 只看该作者
增量式pid如何能防止积分饱和

使用特权

评论回复
12
backlugin| | 2023-3-11 21:10 | 只看该作者
C语言的PID(比例微分积分)算法,有范例么?

使用特权

评论回复
13
youtome| | 2023-3-11 21:18 | 只看该作者
pid算法的参数是怎么整定的              

使用特权

评论回复
14
everyrobin| | 2023-4-4 14:06 | 只看该作者
几种常用温控算法的比较与总结  

使用特权

评论回复
15
sdCAD| | 2023-4-4 14:13 | 只看该作者
如何求它的位置型和增量型PID算法输出表达式?

使用特权

评论回复
16
yorkbarney| | 2023-4-4 14:26 | 只看该作者
在PID控制中的p、i、d是如何计算的呢

使用特权

评论回复
17
saservice| | 2023-4-4 14:39 | 只看该作者
增量式pid如何能防止积分饱和

使用特权

评论回复
18
qiufengsd| | 2023-4-4 15:19 | 只看该作者
如何从理论上分析pid参数的物理意义  

使用特权

评论回复
19
everyrobin| | 2023-4-4 15:26 | 只看该作者
增量式PID算法能否用于力矩电机

使用特权

评论回复
20
albertaabbot| | 2023-4-4 15:49 | 只看该作者
PID控制的增量型公式是什么?   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

167

帖子

0

粉丝