|
|
Robobo: Callbacks
Introducción
Las funciones que hemos visto hasta ahora, forman parte de un programa secuencial, es decir, con una lógica que se cumple paso a paso. Una función de callback, es una función que se pasa como argumento a otra función, desde la que es llamada posteriormente, normalmente cuando se cumple una condición.
La librería Robobo contiene 6 métodos que emplean callbacks. Dos de ellos hacen referencia al sensor fling y al sensor tap de la pantalla táctil, uno utiliza la detección de blobs de color, y los otros 3 actúan sobre los códigos QR.
WhenAFlingIsDetected(callback)
Función: Establece la función callback que se llama cuando se detecta un nuevo fling.
- callback (fun): La función callback a ser llamada.
Puedes ejecutar el código de abajo en un mundo cualquiera. El objetivo de este código es que el Robobo diga su nivel de batería cuando el usuario hace un fling en la pantalla del smarthphone:
from robobopy.Robobo import Robobo
#Función que se utilizará como callback
def say_battery_level():
rob.sayText('La base tiene una bateria de' + str(rob.readBatteryLevel('base')))
rob = Robobo('localhost')
rob.connect()
rob.whenAFlingIsDetected(say_battery_level)
tiempo=0
# el programa se mantiene en ejecución continua hasta que pase 1 minuto
while tiempo<600:
rob.wait(0.1)
tiempo+=1
print("TIMEOUT")
rob.disconnect()
Al incluir esta función whenAFlingIsDetected en el programa, estará comprobando, de manera continuada, si el usuario hace un fling. En ese caso, lanzará la función de callback say_battery_level que se le pasó como argumento y que está definida previamente.
WhenATapIsDetected(callback)
Función: Establece la función callback que se llama cuando se detecta un nuevo tap.
Parámetros:
- callback (fun): La función callback a ser llamada.
Puedes ejecutar el código de abajo en los mundos SLOPE o PLAIN. El objetivo de este programa es que el Robobo avance recto de forma constante hasta que alguien toque la pantalla con un tap, de esa manera, se detendrá.
from robobopy.Robobo import Robobo
#Función que se utilizará como callback
def fun():
rob.stopMotors()
rob = Robobo('localhost')
rob.connect()
rob.moveWheels(30,30)
rob.whenATapIsDetected(fun)
timeout=0
# el programa se mantiene en ejecución continua durante medio minuto
while timeout<300:
rob.wait(0.1)
timeout+=1
print("TIMEOUT")
rob.disconnect()
De nuevo, al incluir la funciónwhenATapIsDetected en el programa, estará comprobando, de manera continuada, si el usuario hace un tap cualquiera. En ese caso, lanzará la función fun que recibe como argumento y que está definida previamente.
whenANewColorBlobIsDetected(callback)
Función:Establece la función callback que se llama cuando se detecta un nuevo blob.
Parámetros:
- callback (fun): La función callback que será llamada.
Para probar este método, cargad el mapa FOUR CYLINDRES y ejecutad el siguiente código:
- Robobo subirá su TILT para detectar mejor los colores, y luego irá girando sobre su eje tratando de detectar los cilindros de colores.
- Cada vez que detecta uno, dice el color que ve.
- En este ejemplo está desactivado el color CUSTOM, por lo que no dirá nada sobre ese blob de color (en este caso, el cilindro amarillo).
from robobopy.Robobo import Robobo
from robobopy.utils.Color import *
#Función que se ejecuta cuando el callback se activa
def color_detected():
print(rob.readColorBlob(Color.BLUE).size)
if rob.readColorBlob(Color.GREEN).size != 0:
rob.sayText('Estoy viendo verde')
else:
if rob.readColorBlob(Color.RED).size != 0:
rob.sayText('Estoy viendo rojo')
else:
rob.sayText('Estoy viendo azul')
#Configurando parámetros iniciales
rob = Robobo("localhost")
rob.connect()
rob.setActiveBlobs(True, True, True, False)
#Declaramos la función de interrupción
rob.whenANewColorBlobIsDetected(color_detected)
#Se mueve el Tilt
rob.moveTiltTo(90,5,True)
# el programa se mantiene en ejecución continua durante aproximadamente 1 minuto
timeout=0
while timeout<300:
rob.moveWheels(3,-3)
rob.wait(0.2)
timeout+=1
print("TIMEOUT")
rob.disconnect()
WhenAQRCodeIsDetected(callback)
Función: Establece la función callback que se llama cuando se detecta un QR.
- callback (fun): La función callback a ser llamada.
El ejemplo de abajo se cargará en el mundo RECYCLING SIMPLE y con la opción "Habilitar mundos aleatorios" activada:
El robot se acercará con tal de detectar el QR que tiene en frente
En el momento en el que el robot detecte un QR, se activará el callback.
El callback detendrá los motores y leerá el QR. Solo hay 3 identificadores de QR en este mapa: ORGANIC, PLASTIC Y PAPER. El robot dirá Código, seguido del nombre del identificador y luego dirá "detectado. Por ejemplo: Código ORGANIC detectado
El callback se activará constantemente mientras siga viendo un QR.
Pasado el medio minuto, el programa se parará.
from robobopy.Robobo import Robobo
from robobopy.utils.Wheels import Wheels
#Función que se ejecuta cuando se activa el callback
def fun():
rob.stopMotors()
rob.sayText('Codigo')
rob.sayText(rob.readQR().id)
rob.sayText('detectado')
rob = Robobo('localhost')
rob.connect()
rob.moveWheels(5,5)
#Se declara la función de interrupción
rob.whenAQRCodeIsDetected(fun)
# El programa se mantiene en ejecución durante medio minuto
timeout=0
while timeout<30:
rob.wait(1)
timeout+=1
print("TIMEOUT")
rob.disconnect()
WhenANewQRCodeIsDetected(callback)
Función: Establece la función callback que se llama cuando se detecta un nuevo QR. Un QR se considera nuevo si es distinto del detectado la última vez.
En el mismo mundo que en el apartado anterior:
- El robot avanzará a una velocidad de 10 durante 3 segundo para tener más cerca el QR.
- El robot dirá "Ya he visto el primer QR. Voy a ver el de la derecha". Como se pudo ver en el ejemplo anterior, Robobo detectó el QR de enfrente nada más ejecutarse el programa, por lo que aquí partimos de que, al poco de conectarse en este nuevo ejemplo, ya ha visto el primer QR leído.
- Para demostrar que el siguiente QR será uno nuevo, Robobo girará a la derecha a una velocidad de 3 durante 3 segundos. Si empieza a hablar antes de detenerse, querrá decir que ha visto el nuevo QR.
- En el callback, Robobo dirá "Un nuevo QR detectado" y después el identificador del mismo.
- Una vez hayan pasado 5 segundos desde que detuvo las ruedas, finalizará el programa.
from robobopy.Robobo import Robobo
from robobopy.utils.Wheels import Wheels
#Función que se usará como callback
def fun():
rob.stopMotors()
rob.sayText('Un nuevo QR detectado')
rob.sayText(rob.readQR().id)
rob.wait(1)
#Conexión y preparativos
rob = Robobo('localhost')
rob.connect()
rob.startQrTracking()
rob.moveWheelsByTime(10,10,3)
#Se declara la función de interrupción
rob.whenANewQRCodeIsDetected(fun)
rob.wait(2)
rob.sayText("Ya he visto el primer QR. Voy a ver el de la derecha")
rob.moveWheelsByTime(-3,3,3)
rob.wait(5)
rob.disconnect()
WhenAQRCodeIsLost(callback)
Función: Establece la función callback que se llama cuando se pierde un QR.
- callback (fun): La función callback a ser llamada.
Siguiendo en el mismo mundo. Se cargará este código:
- Se acercará de la misma manera que se acercó al QR en el ejemplo anterior.
- Después, Robobo girará su tilt a un ángulo de 5 con una velocidad de 25 con tal de perder de vista el QR que tiene enfrente. Así no detectará los otros dos.
from robobopy.Robobo import Robobo
from robobopy.utils.Wheels import Wheels
#Función que se usará como callback
def fun():
rob.sayText('Se ha perdido el codigo QR')
#Conexión y preparativos
rob = Robobo('localhost')
rob.connect()
rob.startQrTracking()
rob.moveWheelsByTime(10,10,3)
#Se declara la función de interrupción
rob.whenAQRCodeIsLost(fun)
#Se mueve el Tilt. Durante su ejecución, se puede activar la función de interrupción
rob.moveTiltTo(35,25)
rob.disconnect()
Ejercicios
EJERCICIO 1
En un mundo cualquiera, realiza un programa en el que Robobo avance dependiendo de la zona que toques de la pantalla táctil y usando la función WhenATapIsDetected(callback):
- Si tocas la zona eye, el robot se moverá a una velocidad de 20 de forma constante.
- Si tocas la zona right, el robot girará hacia la izquierda a una velocidad de 5.
- Si tocas la zona left, el robot girará hacia la derecha a una velocidad de 5.
- Si tocas la zona chin, el robot avanzará el doble de rápido, es decir, a 40.
- Si tocas la zona forehead, el robot avanzará hacia atrás a una velocidad de 20.
- Si tocas la zona mouth, el robot se detendrá.
El programa funcionará durante 60 segundos. Cuando termine se tienen que parar los motores.
#INSERTAR CÓDIGO AQUÍ
EJERCICIO 2
En el mundo FOUR CYLINDERS con la opción "habilitar mundos aleatorios" activada, realizar el siguiente programa:
- Robobo empezará girando sobre su eje a una velocidad de 5.
- Usando la función de interrupción de los blobs, la velocidad de Robobo cambiará dependiendo del color:
- Si es verde, se moverá a 7
- Si es amarillo, se moverá a 3
- Si es azul, se moverá a una velocidad de 2 durante 2 segundos y luego girará constantemente a una velocidad de 10.
- Si es rojo se detendrá durante 1 segundos y después se moverá a una velocidad de 5.
- El programa terminará cuando hayan pasado 40 intervalos de medio segundo. El progrma durará más en función del tiempo que tarda el callback.
#INSERTAR CÓDIGO AQUÍ
EJERCICIO 3
Abrir el mapa TEST PLANE y crear el siguiente código:
Mediante la función de interrupción del Fling, cread un programa en el que Robobo se mueva dependiendo del fling:
- Si el ángulo del fling es inferior a 30 o superor a 330, gira ligeramente hacia la izquierda mientras avanza a una velocidad de 15 (La rueda derecha debe de girar a una velocidad mayor).
- Si el ángulo del fling es superior a 150 e inferior a 210, gira ligeramente hacia la derecha mientras avanza a una velocidad de 15 (La rueda izquierda debe de girar a una velocidad mayor).
- Si el ángulo está entre 80 y 100, avanza recto a una velocidad de 20
- Si el ángulo está entre 260 y 200, avanza hacia atrás a una velocidad de 5 durante 2 segundos y luego se detiene.
- Si el ángulo del fling no corresponde a ninguno de los dos casos anteriores, no afectará su comportamiento actual
- El programa funcionará durante 30 segundos. Cuando termine se tienen que parar los motores. Es posible que tarde más debido a las llamadas del callback.
#INSERTAR CÓDIGO AQUÍ