1
00:00:00,00 --> 00:00:05,600
Uzun bir süreden sonra herkese tekrardan 
merhaba ve proglamlama serimize devam ediyoruz

2
00:00:05,700 --> 00:00:16,000
Bu bölümde robotik için gerçekten önemli 
olan ve özellikle daha gelişmiş projelerde 
işinize yarayacak PID'den bahsedeceğiz.

3
00:00:16,100 --> 00:00:20,900
Bu konu hakkında ilk belirtmek istediğim 
şey PID nedir ve ne işimize yarar.

4
00:00:21,000 --> 00:00:25,800
Ve daha sonrasında bunu nasıl robotumuza 
uygulayacağımızı göstereceğim.

5
00:00:25,900 --> 00:00:30,700
İlk bilmeniz gereken şey PID ne için kullanılır.

6
00:00:30,800 --> 00:00:46,500
PID belirli bir sensör değerini kolay bir 
şekilde belirli bir yerde sabit tutmanızı 
kolaylaştırır.

7
00:00:46,600 --> 00:00:56,800
Buna verebileceğimiz iyi bir örnek robottaki 
elevatördür.

8
00:00:56,900 --> 00:01:01,700
Eğer elevatörde bağlı olan elin nerede olduğunu 
gösterebilecek bir sensör varsa,

9
00:01:01,800 --> 00:01:10,400
ve bu eli belirli bir seviyede tutmak istiyorsanız

10
00:01:10,500 --> 00:01:13,200
motorlar kendiliğinden sizin istediğiniz 
seviyede tutmayacaktır

11
00:01:13,300 --> 00:01:21,900
o seviyede tutabilmek için spesifik bir motor 
gücüne ihtiyacınız var.

12
00:01:22,000 --> 00:01:26,800
Peki, bunu nasıl yapacağız?

13
00:01:26,900 --> 00:01:31,700
Bunun gibi problemleri PID ile çözebiliriz.

14
00:01:31,800 --> 00:01:39,200
Diyelim ki bir grafiğiniz var ve sensörünüzden 
değer okuyabiliyorsunuz,

15
00:01:39,300 --> 00:01:47,100
Buradaki mavi çizgi ise elevatörün olmasını 
istediğiniz yer gibi düşünün

16
00:01:47,200 --> 00:01:55,100
Bu mavi çizgi örneğin 5 feet olsun ve siz 
de 5 feet de sabitlemek istiyorsunuz.

17
00:01:55,200 --> 00:02:03,600
Ve kırmızı çizgi ise motorun yaptığı hareketleri 
temsil ediyor.

18
00:02:03,700 --> 00:02:08,500
Burada orantısal kontrol işin içine giriyor 
ve

19
00:02:08,600 --> 00:02:13,400
sormamız gereken soru hedefe ne kadar yakınız 
ya da ne kadar uzağız

20
00:02:13,500 --> 00:02:22,900
Eğer hedefe ulaşmak adına orantısal bir şekilde 
güç uygularsak,

21
00:02:23,000 --> 00:02:27,800
Motorlar hatayı düzeltmek adına güç uygulayacaktır 
ve hata payına orantısal bir şekilde

22
00:02:27,900 --> 00:02:32,700
uygulanan gücü hedefe göre ayarlayacaktır

23
00:02:32,800 --> 00:02:37,600
Eğer fazla güç uygulanırsa ise hata payı 
negatif olacağı için ters yönde güç uygulanacaktır.

24
00:02:37,700 --> 00:02:42,500
Ve bu şekilde sürekli in çık yaparak hedefe 
ulaşmaya çalışılacaktır.

25
00:02:42,600 --> 00:02:47,400
Buna orantısal kontrol diyoruz ve yeteri 
kadar iyi bir yöntem değil çünkü hedefe ulaşmamız 
zor.

26
00:02:47,500 --> 00:02:57,000
Ancak eğer doğru bir şekilde ayarlayabilirseniz 
bazen işinize yarayabilir bu yöntem.

27
00:02:57,100 --> 00:03:01,900
Her ne kadar ayarlasanız da ideal bir yöntem 
olmayacaktır.

28
00:03:02,000 --> 00:03:10,000
Ve şimdi bakacağımız kontrol yöntemi ise 
türev(derivative)

29
00:03:10,100 --> 00:03:23,000
Burada bizim değişme miktarını türevle hesaplayıp 
performansı iyileştirmemizi sağlayacaktır.

30
00:03:23,100 --> 00:03:32,500
Eğer türevinizi biliyorsanız değiştirme hatasına 
göre bir güç uygulayarak hatanızı düzeltebilirsiniz.

31
00:03:32,600 --> 00:03:46,800
Yaptığınız hatayı hesaplayıp hataya göre 
hareket etmek orantısal kontrole göre size 
daha yardımcı olacaktır.

32
00:03:46,900 --> 00:03:54,200
Eğer buradaki dampening force değişkenini 
değiştirirsek karşımıza çıkan grafik de değişecektir.

33
00:03:54,300 --> 00:04:03,300
Üstteki grafikte gördüğünüz gibi her ne kadar 
mükemmel olmasa da hedefe daha çok yaklaştık.

34
00:04:03,400 --> 00:04:13,300
D değişkenini değiştirdikçe hatayı düzeltmek 
için uyguladığımız güç hassaslaşacaktır.

35
00:04:13,400 --> 00:04:18,700
Ancak bu değerler farklı sistemlere göre 
değişebileceği için

36
00:04:18,800 --> 00:04:23,600
her farklı mekanik sistemin farklı katsayıları 
olacaktır.

37
00:04:23,700 --> 00:04:28,500
Doğru katsayıyı bulmak için farklı metodlar 
vardır ancak deneme yanılma yapmak da gerekir.

38
00:04:28,600 --> 00:04:33,400
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.

39
00:04:33,500 --> 00:04:38,300
Aynı zamanda bu grafikler de ayarlamak için 
size yardımcı olabilir

40
00:04:40,500 --> 00:04:46,000
Ve şimdi bakacağımız katsayı ise integral 
katsayısı.

41
00:04:46,100 --> 00:04:48,000
Ve bu katsayı ayarlaması en zor olan katsayıdır.

42
00:04:48,100 --> 00:04:59,900
Başlangıçtan beri yapılan bütün hataları 
toplar.

43
00:05:00,000 --> 00:05:04,800
Ve hedeflediğiniz yere daha çabuk ve kolayca 
ulaşmanızı sağlar.

44
00:05:04,900 --> 00:05:09,700
Ve steady state error adlı bir şeyi de elimine 
etmenizi sağlar.

45
00:05:09,800 --> 00:05:14,600
Örneğin hedefinize yaklaştıkça daha küçük 
ayarlamalar yapmanız gerektiği için sürtünmenin 
etkisi artabilir.

46
00:05:14,700 --> 00:05:20,800
Ve sürtünme kuvvetini sıfırlayabilmek için 
karşı hareket yapmamızı sağlar.

47
00:05:22,200 --> 00:05:31,500
Genellikle I terimi P ve D terimlerinden 
daha küçük olmalıdır.

48
00:05:31,600 --> 00:05:34,200
Ö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ı

49
00:05:34,300 --> 00:05:39,100
kırmızı ve mavi çizgiler neredeyse aynı hizada 
bu da hedefimize ne kadar iyi ulaşabileceğimizi 
gösteriyor.

50
00:05:39,200 --> 00:05:46,700
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.

51
00:05:46,800 --> 00:06:04,900
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.

52
00:06:05,000 --> 00:06:12,600
Demin söylediğim dönme örneğini güzel bir 
şekilde kodumuzla bağdaştırabiliriz.

53
00:06:12,700 --> 00:06:23,400
Kodumuzda en son TalonSRX tanımlarını ve 
kurulumunu yapmıştık şimdi ise PID kurulumuna 
geçebiliriz.

54
00:06:23,500 --> 00:06:28,300
Şimdi ise WPILib tarafından hazırlanan PID 
metodlarından faydalanacağız.

55
00:06:28,400 --> 00:06:35,400
Bu kodu ister Spark kullanarak ister TalonSRX 
kullanarak yapabiliriz sonuçta tüm metodları 
WPILibden kullancağız.

56
00:06:35,500 --> 00:06:43,100
Ve bu sayede işimiz büyük ölçüde kolaylaşacak 
ancak yine de yapamamız gereken çok şey var.

57
00:06:43,200 --> 00:06:50,800
PID kurulumu için ilk yapmamız gereken şey 
ise bir PID controller tanımlamaktır.

