电机控制(四)-级联PID控制器与参数整定(MATLAB&Simulink)

发布于:2025-09-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

PID算法

普通PID(Proportional-Integral-Derivative)

通过比例(P)、积分(I)和微分(D)三项来进行控制

  • 比例项(P):根据当前误差(目标值与实际值之差)进行控制。误差越大,控制量也越大,但容易导致稳态误差。

    P = K p ⋅ e ( t ) P = K_p \cdot e(t) P=Kpe(t)

  • 积分项(I):累积误差,可以消除稳态误差,特别是在误差长时间存在时,但可能会导致系统超调和震荡。

    I = K i ⋅ ∫ e ( t )   d t I = K_i \cdot \int e(t) \, dt I=Kie(t)dt

  • 微分项(D):根据误差的变化率进行控制,用来预测误差的变化,从而减小超调和改善系统响应速度。

    D = K d ⋅ d d t e ( t ) D = K_d \cdot \frac{d}{dt} e(t) D=Kddtde(t)

PID的实现分为两种:

  • 标准型PID: D = K ( e ( t ) + 1 τ i ∫ e ( t ) + 1 τ d d e ( t ) d t ) D = K(e(t)+ \frac{1}{\tau_i} \int e(t)+ \frac{1}{\tau_d} \frac{de(t)}{dt}) D=K(e(t)+τi1e(t)+τd1dtde(t))
    • τ i \tau_i τi称为积分时间,物理含义为积分项需要多长时间才能追上比例项, τ d \tau_d τd称为微分时间,物理含义为比例项需要多久才能追上微分项。
  • 并联型PID: D = K p e ( t ) + K i ∫ e ( t ) + K d d e ( t ) d t D = K_pe(t)+ K_i \int e(t)+ K_d \frac{de(t)}{dt} D=Kpe(t)+Kie(t)+Kddtde(t)

标准型PID的好处在于确定了积分时间 τ i \tau_i τi和微分时间 τ d \tau_d τd之后,系统就只剩一个增益参数需要调节了。
将其进行拉普拉斯变换得到频域格式: C = K p ( 1 + 1 T i s + T d s ) C = K_p\left(1 + \frac{1}{T_i s} + T_ds\right) C=Kp(1+Tis1+Tds)

  • 在matlab中提供了标准型PID的函数pidstd,但是文档中可以看到其频域公式格式为: C = K p ( 1 + 1 T i s + T d s T d N s + 1 ) C = K_p\left(1 + \frac{1}{T_i s} + \frac{T_d s}{\frac{T_d}{N} s + 1}\right) C=Kp(1+Tis1+NTds+1Tds),这其中的N为滤波器除数。
  • 因为实际使用中,信号多来自于传感器,具有一些高频噪声,普通的微分环节从频率响应的角度来看,其幅频特性 ∣ G ( j ω ) ∣ = K d ω |G(j\omega)|=K_d\omega G()=Kdω,会放大高频信号,导致系统不稳定。
  • 通过在微分环节中添加一个低通滤波器 G ( s ) = 1 1 ω c s + 1 G(s)=\frac{1}{\frac{1}{\omega_c}s+1} G(s)=ωc1s+11,然后整体的传递函数变为 G ( s ) = K d s 1 ω c s + 1 G(s)=\frac{K_ds}{\frac{1}{\omega_c}s+1} G(s)=ωc1s+1Kds,其幅频特性为 ∣ G ( j ω ) ∣ = ∣ K d ( j ω ) 1 ω c ( j ω ) + 1 ∣ = ∣ K d ( j ω ) ∣ ∣ 1 ω c ( j ω ) + 1 ∣ = K d ⋅ ω 1 + ( ω ω c ) 2 |G(j\omega)|=|\frac{K_d (j\omega)}{\frac{1}{\omega_c}(j\omega)+ 1}|=\frac{|K_d (j\omega)|}{|\frac{1}{\omega_c}(j\omega)+ 1|}=\frac{K_d \cdot \omega}{\sqrt{1 + \left( \frac{\omega}{\omega_c} \right)^2}} G()=ωc1()+1Kd()=ωc1()+1∣Kd()=1+(ωcω)2 Kdω,当 ω \omega ω较小时,跟普通微分环节没什么区别,当 ω \omega ω较大时,幅频特性趋近于常数 K d K_d Kd,避免了高频信号的干扰。

其中, u ( t ) u(t) u(t) 是控制信号, K p K_p Kp, K i K_i Ki, K d K_d Kd 是PID常数, e ( t ) e(t) e(t) 是误差。
适用于简单控制,Simulink中也有封装好的PID模块,用单环PID控制一个直流有刷电机仿真如下:
在这里插入图片描述

可以尝试一下在电机转速actual_velocity中添加一些低幅值的高频噪声,会发现对于系统的稳定影响非常大。

采用单环PID控制,使用PWM进行斩波调制,将母线电压控制到想要的电压大小,实现的效果如下:
在这里插入图片描述

用python实现一个PID用于控制摆锤(约等于电机控制问题)

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import gymnasium as gym

