Смекни!
smekni.com

Применение нечёткой логики на примере простой модели зарядного устройства для батарей (стр. 2 из 2)

tmpr=new float[3000];

volt = new float[3000];

mode = new int[3000];

for (i = 0; i < 3000; i++)

{

tmpr[i] = n.temperature;

volt[i] = n.voltage;

mode[i] = n.ChargeMode;

n.simulate();

n.timer = n.chargeControl(n.timer);

n.timer += (float)1.0;

s = "Main: " + i + " volt=" + n.voltage + " temper=" + n.temperature + " Mode=" + n.ChargeMode;

listBox1.Items.Add(s);

}

Console.ReadLine();

}

Программа вызывает функцию, которая эмулирует процесс собственно зарядки и разрядки батареи, а затем позволяет функции управления зарядкой установить нужный режим для зарядного устройства.


Вывод

В результате работы над проектом была создана модель работы зарядного устройства для батареи. Программа описывает выбор режима зарядки, исходя из параметров напряжения и температуры, а так же выводит графики изменения этих параметров.

ПрограмманаписананаMicrosoft Visual C# 2010 Express Edition. Отладка производилась в операционной системе MS Windows ХР.

На этом примере было рассмотрено применение операторов нечёткой логики. Эти операторы используется в самых разнообразных приложениях. Наиболее очевидная область их применения - системы управления, которым нечеткая логика уже обеспечила коммерческий успех. Нечеткая логика используется в устройстве видеокамер и фотоаппаратов с автофокусом, системах смешивания цемента, автомобильных системах (например, системах АБС) и даже системах, основанных на правилах. Наверное, самые полезные области применения все еще остаются неизвестными. Само название «нечеткая логика» не внушает особого доверия, хотя давно известно, что это надежный метод. Как и многие другие методики ИИ, нечеткая логика в настоящее время все чаще используется в устройствах повседневного применения, где она больше не ассоциируется с искусственным интеллектом.


Приложение 1

зарядное устройство батарея нечёткая логика

Код программы:

classNapryagenie

