Bir Arduino kullanarak motorlu bir fader (doğrusal slayt potansiyometre) kontrol etmeye çalışıyorum.
PID kontrolü, belirli bir hedef konuma "zıplamak" için iyi sonuçlar verir, ancak rampaları izlemek bir problemdir, hiç de pürüzsüz değildir. Ne denesem deneyim hareket çok sarsıntılı.
Bir rampayı izlerken referans pozisyonu, ölçülen pozisyon ve motor çıkışının bir çizimi:
Ve işte aynı testin bir videosu .
Ticari sistemlerde, çok daha düzgün görünüyor, bkz bu .
Ayrıntılar :
Motor fader bir Alps RSA0N11M9A0K'dır . Sürmek için, 10 V DC güç kaynağı ( XL6009 ) ile güçlendirilmiş bir ST L293D H köprüsü kullanıyorum .
Arduino UNO'da (ATmega328P), duyulamaz hale getirmek için 31.372 kHz PWM frekansı ile 9 ve 10 pinlerini kullanıyorum (1 ölçeklendiricili Timer1,TCCR1B = (TCCR1B & 0b11111000) | 0b001
).
Potansiyometre, toprak ile 5V arasında bağlanır ve silecek her zamanki gibi ADC0'a gider.
Denetleyici :
1 kHz hızında güncellenen anti-windup özellikli basit bir PID denetleyicisi kullanıyorum (Ts = 1e-3 s):
float update(int16_t input) {
int16_t error = setpoint - input;
int16_t newIntegral = integral + error;
float output = k_p * error
+ k_i * newIntegral * Ts
+ k_d * (input - previousInput) / Ts;
if (output > maxOutput)
output = maxOutput;
else if (output < -maxOutput)
output = -maxOutput;
else
integral = newIntegral;
previousInput = input;
return output;
}
Denetleyicinin çıkışı -127 ila 127 arasında bir değerdir. PWM çıkışı aşağıdaki gibi üretilir:
const int8_t knee = 48;
uint8_t activation(int8_t val) {
if (val == 0)
return 0;
else {
return map(val, 0, 127, 2 * knee, 255);
}
}
void writeMotor(int8_t val) {
if (val >= 0) {
analogWrite(forward, activation(val));
digitalWrite(backward, 0);
} else {
analogWrite(backward, activation(-val));
digitalWrite(forward, 0);
}
}
7 bit PWM sinyaline 48 ekledim, çünkü motor 31 kHz'de hareket etmeye başlıyor ve sonra 8 bit sayıya kadar ölçeklendiriyorum (çünkü analogWrite
fonksiyonun beklediği şey budur):
Ne denedim :
PID denetleyicisinin türev bileşenine giriş, kontrol sinyaline bir EMA filtresi eklemeye çalıştım, ancak boşuna. Ayrıca , durağan olduğunda iki değer arasında geçiş yapmasını durdurmak için histerezis kullanarak analog girişin çözünürlüğünü düşürmeyi denedim . Bu hiçbir şeyi etkilemiyor gibi görünmüyor. Zaman adımını 10 ms'ye çıkarmak da yardımcı görünmüyor.
Ayrıca MATLAB'da bir sistem tanımlaması yapmayı denedim ve Simulink'te ayarlamayı denedim (bu video serisini takiben) ). % 91 uygun bir model aldım, ancak MATLAB modelinin giriş ve çıkış doğrusallıklarının nasıl ele alınacağını, PID ayarını nasıl etkilediğini ve Arduino'ya nasıl uygulanacağını bilmiyordum.
Denediğim son şey iki farklı kontrolör yapmaktır: biri referans konumundaki büyük sıçramalar için ve diğeri bir rampa izlerken küçük hatalar için. Bu biraz yardımcı oluyor gibi görünüyor, çünkü o zaman izleme sırasında integral katsayısını, atlama sırasında aşmayı arttırmadan artırabilirim.
Bununla birlikte, integral (ve orantılı) kazancı artırarak, motor artık sabit olması ve referansın değişmemesi durumunda bile her zaman bir şeyler yapmaktadır. (Gerçekten hareket etmiyor, ancak titreşimli olduğunu hissedebiliyorsunuz.)
Neredeyse hiç türev kazancım yok, çünkü 1e-4'ten daha yüksek bir artış, onu daha da jerkier yapıyor gibi görünüyor ve 0 ile gerçekten arasında herhangi bir fark görmüyorum. 1e-4.
Benim tahminim, statik sürtünmenin üstesinden gelmek için daha fazla güce ihtiyaç duyması, daha sonra dinamik sürtünmenin daha az olması, bu yüzden aşması, bu yüzden motoru geriye doğru sürmesi, tekrar durmasına neden olması, tekrar statik sürtünmenin üstesinden gelmesi gerekiyor, tekrar ileri doğru ateş ediyor , vb.
Ticari denetleyiciler bu sorunun üstesinden nasıl gelir?
Geçmişim :
Elektrik Mühendisliği üçüncü lisans yılımdayım, kontrol teorisi, dijital sinyal işleme, LQR kontrolü vb. Dersleri izledim, bu yüzden teorik bir geçmişim var, ancak tüm bu teorileri uygulamakta sorun yaşıyorum bu gerçek dünya sistemi.
Düzenleme :
Açık döngü sensör ölçümlerini, laptop2d'nin önerdiği gibi test ettim ve sonuçlarla oldukça şaşırdım: Yüksek PWM frekanslarında, okumalarda kötü tepeler var. 490 Hz'de hiç yoktur.
Ve bu sürekli bir görev döngüsünde, bu nedenle motor yönü çok hızlı bir şekilde ters çevirdiğinde ne tür bir gürültü aldığımı hayal edemiyorum.
Bu yüzden kontrol cihazında tekrar çalışmaya başlamadan önce bu gürültüyü filtrelemenin bir yolunu bulmam gerekecek.
Düzenleme 2 :
Üstel hareketli ortalama filtresi kullanmak gürültüyü filtrelemek için yeterli değildi.
Polonyalıları 0,25, 0,50 ve 0,75'te denedim. Küçük kutuplar fazla etkiye sahip değildi ve daha büyük kutuplar çok fazla gecikme ekledi, bu yüzden sabit tutmak için kazançları düşürmek zorunda kaldım, bu da genel performansın daha kötü olmasını sağladı.
Potansiyometre boyunca (silecek ile toprak arasında) 0.1 µF kapasitör ekledim ve bu onu temizliyor gibi görünüyor.
Şimdilik, yeterince iyi çalışıyor. Bu arada Tim Wescott'un gönderdiği makaleyi okuyorum .
Yardımlarınız için hepinize teşekkürler.
This device is suitable for use in switching applications at frequencies up to 5 kHz.
Bağladığınız H köprüsünün veri sayfasının ön sayfasında bulunur: Ancak, tüm gecikmeleri eklerseniz, Elektriksel Özellikler sayfa 3'te mutlak maksimum 690kHz önerir. (alt 4 satır) Şahsen, bundan çok daha yavaş giderdim, ama