# 解决中文显示问题
def setup_font():
    plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Arial Unicode MS"]
    plt.rcParams['axes.unicode_minus'] = False

setup_font()

class PIDController:
    """连续输出的PID控制器"""
    def __init__(self, kp, ki, kd, setpoint=0):
        self.kp = kp  # 比例增益
        self.ki = ki  # 积分增益
        self.kd = kd  # 微分增益
        self.setpoint = setpoint  # 目标摆角(弧度)
        
        self.prev_error = 0.0  # 上一时刻误差
        self.integral = 0.0    # 误差积分
        self.dt = 0.05         # 时间步长(与Pendulum环境一致)
    
    def compute(self, process_value):
        """计算连续控制输出(力矩)"""
        # 计算当前误差(摆角偏差)
        error = self.setpoint - process_value
        # 积分项(限制积分饱和)
        self.integral += error * self.dt
        # 微分项(抑制噪声)
        derivative = (error - self.prev_error) / self.dt
        self.prev_error = error
        
        # 计算PID输出(连续力矩)
        output = self.kp * error + self.ki * self.integral + self.kd * derivative
        # 限制输出在环境允许的力矩范围内
        return np.clip(output, -2, 2)

def run_simulation(kp=10.0, ki=1.0, kd=2.0, render=True):
    """在Pendulum-v1环境中运行PID控制"""
    # 创建连续动作空间的倒立摆环境
    env = gym.make('Pendulum-v1', render_mode='human' if render else None, g=3)
    # 初始化PID控制器(目标:摆角为0,即垂直向上)
    pid = PIDController(kp, ki, kd)
    
    # 存储数据
    states = []
    actions = []
    rewards = []
    
    # 重置环境(初始摆角)
    observation, info = env.reset(options={"theta": -3.14}) 
    done = False
    
    # 仿真主循环
    while not done:
        # 观测值解析:[cos(theta), sin(theta), theta_dot]
        # 计算实际摆角(弧度)
        cos_theta, sin_theta, theta_dot = observation
        theta = np.arctan2(sin_theta, cos_theta)  # 转换为[-π, π]的摆角
        
        # PID计算连续力矩(动作)
        torque = pid.compute(theta)
        action = np.array([torque])  # 环境要求动作是数组形式
        
        # 执行动作
        next_observation, reward, terminated, truncated, info = env.step(action)
        done = terminated or truncated
        
        # 存储数据
        states.append([theta, theta_dot])  # 保存摆角和角速度
        actions.append(torque)
        rewards.append(reward)
        
        observation = next_observation
    
    env.close()
    
    # 转换为数组
    states = np.array(states)
    actions = np.array(actions)
    rewards = np.array(rewards)
    
    return states, actions, rewards

def plot_results(states, actions, rewards):
    """绘制控制结果"""
    time_steps = len(states)
    dt = 0.05  # 时间步长
    time = np.arange(time_steps) * dt
    
    fig, axs = plt.subplots(3, 1, figsize=(10, 12))
    
    # 摆角(转换为度)
    axs[0].plot(time, np.rad2deg(states[:, 0]), label='实际摆角')
    axs[0].axhline(y=0, color='r', linestyle='--', label='目标摆角')
    axs[0].set_title('摆角变化(度)')
    axs[0].set_ylabel('角度')
    axs[0].grid(True)
    axs[0].legend()
    
    # 摆角速度(转换为度/秒)
    axs[1].plot(time, np.rad2deg(states[:, 1]), label='摆角速度')
    axs[1].set_title('摆角速度变化(度/秒)')
    axs[1].set_ylabel('角速度')
    axs[1].grid(True)
    axs[1].legend()
    
    # 控制力矩
    axs[2].plot(time, actions, label='输出力矩')
    axs[2].set_title('PID输出力矩变化')
    axs[2].set_xlabel('时间(秒)')
    axs[2].set_ylabel('力矩')
    axs[2].grid(True)
    axs[2].legend()
    
    plt.tight_layout()
    plt.show()

if __name__ == "__main__":
    # 调优后的PID参数(连续动作空间下)
    kp = 14.0   # 比例增益:主导纠正摆角偏差
    ki = 0.9    # 积分增益:消除稳态误差
    kd = 3.0    # 微分增益:抑制震荡
    
    # 运行仿真
    states, actions, rewards = run_simulation(kp=kp, ki=ki, kd=kd, render=True)
    
    print(f"仿真持续时间: {len(states)*0.05:.2f}秒")
    print(f"最终摆角: {np.rad2deg(states[-1, 0]):.2f}度")
    
    # 绘制结果
    plot_results(states, actions, rewards)

仿真结果如下:
在这里插入图片描述

仿真系统可以设置重力常数g,进而影响力矩,当g较大时,这个单环PID控制器就失效了,因为PID是误差驱动,在最低端时角度会从-180跳变到180,即在最低点左边PID会驱动摆锤向左转,反之亦然。这就导致PID无法做到像运动员助跑一样,在最低点左边向右加速助力从右边转上去,直观的体现就是PID一直在左右摇摆就是上不去。
还有之前使用强化学习方法做的样例,可以参考:
强化学习DDPG算法Demo实现

