Skip to content

FOC 磁场定向控制算法

FOC 简介

FOC(Field Oriented Control,磁场定向控制)是一种用于直流无刷电机(BLDC)和交流感应电动机控制的高级技术。它通过将电动机的电流分解为产生转矩的分量和产生磁通的分量,实现高效和精确的电机控制。

工作原理

FOC 的核心思想是:

  1. 检测电机转子位置 - 通过编码器或霍尔传感器
  2. 坐标变换 - 将三相电流转换到 dq 坐标系
  3. 独立控制 - 分别控制 d 轴和 q 轴电流
  4. 逆变换 - 将控制信号转换回三相信号

LeBot 中的应用

LeBot 的腿部和轮子驱动采用直流无刷电机,FOC 用于:

  • 精确的转速控制
  • 扭矩控制
  • 能量效率提升
  • 低速平稳运行
  • 减小电磁噪声

FOC 基本原理

三相电机模型

交流电动机的三相电流可以表示为:

三个相位相差 120°。

Clark 变换(三相到两相)

将三相电流 (i_a, i_b, i_c) 转换到 (α, β) 静止坐标系:

Park 变换(两相到旋转坐标系)

从静止的 (α, β) 坐标系转换到随转子旋转的 (d, q) 坐标系:

其中 θ 是转子磁通方向角。

逆 Park 和逆 Clark 变换

将控制电压从 dq 坐标系转换回三相:

Python 中的 FOC 实现

基础 FOC 控制器

python
import numpy as np
from typing import Tuple

class FOCController:
    """磁场定向控制(FOC)控制器"""

    def __init__(self,
                 motor_poles: int = 4,
                 kp_id: float = 1.0,
                 ki_id: float = 0.1,
                 kp_iq: float = 1.0,
                 ki_iq: float = 0.1):
        """
        初始化 FOC 控制器

        参数:
            motor_poles: 电机极对数
            kp_id, ki_id: d 轴 PI 控制器参数
            kp_iq, ki_iq: q 轴 PI 控制器参数
        """
        self.poles = motor_poles

        # PI 控制器参数
        self.kp_id = kp_id
        self.ki_id = ki_id
        self.kp_iq = kp_iq
        self.ki_iq = ki_iq

        # 积分项累加
        self.integral_id = 0.0
        self.integral_iq = 0.0

        # 反正切查找表(用于位置估计)
        self.rotor_angle = 0.0

    def clark_transform(self,
                       ia: float, ib: float, ic: float) -> Tuple[float, float]:
        """
        Clark 变换:三相到两相

        参数:
            ia, ib, ic: 三相电流

        返回:
            (i_alpha, i_beta)
        """
        i_alpha = ia
        i_beta = (ia + 2*ib) / np.sqrt(3)

        return i_alpha, i_beta

    def park_transform(self,
                      i_alpha: float,
                      i_beta: float,
                      theta: float) -> Tuple[float, float]:
        """
        Park 变换:两相到旋转坐标系

        参数:
            i_alpha, i_beta: 静止坐标系电流
            theta: 转子位置角

        返回:
            (i_d, i_q)
        """
        cos_theta = np.cos(theta)
        sin_theta = np.sin(theta)

        i_d = i_alpha * cos_theta + i_beta * sin_theta
        i_q = -i_alpha * sin_theta + i_beta * cos_theta

        return i_d, i_q

    def inverse_park_transform(self,
                              v_d: float,
                              v_q: float,
                              theta: float) -> Tuple[float, float]:
        """
        逆 Park 变换

        参数:
            v_d, v_q: 旋转坐标系电压
            theta: 转子位置角

        返回:
            (v_alpha, v_beta)
        """
        cos_theta = np.cos(theta)
        sin_theta = np.sin(theta)

        v_alpha = v_d * cos_theta - v_q * sin_theta
        v_beta = v_d * sin_theta + v_q * cos_theta

        return v_alpha, v_beta

    def inverse_clark_transform(self,
                               v_alpha: float,
                               v_beta: float) -> Tuple[float, float, float]:
        """
        逆 Clark 变换:两相到三相

        参数:
            v_alpha, v_beta: 静止坐标系电压

        返回:
            (v_a, v_b, v_c)
        """
        v_a = v_alpha
        v_b = -v_alpha/2 + np.sqrt(3)*v_beta/2
        v_c = -v_alpha/2 - np.sqrt(3)*v_beta/2

        return v_a, v_b, v_c

    def pi_controller(self,
                     error: float,
                     kp: float,
                     ki: float,
                     integral: float) -> Tuple[float, float]:
        """
        PI 控制器

        参数:
            error: 控制误差
            kp: 比例系数
            ki: 积分系数
            integral: 积分项

        返回:
            (output, new_integral)
        """
        integral += error
        integral = np.clip(integral, -1.0, 1.0)  # 防止积分饱和

        output = kp * error + ki * integral

        return output, integral

    def control_step(self,
                    ia: float, ib: float, ic: float,
                    id_ref: float, iq_ref: float,
                    rotor_angle: float,
                    dt: float = 0.001) -> Tuple[float, float, float]:
        """
        执行一步 FOC 控制

        参数:
            ia, ib, ic: 三相电流
            id_ref, iq_ref: 参考 d、q 轴电流
            rotor_angle: 转子位置角
            dt: 时间步长

        返回:
            (va, vb, vc) - 三相输出电压
        """
        # 步骤 1:Clark 变换(三相 -> 两相)
        i_alpha, i_beta = self.clark_transform(ia, ib, ic)

        # 步骤 2:Park 变换(两相 -> dq)
        i_d, i_q = self.park_transform(i_alpha, i_beta, rotor_angle)

        # 步骤 3:dq 电流控制(PI 控制器)
        error_id = id_ref - i_d
        v_d, self.integral_id = self.pi_controller(
            error_id, self.kp_id, self.ki_id, self.integral_id
        )

        error_iq = iq_ref - i_q
        v_q, self.integral_iq = self.pi_controller(
            error_iq, self.kp_iq, self.ki_iq, self.integral_iq
        )

        # 步骤 4:逆 Park 变换(dq -> 两相)
        v_alpha, v_beta = self.inverse_park_transform(v_d, v_q, rotor_angle)

        # 步骤 5:逆 Clark 变换(两相 -> 三相)
        va, vb, vc = self.inverse_clark_transform(v_alpha, v_beta)

        # 归一化(电压限制)
        v_max = 1.0
        v_scale = max(abs(va), abs(vb), abs(vc), v_max)
        if v_scale > v_max:
            va /= v_scale
            vb /= v_scale
            vc /= v_scale

        return va, vb, vc


