PID Kontrolünün Temelleri: Grafikler ve C++ Kodu ile Basit ve Anlaşılır Bir Rehber

3.330 Kişi Okudu

Diyelim ki bir araba kullanıyorsun ve belirli bir hızda gitmek istiyorsun. Bu durumda, PID kontrolörünün üç bileşeni olan P (Proporsiyonel), I (İntegral) ve D (Türevsel) kontrolü, arabanın hızını ayarlamanıza yardımcı olur.

  1. P (Proporsiyonel Kontrol) – Hedefe Doğru İlk İvme: İlk olarak, hızınızı hedef hıza ulaştırmak için gaza basarsınız. Eğer hedef hızın altındaysanız daha fazla, hedef hızın üstündeyse daha az gaza basarsınız. Bu, ‘P’ kontrolünün işidir; hedefe ne kadar uzakta olduğunuza (hata miktarı) bağlı olarak bir tepki verir. Ancak, bu kontrol tek başına bazen hedef hıza tam olarak ulaşmanıza veya aşırı tepki vermenize sebep olabilir.
  2. I (İntegral Kontrol) – Küçük Düzeltmeler: Uzun bir süre hedef hızın altında kaldıysanız, ‘I’ kontrolü devreye girer. Bu, geçmişteki tüm hataları biriktirir ve hedefe ulaşmak için yavaş yavaş artan bir düzeltme yapar. Örneğin, rüzgar nedeniyle sürekli hafif bir ivme gerektiğinde bu önemlidir. Ancak, bu kontrol yavaş tepki verir ve aşırı düzeltmelere neden olabilir.
  3. D (Türevsel Kontrol) – Ani Değişikliklere Tepki: Eğer bir tepeye tırmanıyorsanız ve hızınız hızla düşmeye başlarsa, ‘D’ kontrolü devreye girer. Bu, hızdaki değişimin hızını algılar ve ona göre bir tepki verir, böylece ani değişikliklere hızla yanıt verebilirsiniz. Bu, aşırı tepkileri ve sarsıntıları önlemeye yardımcı olur.

Bu üç kontrol birlikte çalışarak, hedef hıza stabil ve verimli bir şekilde ulaşmanızı sağlar. Araba örneğinde, P hızınızı hedefe yaklaştırır, I uzun vadeli sapmaları düzeltir ve D ani değişikliklere hızlı bir şekilde yanıt verir. PID kontrolörü de benzer şekilde, sistemleri hedef değerlerine hızlı ve doğru bir şekilde ulaştırmak için bu üç kontrol mekanizmasını kullanır.

Grafikler ile PID

Grafiklerle PID kontrolünün nasıl çalıştığını anlatmak için, önce PID kontrolünün temel bileşenlerini ve her birinin sisteme nasıl etki ettiğini gösteren birkaç basit grafik çizeceğim. Bu grafikler, bir sistemin zaman içindeki tepkisini ve PID kontrolörünün her bir bileşeninin (P, I ve D) bu tepkiye nasıl katkıda bulunduğunu gösterecek.

  1. P (Proporsiyonel) Kontrol: Hata miktarına orantılı bir çıktı üretir. Hata büyükse, çıktı da büyük olur. Bu, sistemin hızlıca hedef değere yaklaşmasını sağlar.
  2. I (İntegral) Kontrol: Zaman içinde biriken hatanın toplamını hesaplar. Bu, sürekli küçük hataları düzeltmeye yardımcı olur ve sistem hedef değere tam olarak ulaşır.
  3. D (Türevsel) Kontrol: Hatanın değişim hızını hesaplar. Bu, ani değişikliklere hızlı bir şekilde yanıt vermek için kullanılır ve aşırı tepkileri engeller.

Bu üç grafik, PID kontrolörünün her bir bileşeninin zaman içinde nasıl davrandığını ve toplam çıktıyı nasıl etkilediğini gösterecek. Şimdi bu grafikleri çizelim.