58
00:06:50,900 --> 00:06:55,700
bunun için public final PIDController şeklinde 
tanımlayabiliriz.

59
00:06:55,800 --> 00:07:05,000
Bu metod tüm PID hesaplamalarını ve ayarlamalarını 
yapan metod olacaktır.

60
00:07:05,100 --> 00:07:09,900
Demin grafiklerde ise bu grafikler excel 
fonksiyonları ile hazırlanmıştı ancak

61
00:07:10,000 --> 00:07:14,800
Şimdi bu hesaplamaları tanımladığımız PIDController 
yapacak.

62
00:07:14,900 --> 00:07:19,700
Hesaplamaların mantığını anlamak istiyorsanız 
Wikipedia'da detaylı anlatımlar mevcut ancak 
şu an sadece PIDController'ı bilmemiz yeterli.

63
00:07:19,800 --> 00:07:30,000
Bu controller'ın çalışması için birkaç şeye 
ihtiyacı var.

64
00:07:30,100 --> 00:07:34,900
İhtiyacı olan şeylerden birisi ise PID çıktısı 
yani kontrol etmesi gereken bir şey.

65
00:07:35,000 --> 00:07:39,800
İhtiyacı olan diğer şeylerden birisi ise 
okuması gereken bir giriş yani bir sensör.

66
00:07:39,900 --> 00:07:44,700
İlk önce sensörle yani girişle başlayalım.

67
00:07:44,800 --> 00:07:50,800
Şu anda bizim yapmak istediğimiz robotu belirli 
bir şekilde döndürmek

68
00:07:50,900 --> 00:08:00,100
ve bunun için drivebase'imizi kontrol etmemiz 
gerekiyor bu da bizim PID outputumuz oluyor.

69
00:08:00,200 --> 00:08:10,200
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.

70
00:08:10,300 --> 00:08:28,400
Eğer java'ya hakimseniz, interfaceleri bilirsiniz. 
Ana sınıfımıza implements PID output ekliyoruz.

71
00:08:28,500 --> 00:08:33,300
Ve şimdi ise bizim için bir çıktı fonksiyonu 
oluşturuldu.

72
00:08:33,400 --> 00:08:47,400
Sensörden okunan değer sonucunda uygulanması 
gereken işlemleri bu fonksiyonda belirleyeceğiz 
ve bu sayede istediğimizi yapacağız.

73
00:08:47,500 --> 00:09:19,400
Şimdi ise yapmamız gereken motorların neye 
göre çalışacağını ve ne yapmalarını istediğimizi 
bu fonksiyona yazmak.

74
00:09:19,500 --> 00:09:24,300
Bu satırı yazmanız sonucunda PID değerleri 
sonucunda robotumuz dönecektir.

75
00:09:24,400 --> 00:09:32,400
Şimdi yapmamız gereken ise grafikteki kırmızı 
çizgi yani PID girişini halletmek.

76
00:09:32,500 --> 00:09:34,400
Yapmamız gereken şeylerden birisi ise bir 
veri kaynağı oluşturmak.

77
00:09:34,500 --> 00:09:47,500
Bunun için ise bir sensör tanımlayabiliriz 
ve bu sayede PID Input kaynağı sağlamış oluruz.

78
00:09:47,600 --> 00:09:54,800
Tanımlayacağımız sensör ise bir gyro ve akselometer 
olan navX sensörü.

79
00:09:54,900 --> 00:09:59,700
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.

80
00:09:59,800 --> 00:10:04,600
Aynı zamanda sınıfımıza PIDInput implementini 
de eklemek zorundayız.

81
00:10:04,700 --> 00:10:25,800
Basit olarak şimdi yaptığımız tanım yani 
navX bizim PID Inputumuz olacak ve robotumuzun 
pozisyonunu bize bildirecek.

82
00:10:25,900 --> 00:10:30,700
Şimdi ise navX in kurulumunu tamamlamamız 
gerekiyor.

83
00:10:30,800 --> 00:10:35,600
Tamamlamak için ise normal bir motor tanımlar 
gibi yazılan satırı yazıyoruz.

84
00:10:35,700 --> 00:10:59,200
navX'in takılı olduğu port genellikle Roboriodaki 
MXP portu oluyor. Ve yazdığım portu yazarak 
AHRS tanımlamasını bitiriyoruz

