PID算法C语言实现

PID算法增量式与位置式C语言实现


【头文件】

#ifndef PID_H_
#define PID_H_

typedef struct
{
    float kp;           // 比例系数
    float ki;           // 积分系数
    float kd;           // 微分系数
    float err_last;     // 上次误差
    float err_sum;      // 误差累计
    float result;
}pid_pos_typedef;
void pid_pos_init(pid_pos_typedef* pid, float kp, float ki, float kd);
float pid_pos_calc(pid_pos_typedef* pid, float currVal, float objVal);


typedef struct
{
    float kp;           // 比例系数
    float ki;           // 积分系数
    float kd;           // 微分系数
    float err_last;     // 上一次的误差
    float err_pree;     // 上二次的误差
    float result;
}pid_delta_typedef;
void pid_delta_init(pid_delta_typedef* pid, float kp, float ki, float kd);
float pid_delta_calc(pid_delta_typedef* pid, float currVal, float objVal);

#endif /* PID_H_ */

【源文件】

//
// Created by Administrator on 2019/10/24 0024.
//

#include "pid.h"

// 位置式pid算法初始化
void pid_pos_init(pid_pos_typedef* pid, float kp, float ki, float kd)
{
    pid->kp = kp;
    pid->ki = ki;
    pid->kd = kd;
    pid->result = 0;
    pid->err_last = 0;
    pid->err_sum = 0;
}

// 位置式pid算法计算
float pid_pos_calc(pid_pos_typedef* pid, float currVal, float objVal)
{
    float err_c = objVal - currVal;       // 当前误差
    pid->err_sum += err_c;                  // 误差累计
    pid->result = pid->kp * err_c + pid->ki * pid->err_sum + pid->kd * (err_c - pid->err_last);
    pid->err_last = err_c;
    return pid->result;
}

// 增量式pid算法初始化
void pid_delta_init(pid_delta_typedef* pid, float kp, float ki, float kd)
{
    pid->kp = kp;
    pid->ki = ki;
    pid->kd = kd;
    pid->result = 0;
    pid->err_last = 0;
    pid->err_pree = 0;
}

// 增量式算法计算
float pid_delta_calc(pid_delta_typedef* pid, float currVal, float objVal)
{
    float err_c;            // 当前误差
    float err_p;            // p误差
    float err_i;            // i误差
    float err_d;            // d误差
    float increment;        // 增量

    err_c = objVal - currVal;
    err_p = err_c - pid->err_last;
    err_i = err_c;
    err_d = err_c - 2 * pid->err_last + pid->err_pree;
    increment = pid->kp * err_p + pid->ki * err_i + pid->kd * err_d;

    pid->err_pree = pid->err_last;
    pid->err_last = err_c;
    pid->result += increment;
    return pid->result;
}



测试

int main(void)
{
	uint32_t i = 0;
	float currVal = 0;				// 当前值
	float objVal = 10;				// 目标值
	pid_delta_typedef pid_delta;
	pid_delta_init(&pid_delta, 0.2, 0.001, 0.0001);

	while(1)
	{
		i++;
		currVal = pid_delta_calc(&pid_delta, currVal, objVal);
		printf("[%d]    currVal:%f \n", i, currVal);

		if(currVal >= 9.999)
			break;
	}

	printf("------ end. \n");
	return 0;
}

在这里插入图片描述


Python版增量式PID

from matplotlib import pyplot as plt


class PID:
    __err_last = 0.0
    __err_pree = 0.0
    __ki = 0.0
    __kp = 0.0
    __kd = 0.0
    __result = 0.0

    def __init__(self, ki, kp, kd):
        self.__ki = ki
        self.__kp = kp
        self.__kd = kd

    def calc(self, objVal, currVal):
        err_c = objVal - currVal
        err_p = err_c - self.__err_last
        err_i = err_c
        err_d = err_c - 2 * self.__err_last + self.__err_pree
        increment = self.__kp * err_p + self.__ki * err_i + self.__kd * err_d

        self.__err_pree = self.__err_last
        self.__err_last = err_c
        self.__result += increment
        return self.__result

    def setKP(self, kp):
        self.__kp = kp

    def setKI(self, ki):
        self.__ki = ki

    def setKD(self, kd):
        self.__kd = kd


