#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
Kisorge
- 粉丝: 1w+
- 资源: 81
最新资源
- MATLAB中的出版物质量图.zip
- MATLAB中基于java实现的YAML IO支持.zip
- MATLAB中用于HODLR和HSS矩阵的工具箱.zip
- MATLAB中的图论网络分析工具包.zip
- MBeautifier是一个MATLAB源代码格式化美化器,它可以直接在MATLAB编辑器中使用,并且是可配置的.zip
- MESH2D是一个基于matlab的二维几何图形的Delaunay网格生成器.zip
- MATLAB自动微分包.zip
- Microstate EEGlab工具箱.zip
- MIMOOFDM无线通信技术及MATLAB实现随书源码.zip
- MOPSO及pso可编译运行matlab源码及相关论文资源.zip
- NSGA2 MATLAB代码.zip
- OctaveMatlab程序用于处理和绘制2D和3D探地雷达数据.zip
- python基于django的图书推荐系统源码(高分毕设).zip
- NaveGo是一个开源的MATLABGNU Octave工具箱,用于处理集成导航系统和执行惯性传感器分析.zip
- Opticka是建立在MATLAB心理物理学工具箱PTB之上的实验管理器,它使用灵活的状态机逻辑运行实验任务,并且可以.zip
- OpenSIM matlab代码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