Butialo: Ejemplo 3 - Robot que no se caiga de la mesa sin eventos, utilizando un sensor de grises

De Proyecto Butiá
Saltar a: navegación, buscar

Descripción

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

El robot deberá avanzar mientras detecte un color semejante al de la mesa. En caso de detectar un color distinto al de la mesa, procederá a retroceder por un tiempo aleatorio para luego girar en un sentido aleatorio (izquierda o derecha), y así poder avanzar nuevamente.

Solució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.

Calculando el valor medio, obtuvimos el valor de la variable COLOR_MESA (43000 para las pruebas realizadas). Determinamos entonces que si el valor arrojado por el sensor es menor a 43000, el robot puede continuar avanzando sin peligro de caer de la mesa, en caso contrario se deberá evitar la caída.

El robot deberá retroceder en un tiempo aleatorio, 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. Para ello el robot se colocará en el centro de la mesa. 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 el sensor 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

Consiste en avanzar el robot hasta tanto no se encuentre en peligro de caer de la mesa, en caso contrario deberá retroceder de forma aleatoria. Luego de que se retrocede aleatoriamente, por un tiempo determinado, se utiliza la función girar_aleatorio() para que gire en un sentido aleatorio cuando deje de retroceder, y la siguiente vez que se avance, lo haga con otra dirección.

while true do
    avanzar()
    while (puedo_avanzar()) do
	util.wait(INTERVALO_CHEQUEO)
    end
    retroceder_aleatorio()
    girar_aleatorio()
end
  • avanzar

Activa los motores haciendo que los mismos giren a una velocidad prefijada en la constante MOTOR_VEL.

local function avanzar()
    Motors.setvel2mtr(0, MOTOR_VEL, 0, MOTOR_VEL)
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.

local function puedo_avanzar()
    return (Grey_2.getValue() < COLOR_MESA)
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
  • retroceder_aleatorio

Utilizamos la función random para obtener un número aleatorio entre MIN_TIEMPO_RETROCESO y MAX_TIEMPO_RETROCESO y así definir el tiempo durante el cual el robot estará retrocediendo.

local function retroceder_aleatorio()
    local tiempo_retroceso = math.random(MIN_TIEMPO_RETROCESO, MAX_TIEMPO_RETROCESO)
    Motors.setvel2mtr(1, VELOCIDAD_RETROCESO, 1, VELOCIDAD_RETROCESO)
    util.wait(tiempo_retroceso)
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

Butialo: Ejemplo 3 - Robot que no se caiga de la mesa sin eventos, utilizando un sensor de grises - Código