Diferencia entre revisiones de «Butialo: Ejemplo 7 - Robot que no se caiga de la mesa con eventos, utilizando un sensor de grises y uno de distancia»

De Proyecto Butiá
Saltar a: navegación, buscar
(Solución)
Línea 14: Línea 14:
 
'''Descripción'''
 
'''Descripción'''
  
Como fue explicado en ejemplos anteriores, el sensor de escala de grises (en este caso, se conectó el sensor al puerto 2, por eso su nombre es “Grey_2”) debe ser calibrado previamente a la ejecución del programa a desarrollar para poder obtener los respectivos valores límites a partir del cual definimos que el robot se encuentra sobre la mesa.
+
Obtenemos los valores de la variable COLOR_MESA, DISTANCIA_MESA, MIN_TIEMPO_RETROCESO, MAX_TIEMPO_RETROCESO, MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO de la misma forma que lo hicimos en el Ejemplo 6.
 +
Como podemos apreciar en el ejemplo anterior, el robot tiene un comportamiento que claramente se adapta al paradigma reactivo. Esto es, SENSAR - ACTUAR.
 +
Cambiará su estado dependiendo de dos condiciones que le indica si el color sensado se corresponde con el de la mesa (COLOR_MESA)o si la distncia sensada es distinta a la distancia que que hay entre el sensor y la mesa (DISTANCIA_MESA) .
 +
Distinguimos entonces tres estados posibles según (ADELANTE_FUERA_MESA, ATRAS_FUERA_MESA, EN_LA_MESA). Si se cumple la condiciones ADELANTE_FUERA_MESA o ATRAS_FUERA_MESA, el robot deberá retroceder o avanzar  un tiempo aleatorio definido entre el rango MIN_TIEMPO_RETROCESO y MAX_TIEMPO_RETROCESO y luego girar de forma aleatoria también por un tiempo entre el rango MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO. En caso contrario, el robot deberá desplazarse en la mesa.
 +
Finalmente se organiza la estructura de la solución en diferentes funciones de forma de modularizar y distinguir fácilmente las acciones. El programa principal quedaría de la siguiente forma:
  
Calculando el valor medio, obtuvimos el valor de la variable COLOR_MESA (55000 para las pruebas realizadas).
 
Determinamos entonces que si el valor arrojado por el sensor es menor a 55000, el robot puede continuar avanzando sin peligro de caer de la mesa, en caso contrario se deberá evitar la caída.
 
 
Además usaremos un sensor de distancia, el cual debe ser calibrado previamente, como explicamos en el ejemplo anterior. De esta forma obtenemos el valor de la variable DISTANCIA_MESA que refiera a la distancia a partir de la cual el robot detecta la presentacia de la mesa, y la relación con respecto a esta con lo cual el robot detecta que esta por caerse de le mesa, entonces deberá evitar la caida .
 
 
 
El robot deberá desplazarse por la mesa, de forma aleatoria para adelante o para atras, cuando este detecte que esta por caerse de la mesa, deberá avanzar o retroceder un tiempo determinado, dependiendo de con cual de los sensore lo detecte. Dicho valor deberá ser calibrado en las variables MIN_TIEMPO_RETROCESO y MAX_TIEMPO_RETROCESO de forma de contemplar que no se caiga de la mesa en caso de que el tiempo sea muy grande y tratando de volver siempre al centro de la misma, que es su estado inicial. De la misma forma, se calibrará los valores de MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO, considerando aquí los posibles valores entre 1° y 90° aproximadamente.
 
 
Una vez calibrado los sensores y obtenidos los respectivos valores de tiempo máximo y mínimo de giro y retroceso, se organiza la estructura de la solución en diferentes funciones de forma de modularizar y distinguir fácilmente las acciones. El programa principal quedaría de la siguiente forma:
 
  
 
* '''programa principal'''
 
