c PID演算法入門

2022-02-14 17:22:54 字數 3589 閱讀 2136

這是乙個 winform 的專案。負載是乙個水箱,有乙個進水口,乙個出水口。設定值為液位,通過控制進水口的閥門開度使液位達到設定值,感測器的滯後時間為10秒。每秒執行一次 pid 演算法(對於運動控制的專案需要將取樣時間調低)。

左圖採用原生 pid 調節,右圖採用積分分離後的 pid 調節(在誤差小於一定值的情況下積分才開始累積)。可以看出積分分離可以有效的抑制超調量,但是會增加調節時間。

由於微分調節對系統穩定性影響較大,不建議初學者使用。

在分配 pid 的各項引數時,除了使用 「自動控制理論」 中計算傳遞函式,還可以通過試湊的方法。先確定比例的大致範圍,再加入積分。加入積分時,需要先將積分值調到很大(積分值大表示效果較弱),再慢慢降低。

label : lblinfo1(用於顯示超調)lblinfo2(用於顯示調節時間)

button:btnstart(開始普通 pid 演算法)btnstart2(開始改進型 pid 演算法)(主要採用積分分離演算法)

numericupdown:nump(比例值)numi(積分值)

panel:panel2(用於繪圖顯示 pid 調節過程)

using

system;

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型別的...