#include "pid.h"
/**************************************************************************
函数功能:位置式PID控制器
pwm+=Kp[e(k)+Ki*e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
position type
**************************************************************************/
float Position_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint, float dt)
{
vPID->Kp = 1.0; // 比例增益
vPID->Ki = 0.1; // 积分增益
vPID->Kd = 0.05; // 微分增益
// 计算误差
vPID->error = setpoint - feedbackpoint;
// 计算误差的积分
vPID->integral += vPID->error * dt;
// 计算误差的微分
vPID->derivative = (vPID->error - vPID->previous_error) / dt;
// 计算控制信号
vPID->control_output = vPID->Kp * vPID->error + vPID->Ki * vPID->integral + vPID->Kd * vPID->derivative;
// 更新上一次的误差
vPID->previous_error = vPID->error;
return vPID->control_output;
}
/**************************************************************************
函数功能:增量PI控制器
根据增量式离散PID公式
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
**************************************************************************/
float Incremental_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint)
{
vPID->Kp = 0.1; // 比例增益
vPID->Ki = 1; // 积分增益
vPID->Kd = 0.00; // 微分增益
// 计算误差
vPID->error = setpoint - feedbackpoint;
// 计算控制信号
vPID->control_output = vPID->Kp * (vPID->error-vPID->next_error) + vPID->Ki * vPID->error + vPID->Kd * (vPID->error-2*vPID->next_error+ vPID->previous_error);
// 更新上一次的误差
vPID->previous_error = vPID->next_error;
vPID->next_error= vPID->error;
return vPID->control_output;
}
//在普通PID控制中,引入积分环节的目的,主要是为了消除静差,提高控制精度。
//但是在启动、结束或大幅度增减设定时,短时间内系统输出有很大的偏差,
//会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范围对应极限控制量,
//从而引起较大的超调,甚至是震荡,这是绝对不允许的。
//为了克服这一问题,引入积分分离PID控制,其基本思路是:
//当被控量与设定值偏差较大时,取消积分作用;
//当被控量接近给定值时,引入积分控制,以消除静差,提高精度。其具体实现代码如下:
/**************************************************************************
函数功能:位置式积分分离PID控制器
pwm+=Kp[e(k)+Ki*(0?1)e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
position type
**************************************************************************/
float Integral_separation_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint, float dt)
{
vPID->Kp = 0.4; // 比例增益
vPID->Ki = 0.1; // 积分增益
vPID->Kd = 0.2; // 微分增益
// 计算误差
vPID->error = setpoint - feedbackpoint;
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
vPID->integral += vPID->error * dt;
}
// 计算误差的微分
vPID->derivative = (vPID->error - vPID->previous_error) / dt;
// 计算控制信号
vPID->control_output = vPID->Kp * vPID->error + vPID->index * vPID->Ki * vPID->integral + vPID->Kd * vPID->derivative;
// 更新上一次的误差
vPID->previous_error = vPID->error;
return vPID->control_output;
}
//所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,
//若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区。
//一旦系统出现反向偏差,u(k)逐渐从饱和区退出。进入饱和区越深则退出饱和区时间越长。
//在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应的改变,这时系统就像失控一样,造成控制性能恶化,这种现象就是积分饱和现象或积分失控现象。
//防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已经超出了极限范围:
// 如果u(k-1)>umax,则只累加负偏差; 如果u(k-1)<umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。
/**************************************************************************
函数功能:位置式抗积分饱和PID控制器
pwm+=Kp[e(k)+Ki*(0?1)e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
position type
**************************************************************************/
float Anti_integral_saturation_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint, float dt)
{
vPID->Kp = 1; // 比例增益
vPID->Ki = 0.1; // 积分增益
vPID->Kd = 0.2; // 微分增益
vPID->umax = 400;
vPID->umin =-200;
// 计算误差
vPID->error = setpoint - feedbackpoint;
if(feedbackpoint > vPID->umax)
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
if(vPID->error < 0)
{
vPID->integral += vPID->error * dt;
}
}
}
else if(feedbackpoint < vPID->umin)
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
if(vPID->error < 0)
{
vPID->integral += vPID->error * dt;
}
}
}
else
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
vPID->integral += vPID->error * dt;
}
}
// 计算误差的微分
vPID->derivative = (vPID->error - vPID->previous_error) / dt;
// 计算控制信号
vPID->control_output = vPID->Kp * vPID->error + vPID->index * vPID->Ki * vPID->integral + vPID->Kd * vPID->derivative;
// 更新上一次的误差
vPID->previous_error = vPID->error;
return vPID->control_output;
}
//作为PID控制律的积分项,其作用是消除余差,为了尽量减小余差,应提高积分项运算精度
/**************************************************************************
函数功能:位置式梯形积分PID控制器
pwm+=Kp[e(k)+Ki*(0?1)e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
position type
**************************************************************************/
float Trapezoidal_integral_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint, float dt)
{
vPID->Kp = 1; // 比例增益
vPID->Ki = 0.1; // 积分增益
vPID->Kd = 0.2; // 微分增益
vPID->umax = 400;
vPID->umin =-200;
// 计算误差
vPID->error = setpoint - feedbackpoint;
if(feedbackpoint > vPID->umax)
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
if(vPID->error < 0)
{
vPID->integral += vPID->error * dt;
}
}
}
else if(feedbackpoint < vPID->umin)
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
if(vPID->error < 0)
{
vPID->integral += vPID->error * dt;
}
}
}
else
{
if(abs(vPID->error) > 200)
{
vPID->index=0;
}
else
{
vPID->index=1;
// 计算误差的积分
vPID->integral += vPID->error * dt;
}
}
// 计算误差的微分
vPID->derivative = (vPID->error - vPID->previous_error) / dt;
// 计算控制信号
vPID->control_output = vPID->Kp * vPID->error + vPID->index * vPID->Ki * vPID->integral / 2 + vPID->Kd * vPID->derivative;
// 更新上一次的误差
vPID->previous_error = vPID->error;
return vPID->control_output;
}
/**************************************************************************
函数功能:位置式变积分PID控制器
pwm+=Kp[e(k)+Ki*(0?1)e(k)+Kd[e(k)-e(k-1)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此类推
position type
**************************************************************************/
float Variational_integral_PID_Controller(PIDTypedef *vPID,float setpoint, float feedbackpoint, float dt)
{
vPID->Kp = 0.4; // 比例增益
vPID->Ki = 0.1; // 积分增益
vPID->Kd = 0.2; // 微分增益
// 计算误差
vPID->error = setpoint - feedbackpoint;
i
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
pid.zip (9个子文件)
pid.h 1KB
pid.exe 133KB
pid.c 8KB
pid.layout 223B
pid.o 4KB
Makefile.win 1KB
main.o 2KB
pid.dev 1KB
main.c 3KB
共 9 条
- 1
资源评论
Kisorge
- 粉丝: 1w+
- 资源: 78
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功