UD04 · Notebook 3 — Ejemplos de robots en AITK¶
En este ejemplo veremos diferentes tipos de sensores y robots en los que podemos usar en aitk.robots y cómo podemos interactuar con ellos.
%pip install aitk ipykernel
from aitk.robots import (
World, Scribbler,
RangeSensor, LightSensor, SmellSensor,
Camera
)
from random import random
Un mundo con paredes, una bombilla y comida¶
Hay una fuente de comida ubicada cerca del origen del mundo detrás de una pequeña pared azul inclinada. Hay una fuente de luz cerca del centro del mundo escondida en la esquina de las paredes cian y naranja.
Usamos la comida y la luz para atraer a los robots. Los robots pueden ver luz y comida y pueden moverse hacia ellos. Los robots también pueden ver las paredes y evitarlas. Obviamente, los robots no comen, este elemento, sin embargo, nos permitirá ver cómo los robots pueden interactuar con los objetos en el mundo.
# Definimos el mundo
# Creamos un mundo de 200x150 con una escala de 5.0
world = World(width=200, height=150, scale=5.0)
world.add_wall("cyan", 80, 50, 90, 150)
world.add_wall("orange", 90, 50, 110, 60)
world.add_wall("blue", 0, 35, 25, 30, box=False)
world.add_bulb("yellow", 100, 70, 0, 75.0)
world.add_food(15, 10, 50)
#Mostramos el mundo y pedimos que se actualice automáticamente
world.watch(width="700px")
Random seed set to: 9396671
Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x0…
El robot rojo usa sensores IR¶
El robot rojo utiliza sensores IR para detectar y evitar obstáculos. Puede determinar a qué lado gira en función de si el obstáculo está más cerca de su parte delantera derecha o izquierda.
robot1 = Scribbler(x=150, y=100, a=35, color="red", name="red")
robot1.add_device(RangeSensor(position=(6,-6),width=57.3,max=20,name="left-ir"))
robot1.add_device(RangeSensor(position=(6,6),width=57.3,max=20,name="right-ir"))
world.add_robot(robot1)
El robot rosa usa sensores de olor y una cámara¶
El robot rosa usa sensores de olor para encontrar comida. También tiene una cámara que puede ver las características del mundo. Puede girar hacia los alimentos detectados a su izquierda o derecha.
robot2 = Scribbler(x=40, y=130, a=75, color="pink", name="pink")
robot2.state["timer"] = 0 # Usamos el diccionario state para guardar variables.
# Esta variable nos ayudará a controlar el tiempo
robot2.add_device(Camera())
robot2.add_device(SmellSensor(position=(6,-6),name="left-smell"))
robot2.add_device(SmellSensor(position=(6,6),name="right-smell"))
world.add_robot(robot2)
El robot amarillo usa sensores de luz¶
El robot amarillo usa sensores de luz para encontrar una fuente de luz. Puede girar hacia la luz detectada a su izquierda o derecha.
robot3 = Scribbler(x=60, y=30, a=0, color="yellow", name="yellow")
robot3.add_device(LightSensor(position=(6,-6), name="left-light"))
robot3.add_device(LightSensor(position=(6,6), name="right-light"))
world.add_robot(robot3)
world.watch(width="700px")
Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x0…
#POV del robot rosa
robot2['camera'].watch()
HTML(value='<style>img.pixelated {image-rendering: pixelated;}</style>') HTML(value='<style>img.pixelated {image-rendering: pixelated;}</style>') HTML(value='<style>img.pixelated {image-rendering: pixelated;}</style>') Image(value=b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00@\x00\x00\x00 \x08\x06\x00\x00\x00\xa2\x9d~\x84\x…
El controlador del robot rojo¶
El robot rojo deambula por todo el mundo evitando los obstáculos que encuentra. Siempre está avanzando, pero elige cantidades de rotación aleatoria cuando sus sensores de rango frontal están limpios.
def deambula_amb_infrarojos(robot):
max_val = robot["left-ir"].get_max()
if robot["left-ir"].get_distance() < max_val:
robot.move(0.1, -0.3)
elif robot["right-ir"].get_distance() < max_val:
robot.move(0.1, 0.3)
else:
robot.move(1, random()-0.5)
El demonio del robot Rosa¶
El robot rosa deambula por todo el mundo buscando comida y evitando los obstáculos, retrocede cuando se queda atascado. Usa una variable de estado llamada timer para asegurarse de que incluso en presencia de un olor siempre retrocede al menos cinco pasos cuando encuentra un obstáculo. Si se acerca a la comida lo suficiente, intenta comerla, y si tiene éxito, la ejecución termina devolviendo True. De vez en cuando elige un nuevo movimiento errático aleatorio. Si no se activan ninguno de sus casos de prueba, repite el movimiento anterior.
def busca_menjar(robot):
left_smell = robot["left-smell"].get_reading()
right_smell = robot["right-smell"].get_reading()
diff = left_smell - right_smell
if left_smell+right_smell>1.95 and robot.eat():
robot.move(0,0)
robot.speak("¡He comido!")
return True
# Usamos un temporizador para asegurarme de volver
# por un tiempo mínimo de 5 iteraciones
if robot.state["timer"] > 5:
robot.state["timer"] = 0
if robot.stalled:
robot.state["timer"] = 1
robot.reverse()
elif robot.state["timer"] > 0:
robot.state["timer"] += 1
elif diff > 0.03:
robot.move(1, 0.3)
elif diff < -0.03:
robot.move(1, -0.3)
elif world.time%2 == 0:
robot.move(1.0, random()*0.5-0.25)
else:
pass #Continua en la misma dirección
El controlador del robot amarillo busca la luz¶
El objetivo del robot amarillo es encontrar y acercarse a una fuente de luz. Cuando no detecta la luz, el robot deambula. Cuando detecta más luz en un lado, gira hacia la luz. Si se detiene el robot, invierte su movimiento. De vez en cuando genera un nuevo movimiento errático aleatorio. Cuando ninguna de las pruebas se activa, el robot continuará haciendo el movimiento anterior. Cuando sus lecturas de luz pasan un umbral, se detiene e informa que ha encontrado la luz, devuelve True y termina la ejecución.
def search_light(robot):
left_light = robot["left-light"].get_brightness()
right_light = robot["right-light"].get_brightness()
diff = left_light - right_light
if left_light + right_light > 1.9:
robot.move(0,0)
robot.speak("¡Encontré la luz!")
return True
if robot.stalled:
robot.reverse()
elif diff > 0.01:
robot.move(1,0.5)
elif diff < -0.01:
robot.move(1,-0.5)
elif world.time%2 == 0:
robot.move(1.0, random()*0.5-0.25)
else:
pass #Continua en la misma dirección
# mostramos de nuevo el mundo
world.watch(width="700px")
Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x0…
world.reset()
robot2.state["timer"] = 0 #set el temporizador
world.set_seed(random())
world.seconds(40,[deambula_amb_infrarojos, busca_menjar, search_light], real_time=True)
0%| | 0/400 [00:00<?, ?it/s]
Simulation stopped at: 00:00:11.50; speed 0.78 x real time
Podemos usar real_time=False para ejecutar el programa más rápido, pero sin esperar la pausa que hemos definido.
Esta función será muy útil para entrenar modelos y hacer simulaciones más rápidas.
# mostramos de nuevo el mundo
world.watch(width="700px")
Image(value=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x0…
world.reset()
robot2.state["timer"] = 0 #reinicia el temporizador
world.set_seed(random())
world.seconds(40,[deambula_amb_infrarojos, busca_menjar, search_light], real_time=False)
0%| | 0/400 [00:00<?, ?it/s]
Simulation stopped at: 00:00:06.20; speed 58.64 x real time