ข้ามไปยังเนื้อหา
ไทย

การสื่อสาร

โปรแกรมของคุณสื่อสารกับเกมผ่านอุปกรณ์สองชิ้นที่หุ่นยนต์ทุกตัวมี:

  • ตัวส่ง (emitter) ส่งข้อความไปยังเกม ไม่จำเป็นต้องเปิดใช้งาน
  • ตัวรับ (receiver) รับข้อความจากเกม ให้เปิดใช้งานเหมือนเซนเซอร์

แต่ละหัวข้อด้านล่างเป็นโปรแกรมที่สมบูรณ์สำหรับหุ่นยนต์เริ่มต้น ข้อความทั้งหมดอยู่ในข้อมูลอ้างอิงข้อความ

ในการทำคะแนนจากผู้ประสบภัยแบบตัวอักษร (letter victim) หรือเป้าหมายเชิงรับรู้ (cognitive target) หุ่นยนต์ต้อง:

  1. หยุดนิ่งนานกว่า 1 วินาที ใกล้กับสัญลักษณ์ Erebus จะไม่รับการรายงานหากหุ่นยนต์เคลื่อนที่ภายใน 1 วินาทีที่ผ่านมา
  2. ส่งตำแหน่งและชนิดของสัญลักษณ์: X และ Z เป็นเซนติเมตร และชนิดเป็นตัวอักษรหนึ่งตัว
สัญลักษณ์บนผนัง ชนิด
ผู้ประสบภัยแบบตัวอักษร Φ (บาดเจ็บ) H
ผู้ประสบภัยแบบตัวอักษร Ψ (อาการคงที่) S
ผู้ประสบภัยแบบตัวอักษร Ω (ไม่บาดเจ็บ) U
เป้าหมายเชิงรับรู้ ผลรวม 0 (ก๊าซไวไฟ) F
เป้าหมายเชิงรับรู้ ผลรวม 1 (สารพิษ) P
เป้าหมายเชิงรับรู้ ผลรวม 2 (สารกัดกร่อน) C
เป้าหมายเชิงรับรู้ ผลรวม 3 (สารเปอร์ออกไซด์อินทรีย์) 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 ซม.

รันโปรแกรมนี้ที่จุดเริ่มต้นของ world1.wbt: ที่นั่นไม่มีสัญลักษณ์ ประวัติของหน้าต่างควบคุมจึงแสดง Misidentification of Victim -5 การรายงานผิด รวมถึงการรายงานของปลอม จะเสีย 5 คะแนน และสัญลักษณ์แต่ละอันได้คะแนนเพียงครั้งเดียว

ประวัติของหน้าต่างควบคุมหลังจากการรายงานผิดและการส่งแผนที่

เมื่อหุ่นยนต์ติดอยู่ การไม่มีความคืบหน้า (lack of progress) จะย้ายหุ่นยนต์กลับไปยังจุดตรวจล่าสุดและเสีย 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 เพื่อจบเกม หากหุ่นยนต์อยู่บนช่องเริ่มต้นและได้ระบุสัญลักษณ์บนผนังไปแล้วอย่างน้อยหนึ่งอัน จะได้รับโบนัสออกจากสนาม (exit bonus) 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)

ขั้นต่อไป เรียนรู้การแยกแยะสัญลักษณ์ในสัญลักษณ์บนผนัง