1. FOC基础概念与坐标系变换

任务目标

本案例实现无感FOC中最基础的坐标变换链路:将电机三相电流(ia、ib、ic)经Clarke变换得到静止α-β轴电流,再经Park变换得到旋转d-q轴电流。最终输出可供电流环使用的id、iq,并验证变换结果在给定输入下的正确性。

核心原理与实现

Clarke变换(等幅值约束)将三相静止坐标映射到两相静止坐标:

iα = ia
iβ = (ia + 2·ib) / √3

Park变换将静止α-β坐标映射到随转子旋转的d-q坐标(θ为转子电角度):

id = iα·cosθ + iβ·sinθ
iq = -iα·sinθ + iβ·cosθ

以下代码实现完整变换链,并包含一个自检测试:输入三相对称电流与给定电角度,验证输出id、iq是否符合理论值。

关键完整代码

#include <stdio.h>
#include <math.h>

#define PI 3.14159265358979323846

// Clarke变换:三相abc -> 两相静止αβ(等幅值)
void clarke(float ia, float ib, float ic, float *i_alpha, float *i_beta) {
    *i_alpha = ia;
    *i_beta  = (ia + 2.0f * ib) / sqrtf(3.0f);
}

// Park变换:静止αβ -> 旋转dq
void park(float i_alpha, float i_beta, float theta, float *id, float *iq) {
    float cos_t = cosf(theta);
    float sin_t = sinf(theta);
    *id =  i_alpha * cos_t + i_beta * sin_t;
    *iq = -i_alpha * sin_t + i_beta * cos_t;
}

// 自检:三相对称电流 + 已知电角度 -> 验证dq输出
void self_test(void) {
    // 输入:幅值1A的三相平衡电流,电角度30°(PI/6)
    float theta = PI / 6.0f;
    float ia = 1.0f;
    float ib = -0.5f;
    float ic = -0.5f;

    float i_alpha, i_beta, id, iq;
    clarke(ia, ib, ic, &i_alpha, &i_beta);
    park(i_alpha, i_beta, theta, &id, &iq);

    printf("i_alpha = %.4f A\n", i_alpha);
    printf("i_beta  = %.4f A\n", i_beta);
    printf("id = %.4f A\n", id);
    printf("iq = %.4f A\n", iq);

    // 理论预期:id = 1.0(与d轴对齐),iq = 0.0
    printf("\n预期: id ≈ 1.0000, iq ≈ 0.0000\n");
}

int main(void) {
    self_test();
    return 0;
}

运行与验证

编译运行:

gcc -o foc_transform foc_transform.c -lm
./foc_transform

通过条件:程序输出中id ≈ 1.0000且iq ≈ 0.0000(浮点误差±0.0001以内)。

验证逻辑说明:输入三相电流幅值1A且相位与d轴初始方向一致(θ=30°时,合成电流矢量恰好与d轴重合),因此理论上d轴电流等于相电流幅值,q轴电流为0。若输出与此不符,说明变换符号或系数有误。

常见问题

  • 等幅值与等功率变换:本实现采用等幅值约束(Clarke系数为1和1/√3),若使用等功率约束(系数√(2/3)),dq输出会相应缩放,需与电流环PI参数匹配。
  • θ的参考点:Park变换中θ为转子d轴与α轴的电角度,实际工程中由编码器或观测器提供,本案例用固定值验证数学正确性。
  • 三相电流采样:实际FOC中ia+ib+ic=0,通常只采样两相即可计算第三相,但本案例直接给定三相以验证完整变换链。