Genetik Algoritmalar’la PID Parametrelerinin Optimizasyonu
Bu yazıda PID kontrolcü parametrelerinin optimizasyonu (eniyilenmesi) için Genetik Algoritmalar’ın (GA) kullanımına dair, Python üzerinde geliştirilmiş basit bir örnek sunulmuştur. PID kontrolcüsü; klasik bir kontrol problemi olan basit sarkaç (simple pendulum) modeli üzerinde çalıştırılarak, zaman uzayında benzetimler yapılmıştır. PID ve Genetik Algoritmalar kavramlarını ilk kez duyuyorsanız, daha önce yazdığım yazılara kavramların üzerlerine tıklayarak göz atabilirsiniz.
Uygulamanın kaynak kodlarına buradan ulaşabilirsiniz.
Amaç
Basit sarkaç problemi: 1 serbestlik dereceli sarkacın açısal konum kontrolünün sağlanmasını ifade eden, alışılagelmiş kontrol problemlerinden birisidir. Genellikle ip veya uzunluğu sabit bir çubuğa bağlı küre olarak tasvir edilir. Özellikle farklı kontrol yöntemlerini birbirleriyle kıyaslamak için yaygın olarak tercih edilir.
Yerçekiminin etkisiyle potansiyel enerji kazandırılıp serbest bırakılan sarkaç, denge noktası üzerinde salınımlar gerçekleştirir ve hava sürtünmesiyle enerjisi sönümlendükçe, açısal konumu (θ) denge noktasına yakınsamaya devam eder. 360 derece dönebilen bir sarkaç için aynı doğru üzerinde iki denge noktasından bahsedilebilir (yukarı ve aşağı). Kontrol probleminin amacı, genellikle, sarkacı bu denge noktaları üzerinde sabit tutmaktır. Bunun yanı sıra, istenilen herhangi bir açısal konum için de kontrol uygulanabilir.
Modelleme
Kontrol edilecek sarkaç, kütle merkezi uzunluğunun tam ortasında bulunan, dikdörtgen bir çubuk olarak belirlenmiştir. Herhangi bir zamanda çubuğa etki eden momentler, aşağıdaki serbest cisim diyagramında belirtilmiştir.
Görüldüğü gibi, sarkacın bağlı olduğunu varsaydığımız motorun uyguladığı moment (T); yerçekimi (Mg), atalet (J) ve hava sürtünmesine (B) maruz kalmaktadır. Sarkaç üzerindeki toplam momenti matematiksel olarak ifade edersek:
Burada elde ettiğimiz denklem, 2’nci dereceden nonlinear homojen olmayan bir diferansiyel denklemdir. Bilindiği gibi nonlinear diferansiyel denklemleri çözmek, farklı adımlar ve yaklaşımlar gerektirmektedir. Örneğin denklemi, bulunduğu sürekli zamandan (continuous-time) ayrık zamana (discrete-time) taşıyarak analitik bir çözüm sağlanabilir. Yaklaşık sonuçlar üretse de uygulaması görece kolay olduğu için bu yöntemi kullanabiliriz.
Öncelikle aşağıdaki ifadeler, sürekli zamandaki basit bir diferansiyel denklemin ayrık zamana geçişini belirtmektedir:
Buradaki k ve Δt ifadeleri sırasıyla: ayrık zamandaki spesifik bir noktayı ve örnekleme zamanını belirtmektedir. Bu şekilde her bir noktada, bir (örnekleme zamanı) önceki noktanın çözümü yapılarak, belli bir zaman aralığındaki yaklaşık çözüm sağlanır. Birinci denklemdeki türevsel ifadeyi genişletirsek:
Yukarıdaki denklem ortaya çıkacaktır. Bu yöntem Forward Euler olarak isimlendirilmektedir ve diferansiyel denklemlerin sayısal çözümünde yaklaşık sonuçlar üreten, makul bir yöntem olarak kullanılmaktadır. Aynı yöntemi en baştaki dinamik modelimize uygulayarak aşağıdaki denklemleri elde edebiliriz:
Birinci denklem açısal hızı, ikinci denklem ise açısal konumu vermektedir. Dikkat ettiyseniz, konum hesaplamasını, hızın hesaplamasından bir adım geride gibi düşünmek mümkün. Hesaplanan hızın, konumu nasıl değiştirdiğini aynı anda görebilmek için, aynı indisli hız değerini (k+1) ikinci denkleme yazarak kabaca bir çözüm sağlayabiliriz.
Benzetimde kullanmak gerektiği için, aynı modeli Python üzerinde kodlayalım:
- Pendulum adında basit bir sınıf oluşturduk ve gerekli parametreleri (kütle, uzunluk, sürtünme katsayısı, yerçekimi ve örnekleme zamanı) şekildeki gibi tanımladık. Birimleri görselde bulabilirsiniz*. Ek olarak atalet momentini hesaplamada gerekli J katsayısı, düz çubuğun atalet momenti göz önüne alınarak, şekildeki gibi hesaplanmıştır. state değişkeni ise sarkacın mevcut açısal hız ve konum bilgilerini tutacaktır. Sınıftan nesne üretildiken sonra, ayrıca başlangıç koşulları belirlenerek bu değişkene atanacaktır.
- Oluşturduğumuz matematiksel modeli, apply fonksiyonunun içine yazdık. Fonksiyon, parametre olarak aldığı giriş değeriyle (u) hesaplamaları yaparak, state değişkenine reset fonksiyonu ile sonuçları göndermektedir. th, thdot ve thddot değişkenleri sırasıyla: Açısal konum, hız ve ivmeyi ifade etmektedir.
- Fonksiyonun düzgün çalıştığından emin olmak için basit bir deneme yapalım:
- Sarkacı yere paralel olarak (θ = π/2 rad) ilk hızsız serbest bıraktık ve herhangi bir dış etki uygulamadık. Elde edilen grafik:
- Beklediğimiz gibi denge noktası etrafında salınan ve sürtünme kuvvetinin etkisiyle gittikçe sönümlenen bir sonuç elde ettik.
PID kontrolcüsü ve GA’nın Python üzerinde kodlanışıyla ilgili ayrıntılara, yazıyı fazla uzun tutmamak için girmiyorum. Fakat örneklerine, yukarıda belirttiğim yazılardan ulaşabilirsiniz.
Sistem modelini oluşturduktan sonra, geriye PID kontrolcüsünü ve onun eniyileyecek GA tanımlamalarını yapmak kalıyor. Öncelikle aşağıdaki blok diyagramına göz atalım:
- Uygunluk fonksiyonu, referans girişiyle mevcut PID parametrelerinin sağladığı kontrolü işleyerek, parametrelerin ne derece başaralı olduğunu uygunluk değerine dönüştürmektedir. Uygunluk fonksiyonu olarak ortalama kare hatası (mean squared error) aşağıdaki gibi belirlenmiştir:
- Referans girişi (R) ve sistem cevabı (r) her bir örnek için paydada hesaplanır ve sonuç 1'e bölünür . Bu sayede sıfırı en kötü uygunluk değeri olarak kabul edip, uygunluk değeri sıfıra daha yakın bireyleri de elverişsiz bireyler olarak değerlendirmemiz mümkün.
- Bir GA klasiği olarak, algoritmanın temelinde üç temel yapıyı inşa etmek gerekecektir: Gen, kromozom ve popülasyon. Herbir kromozom muhtemel bir çözüm adayını, popülasyon ise muhtemel çözüm kümesini temsil etmektedir. Genler ise kromozomu oluşturan ve mutasyon, çaprazlama gibi operatörlerle müdahale edebildiğimiz en temel yapıdır. Bu uygulamada eniyilenecek PID parametreleri olan Kp, Ki ve Kd; gen olarak tutulacaktır. Genleri oluşturmak için literatürde Gray ve ikili kodlama gibi çeşitli yöntemler önerildiyse de, doğrudan reel sayı olarak tanımlamak tercih edilmiştir:
- Başlangıçta parametrelere, ileride belirlenecek aralıktan, rastgele reel sayılar seçilerek atanacaktır.
- Kromozom sınıfı, kendi genlerini oluşturarak, çaprazlama (crossover) ve mutasyon (mutation) operatörlerini bu genler üzerinde uygulamaktadır. Her kromozomun uygunluğu fitness değişkeninde saklanacaktır. count değişkeni ise kromozomun deneme hakkıdır. Kısaca: Her bir kromozom, rastgele başlangıç pozisyonu verilen sarkacı istenilen konuma getirmek için, belirlenen count değeri kadar deneme yapma hakkına sahiptir. Daha sonra bütün denemelerdeki başarısının ortalaması alınarak, uygunluk değeri olarak atanacaktır. Bu şekilde daha güçlü (robust) bir kontrol sağlanması amaçlanmıştır.
- Son olarak popülasyon sınıfımızı oluşturalım:
- GA için çeşitli hiper parametreler, doğrudan bu sınıf üzerinden alınacaktır. Her nesilde en iyi yerel (local) ve genel (global) çözüm adayları bulunarak ilgili değişkenlere atanacaktır. Belirlenen referans konum (target) ve maksimum nesil de aynı zamanda istenmektedir.
- Sınıflarla ilgili oluşturduğum daha fazla değişken ve fonksiyona kaynak kodlarından ulaşabilirsiniz.
Benzetim
- Son olarak uygulamanın asıl çalışacağı main dosyasına geçebiliriz:
- Kontrol ve GA parametrelerini şekildeki gibi belirledik. Genetik Algoritmalar’la daha iyi çalışabilmek için bu parametrelerin de ayrıca bir eniyilemeye gereksinim duyduğu bir gerçek. Fakat yazının kapsamı tam olarak bu konuları içermediği için, buradaki parametrelerin tamamen sezgisel olarak belirlendiğini göz önünde bulundurabilirsiniz.
- Nesnelerimizi oluşturduk ve sarkaç parametrelerini şekildeki gibi belirledik. Ayrıca daha gerçekçi bir sonuç elde edebilmek için bir maksimum çıkış değeri tanımladık. Bu değeri, PID kontrolcünün çıkışına satürasyon uygulamada kullanacağız.
- Başlangıçta uygulamanın düzgün çalışması için gerekli olduğundan, yerel ve genel en iyi değerleri rastgele olarak belirledik. Her bir neslin ortalama uygunluğunu genscore değişkeni tutmaktadır. Aşağıdaki for döngüsü ile mevcut nesildeki bütün kromozomlar dolaşılarak kontrol hesaplamaları yapılmaktadır.
- reset değişkeninin upper parametresiyle gönderdiğimiz açı, sarkacın rastgele serbest bırakılacağı maksimum açıyı belirtmektedir. Minimum değer ise aynı değerin negatifidir. Şekildeki gibi her bir kromozom, sahip olduğu parametrelerle belirlenen count değeri kadar kontrol çevrimini işletmektedir.
- Mevcut nesildeki bütün kromozomlar çalıştırıldıktan sonra, GA’nın asıl değerlendirme ve seçme fonksiyonları şekildeki gibi çalışmaktadır. generate fonksiyonu ile yeni nesil oluşturulmakta ve bütün süreç, yeni nesille böylece devam etmektedir.
- Uygulama yukarıdaki parametrelerle çalıştırılarak aşağıdaki sonuçlar elde edilmiştir:
- 50 nesil boyunca hesaplanan uygunluk değerlerlerinin ortalaması şekildeki gibidir. Başlangıçta arttığı fakat zamanla duraksadığı söylenebilir. Uygulama sonucunda hesaplanan en iyi PID parametreleri:
Kp = 39.23477, Ki = 0.85060, Kd =5.12875
- Parametreleri başlangıçta belirlediğimiz referans girişi ve diğer girişler için, yine rastgele başlangıç pozisyonları belirleyerek, PID kontrolcüsüyle 20 kez çalıştırdığımız zaman aşağıdaki sonuçlar elde edilmiştir:
Sonuç
Genetik Algoritmalar, sistem performansını geliştirmek için gerekli matematiksel modellerin tam olarak belirlenemediği veya öngörülerin yetersiz olduğu durumlarda kabul edilebilir sonuçlar üreten, fakat en iyi sonucu garanti etmeyen bir araçtır. Tıpkı PID performansını geliştirip, sistemde daha hassas ve beklentilere uygun kontrol sağlamak istediğimiz gibi; Genetik Algoritmayı da üzerinde çalıştığı sisteme daha uyumlu hale getirerek, eniyileme performansını geliştirmek mümkün. Bu kısma değinmenin daha fazla uzmanlık gerektirdiği aşikâr. Dolayısıyla bu yazıda basitçe ikisinin ortak kullanımına bir örnek verilmeye çalışılmıştır. Fakat ek olarak; yerleşme zamanı, yükselme zamanı, kalıcı hal hatası gibi temel kontrol ölçütleri de uygunluk fonksiyonuna eklenerek, bu önemli detayları da göz ardı etmeyen daha verimli uygulamalar geliştirilebilir.
Okuduğunuz için teşekkür ederim.
*Düzeltme: gravity birimi m/s² olmalıdır.