Pular para o conteúdo
Português (Brasil)

Comunicação

O seu programa conversa com a partida por meio de dois dispositivos que todo robô tem:

  • O emissor (emitter) envia mensagens para a partida. Ele não precisa ser ativado.
  • O receptor (receiver) recebe mensagens da partida. Ative-o como um sensor.

Cada seção abaixo é um programa completo para o robô inicial. Todas as mensagens estão listadas na Referência de mensagens.

Para pontuar com uma vítima de letra (letter victim) ou um alvo cognitivo (cognitive target), o robô precisa:

  1. Ficar parado por mais de 1 segundo perto do marcador. O Erebus ignora o informe se o robô se moveu no último segundo.
  2. Enviar a posição e o tipo do marcador: X e Z em centímetros, e o tipo como uma letra.
Marcador de parede Tipo
Vítima de letra Φ (ferida) H
Vítima de letra Ψ (estável) S
Vítima de letra Ω (ilesa) U
Alvo cognitivo, soma 0 (gás inflamável) F
Alvo cognitivo, soma 1 (veneno) P
Alvo cognitivo, soma 2 (corrosivo) C
Alvo cognitivo, soma 3 (peróxido orgânico) O

Os tipos são letras, mesmo que as vítimas mostrem símbolos desde 2026. O GPS fornece metros, então multiplique 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")

O robô precisa estar do mesmo lado da parede que o marcador, e tanto o robô quanto a posição que você envia precisam estar perto dele. As regras exigem no máximo meio ladrilho, então mire nisso. O Erebus v26.1 verifica uma distância de 9 cm.

Execute este programa no início de world1.wbt: não há nenhum marcador ali, então o histórico da janela de controle mostra Misidentification of Victim -5. Um informe errado, incluindo o informe de um falso, custa 5 pontos, e cada marcador só pode ser pontuado uma vez.

O histórico da janela de controle depois de um informe errado e do envio de um mapa

Quando o robô fica preso, uma falta de progresso (Lack of Progress, LoP) o leva de volta ao último ponto de controle (checkpoint) e custa 5 pontos. Ela acontece automaticamente após 20 segundos sem se mover, e o seu programa também pode declará-la enviando L. A cada vez, a partida envia L ao robô, para que o seu programa saiba que a posição dele mudou.

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()

O receptor pode receber mensagens diferentes, então confira o tamanho de cada uma antes de lê-la, como no exemplo.

Envie G para obter a pontuação e o tempo restante. A partida responde com uma mensagem de 16 bytes: a letra G, a pontuação, o tempo de partida restante e o tempo real restante, em 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()

O tempo de partida corre mais rápido nos pântanos, e a partida termina quando qualquer um dos dois tempos acaba. Use os dois para saber quando voltar para o início.

Envie E para terminar a partida. Se o robô estiver no ladrilho inicial e tiver identificado pelo menos um marcador, ele ganha o bônus de saída (exit bonus) de 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)

Em seguida, aprenda a diferenciar os marcadores em Marcadores nas paredes.