pid参数优化方法

从pid的角度出发,根据原始参数,计算性能指标,然后通过优化方法(Nelder-Mead法)来调节参数实现性能的提升
在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
import control as ctl # note: pip install control
import matplotlib.font_manager as fm

plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号


# 系统的开环传递函数
def create_system():
    num = [1.151, 0.1774]
    den = [1, 0.739, 0.921, 0]
    return ctl.TransferFunction(num, den)

# 计算性能指标的函数
def calculate_performance(params, sys, target=0.2):
    Kp, Ki, Kd = params
    if Kp >= 20 or Ki >= 20 or Kd >= 20:
        return 9999999999
    C = ctl.TransferFunction([Kd, Kp, Ki], [1, 0])
    T = ctl.feedback(C * sys, 1)
    t = np.linspace(0, 20, 1000)
    _, y = ctl.step_response(0.2 * T, t)
    theta = y
    max_theta = np.max(theta)
    overshoot = (max_theta - target) / target * 100

    ninety_percent_index = np.where(theta >= 0.9 * target)[0]
    rise_time = t[ninety_percent_index[0]] - t[0] if len(ninety_percent_index) > 0 else 999999

    steady_state_indices = np.where(np.abs(theta - target) <= target * 0.02)[0]
    steady_state_time = 999999
    if len(steady_state_indices) > 0:
        for idx in steady_state_indices:
            if np.all(np.abs(theta[idx:] - target) <= target * 0.02):
                steady_state_time = t[idx]
                if steady_state_time >= 15:
                    steady_state_time = 999999
                break

    return overshoot + rise_time + steady_state_time

# 原始PID参数及相关操作
def original_pid_analysis(sys):
    Kp_original = 10
    Ki_original = 5
    Kd_original = 5
    print(f"原始PID参数: Kp={Kp_original}, Ki={Ki_original}, Kd={Kd_original}")

    C_original = ctl.TransferFunction([Kd_original, Kp_original, Ki_original], [1, 0])

    T_original = ctl.feedback(C_original * sys, 1)

    # 仿真原始系统响应
    t_original = np.linspace(0, 20, 1000)
    t_original, y_original = ctl.step_response(0.2 * T_original, t_original)

    # 计算原始PID的性能指标
    overshoot_original = (np.max(y_original) - 0.2) / 0.2 * 100
    ninety_percent_index_original = np.where(y_original >= 0.9 * 0.2)[0]
    rise_time_original = t_original[ninety_percent_index_original[0]] - t_original[0] if len(
        ninety_percent_index_original) > 0 else np.nan
    steady_state_indices_original = np.where(np.abs(y_original - 0.2) <= 0.2 * 0.02)[0]
    steady_state_time_original = np.nan
    if len(steady_state_indices_original) > 0:
        for idx in steady_state_indices_original:
            if np.all(np.abs(y_original[idx:] - 0.2) <= 0.2 * 0.02):
                steady_state_time_original = t_original[idx]
                break
    steady_state_error_original = np.abs(y_original[-1] - 0.2) / 0.2 * 100

    print("原始PID参数性能指标:")
    print(f"超调量: {overshoot_original:.2f}%")
    print(f"上升时间: {rise_time_original:.2f}秒")
    print(f"稳态时间: {steady_state_time_original:.2f}秒")
    print(f"稳态误差: {steady_state_error_original:.2f}%")

    return t_original, y_original


# 优化PID参数及相关操作
def optimized_pid_analysis(sys):
    initial_guess = [10, 1, 1]
    # Nelder-Mead法 优化pid参数
    result = minimize(calculate_performance, initial_guess, args=(sys,), method='Nelder-Mead')
    Kp_opt, Ki_opt, Kd_opt = result.x

    print(f'优化后的PID参数: Kp={Kp_opt:.2f}, Ki={Ki_opt:.2f}, Kd={Kd_opt:.2f}')

    C_opt = ctl.TransferFunction([Kd_opt, Kp_opt, Ki_opt], [1, 0])
    T_opt = ctl.feedback(C_opt * sys, 1)

    t_opt = np.linspace(0, 40, 1000)
    t_opt, y_opt = ctl.step_response(0.2 * T_opt, t_opt)

    # 计算优化后PID的性能指标
    overshoot_opt = (np.max(y_opt) - 0.2) / 0.2 * 100
    ninety_percent_index_opt = np.where(y_opt >= 0.9 * 0.2)[0]
    rise_time_opt = t_opt[ninety_percent_index_opt[0]] - t_opt[0] if len(ninety_percent_index_opt) > 0 else np.nan
    steady_state_indices_opt = np.where(np.abs(y_opt - 0.2) <= 0.2 * 0.02)[0]
    steady_state_time_opt = np.nan
    if len(steady_state_indices_opt) > 0:
        for idx in steady_state_indices_opt:
            if np.all(np.abs(y_opt[idx:] - 0.2) <= 0.2 * 0.02):
                steady_state_time_opt = t_opt[idx]
                break
    steady_state_error_opt = np.abs(y_opt[-1] - 0.2) / 0.2 * 100

    print("优化后PID参数性能指标:")
    print(f"超调量: {overshoot_opt:.2f}%")
    print(f"上升时间: {rise_time_opt:.2f}秒")
    print(f"稳态时间: {steady_state_time_opt:.2f}秒")
    print(f"稳态误差: {steady_state_error_opt:.2f}%")

    return t_opt, y_opt


if __name__ == "__main__":
    sys = create_system()
    t_original, y_original = original_pid_analysis(sys)
    t_opt, y_opt = optimized_pid_analysis(sys)

    plt.plot(t_original, y_original, label='原始PID')
    plt.plot(t_opt, y_opt, label='优化后PID')
    plt.title('原始PID与优化后PID的闭环系统阶跃响应对比')
    plt.xlabel('时间 (秒)')
    plt.ylabel('输出 (弧度)')
    plt.grid()
    plt.legend()
    plt.show()

指标参数

原始PID参数: Kp=10, Ki=5, Kd=5
原始PID参数性能指标:
超调量: 10.02%
上升时间: 0.28秒
稳态时间: 1.26秒
稳态误差: 0.14%
优化后的PID参数: Kp=20.00, Ki=11.79, Kd=13.20
优化后PID参数性能指标:
超调量: 3.94%
上升时间: 0.16秒
稳态时间: 0.80秒
稳态误差: 0.00%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云千载尽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值