PID sorusu,

Başlatan esensoy, 23 Haziran 2015, 17:04:00

esensoy

Selamlar,
Bir dc fırçalı motorun arkasına 3000 pals encoder taktım,
Step dir pinleri ile bir tane 32 bit signed değişkeni (int32_t hedef_pozisyon;) artırıyor ve azaltıyorum,
1ms lik interrupt ile de encoder ı okuyor ve yine 32 bitlik signed bir değişkene atıyorum (int32_t Position_Counter;)
Kesme rutinini aşağıya kopyaladım,
PWM duty değerim 0 dan 1000 e kadar, yani MAX_PWMDUTY = 1000,
Motorun hangi yöne döneceğini de pid_hata değişkeninin işareti ile belirliyorum,

Ki ve Kd yi sıfır olarak atıyorum, Kp yi küçük küçük artırsam da motorda atlamalar zıplamalar oluyor,
Hele Ki ya da Kd yi 1 birim bile artırsam direk sarsılmaya başlıyor,

Merak ettiğim iki husus var,
birincisi PID formulümde hata var mı?
ikincisi Kp Ki ve Kd değerleri hangi aralıkta seçilmeli? Yani ben şu an 0 ila 100 arasında seçiyorum ama çok çabuk sarsılmaya başlıyor,

void __attribute__ ( (interrupt, no_auto_psv) ) _T1Interrupt(void){
    Position_Counter = Read32bitQEI1PositionCounter();

    pid_hata = hedef_pozisyon - Position_Counter;
    integral = integral_eski + (pid_hata / 1000);
    turev = (pid_hata - pid_hata_eski) * 1000;
    
    PWMDUTY2 = abs((Kp * pid_hata) + (integral * Ki)  + (turev * Kd) ));
    pid_hata_eski = pid_hata;
    integral_eski = integral;            
    
    //if (PWMDUTY2 < MIN_PWMDUTY) PWMDUTY2 = MIN_PWMDUTY;
    if (PWMDUTY2 > MAX_PWMDUTY) PWMDUTY2 = MAX_PWMDUTY;   
 IFS0bits.T1IF = 0; 
}
En tehlikeli an "zafer" anıdır.

alexsi

Merhaba hocam,
ben pid formulunde hata  oldugunu düşünüyorum. benim kullandığım pid oransal hesabım söyle;
PID_scale = (unsigned int)(abs((unsigned int)MaxScale - (unsigned int)MinScale)); //senin 0 ila 1000 degeri sonuc yani sonuc 1000
PID_error = (float)((float)SetValue - (float)CurrentValue); // yani Set edilen deger - O an okudugun deger (rpm,sıcaklık ,mA vs.)
PID_band = (float)(((float)ProportionalValue * (float)PID_scale)/100.0); //Oransal olarak olmasını istedigin deger ProportionalValue % Kac ise
Proportional = (1000.0 * (PID_error / PID_band)) ;

Pid_Sum = ProportionalValue +IntegralValue+DerivativeValue;// Pid Sonucunu verir
http://www.kontrolarge.com/ Bildiklerimiz öğrendiklerimiz kadardır. Ya bilmediklerimiz ..?

esensoy

Bu verdiğiniz formulde Kp hangisi? Genel geçer formule gore yazılmış bir kod değil anladığım kadarıyla,

Formul aşağıdaki gibi,


bende dt = 1ms yani 0.001, kp kd ve ki yi 0-100 arasında seçiyorum ama kp 7 8 lerde motoru osilasyona sokarken ki ve kd 1 olur olmaz osilasyona sokuyor
En tehlikeli an "zafer" anıdır.

Erol YILMAZ

Integral birikmesi denen konudan kaynaklanabilir mi ?

superconductor

Motor yönünün hataya göre değil, pid fonksiyonunun çıkışına göre belirlenmesi gerekir. Bazı durumlarda hata pozitif yönde olsa bile motoru yine pozitif yönde döndürmeniz gerekir. Bir örnek vereyim; Motorunuz pozitif hatalı pozisyonda ve hatasını hızlı bir şekilde sıfır noktasına doğru kapatıyor. Hata çok hızlı bir şekilde kapanıyorsa türev terimi bu durumdan kıllanır ve motora fren yaptırmak ister. Motor yönünü hata yönüne göre belirlerseniz türev fren yaptırmak yerine motora daha çok hız vermiş olur bunu da istemeyiz.

alexsi

Benim vermis olduğum formül ısıtma sisteminde oransal band oluşturarak Oransal hesaplama üzerine yapılmış bir formulasyon.
Superconductor hocamın dediği gibi "Motor yönünün hataya göre değil, pid fonksiyonunun çıkışına göre belirlenmesi gerekir. Bazı durumlarda hata pozitif yönde olsa bile motoru yine pozitif yönde döndürmeniz gerekir. Bir örnek vereyim; Motorunuz pozitif hatalı pozisyonda ve hatasını hızlı bir şekilde sıfır noktasına doğru kapatıyor. Hata çok hızlı bir şekilde kapanıyorsa türev terimi bu durumdan kıllanır ve motora fren yaptırmak ister. Motor yönünü hata yönüne göre belirlerseniz türev fren yaptırmak yerine motora daha çok hız vermiş olur bunu da istemeyiz."
Adım adım gitmende fayda var. Integral ve Turevi kapat . PID sonucuna göre Oransala bak nasıl etki yapıyor.  Sonra Integrali aç.PI etkisine bak. En sonra Türevide aç PID etkisine bak. Sorun daha kolay çözülür.
http://www.kontrolarge.com/ Bildiklerimiz öğrendiklerimiz kadardır. Ya bilmediklerimiz ..?


z

Alıntı yapılan: esensoy - 24 Haziran 2015, 11:04:48
bende dt = 1ms yani 0.001, kp kd ve ki yi 0-100 arasında seçiyorum ama kp 7 8 lerde motoru osilasyona sokarken ki ve kd 1 olur olmaz osilasyona sokuyor

Ben dt=1ms yapıyorum demek ne demek?

Hatayı buluyorum, PID hesabını yapıyorum, PWM ve motor yönü değerini çıkıyorum (motora yolluyorum)
Sonra gidip diğer ıvır zıvır işlerimi yapıyorum.
Sonra tekrar
Hatayı buluyorum, PID hesabını yapıyorum, PWM ve motor yönü değerini çıkıyorum (motora yolluyorum)

İşte bu iki PID hesabı arasında geçen süre tamı tamına 1ms oluyor demek.

Eğer bunu başaramıyorsanız yaptığınız hesaplar işin teorik değerlerinden alakasız sonuçlar üretir.

Öncelikle PID rutininin hemen girişinde bir port pinini toggle edin. Scopla bu pine bakın ve ekran görüntüsünü bize de gösterin.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com