ตอนที่ 22: ตำแหน่ง (Position) vs ความเร็ว (Velocity) Form PID: ศึกชิงเจ้ายุทธภพดิจิทัล

1. 🎯 ตอนที่ 22: ตำแหน่ง (Position) vs ความเร็ว (Velocity) Form PID: ศึกชิงเจ้ายุทธภพดิจิทัล
2. 📖 เปิดฉาก (The Hook)
สวัสดีครับน้องๆ และนักพัฒนาทุกท่าน! กลับมาลุยกันต่อในซีรีส์ เจาะลึกวิศวกรรมระบบควบคุม (Control Systems) จาก 101 ถึง Advance สไตล์วิศวกรรุ่นพี่ครับ
ในตอนที่แล้ว เราได้รู้วิธีการแปลงสมการแคลคูลัสให้อยู่ในรูปสมการผลต่าง (Difference Equation) เพื่อให้ไมโครคอนโทรลเลอร์เข้าใจกันไปแล้ว แต่น้องๆ รู้ไหมครับว่า ในโลกของการเขียนโค้ด PID ระดับอุตสาหกรรม มันมีสถาปัตยกรรมการคำนวณอยู่ 2 ค่ายหลักๆ ที่รบพุ่งแย่งชิงความนิยมกันมาอย่างยาวนาน!
ลองจินตนาการว่าน้องเป็นหัวหน้างาน แล้วต้องสั่งลูกน้องให้ไปหมุนวาล์วน้ำ น้องสามารถสั่งได้ 2 แบบครับ: แบบที่ 1: “นาย ก. ไปหมุนวาล์วให้อยู่ที่องศา 45 องศาเดี๋ยวนี้!” (บอก “ตำแหน่ง” สัมบูรณ์) แบบที่ 2: “นาย ก. ตอนนี้วาล์วอยู่ตรงไหนไม่รู้ล่ะ แต่ช่วยหมุนเปิดเพิ่มขึ้นจากเดิมอีก 5 องศา ซิ!” (บอก “ความเร็ว” หรือ “ส่วนต่าง”)
ในทางวิศวกรรมระบบควบคุม เราเรียกการสั่งงานแบบแรกว่า Absolute Algorithm (หรือ Positional Algorithm) และแบบที่สองว่า Incremental Algorithm (หรือ Velocity Algorithm) วันนี้พี่จะพาไปเจาะลึกโครงสร้างของทั้ง 2 แบบ ว่ามันมีข้อดีข้อเสียต่างกันอย่างไร และทำไมค่ายหนึ่งถึงช่วยชีวิตวิศวกรหน้างานได้มากกว่า!
3. 🧠 แก่นวิชา (Core Concepts)
ในระบบควบคุมแบบวิยุต (Discrete-time PID Control) เราสามารถแบ่งรูปฟอร์มการคำนวณออกเป็น 2 ประเภทหลัก:
- 1. Positional Form (รูปแบบตำแหน่ง หรือ Absolute Form): สมองกลจะคำนวณหาค่า “สัญญาณสั่งงานทั้งหมด” $u(k)$ ออกมาตรงๆ เลย โดยอิงจากค่าความผิดพลาด $e(k)$ ณ ปัจจุบัน และการ “บวกสะสม” ความผิดพลาดในอดีตทั้งหมดไว้ในหน่วยความจำ (Integral sum) รูปแบบนี้เข้าใจง่ายและตรงไปตรงมาเหมือนสมการแคลคูลัสเป๊ะๆ
- 2. Velocity Form (รูปแบบความเร็ว หรือ Incremental Form): สมองกลจะ ไม่ คำนวณหา $u(k)$ ตรงๆ แต่มันจะคำนวณหา “ส่วนต่างของการสั่งงาน ($\Delta u(k)$)” หรือ “ความเร็วในการเปลี่ยนคำสั่ง” แทน เมื่อได้ $\Delta u(k)$ มาแล้ว ค่อยเอาไปบวกเพิ่มกับคำสั่งในรอบที่แล้ว ($u(k-1)$) เพื่อส่งไปให้ Actuator

