电路图

绿色箭头为 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}\) 并不总是成立

接下来的分析有两种情况:

  1. 连续电流:PWM 周期中的电流是连续的,即 \(I_0 = I_\text{final}\)
  2. 不连续电流:电流在 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

逆向计算

很多时候我们不仅需要计算马达一定情况下的电流,更需要计算马达在某一状态下为了达到某一指定电流(扭矩)所需要的指令大小。例如:

  1. 计算空载情况下马达到达某一速度所需要的指令值(精确的马达线性化)
  2. 把 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} \]