class BLDCMotorWithFOC:
    """带 FOC 控制的直流无刷电机"""

    def __init__(self,
                 motor_poles: int = 4,
                 motor_inertia: float = 0.01,
                 motor_resistance: float = 1.0):
        """
        初始化 BLDC 电机

        参数:
            motor_poles: 极对数
            motor_inertia: 转动惯量
            motor_resistance: 电阻
        """
        self.poles = motor_poles
        self.J = motor_inertia
        self.R = motor_resistance
        self.Ke = 0.1  # 反电动势常数
        self.Kt = 0.1  # 转矩常数

        # 电机状态
        self.omega = 0.0  # 转速
        self.theta = 0.0  # 转子位置

        # FOC 控制器
        self.foc = FOCController(motor_poles)

    def update(self,
              ia: float, ib: float, ic: float,
              id_ref: float, iq_ref: float,
              load_torque: float = 0.0,
              dt: float = 0.001):
        """
        更新电机状态

        参数:
            ia, ib, ic: 三相电流
            id_ref, iq_ref: 参考电流
            load_torque: 负载扭矩
            dt: 时间步长
        """
        # 执行 FOC 控制
        va, vb, vc = self.foc.control_step(
            ia, ib, ic, id_ref, iq_ref, self.theta, dt
        )

        # 计算电机转矩
        # 对于 BLDC 电机,转矩正比于 q 轴电流
        torque = self.Kt * iq_ref

        # 计算加速度
        angular_accel = (torque - load_torque) / self.J

        # 更新转速和位置
        self.omega += angular_accel * dt
        self.theta += self.omega * dt

        # 位置归一化到 [0, 2π)
        self.theta = self.theta % (2 * np.pi)


# 使用示例
if __name__ == "__main__":
    # 创建带 FOC 的 BLDC 电机
    motor = BLDCMotorWithFOC(motor_poles=4)

    # 模拟控制
    dt = 0.001  # 1 ms
    t_total = 5.0  # 5 秒
    steps = int(t_total / dt)

    id_ref = 0.0  # 不需要磁通
    iq_ref = 0.5  # 50% 转矩

    time_log = []
    omega_log = []

    for step in range(steps):
        t = step * dt

        # 假设测量的三相电流(简化)
        ia = 0.1 * np.sin(motor.theta)
        ib = 0.1 * np.sin(motor.theta - 2*np.pi/3)
        ic = 0.1 * np.sin(motor.theta - 4*np.pi/3)

        # 更新电机
        motor.update(ia, ib, ic, id_ref, iq_ref, load_torque=0.0, dt=dt)

        # 记录
        time_log.append(t)
        omega_log.append(motor.omega)

        if step % 5000 == 0:
            print(f"t={t:.2f}s, ω={motor.omega:.3f} rad/s, θ={motor.theta:.3f} rad")

    print(f"\n最终转速: {motor.omega:.3f} rad/s")

FOC 的优势

  1. 高效率 - 最大化转矩输出
  2. 低纹波 - 平稳运行,低噪声
  3. 精确控制 - 独立控制磁通和转矩
  4. 宽速度范围 - 从低速到高速都能工作

FOC 与传统控制的对比

特性六步换向FOC
控制复杂度
效率中等
转矩纹波
噪声
实时计算量中等

LeBot 电机控制架构

转速参考 ωref

┌──────────────────┐
│  速度控制器      │  → 电流参考 iq_ref
└──────────────────┘

┌──────────────────┐
│  FOC 控制器      │
│  - Clark 变换    │
│  - Park 变换     │
│  - PI 控制       │
└──────────────────┘

┌──────────────────┐
│  PWM 调制        │  → 三相 PWM 信号
└──────────────────┘

  BLDC 电机

参数调整

  • Kp_iq:控制转矩响应速度,范围 0.5 - 2.0
  • Ki_iq:消除稳态误差,范围 0.01 - 0.2
  • Kp_id:控制磁通响应,通常设为 0
  • Ki_id:通常不使用

总结

FOC 是实现高性能直流无刷电机控制的关键技术:

  • 基于坐标变换的解耦控制
  • 在 LeBot 中实现精确的运动控制
  • 提高能源利用效率
  • 降低电磁噪声

在 LeBot 的所有电动机(腿驱动、轮驱动)上都应该应用 FOC 以获得最佳性能。


参考资源

由 LeBot 开发团队编写