WPILib’de PID Kontrolü

Not

Bu makale, WPILib’in sağladığı kütüphane sınıflarıyla PID Denetiminin kod içi uygulamasını kapsar. İlgili kavramları daha ayrıntılı olarak açıklayan belgeler yakında çıkacaktır.

Not

Komut Tabanlı framework aracılığıyla PID kontrolünün uygulanmasına ilişkin bir kılavuz için bkz PIDSubsystems ve PIDCommands üzerinden PID Kontrol.

WPILib, PIDController sınıfı (Java <https://first.wpi.edu/wpilib/allwpilib/docs/release/java/edu/wpi/first/wpilibj/controller/PIDController.html> __, C ++ <https://first.wpi.edu/wpilib/allwpilib/docs/release/cpp/classfrc2_1_1PIDController.html> __) aracılığıyla mekanizmaların PID kontrolünü destekler. Bu sınıf, kullanıcı için geri besleme döngüsü hesaplamasını gerçekleştirmenin yanı sıra hatayı döndürmek, toleransları ayarlamak ve kontrol döngüsünün belirtilen toleranslar dahilinde ayar noktasına ulaşıp ulaşmadığını kontrol etmek için yöntemler sunar.

PIDController Sınıfını Kullanma

Not

Frc namespace içerisinde PIDController sınıfı kullanımdan kaldırıldı - C ++ takımları bunun yerine frc2 namespace kullanmalıdır. Aynı şekilde Java ekipleri de wpilibj.controller paketindeki sınıfı kullanmalıdır.

Bir PIDController Oluşturma

Not

PIDController eşzamansız olarak kullanılabilirken, herhangi güvenlik özelliği sağlamaz - güvenli çalışmanın tamamen kullanıcıya bırakılmasını sağlar ve bu nedenle eşzamansız kullanım yalnızca gelişmiş ekipler için önerilir.

WPILib’in PID kontrol fonksiyonelliğini kullanmak için, kullanıcılar önce istenen kazançlarla bir PIDController nesnesi oluşturmalıdır:

// Creates a PIDController with gains kP, kI, and kD
PIDController pid = new PIDController(kP, kI, kD);

Constructor’a, denetleyicinin çalıştırılacağı süreyi belirleyen isteğe bağlı dördüncü bir parametre sağlanabilir. PIDController nesnesi, esas olarak ana robot döngüsünden senkronize kullanım için tasarlanmıştır ve bu nedenle değeri varsayılan olarak 20ms’dir.

Geri Besleme Döngüsü Çıkışını Kullanma

Not

PIDController, calculate() yönteminin yapılandırılan periyotla tutarlı bir aralıkta düzenli olarak çağrıldığını varsayar. Bunun yapılmaması, istenmeyen döngü davranışına neden olacaktır.

Uyarı

Eski PIDController in aksine, yeni PIDController kendi iş parçacığından bir çıktıyı otomatik olarak kontrol etmez - kullanıcıların calculate() i çağırması ve elde edilen çıktıyı kendi kodlarında kullanması gerekir.

Oluşturulan PIDController i kullanmak basittir: basitçe robotun ana döngüsünden calculate() yöntemini çağırın (örneğin, robotun autonomousPeriodic() yöntemi):

// Calculates the output of the PID algorithm based on the sensor reading
// and sends it to a motor
motor.set(pid.calculate(encoder.getDistance(), setpoint));

Hataları Kontrol Etmek

Not

getPositionError() ve getVelocityError(), döngünün bir konumu kontrol ettiği varsayılarak adlandırılır - bir hızı kontrol eden bir döngü için bunlar sırasıyla hız hatasını ve hızlanma hatasını döndürür.

Ölçülen işlem değişkeninin mevcut hatası,``getPositionError()`` işlevi tarafından döndürülür, türevi ise getVelocityError() işlevi tarafından döndürülür:

Toleransları Belirleme ve Kontrol Etme

Not

Yalnızca bir konum toleransı belirtilirse, hız toleransı varsayılan olarak sonsuzdur.

Not

Yukarıdaki gibi, position işlem değişken ölçümünü ve velocity bunun türevini ifade eder - dolayısıyla, bir hız döngüsü için bunlar aslında sırasıyla hız ve ivmedir.

Bazen, bir denetleyicinin ayar noktasını belirli bir tolerans dahilinde izleyip izlemediğini bilmek yararlıdır - örneğin, bir komutun sonlandırılması gerekip gerekmediğini veya (bir hareket profilini takip ederken) hareketin engellenip engellenmediğini belirlemek yada tekrar planlamak için.

Bunu yapmak için önce toleransları setTolerance() yöntemi ile belirlemeliyiz; daha sonra atSetpoint() metodu ile kontrol edebiliriz.

// Sets the error tolerance to 5, and the error derivative tolerance to 10 per second
pid.setTolerance(5, 10);

// Returns true if the error is less than 5 units, and the
// error derivative is less than 10 units
pid.atSetpoint();

Denetleyiciyi Sıfırlama

Artık geçerli olmayabileceğinden (örneğin, PIDController devre dışı bırakıldığında ve ardından yeniden etkinleştirildiğinde) bir PIDController in dahili durumunu (en önemlisi, integral akümülatörü) temizlemek istenebilir. . Bu, reset() yöntemi çağrılarak gerçekleştirilebilir.

Max Integrator Değeri Ayarlama

Not

Entegratörler, geri besleme döngü sistemlerine kararsızlık ve histerezis getirir. Kesinlikle başka hiçbir çözüm işe yaramayacaksa ekiplerin integral kazanımı kullanmaktan kaçınmaları şiddetle tavsiye edilir - çoğu zaman, bir entegratörle çözülebilecek sorunlar daha doğru bir feedforward kullanılarak daha iyi çözülebilir.

İntegral geri besleme kullanılırken karşılaşılan tipik bir sorun, sistemin ayar noktasını çılgınca aşmasına neden olan aşırı “tetiklemedir”. Bu, birkaç yolla hafifletilebilir - WPILib PIDController, takımların bu sorunun üstesinden gelmesine yardımcı olmak için bir entegratör menzil sınırlayıcısı sunar.

Bu ayarın setIntegratorRange() yöntemiyle etkinleştirilmesi, integral kazancın toplam çıktı katkısının kullanıcı tarafından belirlenen sınırları aşmasını önleyecektir.

// The integral gain term will never add or subtract more than 0.5 from
// the total loop output
pid.setIntegratorRange(-0.5, 0.5);

Sürekli Girişi - Continuous Input Ayarlama

Uyarı

Mekanizmanız tamamen sürekli dönme kabiliyetine sahip değilse (örneğin, kabloları döndükçe bükülen, kayma halkası olmayan bir turret), mekanizmanın limitlerini geçmesini önlemek için ek bir güvenlik özelliği uygulamadıysanız sürekli girişi etkinleştirmeyin !

Uyarı

Sürekli giriş işlevi, giriş değerlerinizi otomatik olarak kaydırmaz - bu özelliği kullanırken, giriş değerlerinin asla belirtilen aralığın dışında olmadığından emin olun!

Bazı işlem değişkenleri (bir taretin açısı gibi) doğrusal bir ölçek yerine dairesel bir ölçekte ölçülür - yani, proses değişken aralığının her “sonu” gerçekte aynı noktaya karşılık gelir (örneğin, 360 derece ve 0 derece). Böyle bir konfigürasyonda, herhangi bir hata için, hatanın daire etrafında hangi yoldan ölçüldüğüne karşılık gelen iki olası değer vardır. Bu hatalardan daha küçük olanı kullanmak genellikle en iyisidir.

Bunu otomatik olarak yapacak bir PIDController yapılandırmak için, enableContinuousInput() yöntemini kullanın:

// Enables continuous input on a range from -180 to 180
pid.enableContinuousInput(-180, 180);

Kontrol Çıkışını Bağlama

Eski PIDController in aksine, kullanıcının döngü çıkışını kendisinin kullanması beklendiğinden, yeni kontrolör herhangi bir çıkış bağlama özelliği sunmamaktadır. Çıkış bağlama, denetleyiciyi WPI’nin clamp() işlevi (veya c++ ‘da std::clamp) ile oluşturarak kolayca elde edilebilir:

// Clamps the controller output to between -0.5 and 0.5
MathUtil.clamp(pid.calculate(encoder.getDistance(), setpoint), -0.5, 0.5);