09电流环 / 速度环 / 位置环

内环快、外环慢和参数整定

本模块主旨
位置 → 速度 → 电流三层级联,外层给参考、内层快速执行;带宽逐层降 5-10 倍,整定从内向外。

学完应能回答

查看完整 Walkthrough(9 步 + 4 误区)

总览
三闭环不是"环越多越强",而是"每层比外层更快、限幅更严"。整定靠纪律不靠玄学。

零基础速入

类比
三闭环就像三层套娃:**位置环**(你想去 3 楼)→ **速度环**(电梯先上升再减速)→ **电流环**(电机出多大力气)。外层告诉内层"目标变多少",内层迅速执行;外层永远比内层慢,否则就抢着指挥乱套。
核心概念
三层级联控制:位置环 → 给速度命令 → 速度环 → 给电流命令 → 电流环 → 给电压命令。带宽自外向内逐层增大(5-10 倍),整定顺序自内向外。

为什么要学

第一手操作
右侧把"位置环 Kp"从 3.5 慢慢推到 12,看电机从平稳到达目标位置变成"过冲后回弹再过冲"。再切到"速度环 Kp"从 0.08 推到 0.4,看电机进入持续高频振荡——内外环都过激。

学习目标

核心概念

公式

三闭环级联结构
位置 PID → 速度 PI → 电流 PI → 反 Park → SVPWM → 桥臂

每层输出下一层的参考值;执行频率逐层降低(电流 PWM 同频,速度 1-2kHz,位置 100-500Hz)。

电流环带宽估算
ω_bw_i ≈ Kp / L

Kp 为电流 PI 比例增益,L 为电感。电流环 1kHz 带宽对应 Kp ≈ 7.5(L = 1.2mH)。

速度环带宽匹配
ω_bw_s ≤ ω_bw_i / (5~10)

电流环 1kHz → 速度环最多 100-200Hz。再快就开始振荡。

位置环 + 前馈
Vref = Kp_p·(Pref-P) + Vref_ff

位置环输出速度参考;加速度前馈 Vref_ff 直接前馈电流命令,可大幅提升跟踪精度。

工程意义

STM32 移植指南

常见误区

  • 先调外环还没整定内环。
  • 内外环同频同高带宽 → 必振荡。
  • 外环输出未限幅 → 电流命令瞬间冲过电机能力上限。
  • 没考虑机械惯量 J 直接用经验值。

调试方法

建议实验

STM32 C 代码骨架

/* ============================================
 * triple_loop.c — 三闭环级联调度
 * 不同环路在不同频率执行
 * ============================================ */
#include "pi.h"

/* 三个 PI 控制器实例 */
static pi_t pi_iq;          // 电流环 (16 kHz)
static pi_t pi_speed;       // 速度环 (2 kHz)
static pi_t pi_position;    // 位置环 (200 Hz)

/* 状态:参考与限幅 */
static float ref_position_deg;
static float ref_speed_rpm;
static float ref_iq_a;

/* 系统限制 */
#define IQ_MAX_A          8.0f
#define SPEED_MAX_RPM     5000.0f
#define ACCEL_MAX_RPMS    20000.0f      // rpm/s

void triple_loop_init(void) {
    /* 电流环:高带宽,PWM 同频 */
    pi_init(&pi_iq, 1.6f, 220.0f, 1.0f/16000.0f, -IQ_MAX_A * 4.0f, IQ_MAX_A * 4.0f);
    /* 速度环:内环 1/8,2 kHz */
    pi_init(&pi_speed, 0.08f, 0.8f, 1.0f/2000.0f, -IQ_MAX_A, IQ_MAX_A);
    /* 位置环:外环 1/10,200 Hz */
    pi_init(&pi_position, 3.5f, 0.2f, 1.0f/200.0f, -SPEED_MAX_RPM, SPEED_MAX_RPM);
}

/* PWM 中断 (16 kHz) — 只跑电流环 */
void TIM1_UP_IRQHandler(void) {
    float v_q = pi_step(&pi_iq, ref_iq_a, g_state.iq);
    /* ... 反 Park, SVPWM ... */
}

/* 软件定时器 (2 kHz) — 速度环 */
void speed_loop_tick(void) {
    /* 速度斜坡限幅,避免电流命令突变 */
    static float ref_speed_lim = 0;
    float dv = ref_speed_rpm - ref_speed_lim;
    float dv_max = ACCEL_MAX_RPMS / 2000.0f;
    if (dv >  dv_max) dv =  dv_max;
    if (dv < -dv_max) dv = -dv_max;
    ref_speed_lim += dv;

    ref_iq_a = pi_step(&pi_speed, ref_speed_lim, g_state.speed_rpm);
}

/* 软件定时器 (200 Hz) — 位置环 */
void position_loop_tick(void) {
    ref_speed_rpm = pi_step(&pi_position, ref_position_deg, g_state.position_deg);
}

/* === 整定步骤 ===
 * 1. 把外环(速度、位置)输出强行清零或开环,先只跑电流环;
 *    给 Iq 阶跃 (1A→3A),调 Kp 到刚开始振荡,取 0.5 倍。
 * 2. 启用速度环,位置环输出仍清零;给小速度阶跃 (100→500 rpm),
 *    调 speed Kp 到响应快但不振荡。
 * 3. 启用位置环;给斜坡位置目标,调 position Kp。
 */

下一步

随堂题

三闭环整定的正确顺序?
  1. 位置→速度→电流
  2. 速度→位置→电流
  3. 电流→速度→位置 (正确)
  4. 随便
提示:从内向外。内环不稳定,外环再怎么调都没用——外环命令送给一个不靠谱的内环,结果一样烂。
电流环带宽 1 kHz,速度环带宽多少最稳?
  1. 同 1 kHz
  2. 500 Hz
  3. 100-200 Hz (正确)
  4. 5 kHz
提示:外环带宽 = 内环 / 5-10。1kHz 内环 → 速度环 100-200 Hz 最稳。同频或更快会振荡。
位置环输出未限幅,给一个大位置阶跃会发生什么?
  1. 正常到位
  2. 速度命令瞬间冲到上千 rpm,超出电机能力 (正确)
  3. 电流降低
  4. 位置环停止
提示:Kp_p × 大误差 = 大速度命令,可能超出电机最大转速 → 速度环输出大 Iq → 撞电流限或过流保护。每环输出必须限幅。
伺服电机加速度前馈的作用?
  1. 没用
  2. 把"理想加速所需的电流"提前直接喂给电流环,减小位置/速度环负担,提高跟踪精度 (正确)
  3. 保护硬件
  4. 降低噪声
提示:反馈控制是"事后纠偏",前馈是"提前预知"。已知运动轨迹时前馈 Iq_ff = J·dω/dt 直接给到电流环参考,跟踪精度大幅提升。
电机机械惯量 J 增大 4 倍,速度环 Kp 大约该怎么调?
  1. 不变
  2. 增大 4 倍 (正确)
  3. 减小 4 倍
  4. 随便
提示:速度环面对的"被控对象增益"反比于 J(同样 Iq 加速度变小)。要保持闭环带宽不变,Kp 也要相应增大。