PID控制算法的簡單分析和仿真!


PID算法簡單剖析如下:

1、首先我們來看一下PID系統的基本組成模塊:

如圖所示,圖中相關參數的表示如下:

r(t):系統實際上需要的輸出值,這是一個標准值,在我們設定了之后讓這個系統去逼近的一個值(隨時間變化的原因是,我們對系統的需求不同才會改變!)

y(t):系統當前的輸出值,這個值應該需要趨近於我們設定的值,當我們沒有增加PID控制模塊之前,它是由被控對象通過r(t)輸入直接產生的。

e(t):系統由於某些擾動,導致的系統產生的偏差,實際輸出的值和想要設定的初始值r(t)的差值。

u(t):系統通過PID控制器輸出的新的輸入值,實際上他是在r(t)的基礎上,針對當前的實際情況做出的改變。

Kp比例模塊:系統PID比例因子,Kp能夠對於產生的偏差e(t)能夠迅速的作出反應,減少偏差。

Ki積分模塊:系統PID積分因子,Ki能夠用於消除靜差,由於前面的誤差有正有負,所以當前偏差的加入能夠抵消部分,保持系統的穩定性,讓系統有記憶功能。

Kd微分模塊:系統微分因子,Kd能夠體現出當前誤差的變化趨勢,引入有效早期修正信號,從而加快系統的動作速度,減少調節時間。

圖中所示的信號關系公式如下所示:

信號誤差公式:

模擬信號的PID控制器公式: 

離散信號的PID控制器公式:

被控對象的信號公式:(簡單的線性系統,比如電機的PWM調速系統)

上述公式參數描述:

       Kp控制器比例系數、Ti控制器積分時間(積分系數)、Td控制器微分時間(微分系數)

       k采樣序列號,k=0,1,2,3...、Uk第k次采樣時刻系統輸出值、ek第k次采樣時刻偏差值、ek-1第k-1次采樣時刻偏差值、Ki=Kp*T/Ti、Kd=Kp*Td/T

2、離散信號的PID控制器算法仿真:

1、位置式PID算法:

  PID系統產生的值,完全作為系統的輸入參數,即采用u(k)代替了r(k),如果計算機出現故障時,位置式PID控制將導致Uk的劇烈變化,這會引起執行機構的大幅度變化,造成巨大損失。

仿真代碼如下(python):

import matplotlib.pyplot as plt 
import numpy as np 
import random
import sys
import os

time_length = 600
time_sample = 100
time_interval = float(time_length/time_sample)
error_coeff = 3
t = np.linspace(0,time_length,time_sample)
Slope = 1
Intercept = 0
standard_in = 20

# The system model
system_model = lambda i : Slope*i + Intercept
standard_out = system_model(standard_in)
print("The Standard Output:%d" % standard_out)

Kp = 0.08 # average
Ki = -0.7 # intergre
Kd = 0.01 # diff

error_bef = []
real_out_ajust = []
real_out_ajust.append(70)
real_out_ajust.append(75)
error_bef.append(real_out_ajust[0]-standard_out)
Out_plt = np.linspace(standard_out,standard_out,time_sample)

# 標准直接計算公式1:Pout=Kp*e(t) + Ki*Sum[e(t)] + Kd*[e(t) - e(t-1)]
def PID_Controller_Direct_Mem(standard_out,t):
        global time_sample,Kp,Ki,Kd,error_bef,real_out_ajust
        if t > time_sample:
                print("Time Out! Quit!")
                return -1
        error_now = real_out_ajust[t] - standard_out
        error_bef.append(error_now) # 記錄了所有的誤差
        integrate_res = np.sum(error_bef)
        Diffirent_res = error_now - error_bef[t-1]
        return Kp*error_now + Ki*integrate_res + Kd*Diffirent_res

for t_slice in range(1,time_sample-1):
        Pout = PID_Controller_Direct_Mem(standard_out,t_slice)
        real_out_ajust.append(system_model(Pout))

plt.figure('PID_Controller_Direct_Mem')
plt.xlim(0,time_length)
plt.ylim(0,2*standard_out)
plt.plot(t,real_out_ajust)
plt.plot(t,Out_plt)

仿真結果如下所示:

圖中所示,系統最終收斂於我們設定的紅線的位置r(t)

2、增量式PID算法:

當執行機構需要的控制量是增量而不是位置量的絕對數值是,可以采用增量式PID控制算法。

代碼如下(python):

import matplotlib.pyplot as plt 
import numpy as np 
import random
import sys
import os

class PID_Prama:
        def __init__(self):
                self.Kp = 0
                self.Ki = 0
                self.Kd = 0
                self.set_val = 0
                self.error_last = 0
                self.error_prev = 0
                self.error_sum = 0

# 增量計算公式:
# Pout=Kp*[e(t) - e(t-1)] + Ki*e(t) + Kd*[e(t) - 2*e(t-1) +e(t-2)]
def PID_Controller_Increa(pid,out_now):
        error = pid.set_val - out_now
        Res = pid.Kp*(error-pid.error_last) + pid.Ki*error + \
              pid.Kd*(error-2*pid.error_last+pid.error_prev)
        pid.error_prev = pid.error_last
        pid.error_last = error
        return Res

standard_out = 100
PID_val = PID_Prama()

# PID參數
PID_val.Kp = 0.01
PID_val.Ki = 0.1
PID_val.Kd = 0.05
PID_val.set_val = standard_out # 標准輸出值
# 增量型PID控制器輸出值
PID_Controller_Increa_Out = []
Sys_In = []
# 0時刻系統輸入值
Sys_In.append(5)
# 系統響應函數
SystemFunc = lambda x : 5*x + np.random.normal(0,0.5,1)[0]

Sys_Out = []
# 0時刻系統輸出值
Sys_Out.append(SystemFunc(Sys_In[0]))

for t_slice in range(Time):
        Diff = PID_Controller_Increa(PID_val,Sys_Out[t_slice]) #系統誤差
        PID_Controller_Increa_Out.append(Diff) # 記錄所有的系統誤差
        Sys_In.append(Sys_In[0]+np.sum(PID_Controller_Increa_Out)) # 計算增量之后的新的系統輸入
        Sys_Out.append(SystemFunc(Sys_In[t_slice+1])) # 計算下一時刻系統新的輸出值

standard = np.linspace(PID_val.set_val,PID_val.set_val,Time)

plt.figure('PID_Controller_Increa')
plt.xlim(0,Time)
plt.ylim(0,2*standard_out)
plt.plot(Sys_Out)
plt.plot(standard)

plt.show()

這里對增量式PID算法進行深入的分析和計算:

No1:class PID_Param類保存了PID算法中的三個參數,Kp Ki Kd,同時類當中也記錄了上一次系統存在的誤差error_last,以及上上一次系統的誤差error_prev,這樣就能夠完成增量式誤差的公式計算。

No2:上述算法中在循環體中記錄了所有的誤差變量PID_Controller_Increa_Out,這是為了仿真的目的,實際上我們比不需要存儲所有的誤差參數。

No3:系統的響應system_model:,系統后面添加了高斯噪聲,這表示了系統在運行過程中的不穩定的過程,同時系統本身是一個線性系統,例如控制電機轉速的系統:PWM--ctl--Speed

系統仿真結果:

 

其他的相關參考資料見我的cnblog文件中,下一篇介紹PID實戰,基於STM32微控制器的C語言控制PWM電機力矩調節系統!

 https://www.cnblogs.com/uestc-mm/p/10513131.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM