FOC 参考手册 01 基础

标幺值与缩放

每一台量产驱动器都会做、但大多数教程却直接跳过的两项基础换算。它们本是两个独立的概念,却总是配合使用,因为它们恰好解决了同一个问题的两半:国际单位制(SI)既不便于直观分析控制器参数,也不便于在微控制器中高效运算。

国际单位制物理量除以基准值得到标幺值,再乘以 2 的幂次缩放为 MCU 存储的整数。 建模方式选择 存储格式选择 国际单位制(SI)物理量 A, V, rad/s ÷ 基准值 I base , V base , ω base 标幺值(p.u.) 绝大部分落在 ±1 内 × 2^n 定点 Q 格式 整型数 MCU 寄存器实际存储值 动态裕量校核 何处会发生溢出?
两次归一化处理,按此顺序依次应用。将两者分开处理,使得你可以在不调整任何一个控制器增益的情况下改变 ADC 的缩放系数。

标幺值:将所有物理量除以其基准值

选定三个基本基准值——电流、电压和转速——并将所有物理量表示为相应基准值的比值(即标幺值)。其余物理量的基准值均可由此导出:

对于参考电机,取基准电流为 40 A、基准电压为逆变器线性区电压上限 V、基准转速为 3000 rpm:

基准量数值
电流40 A
电压27.71 V
转速1257 弧度/秒(电角度,即 3000 转/分钟)
阻抗0.693 Ω
电感551 µH
磁链0.0221 Wb
转矩5.29 N·m
功率1663 W

而电机本身则被转化为一组无量纲数值:

现在各参数的量级都在 1 附近。这并非形式上的好处,而是能让错误的数值显得不合理。标幺值电阻为 0.505,显然像一台正常电机;若为 8.0,则明显异常。以国际单位制表示时,若不了解电机,仅凭 0.35 Ω 无从判断。

在试验台上 基准值只是一种约定,并非事实;如果不明确所使用的基准值,标幺值就没有意义。请将基准值与常数一同标注。最常见的标幺值错误并非算术问题,而是两位工程师分别使用峰值电流和有效值电流作为基准,却都未予说明。

优势:一次整定,多机复用

取另一台电机:电阻和电感都是原电机的四倍,磁链是两倍;再把它的基准电流设为原电机的一半、基准电压设为两倍。这样得到的标幺值描述与原电机相同。本站的测试验证了这一点,数值误差低于 1e-12。

因此,同一组控制器参数在两台电机上都能正常工作。物理参数截然不同的电机,却可以使用同一组控制增益,因为在标幺值体系下它们是同一台电机。这正是引入这套额外换算的全部理由,也是电机控制库普遍采用标幺值编写的原因。

时间常数的关系同样得以保留:

换回国际单位制后,时间常数是 600 µs,恰好等于 ,符合预期。

在试验台上 建议将电压基准值选为逆变器的线性区上限 ,而非 。这样一来,1.0 标幺值的调制比就精确对应“线性调制区的边界”,任何大于 1.0 的电压指令都能一眼识别为过调制,无需任何额外换算。

定点数:在硬件中表示标幺值

标幺值使所有量都接近于 1。定点数是在没有浮点运算单元的处理器上存储接近 1 的数值的方式——将其表示为整数,并隐含一个二进制小数点。

Qn 表示小数点后有 n 位。下面两个性质尤其重要:

对于一个b位的字而言,分辨率与动态范围成反比,具体选择取决于小数位的分配位置。

格式
信号

基准电流是驱动器的额定峰值相电流——小型工业伺服为5 A,电动自行车或叉车驱动则为200 A。调整该值改变的是所针对的驱动器规格,而非本页所示的电机;它仅决定了一个最低有效位(LSB)在安培单位下的数值。

以所选格式存储一个电周期。下方的误差曲线具有独立的刻度——通常比上方的信号细数千倍——因此能够清晰显示。勾选溢出时回绕复选框,并将幅值推至超出限制。

Q15 没有裕量,这正是陷阱所在

对于16位字,显而易见的选择是Q15格式:全部15个非符号位均为小数位。该格式可提供极高的分辨率——在40 A基准下为1.22 mA——且动态范围恰好为。

请注意括号。Q15 无法表示 1.0。 任何可能合法达到或超过额定值的标幺值都会溢出:

  • 阶跃过程中的电流瞬态,
  • 过调制时的电压请求,
  • 发生积分饱和的积分器,
  • 1.0 标幺值的转矩需求。