* '''programa principal'''
Línea 53: Línea 48:
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
local function puedo_avanzar()
+
local function puedo_seguir()
local ret
+
 
   if Grey_2.getValue() < COLOR_MESA and Distanc_6.getValue() >= DISTANCIA_MESA then
+
   if Grey_2.getValue() > COLOR_MESA then
    ret = true
+
    --retroceder
 +
    ret = ADELANTE_FUERA_MESA
 
   else
 
   else
     ret = false
+
     if Distanc_6.getValue() < DISTANCIA_MESA then
 +
      --avanzar
 +
      ret = ATRAS_FUERA_MESA
 +
    else
 +
      --puedo seguir
 +
      ret = EN_LA_MESA
 +
    end
 
   end
 
   end
    if(not ret) then
+
  return ret  
        if(Grey_2.getValue() > COLOR_MESA ) then
+
 
          --se esta por caer desde la parte de adelante
+
          debe_avanzar = false
+
        else
+
          debe_avanzar = true
+
        end
+
    end   
+
return ret
+
 
end
 
end
end</syntaxhighlight>
+
</syntaxhighlight>
  
 
* '''chequear_giro_izquierda'''
 
* '''chequear_giro_izquierda'''

Revisión del 16:00 13 oct 2012

Descripción

Se desea implementar un programa que permita al robot Butiá poder desplazarse en una mesa sin caerse de la misma.

Implementamos lógica de nivel intermedio que permite que el robot Butiá pueda desplazarse en una mesa sin caerse de la misma. Inicialmente el robot sorteará hacia dónde desplazarse (avanzar o retroceder). En caso detectar un color distinto al de la mesa o bien detectar una distancia mayor a la separación con la mesa el robot deberá volver al centro de la misma para volver al estado inicial y luego comenzar otra vez.

Solución

Descripción

Obtenemos los valores de la variable COLOR_MESA, DISTANCIA_MESA, MIN_TIEMPO_RETROCESO, MAX_TIEMPO_RETROCESO, MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO de la misma forma que lo hicimos en el Ejemplo 6. Como podemos apreciar en el ejemplo anterior, el robot tiene un comportamiento que claramente se adapta al paradigma reactivo. Esto es, SENSAR - ACTUAR. Cambiará su estado dependiendo de dos condiciones que le indica si el color sensado se corresponde con el de la mesa (COLOR_MESA)o si la distncia sensada es distinta a la distancia que que hay entre el sensor y la mesa (DISTANCIA_MESA) . Distinguimos entonces tres estados posibles según (ADELANTE_FUERA_MESA, ATRAS_FUERA_MESA, EN_LA_MESA). Si se cumple la condiciones ADELANTE_FUERA_MESA o ATRAS_FUERA_MESA, el robot deberá retroceder o avanzar un tiempo aleatorio definido entre el rango MIN_TIEMPO_RETROCESO y MAX_TIEMPO_RETROCESO y luego girar de forma aleatoria también por un tiempo entre el rango MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO. En caso contrario, el robot deberá desplazarse en la mesa. Finalmente se organiza la estructura de la solución en diferentes funciones de forma de modularizar y distinguir fácilmente las acciones. El programa principal quedaría de la siguiente forma:


  • programa principal

Consiste en avanzar el robot hasta tanto no se cumpla alguna de las condiciones para cambiar de estado y en tal caso, se ejecutará la función asociada al evento correspondiente

events.add(puedo_seguir, '==', ADELANTE_FUERA_MESA, volver_inicio)
events.add(puedo_seguir, '==', ADELANTE_FUERA_MESA, volver_inicio)
events.add(puedo_seguir, '==', EN_MESA, moverse)

events.go()
  • chequear_avance_o_retrocedo

Retorna un valor booleano que indica si el robot debe avanzar. Para desplazarse de forma aleatoria, a adelante o atras, obtenemos un valor entre 0 y 1 con la función random de la bibloteca math. Si el valor randómico obtenido es mayor a 0.5 definimos que el desplazamiento hacia adelante, retornando True y en caso contrario deberá dsplazarse hacia atras retornando False.

