Komunikasi
Programmu berkomunikasi dengan permainan melalui dua perangkat yang dimiliki setiap robot:
- Emitter mengirim pesan ke permainan. Perangkat ini tidak perlu diaktifkan.
- Receiver menerima pesan dari permainan. Aktifkan receiver seperti mengaktifkan sensor.
Setiap bagian di bawah ini adalah program lengkap untuk robot pemula. Semua pesan tercantum di Referensi pesan.
Mencetak poin dari penanda dinding
Section titled “Mencetak poin dari penanda dinding”Untuk mencetak poin dari korban huruf (letter victim) atau target kognitif (cognitive target), robot harus:
- Berhenti lebih dari 1 detik di dekat penanda. Erebus mengabaikan laporan jika robot bergerak dalam satu detik terakhir.
- Mengirim posisi dan jenis penanda: X dan Z dalam sentimeter, dan jenisnya sebagai satu huruf.
| Penanda dinding | Jenis |
|---|---|
| Korban huruf Φ (terluka) | H |
| Korban huruf Ψ (stabil) | S |
| Korban huruf Ω (tidak terluka) | U |
| Target kognitif, jumlah 0 (Gas Mudah Terbakar) | F |
| Target kognitif, jumlah 1 (Racun) | P |
| Target kognitif, jumlah 2 (Korosif) | C |
| Target kognitif, jumlah 3 (Peroksida Organik) | O |
Jenisnya berupa huruf, meskipun sejak 2026 korban menampilkan simbol. GPS memberikan nilai dalam meter, jadi kalikan dengan 100.
from controller import Robotimport 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 isprint("Reported")#include <iostream>#include <cmath>#include <cstring>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/GPS.hpp>#include <webots/Motor.hpp>
using namespace webots;
Robot *robot;Emitter *emitter;GPS *gps;Motor *leftWheel, *rightWheel;int timeStep;
void wait(double seconds) { double start = robot->getTime(); while (robot->step(timeStep) != -1) { if (robot->getTime() - start >= seconds) break; }}
void report(char 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 int position[2] = {(int)(gps->getValues()[0] * 100), (int)(gps->getValues()[2] * 100)}; char message[9]; memcpy(message, position, sizeof(position)); message[8] = tokenType; emitter->send(message, sizeof(message)); robot->step(timeStep);}
int main() { robot = new Robot(); timeStep = (int)robot->getBasicTimeStep();
emitter = robot->getEmitter("emitter"); // Always on the robot. It does not need to be enabled. gps = robot->getGPS("gps"); gps->enable(timeStep); leftWheel = robot->getMotor("left wheel motor"); rightWheel = robot->getMotor("right wheel motor"); leftWheel->setPosition(INFINITY); rightWheel->setPosition(INFINITY);
report('H'); // Reports a harmed victim (Φ) where the robot is std::cout << "Reported" << std::endl;
delete robot; return 0;}Robot harus berada di sisi dinding yang sama dengan penanda, dan baik robot maupun posisi yang kamu kirim harus dekat dengan penanda itu. Aturan mensyaratkan jarak paling jauh setengah ubin, jadi usahakan agar tidak lebih dari itu. Erebus v26.1 memeriksa jarak 9 cm.
Jalankan program ini di awal world1.wbt: tidak ada penanda di sana, jadi riwayat jendela kontrol menampilkan Misidentification of Victim -5. Laporan yang salah, termasuk laporan penanda palsu, mengurangi 5 poin, dan setiap penanda hanya bisa dihitung sekali.

Kurangnya kemajuan
Section titled “Kurangnya kemajuan”Saat robot terjebak, kurangnya kemajuan (lack of progress) memindahkannya kembali ke checkpoint terakhir dan mengurangi 5 poin. Ini terjadi otomatis setelah robot tidak bergerak selama 20 detik, dan programmu juga bisa memicunya dengan mengirim L. Setiap kali terjadi, permainan mengirim L ke robot, agar programmu tahu posisinya sudah berubah.
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")receiver = robot.getDevice("receiver")receiver.enable(timeStep) # The receiver must be enabled
askedAt = Nonewhile 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()#include <iostream>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/Receiver.hpp>
using namespace webots;using namespace std;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep();
Emitter *emitter = robot->getEmitter("emitter"); Receiver *receiver = robot->getReceiver("receiver"); receiver->enable(timeStep); // The receiver must be enabled
bool asked = false; while (robot->step(timeStep) != -1) { // Call a lack of progress once, after 2 seconds if (!asked && robot->getTime() > 2) { char message = 'L'; emitter->send(&message, 1); asked = true; }
// Listen for messages from the game while (receiver->getQueueLength() > 0) { const char *data = (const char *)receiver->getData(); if (receiver->getDataSize() == 1 && data[0] == 'L') cout << "Lack of progress! The robot is back at the last checkpoint." << endl; receiver->nextPacket(); } }
delete robot; return 0;}Receiver bisa menerima pesan yang berbeda-beda, jadi periksa panjang setiap pesan sebelum membacanya, seperti pada contoh.
Informasi permainan
Section titled “Informasi permainan”Kirim G untuk mendapatkan skor dan sisa waktu. Permainan membalas dengan pesan 16 byte: huruf G, skor, sisa waktu permainan, dan sisa waktu nyata, dalam detik.
from controller import Robotimport struct
robot = Robot()timeStep = int(robot.getBasicTimeStep())
emitter = robot.getDevice("emitter")receiver = robot.getDevice("receiver")receiver.enable(timeStep)
lastAsked = 0while 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()#include <iostream>#include <cstring>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>#include <webots/Receiver.hpp>
using namespace webots;using namespace std;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep();
Emitter *emitter = robot->getEmitter("emitter"); Receiver *receiver = robot->getReceiver("receiver"); receiver->enable(timeStep);
double lastAsked = 0; while (robot->step(timeStep) != -1) { // Ask for the game information once a second if (robot->getTime() - lastAsked > 1) { char message = 'G'; emitter->send(&message, 1); lastAsked = robot->getTime(); }
while (receiver->getQueueLength() > 0) { const char *data = (const char *)receiver->getData(); if (receiver->getDataSize() == 16 && data[0] == 'G') { // The game information is 16 bytes long float score; int timeLeft, realTimeLeft; memcpy(&score, data + 4, 4); memcpy(&timeLeft, data + 8, 4); memcpy(&realTimeLeft, data + 12, 4); cout << "Score: " << score << " Time left: " << timeLeft << " s Real time left: " << realTimeLeft << " s" << endl; } receiver->nextPacket(); } }
delete robot; return 0;}Waktu permainan berjalan lebih cepat di rawa, dan permainan berakhir saat salah satu waktu habis. Gunakan keduanya untuk menentukan kapan robot harus kembali ke titik awal.
Mengakhiri permainan
Section titled “Mengakhiri permainan”Kirim E untuk mengakhiri permainan. Jika robot berada di ubin awal dan sudah mengidentifikasi minimal satu penanda dinding, robot mendapat bonus keluar (exit bonus) 10%.
from controller import Robotimport 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)#include <iostream>#include <webots/Robot.hpp>#include <webots/Emitter.hpp>
using namespace webots;
int main() { Robot *robot = new Robot(); int timeStep = (int)robot->getBasicTimeStep(); Emitter *emitter = robot->getEmitter("emitter");
robot->step(timeStep); std::cout << "Ending the game" << std::endl; // 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. char message = 'E'; emitter->send(&message, 1); robot->step(timeStep);
delete robot; return 0;}Selanjutnya, pelajari cara membedakan jenis-jenis penanda di Penanda dinding.
