From constant disturbance to time-varying disturbance 从恒定扰动到时变扰动
The mechanical equation机械方程
Define the total disturbance $d_{to}$ as everything the controller does not model: 定义总扰动 $d_{to}$ 为控制器未建模的所有内容:
An observer that estimates $d_{to}$ can feed it forward to cancel the disturbance before the PI regulator reacts. The question is: how well can the observer track $d_{to}$ when it changes over time? 估计 $d_{to}$ 的观测器可以将其前馈,在 PI 调节器反应之前就抵消扰动。问题是:当 $d_{to}$ 随时间变化时,观测器能跟踪得多好?
3rd-order observer: assumes constant disturbance三阶观测器:假设扰动恒定
States: $[\hat{\theta}_d,\ \hat{\omega}_r,\ \hat{d}_{to}]$. The internal model assumes $\dot{d}_{to} = 0$.状态:$[\hat{\theta}_d,\ \hat{\omega}_r,\ \hat{d}_{to}]$。内部模型假设 $\dot{d}_{to} = 0$。
Gains placed at $(s + \omega_{ob})^3$:增益配置在 $(s + \omega_{ob})^3$:
4th-order observer: models ramp disturbance四阶观测器:建模斜坡扰动
States: $[\hat{\theta}_d,\ \hat{\omega}_r,\ \hat{d}_{to},\ \hat{p}_{to}]$. The internal model assumes $\dot{d}_{to} = p_{to}$, $\dot{p}_{to} = 0$.状态:$[\hat{\theta}_d,\ \hat{\omega}_r,\ \hat{d}_{to},\ \hat{p}_{to}]$。内部模型假设 $\dot{d}_{to} = p_{to}$,$\dot{p}_{to} = 0$。
Gains placed at $(s + \omega_{ob})^4$:增益配置在 $(s + \omega_{ob})^4$:
3rd-order under ramp load三阶在斜坡负载下
$\hat{d}_{to}$ lags behind $d_{to}$. Speed drops continuously. PI compensates slowly via integral action.$\hat{d}_{to}$ 滞后于 $d_{to}$。速度持续下降。PI 通过积分作用缓慢补偿。
4th-order under ramp load四阶在斜坡负载下
$\hat{d}_{to}$ tracks $d_{to}$ with zero steady-state error. Feedforward cancels the ramp. Speed stays on target.$\hat{d}_{to}$ 以零稳态误差跟踪 $d_{to}$。前馈抵消斜坡。速度保持目标值。
Where to find and modify the observer观测器代码位置与修改点
1. Observer gains initialization1. 观测器增益初始化
In The_Motor_Controller.__init__ (around line 165), the observer gains are selected by an if/elif/else chain. Currently the 3rd-order branch is active:在 The_Motor_Controller.__init__(约第 165 行),观测器增益通过 if/elif/else 链选择。当前三阶分支生效:
omega_ob = 100 # [rad/s]
if False: # 2nd-order speed observer
...
elif False: # 2nd-order position observer
...
elif True: # 3rd-order <--- CURRENTLY ACTIVE
self.ell1 = 3 * omega_ob
self.ell2 = 3 * omega_ob**2
self.ell3 = omega_ob**3 * init_Js/init_npp
else: # 4th-order <--- YOU NEED TO ACTIVATE THIS
self.ell1 = 4 * omega_ob
self.ell2 = 6 * omega_ob**2
self.ell3 = 4 * omega_ob**3 * init_Js/init_npp
self.ell4 = omega_ob**4
2. Observer dynamics (already supports 4th-order)2. 观测器动态方程(已支持四阶)
def DYNAMICS_SpeedObserver(x, CTRL):
fx = np.zeros(6)
output_error = angle_diff(CTRL.theta_d, x[0])
fx[0] = CTRL.ell1*output_error + x[1] # theta
fx[1] = CTRL.ell2*output_error + (CTRL.Tem + x[2]) * CTRL.npp/CTRL.Js # omega
fx[2] = CTRL.ell3*output_error + x[3] # d_to
fx[3] = CTRL.ell4*output_error + 0.0 # p_to (rate)
return fx
When ell4 = 0 (3rd-order), x[3] stays zero. When ell4 > 0 (4th-order), x[3] estimates the rate of disturbance change.当 ell4 = 0(三阶)时,x[3] 保持为零。当 ell4 > 0(四阶)时,x[3] 估计扰动变化率。
3. The missing link: feedforward is not wired in!3. 缺失的环节:前馈未接入!
In FOC() (line 638), the speed controller output goes directly to cmd_idq[1]:在 FOC()(第 638 行),速度控制器输出直接赋给 cmd_idq[1]:
# Current code (line 638-639):
if CTRL.bool_apply_speed_closed_loop_control == True:
CTRL.cmd_idq[1] = reg_speed.Out # feedforward NOT added!
The observer computes total_disrubance_feedforward (line 757-761) but it is never used. You must wire it in.观测器计算了 total_disrubance_feedforward(第 757-761 行),但从未使用。你需要将其接入。
4. Watch data for plotting4. 画图用的观测数据
sim.gdd['CTRL.xS[2]'] # estimated disturbance (d_to)
sim.gdd['CTRL.xS[3]'] # estimated rate (p_to)
sim.gdd['ACM.TLoad'] # actual load torque
sim.gdd['CTRL.omega_r_mech'] # measured speed [rpm]
sim.gdd['CTRL.cmd_rpm'] # speed command [rpm]
Switch from 3rd-order to 4th-order observer 从三阶切换到四阶观测器
You need a way to select observer order from the d configuration dictionary, without hard-coding if True/if False in source code.
你需要一种方法,从 d 配置字典选择观测器阶数,而不是在源代码中硬编码 if True/if False。
- Modify
get_global_objects()intutorials_ep6_svpwm.pyso that after creatingCTRL, you can overwriteCTRL.ell1–CTRL.ell4based on a new config keyd['observer_order'](3 or 4).修改tutorials_ep6_svpwm.py中的get_global_objects(),在创建CTRL后,根据新的配置键d['observer_order'](3 或 4)重写CTRL.ell1–CTRL.ell4。 - Set
CTRL.index_separate_speed_estimation = 1to enable the observer.设置CTRL.index_separate_speed_estimation = 1来启用观测器。 - Verify with a step load: both 3rd-order and 4th-order should track a constant
ACM.TLoad = 0.2with zero steady-state error inxS[2].用阶跃负载验证:三阶和四阶都应以零稳态误差跟踪恒定ACM.TLoad = 0.2的xS[2]。
The_Motor_Controller is a @jitclass. You cannot add new fields. But ell1–ell4 and xS[0:5] already exist — no spec changes needed. You can freely overwrite their values after construction.
The_Motor_Controller 是 @jitclass,不能添加新字段。但 ell1–ell4 和 xS[0:5] 已经存在——不需要修改 spec。你可以在构造后自由覆写它们的值。
Connect the observer output to the speed controller 将观测器输出连接到速度控制器
The observer estimates disturbance $\hat{d}_{to}$ in torque-like units. To use it as a feedforward, convert to $i_q$ current: 观测器估计的扰动 $\hat{d}_{to}$ 单位类似转矩。要用作前馈,需转换为 $i_q$ 电流:
tutorials_ep6_svpwm.py from:
将 tutorials_ep6_svpwm.py 第 638-639 行从:
# BEFORE:
CTRL.cmd_idq[1] = reg_speed.Out
# AFTER:
CTRL.cmd_idq[1] = reg_speed.Out
if CTRL.use_disturbance_feedforward_rejection > 0:
if CTRL.KA > 0:
CTRL.cmd_idq[1] += CTRL.total_disrubance_feedforward / (1.5 * CTRL.npp * CTRL.KA)
xS[2] should be negative.
在被控对象中:$J\dot{\omega} = T_{em} - T_L$。在观测器中:$\dot{\hat{\omega}} \propto T_{em} + \hat{d}_{to}$。所以 $\hat{d}_{to} \approx -T_L$(负载转矩的负值)。将 $\hat{d}_{to}/(1.5\,n_{pp}\,K_A)$ 加到 $i_q^*$ 上会产生负电流来抵消负载效应。请在图中验证:当 $T_L > 0$ 时,xS[2] 应为负。
Prove the 4th-order observer can track ramp disturbance 证明四阶观测器能跟踪斜坡扰动
| Scenario场景 | Observer观测器 | Feedforward前馈 | Expected result预期结果 |
|---|---|---|---|
| A | 3rd-order | OFF | Baseline, PI only基准,仅 PI |
| B | 3rd-order | ON | FF helps but cannot eliminate ramp lagFF 有帮助但无法消除斜坡滞后 |
| C | 4th-order | OFF | Better estimation, no compensation更好的估计,但无补偿 |
| D | 4th-order | ON | Best: zero estimation error, full compensation最佳:零估计误差,完全补偿 |
Ramp load torque setup斜坡负载转矩设置
# In user_system_input_code:
"CTRL.cmd_rpm = 50\n"
"if ii >= 2: ACM.TLoad = 0.05 * (ii - 2) * d['TIME_SLICE']"
This creates a linearly increasing load starting at time slice 2. Adjust the slope (0.05) so the motor doesn't stall.这将从时间片 2 开始创建线性增加的负载。调整斜率(0.05)使电机不会堵转。
What to plot for each scenario每个场景需要画什么
- Subplot 1: Speed command
CTRL.cmd_rpmvs actual speedCTRL.omega_r_mech[rpm]子图 1:速度给定CTRL.cmd_rpmvs 实际速度CTRL.omega_r_mech[rpm] - Subplot 2: Actual load
ACM.TLoadvs estimated disturbanceCTRL.xS[2](note: opposite sign)子图 2:实际负载ACM.TLoadvs 估计扰动CTRL.xS[2](注意:符号相反) - Subplot 3: Estimated rate
CTRL.xS[3]— should converge to the ramp slope for 4th-order子图 3:估计变化率CTRL.xS[3]——四阶时应收敛到斜坡斜率
ACM.TLoad = 0.2 at some time). Show that both observers handle step load well, but only 4th-order handles ramp. This demonstrates that the 4th-order advantage is specifically for time-varying disturbances.
用阶跃负载(某时刻 ACM.TLoad = 0.2)重复场景 A–D。展示两种观测器都能很好地处理阶跃负载,但只有四阶能处理斜坡。这证明四阶的优势专门针对时变扰动。
Tracking, disturbance rejection, and noise: the three-way tradeoff 跟踪、抗扰与噪声:三方权衡
A closed-loop system's output can be decomposed into three paths: 闭环系统的输出可以分解为三条通道:
Command tracking指令跟踪
Compare step response (rise time, overshoot) between 3rd and 4th-order observer systems. Does the observer order affect tracking performance? Why or why not?对比三阶和四阶观测器系统的阶跃响应(上升时间、超调)。观测器阶数是否影响跟踪性能?为什么?
Disturbance rejection扰动抑制
Under ramp load, what is the steady-state speed error for 3rd-order vs 4th-order (both with feedforward ON)? Can you derive the theoretical error from the internal model principle?在斜坡负载下,三阶和四阶(均开前馈)的稳态速度误差分别是多少?你能从内模原理推导理论误差吗?
Noise sensitivity噪声敏感性
Higher-order observers amplify noise more. Try increasing omega_ob and observe the noise in xS[2] and xS[3]. Is the 4th-order observer noisier than 3rd-order at the same bandwidth? What is the tradeoff?高阶观测器放大更多噪声。尝试增大 omega_ob,观察 xS[2] 和 xS[3] 中的噪声。在相同带宽下,四阶观测器是否比三阶更嘈杂?权衡是什么?
Observer bandwidth selection观测器带宽选择
Try omega_ob = 50, 100, 200, 400 for the 4th-order observer. Plot disturbance estimation error vs noise level. What is the optimal omega_ob? Does it differ from the 3rd-order optimal?对四阶观测器尝试 omega_ob = 50, 100, 200, 400。画扰动估计误差 vs 噪声水平的图。最优 omega_ob 是多少?与三阶的最优值不同吗?
Required content of the final PDF report最终 PDF 报告要求
- Step load comparison — 4 scenarios (A–D), speed + disturbance estimate waveforms.阶跃负载对比——4 种场景(A–D),速度 + 扰动估计波形。
- Ramp load comparison — 4 scenarios (A–D), speed + disturbance estimate + rate estimate waveforms.斜坡负载对比——4 种场景(A–D),速度 + 扰动估计 + 变化率估计波形。
- Observer bandwidth sweep — effect of
omega_obon estimation accuracy and noise for both observer orders.观测器带宽扫描——omega_ob对两种阶数的估计精度和噪声的影响。 - Code diff — show the exact lines you modified in
tutorials_ep6_svpwm.py.代码差异——展示你在tutorials_ep6_svpwm.py中修改的确切行。
Mandatory必须包含
FOC() with correct unit conversion.前馈接入 FOC(),单位转换正确。Suggested report structure建议结构
- Background: why higher-order observer背景:为什么需要高阶观测器
- Code modifications (with diff)代码修改(附差异)
- Step load experiments and analysis阶跃负载实验与分析
- Ramp load experiments and analysis斜坡负载实验与分析
- Bandwidth sweep and noise discussion带宽扫描与噪声讨论
- Conclusion结论
Online submission is currently disabled.当前暂不支持在线提交。 Please prepare your report as a PDF. 请先准备 PDF 报告。