Ir al contenido
Español

Comunicación

Tu programa habla con la partida a través de dos dispositivos que tienen todos los robots:

  • El emisor (emitter) envía mensajes a la partida. No hace falta activarlo.
  • El receptor (receiver) recibe mensajes de la partida. Actívalo como un sensor.

Cada sección siguiente es un programa completo para el robot inicial. Todos los mensajes están en la Referencia de mensajes.

Para puntuar una víctima de letra (Letter victim) o un objetivo cognitivo (Cognitive target), el robot debe:

  1. Detenerse más de 1 segundo cerca de la marca. Erebus ignora el informe si el robot se ha movido en el último segundo.
  2. Enviar la posición y el tipo de la marca: X y Z en centímetros, y el tipo como una letra.
Marca en la pared Tipo
Víctima de letra Φ (herida) H
Víctima de letra Ψ (estable) S
Víctima de letra Ω (ilesa) U
Objetivo cognitivo, suma 0 (gas inflamable) F
Objetivo cognitivo, suma 1 (veneno) P
Objetivo cognitivo, suma 2 (corrosivo) C
Objetivo cognitivo, suma 3 (peróxido orgánico) O

Los tipos son letras, aunque desde 2026 las víctimas muestran símbolos. El GPS da metros, así que multiplica por 100.

from controller import Robot
import struct
robot = Robot()
timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter") # Always on the robot. It does not need to be enabled.
gps = robot.getDevice("gps")
gps.enable(timeStep)
leftWheel = robot.getDevice("left wheel motor")
rightWheel = robot.getDevice("right wheel motor")
leftWheel.setPosition(float("inf"))
rightWheel.setPosition(float("inf"))
def wait(seconds):
start = robot.getTime()
while robot.step(timeStep) != -1:
if robot.getTime() - start >= seconds:
break
def report(tokenType):
# 1. Stop for more than 1 second
leftWheel.setVelocity(0)
rightWheel.setVelocity(0)
wait(1.2)
# 2. Send the position in centimeters, and the type as one letter
x, _, z = gps.getValues()
message = struct.pack("i i c", int(x * 100), int(z * 100), tokenType.encode())
emitter.send(message)
robot.step(timeStep)
report("H") # Reports a harmed victim (Φ) where the robot is
print("Reported")

El robot debe estar en el mismo lado de la pared que la marca, y tanto el robot como la posición que envías deben estar cerca de ella. Las reglas exigen como máximo media baldosa, así que apunta a eso. Erebus v26.1 comprueba una distancia de 9 cm.

Ejecuta este programa al inicio de world1.wbt: ahí no hay ninguna marca, así que el historial de la ventana de control muestra Misidentification of Victim -5. Un informe erróneo, incluido el informe de una marca falsa, cuesta 5 puntos, y cada marca solo se puede puntuar una vez.

El historial de la ventana de control tras un informe erróneo y el envío de un mapa

Cuando el robot está atascado, una falta de progreso (Lack of Progress, LoP) lo devuelve al último punto de control (checkpoint) y cuesta 5 puntos. Ocurre automáticamente tras 20 segundos sin moverse, y tu programa también puede declararla enviando L. Cada vez, la partida envía L al robot, para que tu programa sepa que su posición ha cambiado.

from controller import Robot
import struct
robot = Robot()
timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")
receiver = robot.getDevice("receiver")
receiver.enable(timeStep) # The receiver must be enabled
askedAt = None
while robot.step(timeStep) != -1:
# Call a lack of progress once, after 2 seconds
if askedAt is None and robot.getTime() > 2:
emitter.send(struct.pack("c", b"L"))
askedAt = robot.getTime()
# Listen for messages from the game
while receiver.getQueueLength() > 0:
data = receiver.getBytes()
if len(data) == 1 and data == b"L":
print("Lack of progress! The robot is back at the last checkpoint.")
receiver.nextPacket()

El receptor puede recibir mensajes distintos, así que comprueba la longitud de cada uno antes de leerlo, como en el ejemplo.

Envía G para obtener la puntuación y el tiempo restante. La partida responde con un mensaje de 16 bytes: la letra G, la puntuación, el tiempo de partida restante y el tiempo real restante, en segundos.

from controller import Robot
import struct
robot = Robot()
timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")
receiver = robot.getDevice("receiver")
receiver.enable(timeStep)
lastAsked = 0
while robot.step(timeStep) != -1:
# Ask for the game information once a second
if robot.getTime() - lastAsked > 1:
emitter.send(struct.pack("c", b"G"))
lastAsked = robot.getTime()
while receiver.getQueueLength() > 0:
data = receiver.getBytes()
if len(data) == 16: # The game information is 16 bytes long
_, score, timeLeft, realTimeLeft = struct.unpack("c f i i", data)
print("Score:", round(score, 2), "Time left:", timeLeft, "s", "Real time left:", realTimeLeft, "s")
receiver.nextPacket()

El tiempo de partida corre más rápido en los pantanos, y la partida termina cuando se acaba cualquiera de los dos tiempos. Usa ambos para saber cuándo volver a la salida.

Envía E para terminar la partida. Si el robot está en la baldosa de salida y ha identificado al menos una marca en la pared, consigue la bonificación de salida (Exit bonus) del 10 %.

from controller import Robot
import struct
robot = Robot()
timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")
robot.step(timeStep)
print("Ending the game")
# Ends the game. Send it on the starting tile, after identifying a token, to get the exit bonus.
# The game stops your program right after this message.
emitter.send(struct.pack("c", b"E"))
robot.step(timeStep)

A continuación, aprende a distinguir las marcas en Marcas en las paredes.