实现离散PI控制器后单相并网逆变器仿真时间大幅增加问题求助
单相并网逆变器仿真耗时过高问题定位与解决方案
问题根因定位
- 常量未加
parameter修饰:代码中的a_const、b_const为固定计算值,但定义为普通Real类型,仿真器无法将其识别为常量,每个仿真步都会重复计算,也无法做编译期优化,带来不必要的计算开销。 - 参考电流判断逻辑放在连续域执行:
Id_ref_curr、Iq_ref_curr的分支判断逻辑写在when sample()语句之外,会跟随1e-5的连续仿真步长反复执行,而非仅在采样时刻或参考值跳变时刻执行,放大了计算量。 - 离散输出未明确保持属性:
Mr和th两个输出仅在when语句内赋值,仿真器默认会将其在采样间隔内的变化判定为连续未知状态,会触发大量不必要的迭代求解、自动缩小步长来保证求解精度,这是仿真耗时骤增的核心原因。 - 分支判断存在边界漏洞:
step_times的判断条件没有包含等于的情况,在0.08s和0.12s两个跳变点处可能触发求解器的事件检测逻辑,额外增加计算负担。 - 角度计算存在数值风险:使用
atan(Vin_q / Vin_d)计算角度时,若Vin_d趋近于0会触发除零错误,导致求解器为规避数值异常压缩步长。
可行解决方案
代码优化调整
- 给固定常量加
parameter修饰,让仿真器编译时就完成常量计算:
parameter Real a_const = Kp_cc + Ki_cc * T_sample / 2; parameter Real b_const = -Kp_cc + Ki_cc * T_sample / 2;
- 明确输出的离散保持属性,将参考电流的判断逻辑移入
when sample()语句内,仅在采样时刻更新参考值,同时补全边界判断、替换角度计算函数:
algorithm // 声明输出在采样间隔保持上一次的值,避免求解器做连续迭代 Mr = pre(Mr); th = pre(th); when sample(0, T_sample) then // 更新参考电流 if time < step_times[1] then Id_ref_curr := Id_ref[1]; Iq_ref_curr := Iq_ref[1]; elseif time >= step_times[1] and time < step_times[2] then Id_ref_curr := Id_ref[2]; Iq_ref_curr := Iq_ref[2]; else Id_ref_curr := Id_ref[3]; Iq_ref_curr := Iq_ref[3]; end if; // 原有采样计算逻辑 ed_curr := Id_ref_curr - Id; eq_curr := Iq_ref_curr - Iq; ud_curr := ud_prev + a_const * ed_curr + b_const * ed_prev; uq_curr := uq_prev + a_const * eq_curr + b_const * eq_prev; Vin_d := (Vd_pcc_prev + ud_prev); Vin_q := (Vq_pcc_prev + uq_prev); // 替换为atan2避免除零错误 th := atan2(Vin_q, Vin_d); Mr := sqrt(Vin_d^2 + Vin_q^2) / 360; // 更新历史变量 Vd_pcc_prev := Vd_pcc; Vq_pcc_prev := Vq_pcc; ed_prev := ed_curr; eq_prev := eq_curr; ud_prev := ud_curr; uq_prev := uq_curr; end when;
仿真设置优化
- 开启仿真工具的离散事件优化选项,跳过离散变量的连续迭代步骤。
- 若模型精度允许,可将仿真步长设置为和控制器采样率一致的1e-4,无需使用1e-5的更小步长,可直接减少90%的仿真步数。
优化完成后仿真耗时会回落至和开环仿真相近的水平,不会出现数量级的耗时增长。
内容的提问来源于stack exchange,提问作者Bernard A.
相关产品推荐
相关产品推荐

