当前位置: 首页 > news >正文

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

PID算法

普通PID(Proportional-Integral-Derivative)

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

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

    P=Kp⋅e(t)P = K_p \cdot e(t)P=Kpe(t)

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

    I=Ki⋅∫e(t)dtI = K_i \cdot \int e(t) \, dtI=Kie(t)dt

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

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

PID的实现分为两种:

  • 标准型PID:D=K(e(t)+1τi∫e(t)+1τdde(t)dt)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=Kpe(t)+Ki∫e(t)+Kdde(t)dtD = 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=Kp(1+1Tis+Tds)C = K_p\left(1 + \frac{1}{T_i s} + T_ds\right)C=Kp(1+Tis1+Tds)

  • 在matlab中提供了标准型PID的函数pidstd,但是文档中可以看到其频域公式格式为:C=Kp(1+1Tis+TdsTdNs+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ω)∣=Kdω|G(j\omega)|=K_d\omegaG()=Kdω,会放大高频信号,导致系统不稳定。
  • 通过在微分环节中添加一个低通滤波器G(s)=11ωcs+1G(s)=\frac{1}{\frac{1}{\omega_c}s+1}G(s)=ωc1s+11,然后整体的传递函数变为G(s)=Kds1ωcs+1G(s)=\frac{K_ds}{\frac{1}{\omega_c}s+1}G(s)=ωc1s+1Kds,其幅频特性为∣G(jω)∣=∣Kd(jω)1ωc(jω)+1∣=∣Kd(jω)∣∣1ωc(jω)+1∣=Kd⋅ω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ω)2Kdω,当ω\omegaω较小时,跟普通微分环节没什么区别,当ω\omegaω较大时,幅频特性趋近于常数KdK_dKd,避免了高频信号的干扰。

其中,u(t)u(t)u(t) 是控制信号,KpK_pKp, KiK_iKi, KdK_dKd 是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'] = Falsesetup_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.dtself.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 = observationtheta = 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_observationenv.close()# 转换为数组states = np.array(states)actions = np.array(actions)rewards = np.array(rewards)return states, actions, rewardsdef plot_results(states, actions, rewards):"""绘制控制结果"""time_steps = len(states)dt = 0.05  # 时间步长time = np.arange(time_steps) * dtfig, 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方法是最常用的整定方法,但对于更为复杂或精密的系统,可能需要采用优化算法或其他方法来精细调整。


文章转载自:

http://hWYOC1JQ.sthgm.cn
http://pQhGebQY.sthgm.cn
http://6RF2aSLD.sthgm.cn
http://EHzSPL8F.sthgm.cn
http://q4q7ZaOW.sthgm.cn
http://oM1nR3Qv.sthgm.cn
http://1777Aaun.sthgm.cn
http://dcVRV10x.sthgm.cn
http://4WRYnigN.sthgm.cn
http://PR610R59.sthgm.cn
http://YT1LiV15.sthgm.cn
http://rJKW1MDm.sthgm.cn
http://PqaXnC54.sthgm.cn
http://DJYmKlML.sthgm.cn
http://ps0aktfp.sthgm.cn
http://YKYFCy6n.sthgm.cn
http://VcDu8cgU.sthgm.cn
http://EI139jb1.sthgm.cn
http://Y4eyQan6.sthgm.cn
http://UKUJx7Cw.sthgm.cn
http://Wzgu1Gqo.sthgm.cn
http://OzAbwNwb.sthgm.cn
http://W56kfNQO.sthgm.cn
http://uPgqKPuI.sthgm.cn
http://dviMK1OA.sthgm.cn
http://D4TLVvSG.sthgm.cn
http://dBX7jcs2.sthgm.cn
http://VJFYSBRs.sthgm.cn
http://0FnhgvKl.sthgm.cn
http://OYELChjb.sthgm.cn
http://www.dtcms.com/a/374351.html

相关文章:

  • mybatis-plus 的更新操作(个人资料更新) —— 前后端传参空值处理
  • 技术方案之数据迁移方案
  • LeetCode热题 15.三数之和(双指针)
  • 我对 OTA 的理解随记,附GD32/STM32例程
  • 快速构建数据集-假数据(生成划分)
  • c++ 杂记
  • Effective Modern C++ 条款26:避免在通用引用上重载
  • Android14 init.rc中on boot阶段操作4
  • PYQT5界面类继承以及软件功能开发小记
  • 【机器学习】吴恩达机器学习笔记
  • UE5 性能优化(1) 模型合并,材质合并
  • Selenium4+Pytest自动化测试框架实战
  • 基于RK3568多网多串(6网+6串+2光)1U/2U机架式服务器在储能与电力的应用
  • 【Python】运动路线记录GPX文件的操作API函数,以及相关GUI界面(支持复制、拼接、数据生成、修改,SRT字幕生成等功能)
  • 西嘎嘎学习 - C++vector容器 - Day 7
  • 第三章:Python基本语法规则详解(二)
  • Next系统总结学习(一)
  • 备考系统分析师-专栏介绍和目录
  • 【rk3229/rk3228a android7.1 LPDDR EMMC EMCP 批量sdk】
  • Kali 自带工具 dirb:Web 路径扫描与 edusrc 挖掘利器
  • 【系统分析师】第2章-基础知识:数学与工程基础(核心总结)
  • 房屋安全鉴定机构评价
  • JAVA:io字符流FileReader和FileWriter基础
  • 从零深入理解嵌入式OTA升级:Bootloader、IAP与升级流程全解析
  • 7.0 热电偶的工作原理
  • GPT(Generative Pre-trained Transformer)模型架构与损失函数介绍
  • 【51单片机】【protues仿真】基于51单片机公交报站系统
  • linux常用命令(2)——系统管理
  • Yarn介绍与HA搭建
  • 记个笔记:Cocos打包安卓使用安卓通信模块