85
00:11:07,100 --> 00:11:17,100
Şimdi ise önceden tanımladığımız PID controller'ın 
tanımını tamamlamamız gerekiyor

86
00:11:17,200 --> 00:11:24,100
Ve burada da grafikte kullandığımız katsayıları 
argüman olarak kullanmamız gerekiyor.

87
00:11:24,200 --> 00:11:29,000
Buradaki argümanları sonradan da değiştirebileceğiniz 
için farklı değişkenler yaratırsanız işiniz 
kolaylaşacaktır.

88
00:11:29,100 --> 00:11:45,600
Şimdi deneme amaçlı olduğu için bu katsayıları 
şimdilik 0 yapacağım sonradan değiştirebiliriz.

89
00:11:45,700 --> 00:11:55,600
Şimdi ise tanıma geri dönüp boş kalan yerleri 
doldurmamız gerekiyor.

90
00:11:55,700 --> 00:12:05,100
P I ve D katsaılarını yazdıktan sonra geriye 
input ve output kalıyor.

91
00:12:05,200 --> 00:12:20,400
Source olarak doğrudan navX'in adını yazarsak 
input değişkenini de tanımlamış olacağız.

92
00:12:20,500 --> 00:12:25,300
Output olarak ise yazmamız gereken şey ise 
drivebase metodunda olduğumuz için this yazmanız 
yeterli.

93
00:12:25,400 --> 00:12:32,200
Ve bunları yaparak PIDController tanımını 
tamamlamış olduk.

94
00:12:32,300 --> 00:12:55,100
Controller input ve output tanımladık ancak 
şimdi yapmamız gereken girdi değerinin aralığını 
belirtmek.

95
00:12:55,200 --> 00:13:05,900
Burada yazdığımı yazarak ve bir minimum bir 
de maksimum değer belirleyerek girdilerinize 
aralık belirleyebilirsiniz.

96
00:13:06,000 --> 00:13:10,800
Bizim ise burada belirleyeceğimiz aralık 
-180 derece ile 180 derece arasında olacağı 
için bu değerleri yazıyorum.

97
00:13:10,900 --> 00:13:20,000
Aynı şekilde output için de bir değer aralığı 
belirlememiz gerekmektedir.

98
00:13:20,100 --> 00:13:29,800
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

99
00:13:29,900 --> 00:13:55,400
Şimdi ise ayarlamamız gereken absoultetolerance 
değeri var. Bu değer için 2 derece yeterli 
olacaktır.

100
00:13:55,500 --> 00:14:13,100
Ayarlamamız gereken son bir şey ise dönerken 
bir daire oluşturduğumuz için ve

101
00:14:13,200 --> 00:14:23,100
-180 derece ile 180 derece arasındaki fark 
360 derece yerine 1 derece olduğu için bu 
değeri ayarlamamız gerekiyor

102
00:14:23,200 --> 00:14:28,000
setContinious satırını ekleyerek PID kontrolörümüzü 
dönmeye göre ayarlamamıza yardımcı olacağız.

103
00:14:28,100 --> 00:14:44,100
Ve tüm bu değerler sayesinde çalışacak bir 
PID controller elde ettik şimdi ise yapmamız 
gereken ise

104
00:14:44,200 --> 00:14:56,300
bu kontrolörün çalışmasını tetikleyecek bir 
komut oluşturmak ve ne zaman çalışacağını 
belirlemek.

105
00:14:56,400 --> 00:15:01,200
Bunun için yeni bir fonksiyon oluşturmamız 
gerekiyor

106
00:15:01,300 --> 00:15:12,000
Ve bu fonksiyonun girdisi olarak açı değerini 
yazmamız gerekiyor

107
00:15:12,100 --> 00:15:33,000
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.

108
00:15:33,100 --> 00:15:44,700
Bu fonksiyonda yapmamız gereken ise sensörümüzün 
değerini sıfırlamak ve oryantasyonunu güncel 
konumuna göre ayarlamak.

109
00:15:44,800 --> 00:16:05,200
Aynı şekilde kontrolörümüzü de sıfırlamak 
ve girdi değerlerini sıfırlamamız gerekiyor

110
00:16:05,300 --> 00:16:10,100
Ve garanti olsun diye PID katsayılarını tekrardan 
vermemiz bizim için iyi olacaktır.

