使用MATLAB进行步进电机PID仿真

@fsw  June 12, 2019

之前设计的系统是一个开环的控制系统,比较简单,但是存在失步等情况。所以需要用闭环的方式控制步进电机,以提高电机运行时的位置精度,然后再加上PID算法,可以更加稳定高效精准的控制电机位置。想要实现闭环控制就要在步进电机上面加上能够反馈信息的编码器,编码器能够将角位移或角速度转换成数字脉冲,通过编码器测量出位移或者速度。把STM32的GPIO口设置为输入模式接收编码器的脉冲信号,通过输入电平变化可以确定电机正反转、速度等信息。

PID即比例(Proportion)、积分(Integral)、微分(Derivative),PID控制是应用非常广泛的控制算法,小到控制一个元件的温度,大到控制飞行器的飞行姿态与速度。

比例调节作用:比例调节即调节放大倍数,系数大可加快调节减少误差,但是过大的比例也可能使系统的稳定性下降,比例系数反映了系统当前最基本的误差;

积分调节作用:积分控制的作用就是对输入偏差进行积分运算,消除系统的余差,输出与输入偏差的积分成正比关系,只要偏差存在,积分就会起作用,直到没有偏差时才会停止,积分系数反映了系统的累计误差;

微分调节作用:微分控制就是对输入偏差进行微分运算,输出与输入误差信号的微分成正比关系,微分时间越长输出变化越大,如果微分作用过强则可能引起震荡。微分系数反映了系统误差变化率,居于预见性,可以预见偏差变化趋势,产生超前控制效果。

PIDkdtu.png

(偷了个懒,不会用MarkDown写公式,就直接复制过来了...)
PID控制系统的输出e(t)与输入u(t)关系式为:

u(t)=k_p e((t)+1/T ∫_0^t▒e(t)dt+T_D de(t)/dt)

其传递函数为:

G(s)=(U(s))/(E(s))=k_p (1+1/(T_1 s) T_D s)

数字PID有位置型和增量型控制算法,驱动步进电机需要控制量的增量,所以应该采用增量式PID控制。根据递推原理可得:

u(k-1)=k_p (e(k-1)+k_i ∑_(j=0)^k▒e(j) +k_d (e(k)-e(k-1)))

增量式PID算法:

Δu(k)=u(k)-u(k-1)
Δu(k)=k_p (e(k)-e(k-1))+k_i e(k)+k_d (e(k)-2e(k-1)+e(k-2))

根据增量式PID控制算法,设计PID仿真程序,建立两相式混合步进电机数学模型:

G(s)=(Z_r^2 Li_A^2)/(2Js^2+2Bs+Z_r^2 Li_A^2 )

Z_r为每个转子级齿数,L为A、B的自感,i_A为电机两相电流,J为转动惯量,B为制动阻尼常数[17]。
步进电机输入的是一个阶跃电压,对应电机转过一个步距角,即输入。
根据电机各项参数(具体查阅自己点击的参数),L取值0.01,Z_r=40,J=1.08, i_A=1.0,B=3.1。被控对象如下:

G(s)=7.42/(s^2+2.87s+7.42)

使用SIMULINK模块进行仿真

下面是仿真模块图

PIDsimulink.png

为了限制高频增益及噪声等干扰,会加入一个Saturation模块,限制饱和度的上限与下限,假如输入的信号超过了设定的范围,那么会被自动限制到范围内。

利用PID算法实现步进电机的精准定位,实际上是控制步进电机的旋转角度的精度。由于不同的输入信号对应的Kp、Ki、Kd整定参数会不一样,所以这里选取移动距离最大1000mm和最小10mm两个值进行研究。假设电机上齿轮的直径d为40mm,电机位移的距离s与电机所需旋转角度θ关系式为:
θ=360s/πd=9s/π
当s为最大值1000mm时,输入信号θ=2864.7890°。当s最小值为10mm时,输入信号θ=28.6479°。对PID参数进行整定,Kp=100,Ki=2,Kd=6得到如下波形。
(波形图就不放了)

使用代码进行仿真

创建一个m脚本文件使用代码进行仿真,具体就不多说了,参考这篇文章https://blog.csdn.net/weixin_44044411/article/details/85891109

%Increment PID Controller 
%增量式PID控制算法中不需要累加,控制增量u(k)仅与最近k次的采样有关,所以误动作影响小。
%(输入分别为单位阶跃、正弦信号,采样时间为1ms,控制器输出限幅:[-5,5], 
clc;
clear;
%根据系统的传递函数被要求
%设一被控对象G(s)=7.42/(s^2+2.84s+7.42),
ts=0.001;%设置采样周期
sys=tf(7.42,[1,2.87,7.42]);%被控对象的传递函数,用来实现G(s)
dsys=c2d(sys,ts,'z');%把被控对象离散化,转换为拆分方程
[num,den]=tfdata(dsys,'v');%离散化后提取分子分母,提取拆分方程系数
%设置初始输入值
u_1=0.0;u_2=0.0;
y_1=0.0;y_2=0.0;
x=[0,0,0]';
error_1=0;
error_2=0;
%开始循环采样,用PID控制算法
for k=1:1:10000
   time(k)=k*ts;%采样次数
   rin(k)=36;%设置跟踪函数(阶跃函数)
   kp=100;
   ki=1;
   kd=0;
   du(k)=kp*x(1)+kd*x(2)+ki*x(3); 
   u(k)=u_1+du(k);
  if u(k)>=10 %输出限幅
     u(k)=10;
  end
   if u(k)<=-10
     u(k)=-10;
   end   
   yout(k)=-den(2)*y_1-den(3)*y_2+num(2)*u_1+num(3)*u_2;%实际输出 num为dsys分子多项式系数,den为dsys分母 
   多项式系数,从n阶定常离散系统差分方程变化来的。
   error(k)=rin(k)-yout(k);%误差 输入-输出
   %参数会随着循环变化而变化
   u_2=u_1;u_1=u(k);%保存上次输入、控制系数,为下次计算
   y_2=y_1;y_1=yout(k);%保存上次输入、控制系数,为下次计算
   x(1)=error(k)-error_1;             %Calculating P
   x(2)=error(k)-2*error_1+error_2;   %Calculating D
   x(3)=error(k);                     %Calculating I
   error_2=error_1;
   error_1=error(k);
end
figure(1);
plot(time,rin,'b',time,yout,'r');%输入和实际控制输出
xlabel('time(s)');ylabel('rin,yout');
%subplot(1,2,2),plot(a,pwm,'g');%输入和实际控制输出
%figure(2);
%plot(time,error,'r',time,pwm,'b');
%xlable('time(s)');ylable('error');
阅读量:162

添加新评论