sábado, 25 de febrero de 2017

Implementación de un Paso de Peatones con Sensores Inteligentes de Bajo Coste. Parte IV

Sistema Software

Software nodo terminal

La 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