2、运动控制系统基础:伺服系统三环结构、位置环/速度环/电流环、典型传递函数模型

好,咱们正式开始聊运动控制的核心——伺服系统的三环结构。

很多刚入行的工程师,一听到“三环”就头大。其实说白了,就是三个控制环路,像俄罗斯套娃一样,一层套一层。最里面是电流环,中间是速度环,最外面是位置环。我当年刚接触伺服驱动时,也觉得这东西玄乎,直到亲手调过几次参数,才真正明白它们各自的分工。

2.1 三环结构:为什么需要三层?

你想想看,一个电机要精确地转到某个位置,中间要经历什么?

  • 电流环(最内层):控制电机线圈里的电流。电流直接决定力矩。这是响应最快的一环,通常带宽能做到1-2kHz甚至更高。
  • 速度环(中间层):控制电机的转速。它给电流环发指令:“我需要这么大的力矩来达到这个速度”。速度环的带宽一般在几十到几百Hz。
  • 位置环(最外层):控制最终的位置。它给速度环发指令:“我需要以这个速度运动到目标位置”。位置环带宽最低,通常只有几Hz到几十Hz。

为什么要分三层?直接控制位置不行吗?

嗯,这里要注意。如果直接控制位置,电机内部的电流波动、负载突变,都会直接影响到位置精度。分层的好处是:每一层只干自己最擅长的事。电流环负责“快”,速度环负责“稳”,位置环负责“准”。

核心观点:三环结构本质上是一种“串级控制”思想。内环的带宽必须远高于外环,通常相差5-10倍,系统才能稳定。这是我做项目时反复验证过的经验。

2.2 各环的典型传递函数模型

搞控制,离不开数学模型。咱们来看看每个环路的典型传递函数长什么样。

2.2.1 电流环

电流环的控制对象是电机绕组,可以简化成一个RL串联电路。加上PWM逆变器的延迟,电流环的传递函数通常可以写成:

G_i(s) = K_p * (1 + 1/(T_i * s)) * (1 / (R + L*s)) * (1 / (T_pwm * s + 1))

其中:

  • K_p, T_i 是PI调节器的参数
  • R, L 是电机绕组的电阻和电感
  • T_pwm 是PWM开关周期带来的延迟

我在项目中遇到过一个问题:当电机电感很小时,电流环很容易振荡。后来我把电流环的积分时间常数调大了一些,才压住振荡。说白了,电流环的PI参数和电机本身的电气参数强相关。

2.2.2 速度环

速度环的控制对象是电流环(已闭环)加上电机和负载的机械惯量。简化后的模型是:

G_v(s) = (K_v * (1 + 1/(T_v * s))) * (1 / (J * s + B)) * G_i_closed(s)

这里:

  • K_v, T_v 是速度环PI参数
  • J 是转动惯量,B 是阻尼系数
  • G_i_closed(s) 是电流环的闭环传递函数

你想想看,速度环的难点在哪里?在于惯量J的变化。比如机器人手臂,在不同姿态下,折算到电机轴上的惯量可能差好几倍。我曾经调试一个码垛机器人,空载时速度环参数好好的,一抓取重物就开始抖。后来我加了惯量辨识和前馈补偿,才算搞定。

2.2.3 位置环

位置环最简单,通常只用比例控制(P控制),甚至有些场合用纯比例就够了。传递函数:

G_p(s) = K_p * G_v_closed(s) * (1/s)

注意那个1/s,它是位置对速度的积分关系。位置环的增益K_p不能太大,否则系统会超调甚至振荡。我个人的习惯是,先让速度环响应足够快,再慢慢增加位置环增益,直到出现轻微超调,然后退回一点。

调试小技巧:调三环的顺序一定是“从内到外”。先调电流环,让它不振荡;再调速度环,让它响应快且稳;最后调位置环,追求定位精度。千万别跳级,否则你会被各种奇怪的现象搞疯。

2.3 三环参数整定的经验法则

理论讲完了,来点实际的。下面这个表格是我多年调试经验的总结,你可以作为参考起点:

环路 带宽范围 典型PI参数范围 常见问题
电流环 500Hz - 2kHz Kp: 5-50, Ki: 0.001-0.01 电感小易振荡,电感大响应慢
速度环 50Hz - 300Hz Kp: 0.5-10, Ki: 0.01-0.1 惯量变化导致不稳定
位置环 5Hz - 50Hz Kp: 1-50 (纯P) 增益过大导致超调或振荡

警告:以上参数只是参考起点。实际项目中,一定要根据具体的电机、负载、驱动器来调整。我曾经见过有人直接套用别人的参数,结果电机啸叫得像杀猪一样。记住:没有万能参数,只有合适的参数

2.4 一个简单的仿真代码示例

为了让你更直观地理解三环结构,我写了一个简单的Python仿真代码。它模拟了一个位置环+速度环+电流环的串联控制:

import numpy as np
import matplotlib.pyplot as plt

# 模拟三环控制
def three_loop_control(target_pos, dt=0.001, total_time=1.0):
    # 参数
    Kp_pos = 10.0      # 位置环增益
    Kp_vel = 2.0       # 速度环比例
    Ki_vel = 0.05      # 速度环积分
    Kp_cur = 1.0       # 电流环比例
    Ki_cur = 0.01      # 电流环积分
    
    J = 0.01           # 惯量
    B = 0.001          # 阻尼
    R = 1.0            # 电阻
    L = 0.005          # 电感
    
    # 状态变量
    pos = 0.0
    vel = 0.0
    cur = 0.0
    vel_int = 0.0
    cur_int = 0.0
    
    time_steps = int(total_time / dt)
    pos_log = []
    
    for i in range(time_steps):
        # 位置环:计算速度指令
        pos_error = target_pos - pos
        vel_cmd = Kp_pos * pos_error
        
        # 速度环:计算电流指令
        vel_error = vel_cmd - vel
        vel_int += vel_error * dt
        cur_cmd = Kp_vel * vel_error + Ki_vel * vel_int
        
        # 电流环:计算电压指令
        cur_error = cur_cmd - cur
        cur_int += cur_error * dt
        voltage = Kp_cur * cur_error + Ki_cur * cur_int
        
        # 电机模型
        d_cur = (voltage - R*cur - 0.0) / L  # 忽略反电动势简化
        cur += d_cur * dt
        
        torque = cur  # 假设力矩常数=1
        d_vel = (torque - B*vel) / J
        vel += d_vel * dt
        
        pos += vel * dt
        
        pos_log.append(pos)
    
    return pos_log

# 运行仿真
result = three_loop_control(1.0)
print("仿真完成,最终位置:", result[-1])

这个代码虽然简化了很多东西(比如忽略了反电动势、PWM延迟等),但三环的骨架是完整的。你可以试着改改Kp_pos、Kp_vel这些参数,看看位置响应会怎么变化。我建议你亲手跑一跑,比看十遍理论都管用。

2.5 小结

这一章我们聊了三环结构的基本原理和传递函数模型。记住几个关键点:

  • 电流环是基础,响应最快,负责力矩控制
  • 速度环是中间层,负责转速稳定
  • 位置环是最外层,负责定位精度
  • 调试顺序永远是:电流环 → 速度环 → 位置环

下一章,我们会深入讨论前馈补偿技术。为什么有了三环反馈还不够?前馈到底能解决什么问题?到时候我会结合一个实际案例来讲,敬请期待。