⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcontrollor.cpp

📁 程序实现了模糊控制理论中恒温箱的模拟
💻 CPP
字号:
// TControllor.cpp: implementation of the CTControllor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TControllor.h"

#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTControllor::CTControllor()
{
	int i;
	T=0;
	w0=0;

	E.value=0;
	detaE.value=0;
	W.value=0;

	for(i=0;i<5;i++)
	{
		E.lishudu[i]=0;
		detaE.lishudu[i]=0;
		W.lishudu[i]=0;
	}

	for(i=0;i<9;i++)
	{
		using_rule[i]=0;
		using_rule_weight[i]=0;
	}

	cnt=0;
	enhance=0.2f;
}

CTControllor::~CTControllor()
{

}
//求较小值
float CTControllor::Min(float a, float b)
{
	return ((a<=b)?a:b);
}
//求较大值
float CTControllor::Max(float a, float b)
{
	return ((a>=b)?a:b);
}
//规范取值,计算隶属度
void CTControllor::CalLishudu(Variable &v)
{
	for(int i=0;i<5;i++)
		v.lishudu[i]=0;

	if(v.value<=-4)
	{
		v.value=-4;
		v.lishudu[0]=1;
	}
	else if(-4<v.value&&v.value<=-2)
	{
		v.lishudu[0]=(float)(-0.5*v.value-1);
		v.lishudu[1]=(float)(0.5*v.value+2);
	}
	else if(-2<v.value&&v.value<=0)
	{
		v.lishudu[1]=(float)(-0.5*v.value);
		v.lishudu[2]=(float)(0.5*v.value+1);
	}
	else if(0<v.value&&v.value<=2)
	{
		v.lishudu[2]=(float)(-0.5*v.value+1);
		v.lishudu[3]=(float)(0.5*v.value);
	}
	else if(2<v.value&&v.value<=4)
	{
		v.lishudu[3]=(float)(-0.5*v.value+2);
		v.lishudu[4]=(float)(0.5*v.value-1);
	}
	else if(v.value>4)
	{
		v.value=4;
		v.lishudu[4]=1;
	}
}

void CTControllor::WriteRules()
{
	int ei,dei;
	int i=0;

	for(i=0;i<9;i++)
	{
		using_rule[i]=0;  //使用规则清零
		using_rule_weight[i]=0;
	}

	for(i=0;i<5;i++)
		W.lishudu[i]=0; //输出量对模糊量的隶属度置为零

	for(ei=0;ei<5;ei++) //温差的五个模糊级
	{
		for(dei=0;dei<5;dei++) //温度变化率的五个模糊级
		{
			if(E.lishudu[ei]!=0&&detaE.lishudu[dei]!=0) //可能对应有输出量W
			{
				if(ei==2) //温差对应模糊变量为ZO
				{
					using_rule[dei]=1;
					using_rule_weight[dei]=Min(E.lishudu[ei],detaE.lishudu[dei]);

					W.lishudu[4-dei]=1; //使输出量隶属于该模糊量
				}
				else if(ei<2&&dei==2) //up
				{
					using_rule[ei+5]=1;
					using_rule_weight[ei+5]=Min(E.lishudu[ei],detaE.lishudu[dei]);

					W.lishudu[4-ei]=1;

				}
				else if(ei>2&&dei==2) //down
				{
					using_rule[ei+4]=1;
					using_rule_weight[ei+4]=Min(E.lishudu[ei],detaE.lishudu[dei]);

					W.lishudu[4-ei]=1;
				}
			}
		}
	}

}

void CTControllor::CalculateW()
{
	int i;
	float numerator=0.0,denominator=0.0;

	for(i=0;i<200;i++)//积分元为0.04
	{
		W.value=0.04f*i-4.0f;
		numerator+=W.value*GetMTW(W);
		denominator+=GetMTW(W);
	}

	w0=numerator/denominator;
}

void CTControllor::UseFun()
{
	CalLishudu(E);
	CalLishudu(detaE);
	WriteRules();
	CalculateW();
}

float CTControllor::GetMTW(Variable &v)
{
	int i;
	int vi;
	float miw[9];

	for(i=0;i<=9;i++)miw[i]=0;

	for(i=0;i<=8;i++)
		if(using_rule[i]==1)
		{
			if(i<=4)vi=4-i;
			else if((i>=5)&&(i<=6))vi=9-i;
			else if((i>=7)&&(i<=8))vi=8-i;
			v.lishudu[vi]=(float)((2-fabs(v.value-(vi*2-4)))/2.0);
			miw[i]=Min(using_rule_weight[i],v.lishudu[vi]);
		}

	float max=miw[0];
	for(i=0;i<=8;i++)
		if(miw[i]>max)max=miw[i];

	return max;
}

void CTControllor::MainContrllor()
{
	cnt--;
	if(cnt<0)
	{
		UseFun();
		cnt=1;
	}

	detaE.value+=w0*enhance;
	E.value+=detaE.value;
	T+=detaE.value;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -