Table of Contents

Modificación de CRRCSIM para agregar la funcionalidad de modelado de ráfagas de viento II

Elaborado por: Jose Pablo Espinoza Barahona

Introducción

Este trabajo es una continuación del proyecto anterior; donde se hará uso de los elementos encontrados para lograr el objetivo principal: otorgar la funcionalidad de tener ráfagas aleatorias. Se verán conceptos sobre la elaboración y modificación de un paquete debian(tomar un paquete existente, re-bulding it, aplicar cambios, preparar cambios para enviarlos como un parche.), particularidades de las ráfagas de viento y abstracción de su comportamiento para su traspaso a código.

Objetivos

Objetivo General

Dotar al programa “crrcsim” la funcionalidad de modelado de ráfagas de viento.

Objetivos Específicos

  1. Definir y estudiar un algoritmo que abstraiga la naturaleza de una ráfaga de viento y su influencia el ambiente.
  2. Construir un modulo de yarp que implemente el modelo de viento para ser enviado mediante yarp a crrcsim.
  3. Realizar la modificación a crrcsim para que acepte la velocidad del viento desde un puerto yarp.
  4. Realizar pruebas de funcionamiento.

Preparación del equipo

1. build-essential, fakeroot, devscripts

  sudo apt-get install build-essential fakeroot devscripts
  

2. configurar apt

  sudo nano /etc/apt/sources.list
  

Añadir:

  deb-src http://http.us.debian.org/debian unstable main

Actualizar:

  sudo apt-get update
  

3. crear un directorio de trabajo. Una vez añadido la url podemos descargar la fuente(source). Es una buena práctica tener una carpeta exclusiva para trabajar que contenga la fuente del software.

  
      mkdir -p src/debian/
      

4. Debemos instalar el paquete antes y que sea la última versión debido a que necesitamos resolver depedencias antes de instalar la modificación.

  sudo apt-get crrcsim

5. descargamos el fuente

  cd ~/src/debian
  apt-get source crrcsim
  

Ahora tenemos 3 archivos (.dsc, .debian.tar.gz, .orig.tar.gz) y un directorio “crrcsim-0.9.12” dentro de este se encuentra la fuente desempaquetada. Dentro de ese directorio encontramos un subdirectorio “debian”. Todo paquete de debian (o derivado de este) incluye un directorio “debian”, este contiene información relacionada con el paquete de debian. Todo lo que se encuentra afuera de ese directorio es “upstream code”, i.e. el codigo original que fue liberado por el desarrollador original.

Del contenido del directorio debian nos interesa entender dos archivos:

  Archivo "rules": ejecutable que va ser llamado para construir el paquete.
  Directorio "patches": parches aplicados por el encargado del paquete.

6. obteniendo las dependencias de build.

Para construir satisfactoriamente la mayoría de los programas, necesitamos solventar ciertas dependencias. generalmente son paquetes que tienen el sufijo “-dev”, pero tambien pueden ser otros como “automake” o “gcc”; “apt” nos ofrece la siguiente forma para instalar todas las dependencias necesarias.

  sudo apt-get build-dep crrcsim

7. Build sin cambios.

  Con esto garantizamos que se construyo e instalo correctamente el paquete.
  
  cd ~/src/debian/crrcsim-0.9.12/
  debuild -b -uc -us
  
  Crea un ".deb" (binary only package) y previene que se firme el paquete. Lo que ejecuta es lo que dicte el archivo "rules".

8. instalación

  sudo dpkg -i ../crrcsim-0.9.12_<your arch>.deb

donde:

  <your arch> = [i386|amd64]
  

8. ejecutarlo

  crrcsim

Debería de funcionar.

9. Pre-requisitos “quilt”. Estas son Herramientas para trabajar con parches de paquetes. Los parches contienen código que debe ser inyectado para solucionar bugs y mantener una documentación de los cambios realizados.

  
  sudo apt-get install packaging-dev
  vi ~/.quiltrc
  insertamos esto:
  #-----
  QUILT_PATCHES=debian/patches
  QUILT_NO_DIFF_INDEX=1
  QUILT_NO_DIFF_TIMESTAMPS=1
  QUILT_REFRESH_ARGS="-p ab"
  QUILT_DIFF_ARGS="--color=auto" # If you want some color when using `quilt diff`.
  #-----

10. Crear un parche

  existe directorio debian y el archivo rules.
  cd ~/src/debian/crrcsim-0.9.12/
  quilt push -a
  quilt new <NOMBRE>
  add <path a archivo a modificar>
  ... MOFICAR FUENTE ...
  quilt refresh <NOMBRE>
  quilt pop -a
  

11. Editar un parche

  cd ~/src/debian/crrcsim-0.9.12/
  quilt push <NOMBRE>
  ... MOFICAR FUENTE ...
  quilt refresh <NOMBRE>
  quilt pop -a

Con esto ya debemos de ser capaces de realizar cambios en el código fuente de crrcsim y solventamos cualquier tipo de dependencia requerida.