İşte PID kontrolünün her bir bileşeninin grafiksel temsili:

  1. Hata (Setpoint – PV) Grafiği: Bu grafik, hedef değer (setpoint) ile mevcut değer (PV) arasındaki farkı (hatayı) zaman içinde gösterir. Başlangıçta hata büyük ve zamanla azalarak sıfıra yaklaşır.
  2. Proporsiyonel (P) Kontrol Grafiği: P kontrolünün çıktısı, hata ile doğrudan orantılıdır. Hatayı azaltmak için çıktı başlangıçta yüksek ve zamanla azalır.
  3. İntegral (I) Kontrol Grafiği: I kontrolünün çıktısı, zaman içinde biriken hatayı temsil eder. Bu, sürekli küçük hataları düzeltmeye yardımcı olur ve sistem hedef değere tam olarak ulaşır.
  4. Türevsel (D) Kontrol Grafiği: D kontrolünün çıktısı, hatadaki değişim oranını (türevini) temsil eder. Bu, sistemin ani değişikliklere hızlı bir şekilde yanıt vermesini sağlar.

Bu grafikler, PID kontrolörünün her bileşeninin sistemdeki etkisini ve birlikte nasıl çalıştıklarını gösterir. Gerçek bir uygulamada, bu bileşenlerin dengesi, sistemin ihtiyaçlarına ve özelliklerine göre ayarlanır. ​

PID C/C++ Kodu

Gerçek dünyada kullanılmak üzere daha karmaşık ve özelleştirilmiş bir PID kontrolörü yazmak isteyebilirsiniz, ancak bu örnek temel bir başlangıç noktası sağlayacaktır.

#include <iostream>
#include <chrono>

class PID {
    double Kp; // Proportional gain
    double Ki; // Integral gain
    double Kd; // Derivative gain

    double previous_error;
    double integral;

public:
    PID(double p, double i, double d) 
        : Kp(p), Ki(i), Kd(d), previous_error(0), integral(0) {}

    double calculate(double setpoint, double pv, double dt) {
        // Calculate error
        double error = setpoint - pv;

        // Proportional term
        double P_out = Kp * error;

        // Integral term
        integral += error * dt;
        double I_out = Ki * integral;

        // Derivative term
        double derivative = (error - previous_error) / dt;
        double D_out = Kd * derivative;

        // Calculate total output
        double output = P_out + I_out + D_out;

        // Remember current error for next time derivative calculation
        previous_error = error;

        return output;
    }
};

int main() {
    // PID parameters
    double Kp = 0.1;
    double Ki = 0.01;
    double Kd = 0.1;

    // PID instance
    PID pid(Kp, Ki, Kd);

    // Control loop
    double setpoint = 100; // Desired value
    double pv = 0;        // Initial process value
    auto previous_time = std::chrono::high_resolution_clock::now();

    while (true) {
        auto current_time = std::chrono::high_resolution_clock::now();
        double dt = std::chrono::duration<double>(current_time - previous_time).count();
        previous_time = current_time;

        double output = pid.calculate(setpoint, pv, dt);

        // Here, you would use the 'output' to control your system.
        // For this example, let's just print it.
        std::cout << "Output: " << output << std::endl;

        // Simulate process value change (this is just an example)
        pv += output * dt;

        // Break condition for the loop (for demonstration)
        if (std::abs(pv - setpoint) < 0.01) {
            break;
        }
    }

    return 0;
}

Bu kod, PID kontrolörünün temel yapı taşlarını içerir. Kp, Ki ve Kd değişkenleri PID kontrolörünün parametreleridir. calculate fonksiyonu, istenen setpoint değerine ve mevcut süreç değerine (pv) bağlı olarak bir çıktı üretir. Bu çıktı, gerçek sistemdeki bir aktüatörü kontrol etmek için kullanılır. Örnek olarak, bu kodda çıktının süreç değeri (pv) üzerindeki etkisini basit bir şekilde simüle ediyoruz.

Gerçek bir uygulamada, PID kontrolörü sensör verileri ve fiziksel aktüatörlerle entegre edilir. Bu entegrasyon, kontrol döngüsünün bir parçasıdır ve sistem hedef değere (setpoint) uygun şekilde tepki verir.

Yayınlayan

Ahmet Yasin CİVAN

Mekatronik Mühendisi, Gömülü Yazılım Geliştiricisi.