這是乙個 winform 的專案。負載是乙個水箱,有乙個進水口,乙個出水口。設定值為液位,通過控制進水口的閥門開度使液位達到設定值,感測器的滯後時間為10秒。每秒執行一次 pid 演算法(對於運動控制的專案需要將取樣時間調低)。
左圖採用原生 pid 調節,右圖採用積分分離後的 pid 調節(在誤差小於一定值的情況下積分才開始累積)。可以看出積分分離可以有效的抑制超調量,但是會增加調節時間。
由於微分調節對系統穩定性影響較大,不建議初學者使用。
在分配 pid 的各項引數時,除了使用 「自動控制理論」 中計算傳遞函式,還可以通過試湊的方法。先確定比例的大致範圍,再加入積分。加入積分時,需要先將積分值調到很大(積分值大表示效果較弱),再慢慢降低。
label : lblinfo1(用於顯示超調)lblinfo2(用於顯示調節時間)
button:btnstart(開始普通 pid 演算法)btnstart2(開始改進型 pid 演算法)(主要採用積分分離演算法)
numericupdown:nump(比例值)numi(積分值)
panel:panel2(用於繪圖顯示 pid 調節過程)
usingsystem;
using
system.collections.generic;
using
system.componentmodel;
using
system.data;
using
system.drawing;
using
system.linq;
using
system.text;
using
system.threading.tasks;
using
system.windows.forms;
namespace
pid
//初始化
private
void
init()
maxlevel = 0
; time = 0
; lastpoint = new point(0
, ybase);
}private
void btnstart_click(object
sender, eventargs e)
private
void btnstart2_click(object
sender, eventargs e)
//////
開始
/// ///
0使用普通pi調節,1使用改進pi調節
private
void start(int
number)
bool complete = false
;
for (int i = 0; i < 1000; i++)
decimal degreein =frmpid.getoutputvalue(frmbox.getlevel(), number);
frmbox.changedegreein(degreein);
}if (frmbox.getlevel() >maxlevel)
if ((math.abs(frmbox.getlevel() - frmpid.target) / frmpid.target < 0.01m) && (!complete))
}decimal up = 0
;
if (maxlevel >frmpid.target)
lblinfo1.text = "
超調:" + up.tostring("
0.000");}}
public
class
box
public
void
init()
private
decimal
getactuallevel()
//////
每呼叫一次表示經過了一秒
/// public
void
changelevel()
if (level > 1
)
this
.levellist.add(level);
while (this.levellist.count > 10
)
}public
decimal
getlevel()
//////
改變進水閥開度
/// public
void changedegreein(decimal
degreein)
}//////
pid控制類
/// public
class
pid
//////
設定值
/// public
decimal target
//////
比例
/// public
decimal p
//////
積分
/// public
decimal i
//////
輸出限幅
/// private
decimal minoutput
//////
輸出限幅
/// private
decimal maxoutput
public
void init(decimal target, decimal p, decimal i, decimal minoutput, decimal
maxoutput)
this.minoutput =minoutput;
this.maxoutput =maxoutput;
}//////
獲得輸出值
/// ///
反饋值 ///
0普通演算法,1改進後的演算法
///public
decimal getoutputvalue(decimal feedback, int
number)
else}}
decimal output = error * this.p + this
.integralvalue;
if (output < this
.minoutput)
if (output > this
.maxoutput)
return
output;}}
}
A 演算法入門
一 概述 a 演算法在遊戲中應用是十分廣泛的,許許多多的遊戲在尋路方面都會考慮使用該演算法 當然除該演算法外,前輩們也想出很多其他辦法 它是一種啟發式的尋路搜尋演算法。今天這邊重點全面分析 a 演算法。二 術語 start node 起始節點。即 使用者請求尋路時的起點 end node 目標節點 ...
ACM演算法入門
oj上的一些水題 可用來練手和增加自信 poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094 初期 一.基本演算法 1 列舉.poj1753,poj2965 2 貪心 poj1328,poj2109,poj25...
演算法入門(一)
1.for迴圈的使用 其實簡單的for 初始化 判斷條件 調整 迴圈,一般都會用。tip break用於跳出for迴圈,continue用於跳出此次迴圈,進入下一次 for 死迴圈 如 int i,j 3,n 5 for i 0 ij 迴圈結束時,i 4 q1.求1000 9999中的aabb型別的...