2023年9月2日土曜日

PMSMの制御系の設計

 前書き

この記事では永久磁石同期モータ(Permanent Magnet Synchronous Motor; PMSM)の電流制御シミュレーションを対象としたPMSMモータの制御系の設計を検討する。

PMSM駆動システムモデル

PMSM駆動システム
検討する永久磁石同期モータ(Permanent Magnet Synchronous Motor; PMSM)の制御は空間ベクトル理論を用いて、 PMSM をインバータによって駆動するシステムである。モータの負荷は定速度負荷とする。インバータは PWM Controller から受け取ったゲート信号にしたがって、必要な電圧を出力するように動作する。モータコントローラは、検出したiuiviwθmを用いて、電流フィードバック制御により PMSM を指令値に追従させるために必要なインバータ出力電圧指令値を出力する。PWMコントローラはこれらの指令値を実現するインバータのゲート信号を三角波比較法を用いて生成する。

PMSMの制御システム

電流フィードバック制御器

ここでは古典的な比例積分(PI)制御を適用する。PMSMの電流フィードバック制御では、 dq 軸電流の干渉項と永久磁石による誘起電圧項をフィードフォワードすることによって補償する。上図は制御ブロック図であり、idiqvdvqidiqvdvqの司令値である。上図のidiqωeはセンサなどにより検出する。司令値vdvqは逆dq変換と逆クラーク変換により、vuvvvwに変換して PWM Controller に転送する。

PMSM駆動システムのブロック線図

PMSMの数理モデルは前回の記事で示した。干渉項と誘起電圧項はフィードフォワードによって補償されるため、ブロック線図上では相殺されて無くなる。これらの項を無視して巻き線抵抗をRとすると、PMSMの入出力伝達関数は次式となる。
(1)Gdm=IdVd=1R+sLd(2)Gqm=IqVq=1R+sLq
dq 軸の伝達関数はどちらも1次遅れ系であるため、それぞれ同じ解析となる。したがって、ここではPMSMの伝達関数を次式として解析する。
(3)Gm=IdqVdq=Km1+τms
dq 軸の伝達関数に置き換えるときには下式を用いる。
(4)Idq=IdorIqVdq=VdorVqτm=LdRorLqRKm=1R



PI制御器の伝達関数GcはゲインKcと時定数τcを用いて次式で表される。Kcτcが設計変数である。
(5)Gc=Kc(1+1τcs)
よってシステムの閉ループ伝達関数Gは次式で得られる。
(6)G=GcGm1+GcGm=KcKm(τcs+1)KcKm(τcs+1)+τcs(τms+1)

ボード線図を用いた PI 制御系の設計

電流フィードバック制御による補償では、アプリケーションにもよるが、一般に応答速度が速く、電流の振動がないほうがよい。一方でインバータの出力電圧にはスイッチング周波数成分が重畳して電流波形をひずませるため、この周波数成分を減衰させるシステムとすることが求められる。

2次遅れと1次進み伝達関数による設計

(6)を展開して整理することで次式を得る。
(7)G=(τcs+1)(KcKm/(τcτm)s2+(KcKm+1)/τms+KcKm/(τcτm))
上式は伝達関数Gが1次進み系と2次遅れ系の伝達関数の積であることを示す。これらの1次進み系と2次遅れ系の伝達関数をそれぞれG1_leadG2_lagとする。
(8)G1_lead=τcs+1(9)G2_lag=KcKm/(τcτm)s2+(KcKm+1)/τms+KcKm/(τcτm)

G1_leadはPI制御器の時定数τcだけでシンプルに設計される。一方でG2_lagは下式のように減衰係数ζ2_lagと共振周波数ωc2_lagに置き換えて設計される。つまり、Kcτcの2変数を適切に設定して、必要なG1_leadの時定数とG2_lagζ2_lagω2_lagとする必要がある。
(10)G2_lag=ω2_lag2s2+2ζ2_lagω2_lags+ω2_lag2(11)2ζ2_lagω2_lag=KcKm+1τm(12)ω2_lag2=KcKmτcτm
伝達関数GG1_leadG2_lagのボード線図の概形を下記に示す。これらのボード線図の詳細については制御理論を参照していただき、ここでは簡単な特徴のみ記述する。伝達関数Gの大きさ|G|は、dBで考えるとG1_leadの大きさ|G1_lead|G2_lagの大きさ|G2_lag|の和である。|G1_lead|ω=ω1_lead以上で20dB/dec. で変化する。一方で、|G2_lag|ω=ω2_lag以上で-40dB/dec. で変化する。低周波領域で|G1_lead|による増幅を避けるためにはω2_lag<ω1_leadとする必要がある。このとき|G|は-40dB/dec. と-20dB/dec. で変化する区間を持ち、それぞれの領域をPI制御器のパラメータKcτcによって調節する。