111
00:16:13,800 --> 00:16:25,500
Şimdi ayarlamamız gereken diğer şey ise, 
bir setpoint belirlemektir.

112
00:16:25,600 --> 00:16:30,400
Setpoint mavi çizgi yani ulaşmak istediğimiz 
hedef olacaktır.

113
00:16:30,500 --> 00:16:37,500
Son yapamamız gereken ise PID kontrolcüsünü 
etkin hale getirmektir.

114
00:16:37,600 --> 00:16:42,400
Bu fonkisyon çalıştığı andan itibaren PID 
fonksiyonunuz çalışmaya başlayacaktır.

115
00:16:42,500 --> 00:16:54,500
Gerekli zamanlarda çalışması için bir komut 
atayabiliriz örneğin otonom ya da bir düğmeye 
basıldığında çalışması için.

116
00:16:54,600 --> 00:17:10,000
Başlı başına öğrenmek adına bunu da yapmamız 
öğrenme açısından işimize yarayacaktır ve 
yardımcı olacaktır

117
00:17:10,100 --> 00:17:14,900
O yüzden komutlar paketinde yeni bir class 
oluşturalım ve buraya PID için çalışacak 
komutumuzu hazırlayalım

118
00:17:15,000 --> 00:17:21,500
Bize hazır verilmiş kodları kullanmayacağımız 
için onları silebiliriz

119
00:17:37,100 --> 00:17:50,200
Sınıfı temizledikten sonra kullanacağımız 
bir fonksiyon açıp komutumuz için gerekli 
olan değerleri girmemiz gerekiyor.

120
00:17:50,300 --> 00:18:06,400
PID kontrolörünün ne zaman işlemi bitirdiğini 
öğrenmek için bir boolean oluşturabliriz.

121
00:18:23,200 --> 00:18:41,100
Şimdi ise normal bir komut yaparken yapmamız 
gereken basit şeyleri yapmamız gerekiyor.

122
00:18:41,200 --> 00:19:01,700
Daha sonra fonksiyonun içine kullanacağımız 
açı değerlerini tanımlamamız gerekiyor.

123
00:19:01,800 --> 00:19:10,700
İ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

124
00:19:10,800 --> 00:19:22,200
bu nedenle execute kısmında bahsetmemize 
gerek yok init kısmında bahsetmemiz çalışması 
için yeterli olacaktır.

125
00:19:22,300 --> 00:19:35,100
İ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.

126
00:19:35,200 --> 00:19:51,300
Ancak kontrolörün belli bir süreden sonra 
durması gerekmekte bunu ise ben PID deki 
hata payına göre yapmayı tercih ediyorum.

127
00:19:51,400 --> 00:20:12,500
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.

128
00:20:12,600 --> 00:20:23,500
Ve durmamız için bir uygun aralık belirlersek 
istediğimiz hedefe ulaştığımızda robotun 
dönmeyi durmasını sağlayabiliriz.

129
00:20:23,600 --> 00:20:45,800
Normalde PID controller hedefine ulaştığında 
duracaktır ancak robotun durmasını sağlamak 
için bu aralığa ihtiyacımız var.

130
00:20:45,900 --> 00:20:50,700
Bunun için ise bir farklı boolean oluşturarak 
ve boolean true olduğunda robotun durmasını 
sağlayacağız.

131
00:20:50,800 --> 00:21:15,300
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.

132
00:21:15,400 --> 00:22:06,300
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

133
00:22:06,400 --> 00:22:40,600
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.

134
00:23:03,600 --> 00:23:13,300
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.

135
00:23:13,400 --> 00:23:32,400
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.

136
00:23:32,500 --> 00:24:00,700
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.

137
00:24:00,800 --> 00:24:12,700
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.

138
00:24:12,800 --> 00:24:17,600
Burada controller'ı gördüğünüz gibi disable 
etmemiz gerekiyor.

139
00:24:17,700 --> 00:24:34,100
Şu ana kadar yaptıklarımızdan yola çıkarak 
umarım PID'yi daha iyi bir şekilde anlamışsınızdır 
ve kullanabilirsiniz.

140
00:24:34,200 --> 00:24:43,400
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.

141
00:24:43,500 --> 00:24:52,000
İzlediğiniz için teşekkürler ve umarım size 
yardım edebilmişimdir.

