hard linkdownload
posted: LordN
(875 downloads)

ПИД-регулятор

заготовка для следящего, U=(P+I+D)/Zp, ПИД-регулятора с некоторыми пояснениями


/*	
	заготовка/болванка для ПИД-регулятора.
	основные и главные вещи.
	
	кой-какие пояснения:
	
	#define real	double
	
	real	themp			//	входная температура, регулируемый параметр, размерность - градусы
	real	thempSet		//	уставка температуры, размерность - градусы
	real	errThemp[3]		//	массив ошибок регулятора
	
	real	zoneProp		//	зона пропорциональности, размерность - градусы
	real	tauInt			//	постоянная интегрирования, размерность - секунды
	real	tauDiff			//	постоянная дифференцирования, размерность - секунды
	
	real	tauQuant		//	период квантования (реальный!!! период запуска функции регулятора), размерность - секунды
	
	real	tauDiffFilter		//	как бы кол-во усредняемых отсчётов Д-составляющей, 
					//	не стоит увлекаться и делать это число слишком большим.
	real	tauOutFilter		//	как бы кол-во усредняемых отсчётов полного выходного сигнала, аналогично.
//	подробности тут http://www.may.nnov.ru/mak/DSP/chEMA.shtml

	
	полезные ссылки по теме
	http://lord-n.narod.ru/walla.html#TheoryACUTP
	http://lord-n.narod.ru/walla.html#creatPID
	http://lord-n.narod.ru/walla.html#tunPID

важная ссылка!!!
	http://lord-n.narod.ru/walla.html#Denisenko
	для модификации регулятора с весовыми коэффициентами (гл.3.1), 
	потребуется расчитывать ошибки (и сохранять историю) отдельно для каждой составляющей!
	т.е. массив ошибок должен быть таким => errThemp[3,3]
*/

	KoeffNormOut = (real)MaxOut  / zoneProp;	//	нормировочный коэффициент
	
	/****************************************/
	
	errThemp[2] = errThemp[1];
	errThemp[1] = errThemp[0];
	
	//*******************************************************************
	//	Нормированная к отношению MaxOut/zoneProp ошибка регулирования для прямого регулятора.
	//	т.е. увеличивается температура - увеличивается выходной сигнал.
	//	режим - охлаждение нагревателя, обогрев.
	errThemp[0] = (themp - thempSet) * KoeffNormOut;
	
	//	ошибка для обратного регулятора.
	//	режим - нагрев охладителя, охлаждение.
	//	errThemp[0] = (thempSet - themp) * KoeffNormOut;
	
	//	вычисление и простейшая фильтрация Д-составляющей с предварительным усреднением по двум отсчётам
	Differential += (((errThemp[0] - errThemp[2]) * tauDiff * 0.5) - Differential) / tauDiffFilter;

//	без предварительного усреднения
//	Differential += (((errThemp[0] - errThemp[1]) * tauDiff) - Differential) / tauDiffFilter;
	
	//	вычисление И-составляющей методом трапеций с предварительным усреднением по двум отсчётам
	Integral += (((errThemp[0] + 2*errThemp[1] + errThemp[2]) * tauQuant * 0.25) / tauInt);

//	без предварительного усреднения
//	Integral += (((errThemp[0] + errThemp[1]) * tauQuant * 0.5) / tauInt);
	
	//	Ограничитель И-составляющей
	if(Integral > (real)MaxOut)
		Integral = (real)MaxOut;
	else
		if(Integral < (real)MinOut)
			Integral = (real)MinOut;
	
	//	Полный сигнал
	tmpReal = errThemp[0] + Integral + Differential / tauQuant;
	
	//	Ограничитель полного входного сигнала
	if(tmpReal > (real)MaxOut)
		tmpReal = (real)MaxOut;
	else 
		if(tmpReal < (real)MinOut)
			tmpReal = (real)MinOut;
			
	OutPID += (tmpReal - OutPID) / tauOutFilter;	//	фильтрация полного выходного сигнала