4、坐标变换基础:Clark变换与Park变换的数学推导、变换在电流环中的作用、离散化实现注意事项
坐标变换,说白了就是换个角度看问题。
你想想看,电机里转的是三相正弦电流,可我们控制器能直接处理的,是直流量。怎么把交流量变成直流量?这就是Clark和Park两兄弟干的事。我当年刚接触伺服驱动时,觉得这玩意儿就是一堆数学公式,没啥意思。直到有一次调试电流环,发现PI参数怎么调都调不好,后来才意识到——哦,原来是坐标变换没搞对。
4.1 为什么需要坐标变换?
三相永磁同步电机(PMSM)的数学模型,在三相静止坐标系下是时变的、强耦合的。说白了,就是A相电流不仅影响A相,还影响B相和C相。你调一个参数,三个相都跟着变,这谁受得了?
坐标变换的目的,就是把三相交流量,变成两相直流量。这样一来,电流环的控制对象就从交流变成了直流,PI控制器就能发挥它的看家本领了。
核心思想:三相交流 → 两相交流(Clark) → 两相直流(Park)
4.2 Clark变换:从ABC到αβ
Clark变换,也叫3/2变换。它把三相静止坐标系(A、B、C)下的量,映射到两相静止坐标系(α、β)下。
数学推导其实不复杂。假设三相电流是平衡的,即 iA + iB + iC = 0。那么Clark变换的公式就是:
iα = iA
iβ = (iA + 2*iB) / √3
等等,你可能会问:为什么不是标准的等幅值变换?
嗯,这里有个细节。Clark变换有两种常见形式:等幅值变换和等功率变换。我个人习惯用等幅值变换,因为这样变换后的αβ电流幅值,和三相电流幅值是一样的,调试时直观一些。
完整的矩阵形式是这样的:
[ iα ] [ 1 -1/2 -1/2 ] [ iA ]
[ iβ ] = [ 0 √3/2 -√3/2 ] [ iB ]
[ i0 ] [ 1/2 1/2 1/2 ] [ iC ]
注意那个i0分量。在三相平衡系统中,i0 = 0,可以忽略。但如果你遇到三相不平衡的情况,比如电机缺相或者电流传感器有偏差,i0就不为零了。我在项目中遇到过这种情况,当时电流环一直震荡,查了半天才发现是传感器零漂导致的i0分量在作怪。
4.3 Park变换:从αβ到dq
Clark变换完了,我们得到了两相交流量iα和iβ。但它们还是交流的,频率和电机转速有关。要变成直流量,还得再转一次——Park变换。
Park变换的核心,就是让坐标系跟着转子一起转。转子转多快,坐标系就转多快。这样,原本旋转的电流矢量,在新的坐标系下就静止了。
公式很简单:
id = iα * cos(θ) + iβ * sin(θ)
iq = -iα * sin(θ) + iβ * cos(θ)
这里的θ,就是转子位置角,通常由编码器或霍尔传感器提供。
变换之后,id和iq就变成了直流量。id控制励磁,iq控制转矩。这就是我们常说的矢量控制(FOC)的基础。
我的经验:Park变换对角度精度要求很高。角度误差1度,电流环性能就会下降不少。我建议用高分辨率编码器,至少17位以上。如果角度有延迟,记得做角度补偿。
4.4 变换在电流环中的作用
坐标变换在电流环里,到底起了什么作用?
说白了,就是把一个非线性、时变、强耦合的系统,变成了一个线性、时不变、解耦的系统。
没有坐标变换,你面对的是三个相互影响的PI环。有了坐标变换,你只需要调两个独立的PI环——d轴和q轴。而且这两个环的参数,在电机整个转速范围内基本不变。
我举个例子。有一次我调试一个高速主轴电机,转速到15000rpm。如果没有坐标变换,电流环的带宽根本提不上去,因为三相电流的频率太高了,PI控制器跟不上。但用了坐标变换后,d轴和q轴的电流是直流量,PI控制器可以轻松应对。
下面这张图,展示了整个变换的流程:
4.5 离散化实现注意事项
理论讲完了,咱们聊聊实战。坐标变换在数字控制器里实现,有几个坑要注意。
4.5.1 角度同步问题
Clark变换不需要角度,但Park变换需要。角度从哪里来?从编码器来。但编码器采样和电流采样,往往不是同一时刻发生的。
我曾经踩过这个坑。电流采样和角度采样之间有几十微秒的延迟,结果高速时电流环性能急剧下降。后来我加了角度预测补偿,才把问题解决。
注意:在高速运行时,角度延迟会导致Park变换后的dq轴电流出现耦合。建议在Park变换前,对角度做一步预测:θpred = θmeas + ω * Tdelay。
4.5.2 计算精度与溢出
坐标变换里有很多三角函数和开方运算。在定点DSP上实现时,要特别注意精度问题。
我建议用Q格式来做定点运算。比如Q15格式,可以表示-1到0.9999之间的数,精度足够。但要注意,中间计算结果可能会溢出,需要做饱和处理。
下面是一个C语言的离散化实现示例:
// Clark变换(等幅值)
void clark_transform(int16_t iA, int16_t iB, int16_t iC,
int16_t *iAlpha, int16_t *iBeta) {
// 假设输入是Q15格式
*iAlpha = iA; // iα = iA
// iβ = (iA + 2*iB) / √3
// 1/√3 ≈ 0.57735,在Q15中为 18919
int32_t tmp = (int32_t)iA + 2 * (int32_t)iB;
*iBeta = (int16_t)((tmp * 18919) >> 15);
}
// Park变换
void park_transform(int16_t iAlpha, int16_t iBeta, int16_t sinTheta, int16_t cosTheta,
int16_t *iD, int16_t *iQ) {
// id = iα*cosθ + iβ*sinθ
int32_t id_tmp = (int32_t)iAlpha * cosTheta + (int32_t)iBeta * sinTheta;
*iD = (int16_t)(id_tmp >> 15);
// iq = -iα*sinθ + iβ*cosθ
int32_t iq_tmp = -(int32_t)iAlpha * sinTheta + (int32_t)iBeta * cosTheta;
*iQ = (int16_t)(iq_tmp >> 15);
}
4.5.3 反Park变换
别忘了,电流环输出的是dq轴电压,要送到SVPWM模块,还得先做反Park变换,把dq电压变回αβ电压。
反Park变换的公式:
uα = ud * cos(θ) - uq * sin(θ)
uβ = ud * sin(θ) + uq * cos(θ)
这个变换同样要注意角度同步问题。我习惯把正反Park变换放在同一个中断里,用同一个角度值,这样能保证一致性。
4.5.4 执行频率
坐标变换的执行频率,应该和电流环的采样频率一致。通常电流环频率在10kHz到20kHz之间。
如果频率太低,比如只有5kHz,那么对于高速电机来说,一个电周期内只有几个采样点,变换后的dq电流会有很大的纹波。我建议至少保证每个电周期有20个以上的采样点。
| 电机极对数 | 最高转速(rpm) | 电频率(Hz) | 建议采样频率(kHz) |
|---|---|---|---|
| 4 | 3000 | 200 | ≥4 |
| 4 | 6000 | 400 | ≥8 |
| 8 | 10000 | 1333 | ≥26 |
我的建议:如果MCU算力够,把坐标变换和电流环都放在同一个中断里,频率做到20kHz。这样既能保证实时性,又能减少延迟。如果算力紧张,至少也要做到10kHz。
4.6 小结
坐标变换是电流环的基石。Clark变换把三相变两相,Park变换把交流变直流。这两个变换做对了,电流环的带宽才能提上去。
离散化实现时,重点关注三点:角度同步、计算精度、执行频率。这三个坑我都踩过,希望你别再踩一遍。
嗯,坐标变换就聊到这里。记住,理论要扎实,实现要细致。电流环的性能,很大程度上取决于坐标变换的质量。
公众号:蓝海资料掘金营,微信deep3321