{

int TRICKLE_CHARGE; //charge=заряд 0

int FAST_CHARGE; // 1

public int ChargeMode;

int MAX_LOADS; // 5

public float voltage, temperature;

public float timer;

float[] load;

int curLoad;

float lo;

//constructor

public Napryagenie() {

TRICKLE_CHARGE = 0;

FAST_CHARGE = 1;

ChargeMode = TRICKLE_CHARGE;

MAX_LOADS=5;

load = new float[MAX_LOADS];

curLoad = 0;

temperature = (float)12.0;

timer = (float)0.0;

voltage = (float)20.0;

load[0]=(float)0.02;

load[1]=(float)0.04;

load[2]=(float)0.06;

load[3]=(float)0.08;

load[4] = (float)0.1;

}

int t;

public float charge( int t )

{

float result;

result = (float)Math.Sin((double)((float)t/(float)100.0));

if (result < 0.0) result = (float)0.0;

return result;

}

public int simulate()

{

//extern int chargeMode;

t=0;

// First, update the loading if necessary

if (getSRand() < 0.02) {

curLoad = getRand( MAX_LOADS );

}

// Affect the current battery voltage given the load

voltage -= load[curLoad];

// Next, update the battery voltage given input charge

if (ChargeMode == FAST_CHARGE) {

voltage += (charge(t) * (float)Math.Sqrt(timer));

} else {

voltage += ((charge(t) * (float)Math.Sqrt(timer)) / (float)10.0 );

}

if (voltage < 0.0) voltage = (float)0.0;

else if (voltage > 35.0) voltage = (float)35.0;

// Update the temperature

if (ChargeMode == FAST_CHARGE) {

if (voltage > 25) {

temperature += ((load[curLoad] * ((float)Math.Sqrt(timer)/(float)25.0)) * (float)10.0);

} else if (voltage > 15) {

temperature += ((load[curLoad] * ((float)Math.Sqrt(timer) / (float)20.0)) * (float)10.0);

} else {

temperature += ((load[curLoad] * ((float)Math.Sqrt(timer) / (float)15.0)) *(float) 10.0);

}

} else {

if (temperature > 20.0) {

temperature -= ((load[curLoad] * ((float)Math.Sqrt(timer) / (float)20.0)) * (float)10.0);

} else {

temperature -= ((load[curLoad] * ((float)Math.Sqrt(timer) /(float) 100.0)) * (float)10.0);

}

}

if (temperature < 0.0) temperature = (float)0.0;

else if (temperature > 40.0) temperature = (float)40.0;

t++;

return 0;

}

public float getSRand() {

float c;

Random r=new Random();

uint RAND_MAX=0x7FFFFU;

c=((float)r.Next()/(float)RAND_MAX);

return c;

}

public int getRand(float x) { return (int)((x) * getSRand()); }

public float MAX(float a,float b) { return (a>b) ? a : b; }

public float MIN(float a, float b) { return (a < b) ? a : b; }

public float fuzzyAnd (float a, float b)

{

if (a < 0.0) return 0;

if (a > 1.0) return 0;

if (b < 0.0) return 0;

if (b > 1.0) return 0;

return MAX(a, b);

}

public float fuzzyOr(float a, float b)

{

if (a < 0.0) return 0;

if (a > 0.0) return 0;

if (a < 0.0) return 0;

if (a > 0.0) return 0;

return MIN(a, b);

}

public float fuzzyNot(float a)

{

if (a < 0.0) return 0;

if (a > 1.0) return 0;

float c = (float)1.0 - a;

return c;

}

//нормализация

public int normalize(float inn)

{

if (inn >= 0.5) return 1;

else return 0;

}

//функцияпринадлежностиввидетреугольника

public float spikeProfile (float value, float lo, float high)

{

float peak;

value += (-lo);

if ((lo < 0) && (high < 0))

{

high = -(high - lo);

}

else if ((lo < 0) && (high > 0))

{

high += -lo;

}

else if ((lo > 0) && (high > 0))

{

high -= lo;

}

peak = (float)(high / 2.0);

lo =(float)0.0;

if (value < peak)

{

return (value / peak);

}

else if (value > peak)

{

return ((high - value) / peak);

}

return (float)1.0;

}

// функцияпринадлежностиввидетрапеции

public float plateauProfile(float value, float lo, float lo_plat,

float hi_plat, float hi)

{

float upslope;

float downslope;

value += (-lo);

if (lo < 0.0)

{

lo_plat += -lo; hi_plat += -lo;

hi += -lo; lo = 0;

}

else

{

lo_plat -= lo; hi_plat -= lo;

hi -= lo; lo = 0;

}

upslope =(float) (1.0 / (lo_plat - lo));

downslope = (float)(1.0 / (hi - hi_plat));

if (value < lo) return (float)0.0;

else if (value > hi) return (float)0.0;

else if ((value >= lo_plat) && (value <= hi_plat)) return (float)1.0;

else if (value < lo_plat) return ((value - lo) * upslope);

else if (value > hi_plat) return ((hi - value) * downslope);

return (float)0.0;

}

// функция принадлежностми для высокой температуры

public float m_temp_hot(float temp)

{

const float lo = (float)35.0;

const float lo_plat = (float)45.0;

const float hi_plat = (float)45.0;

const float hi = (float)45.0;

if (temp < lo) return (float)0.0;

if (temp > hi) return (float)1.0;

return plateauProfile(temp, lo, lo_plat, hi_plat, hi);

}

// функция принадлежностми для средней температуры

public float m_temp_warm(float temp)

{

const float lo = (float)15.0;

const float lo_plat = (float)25.0;

const float hi_plat = (float)35.0;

const float hi = (float)45.0;

if ((temp < lo) || (temp > hi)) return (float)0.0;

return plateauProfile(temp, lo, lo_plat, hi_plat, hi);

}

// функция принадлежностми для низкой температуры

public float m_temp_cold(float temp)

{

const float lo = (float)15.0;

const float lo_plat = (float)15.0;

const float hi_plat = (float)15.0;

const float hi = (float)25.0;

if (temp < lo) return (float)1.0;

if (temp > hi) return (float)0.0;

return plateauProfile(temp, lo, lo_plat, hi_plat, hi);

}

//функцияпринадлежностидлянизкогонааряжения

public float m_voltage_low(float voltage)

{

const float lo = (float)5.0;

const float lo_plat = (float)5.0;

const float hi_plat = (float)5.0;

const float hi = (float)10.0;

if (voltage < lo) return (float)1.0;

if (voltage > hi) return (float)0.0;

return plateauProfile(voltage, lo, lo_plat, hi_plat, hi);

}

//функция принадлежности для среднего напряжения

public float m_voltage_medium(float voltage)

{

const float lo = (float)5.0;

const float lo_plat = (float)10.0;

const float hi_plat = (float)20.0;

const float hi = (float)25.0;

if (voltage < lo) return (float)0.0;

if (voltage > hi) return (float)0.0;

return plateauProfile(voltage, lo, lo_plat, hi_plat, hi);

}

//функцияпринадлежностидлявысокогонааряжения

public float m_voltage_high(float voltage)

{

const float lo = (float)25.0;

const float lo_plat = (float)30.0;

const float hi_plat = (float)30.0;

const float hi = (float)30.0;

if (voltage < lo) return (float)0.0;

if (voltage > hi) return (float)1.0;

return plateauProfile(voltage, lo, lo_plat, hi_plat, hi);

}

public float chargeControl(float timer )

{

int i = 0;

if ( (i++ % 10) == 0 ) {

if ( normalize(m_voltage_high(voltage)) ==1) {

ChargeMode = TRICKLE_CHARGE;

timer = (float)0.0;

} else if (normalize( m_temp_hot(temperature))==1) {

ChargeMode = TRICKLE_CHARGE;

timer = (float)0.0;

} else if (normalize(

fuzzyAnd(fuzzyNot(m_voltage_high(voltage)),

fuzzyNot(m_temp_hot(temperature))))==1) {

ChargeMode = FAST_CHARGE;

timer = (float)0.0;

}

}

return timer;

}

}//class

}

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

}