级联PID(Cascade PID)

级联PID控制算法是对普通PID的扩展,通常用于多变量控制系统。它的核心思想是将一个主控制器和一个或多个子控制器结合起来,使得系统能更好地处理复杂的动态行为。

在级联PID中,主控制器负责控制整个系统的大范围误差,而子控制器则负责细化处理主控制器的控制输出。这种结构适用于需要分层控制的场景,例如温度控制、压力控制等。

  • 主回路:根据主回路的误差计算出一个控制量,通常是设定值和实际值之间的差。
  • 子回路:主回路的控制输出作为子回路的设定值。子回路的作用是进一步精细调整,控制精度通常较高。

这种方法的优点是可以减少滞后效应,快速响应动态变化,提高系统的稳定性。
在电机控制中,可以使用级联PID进行控制:
在这里插入图片描述
使用速度环和电流环的电机控制如下:
在这里插入图片描述
得到的效果如下:
在这里插入图片描述

参数整定

PID控制器是自动控制系统中非常常见的一种反馈控制器。它通过比例(P)、积分(I)和微分(D)三个参数来调节系统的输出,以达到设定值。PID参数整定的目的是确定这三个参数的最佳值,以使控制系统在性能上达到最佳。

经验调试

经验整定法是最简单的一种方法,通常用于经验丰富的工程师通过反复调整PID控制器的参数(Kp、Ki、Kd)来达到满意的控制效果。

  • 过程
    • 先设置KiKd为零。
    • 调整Kp,直到系统出现小的稳态误差,并使系统不产生大的超调量。
    • 调整Ki以消除稳态误差。
    • 最后,调整Kd以减少系统的振荡或过冲。
  • 优缺点
    • 优点:简单直观,适用于对系统了解较多的场合。
    • 缺点:操作繁琐,且需要根据经验来调整参数,可能导致不稳定或效率不高。

PID调参口诀:
参数整定找最佳,从小到大顺序查;
先是比例后积分,最后再把微分加;
曲线振荡很频繁,比例度盘要放大;
曲线漂浮绕大弯,比例度盘往小扳;
曲线偏离回复慢,积分时间往下降;
曲线波动周期长,积分时间再加长;
理想曲线两个波,前高后低4比1;
一看二调多分析,调节质量不会低。

PID参数的整定方法主要包括: 基于响应法、模型解析法、 设计图谱法、目标优化法等。其中,基于响应法包括经典的Ziegler-Nichols整定法和继电器反馈法,通过实测系统的时域响应曲线,辨识系统的临界特征参数,进而调节PID参数。常见的PID参数整定方法有以下几种:

Ziegler-Nichols方法

Ziegler-Nichols法是基于响应的经典整定方法,适用于大多数控制系统。它通过设置不同的控制器参数,观察系统响应,进而获得PID参数。

  • 步骤

    1. 设置KiKd为零,仅调整Kp(比例增益),直到系统发生持续振荡(临界振荡)。

    2. 记录此时的Kp值(临界增益Kc)和振荡周期Pc

    3. 根据Ziegler-Nichols表格,通过KcPc计算出PID参数:

      • P控制Kp = 0.5 * Kc
      • PI控制Kp = 0.45 * Kc, Ki = 1.2 * Kp / Pc
      • PID控制Kp = 0.6 * Kc, Ki = 2 * Kp / Pc, Kd = Kp * Pc / 8
  • 优缺点

    • 优点:简单有效,能够快速获得较为合理的控制参数。
    • 缺点:对系统的初始调节有较高要求,且可能存在一定的超调和震荡。

优化算法法

这种方法通过优化算法来自动搜索PID控制器的最佳参数。常用的优化算法包括:

  • 遗传算法:通过模拟自然选择的过程,逐步寻找最佳PID参数。
  • 粒子群优化算法(PSO):通过模拟粒子在搜索空间中的运动来寻求最优解。
  • 最小二乘法:通过最小化误差平方和来优化PID参数。

优缺点

  • 优点:适用于复杂的控制系统,能够自动找到最佳的PID参数。
  • 缺点:计算量大,且依赖于算法的选择和参数设置。

频域分析法

在频域中,通过对系统的传递函数进行分析,可以在系统频率响应上调节PID参数。频域整定法通常依赖于系统的开环增益和相位特性。

  • 步骤
    • 通过频率响应法(例如伯德图)分析系统的幅频特性。
    • 根据系统的相位裕度和增益裕度来确定PID的参数。
  • 优缺点
    • 优点:对于大部分线性系统适用,能够精确调节系统的动态性能。
    • 缺点:需要较强的系统建模和频域分析能力。

总结

PID参数整定的选择应依据具体系统的特点、对性能的要求以及对控制过程的理解来决定。一般情况下,Ziegler-Nichols方法是最常用的整定方法,但对于更为复杂或精密的系统,可能需要采用优化算法或其他方法来精细调整。


网站公告

今日签到

点亮在社区的每一天
去签到