电路图
绿色箭头为 PWM 开段电流方向,红色为闭段电流方向。
模型
符号定义
符号 | 含义 |
---|---|
\(f_{\text{pwm}} \approx 1250\text{Hz}\) | PWM 频率 |
\(t_{\text{pwm}} \approx 1 / f_{\text{pwm}}\) | PWM 周期 |
\(t_{\text{on}}\) | PWM 高电位时间 |
\(t_{\text{off}}\) | PWM 低电位时间 |
\(I(t)\) | 电流(随时间变化) |
\(I_0\) | PWM 周期开始时的电流 |
\(I_{\text{max}}\) | PWM 峰值电流 |
\(I_{\text{final}}\) | PWM 周期结束时的电流 |
\(U_\text{b} \approx 7.4\text V\) | 电池电压 |
\(U_\text{bemf}\) | 反电动势 |
\(U_\text L\) | 电感电压 |
\(U_\text D \approx 0.75 \text V\) | 二极管压降 |
\(L \approx 6.5\times 10^{-4}\text H\) | 电感 |
\(R \approx 1.609\Omega\) | 马达内阻 |
\(R_\text s \approx 0.28\Omega\) | 系统内阻 |
部分参数可以自行测定,测定方法见文末。
开段分析
首先,由基尔霍夫定律和欧姆定律,可得: \[ U_\text b - I(t)(R+R_\text s) - U_\text L - U_\text {bemf} = 0 \] 对上式进行整理,并结合电感电压公式: \[ U_\text b = L\frac{dI(t)}{dt} + I(t)(R + R_\text s) + U_\text {bemf} \] 我们把它看做一个关于 \(I\) 的线性微分方程,初始条件为 \(I(0) = I_0\) 解得: \[ I(t) = e^{-\frac{t(R + R_\text s)}{L}} \left( I_0 - \frac{U_\text b - U_\text {bemf}}{R + R_\text s}\right) + \frac{U_\text b - U_\text {bemf}}{R + R_\text s} \] 我们知道电流在高电压段逐步变大,因此 \(I_\text{max} = I(t_\text{on})\),即: \[ I_\text{max} = e^{-\frac{t_\text{on}(R + R_\text s)}{L}} \left( I_0 - \frac{U_\text b - U_\text {bemf}}{R + R_\text s}\right) + \frac{U_\text b - U_\text {bemf}}{R + R_\text s} \] 出于简化式子的需要,令 \[ \begin{aligned} c_\text{on} &= -\frac{t_\text{on}(R + R_\text s)}{L} \\ e_\text{on} &= e^{c_\text{on}} = e^{-\frac{t_\text{on}(R + R_\text s)}{L}} \\ I_\text{on} &= \frac{U_\text b - U_\text {bemf}}{R + R_\text s} \end{aligned} \] 注意到 \(I_\text{on}\) 为 \(\frac{dI(t)}{dt} \to 0\) 时的电流,因此也称作稳态电流。
整理得到: \[ I_\text{max} = e_\text{on}I_0 + (1 - e_\text{on})I_\text{on} \] 为了之后平均电流的计算需要我们顺便计算一波 \(I(t)\) 的积分: \[ \int^{t_\text{on}}_0 I(t)dt = t_\text{on}\left(I_\text{on} - \frac{(1 - e_\text{on})(I_0 - I_\text{on})}{c_\text{on}}\right) \]
闭段分析
再次由基尔霍夫定律及欧姆定律,有:
\[ I(t)R + U_\text L + U_\text {bemf} + U_\text D = 0 \] 同样整理: \[ I(t)R + L \frac{dI(t)}{dt}+ U_\text {bemf} + U_\text D = 0 \] 以初始条件 \(I(0) = I_\text{max}\) 求解这个微分方程解得: \[ I(t) = e^{-\frac{tR}{L}}\left(I_\text{max} + \frac{U_\text {bemf} + U_\text D}{R}\right) - \frac{U_\text {bemf} + U_\text D}{R} \] 类似地: \[ I_\text{final} = e^{-\frac{t_\text{off}R}{L}}\left(I_\text{max} + \frac{U_\text {bemf} + U_\text D}{R}\right) - \frac{U_\text {bemf} + U_\text D}{R} \] 我们也令: \[ \begin{aligned} c_\text{off} &= -\frac{t_\text{off}R}{L}\\ e_\text{off} &= e^{c_\text{off}} = e^{-\frac{t_\text{off}R}{L}} \\ I_\text{off} &= - \frac{U_\text {bemf} + U_\text D}{R} \end{aligned} \] 可见 \(I_\text{off}\) 也是 \(\frac{dI(t)}{dt} \to 0\) 时的电流,也是稳态电流。
整理得到: \[ I_\text{final} = e_\text{off}I_\text{max} + (1 - e_\text{off})I_\text{off} \] 为了后文计算平均电流的需要,我们也计算积分: \[ \int^{t_\text{off}}_0 I(t)dt = t_\text{off}\left(I_\text{off} - \frac{(1 - e_\text{off})(I_\text{max} - I_\text{off})}{c_\text{off}}\right) \]
注意到以上式子都依赖于 \(t_\text{on}\) 和 \(t_\text{off}\),前者就是占空比乘以 PWM 总周期长度,而后者则有些棘手,因为 \(t_\text{off} = t_\text{pwm} - t_\text{on}\) 并不总是成立。
接下来的分析有两种情况:
- 连续电流:PWM 周期中的电流是连续的,即 \(I_0 = I_\text{final}\)。
- 不连续电流:电流在 PWM 闭段下降至 \(0\) 被二极管截断,即 \(I_0 = I_\text{final} = 0\)。
两种情况需要分类讨论。
连续电流
由 \(I_0 = I_\text{final}\),将 \(I_\text{final}\) 展开: \[ I_0 = I_\text{final} = e_\text{off}(e_\text{on}I_0 + (1 - e_\text{on})I_\text{on}) + (1 - e_\text{off})I_\text{off} \] 解出 \(I_0\): \[ I_0 = \frac{e_\text{off}(I_\text{off} + (e_\text{on} - 1)I_\text{on}) - I_\text{off}}{e_\text{off}e_\text{on} - 1} \]
不连续电流
这个时候我们知道 \(I_0 = I_\text{final} = 0\),由 \(I_\text{final}\) 的计算式我们可以反解出 \(t_\text{off}\): \[ t_\text{off} = -\frac{L}{R}\ln\left(-\frac{I_\text{off}}{I_\text{max} - I_\text{off}}\right) \] 从实现上来说,我们先假定 \(t_\text{off} = t_\text{pwm} - t_\text{on}\)(即假设没有二极管),计算出 \(I_\text{final}\),检查它的正负性,来判断电流是否被截断。
平均电流计算
最后,我们结合计算出来的 $ t_, t_\(,以及开闭段计算出来的两个积分,我们终于可以计算 PWM 过程中的平均电流:\)$ = f_(t_(I_ -) + t_(I_ -)) $$ 这也是我们模型计算的最终结果。
在实际的实现当中需要考虑更多的细节,比如说转速的方向,命令的方向等等…… 并不总是如以上的公式那么简单,是一项艰苦的体力劳动,具体可以参考 In The Zone 下的 model.c。
逆向计算
很多时候我们不仅需要计算马达一定情况下的电流,更需要计算马达在某一状态下为了达到某一指定电流(扭矩)所需要的指令大小。例如:
- 计算空载情况下马达到达某一速度所需要的指令值(精确的马达线性化)
- 把 PID 的输出看做目标扭矩使用模型再反解出指令。
针对这个需求,因为马达曲线直观上总是单调的,因此理论上你总可以根据数学反推推出一个公式,但是由于模型当中牵涉到了分类讨论(电流的连续性),因此较为复杂。利用马达曲线的单调性,二分不失为一个更好的做法。由于指令的范围不大,我们至多只需要二分七八次即可。
注意:模型的计算在 Cortex 上还是较为耗时间的,实际当中根据当前电压计算一次完整的马达曲线需要 4 秒左右,优化常数,提高模型计算的效率一直是一个大问题,这也是为什么在实际应用中也许 tanh 线性化等计算更快的线性化的方法会更好的原因。
结果
这是真实的速度 - 指令曲线(空载):
这是使用模型计算的速度 - 指令曲线:
两者几乎一致,说明建模正确。
参数测定
马达内阻
使用伏安法,我们首先需要测量出马达在 127 命令下堵转电流 \(I_\text{stall}\),127 命令是为了尽可能消除电感的影响(即 PWM 全开),堵转是为了避免电能转化为机械能消耗掉,则根据开段分析当中的 \[ U_\text b - I(t)(R+R_\text s) - U_\text L - U_\text {bemf} = 0 \] 此时 \(U_\text L = U_\text{bemf} = 0, I(t) = I_\text{stall}\),可反解出 \[ R = \frac{U_\text b}{I_\text{stall}} - R_\text s \]
反电动势常数
我们知道 \(U_\text{bemf} = K_\text e\omega\),其中 \(\omega\) 是转速, \(K_\text e\) 为反电动势常数,为了测定其值,我们测量出马达在 127 命令无负载运转电流 \(I_\text{free}\) 和此时的转速 \(\omega_\text{free}\)(单位不论,但是需要保持统一),由 \[ U_\text b - I(t)(R+R_\text s) - U_\text L - U_\text {bemf} = 0 \] 此时 \(U_\text L = 0, I(t) = I_\text{free}\),解得 \[ U_\text{bemf} = U_\text b - I_\text{free}(R + R_\text s) \] 那么 \[ \begin{aligned} K_\text e &= \frac{U_\text b - I_\text{free}(R + R_\text s)}{\omega_\text{free}} \\ &= \left(1 - \frac{I_\text{free}}{I_\text{stall}}\right)\frac{U_\text b}{\omega_\text{free}} \end{aligned} \]