PID Kontrol?

Başlatan Analyzer, 07 Mayıs 2006, 08:05:47

Analyzer

Selam,

PID kontrol işlemini bir Windows programı yazarak simule etmek istiyorum. Bu sebeple pid kontrolün mantığını arıyorum. Konu hakkında bilgisi olan var mı acaba?

Teşekkürler,

Analyzer
Üşeniyorum, öyleyse yarın!

conavar

bilmiyorum bu kısa acaklama size yeter mi
PID (Proportional-Integral-Derivative) günümüzde en çok kullanılan kontrol yöntemidir.
Endüstrideki uygulamaların bir çoğunda rahatca uygulanabilir. Çok geniş bir uygulama alanının olmasına rağmen PID uygulamaları için standart bir tanımlama yoktur.
Karl Astrom'a göre PID algoritması aşağıdaki gibidir:
Burada u(t) kontrol değişkeni, e(t) toplama noktası, y(t) çıkıştan ölçülen değerle aynıdır.
K, Ti, Td PID parametreleridir.
P: Oransal I: İntegral D:Türevsel

sadece P kontrolde kalıcı etki olmkta sistemde kalıcı hata meydana gelmektedir...
P+I kontrolde sistem referans sinyaline daha cabuk adepte olur ancak hızı ve oturma seyiyesi yeterli deildir...Ayrıca sönumli osilasyon yapar.
en iyisi(her yerde deil) P+I+D kontroldur....sonumlu osilasyonu yok eder ve sistem daha karalı calışır.....





özet:
yani referans sinyali ile iş sahasından gelen değişkenin integral ve türevlerini alarak hata katsayısı işe çarpıp çıkısa verir.....
kolay gelsin
.::BiLgi Paylaştıkça Çoğalır::.[/url]

CoşkuN


Ziya

/***************************************************************************\
   	PID Function
		
	Author : Greg Young, Z-World.

	The PID (Proportional Integral Derivative) function is used in mainly
	control applications. PIDCalc performs one iteration of the PID
	algorithm.

	While the PID function works, main is just a dummy program showing
	a typical usage.
\***************************************************************************/

typedef struct PID	{
		double	SetPoint;         //	Desired Value

		double	Proportion;			//	Proportional Const
		double	Integral;			//	Integral Const
		double	Derivative;			//	Derivative Const

		double	LastError;			//	Error[-1]
		double	PrevError;			//	Error[-2]
		double	SumError;			//	Sums of Errors
}	PID;

/*=========================================================================*\
   Perform One PID Iteration
\*=========================================================================*/

double
PIDCalc			(  PID				*pp,
						double			NextPoint
         		)

{	double	dError,
				Error;

		pp->SumError += (Error = pp->SetPoint - NextPoint);
		dError = pp->LastError - pp->PrevError;
		pp->PrevError = pp->LastError;
		pp->LastError = Error;
		return   (  pp->Proportion * Error
               +  pp->Integral * pp->SumError
               +  pp->Derivative * dError
               );
}

/*=========================================================================*\
   Initialize PID Structure
\*=========================================================================*/

void
PIDInit  (  PID      *pp
         )

{     memset ( pp,0,sizeof(PID) );
}

/***************************************************************************\
	Main Program
\***************************************************************************/

double
sensor			(	void								//	Dummy Sensor Function
					)

{		return 100.0;
}

void
actuator			(	double			rDelta		//	Dummy Actuator Function
					)

{}

void
main				(	void
					)

{	PID			sPID;							//	PID Control Structure
	double		rOut;							//	PID Response (Output)
	double		rIn;							//	PID Feedback (Input)

		PIDInit ( &sPID );					//	Initialize Structure
		sPID.Proportion	= 0.5;			//	Set PID Coefficients
		sPID.Integral		= 0.5;
		sPID.Derivative	= 0.0;
		sPID.SetPoint     = 100.0;			//	Set PID Setpoint

		for (;;) {								//	Mock Up of PID Processing
			rIn = sensor ();						//	Read Input
			rOut = PIDCalc ( &sPID,rIn );		//	Perform PID Interation
			actuator ( rOut );					//	Effect Needed Changes
		}
}
Arkadaşlar, bu kod ile ilgili bir kaç şey soracağım.

Derivative hesabında neden en yeni örneklemeden elde edilen error'u kullanmıyor da bir ve iki önceki örneklemeden elde edilen erroru kullanıyor?

Bir başka soru da türev ve integral alırken delta t zamanı neden kullanmıyor? Çünkü pid de oransal kısımda delta t yok, türevde bölüm, integralde de çarpan olarak gelmeyecek mi? Eğer örnek değerini alan olarak alıyorsa o zaman oransal kısım da sanki integral gibi olmuyor mu?
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