解决办法是留出一位表示整数部分。16 位 Q14 格式的可表示范围为 ,分辨率为 2.44 mA:精度减半,余量加倍,额定值处不再溢出。对于 32 位处理器,这个问题基本消失;Q24 的范围可达 标幺值,分辨率为 0.002 mA。

格式范围(标幺值)在40 A时的分辨率0.8 标幺值时的信噪比
16 位 Q15±1.0(不含 +1.0)1.22 mA96 dB
16 位 Q14±2.02.44 mA90 dB
32 位 Q24±1280.002 mA150 dB

溢出时饱和处理,绝不回绕

这种错误可能损坏硬件。

采用饱和格式时,1.2 标幺值的电流发生溢出后会被记作 1.0——虽然有 17% 的误差,但符号和数量级都是正确的。控制器认为电流偏小,只会稍微加大输出,系统仍可恢复。

当一个 回绕 格式的数值发生溢出时,1.2 pu 会被读作 −0.8。符号发生了反转。此时控制器会认为电流流向相反,并进一步加大驱动,使其沿原方向继续流动。这并非简单的测量精度下降,而是一种失控现象,且会在一个控制周期内发生。

该图显示了差值。以40 A为基准时,1.3 pu的信号对应52 A,这是一个合理的暂态值,以Q15格式存储:

溢出行为最坏误差
饱和12 A
回绕80 A

情况几乎恶化了七倍,而且指向了错误的方向。勾选 溢出时回绕,并将幅值推过极限,即可观察到波形反相。然后将 整数位 设置为 1——即 Q14 格式,量程 ±2.0——误差便降至 1.2 mA,因为数值仍在范围内。

在试验台上 C 语言内置的整数运算默认会发生溢出回绕。饱和处理必须显式指定——要么调用饱和内联指令(如 Cortex-M 上的 __SSAT,或 DSP 扩展指令集中的饱和乘累加指令),要么在每次写入存储前显式执行限幅(clamp)。每一处将标幺值截断为较窄位宽的地方,都必须逐一检查。

缩放不会凭空增加精度

一种格式只有在信号满量程时才能提供其标称分辨率。在满量程的十分之一处,你会损失超过三位——信噪比下降20 dB,有效字长比你购买的规格短了三位。

实际后果是:应将电流基准值选取为接近你实际要测量的最大电流,而非某个遥远的 绝对最大值。如果按你希望永远不会出现的故障电流来设定基准,那么其分辨率的 大部分都将用于表示那些你根本不会遇到的数值。

单位换算应当放在何处

可行的模式是在 边界 进行归一化,并在内部所有地方都以标幺值进行计算:

/* Edge: ADC counts -> per-unit, once, on the way in. */
const q15_t i_a = mul_q15(adc_a - offset_a, ADC_TO_PU);

/* Interior: everything is per-unit and dimensionless. */
foc_step(i_a, i_b);

/* Edge: per-unit -> compare register counts, once, on the way out. */
timer->CCR1 = mul_q15(duty_a, PWM_PERIOD_COUNTS);

两次单位转换都发生在边界处,而控制算法中从未出现过任何单位。另一种做法——在控制回路内部反复进行单位转换——则容易引入缩放误差,因为每次转换都有可能使用错误的基准,而且这些转换在方程中完全不可见。

在试验台上 在编写任何代码之前,先在纸上完成标幺值体系的设计,并将基准值表作为注释写在常量定义旁边。几乎所有的缩放错误归根结底都是账目管理失误:有人混用了属于另一个物理量的基准值,而算出的结果又看似合理,就这样一路混进了量产代码。

要点回顾

  • 选定三个基本基准值——电流、电压、转速——其余所有基准值均可由此导出。务必将它们明确记录在注释中。
  • 采用标幺值时,各电机参数均接近 1,因此错误的数值会显得尤为明显。
  • 两台物理特性不同的电机,若采用相同的标幺值描述,则可使用相同的控制器参数。这正是采用标幺值的意义所在。
  • 将电压基准设为 ,使得 1.0 标幺值表示“线性区的边界”。
  • 16位的Q15格式无法表示1.0。要么预留一些裕量,要么采用32位格式,这样就不会出现这个问题。
  • 溢出时进行饱和处理。溢出回绕会导致符号反转,而符号反转的电流会造成失控,而非错误。
  • 一种数据格式只有对满量程信号才能发挥其标称分辨率。应根据实际要测量的电流来设定基准值,而不是根据你担心的极限故障电流。

接下来可以先读空间矢量;如果已经读过,就前往Clarke 与 Park 变换,了解如何控制这个矢量。