Viento

El objetivo es tener ráfagas aleatorias, pero debemos de dar nuestra definición de aleatorio para la funcionalidad que deseamos obtener. Vamos a definir ráfaga aleatórea como: una graduación variable de los parametros de velocidad y dirección que permitan al piloto enfrentarse ante situaciones que obliguen una estabilización del vehículo.

Teniendo esto en cuenta tenemos que procedemos a realizar una comparación de los parametros de velocidad para comprender su magnitud. Usamos el siguiente cuadro.

km/hr ft/s descripción
1 0.9 calmado
1-5 0.9-4.5 viento ligero
6-11 5.4-10 brisa suave
19-38 17.3-34.6 brisa muy fuerte
39-49 35.5-44.6 viento fuerte
117 106.6 huracán

fuente:http://www.windows2universe.org/earth/Atmosphere/wind_speeds.html

Teniendo la idea de la magnitud de los valores con los que contamos, se considera que el rango que se debe de manejar no debería de sobrepasar los 20 ft/s.

Ciclo de Juego

De la parte uno del proyecto identificamos el ciclo de juego y se concluyó que nuestro código debe ser inyectado en el ciclo y antes de que de invoque el método draw(). Por lo tanto lo que queremos desarrollar es el siguiente esquema.

Haciendo uso de módulos de yarp para escritura y lectura se busca brindar los datos de: windBase: Viento base el cual es tomado como referencia para oscilar entre los límites superior e inferior. dirBase: Direccion base el cual es tomado como eje central de los cambios. limInf: límite inferior, usado por windBase. limSup: límite superior, usado por windBase. Implementado de la forma presentado en el esquema:

Debido a problemas con la configuración de yarp este objetivo no podrá ser cumplido por el momento. Por lo tanto para lograr un comportamiento similar se hará uso de un patrón de grafos donde los nodos contienen una velocidad base y sus enlaces indican la probabilidad de pasar al otro nodo ,i.e. cambiar de velocidad. Representado en el siguiente diagrama:

Tomaremos las velocidades base del cuadro[1] como {1,10,20} por lo que vamos a tener 3 niveles de intensidad. Se usará un arreglo con una incidencia mayor de ciertos vientos base para aumentar la probabilidad de aparación. Del gráfico C podemos hacer la implementación en código

version 0.0.2 softcoded not cleaned.

void rafagas(){
    srand(time(NULL));
    //calculo del porcentaje
    percentWin = rand() % 100 + 1;
    if(percentWin+percentBooster > 95){//cambio de banda
        //escoger banda
        indexWin = rand() % 6 + 1;
        cfg->wind->setVelocity(range[indexWin]);
        if(indexWin == 6){//esto es para evitar que pase mucho tiempo en high
            percentBooster=40;
        }
    }else if(percentWin > 40){//aumenta o disminuye
        conditionalWin = rand() % 8 + 1;
        if(conditionalWin+tendencyWin>4){//aumenta
            cfg->wind->setVelocity(cfg->wind->getVelocity()+1);
            tendencyWin = 2;
        }else{//disminuye
            cfg->wind->setVelocity(cfg->wind->getVelocity()-1);
            tendencyWin = -2;
        }//END Conditional +/-
        percentBooster=0;
    }//END conditional
}//END rafagas

Una muestra de los valores obtenidos durante ejecución (x,y):(iteración, velocidad)

De forma similar hacemos un diagrama de grafos para la dirección del viento. El cual va tener como nodos los puntos cardinales {0,90,180,270} y sus enlaces son las probabilidad de que se cambie. Representado en el siguiente diagrama:

Del gráfico podemos hacer la implementación en código:

version 0.0.2 softcoded not cleaned.

void cambioDireccion(int pchange){
    int newDirection = cfg->wind->getDirection() + pchange;
    if(newDirection >= 360){
        newDirection = newDirection - 360;
    }else if(newDirection <= 0){
        newDirection = 360 - newDirection;
    }
    cfg->wind->setDirection(newDirection,cfg);
}

void direccion(){
    //calculo del porcentaje
     percentDir = rand() % 100 + 1;
     conditionalDir = rand() % 8 + 1;
     if(percentDir > 97){//cambio grande corto
        cfg->wind->setDirection(rosa[indexDir],cfg);
        indexDir = rand() % 5 + 1;
     }else if(percentDir > 85){//oscilacion alta
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(alto[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-alto[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }else if(percentDir > 55){//oscilacion media
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(medio[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-medio[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }else if(percentDir > 40){//oscilacion leve
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(bajo[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-bajo[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }//END condDiritional
}//END direccion

Implementación usando

  cd ~/src/debian/crrcsim-0.9.12/
  quilt push -a
  quilt new randomWind.diff

Ahora insertamos el codigo en ./src/crrc_main.cpp

linea 109

//*******MOD*****
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
//*****END-MOD***

linea 136

//*******MOD*****
int range [7] = {1, 1, 1, 1, 10, 10, 20}; //usado para aumentar incidencia de ciertos elementos
int rosa [5] = {0, 0, 90, 180, 270}; //{vacum, NORTH, EAST, SOUTH, WEST}
int alto [4] = {5, 6, 7, 8};
int medio [4] = {2, 3, 4, 5};
float bajo [4] = {0, 0.25, 0.50, 0.75};
int percentBooster, percentWin, indexWin, tendencyWin, conditionalWin, modCycle = 0;
int percentDir, indexDir, tendencyDir, conditionalDir = 0;
//*****END-MOD***

linea 518

//*******MOD***
void rafagas(){
    srand(time(NULL));
    //calculo del porcentaje
    percentWin = rand() % 100 + 1;
    if(percentWin+percentBooster > 95){//cambio de banda
        //escoger banda
        indexWin = rand() % 6 + 1;
        cfg->wind->setVelocity(range[indexWin]);
        if(indexWin == 6){//esto es para evitar que pase mucho tiempo en high
            percentBooster=40;
        }
    }else if(percentWin > 40){//aumenta o disminuye
        conditionalWin = rand() % 8 + 1;
        if(conditionalWin+tendencyWin>4){//aumenta
            cfg->wind->setVelocity(cfg->wind->getVelocity()+1);
            tendencyWin = 2;
        }else{//disminuye
            cfg->wind->setVelocity(cfg->wind->getVelocity()-1);
            tendencyWin = -2;
        }//END Conditional +/-
        percentBooster=0;
    }//END conditional
}//END rafagas

void cambioDireccion(int pchange){
    int newDirection = cfg->wind->getDirection() + pchange;
    if(newDirection >= 360){
        newDirection = newDirection - 360;
    }else if(newDirection <= 0){
        newDirection = 360 - newDirection;
    }
    cfg->wind->setDirection(newDirection,cfg);
}

void direccion(){
    //calculo del porcentaje
     percentDir = rand() % 100 + 1;
     conditionalDir = rand() % 8 + 1;
     if(percentDir > 97){//cambio grande corto
        cfg->wind->setDirection(rosa[indexDir],cfg);
        indexDir = rand() % 5 + 1;
     }else if(percentDir > 85){//oscilacion alta
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(alto[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-alto[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }else if(percentDir > 55){//oscilacion media
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(medio[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-medio[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }else if(percentDir > 40){//oscilacion leve
        indexDir = rand() % 4 + 1;
        if(conditionalDir+tendencyDir>4){//aumenta
            cambioDireccion(bajo[indexDir]);
            tendencyDir = 2;
        }else{//disminuye
            cambioDireccion(-bajo[indexDir]);
            tendencyDir = -2;
        }//END condDiritional +/-
     }//END condDiritional
}//END direccion
//*****END-MOD***

linea 954

//*******MOD*****
  modCycle++;
  if(modCycle==60){
    rafagas();
    direccion();
    modCycle=0;
    printf("MODIFICACION REALIZADA\n");
    printf("   VIENTO: %f \n", cfg->wind->getVelocity());
    printf("DIRECCION: %f \n", cfg->wind->getDirection());
  }//end if mod
//*****END-MOD***

Luego de haber insertado

  quilt refresh randomWind.diff
  quilt pop -a
  debuild -b -uc -us
  sudo dpkg -i ../crrcsim-0.9.12_<your arch>.deb

donde: <your arch> = [i386|amd64]

ejecutamos desde consola

  crrcsim
  

Imagenes:

Conclusiones

El programa resiste cambios durante ejecución y no existen inconvenientes si se ingresa un valor no soportado por el dominio, por lo que deja la duda, ¿Por qué no se había implementado esta funcionalidad antes? Si todo lo que tenemos que hacer es jugar con dos variables entonces debió de haber sido implementado por los desarrolladores originales siendo esta una función que incluso en su README.txt se menciona que se quiere implementar.

Se deben de hacer más pruebas sobre la usabilidad del código inyectado ya que no ha sido probado aun con pilotos experimentados.

Apendices

Modulo simple Rx/Tx http://www.yarp.it/yarp_code_examples.html

Presentación: presentacionii.pdf

fuente de crrcsim de los repositorios de debian. crrcsim.tar.gz

paquete generado del proyecto: crrcsim_0.9.12-6.1_amd64.deb

Referencias

Lippman, S. , Lajoie, J. & Moo, B.E. August 16, 2012 C++ Premier, 5th Edition. Boston, Massachusetts : Addison-Wesley Professional.

Tolman, H. November 28, 1990. A third-generation model for wind waves on slowy varying, unsteady, and inhomogeneous depths and currents: Journal of physics oceanography, volume number(21), pp 782-797. Extracted from http://journals.ametsoc.org/doi/pdf/10.1175/1520-0485%281991%29021%3C0782%3AATGMFW%3E2.0.CO%3B2 https://wiki.debian.org/UsingQuilt https://wiki.debian.org/BuildingTutorial