z

Sinyal frekansi dusukse yada sensor detayli bilgi vermiyorsa turev alirken iki komsu siralamadaki hatalarin farki cok kucuk olacagindan turev doyurucu bilgi icermez. Bu nedenle 2,3, hatta 100 geriden bile turev hesaplanir.

DT neden hesaplarda gorulmuyor.

Integral=DT* Sum_of_err*KI olsun

KI'=DT*KI dersek

Integral=KI'* Sum_of_err olur. Burada DT gizli kalmistir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

picusta

Ziya hocam, o kod örnek olarak verilmis, gerçekte çalismasi için birkaç ilave yapmak gerekir.

Endüstride kullanilan PID'lerin hepsi PIDf 'tir aslinda. Yani Türev kismi filtrelenerek kullanilir. Bunun nedeni sensörlerdeki gürültüdür, iki sensör ölçümü arasindaki fark hesaplanirsa, degisim olmazsa bile gürültü yüzünden yok sayilmayacak bir degerin çikacagidir.
Orada yapilmak istenilen hatanin türevinin ortalamasini hesaplamaktir. moving average veya 1. filtre konmak istenmistir.
Fark ettiginiz gibi pek basarili olmamistir.

Ayrica fark ettiginiz gibi örnekleme zamani kaale alinmamistir.
     for (;;) {                        //   Mock Up of PID Processing
         rIn = sensor ();                  //   Read Input
         rOut = PIDCalc ( &sPID,rIn );      //   Perform PID Interation
         actuator ( rOut );               //   Effect Needed Changes
      }

Bu döngüye zamani eklemek gerekir.

Ziya

Alıntı yapılan: "bunalmis"Sinyal frekansi dusukse yada sensor detayli bilgi vermiyorsa turev alirken iki komsu siralamadaki hatalarin farki cok kucuk olacagindan turev doyurucu bilgi icermez. Bu nedenle 2,3, hatta 100 geriden bile turev hesaplanir.

DT neden hesaplarda gorulmuyor.

Integral=DT* Sum_of_err*KI olsun

KI'=DT*KI dersek

Integral=KI'* Sum_of_err olur. Burada DT gizli kalmistir.
İlk kısım tamam. Yalnız DT gizli kalmamalı. İntegralde çarpan ama türevde bölen olarak girip toplanacak. Eğer DT'yi katsayılarda dikkate aldılarsa, yani kodda kullanılan Kd aslında Kd(set edilen)/DT ise, Ki de Ki(set edilen)*DT ise sorun kalmıyor. Ama öyle değilse kod hatalı.
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

Ziya

picusta, zaten sensörden alınan örneklerin filtrelenmiş olduğunu varsaymış olması gerekir değil mi? Zamanın eklenmesi gerektiği konusunda hemfikiriz :)

Eğer zaman katsayılarda gizli ise, ARM7'lerin Multiply Accumulate unitesi kullanılarak üç değerin katsayılarla çarpılması yeterli olacak (toplama otomatik yapılıyor) değil mi?

Yukarıdaki örnek kodda integralde de bir sorun görünüyor mu sizce?
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

z

Alıntı Yapİlk kısım tamam. Yalnız DT gizli kalmamalı. İntegralde çarpan ama türevde bölen olarak girip toplanacak. Eğer DT'yi katsayılarda dikkate aldılarsa, yani kodda kullanılan Kd aslında Kd(set edilen)/DT ise, Ki de Ki(set edilen)*DT ise sorun kalmıyor. Ama öyle değilse kod hatalı.

Aynen oyle. Turevde de DT gizli bolen olarak KD ye dahil edilir.

Islemciyi KD/DT islemi ile yada KI*DT islemi ile neden yorasin. KD' ve KI' nu bir kere hesaplarsin artik islemci sadece bunlari kullanir.

Bu tur hiz kazandiran islemler ozellikle kritik kucuk sureli PID dongulerinde cok onemlidir.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Ziya

Alıntı yapılan: "bunalmis"Aynen oyle. Turevde de DT gizli bolen olarak KD ye dahil edilir.

Islemciyi KD/DT islemi ile yada KI*DT islemi ile neden yorasin. KD' ve KI' nu bir kere hesaplarsin artik islemci sadece bunlari kullanir.

Bu tur hiz kazandiran islemler ozellikle kritik kucuk sureli PID dongulerinde cok onemlidir.
Kodu yazan kişi bundan bahsetmemiş. Neyse herkesin anlayacağını düşünmüş belki.

