- หน้าแรก
- คลังความรู้
- ระบบควบคุม
- P · PI · PD · PID
// บทที่ 13.16 · ระบบควบคุม · PID Control
ตัวควบคุม P, PI, PD และ PID
กว่า 90% ของลูปควบคุมในโรงงาน และแทบทุกลูปในมอเตอร์ไดรฟ์ โดรน และพาวเวอร์ซัพพลาย ใช้ PID หรือญาติของมัน สามเทอมนี้ดูความผิดพลาดในปัจจุบัน (P) อดีต (I) และแนวโน้มอนาคต (D) หน้านี้อธิบายว่าแต่ละเทอมเปลี่ยนขั้ว ศูนย์ และเฟสอย่างไร ออกแบบด้วยการวางขั้ว สร้างจริงด้วยออปแอมป์ และเจอปัญหาจริงอย่าง windup แล้วแก้อย่างไร สูตรใช้รหัส P
- : เพิ่มขั้วที่ศูนย์ 1 ตัว และศูนย์ 2 ตัว
- P: เร็วขึ้น แต่ยังมีความผิดพลาดค้าง · I: ความผิดพลาดค้างเป็นศูนย์ แต่ช้าและแกว่งขึ้น · D: หน่วงการแกว่ง แต่ขยายสัญญาณรบกวน
- PI ≈ ตัวชดเชย lag · PD ≈ lead · ออกแบบด้วยรูทโลคัส โบด หรือวางขั้วตรง ๆ
- ใช้จริงต้องมี: ฟิลเตอร์ D, D จากเอาต์พุต, anti-windup
โครงสร้างของ PID สามรูปแบบ พื้นฐาน
ตัวควบคุมรับความผิดพลาด แล้วสร้างสัญญาณควบคุม ส่งให้ตัวขับ (ไดรเวอร์มอเตอร์ PWM ฮีตเตอร์) ตำราและผู้ผลิตแต่ละรายเขียนสูตรต่างกัน ต้องรู้ว่าตัวเลขที่เห็นเป็นรูปแบบไหน ไม่อย่างนั้นจูนผิด
P1 Parallel (independent) form รูปแบบขนาน
ใช้ในตำราและไลบรารีไมโครคอนโทรลเลอร์ส่วนใหญ่ (Arduino PID, MATLAB pid) · แต่ละเกนเป็นอิสระต่อกัน
P2 Ideal (standard, ISA) form รูปแบบมาตรฐาน
(เวลาอินทิกรัล, “reset time”) และ (เวลาอนุพันธ์) มีหน่วยวินาที · ใช้ใน PLC และตัวควบคุมอุตสาหกรรม และในตาราง Ziegler–Nichols
P3 Series (interacting) form รูปแบบอนุกรม
= PI อนุกรมกับ PD · ศูนย์สองตัวเป็นจำนวนจริงเสมอ ( และ ) · ตัวควบคุมแอนะล็อกรุ่นเก่าและวงจรออปแอมป์หลายแบบเป็นแบบนี้
P4 PID as poles and zeros PID ในภาษาขั้วและศูนย์
ขั้วที่ (ยกชนิดของระบบ) + ศูนย์สองตัว (จริงหรือเชิงซ้อนก็ได้ในรูปแบบขนาน) · PI: ศูนย์ที่ · PD: ศูนย์ที่ · ภาพนี้คือกุญแจในการออกแบบด้วยรูทโลคัส
ผลของแต่ละเทอม พื้นฐาน
ตารางนี้เป็นแนวโน้มทั่วไปเมื่อเพิ่มแต่ละเกนทีละตัว (ระบบอันดับต่ำ เสถียรวงเปิด) ใช้เป็นจุดเริ่มคิด ไม่ใช่กฎตายตัว ทดลองเองในแล็บด้านล่างได้ทันที
| เพิ่ม | Rise time | Overshoot | Settling time | ess (ขั้นบันได) | เสถียรภาพ | ในภาษาขั้ว/เฟส |
|---|---|---|---|---|---|---|
| ลดลง | เพิ่มขึ้น | เปลี่ยนเล็กน้อย | ลดลง ไม่เป็นศูนย์ (type 0) | แย่ลง | เลื่อนโบดขึ้น ขั้วเดินตามรูทโลคัส | |
| ลดลง | เพิ่มขึ้น | เพิ่มขึ้น | เป็นศูนย์ | แย่ลง | ขั้วที่ 0 · เฟสล่าช้า −90° ที่ความถี่ต่ำ | |
| เปลี่ยนเล็กน้อย | ลดลง | ลดลง | ไม่เปลี่ยน | ดีขึ้น (ถ้า ไม่มากเกิน) | ศูนย์ · เฟสนำ +90° ที่ความถี่สูง |
ในโบดไดอะแกรม มองง่ายกว่า: เทอม I เพิ่มเกนมหาศาลที่ความถี่ต่ำ (ความแม่นยำ) แต่ดึงเฟสลง เทอม D ยกเฟสขึ้นที่ความถี่สูง (เพิ่มเฟสมาร์จิน) แต่ยกเกนความถี่สูงด้วย (สัญญาณรบกวน) ตัวควบคุมที่ดีจึงวาง “ช่วงทำงาน” ของแต่ละเทอมให้อยู่คนละความถี่
ตัวควบคุม P: เร็วขึ้น แต่ไม่แม่น พื้นฐาน
ใช้พลานต์ตัวเดียวกันตลอดหน้านี้ (เช่น มอเตอร์ที่มีค่าคงเวลาทางกลและทางไฟฟ้า หรือวงจร RC สองชั้น) จะได้เทียบกันได้ว่าแต่ละแบบให้อะไร
P5 P-control offset ความผิดพลาดค้างของตัวควบคุม P
ระบบ type 0 (ไม่มีขั้วที่ 0) จะมีความผิดพลาดค้างเสมอ ลดได้ด้วย สูง แต่จะแกว่งมากขึ้น ดูความผิดพลาดอยู่ตัว
หา ที่ให้ สำหรับ แล้วหา overshoot และความผิดพลาดค้าง
สมการลักษณะเฉพาะ:
เทียบกับ : และ
· s
ความผิดพลาดค้าง P5: ได้
: overshoot 16.3% แต่เอาต์พุตไปค้างที่ 0.778 ไม่ถึง 1 (ผิด 22%) การเพิ่ม ลดความผิดพลาดได้แต่ จะลดลง แกว่งมากขึ้น P อย่างเดียวจึงแลกกันระหว่าง “แม่น” กับ “นิ่ง”
python-control: overshoot 16.30%, (2%) = 2.70 s, ค่าสุดท้าย 0.778 ✓
ตัวควบคุม PI: กำจัดความผิดพลาดค้าง พื้นฐาน
เพิ่มอินทิเกรเตอร์ ได้ขั้วที่ศูนย์ (ระบบกลายเป็น type 1 ความผิดพลาดต่อขั้นบันไดเป็นศูนย์) และศูนย์ที่ เทคนิคที่นิยมคือวางศูนย์ของ PI หักล้างขั้วที่ช้าที่สุดของพลานต์ ระบบที่เหลือจะง่ายและเร็วขึ้น
ออกแบบ PI ให้พลานต์เดิมมี และความผิดพลาดค้างเป็นศูนย์
วางศูนย์ของ PI ที่ หักล้างขั้วช้า: ได้
วงปิด: · ·
ศูนย์อยู่ที่
· overshoot 16.3% เท่าเดิม ความผิดพลาดค้างเป็นศูนย์ แต่ s ช้ากว่าแบบ P (2.7 s) เพราะ ลดจาก 1.5 เหลือ 1 นี่คือราคาของเทอม I
python-control: overshoot 16.30%, = 4.05 s, ค่าสุดท้าย 1.000 ✓ · การหักล้างขั้วใช้ได้เมื่อขั้วของพลานต์เสถียรและรู้ค่าแม่นพอ ห้ามหักล้างขั้วฝั่งขวาเด็ดขาด (ดูหน้าควบคุมได้)
ตัวควบคุม PD: หน่วงการแกว่ง กลาง
เทอม D ตอบสนองต่ออัตราการเปลี่ยนของความผิดพลาด ถ้าเอาต์พุตกำลังพุ่งเข้าหาเป้าเร็ว D จะ “เบรก” ก่อนถึง จึงลด overshoot ในทางฟิสิกส์ PD กับมอเตอร์ตำแหน่งเหมือนการเพิ่มสปริง (P) และแดมเปอร์ (D) เสมือน ดูตัวอย่างลูปตำแหน่ง
ออกแบบ PD ให้ มีขั้ววงปิดที่ rad/s
เทียบสัมประสิทธิ์: และ
ระวัง: วงปิดคือ มีศูนย์ที่ ใกล้ขั้ว ทำให้ตอบสนองเร็วและพุ่งเกินกว่าระบบอันดับสองบริสุทธิ์
· ขั้วอยู่ตรงตามสเปก แต่ overshoot จริง 9.5% (สูตรอันดับสองทำนาย 4.6%) เพราะศูนย์ของ PD
python-control: overshoot 9.52%, rise 0.32 s · ถ้าต้องการ overshoot ตามสูตรจริง ให้คำนวณ D จากเอาต์พุต ( แทน ) ศูนย์จะหายไปจาก ทดลองได้ด้วยตัวเลือก “D จากเอาต์พุต” ในแล็บ P7
P6 Filtered derivative เทอม D ที่มีฟิลเตอร์ (ใช้จริงเสมอ)
D บริสุทธิ์มีเกนโตไม่จำกัดที่ความถี่สูง () สัญญาณรบกวนจากเซนเซอร์จะถูกขยาย ฟิลเตอร์จำกัดเกนความถี่สูงไว้ที่ · PD + ฟิลเตอร์ = ตัวชดเชย lead ทุกประการ
ออกแบบ PID ด้วยการวางขั้ว กลาง
พลานต์อันดับสอง + PID ได้ระบบวงปิดอันดับสาม มีสามเกนให้เลือกพอดีกับสามสัมประสิทธิ์ จึงวางขั้ววงปิดได้ทุกตัวตามต้องการ นิยมเลือกคู่ขั้วเด่นจากสเปก และขั้วที่สามให้ไกลกว่าประมาณ 5 เท่า
ออกแบบ PID ให้ มีขั้วเด่นที่ และขั้วที่สามที่
สมการลักษณะเฉพาะ P4:
พหุนามที่ต้องการ
เทียบสัมประสิทธิ์: , ,
· ศูนย์ของ PID อยู่ที่ ทำให้ overshoot จริง 9.6% (มากกว่า 4.6% ที่ ทำนาย) และ s
python-control ยืนยันขั้ววงปิด และ overshoot 9.57% · แก้ overshoot ส่วนเกินได้ด้วย setpoint weighting P7 หรือ prefilter โดยไม่ต้องเปลี่ยนขั้วเลย
วิธีอื่นที่ใช้บ่อย: ออกแบบด้วยรูทโลคัส (วางศูนย์ของ PD ให้โลคัสผ่านจุดที่ต้องการ แล้ววางศูนย์ PI ใกล้จุดกำเนิด) ด้วยโบด (เลือกความถี่ครอสโอเวอร์และเฟสมาร์จิน) หรือจูนจากการทดลองด้วยกฎ Ziegler–Nichols เมื่อไม่มีแบบจำลอง
PID ในงานจริง: kick, setpoint weighting และ windup ขั้นสูง
สูตรในตำราทำงานได้ในโลกเชิงเส้นที่ไม่มีขีดจำกัด แต่ตัวขับจริงอิ่มตัว เซนเซอร์มีสัญญาณรบกวน และค่าอ้างอิงเปลี่ยนแบบขั้นบันได ปัญหาสามข้อนี้แก้ได้ด้วยการเปลี่ยนโครงสร้างเล็กน้อย
P7 Setpoint weighting (2-DOF PID) ถ่วงน้ำหนักค่าอ้างอิง
: D คำนวณจากเอาต์พุตอย่างเดียว ไม่กระตุก (derivative kick) ตอนค่าอ้างอิงกระโดด · : ลด overshoot ต่อค่าอ้างอิง · เทอม I ต้องใช้ เต็ม ๆ เพื่อให้ไม่มีความผิดพลาดค้าง · ขั้ววงปิดและการต้านการรบกวนเหมือนเดิมทุกประการ
P8 Anti-windup ป้องกันอินทิกรัลสะสมเกิน
คือค่าหลังอิ่มตัว · (tracking time) นิยม หรือประมาณ · ไมโครคอนโทรลเลอร์ใช้ clamping บ่อยที่สุดเพราะเขียนง่าย
ลองในแล็บ: เลือกพลานต์ “ฮีตเตอร์ + หน่วงเวลา” เปิด “จำกัด |u|” แล้วปิด anti-windup จะเห็นเอาต์พุตพุ่งเกินมากและช้า เพราะอินทิกรัลสะสมระหว่างที่ฮีตเตอร์เปิดเต็ม เปิด anti-windup แล้วเทียบ (กดปักกราฟไว้ก่อน)
สร้าง PID ด้วยออปแอมป์ตัวเดียว กลาง
สำหรับนักศึกษาไฟฟ้า นี่คือจุดที่ทฤษฎีกลายเป็นวงจรบนเบรดบอร์ด ใช้วงจรออปแอมป์อินเวอร์ติง ให้ เป็น ขนานกับ และ เป็น อนุกรมกับ
วงจร PID ออปแอมป์ใช้ ได้เกนเท่าไร
s · s · s · s
แทน P9: , , s
ศูนย์อยู่ที่ และ rad/s
ตรวจ: ✓ · วงจรนี้คือหัวใจของ Type II/III compensator ในพาวเวอร์ซัพพลาย
PID ในไมโครคอนโทรลเลอร์ กลาง
ทุกคาบสุ่ม อ่านเซนเซอร์ คำนวณ แล้วเขียน PWM โค้ดด้านล่างรวม D จากเอาต์พุต ฟิลเตอร์ D และ anti-windup แบบ clamping ไว้แล้ว รายละเอียดการแปลงและการเลือก อยู่ที่ควบคุมดิจิทัล
// เรียกทุก Ts วินาที (เช่น จาก timer interrupt)
float pid_step(float r, float y) {
float e = r - y;
float P = Kp * e;
// D จากเอาต์พุต + ฟิลเตอร์อันดับหนึ่ง (Tf = Kd/(N*Kp))
D = (Tf * D - Kd * (y - y_prev)) / (Tf + Ts);
y_prev = y;
float u = P + I + D;
float u_sat = fminf(fmaxf(u, U_MIN), U_MAX);
// anti-windup: อินทิเกรตเฉพาะเมื่อไม่ได้ดันให้อิ่มตัวหนักขึ้น
if (u == u_sat || (e * u) < 0) I += Ki * Ts * e;
return u_sat;
}
แล็บจำลอง PID
เลือกพลานต์ เลื่อน (สเกลลอการิทึม ลากซ้ายสุดคือปิดเทอมนั้น) และ ของฟิลเตอร์ ระบบจำลองในโดเมนเวลาจริงทีละก้าว (ไม่ใช่สูตร) จึงรวมการอิ่มตัว หน่วงเวลา และสัญญาณรบกวนที่โหลด (ขั้นบันไดเข้าที่อินพุตพลานต์ครึ่งทาง ขนาดเทียบเท่าครึ่งหนึ่งของค่าอ้างอิง) ได้ กด “ปักกราฟไว้เทียบ” ก่อนเปลี่ยนค่าจะเห็นผลชัด
กำลังโหลดแล็บ (ต้องเปิด JavaScript)
โจทย์ท้าทาย: (1) เลือกพลานต์อันดับสาม เพิ่ม อย่างเดียวจนแกว่งค้าง จด และคาบ แล้วเทียบกับเราท์ (ควรได้ , ) (2) ใช้ค่านั้นจูนด้วยZiegler–Nichols (3) พลานต์มวล-สปริง ลองเพิ่มแค่ ดูการแกว่งหายไป
ข้อผิดพลาดที่พบบ่อย
- ใส่เกน ISA ลงไลบรารีแบบขนาน → ไม่ใช่ P2
- ลืมคูณ/หาร ในโค้ด → แบบดิจิทัลต้องคูณ เทอม D ต้องหาร เปลี่ยนคาบสุ่มแล้วต้องแก้ด้วย
- ใช้ D บริสุทธิ์ → สัญญาณรบกวนถูกขยาย ตัวขับสั่น ใส่ฟิลเตอร์เสมอ P6
- overshoot มากเกินสูตรทั้งที่ขั้วถูก → ศูนย์ของ PID ใช้ setpoint weighting P7
- ตัวขับอิ่มตัวแล้ว overshoot มหาศาล → integral windup ใส่ anti-windup P8
- หักล้างขั้วฝั่งขวาด้วยศูนย์ของตัวควบคุม → ขั้วนั้นยังอยู่ภายใน ระบบไม่เสถียรภายใน (internally unstable)
- เพิ่ม KI เพื่อให้เร็วขึ้น → I ไม่ได้ทำให้เร็ว มันทำให้แม่น เพิ่มมากไปจะแกว่งและไม่เสถียร (ดู R-8 ในหน้าเราท์)
ต่อยอดไปหน้าถัดไป
เมื่อไม่มีแบบจำลองแม่นพอ หรืออยากได้ค่าเริ่มต้นเร็ว ๆ ใช้วิธีจูนจากการทดลอง Ziegler–Nichols, Cohen–Coon, IMC และ relay auto-tune ส่วนการนำ PID ไปใช้ในลูปซ้อนของมอเตอร์และหุ่นยนต์ ดูเมคาทรอนิกส์
คำถามที่พบบ่อย
Kp Ki Kd แต่ละตัวทำอะไร พูดสั้น ๆ?
Kp ตอบสนองต่อความผิดพลาดตอนนี้ ยิ่งมากยิ่งเร็วแต่แกว่งมากขึ้น Ki สะสมความผิดพลาดในอดีต ทำให้ความผิดพลาดอยู่ตัวเป็นศูนย์แต่เพิ่มความล่าช้าและ overshoot Kd ดูแนวโน้มอนาคต (อัตราการเปลี่ยน) ช่วยหน่วงการแกว่งและเพิ่มเฟสมาร์จิน แต่ขยายสัญญาณรบกวนความถี่สูง
ทำไม PI จึงทำให้ความผิดพลาดอยู่ตัวเป็นศูนย์?
เทอม I เพิ่มขั้วที่ s = 0 ทำให้ชนิดของระบบเพิ่มขึ้นหนึ่ง ในเชิงกายภาพ ถ้ายังมีความผิดพลาดค้างอยู่แม้นิดเดียว อินทิกรัลจะโตไปเรื่อย ๆ จนสัญญาณควบคุมเปลี่ยนพอที่จะกำจัดความผิดพลาดนั้น สภาวะอยู่ตัวจึงเกิดได้เฉพาะเมื่อความผิดพลาดเป็นศูนย์
ทำไมงานจริงส่วนใหญ่ใช้ PI ไม่ค่อยใช้ D?
เพราะกระบวนการส่วนใหญ่ (อุณหภูมิ การไหล ความดัน ลูปความเร็วมอเตอร์) ช้าและสัญญาณวัดมีสัญญาณรบกวน เทอม D ขยายสัญญาณรบกวนและทำให้ตัวขับทำงานหนัก PI จึงพอ ส่วนระบบที่ต้องการหน่วงเพิ่ม เช่น ลูปตำแหน่งของเซอร์โว โดรน หรือพาวเวอร์ซัพพลาย ใช้ D (หรือ lead) พร้อมฟิลเตอร์
Integral windup คืออะไร แก้อย่างไร?
เมื่อตัวขับอิ่มตัว (เช่น PWM เต็ม 100%) ความผิดพลาดยังค้าง อินทิกรัลจึงสะสมเกินจริง เมื่อเอาต์พุตถึงเป้าแล้วต้องใช้เวลานานกว่าจะคายค่าที่สะสม ทำให้ overshoot มาก แก้ด้วย anti-windup เช่น หยุดอินทิเกรตเมื่ออิ่มตัว (clamping) หรือป้อนกลับส่วนต่างระหว่างค่าที่สั่งกับค่าที่อิ่มตัวมาลดอินทิกรัล (back-calculation)
PID กับตัวชดเชย lead lag เกี่ยวกันอย่างไร?
PI คือ lag ที่ขั้วอยู่ที่ศูนย์พอดี PD คือ lead ที่ขั้วอยู่ไกลมาก (อนันต์) ส่วน PD ที่มีฟิลเตอร์อนุพันธ์คือ lead ทุกประการ ดังนั้น PID ที่มีฟิลเตอร์ก็คือ lag-lead และ Type III compensator ของพาวเวอร์ซัพพลายก็คือ PID บวกขั้วเพิ่มหนึ่งตัว