Özellikle MEB’in yaptığı robot yarışmaları ile daha çok duyulan PID, robotların yol tutuşunu arttırmakta ve daha hızlı işlemcilerin kullanılmasını sağlamaktadır. PID bir fonksiyondan ibaret olup bir yazım tekniği değildir. Robot yazılımı içinde kullanılan bir hesaplama fonksiyonudur. Fonksiyon tanımlarını robot dokümanımızın global.c dosyasında, fonksiyonları ise helpers.c dosyasında bulabilirsiniz. Aşağıda PID ile yazılmış robot dosyaların tamamına ulaşabilmek için bir link bulacaksınız.

Konuyu daha iyi kavrayabilmek şekiller üzerinde anlatalım.

 

 

Yukarıdaki resimde mavi hattımız yolumuz olsun. Altındaki ise robotumuz. Robotun an0-an7 olmak üzere 7 adet sensoru var. Robotun yoldaki hareketlerine göre bu sensorlar aktif oluyorlar ve bize nasıl gitmemiz gerektiği hakkında ipucu veriyorlar. Bizim offset noktamız an4 ve an3 sensorları. Bu offset noksanından uzaklaşmasına göre de pid fonksiyonumuza ne kadar sapma olduğunu bildireceğiz. Bu sapma değerleri fonksiyon içindeki oransal değerimizi oluşturur.  An4 ve an3 tam çizginin üzerindeyse robot tam yol üzerindedir ve oransal olarak 0 değeri gönderecektir. Eğer an3 sensoru aktifse 1 değeri an4 sensoru aktif olursa -1 değeri gönderiyoruz. Olası ihtimalleri aşağıdaki tablodan inceleyelim.

Bizim için decimal değerler ve PID oransan değerler önemli. Bu değerleri programımızda kullanacağız. Mesela 24 değerine karşılık pid(0), 128 değerine karşılık olarak da pid(-7) değerini fonksiyona gönderiyoruz. PID fonksiyonu bu değerleri işliyor. Ana program parçasında şöyle görünüyor; case 24:pid(0);break; ve case 128:pid(-7);break;

Aşağıdaki fonksiyon 2016 daki robot yarışmasında yarışmış olan robotumuzun program parçasıdır. Ben programda integral değerini kullanmadım. Ancak aşağıda konu bütünlüğünü bozmamak için aşağıya integrali de dâhil edip öyle anlatacağım konuyu. Önce pid fonksiyonunu bir inceleyelim.

void pid(signed int8 pidGelen){

error=offset-pidGelen; // proportional değer

integral = integral+error; // bu kısım normalde yok

derivative=error-lastError;

lastError=error;

pidDeger=(Kp*error)+(Kd*derivative)+(Ki*integral); // (Ki*integral) kısmı programda yok

if (pidDeger>mp) pidDeger=mp;

pwmSol=mp-pidDeger;pwmSag=mp+pidDeger;

if (pwmSol<min) pwmSol=min;if (pwmSol>max) pwmSol=max;

if (pwmSag<min) pwmSag=min;if (pwmSag>max) pwmSag=max;

}

Yukarıdaki fonksiyonu anlayabilmeniz için fonksiyon içinde geçen değişkenleri de görmemiz gerekir. Aşağıda programdan alınmış değerler var. Kafa karıştırmamak için gereksiz yerleri sildim ve integral için ekleme yaptım.

Unsigned int8 offset=0;

signed int32 mp=255, pidDeger=0, anDeger=0, anKalibre=225, min=0, max=403, pwmSol=0, pwmSag=0;

float Kp=10,Kd=5, Ki=2, integral=0, derivative=0, error=0, lastError=0;

Yukarıdaki değişkenleri biraz açıklayalım.

Offset: robotun olmasını istediğimiz konumdur.

Error: offset-pidGelen; değeridir. Offset değerden ne kadar uzaklaştığımızı anlarız. Aynı zamanda oransal değerimizdir.

Mp: motor power anlamıdadır. Robot pid işlemediği zaman motorların güç değeri içindir.

Min=0; bu değer pwm in alabileceği minimum değer içindir.

Max=403; bu değer pwm in alabileceği maximum değer içindir. Normalde max değer 255 olabilirken özel bir fonksiyon yardımıyla biz çözünürlüğümüzü arttırarak max değerimizi 403 yaptık. Çoğu projelerde bu değer 255 olabilir.

pwmSol=0; sol motora verilecek pwm değeri içindir.

pwmSag=0; sağ motora verilecek pwm değeri içindir.