零極相殺による設計方法

この制御系は零極相殺により、より簡単に設計することが可能である。(6)より、τc=τmとなるように設計すると、Gは明らかにs=1/τm<0の安定な極とゼロ点をもち、これらが約分されて、1次のシステムとなる。よって、このときのシステムの伝達関数G1_lagは次式となる。
(13)G1_lag=11+1KcτmKms
(6)(13)を比較すると、零極相殺により、伝達関数が1次遅れ系となるとともに、設計変数がKcだけとなり、システムの設計が簡単になる。(13)の1次遅れ系のカットオフ角周波数ω1_lagは次式で表される。
(14)ω1_lag=KcKmτm
このとき(13)のボード線図の概形は下図となる。
さて、インバータの出力電圧にはスイッチング周波数成分が重畳して電流波形をひずませるため、この周波数成分を減衰させるシステムとする必要がある。よって、スイッチング角周波数ωswをどれくらい減衰させるかによってω1_lagを決定することができる。例えばωswを-20dBとするためにはω1_lag=ωsw/10とすればよい。ただし低いω1_lagほど、システムの応答は遅くなる。

シミュレーション

OpenModelica を用いた PMSM のシミュレーションにより、制御系の設計による効果を確認する。シミュレーションに用いたModelicaモデルを下記に示す。シミュレーションではスイッチング周波数fsw=10kHzであり、三角波比較では、搬送波をこの2倍の周波数でゼロ次ホールドした波形と三角波を比較する。
  1. model PMSM_model_20230907
  2. parameter Modelica.Electrical.Machines.Utilities.ParameterRecords.SM_PermanentMagnetData smpmData(useDamperCage = true) annotation(
  3. Placement(visible = true, transformation(origin = {0, 0}, extent = {{240, 10}, {260, 30}}, rotation = 0)));
  4. Modelica.Blocks.Math.Gain gain_Phi(k = sqrt(3)*smpmData.VsOpenCircuit/(2*Modelica.Constants.pi*smpmData.fsNominal)) annotation(
  5. Placement(visible = true, transformation(origin = {150, -340}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  6. Modelica.Blocks.MathBoolean.Not not_w annotation(
  7. Placement(visible = true, transformation(origin = {40, 16}, extent = {{4, -4}, {-4, 4}}, rotation = -90)));
  8. Modelica.Blocks.Math.Gain gain_half(k = 0.5) annotation(
  9. Placement(visible = true, transformation(origin = {-70, -350}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  10. Modelica.Blocks.Continuous.PI pi_q(T = (smpmData.Lmq)/(smpmData.Rs), k = 2*Modelica.Constants.pi*5e2*(smpmData.Lmq)) annotation(
  11. Placement(visible = true, transformation(origin = {150, -280}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  12. Modelica.Blocks.Math.Add add_d(k2 = -1) annotation(
  13. Placement(visible = true, transformation(origin = {50, -266}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  14. Modelica.Blocks.Math.Add add_q2 annotation(
  15. Placement(visible = true, transformation(origin = {90, -316}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  16. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_pw annotation(
  17. Placement(visible = true, transformation(origin = {0, 50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  18. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_nu annotation(
  19. Placement(visible = true, transformation(origin = {-120, -50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  20. Modelica.Blocks.Continuous.Der der_theta annotation(
  21. Placement(visible = true, transformation(origin = {210, -320}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  22. Modelica.Electrical.Machines.BasicMachines.SynchronousMachines.SM_PermanentMagnet smpm(Jr = smpmData.Jr, Js = smpmData.Js, Lmd = smpmData.Lmd, Lmq = smpmData.Lmq, Lrsigmad = smpmData.Lrsigmad, Lrsigmaq = smpmData.Lrsigmaq, Lssigma = smpmData.Lssigma, Lszero = smpmData.Lszero, Rrd = smpmData.Rrd, Rrq = smpmData.Rrq, Rs = smpmData.Rs, TrOperational = 293.15, TrRef = smpmData.TrRef, TsOperational = 293.15, TsRef = smpmData.TsRef, VsOpenCircuit = smpmData.VsOpenCircuit, alpha20r = smpmData.alpha20r, alpha20s = smpmData.alpha20s, frictionParameters = smpmData.frictionParameters, fsNominal = smpmData.fsNominal, p = smpmData.p, permanentMagnetLossParameters = smpmData.permanentMagnetLossParameters, phiMechanical(displayUnit = "rad", fixed = true), statorCoreParameters = smpmData.statorCoreParameters, strayLoadParameters = smpmData.strayLoadParameters, useDamperCage = smpmData.useDamperCage, wMechanical(displayUnit = "rad/s", fixed = false)) annotation(
  23. Placement(visible = true, transformation(origin = {0, 0}, extent = {{200, -50}, {220, -30}}, rotation = 0)));
  24. Modelica.Blocks.Sources.Constant zero_voltage_ref(k = 0) annotation(
  25. Placement(visible = true, transformation(origin = {-30, -240}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  26. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_pv annotation(
  27. Placement(visible = true, transformation(origin = {-60, 50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  28. Modelica.Blocks.Logical.Greater greater_u annotation(
  29. Placement(visible = true, transformation(origin = {-80, -90}, extent = {{-10, 10}, {10, -10}}, rotation = 90)));
  30. Modelica.Blocks.Sources.Trapezoid triangle(amplitude = 2, falling(displayUnit = "us") = 5.000000000000003e-05, offset = -1, period(displayUnit = "us") = 0.0001000000000000001, rising(displayUnit = "us") = 5.000000000000003e-05, width(displayUnit = "us") = 0) annotation(
  31. Placement(visible = true, transformation(origin = {-130, -140}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  32. Modelica.Blocks.Math.MatrixGain InvParkConvGain(K = [sqrt(2/3), 0, 0; 0, sqrt(2/3), 0; 0, 0, sqrt(2/3)]) annotation(
  33. Placement(visible = true, transformation(origin = {-90, -250}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
  34. Modelica.Electrical.Polyphase.Basic.PlugToPin_p plugToPin(k = 1) annotation(
  35. Placement(visible = true, transformation(origin = {70, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  36. Modelica.Blocks.Math.Division div_Vdc_d annotation(
  37. Placement(visible = true, transformation(origin = {10, -272}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  38. Modelica.Blocks.Math.Add add_q annotation(
  39. Placement(visible = true, transformation(origin = {50, -310}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  40. Modelica.Blocks.MathBoolean.Not not_u annotation(
  41. Placement(visible = true, transformation(origin = {-80, 16}, extent = {{4, -4}, {-4, 4}}, rotation = -90)));
  42. Modelica.Blocks.Math.Feedback feedback_q annotation(
  43. Placement(visible = true, transformation(origin = {210, -280}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  44. Modelica.Blocks.Math.Product product_id_omega annotation(
  45. Placement(visible = true, transformation(origin = {150, -310}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  46. Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor annotation(
  47. Placement(visible = true, transformation(origin = {226, -70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  48. Modelica.Electrical.Machines.SpacePhasors.Blocks.ToSpacePhasor toSpacePhasor annotation(
  49. Placement(visible = true, transformation(origin = {130, -30}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  50. Modelica.Blocks.Math.Gain gain_Ld(k = smpmData.Lmd) annotation(
  51. Placement(visible = true, transformation(origin = {122, -310}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  52. Modelica.Blocks.Sources.Constant const_ref_d_current(k = 0) annotation(
  53. Placement(visible = true, transformation(origin = {250, -260}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  54. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_nw annotation(
  55. Placement(visible = true, transformation(origin = {0, -50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  56. Modelica.Mechanics.Rotational.Sources.ConstantSpeed constantSpeed(w_fixed = 2*Modelica.Constants.pi*20) annotation(
  57. Placement(visible = true, transformation(origin = {270, -40}, extent = {{-10, 10}, {10, -10}}, rotation = 180)));
  58. Modelica.Blocks.MathBoolean.Not not_v annotation(
  59. Placement(visible = true, transformation(origin = {-20, 16}, extent = {{4, -4}, {-4, 4}}, rotation = -90)));
  60. Modelica.Blocks.Sources.Constant const_ref_q_current(k = 30) annotation(
  61. Placement(visible = true, transformation(origin = {290, -280}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  62. Modelica.Blocks.Logical.Greater greater_v annotation(
  63. Placement(visible = true, transformation(origin = {-20, -90}, extent = {{-10, 10}, {10, -10}}, rotation = 90)));
  64. Modelica.Blocks.Math.Feedback feedback_d annotation(
  65. Placement(visible = true, transformation(origin = {190, -260}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  66. Modelica.Electrical.Polyphase.Basic.PlugToPin_p plugToPin_p(k = 2) annotation(
  67. Placement(visible = true, transformation(origin = {70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  68. Modelica.Electrical.Polyphase.Basic.Star star annotation(
  69. Placement(visible = true, transformation(origin = {170, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  70. Modelica.Blocks.Math.Division div_Vdc_q annotation(
  71. Placement(visible = true, transformation(origin = {10, -316}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  72. Modelica.Electrical.Polyphase.Sensors.CurrentSensor currentSensor annotation(
  73. Placement(visible = true, transformation(origin = {130, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  74. Modelica.Blocks.Logical.Greater greater_w annotation(
  75. Placement(visible = true, transformation(origin = {40, -90}, extent = {{-10, 10}, {10, -10}}, rotation = 90)));
  76. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_nv annotation(
  77. Placement(visible = true, transformation(origin = {-60, -50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  78. Modelica.Electrical.Analog.Ideal.IdealOpeningSwitch idealOpenSW_pu annotation(
  79. Placement(visible = true, transformation(origin = {-120, 50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  80. Modelica.Electrical.Machines.SpacePhasors.Blocks.Rotator inv_rotator annotation(
  81. Placement(visible = true, transformation(origin = {-30, -280}, extent = {{-10, 10}, {10, -10}}, rotation = 180)));
  82. Modelica.Electrical.Machines.SpacePhasors.Blocks.FromSpacePhasor fromSpacePhasor annotation(
  83. Placement(visible = true, transformation(origin = {-70, -280}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  84. Modelica.Electrical.Analog.Basic.Ground ground annotation(
  85. Placement(visible = true, transformation(origin = {-60, -76}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  86. Modelica.Blocks.Math.Gain gain_minus1(k = -1) annotation(
  87. Placement(visible = true, transformation(origin = {50, -390}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  88. Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor annotation(
  89. Placement(visible = true, transformation(origin = {-150, 0}, extent = {{-10, 10}, {10, -10}}, rotation = -90)));
  90. Modelica.Electrical.Machines.SpacePhasors.Blocks.Rotator rotator annotation(
  91. Placement(visible = true, transformation(origin = {130, -210}, extent = {{-10, 10}, {10, -10}}, rotation = -90)));
  92. Modelica.Blocks.Math.Product product_iq_omega annotation(
  93. Placement(visible = true, transformation(origin = {150, -370}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  94. Modelica.Blocks.Math.MatrixGain ParkConvGain(K = [sqrt(3/2), 0; 0, sqrt(3/2)]) annotation(
  95. Placement(visible = true, transformation(origin = {130, -70}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  96. Modelica.Electrical.Analog.Sources.ConstantVoltage constantVoltage(V = 282) annotation(
  97. Placement(visible = true, transformation(origin = {-180, 0}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  98. Modelica.Electrical.Polyphase.Basic.PlugToPin_p plugToPin_p1(k = 3) annotation(
  99. Placement(visible = true, transformation(origin = {70, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 180)));
  100. Modelica.Blocks.Math.Gain gain_pole_pair(k = smpmData.p) annotation(
  101. Placement(visible = true, transformation(origin = {226, -208}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
  102. Modelica.Blocks.Math.Gain gain_Lq(k = smpmData.Lmq) annotation(
  103. Placement(visible = true, transformation(origin = {90, -370}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  104. Modelica.Blocks.Continuous.PI pi_d(T = (smpmData.Lmd)/(smpmData.Rs), k = 2*Modelica.Constants.pi*5e2*(smpmData.Lmd)) annotation(
  105. Placement(visible = true, transformation(origin = {110, -260}, extent = {{10, -10}, {-10, 10}}, rotation = 0)));
  106. Modelica.Blocks.Discrete.ZeroOrderHold zeroOrderHold(samplePeriod = triangle.period) annotation(
  107. Placement(visible = true, transformation(origin = {-80, -170}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
  108. Modelica.Blocks.Discrete.ZeroOrderHold zeroOrderHold1(samplePeriod = triangle.period) annotation(
  109. Placement(visible = true, transformation(origin = {-20, -170}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
  110. Modelica.Blocks.Discrete.ZeroOrderHold zeroOrderHold2(samplePeriod = triangle.period) annotation(
  111. Placement(visible = true, transformation(origin = {40, -170}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
  112. equation
  113. connect(der_theta.y, gain_Phi.u) annotation(
  114. Line(points = {{199, -320}, {180, -320}, {180, -340}, {162, -340}}, color = {0, 0, 127}));
  115. connect(plugToPin_p1.plug_p, currentSensor.plug_p) annotation(
  116. Line(points = {{72, -30}, {80, -30}, {80, 0}, {120, 0}}, color = {0, 0, 255}));
  117. connect(idealOpenSW_nu.n, idealOpenSW_nv.n) annotation(
  118. Line(points = {{-120, -60}, {-60, -60}}, color = {0, 0, 255}));
  119. connect(greater_w.y, idealOpenSW_nw.control) annotation(
  120. Line(points = {{40, -78}, {40, -50}, {12, -50}}, color = {255, 0, 255}));
  121. connect(plugToPin.plug_p, currentSensor.plug_p) annotation(
  122. Line(points = {{72, 30}, {80, 30}, {80, 0}, {120, 0}}, color = {0, 0, 255}));
  123. connect(idealOpenSW_pu.p, idealOpenSW_pv.p) annotation(
  124. Line(points = {{-120, 60}, {-60, 60}}, color = {0, 0, 255}));
  125. connect(constantVoltage.p, idealOpenSW_pu.p) annotation(
  126. Line(points = {{-180, 10}, {-180, 60}, {-120, 60}}, color = {0, 0, 255}));
  127. connect(add_q.y, div_Vdc_q.u1) annotation(
  128. Line(points = {{39, -310}, {22, -310}}, color = {0, 0, 127}));
  129. connect(plugToPin_p.pin_p, idealOpenSW_pv.n) annotation(
  130. Line(points = {{68, 0}, {-60, 0}, {-60, 40}}, color = {0, 0, 255}));
  131. connect(der_theta.y, product_id_omega.u2) annotation(
  132. Line(points = {{199, -320}, {180, -320}, {180, -316}, {162, -316}}, color = {0, 0, 127}));
  133. connect(gain_minus1.y, inv_rotator.angle) annotation(
  134. Line(points = {{39, -390}, {-30, -390}, {-30, -292}}, color = {0, 0, 127}));
  135. connect(der_theta.y, product_iq_omega.u2) annotation(
  136. Line(points = {{199, -320}, {180, -320}, {180, -376}, {162, -376}}, color = {0, 0, 127}));
  137. connect(smpm.flange, angleSensor.flange) annotation(
  138. Line(points = {{220, -40}, {226, -40}, {226, -60}}));
  139. connect(gain_half.y, div_Vdc_d.u2) annotation(
  140. Line(points = {{-59, -350}, {32, -350}, {32, -278}, {22, -278}}, color = {0, 0, 127}));
  141. connect(idealOpenSW_pw.n, idealOpenSW_nw.p) annotation(
  142. Line(points = {{0, 40}, {0, -40}}, color = {0, 0, 255}));
  143. connect(plugToPin_p.plug_p, currentSensor.plug_p) annotation(
  144. Line(points = {{72, 0}, {120, 0}}, color = {0, 0, 255}));
  145. connect(smpm.flange, constantSpeed.flange) annotation(
  146. Line(points = {{220, -40}, {260, -40}}));
  147. connect(greater_u.y, idealOpenSW_nu.control) annotation(
  148. Line(points = {{-80, -78}, {-80, -50}, {-108, -50}}, color = {255, 0, 255}));
  149. connect(div_Vdc_q.y, inv_rotator.u[2]) annotation(
  150. Line(points = {{-1, -316}, {-8, -316}, {-8, -280}, {-18, -280}}, color = {0, 0, 127}));
  151. connect(plugToPin.pin_p, idealOpenSW_pu.n) annotation(
  152. Line(points = {{68, 30}, {-120, 30}, {-120, 40}}, color = {0, 0, 255}));
  153. connect(not_w.y, idealOpenSW_pw.control) annotation(
  154. Line(points = {{40, 20}, {40, 50}, {12, 50}}, color = {255, 0, 255}));
  155. connect(gain_Phi.y, add_q2.u2) annotation(
  156. Line(points = {{139, -340}, {110, -340}, {110, -322}, {102, -322}}, color = {0, 0, 127}));
  157. connect(rotator.y[2], feedback_q.u2) annotation(
  158. Line(points = {{130, -221}, {130, -241}, {210, -241}, {210, -273}}, color = {0, 0, 127}));
  159. connect(greater_v.y, idealOpenSW_nv.control) annotation(
  160. Line(points = {{-20, -78}, {-20, -50}, {-48, -50}}, color = {255, 0, 255}));
  161. connect(product_iq_omega.y, gain_Lq.u) annotation(
  162. Line(points = {{139, -370}, {102, -370}}, color = {0, 0, 127}));
  163. connect(pi_q.y, add_q.u1) annotation(
  164. Line(points = {{139, -280}, {76, -280}, {76, -304}, {62, -304}}, color = {0, 0, 127}));
  165. connect(ParkConvGain.y, rotator.u) annotation(
  166. Line(points = {{130, -81}, {130, -198}}, color = {0, 0, 127}, thickness = 0.5));
  167. connect(const_ref_q_current.y, feedback_q.u1) annotation(
  168. Line(points = {{279, -280}, {218, -280}}, color = {0, 0, 127}));
  169. connect(star.plug_p, smpm.plug_sn) annotation(
  170. Line(points = {{180, -30}, {204, -30}}, color = {0, 0, 255}));
  171. connect(rotator.y[1], product_iq_omega.u1) annotation(
  172. Line(points = {{130, -221}, {130, -241}, {170, -241}, {170, -365}, {162, -365}}, color = {0, 0, 127}));
  173. connect(feedback_d.y, pi_d.u) annotation(
  174. Line(points = {{181, -260}, {122, -260}}, color = {0, 0, 127}));
  175. connect(currentSensor.plug_n, smpm.plug_sp) annotation(
  176. Line(points = {{140, 0}, {216, 0}, {216, -30}}, color = {0, 0, 255}));
  177. connect(gain_pole_pair.y, der_theta.u) annotation(
  178. Line(points = {{226, -219}, {226, -320}, {222, -320}}, color = {0, 0, 127}));
  179. connect(not_u.y, idealOpenSW_pu.control) annotation(
  180. Line(points = {{-80, 20}, {-80, 50}, {-108, 50}}, color = {255, 0, 255}));
  181. connect(rotator.y[1], feedback_d.u2) annotation(
  182. Line(points = {{130, -221}, {130, -241}, {190, -241}, {190, -253}}, color = {0, 0, 127}));
  183. connect(inv_rotator.y, fromSpacePhasor.u) annotation(
  184. Line(points = {{-41, -280}, {-58, -280}}, color = {0, 0, 127}, thickness = 0.5));
  185. connect(greater_u.y, not_u.u) annotation(
  186. Line(points = {{-80, -78}, {-80, 10}}, color = {255, 0, 255}));
  187. connect(idealOpenSW_pv.p, idealOpenSW_pw.p) annotation(
  188. Line(points = {{-60, 60}, {0, 60}}, color = {0, 0, 255}));
  189. connect(gain_Ld.y, add_q2.u1) annotation(
  190. Line(points = {{111, -310}, {102, -310}}, color = {0, 0, 127}));
  191. connect(plugToPin_p1.pin_p, idealOpenSW_nw.p) annotation(
  192. Line(points = {{68, -30}, {0, -30}, {0, -40}}, color = {0, 0, 255}));
  193. connect(rotator.y[2], product_id_omega.u1) annotation(
  194. Line(points = {{130, -221}, {130, -241}, {170, -241}, {170, -305}, {162, -305}}, color = {0, 0, 127}));
  195. connect(fromSpacePhasor.y, InvParkConvGain.u) annotation(
  196. Line(points = {{-81, -280}, {-90, -280}, {-90, -262}}, color = {0, 0, 127}, thickness = 0.5));
  197. connect(feedback_q.y, pi_q.u) annotation(
  198. Line(points = {{201, -280}, {162, -280}}, color = {0, 0, 127}));
  199. connect(gain_half.y, div_Vdc_q.u2) annotation(
  200. Line(points = {{-59, -350}, {32, -350}, {32, -322}, {22, -322}}, color = {0, 0, 127}));
  201. connect(add_q2.y, add_q.u2) annotation(
  202. Line(points = {{79, -316}, {62, -316}}, color = {0, 0, 127}));
  203. connect(gain_Lq.y, add_d.u2) annotation(
  204. Line(points = {{79, -370}, {70, -370}, {70, -272.063}, {62, -272.063}, {62, -272}}, color = {0, 0, 127}));
  205. connect(div_Vdc_d.y, inv_rotator.u[1]) annotation(
  206. Line(points = {{-1, -272}, {-8, -272}, {-8, -280}, {-18, -280}}, color = {0, 0, 127}));
  207. connect(constantVoltage.n, idealOpenSW_nu.n) annotation(
  208. Line(points = {{-180, -10}, {-180, -60}, {-120, -60}}, color = {0, 0, 255}));
  209. connect(greater_v.y, not_v.u) annotation(
  210. Line(points = {{-20, -78}, {-20, 10}}, color = {255, 0, 255}));
  211. connect(greater_w.y, not_w.u) annotation(
  212. Line(points = {{40, -78}, {40, 10}}, color = {255, 0, 255}));
  213. connect(idealOpenSW_pu.n, idealOpenSW_nu.p) annotation(
  214. Line(points = {{-120, 40}, {-120, -40}}, color = {0, 0, 255}));
  215. connect(voltageSensor.n, constantVoltage.n) annotation(
  216. Line(points = {{-150, -10}, {-150, -20}, {-180, -20}, {-180, -10}}, color = {0, 0, 255}));
  217. connect(angleSensor.phi, gain_pole_pair.u) annotation(
  218. Line(points = {{226, -80}, {226, -196}}, color = {0, 0, 127}));
  219. connect(voltageSensor.p, constantVoltage.p) annotation(
  220. Line(points = {{-150, 10}, {-150, 20}, {-180, 20}, {-180, 10}}, color = {0, 0, 255}));
  221. connect(const_ref_d_current.y, feedback_d.u1) annotation(
  222. Line(points = {{239, -260}, {198, -260}}, color = {0, 0, 127}));
  223. connect(gain_pole_pair.y, gain_minus1.u) annotation(
  224. Line(points = {{226, -219}, {226, -390}, {62, -390}}, color = {0, 0, 127}));
  225. connect(pi_d.y, add_d.u1) annotation(
  226. Line(points = {{99, -260}, {62, -260}}, color = {0, 0, 127}));
  227. connect(idealOpenSW_nw.n, idealOpenSW_nv.n) annotation(
  228. Line(points = {{0, -60}, {-60, -60}}, color = {0, 0, 255}));
  229. connect(product_id_omega.y, gain_Ld.u) annotation(
  230. Line(points = {{139, -310}, {134, -310}}, color = {0, 0, 127}));
  231. connect(gain_pole_pair.y, rotator.angle) annotation(
  232. Line(points = {{226, -219}, {226, -233}, {200, -233}, {200, -211}, {142, -211}}, color = {0, 0, 127}));
  233. connect(idealOpenSW_pv.n, idealOpenSW_nv.p) annotation(
  234. Line(points = {{-60, 40}, {-60, -40}}, color = {0, 0, 255}));
  235. connect(currentSensor.i, toSpacePhasor.u) annotation(
  236. Line(points = {{130, -10}, {130, -18}}, color = {0, 0, 127}, thickness = 0.5));
  237. connect(add_d.y, div_Vdc_d.u1) annotation(
  238. Line(points = {{39, -266}, {22, -266}}, color = {0, 0, 127}));
  239. connect(zero_voltage_ref.y, fromSpacePhasor.zero) annotation(
  240. Line(points = {{-41, -240}, {-51, -240}, {-51, -272}, {-58, -272}}, color = {0, 0, 127}));
  241. connect(voltageSensor.v, gain_half.u) annotation(
  242. Line(points = {{-138, 0}, {-130, 0}, {-130, -40}, {-160, -40}, {-160, -350}, {-82, -350}}, color = {0, 0, 127}));
  243. connect(toSpacePhasor.y, ParkConvGain.u) annotation(
  244. Line(points = {{130, -40}, {130, -58}}, color = {0, 0, 127}, thickness = 0.5));
  245. connect(not_v.y, idealOpenSW_pv.control) annotation(
  246. Line(points = {{-20, 20}, {-20, 50}, {-48, 50}}, color = {255, 0, 255}));
  247. connect(ground.p, idealOpenSW_nv.n) annotation(
  248. Line(points = {{-60, -66}, {-60, -60}}, color = {0, 0, 255}));
  249. connect(triangle.y, greater_u.u2) annotation(
  250. Line(points = {{-118, -140}, {-88, -140}, {-88, -102}}, color = {0, 0, 127}));
  251. connect(triangle.y, greater_v.u2) annotation(
  252. Line(points = {{-118, -140}, {-28, -140}, {-28, -102}}, color = {0, 0, 127}));
  253. connect(triangle.y, greater_w.u2) annotation(
  254. Line(points = {{-118, -140}, {32, -140}, {32, -102}}, color = {0, 0, 127}));
  255. connect(InvParkConvGain.y[1], zeroOrderHold.u) annotation(
  256. Line(points = {{-90, -238}, {-90, -200}, {-80, -200}, {-80, -182}}, color = {0, 0, 127}));
  257. connect(InvParkConvGain.y[2], zeroOrderHold1.u) annotation(
  258. Line(points = {{-90, -238}, {-90, -200}, {-20, -200}, {-20, -182}}, color = {0, 0, 127}));
  259. connect(InvParkConvGain.y[3], zeroOrderHold2.u) annotation(
  260. Line(points = {{-90, -238}, {-90, -200}, {40, -200}, {40, -182}}, color = {0, 0, 127}));
  261. connect(zeroOrderHold.y, greater_u.u1) annotation(
  262. Line(points = {{-80, -158}, {-80, -102}}, color = {0, 0, 127}));
  263. connect(zeroOrderHold1.y, greater_v.u1) annotation(
  264. Line(points = {{-20, -158}, {-20, -102}}, color = {0, 0, 127}));
  265. connect(zeroOrderHold2.y, greater_w.u1) annotation(
  266. Line(points = {{40, -158}, {40, -102}}, color = {0, 0, 127}));
  267. annotation(
  268. uses(Modelica(version = "4.0.0")),
  269. Diagram(coordinateSystem(extent = {{-200, 60}, {320, -400}})),
  270. version = "",
  271. Documentation(revisions = "
  272. "));
  273. end PMSM_model_20230907;
零極相殺による設計方法で、ω1_lag/2π=fsw,fsw/10,fsw/20とした三通りのシミュレーションを行った。シミュレーション結果を示す。
上図は、搬送波をゼロ次ホールドする前後の波形であり、赤色がホールド前、黒色がホールド後の波形である。カットオフ周波数ω1_lag/2π=fsw/10,fsw/20の場合には、スイッチング周波数成分が十分に減衰されるため、搬送波に重畳するスイッチング周波数成分は小さく、ゼロ次ホールド後の波形はゼロ次ホールド前の波形の平均値に近い値となっている。一方でω1_lag/2π=fswでは、搬送波のスイッチング周波数成分が支配的であり、ゼロ次ホールド後の波形が搬送波を正しくサンプリングできない。このため、誤った信号が三角波比較され、システムが不安定となる。


上図はdq電流の司令値(点線)と測定値(実線)を示しており、これらが一致するようにフィードバック制御を適用している。ω1_lag/2π=fsw/10,fsw/20では、測定値は司令値に追従している。ω1_lag/2π=fsw/10の方がω1_lag/2π=fsw/20よりも少し早く収束しているため、大きいω1_lagの方が応答速度が速い。ω1_lag=fswではフィードバック制御が不安定となることがわかる。したがって、ω1_lagfswとする必要がある。

まとめ

0 件のコメント:

コメントを投稿

変圧器の動作と内部磁束

前書き この記事では、変圧器の基本的な動作と変圧器内部の磁束について紹介する。変圧器は磁気結合を利用して、簡単に交流電圧を変圧することができる。変圧器の各コイルが発生させる磁束は互いに打ち消しあうため、変圧器の内部磁束は小さくなる。特に変圧器の片側が電圧源に接続されるとき...