if __name__ == '__main__':
    index = 0
    currval = 0.0

    pid = PID(0.2, 0.001, 0.0001)

    array = []
    array.append(currval)

    while True:
        if currval >= 99.999:
            break
        index += 1
        currval = pid.calc(100, currval)
        array.append(currval)
        print("[%d]    curr:%f      " % (index, currval))

    plt.figure()
    plt.xlabel('count')
    plt.ylabel('value')
    plt.plot(array)
    plt.show()

从0到100实验效果:
在这里插入图片描述


Python版位置式PID

from matplotlib import pyplot as plt


class PID:
    __err_last = 0.0
    __err_sum = 0.0
    __ki = 0.0
    __kp = 0.0
    __kd = 0.0

    def __init__(self, ki, kp, kd):
        self.__ki = ki
        self.__kp = kp
        self.__kd = kd

    def calc(self, objVal, currVal):
        err = objVal - currVal
        self.__err_sum += err
        result = self.__kp * err + self.__ki * self.__err_sum + self.__kd * (err - self.__err_last)
        self.__err_last = err
        return result

    def setKP(self, kp):
        self.__kp = kp

    def setKI(self, ki):
        self.__ki = ki

    def setKD(self, kd):
        self.__kd = kd


if __name__ == '__main__':
    index = 0
    currval = 0.0

    pid = PID(0.2, 0.001, 0.0001)

    array = []
    array.append(currval)

    while True:
        if currval >= 99.999:
            break

        index += 1
        currval = pid.calc(100, currval)
        array.append(currval)
        print("[%d]    curr:%f      " % (index, currval))

    plt.figure()
    plt.xlabel('count')
    plt.ylabel('value')
    plt.plot(array)
    plt.show()

从0加到100实验效果:
在这里插入图片描述


ends…

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 模糊PID算法是一种基于模糊控制原理的PID优化控制算法,它利用模糊逻辑对PID参数进行调整,以提高系统的控制性能。C语言实现模糊PID算法需要定义模糊变量,定义模糊规则,定义模糊控制输出,以及定义控制器的控制策略等。 ### 回答2: 模糊PID算法是一种应用于控制系统的调节算法,用于自动化系统的控制和调节。它是在传统PID(比例-积分-微分)控制算法的基础上引入了模糊逻辑的概念,以便更好地应对非线性、时变的系统。 模糊PID算法实现过程主要包括以下几个步骤: 1. 确定模糊规则库:首先需要确定系统的输入和输出变量,并将其进行模糊化处理,将连续的输入和输出转化为模糊集合,如“大、中、小”等。然后,根据经验和专家知识,建立模糊规则库,即描述输入和输出之间的关系。 2. 模糊推理:将输入变量和模糊规则库进行匹配,通过使用模糊逻辑运算,计算出模糊输出。 3. 解模糊化:将模糊输出转化为具体的数值,以便后续的控制操作。 4. PID控制:将解模糊化后的输出与实际输出进行比较,计算出PID控制器的输出。其中,比例控制项与模糊输出成正比,积分控制项与过去的误差累积成正比,微分控制项与误差的变化速度成正比。将PID控制器的输出作为控制系统的控制信号,进行系统的控制和调节。 模糊PID算法实现可以使用C语言进行编程。首先需要定义输入和输出的模糊集合,并实现模糊化和解模糊化的函数。然后,根据专家经验和知识,建立模糊规则库,并通过模糊推理的方法计算出模糊输出。最后,根据PID控制的原理,结合模糊输出和实际输出,计算PID控制器的输出值,并实施系统的控制和调节。 总之,模糊PID算法是一种利用模糊逻辑的方法来实现控制系统自动调节的算法。通过合理地定义模糊集合、建立模糊规则库和采用模糊推理方法,可以有效地应对复杂的非线性、时变系统。而在C语言实现模糊PID算法,则需要考虑输入输出的模糊化与解模糊化方法,以及模糊推理和PID控制的具体实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觉皇嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值