Graphics g;

float [] tmpr;

float [] volt;

int [] mode;

private void button1_Click(object sender, EventArgs e)

{

int i;

Napryagenie n = new Napryagenie();

string s="";

tmpr=new float[3000];

volt = new float[3000];

mode = new int[3000];

for (i = 0; i < 3000; i++)

{

tmpr[i] = n.temperature;

volt[i] = n.voltage;

mode[i] = n.ChargeMode;

n.simulate();

n.timer = n.chargeControl(n.timer);

n.timer += (float)1.0;

s = "Main: " + i + " volt=" + n.voltage + " temper=" + n.temperature + " Mode=" + n.ChargeMode;

listBox1.Items.Add(s);

}

Console.ReadLine();

}

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)

{

}

class graphic

{

int xw, yw;

Graphics gr;

int mx, my;

int minx,maxx,miny,maxy;

float shx,shy;

public graphic(Graphics g, int mx1, int my1, int minx1, int maxx1, int miny1, int maxy1)

{

gr = g;

mx = mx1; my = my1;

minx = minx1; maxx = maxx1; miny = miny1; maxy = maxy1;

xw = maxx1 - minx1;

yw = maxy1 - miny1;

}

public void drawaxes()

{

int i;

int lrsk = 5;

float x = 0, y;

shx = (float)mx / (float)xw;

shy = (float)my / (float)yw;

for (i = 0; i < xw; i++)

{

x = (float)i * shx;

if (i % 50 == 0)

gr.DrawLine(new Pen(Color.Black, 1), x, my, x, my - lrsk);

}

for (i = 0; i < yw; i++)

{

y = i * shy;

if (i % 1 == 0)

gr.DrawLine(new Pen(Color.Black, 1), 0, y, lrsk, y);

}

}//drawaxes

public void drawgr(Color clr,float [] tmp)

{

float x,y;

int i;

int k = 0;

for (i = maxx - xw; i < maxx; i++)

{

x = k++ * shx;

y = tmp[i] * shy;

gr.DrawEllipse(new Pen(clr, 1), x, my - y, 1, 1);

}

}//drawgr

}//graphic

private void button2_Click(object sender, EventArgs e)

{

g = panel1.CreateGraphics();

graphic gra=new graphic(g,panel1.Width,panel1.Height,0,3000,0,50);

gra.drawaxes();

gra.drawgr(Color.Green, tmpr);

gra.drawgr(Color.Red, volt);

}

}


Приложение 2