local function chequear_avance_o_retrocedo()
    -- Avanzar = true, Retroceder = false
    local sentido = math.random (0, 1)
    return sentido > 0.5
end
  • puedo_avanzar

Retorna un valor booleano que indica si el robot se encuentra en peligro de caerse, según el valor obtenido por el sensor de grises y su comparación con la variable COLOR_MESA y el valor obtenido por el sensor de distancia y su comparación con la variable DISTANCIA_MESA. Define el valor de la variable debe_avanzar que será false si se detectó con el sensor de grises (sensor se encuentra en la parte de adelante del robot) peligro de caerse de la mesa, entonces este debera retroceder o en caso de que detectó peligro de caerse con el sensor de distancia (sensor se encuentra en la parte de atras del robot), este debe avanzar.

local function puedo_seguir()

   if Grey_2.getValue() > COLOR_MESA then
     --retroceder
     ret = ADELANTE_FUERA_MESA
   else
     if Distanc_6.getValue() < DISTANCIA_MESA then
       --avanzar
       ret = ATRAS_FUERA_MESA
     else
       --puedo seguir
       ret = EN_LA_MESA
     end
   end
   return ret   
	 
end
  • chequear_giro_izquierda

Retorna un valor booleano que indica si el robot debe girar hacia la izquierda. Para girar de forma aleatoria, a izquierda o derecha, obtenemos un valor entre 0 y 1 con la función random de la bibloteca math. Si el valor randómico obtenido es mayor a 0.5 definimos que el giro será hacia la izquierda, retornando True y en caso contrario deberá girar a la derecha retornando False.

local function chequear_giro_izquierda()
    local sentido = math.random (0, 1)
    return sentido > 0.5
end
  • girar_aleatorio

Nuevamente utilizamos la función random para obtener un número aleatorio entre MIN_TIEMPO_GIRO y MAX_TIEMPO_GIRO y así definir el tiempo durante el cual el robot estará girando. Luego chequeamos con la función chequear_giro_izquierda() si el giro será en sentido izquierdo o derecho, dependiendo de ese valor se procederá entonces a girar en ese sentido con una velocidad definida por la variable VELOCIDAD_GIRO.

local function girar_aleatorio()
    local tiempo_giro = math.random(MIN_TIEMPO_GIRO, MAX_TIEMPO_GIRO)
    local izquierda = chequear_giro_izquierda()
    if (izquierda) then
	Motors.setvel2mtr(0, VELOCIDAD_GIRO, 1, VELOCIDAD_GIRO)
    else
	Motors.setvel2mtr(1, VELOCIDAD_GIRO, 0, VELOCIDAD_GIRO)
    end
    util.wait(tiempo_giro)
end
  • volver_inicio

Esta función se encarga de que el robot vuelva la centro de la mesa, que es su posición inicial. Para esto utiliza la variable debe_avanzar que indica si el robot debe avanzar o retoceder dependiendo su posición actual.

local function volver_inicio()
   if (debe_avanzar) then
	    Motors.setvel2mtr(0, VELOCIDAD_RETROCESO, 0, VELOCIDAD_RETROCESO)
	else
	   Motors.setvel2mtr(1, VELOCIDAD_RETROCESO, 1, VELOCIDAD_RETROCESO) 
	end
	util.wait(TIEMPO_VOLVER_INICIO)
	girar_aleatorio()
end

Configuración

Se debe colocar un sensor de escala de grises lo más cercano a la mesa, pero siempre sin tocarla, en la parte de adelante del Butiá.

En nuestro caso encastramos piezas de forma de generar el soporte para adherir el sensor al Butiá, quedando dicho sensor a ras de la mesa.

Se muestra a continuación una imagen ilustrativa de la configuración del robot vista desde arriba.

Configuración

Video

Código