Hız dediniz de, bu işlemler integer aritmetiği ile yapılsa işlem daha hızlı olmaz mı?
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

z

Integer aritmetikte elbet hizli olur ancak program buradaki gibi basit olmaz.
Bu durumda kesirli sayilar uzerine islem yapmak gerekecek. Ancak gercekten hiz gerekiyorsa kesirli sayilarla islemler cok cambazlik gerektirir.
(Surekli olarak tam ve kesirli kisma atanan bitlerin sayisi ile oynanir.)
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

picusta

Evet ARM'lerin bazilarinda bu komut seti var:
Multiply And aCcumulate (MAC) ve long MAC.
dsPIC'lerde de var ama çarpanlar 16bit accumulator 40bit.
iyi bir noktaya parmak bastiniz, eger hiz araniyorsa islmeler floating point değil, fixed point yapilmali (islemcinin floating point co-process. yoksa), böylece donanim en iyi sekilde kullanilir.
float'tan fixed point'a dönüsüm yaparken en iyi erim/hassasiyet elde edilen dönüsüm yapilmalidir.
örnek olarak basit oransal kontrol alalim : 1V hata ölçüyorsunuz, bunu 12bit ADC'nin yazmacinda 1024 olarak okuyorsunuz. Katsayimiz 2 olsun.
Demek 1024'ü 2 ile çarpip çikisa verecegiz (çikistada A/D ile ayni D/A çevirim katsayisi oldugunu farz edersek).
Ama simdi diyelim katsayimizi 2.1 yapmak istiyoruz nasil olacak? 100 yapmak istesek?

Tahminimce ADuC ARM7'de bir PID 100kHz'den hizli örnekleme yapabilir (A/D çevrim, interrupt latency, hesaplama, çikis ). Kodu RAM'de çalistirmakta fayda var, yoksa hiz yari yariya iner. Zaten PID analog kontrolün taklidi oldugu için prosesin hizindan 20 kat hizli örnekleme yapmakta fayda var.

Bir yarisma açalim :
Kim daha hizli PID yapar diye, ARM,DSP, FPGA, PLC, Op-amp ? Herkes kendi sistemini çuvallamadan maksimum hizda çalistirmali.
Kurallar:
- Mikrodenetleyiciler polling kullanmamali, timer kesmesini kullanmali.
- En kötü süre hesaba alinmali.
- vs..

z

Ben opamp ile yarismaya katilmaya hazirim.

Kim ne ile cikacak karsima?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Ziya

Jal kullandığım yıllarda sht11 için bir arkadaş integer aritmetiği kullanarak hesaplamalari yaptirmişti ve gerçekten hayran kalmistim.

Integer aritmetiği kullanılırken işlemlerde kullanılan parametreler ve ölçümler baştan 10 veya 100 ile çarpıldıktan sonra işlem yapılsa ve en son sonuç çıktığında ilk başta çarptığımız rakama bölsek ondalık kısımlarını (en azından bir veya iki dijit) dikkate almış oluruz.

Yarışma konusu çok iyi olur da standart bir problem ile olsa çok daha iyi olur. Kuralların sınırlamaların detaylandırılması gerekir.
Bu günden sonra hiç kimse sarayda, divanda, meclislerde ve seyranda Türk dilinden başka dil kullanmaya. (13 Mayıs 1277) Karamanoğlu Mehmet Bey

picusta

Yarismadan çok bir benchmark yapsak?
Her kim bir sisteme PID uyguladi ise ulasabilecegi maks. hizi, hesap süresi, hassasiyet gibi teknik detaylari paylassin.
Op-Amp'tan op-amp'a fark var tabii. Piyasada bulunan orta boy bir FPGA ile  10MHz'lik bant genisligine sahip bir op-amp'tan daha fazla islem gücü çikar. Tabii o hizda çalisan A/D ve D/A katlarini ilave etmek gerekir.
Ben en son kontrolör yaptigimda ayni bu sorun ile karsi karsiya gelmistim.
Yanlis hatirlamiyorsam ilk basta PID algoritmasinin disinda katsayiyi oranliyordum (32 bitin tamamini kullanmak için).
ölçülen degeri de x bit sola shift ediyordum (o mikrodenetleyicide (Renesas) çarpmaktan daha hizli ) sonra oranlanmis katsayi ile çarpim çikista saga shift ile bölme ( çikis katindaki D/A katsayisi hesaba katilarak).
Bütün bunlari yaparken accumulator'ün overflow yapmamasina dikkat etmek gerekir tabii.