simulink的背景资料百度百科是这么定义的:
simulink就是对一般的物理模型进行仿真的一个平台,和大部分的仿真软件不同的是:
1.simulink更容易和matlab实现交互,所以我们可以更加容易的修改simulink的参数,并且在.m文件中调用simulink仿真从而为我们的计算服务。
2.simulink比较强的一点在于它的覆盖面极广,支持我们科学领域几乎所有的基本单元的仿真。
不过呢,缺点也是十分明显的,那就是simulink建立模型得从最底层建立起来。尽管simulink也同样具备很多的专业子系统,比如说噪声处理系统。但是,在大多数的情况下,我们对simulink的仿真都是基于模型的可见性分析,也就是说我们对模型内部运行的机理得做到差不多完全了解才能分析仿真,也就是通常说的白箱模型。这也就决定了simulink建立的仿真可能会与实际的模型有一些偏差。所以,我们在这里研究的就是理想的伺服电机模型,具体的参PID参数的优化,我们得在实验中慢慢改进。
一般来说,我们现在研究的直流电机具有电机体积小,重量轻,出力大,响应快,速度高,惯量小,转动平滑,力矩稳定。容易实现智能化,其电子换相方式灵活,可以方波换相或正弦波换相。电机免维护不存在碳刷损耗的情况,效率很高,运行温度低噪音小,电磁辐射很小,长寿命,可用于各种环境的。
因此,直流无刷电机一直被广泛的应用于与单片机相关的硬件设计和驱动当中。可以做机械臂的转轴驱动,驱动机器人云台旋转等等。具体的样子就是下面所示:
基本上可以这样理解,伺服电机接收到1个脉冲,就会旋转1个脉冲对应的角度,从而实现位移。因为,伺服电机本身具备发出脉冲的功能,所以伺服电机每旋转一个角度,都会发出对应数量的脉冲,这样,和伺服电机接受的脉冲形成了呼应,或者叫闭环,如此一来,系统就会知道发了多少脉冲给伺服电机,同时又收了多少脉冲回来。这样,就能够很精确的控制电机的转动,从而实现精确的定位。而伺服电机的反馈机制主要是根据内部的测速系统实现的。具体的内容建议百度。
我们在这里的目的就是为了建立一个和电机工作原理相匹配,同时用外部的PID反馈环节对该电机的转速进行闭环调控从而实现精确控制转速的一个simulink优化模型,优化的对象是PID环节的参数。
直流伺服电机驱动是在电路两端加载电压,电路中的电流流过电感 L 产生磁场力,电机转轴在磁场力的作用下转动,其驱动原理图如下图所示:
规定如下:
L : 电 感 大 小 , E a : 电 动 机 反 电 动 势 θ : 电 动 机 轴 转 角 , B m : 机 械 时 间 常 数 K m : 电 气 时 间 常 数 , R : 电 机 电 枢 电 阻 T : 电 动 机 输 出 转 矩 , J : 电 动 机 输 出 惯 量 B : 电 动 机 阻 尼 系 数 L:电感大小,E_a:电动机反电动势\\ \theta:电动机轴转角,B_m:机械时间常数\\ K_m:电气时间常数,R:电机电枢电阻\\ T:电动机输出转矩,J:电动机输出惯量\\ B:电动机阻尼系数 L:电感大小,Ea:电动机反电动势θ:电动机轴转角,Bm:机械时间常数Km:电气时间常数,R:电机电枢电阻T:电动机输出转矩,J:电动机输出惯量B:电动机阻尼系数
现在,我们对伺服电机的左半部进行分析,由闭合电路的基尔霍夫定律,我们可以得到:
u = E a + R i + L d i d t u=E_a+Ri+L\frac{di}{dt} u=Ea+Ri+Ldtdi
同时该电机产生的反电动势与电机的转速成正比:
E a = k ϵ d θ d t E_a = k_{\epsilon}\frac{d\theta}{dt} Ea=kϵdtdθ
而且,我们知道电机的电磁转矩是与回路中的电流成正比的:
T = k t i T=k_ti T=kti
当电路达到稳定时候,电机的电磁转矩由转动定律可知:
T − B d θ d t = J d 2 θ d t 2 T-B\frac{d\theta}{dt}=J\frac{d^2\theta}{dt^2} T−Bdtdθ=Jdt2d2θ
我们工程上对下列参数有一个很具体的定义:
K m = K t R B m = B + K t K ϵ R K_m = \frac{K_t}{R}\\ B_m = B+\frac{K_tK_\epsilon}{R} Km=RKtBm=B+RKtKϵ
如果我们查表,我们机会发现工业上对具体的伺服电机的电气时间常数和机械时间常数都有说明。而在一般的伺服电机里面,电感同其他参数相比都是极小的,理想情况下,我们对它进行忽略掉。
经过对上面的式子整理,我们可以得到:
K m u = J d 2 θ d t 2 + B m d θ d t K_mu=J\frac{d^2\theta}{dt^2}+B_m\frac{d\theta}{dt} Kmu=Jdt2d2θ+Bmdtdθ
经过拉普拉斯变换我们可以得到伺服电机系统的传递函数为:
G 1 ( s ) = θ ( s ) u ( s ) = K m J s 2 + B m s G_1(s)=\frac{\theta(s)}{u(s)}=\frac{K_m}{Js^2+B_ms} G1(s)=u(s)θ(s)=Js2+BmsKm
简单的说,根据给定值和实际输出值构成控制偏差,将偏差按比例,积分和微分通过线性组合构成控制量,对被控对象进行控制。常规PID控制器作为一种线性控制器:
u ( t ) = K p ( e ( t ) + 1 T i ∫ 0 t e ( t ) d t + T d d e ( t ) d t ) G ( s ) = U ( s ) E ( s ) = K p ( 1 + 1 T i s + T d s ) = K p + K i 1 s + K d s u(t) = K_p(e(t)+\frac{1}{T_i}\int_0^te(t)dt+T_d\frac{de(t)}{dt})\\ G(s) = \frac{U(s)}{E(s)} = K_p(1+\frac{1}{T_is}+T_ds)=K_p+K_i\frac{1}{s}+K_ds u(t)=Kp(e(t)+Ti1∫0te(t)dt+Tddtde(t))G(s)=E(s)U(s)=Kp(1+Tis1+Tds)=Kp+Kis1+Kds
e ( t ) e(t) e(t):偏差, u ( t ) u(t) u(t):输出
我们要对这个电机执行如下操作:
当我们给控制单元(在本题中我们假设是stm32单片机)一个转动的理想角度时,这个控制单元能够将我们输入的理想角度转化成应该施加在伺服电机两端的电压值,假设这个转化是正比的,而且比例系数是K。那么在通过PID环节修正之后,我们的理想电压将会成为实际加载在伺服电机,也就是我们的被控对象两端的电压。此时电机将会输出一个角度,并且通过测量环节,例如电机自带的测量系统等将结果反馈到我们的比较环节,得到误差。周而往复,从而使得误差为0的时候,达到实际的输出环节就是我们想要的理想输出的效果.
而在这个过程当中,我们最为关心的是当稳态误差为0的时候,所经历的时间和总的误差之和。我们要让它达到最小,于是我们引入以下评判指标:
m i n k p , k i , k d I T A E = ∫ 0 ∞ t ∣ e ( t ) ∣ d t min_{k_p,k_i,k_d}ITAE = \int_0^{\infty}t|e(t)|dt minkp,ki,kdITAE=∫0∞t∣e(t)∣dt
在这里,我们假设转化系数K是10,如果读者想自行研究的话也可以设置一些其他的比例值:
G 2 ( s ) = u ( s ) θ i d e a l ( s ) = K G_2(s)=\frac{u(s)}{\theta_{ideal}(s)}=K G2(s)=θideal(s)u(s)=K
在用simulink求解时候记得修改如下参数,否则会报错:
将建立好的simulink文件命名为’sim2.slx’放入matlab路径下,便于后续用遗传算法工具箱优化参数。
先建立simulink文件的ITAE求解函数:
function value = PID_fun(x)
assignin('base','kp',x(1));
assignin('base','ki',x(2));
assignin('base','kd',x(3));
[t x_state,y_out] = sim('sim2.slx',[0 40]);
value = y_out(end,1);
end
再用matlab遗传算法工具箱求解:
clc,clear;
options = gaoptimset('PopulationSize',40,'Generations',10,'PlotFcns',@gaplotbestf);
[x fval] = ga(@PID_fun,3,[],[],[],[],[0 0 0],[300 300 300],[],options);
x,fval
求解出来的最合适的kp,ki,kd分别是:10.7712,280.1890,0;
经过遗传算法优化后得到的曲线如下:
按最优的参数调PID的话可以发现伺服电机响应的速度几乎就是在0.5s以内,最大超调量也不到25%。可以发现优化得到的效果也是非常好的。