重复控制器的传递函数
重复控制器(Repetitive Controller,RC)是一种基于“内模原理”(Internal Model Principle)设计的控制器,用于消除周期性参考信号或周期性扰动下的稳态误差。逆变器具有周期性参考信号的特征,采用重复控制器进行控制,可以获得更稳定的控制性能。
重复控制器的基本传递函数为:
\[G(z)=\frac{z^{-N}}{1-z^{-N}}\]
其中,\(N\) 表示在一个周期内的采样数。意思是采用一个重复周期之前的采样样本作为环路的反馈值进行计算。
通常,重复控制器更为实用的传递函数是:
\[G(z)=\frac{z^m Q(z) z^{-N}}{1-Q(z) z^{-N}}\]
其中,\(Q(z)\) 是一个低通滤波器,用于消减高频处的增益,增加相位裕量。\(z^m\) 是一个超前相位补偿器,\(m\) 表示超前的采样数。
重复控制逆变器的仿真调试
仿真过程中将搭建一个逆变器电路,并使用重复控制器对输出电压进行控制,观察其性能。仿真软件使用的 GeckoCircuits 。
步骤1:搭建逆变器电路
搭建一个全桥逆变器电路,母线电压设为 \(400V\),输出电压有效值 \(230V\),频率 \(50Hz\),负载电阻 \(200 \Omega\)。
其中,LC 滤波器参数的估算过程:LC 滤波器截止频率计算公式为 \(f_c = 1/2\pi \sqrt{LC}\),该频率应远高于 \(10\) 倍基波频率,远低于开关频率 \(10\%\),开关频率取\(32kHz\),即 \(500Hz = 0.980){ vOUT = 0.980; } else if (vOUT < -0.980){ vOUT = -0.980; } if (vSet >= 0){ if (vOUT < 0){ vOUT = 0; } } else{ if (vOUT > 0){ vOUT = 0; } } lpf_b1 = lpf_b0; lpf_a1 = vOUT; bufferIndex ++; if (bufferIndex >= indexMAX){ bufferIndex = 0; } theta += thetaStep; if (theta >= TWOPI){ theta = 0; } } } else{ countMAX = (int)(1/(sampleRate*dt)); initialized = true; vOUT = 0; } yOUT[0] = vOUT; yOUT[1] = vSet; return yOUT;// ****************** end of code segment ********************** }}[/code]H 桥驱动器的代码内容如下:- public class tmpJav393624554 implements java.io.Serializable, ch.technokrat.gecko.ControlCalculatable {
- // variables:
- private final double sampleRate = 32000;
- private final double frequency = 50;
- private final double vRMS = 230;
- private final int indexMAX = (int)(sampleRate / frequency);
- private final double PI = Math.PI;
- private final double TWOPI = 2.0*PI;
- private final double thetaStep = TWOPI / indexMAX;
- private double[] bufferIN = new double[indexMAX];
- private double[] bufferOUT = new double[indexMAX];
- private int bufferIndex;
- private double error;
- private int count;
- private int countMAX;
- private boolean initialized;
- private double vSet;
- private double theta;
- private double vIN;
- private double vOUT;
- private double gain, gain1;
- private double q_b0, q_b1, q_a1;
- private double y, y0, y1, y2;
- private double x, x0, x1, x2;
- private double rc0, rc1, rc2;
- private double lpf_b0, lpf_b1, lpf_a1;
- private int m;
- private double[] yOUT = new double[2];
- @Override
- public void init() {
- initialized = false;
- bufferIndex = 0;
- count = 0;
- theta = 0;
- gain = 0.0035;
- q_b0 = 0.07246376811594202;
- q_b1 = 0.07246376811594202;
- q_a1 = -0.855072463768116;
- lpf_b0 = 0.23809523809523814;
- lpf_b1 = 0.23809523809523814;
- lpf_a1 = -0.5238095238095238;
- m = 3;
- }
- @Override
- public double[] calculateYOUT(final double[] xIN, final double time, final double dt) throws Exception {
- // ****************** your code segment **********************
- if (initialized){
- count ++;
- if (count >= countMAX){
- count = 0;
-
- vIN = xIN[0];
- vSet = 1.414*vRMS*Math.sin(theta);
- error = (vSet - vIN);
-
- y0 = bufferOUT[bufferIndex];
- y = y0*q_b0 + y1*q_b1 - y2*q_a1;
- y1 = y0;
- y2 = y;
-
- if (bufferIndex+m < indexMAX){
- x0 = bufferIN[bufferIndex+m];
- }
- else{
- x0 = bufferIN[bufferIndex+m-indexMAX];
- }
-
- x = x0*q_b0 + x1*q_b1 - x2*q_a1;
- x1 = x0;
- x2 = x;
-
- rc0 = x + y;
- bufferIN[bufferIndex] = error;
- bufferOUT[bufferIndex] = rc0;
-
- vOUT = rc0*lpf_b0 + rc1*lpf_b1 - rc2*lpf_a1;
- vOUT = vOUT*gain;
-
- if (vOUT >= 0.980){
- vOUT = 0.980;
- }
- else if (vOUT < -0.980){
- vOUT = -0.980;
- }
-
- if (vSet >= 0){
- if (vOUT < 0){
- vOUT = 0;
- }
- }
- else{
- if (vOUT > 0){
- vOUT = 0;
- }
- }
-
- lpf_b1 = lpf_b0;
- lpf_a1 = vOUT;
-
- bufferIndex ++;
- if (bufferIndex >= indexMAX){
- bufferIndex = 0;
- }
- theta += thetaStep;
- if (theta >= TWOPI){
- theta = 0;
- }
- }
- }
- else{
- countMAX = (int)(1/(sampleRate*dt));
- initialized = true;
- vOUT = 0;
- }
-
- yOUT[0] = vOUT;
- yOUT[1] = vSet;
-
- return yOUT;
- // ****************** end of code segment **********************
- }
- }
复制代码 步骤3:运行结果
运行仿真,查看输出电压波形:
转载请注明文章出处:https://www.cnblogs.com/CIB27149/p/19656366
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |