Diferencia entre revisiones de «Butialo: Ejemplo 8 - Seguidor de líneas con obstáculos, sin eventos, utilizando un sensor de grises y uno de distancia»
(→Solución) |
m (→Configuración) |
||
(No se muestran 8 ediciones intermedias de 2 usuarios) | |||
Línea 11: | Línea 11: | ||
'''Descripción''' | '''Descripción''' | ||
− | Obtenemos el valor de la variable COLOR_NEGRO de la misma forma que lo hicimos en el Ejemplo 1. Además, debemos calibrar el valor de la distancia mínima a partir de la cual el robot detecta la presentacia de un obstáculo y por lo tanto deberá esquivar el mismo utilizando una técnica de rodeo. | + | Obtenemos el valor de la variable COLOR_NEGRO de la misma forma que lo hicimos en el Ejemplo 1. Además, debemos calibrar el valor de la variable DISTANCIA_OBSTACULO que refiera a la distancia mínima a partir de la cual el robot detecta la presentacia de un obstáculo y por lo tanto deberá esquivar el mismo utilizando una técnica de rodeo. |
El robot deberá seguir el rastro de la línea de color negro de la misma forma que se realizó en el Ejemplo 1, chequeando además la presencia de un obstáculo que deberá esquivar para luego regresar a línea negra. | El robot deberá seguir el rastro de la línea de color negro de la misma forma que se realizó en el Ejemplo 1, chequeando además la presencia de un obstáculo que deberá esquivar para luego regresar a línea negra. | ||
Línea 19: | Línea 19: | ||
* '''programa principal''' | * '''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 la siguiente vez que se avance, se haga en | + | 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 la siguiente vez que se avance, se haga en una dirección aleatoria. |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
Línea 67: | Línea 67: | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
* '''es_negro''' | * '''es_negro''' | ||
Línea 117: | Línea 116: | ||
* '''hay_obstaculo''' | * '''hay_obstaculo''' | ||
− | Retorna un valor booleano que indica si el robot | + | Retorna un valor booleano que indica si el robot ha detectado la presencia de un obstáculo, según el valor obtenido por el sensor de distancia y su comparación con la constante DISTANCIA_OBSTACULO. |
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
Línea 127: | Línea 126: | ||
* '''esquivar_obstaculo''' | * '''esquivar_obstaculo''' | ||
− | + | Al detectar la presencia de un obstáculo, el robot deberá actuar de la siguiente forma: | |
+ | 1) Retroceder un tiempo determinado hasta alejarse lo suficiente como para poder girar. | ||
+ | 2) Girar a la derecha 90°. | ||
+ | 3) Avanza un tiempo determinado para alejarse del obstáculo. | ||
+ | 4) Girar a la izquierda 90°. | ||
+ | 5) Avanza un tiempo determinado para poder pasar el obstáculo. | ||
+ | 6) Girar a la izquierda 120° (=90*4/3) | ||
+ | 7) Avanza para volver a retomar la línea. | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
Línea 157: | Línea 163: | ||
==Configuración== | ==Configuración== | ||
− | Se debe colocar un sensor de escala de grises lo más cercano | + | Se debe colocar un sensor de escala de grises lo más cercano al suelo, pero siempre sin tocarlo, 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 del suelo. | ||
− | + | Además se debe colocar un sensor de distancia al frente del Butiá, de manera que sense lo que tiene por delante. | |
Se muestra a continuación una imagen ilustrativa de la configuración del robot vista desde arriba. | Se muestra a continuación una imagen ilustrativa de la configuración del robot vista desde arriba. | ||
Línea 167: | Línea 175: | ||
==Video== | ==Video== | ||
+ | <youtube>maY-Xjjofp4</youtube> | ||
==Código== | ==Código== | ||
− | [[Butialo: Ejemplo | + | [[Butialo: Ejemplo 8 - Seguidor de líneas con obstáculos, sin eventos, utilizando un sensor de grises y uno de distancia - Código]] |
Revisión actual del 16:55 15 oct 2012
Contenido
Descripción
Se desea implementar un seguidor de líneas de nivel avanzado que permita al robot Butiá seguir el rastro de una línea de color negro sobre el suelo eludiendo obstáculos.
El robot deberá avanzar mientras se encuentre en una zona oscura y no detecte la proximidad de un obstáculo. En caso de salirse de la línea, deberá girar para poder encontrar nuevamente una zona oscura y en caso de detectar un obstáculo procederá a aplicar una técnica de rodeo poder continuar avanzando por la línea de color negro.
Solución
Descripción
Obtenemos el valor de la variable COLOR_NEGRO de la misma forma que lo hicimos en el Ejemplo 1. Además, debemos calibrar el valor de la variable DISTANCIA_OBSTACULO que refiera a la distancia mínima a partir de la cual el robot detecta la presentacia de un obstáculo y por lo tanto deberá esquivar el mismo utilizando una técnica de rodeo.
El robot deberá seguir el rastro de la línea de color negro de la misma forma que se realizó en el Ejemplo 1, chequeando además la presencia de un obstáculo que deberá esquivar para luego regresar a línea negra.
Una vez calibrados los valores de los sensores, 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 la siguiente vez que se avance, se haga en una dirección aleatoria.
while true do
avanzar()
while (es_negro() and not hay_obstaculo()) do
util.wait(INTERVALO_CHEQUEO)
end
if hay_obstaculo() then
esquivar_obstaculo()
else
buscar_negro()
util.wait(TIEMPO_CENTRADO)
invertir_sentido()
end
end
- invertir_sentido
Cambia el sentido de izquierda a derecha o viceversa.
local function invertir_sentido()
if sentido == "I" then
sentido = "D"
else
sentido = "I"
end
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
- retroceder
Retrocede el Butiá haciendo que los motores giren a una velocidad prefijada en la constante MOTOR_VEL.
local function retroceder()
Motors.setvel2mtr(1, MOTOR_VEL, 1, MOTOR_VEL)
end
- es_negro
Retorna un valor booleano que indica si el robot está parado sobre la zona oscura, según el valor obtenido por el sensor de grises y su comparación con la constante COLOR_NEGRO.
local function es_negro()
local color = Grey_1.getValue()
return (color > COLOR_NEGRO)
end
- girar
Gira el robot en el sentido correspondiente, el cual estará definido por la variable sentido.
local function girar()
if sentido == "I" then
Motors.setvel2mtr(0,MOTOR_GIRO_VEL,1,MOTOR_GIRO_VEL)
else
Motors.setvel2mtr(1,MOTOR_GIRO_VEL,0,MOTOR_GIRO_VEL)
end
end
- buscar_negro
Si el robot no encuentra color negro entonces deberá buscarlo. El robot hace un abanico, girando determinado tiempo en un sentido, para luego girar el doble de tiempo en el sentido opuesto. Esta acción culminará cuando se detecte que el robot está en una zona oscura.
local function buscar_negro()
tiempo = 0.5
local tiempo_girando
while true do
tiempo_girando = 0
girar()
invertir_sentido()
while (not es_negro() and tiempo_girando <= tiempo) do
util.wait(0.1)
tiempo_girando = tiempo_girando + 0.1
end
if es_negro() then
break
else
tiempo = tiempo * 2
end
end
end
- hay_obstaculo
Retorna un valor booleano que indica si el robot ha detectado la presencia de un obstáculo, según el valor obtenido por el sensor de distancia y su comparación con la constante DISTANCIA_OBSTACULO.
local function hay_obstaculo()
local distancia = Distanc_2.getValue()
return (distancia > DISTANCIA_OBSTACULO)
end
- esquivar_obstaculo
Al detectar la presencia de un obstáculo, el robot deberá actuar de la siguiente forma: 1) Retroceder un tiempo determinado hasta alejarse lo suficiente como para poder girar. 2) Girar a la derecha 90°. 3) Avanza un tiempo determinado para alejarse del obstáculo. 4) Girar a la izquierda 90°. 5) Avanza un tiempo determinado para poder pasar el obstáculo. 6) Girar a la izquierda 120° (=90*4/3) 7) Avanza para volver a retomar la línea.
local function esquivar_obstaculo()
local sentido_previo = sentido
retroceder()
util.wait(TIEMPO_RETROCESO)
sentido = "D"
girar()
util.wait(TIEMPO_GIRO_90_GRADOS)
avanzar()
util.wait(TIEMPO_AVANCE)
sentido = "I"
girar()
util.wait(TIEMPO_GIRO_90_GRADOS)
avanzar()
util.wait(TIEMPO_AVANCE * 3)
sentido = "I"
girar()
util.wait(TIEMPO_GIRO_90_GRADOS * 4 / 3)
avanzar()
while (not es_negro()) do
util.wait(INTERVALO_CHEQUEO)
end
sentido = sentido_previo
end
Configuración
Se debe colocar un sensor de escala de grises lo más cercano al suelo, pero siempre sin tocarlo, 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 del suelo.
Además se debe colocar un sensor de distancia al frente del Butiá, de manera que sense lo que tiene por delante.
Se muestra a continuación una imagen ilustrativa de la configuración del robot vista desde arriba.
Video