コンテンツにスキップ
日本語

通信

プログラムは、すべてのロボットに付いている 2 つのデバイスを通じてゲームとやり取りします。

  • エミッター(emitter) は、ゲームにメッセージを送ります。有効にする必要はありません。
  • レシーバー(receiver) は、ゲームからメッセージを受け取ります。センサーと同じように有効にします。

以下の各セクションは、スターターロボット用の完全なプログラムです。すべてのメッセージはメッセージリファレンスに載っています。

文字の被災者(Letter victim)やコグニティブターゲット(Cognitive target)で得点するには、ロボットは次のことをする必要があります。

  1. トークンの近くで 1 秒より長く停止する。直前の 1 秒間にロボットが動いていると、Erebus は報告を無視します。
  2. トークンの 位置と種類を送る。X と Z は センチメートル 単位で、種類は 1 文字で表します。
壁のトークン 種類
文字の被災者 Φ(harmed) H
文字の被災者 Ψ(stable) S
文字の被災者 Ω(unharmed) U
コグニティブターゲット、合計 0(Flammable Gas、可燃性ガス) F
コグニティブターゲット、合計 1(Poison、毒物) P
コグニティブターゲット、合計 2(Corrosive、腐食性物質) C
コグニティブターゲット、合計 3(Organic Peroxide、有機過酸化物) O

2026 年から被災者は記号で表示されますが、種類は文字のままです。GPS はメートル単位なので、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")

ロボットはトークンと同じ壁の側にいる必要があり、ロボットと送る位置の両方がトークンに近くなければなりません。ルールではタイル半分以内と定められているので、それを目指しましょう。Erebus v26.1 では 9 cm の距離で判定しています。

このプログラムを world1.wbt のスタート地点で実行してみましょう。そこにはトークンがないので、コントロールウィンドウの履歴に Misidentification of Victim -5 と表示されます。偽物の報告を含め、誤った報告は 5 点の減点になり、各トークンで得点できるのは 1 回だけです。

誤った報告と地図の提出の後の、コントロールウィンドウの履歴

ロボットが動けなくなったとき、競技進行停止(Lack of Progress, LoP)によってロボットは最後のチェックポイントに戻され、5 点を失います。20 秒間動かないと自動的に発生しますが、プログラムから L を送って宣言することもできます。そのたびにゲームはロボットに L を送るので、プログラムは自分の位置が変わったことがわかります。

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

レシーバーはさまざまなメッセージを受け取るので、例のように、読み取る前に各メッセージの長さを確認してください。

G を送ると、スコアと残り時間を取得できます。ゲームは 16 バイトのメッセージで返信します。内容は、文字 G、スコア、残りのゲーム時間、残りの実時間(秒)です。

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

沼地ではゲーム時間が速く進み、どちらかの時間がなくなるとゲームは終了します。両方を使って、スタートに戻り始めるタイミングを判断しましょう。

E を送るとゲームが終了します。ロボットがスタートタイルにいて、壁のトークンを 1 つ以上識別していれば、10% の脱出ボーナス(Exit bonus)が得られます。

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)

次は、壁のトークンでトークンの見分け方を学びましょう。