4. 🧮 ร่ายมนต์สมการและโค้ดควบคุม (The Math & Implementation)
มาดูความงดงามทางคณิตศาสตร์กันครับ ว่าเราจะได้สมการ Incremental มาได้อย่างไร
สเตปที่ 1: สมการ Positional Form ดั้งเดิม
สมการที่เราแปลงมาจากแคลคูลัสโดยใช้วิธี Euler Backward จะหน้าตาแบบนี้:
$$ u(k) = K_p e(k) + K_i T_s \sum_{i=1}^{k} e(i) + \frac{K_d}{T_s} (e(k) - e(k-1)) $$
(จุดอ่อนคือ เราต้องมีตัวแปร sum_e เพื่อบวกสะสม $\sum e(i)$ ไปเรื่อยๆ ตลอดกาล)
สเตปที่ 2: สร้างสมการ Velocity Form เรานำสมการข้างต้นมาเขียนในรอบเวลาที่แล้ว $u(k-1)$ จากนั้นนำสมการรอบปัจจุบัน $u(k)$ มาตั้ง แล้วลบด้วยสมการรอบที่แล้ว $u(k-1)$ ความมหัศจรรย์คือ ก้อนสะสม $\sum_{i=1}^{k} e(i) - \sum_{i=1}^{k-1} e(i)$ จะหักล้างกันจนเหลือแค่ $e(k)$ ตัวเดียว!
ผลลัพธ์ของสมการผลต่างคือ: $$ \Delta u(k) = K_p [e(k) - e(k-1)] + K_i T_s e(k) + \frac{K_d}{T_s} [e(k) - 2e(k-1) + e(k-2)] $$ และสัญญาณที่ส่งไปสั่งงานฮาร์ดแวร์จริงคือ: $$ u(k) = u(k-1) + \Delta u(k) $$
ตัวอย่างโค้ด C/C++ เปรียบเทียบ:
// 1. โค้ดแบบ Positional Form (แบบดั้งเดิม)
float PID_Position(float setpoint, float pv) {
float e = setpoint - pv;
integral_sum += (e * Ts); // ต้องสะสมค่า (เสี่ยง Windup!)
float derivative = (e - prev_e) / Ts;
float u = (Kp * e) + (Ki * integral_sum) + (Kd * derivative);
prev_e = e;
return u;
}
// 2. โค้ดแบบ Velocity / Incremental Form (แบบมือโปร)
float PID_Velocity(float setpoint, float pv) {
float e = setpoint - pv;
// คำนวณเฉพาะ "ส่วนต่าง" (Delta u)
float delta_u = Kp * (e - prev_e1)
+ (Ki * Ts) * e
+ (Kd / Ts) * (e - 2.0*prev_e1 + prev_e2);
// บวกทบกับคำสั่งรอบที่แล้ว
u_out = u_out + delta_u;
// เลื่อนเวลาอดีต
prev_e2 = prev_e1;
prev_e1 = e;
return u_out; // ส่ง u_out ไปขับมอเตอร์
}5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)
ในวงการอุตสาหกรรม วิศวกรระบบควบคุมมักจะเชียร์ให้ใช้ Velocity Form ในการอิมพลีเมนต์ลง Microcontroller หรือ PLC ด้วยเหตุผลระดับเทพดังนี้ครับ:
- สยบ Integral Windup ได้โดยธรรมชาติ (Inherent Anti-windup):
จำปีศาจ Integral Windup ในตอนที่ 16 ได้ไหมครับ? ใน Positional Form เราต้องเขียนโค้ดเช็คลิมิตแล้วสั่งหยุดการบวก
integral_sumให้วุ่นวาย แต่ใน Velocity Form มันไม่มีตัวแปรสะสมค่า! หากมอเตอร์จ่ายพลังงานตันที่ $100%$ เราก็แค่สั่งif(u_out > 100) u_out = 100;แค่นี้จบเลยครับ เมื่อ Error เปลี่ยนทิศทาง มันก็พร้อมจะลบออกจาก 100 และดึงระบบกลับมาได้ทันทีอย่างนิ่มนวล - การโอนย้ายแบบไร้รอยต่อ (Bumpless Transfer):
ในโรงงาน เวลาโอเปอเรเตอร์สลับโหมดการทำงานจาก Manual (หมุนวาล์วด้วยมือ) ไปเป็น Auto (ให้ PID คุม) ถ้าระบบใช้ Positional Form ค่า
integral_sumอาจจะเริ่มจากศูนย์ ทำให้วาล์วกระตุกอย่างรุนแรง (Bump) แต่ถ้าใช้ Velocity Form ตัวแปร $u(k-1)$ ก็แค่ไปดึงค่าคำสั่ง Manual สุดท้ายมาใช้เป็นจุดเริ่มต้น ($u_0$) การเปลี่ยนผ่านจึงราบรื่นดุจแพรไหม (Bumpless) - คู่ขวัญของ Stepper Motor: หาก Actuator ของน้องคือ สเตปปิ้งมอเตอร์ (Stepper Motor) หรือระบบที่รับคำสั่งเป็น “จำนวนก้าว (Pulse increment)” การใช้ Incremental Algorithm จะสมบูรณ์แบบมาก เพราะตัวมอเตอร์เองทำหน้าที่เป็น “ตัวอินทิเกรต (Integrator)” ทางกายภาพอยู่แล้ว น้องสามารถส่งค่า $\Delta u(k)$ ไปขับมอเตอร์ได้โดยตรงเลยครับ!
ข้อสังเกต: ข้อดีอย่างหนึ่งของ Positional Form คือ หากเราต้องการปรับแก้ฟังก์ชันเฉพาะส่วน (เช่น ปิดโหมด I หรือใส่ Filter ในโหมด D) มันจะเขียนโค้ดและทำความเข้าใจได้ง่ายกว่าโครงสร้างที่ถูกรวบยอดมาแล้วแบบ Velocity Form ครับ
6. 🏁 บทสรุป (To be continued…)
การเลือกระหว่าง Position Form และ Velocity Form ก็เหมือนการเลือกอาวุธให้เหมาะกับสนามรบ แม้ในทางคณิตศาสตร์ทั้งสองแบบจะให้ผลลัพธ์การควบคุมที่เท่าเทียมกัน แต่ในทางปฏิบัติ (Implementation) Velocity Form มักจะกินขาดในแง่ของความปลอดภัย (Anti-windup), การประหยัดหน่วยความจำ, และความเสถียรในการทำงานร่วมกับมนุษย์ (Bumpless Transfer)
เอาล่ะครับ! ตอนนี้เราได้โครงสร้างสมการที่เพอร์เฟกต์ที่สุดสำหรับคอมพิวเตอร์แล้ว ในตอนต่อไป เราจะเข้าสู่เนื้อหาที่วิศวกรทุกคนตั้งตารอ: “คัมภีร์การจูน PID ระดับตำนานอย่าง Ziegler-Nichols Method” เราจะหาค่า $K_p, K_i, K_d$ ที่ดีที่สุดได้อย่างไรโดยไม่ต้องนั่งเดาสุ่ม? รอติดตามกันนะครับ!
ต้องการที่ปรึกษาด้านการออกแบบระบบควบคุม (Control Systems), หุ่นยนต์อัตโนมัติ (Robotics) หรือพัฒนาระบบ Automation ขั้นสูงให้กับโรงงานของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและติดตั้งระบบแบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p