Sistema Software
Software nodo terminalLa fusión sensorial complementaria implementada trata de proporcionar una fusión de la información obtenida por el sensor de distancia, el sensor de luz y el tiempo. Esta fusión trata de determinar la presencia de un peatón, un coche o nada. Para implementarla se ha hecho uso de un sistema difuso.
Las variables de entrada son:
- Luminosidad:
- Distancia :
- TiempoNoLuz
Solo existirá una variable de salida llamada estado que poseera los valores PEATON, COCHE o NADA
La base de reglas es:
A continuacion se muestra el código que implementa la fusion sensorial
#define NADA 0
#define PEATON 1
#define COCHE
int min_medida_luz = 8; //->valores de ejemplo
int max_medida_luz = 913; //->valores de ejemplo
int min_real_luz = 0; //->valores de ejemplo
int max_real_luz = 934; //->valores de ejemplo
int min_medida_distancia = 3; //->valores de ejemplo
int max_medida_distancia = 13; //->valores de ejemplo
int min_real_distancia = 3; //->valores de ejemplo
int max_real_distancia = 13; //->valores de ejemplo
int UMBRAL_LUZ=550;
double instante_no_luz;
double MAX_NO_LUZ = 4000;
///////////////////////////////////////////////////////////////////////////
//////////////////////VARIABLES SISTEMA DIFUSO/////////////////////////////
//////////////////////////////////////////////////////////////////////////
double x0K1[2];
double x1K1[2];
double x2K1[2];
double x3K1[2];
double x0K2[2];
double x1K2[2];
double x2K2[2];
double x3K2[2];
double x0K3[2];
double x1K3[2];
double x2K3[2];
double x3K3[2];
int K1[8];
int K2[8];
int K3[8];
int C1[8];
double H[8];
//FUNCION QUE MAPEA LA VARIABLE DE ENTRADA CON EL RANGO DE ENTRADA EN EL RANGO DE SALIDA
double mapdouble(double x, double in_min, double in_max, double out_min, double out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
//FUNCION QUE EJECUTA EL SISTEMA DIFUSO
int fuzzysystem(double E1, double E2, double E3) {
double corte;
for (int i = 0; i<8; i++) {
H[i] = 2147483648; //{IniciKlizo K un m¡nimo muy grKnde}
corte = 0;
if ((E1 >= x0K1[K1[i]]) && (E1<x1K1[K1[i]])) { corte = (E1 - x0K1[K1[i]]) / (x1K1[K1[i]] - x0K1[K1[i]]); }
if ((E1 >= x1K1[K1[i]]) && (E1<x2K1[K1[i]])) { corte = 1; }
if ((E1 >= x2K1[K1[i]]) && (E1<=x3K1[K1[i]])) { corte = (E1 - x3K1[K1[i]]) / (x2K1[K1[i]] - x3K1[K1[i]]); }
if (corte<H[i]) { H[i] = corte; }// {M¡nimo de los Kntecedentes hKstK KhorK}
corte = 0;
if ((E2 >= x0K2[K2[i]]) && (E2<x1K2[K2[i]])) { corte = (E2 - x0K2[K2[i]]) / (x1K2[K2[i]] - x0K2[K2[i]]); }
if ((E2 >= x1K2[K2[i]]) && (E2<x2K2[K2[i]])) { corte = 1; }
if ((E2 >= x2K2[K2[i]]) && (E2<=x3K2[K2[i]])) { corte = (E2 - x3K2[K2[i]]) / (x2K2[K2[i]] - x3K2[K2[i]]); }
if (corte<H[i]) { H[i] = corte; } //{M¡nimo de los Kntecedentes hKstK KhorK}
corte = 0;
if ((E3 >= x0K3[K3[i]]) && (E3<x1K3[K3[i]])) { corte = (E3 - x0K3[K3[i]]) / (x1K3[K3[i]] - x0K3[K3[i]]); }
if ((E3 >= x1K3[K3[i]]) && (E3<x2K3[K3[i]])) { corte = 1; }
if ((E3 >= x2K3[K3[i]]) && (E3<=x3K3[K3[i]])) { corte = (E3 - x3K3[K3[i]]) / (x2K3[K3[i]] - x3K3[K3[i]]); }
if (corte<H[i]) { H[i] = corte; }// {M¡nimo de los Kntecedentes hKstK KhorK}
}
double sumHM[3];
for (int i = 0; i<3; i++) {
sumHM[i] = 0;
}
for (int i = 0; i<8; i++) {
sumHM[C1[i]] = sumHM[C1[i]] + H[i];
}
int resultado = NADA;
double value = 0;
for (int i = 0; i < 3; i++) {
if (sumHM[i] > value) {
resultado = i;
value = sumHM[i];
}
}
return resultado;
}
//FUNCION QUE RESTRINGE EL RANGO DE UNA VARIABLE
double constraintdouble(double x, double in_min, double in_max){
if(x<in_min){
return in_min;
}else if(x>in_max){
return in_max;
}else{
return x;
}
}
//FUNCION DE INICIALIZACION PRINCIPAL
void setup() {
Serial.begin(115200); delay(100);
///////////////////////////////////////////////////////////////////////////
///////////////INICIALIZACION BASICA SISTEMA DIFUSO////////////////////////
//////////////////////////////////////////////////////////////////////////
x0K1[0] = 0; x1K1[0] = 0; x2K1[0] = 0.3333; x3K1[0] = 0.6667;
x0K1[1] = 0.3333; x1K1[1] = 0.6667; x2K1[1] = 1; x3K1[1] = 1;
x0K2[0] = 0; x1K2[0] = 0; x2K2[0] = 0.3333; x3K2[0] = 0.6667;
x0K2[1] = 0.3333; x1K2[1] = 0.6667; x2K2[1] = 1; x3K2[1] = 1;
x0K3[0] = 0; x1K3[0] = 0; x2K3[0] = 0.3333; x3K3[0] = 0.6667;
x0K3[1] = 0.3333; x1K3[1] = 0.6667; x2K3[1] = 1; x3K3[1] = 1;
K1[0] = 0; K1[1] = 1; K1[2] = 1; K1[3] = 0; K1[4] = 0; K1[5] = 0; K1[6] = 1; K1[7] = 1;
K2[0] = 0; K2[1] = 0; K2[2] = 1; K2[3] = 1; K2[4] = 1; K2[5] = 0; K2[6] = 0; K2[7] = 1;
K3[0] = 0; K3[1] = 0; K3[2] = 0; K3[3] = 0; K3[4] = 1; K3[5] = 1; K3[6] = 1; K3[7] = 1;
C1[0] = 2; C1[1] = 2; C1[2] = 2; C1[3] = 2; C1[4] = 2; C1[5] = 2; C1[6] = 1; C1[7] = 0;
min_medida_luz = medida_luz[0];
max_medida_luz = medida_luz[n_lookup_luz - 1];
min_real_luz = real_luz[0];
max_real_luz = real_luz[n_lookup_luz - 1];
UMBRAL_LUZ = (real_luz[1]+real_luz[2])/2;
instante_no_luz=millis();
//Configuracion etiquetas Fuzzy
x2K3[0] = mapdouble(real_luz[1],min_real_luz,max_real_luz,0,1);
x3K3[0] = mapdouble(real_luz[2],min_real_luz,max_real_luz,0,1);
x0K3[1] = mapdouble(real_luz[1],min_real_luz,max_real_luz,0,1);
x1K3[1] = mapdouble(real_luz[2],min_real_luz,max_real_luz,0,1);
}
//FUNCION BUCLE PRINCIPAL
void loop() {
////////////OBTENCION TIEMPO (0,1)////////////
if(out_luz<UMBRAL_LUZ){
instante_no_luz=millis();
}
double tiempo_no_luz=millis()-instante_no_luz;
if(tiempo_no_luz>MAX_NO_LUZ){
tiempo_no_luz=MAX_NO_LUZ;
}
//////////////PRE-CALCULOS FUZZY//////////////
double E1=mapdouble(tiempo_no_luz,0,MAX_NO_LUZ,0,1);
double E2=mapdouble(out_distancia,min_real_distancia,max_real_distancia,0,1);
double E3=mapdouble(out_luz,min_real_luz,max_real_luz,0,1);
///////////////SISTEMA FUZZY///////////////
// Serial.println(out_distancia);
int ESTADO=fuzzysystem(E1,E2,E3);
}
<<Anterior
No hay comentarios:
Publicar un comentario