00:00.0
00:05.6
Uzun bir süreden sonra herkese tekrardan merhaba ve proglamlama serimize devam ediyoruz
00:05.7
00:16.0
Bu bölümde robotik için gerçekten önemli olan ve özellikle daha gelişmiş projelerde işinize yarayacak PID'den bahsedeceğiz.
00:16.1
00:20.9
Bu konu hakkında ilk belirtmek istediğim şey PID nedir ve ne işimize yarar.
00:21.0
00:25.8
Ve daha sonrasında bunu nasıl robotumuza uygulayacağımızı göstereceğim.
00:25.9
00:30.7
İlk bilmeniz gereken şey PID ne için kullanılır.
00:30.8
00:46.5
PID belirli bir sensör değerini kolay bir şekilde belirli bir yerde sabit tutmanızı kolaylaştırır.
00:46.6
00:56.8
Buna verebileceğimiz iyi bir örnek robottaki elevatördür.
00:56.9
01:01.7
Eğer elevatörde bağlı olan elin nerede olduğunu gösterebilecek bir sensör varsa,
01:01.8
01:10.4
ve bu eli belirli bir seviyede tutmak istiyorsanız
01:10.5
01:13.2
motorlar kendiliğinden sizin istediğiniz seviyede tutmayacaktır
01:13.3
01:21.9
o seviyede tutabilmek için spesifik bir motor gücüne ihtiyacınız var.
01:22.0
01:26.8
Peki, bunu nasıl yapacağız?
01:26.9
01:31.7
Bunun gibi problemleri PID ile çözebiliriz.
01:31.8
01:39.2
Diyelim ki bir grafiğiniz var ve sensörünüzden değer okuyabiliyorsunuz,
01:39.3
01:47.1
Buradaki mavi çizgi ise elevatörün olmasını istediğiniz yer gibi düşünün
01:47.2
01:55.1
Bu mavi çizgi örneğin 5 feet olsun ve siz de 5 feet de sabitlemek istiyorsunuz.
01:55.2
02:03.6
Ve kırmızı çizgi ise motorun yaptığı hareketleri temsil ediyor.
02:03.7
02:08.5
Burada orantısal kontrol işin içine giriyor ve
02:08.6
02:13.4
sormamız gereken soru hedefe ne kadar yakınız ya da ne kadar uzağız
02:13.5
02:22.9
Eğer hedefe ulaşmak adına orantısal bir şekilde güç uygularsak,
02:23.0
02:27.8
Motorlar hatayı düzeltmek adına güç uygulayacaktır ve hata payına orantısal bir şekilde
02:27.9
02:32.7
uygulanan gücü hedefe göre ayarlayacaktır
02:32.8
02:37.6
Eğer fazla güç uygulanırsa ise hata payı negatif olacağı için ters yönde güç uygulanacaktır.
02:37.7
02:42.5
Ve bu şekilde sürekli in çık yaparak hedefe ulaşmaya çalışılacaktır.
02:42.6
02:47.4
Buna orantısal kontrol diyoruz ve yeteri kadar iyi bir yöntem değil çünkü hedefe ulaşmamız zor.
02:47.5
02:57.0
Ancak eğer doğru bir şekilde ayarlayabilirseniz bazen işinize yarayabilir bu yöntem.
02:57.1
03:01.9
Her ne kadar ayarlasanız da ideal bir yöntem olmayacaktır.
03:02.0
03:10.0
Ve şimdi bakacağımız kontrol yöntemi ise türev(derivative)
03:10.1
03:23.0
Burada bizim değişme miktarını türevle hesaplayıp performansı iyileştirmemizi sağlayacaktır.
03:23.1
03:32.5
Eğer türevinizi biliyorsanız değiştirme hatasına göre bir güç uygulayarak hatanızı düzeltebilirsiniz.
03:32.6
03:46.8
Yaptığınız hatayı hesaplayıp hataya göre hareket etmek orantısal kontrole göre size daha yardımcı olacaktır.
03:46.9
03:54.2
Eğer buradaki dampening force değişkenini değiştirirsek karşımıza çıkan grafik de değişecektir.
03:54.3
04:03.3
Üstteki grafikte gördüğünüz gibi her ne kadar mükemmel olmasa da hedefe daha çok yaklaştık.
04:03.4
04:13.3
D değişkenini değiştirdikçe hatayı düzeltmek için uyguladığımız güç hassaslaşacaktır.
04:13.4
04:18.7
Ancak bu değerler farklı sistemlere göre değişebileceği için
04:18.8
04:23.6
her farklı mekanik sistemin farklı katsayıları olacaktır.
04:23.7
04:28.5
Doğru katsayıyı bulmak için farklı metodlar vardır ancak deneme yanılma yapmak da gerekir.
04:28.6
04:33.4
Farklı metodlardan birisi ise ilk P sonra D sonra ise I katsayılarını ayarlamaktır bu sayede en doğru değere ulaşabilirsiniz.
04:33.5
04:38.3
Aynı zamanda bu grafikler de ayarlamak için size yardımcı olabilir
04:40.5
04:46.0
Ve şimdi bakacağımız katsayı ise integral katsayısı.
04:46.1
04:48.0
Ve bu katsayı ayarlaması en zor olan katsayıdır.
04:48.1
04:59.9
Başlangıçtan beri yapılan bütün hataları toplar.
05:00.0
05:04.8
Ve hedeflediğiniz yere daha çabuk ve kolayca ulaşmanızı sağlar.
05:04.9
05:09.7
Ve steady state error adlı bir şeyi de elimine etmenizi sağlar.
05:09.8
05:14.6
Örneğin hedefinize yaklaştıkça daha küçük ayarlamalar yapmanız gerektiği için sürtünmenin etkisi artabilir.
05:14.7
05:20.8
Ve sürtünme kuvvetini sıfırlayabilmek için karşı hareket yapmamızı sağlar.
05:22.2
05:31.5
Genellikle I terimi P ve D terimlerinden daha küçük olmalıdır.
05:31.6
05:34.2
Örneğin burada P 10 D 20 olmasına rağmen I yı 2 verdik ve karşımıza gayet güzel bir grafik çıktı
05:34.3
05:39.1
kırmızı ve mavi çizgiler neredeyse aynı hizada bu da hedefimize ne kadar iyi ulaşabileceğimizi gösteriyor.
05:39.2
05:46.7
PID sistemlerinde katsayıları doğru ayarlamak en çok zaman harcanan kısımdır ancak doğru yaparsanız çok iyi bir sonuç alırsınız.
05:46.8
06:04.9
PID aynı zamanda dönmek için de kullanılabilir. Yani robotunuzun tam olarak 90 derece olmasını istiyorsanız bu konuda PID işinize yarar.
06:05.0
06:12.6
Demin söylediğim dönme örneğini güzel bir şekilde kodumuzla bağdaştırabiliriz.
06:12.7
06:23.4
Kodumuzda en son TalonSRX tanımlarını ve kurulumunu yapmıştık şimdi ise PID kurulumuna geçebiliriz.
06:23.5
06:28.3
Şimdi ise WPILib tarafından hazırlanan PID metodlarından faydalanacağız.
06:28.4
06:35.4
Bu kodu ister Spark kullanarak ister TalonSRX kullanarak yapabiliriz sonuçta tüm metodları WPILibden kullancağız.
06:35.5
06:43.1
Ve bu sayede işimiz büyük ölçüde kolaylaşacak ancak yine de yapamamız gereken çok şey var.
06:43.2
06:50.8
PID kurulumu için ilk yapmamız gereken şey ise bir PID controller tanımlamaktır.
06:50.9
06:55.7
bunun için public final PIDController şeklinde tanımlayabiliriz.
06:55.8
07:05.0
Bu metod tüm PID hesaplamalarını ve ayarlamalarını yapan metod olacaktır.
07:05.1
07:09.9
Demin grafiklerde ise bu grafikler excel fonksiyonları ile hazırlanmıştı ancak
07:10.0
07:14.8
Şimdi bu hesaplamaları tanımladığımız PIDController yapacak.
07:14.9
07:19.7
Hesaplamaların mantığını anlamak istiyorsanız Wikipedia'da detaylı anlatımlar mevcut ancak şu an sadece PIDController'ı bilmemiz yeterli.
07:19.8
07:30.0
Bu controller'ın çalışması için birkaç şeye ihtiyacı var.
07:30.1
07:34.9
İhtiyacı olan şeylerden birisi ise PID çıktısı yani kontrol etmesi gereken bir şey.
07:35.0
07:39.8
İhtiyacı olan diğer şeylerden birisi ise okuması gereken bir giriş yani bir sensör.
07:39.9
07:44.7
İlk önce sensörle yani girişle başlayalım.
07:44.8
07:50.8
Şu anda bizim yapmak istediğimiz robotu belirli bir şekilde döndürmek
07:50.9
08:00.1
ve bunun için drivebase'imizi kontrol etmemiz gerekiyor bu da bizim PID outputumuz oluyor.
08:00.2
08:10.2
Ancak dönmek için birdan fazla motoru kullandığımız için tek bir motor yerine bir fonksiyon ile bu işlemi yapacağız.
08:10.3
08:28.4
Eğer java'ya hakimseniz, interfaceleri bilirsiniz. Ana sınıfımıza implements PID output ekliyoruz.
08:28.5
08:33.3
Ve şimdi ise bizim için bir çıktı fonksiyonu oluşturuldu.
08:33.4
08:47.4
Sensörden okunan değer sonucunda uygulanması gereken işlemleri bu fonksiyonda belirleyeceğiz ve bu sayede istediğimizi yapacağız.
08:47.5
09:19.4
Şimdi ise yapmamız gereken motorların neye göre çalışacağını ve ne yapmalarını istediğimizi bu fonksiyona yazmak.
09:19.5
09:24.3
Bu satırı yazmanız sonucunda PID değerleri sonucunda robotumuz dönecektir.
09:24.4
09:32.4
Şimdi yapmamız gereken ise grafikteki kırmızı çizgi yani PID girişini halletmek.
09:32.5
09:34.4
Yapmamız gereken şeylerden birisi ise bir veri kaynağı oluşturmak.
09:34.5
09:47.5
Bunun için ise bir sensör tanımlayabiliriz ve bu sayede PID Input kaynağı sağlamış oluruz.
09:47.6
09:54.8
Tanımlayacağımız sensör ise bir gyro ve akselometer olan navX sensörü.
09:54.9
09:59.7
Bu sensörü kullanmak için de farklı kütüphanelere ihtiyacımız var siz de bu kütüphaneleri kullancaksanız sizin de ihtiyacınız olacak.
09:59.8
10:04.6
Aynı zamanda sınıfımıza PIDInput implementini de eklemek zorundayız.
10:04.7
10:25.8
Basit olarak şimdi yaptığımız tanım yani navX bizim PID Inputumuz olacak ve robotumuzun pozisyonunu bize bildirecek.
10:25.9
10:30.7
Şimdi ise navX in kurulumunu tamamlamamız gerekiyor.
10:30.8
10:35.6
Tamamlamak için ise normal bir motor tanımlar gibi yazılan satırı yazıyoruz.
10:35.7
10:59.2
navX'in takılı olduğu port genellikle Roboriodaki MXP portu oluyor. Ve yazdığım portu yazarak AHRS tanımlamasını bitiriyoruz
11:07.1
11:17.1
Şimdi ise önceden tanımladığımız PID controller'ın tanımını tamamlamamız gerekiyor
11:17.2
11:24.1
Ve burada da grafikte kullandığımız katsayıları argüman olarak kullanmamız gerekiyor.
11:24.2
11:29.0
Buradaki argümanları sonradan da değiştirebileceğiniz için farklı değişkenler yaratırsanız işiniz kolaylaşacaktır.
11:29.1
11:45.6
Şimdi deneme amaçlı olduğu için bu katsayıları şimdilik 0 yapacağım sonradan değiştirebiliriz.
11:45.7
11:55.6
Şimdi ise tanıma geri dönüp boş kalan yerleri doldurmamız gerekiyor.
11:55.7
12:05.1
P I ve D katsaılarını yazdıktan sonra geriye input ve output kalıyor.
12:05.2
12:20.4
Source olarak doğrudan navX'in adını yazarsak input değişkenini de tanımlamış olacağız.
12:20.5
12:25.3
Output olarak ise yazmamız gereken şey ise drivebase metodunda olduğumuz için this yazmanız yeterli.
12:25.4
12:32.2
Ve bunları yaparak PIDController tanımını tamamlamış olduk.
12:32.3
12:55.1
Controller input ve output tanımladık ancak şimdi yapmamız gereken girdi değerinin aralığını belirtmek.
12:55.2
13:05.9
Burada yazdığımı yazarak ve bir minimum bir de maksimum değer belirleyerek girdilerinize aralık belirleyebilirsiniz.
13:06.0
13:10.8
Bizim ise burada belirleyeceğimiz aralık -180 derece ile 180 derece arasında olacağı için bu değerleri yazıyorum.
13:10.9
13:20.0
Aynı şekilde output için de bir değer aralığı belirlememiz gerekmektedir.
13:20.1
13:29.8
Yapacağımız hareket dönme hareketi olduğu için yeterli bir miktar güç olan %45 in ters ve düz yönde olacak şekilde belirliyoruz
13:29.9
13:55.4
Şimdi ise ayarlamamız gereken absoultetolerance değeri var. Bu değer için 2 derece yeterli olacaktır.
13:55.5
14:13.1
Ayarlamamız gereken son bir şey ise dönerken bir daire oluşturduğumuz için ve
14:13.2
14:23.1
-180 derece ile 180 derece arasındaki fark 360 derece yerine 1 derece olduğu için bu değeri ayarlamamız gerekiyor
14:23.2
14:28.0
setContinious satırını ekleyerek PID kontrolörümüzü dönmeye göre ayarlamamıza yardımcı olacağız.
14:28.1
14:44.1
Ve tüm bu değerler sayesinde çalışacak bir PID controller elde ettik şimdi ise yapmamız gereken ise
14:44.2
14:56.3
bu kontrolörün çalışmasını tetikleyecek bir komut oluşturmak ve ne zaman çalışacağını belirlemek.
14:56.4
15:01.2
Bunun için yeni bir fonksiyon oluşturmamız gerekiyor
15:01.3
15:12.0
Ve bu fonksiyonun girdisi olarak açı değerini yazmamız gerekiyor
15:12.1
15:33.0
Normalde dönmek için 2 yol vardır ya tek bir yönde sabit bir değere ulaşmak adına dönersiniz ya da değişken bir değere göre dönersiniz.
15:33.1
15:44.7
Bu fonksiyonda yapmamız gereken ise sensörümüzün değerini sıfırlamak ve oryantasyonunu güncel konumuna göre ayarlamak.
15:44.8
16:05.2
Aynı şekilde kontrolörümüzü de sıfırlamak ve girdi değerlerini sıfırlamamız gerekiyor
16:05.3
16:10.1
Ve garanti olsun diye PID katsayılarını tekrardan vermemiz bizim için iyi olacaktır.
16:13.8
16:25.5
Şimdi ayarlamamız gereken diğer şey ise, bir setpoint belirlemektir.
16:25.6
16:30.4
Setpoint mavi çizgi yani ulaşmak istediğimiz hedef olacaktır.
16:30.5
16:37.5
Son yapamamız gereken ise PID kontrolcüsünü etkin hale getirmektir.
16:37.6
16:42.4
Bu fonkisyon çalıştığı andan itibaren PID fonksiyonunuz çalışmaya başlayacaktır.
16:42.5
16:54.5
Gerekli zamanlarda çalışması için bir komut atayabiliriz örneğin otonom ya da bir düğmeye basıldığında çalışması için.
16:54.6
17:10.0
Başlı başına öğrenmek adına bunu da yapmamız öğrenme açısından işimize yarayacaktır ve yardımcı olacaktır
17:10.1
17:14.9
O yüzden komutlar paketinde yeni bir class oluşturalım ve buraya PID için çalışacak komutumuzu hazırlayalım
17:15.0
17:21.5
Bize hazır verilmiş kodları kullanmayacağımız için onları silebiliriz
17:37.1
17:50.2
Sınıfı temizledikten sonra kullanacağımız bir fonksiyon açıp komutumuz için gerekli olan değerleri girmemiz gerekiyor.
17:50.3
18:06.4
PID kontrolörünün ne zaman işlemi bitirdiğini öğrenmek için bir boolean oluşturabliriz.
18:23.2
18:41.1
Şimdi ise normal bir komut yaparken yapmamız gereken basit şeyleri yapmamız gerekiyor.
18:41.2
19:01.7
Daha sonra fonksiyonun içine kullanacağımız açı değerlerini tanımlamamız gerekiyor.
19:01.8
19:10.7
İnit kısmında ise, PID kontrolörünü çağırmamız gerekiyor basitçe PID kontrolörü kendi döngüsünde dönüyor ve
19:10.8
19:22.2
bu nedenle execute kısmında bahsetmemize gerek yok init kısmında bahsetmemiz çalışması için yeterli olacaktır.
19:22.3
19:35.1
İnit kısmında bu komut sayesinde çalışması gerektiğini ve neye göre çalışması gerektiğini kontrolöre söylüyoruz ve buna göre çalışıyor.
19:35.2
19:51.3
Ancak kontrolörün belli bir süreden sonra durması gerekmekte bunu ise ben PID deki hata payına göre yapmayı tercih ediyorum.
19:51.4
20:12.5
Bunu da burada yazdığım satırla tanımlayabiliyoruz ve bu tanım sayesinde uzaklığa göre ne zaman durması gerektiğini ayarlayabileceğiz.
20:12.6
20:23.5
Ve durmamız için bir uygun aralık belirlersek istediğimiz hedefe ulaştığımızda robotun dönmeyi durmasını sağlayabiliriz.
20:23.6
20:45.8
Normalde PID controller hedefine ulaştığında duracaktır ancak robotun durmasını sağlamak için bu aralığa ihtiyacımız var.
20:45.9
20:50.7
Bunun için ise bir farklı boolean oluşturarak ve boolean true olduğunda robotun durmasını sağlayacağız.
20:50.8
21:15.3
Hata payının mutlak değer 2'den küçükse boolean değerimiz true hale gelecek ve bu sayede robotun dönemsini durdurabileceğiz.
21:15.4
22:06.3
Ayrıca yeni bir if döngüsü oluşturup robotun dönüşünü kesinleştirmek adına bir de count adında yeni bir değişken oluşturup
22:06.4
22:40.6
Dönüşün ne zaman kesin olarak tamamlandığını öğrenip ona göre durdurmak adına eğer istediğimiz değere 5 kere ulaşıldıysa kontrolörü ve robotu durduruyoruz.
23:03.6
23:13.3
Eğer hedefe ulaşılmadıysa ise yani değer 5 in altında kaldıysa sıfırlıyoruz ve olana kadar devam etmesini sağlıyoruz.
23:13.4
23:32.4
Ve eğer tüm bu aşamalar başarılı bir şekilde geçildiyse isfinished değişkenimiz de true hale gelecek ve işlem ve komut sonlanacak.
23:32.5
24:00.7
Bitirmeden önce dikkat etmemiz gereken son noktalardan birisi ise eğer bu işlemlerden herhangi birisi bölünürse veya durdurulursa kontrolörün de durmasını sağlamalıyız.
24:00.8
24:12.7
Bunun için ise en son bir end metodu oluşturarak bu metoda komut ve işlem tamamlandığında yapılması gerekenleri yazmamız gerekiyor.
24:12.8
24:17.6
Burada controller'ı gördüğünüz gibi disable etmemiz gerekiyor.
24:17.7
24:34.1
Şu ana kadar yaptıklarımızdan yola çıkarak umarım PID'yi daha iyi bir şekilde anlamışsınızdır ve kullanabilirsiniz.
24:34.2
24:43.4
Bunu farklı sistemler için kullanırken elbette farklı girdileriniz ve farklı alt sistemleriniz olacak ancak basit olarak bunları bilmeniz size yardımcı olacaktır.
24:43.5
24:52.0
İzlediğiniz için teşekkürler ve umarım size yardım edebilmişimdir.