Kp=10,Kd=5, Ki=2; bu değerler formülde kullanılacak ilgili sabitler olup robotun tepkisine göre sizin belirleyeceğiniz sayılardır. Genellikle deneme yanılma yoluyla yapılırlar. Kp=0.000025 de olabilirdi. Bu durumda pid gelen değerleri daha yüksek olmalıdır. 30 ,40 gibi değerler.

Önemli Not: Kp değeri düz yoldaki hataları düzeltmek için kullanılan sabittir. Kd değeri virajlı yollarda kullanılan ve tutunmayı sağlayan değerdir. Ki değeri ise yolun tamamı için (sık virajlı veya daha çok düz yol olmasına göre) kendini düzenleyen bir değerdir. Türev 2.dereceden bir fonksiyonu 1.dereceye indirger. Burada matematiksel fonksiyonları hatırlayacak olursanız düz bir doğru için denklemimiz 1.dereceden olmaktadır. Yine 2.dereceden fonksiyonların şekli virajlı yollar gibidir. Virajlı yolları daha düzgün gidebilmek için türev kullanılır. 

PID İngilizce oransal terimin (proportional), integral teriminin (integral) ve türev teriminin (derivative ) baş harfleridir. Oransal değer(Error); robotunuzun çizgiye göre konumunu yaklaşık olarak orantılayan değerdir. Biz robotun daima çizgi üzerinde olmasını isteriz. Eğer robotumuz çizgi üzerindeyse kayma orantımız sıfırdır diyebiliriz. Yani, robotunuz hat üzerinde tam merkezlenmişse, oransal değer tam olarak 0 olacak şekilde bekleriz. Eğer robotumuzun kafası çizginin solundaysa (orta sensorun sağındaki sensorlar görüyor demektir), orantı değerimiz pozitif bir sayı olacaktır. Robot çizginin sağındaysa orantı değerimiz negatif bir sayı olacaktır. Orantı değerinin, robotun solda olmasına göre pozitif olması veya tam tersine sağında olmasına göre negatif olması tamamen sizin yazdığınız fonksiyonun işlevine bağlıdır ve görecelidir. Konuyu kavradığımızda ne demek istediğimi tam olarak anlayacaksınız. Okumaya devam edelim…

İntegral değer; robotumuzun tüm hareketlerini kayıt altına alır. Oransal değerlerin toplamına eşittir. İntegral değer ne kadar küçükse yol o kadar düz olduğu anlaşılır.

Türev değeri; oransal değerin değişim oranıdır. Son iki oransal değer arasındaki fark kadardır. Robotumuz viraja girdiğinde hep aynı yönde fark oluşacaktır. Fark oluştuğu sürece de toparlanma hızlandırılacaktır. Türev önüne çıkan virajı (2.dereceden grafik gibi) doğrultmaya çalışarak (1.dereceden grafik gibi) yol tutuşunu arttıracaktır. Aşağıdaki örnek 2 şekli inceleyin.

 

 

Ben yaptığım çalışmalarda integral değerinin etkisini çok göremediğimden yazılıma eklemedim. Ayrıca hesaplamalar sonucunda çıkan değerleri de sınırlar içinde tutmanız gerekir. Motorlara verdiğiniz pwm değeri sınırı ne ise bu sınırlara göre pid’den gelen pwm değerini sınırlamanız gerekir. Pid fonksiyonundaki son 4 satır bunun için.

Pwm değerleri elde edilirken (pwmSol=mp-pidDeger;pwmSag=mp+pidDeger;) mp değerine ekleme ve çıkartma yapılır. Motorların ortalama hızları hep aynı kalır. Mp değeri virajlarda düşürülmesi gereken bir değer olmalıdır. Bunun için biraz daha kafa patlatmak gerek. Mp değerini başlangıçta düşük seçerseniz toplamda zaman kaybı olacaktır. Yazdığımız ifadeyi rakamlar kullanarak daha anlaşılır hale getirelim. Mp=255 olsun. Hesaplanan pidDeger ise 55 olsun. Bu değerlere göre yukarıdaki formüle göre pwmSol değerimiz 200 ve pwmSag değerimiz 310 olur. Robotun viraj üzerindeki ortalama hızı (200+310)/2 = 255 olur. Benzer şekilde Hesaplanan pidDeger ise 30 olsun. Bu değerlere göre yukarıdaki formüle göre pwmSol değerimiz 225 ve pwmSag değerimiz 285 olur. Robotun viraj üzerindeki ortalama hızı (225+285)/2 = 255 olur. Mp değeri değişmediği sürece bu değer böyle kalacaktır.

ALINTIDIR.

KAYNAK

Yorum ekle


Güvenlik kodu
Yenile