ลิงก์ข้อความ#
การแนะนำ#
คลาส message_link ช่วยให้หุ่นยนต์ V5 Brain สองตัวสื่อสารกันได้โดยการส่งข้อความสตริงสั้นๆ พร้อมข้อมูลขนาดเล็กเพิ่มเติม ออกแบบมาเพื่อการประสานงานระหว่างหุ่นยนต์ เช่น การเริ่มต้นรูทีน การแบ่งปันผลลัพธ์จากเซ็นเซอร์ หรือการสั่งการให้หุ่นยนต์อีกตัวแสดงพฤติกรรมบางอย่าง
ทุกครั้งที่ใช้ send จะเพิ่มข้อความลงในคิวของ V5 Brain ที่เชื่อมโยง และคิวจะถูกอ่านแบบเข้าก่อนออกก่อน (FIFO) หากมีการส่งข้อความหลายข้อความก่อนที่ V5 Brain อีกตัวจะใช้ receive ข้อความเหล่านั้นจะถูกจัดเก็บและส่งคืนทีละข้อความตามลำดับที่ส่ง เนื่องจากข้อความสามารถอยู่ในคิวได้ การส่งสถานะเดียวกันซ้ำๆ ในแต่ละรอบอาจทำให้เกิดงานค้าง สำหรับตรรกะที่สำคัญต่อเวลา ให้ส่งเฉพาะเมื่อค่าเปลี่ยนแปลงเท่านั้น
สำคัญ: หุ่นยนต์ทั้งสองตัวต้องรันโปรเจกต์ที่ใช้ message_link พร้อมกัน มิฉะนั้นจะไม่มีการส่ง/รับข้อความใดๆ
ตัวสร้างคลาส#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
ตัวทำลายคลาส#
ทำลายอ็อบเจ็กต์ message_link จำนวน รายการ และปล่อยทรัพยากรที่เกี่ยวข้อง
virtual ~message_link();
พารามิเตอร์#
พารามิเตอร์ |
พิมพ์ |
คำอธิบาย |
|---|---|---|
|
|
พอร์ตอัจฉริยะที่เชื่อมต่อกับวิทยุ V5 หรือสายเคเบิลอัจฉริยะ จะเขียนในรูปแบบ |
|
|
ชื่อของลิงก์ข้อความ |
|
|
ประเภทของลิงก์ อาจเป็น
|
|
|
ตรวจสอบว่าอ็อบเจ็กต์ message_link เชื่อมต่อด้วยสายหรือไม่
|
ตัวอย่าง#
รหัสสำหรับหุ่นยนต์ตัวที่ 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredโค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
ฟังก์ชันสมาชิก#
คลาส message_link ประกอบด้วยฟังก์ชันสมาชิกต่อไปนี้:
isLinked— ส่งคืนว่าสมองนี้เชื่อมต่อกับสมองคู่ของมันอยู่หรือไม่send— ส่งข้อความไปยังสมองที่จับคู่กันreceive— รอและส่งคืนข้อความขาเข้าถัดไปreceived— ลงทะเบียนฟังก์ชันที่จะถูกเรียกเมื่อใดก็ตามที่ได้รับข้อความใหม่
ก่อนเรียกใช้ฟังก์ชันสมาชิก message_link ใดๆ จะต้องสร้างอิน แตนซ์ message_link ดังแสดงด้านล่าง:
รหัสสำหรับหุ่นยนต์ตัวที่ 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredโค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
เมธอด isLinked จะส่งคืนค่าว่า V5 Brains บน MessageLink นั้นจับคู่กันหรือไม่
bool isLinked();
ฟังก์ชันนี้ไม่มีพารามิเตอร์ใดๆ
Return Valuesฟังก์ชันนี้จะส่งคืนค่าบูลีน
true– สมอง V5 ทั้งสองตัวจับคู่กันและสื่อสารกันผ่านลิงก์นี้false– สมอง V5 ทั้งสองตัวไม่ได้จับคู่กันในลิงก์นี้
เป็นเรื่องที่ควรปฏิบัติเสมอให้แน่ใจว่าได้เชื่อมต่อ V5 Brains แล้วในตอนเริ่มต้นโปรเจ็กต์ ก่อนที่จะรันโค้ดใดๆ ต่อไป
Examplesรหัสสำหรับหุ่นยนต์ตัวที่ 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }โค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
send#
ส่งข้อความผ่านการเชื่อมต่อลิงก์
Available FunctionsParameters1 — ส่งข้อความสตริง
int32_t send( const char *message );2 — ส่งสตริงข้อความที่มีเลขฐาน
doubleสองตัวint32_t send( const char *message, double value );3 — ส่งสตริงข้อความที่มี
int32_tและdoubleint32_t send( const char *message, int32_t index, double value );
พารามิเตอร์ |
พิมพ์ |
คำอธิบาย |
|---|---|---|
|
|
ข้อความที่จะส่งไปยัง V5 Brain อีกเครื่องที่เชื่อมต่ออยู่ |
|
|
ตัวเลขจำนวนเต็มที่จะส่งไปยัง V5 Brain อีกตัวที่เชื่อมต่ออยู่ |
|
|
ค่าตัวเลขทศนิยม (double) ที่จะส่งไปยัง V5 Brain ที่เชื่อมต่ออยู่ ค่าตัวเลขทศนิยมจะถูกจัดรูปแบบให้มีทศนิยม 4 ตำแหน่ง หากระบุทศนิยมน้อยกว่านั้น จะมีการเพิ่มเลขศูนย์ต่อท้ายจนกว่าจะแสดงครบ 4 ตำแหน่ง |
ฟังก์ชันนี้ไม่ส่งค่าใดๆ กลับมา
Notesถ้าส่งข้อความ message เท่านั้น สมอง V5 ที่เชื่อมต่ออีกตัวจะได้รับข้อความนั้นเช่นกัน
ถ้าค่า value (และดัชนี index ถ้ามีการระบุไว้) สมองที่รับข้อความจะได้รับข้อความที่เข้ารหัสเพียงข้อความเดียวซึ่งรวมฟิลด์ทั้งหมดตามลำดับนี้: .message_index_value
เมื่อใช้ link.send(“string”, 1, 2.55) จะได้รับเป็น .string_1_2.5500.
รหัสสำหรับหุ่นยนต์ตัวที่ 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }โค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
receive#
รับข้อความจากการเชื่อมต่อลิงก์
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
พารามิเตอร์ |
พิมพ์ |
คำอธิบาย |
|---|---|---|
|
|
หน่วยความจำสำรองสำหรับจัดเก็บข้อความที่ได้รับ |
|
|
ความยาวของบัฟเฟอร์ |
|
|
ระยะเวลารอรับข้อความใหม่ในหน่วยมิลลิวินาที |
ฟังก์ชันนี้จะส่งคืนจำนวนไบต์ที่ได้รับ
Notesreceiveส่งคืนข้อความถัดไปที่อยู่ในคิวจาก V5 Brain ที่เชื่อมต่ออีกตัว ข้อความจะถูกอ่านตามลำดับ FIFO (ข้อความที่เก่าที่สุดที่ยังไม่ได้อ่านจะถูกอ่านก่อน) หากคิวว่างเมื่อเรียกใช้receiveระบบจะรอข้อความใหม่จนถึงเวลาหมดเวลาreceiveหากไม่มีข้อความใดมาถึงภายในช่วงเวลานั้นreceiveจะส่งคืนค่า0และข้อความใดๆ ที่ส่งมาหลังจากนั้นจะยังคงอยู่ในคิวเพื่อรออ่านในครั้งถัดไปที่ใช้timeoutหาก V5 Brain ที่เชื่อมต่ออีกตัวส่งสตริง
string,receiveจะส่งสตริงนั้นกลับมาหาก V5 Brain ตัวอื่นที่เชื่อมต่อส่งค่าจำนวนเต็มและ/หรือค่าทศนิยมมา
receiveและส่งคืนค่าสตริงที่เข้ารหัสเพียงค่าเดียวซึ่งรวมฟิลด์ทั้งหมดตามลำดับนี้:.string_integer_floatตัวอย่างเช่น หาก V5 Brain ที่เชื่อมโยงอีกตัวใช้
link.send(“string”, 1, 2.55)แล้วการใช้link.receive()จะส่งคืนสตริงที่เข้ารหัส เช่น.string_1_2.5500คุณสามารถแยกสตริงที่เข้ารหัสนี้ (ดูตัวอย่างด้านล่าง) เพื่อดึงชื่อข้อความ ค่าจำนวนเต็ม และค่าทศนิยมออกมาได้หากคุณต้องการหลีกเลี่ยงการแยก/วิเคราะห์ด้วยตนเอง ให้ใช้
receivedเพื่อลงทะเบียนตัวจัดการสำหรับชื่อข้อความเฉพาะ ตัวจัดการจะได้รับค่าที่ส่งมาเป็นอาร์กิวเมนต์
เมื่อใช้ link.send(“string”, 1, 2.55) จะได้รับเป็น .string_1_2.5500.
รหัสสำหรับหุ่นยนต์ตัวที่ 1
// Tell the other robot when the screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); // Continuously send if the screen is being pressed while (true){ if (Brain.Screen.pressing()){ link.send("pressed"); } else { link.send("released"); } wait(0.05, seconds); }โค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Display if the other robot's screen is being pressed // Create the link message_link link = message_link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()){ wait(0.1, seconds); } // Continuously check if Robot 1 has sent "pressed" while (true){ Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); char msg[32] = {0}; // buffer for incoming message int32_t n = link.receive(msg, sizeof(msg), 100); // wait up to 100ms if (n > 0 && strcmp(msg, "pressed") == 0) { Brain.Screen.newLine(); Brain.Screen.print("Manager is being pressed!"); } wait(0.05, seconds); }
received#
ลงทะเบียนฟังก์ชันที่จะถูกเรียกใช้ทุกครั้งที่ V5 Brain ได้รับข้อความที่ส่งมา
Available FunctionsParameters1 ลงทะเบียนฟังก์ชันเรียกกลับสำหรับข้อความที่ได้รับทั้งหมด (ข้อความ + ค่า)
void received( void (* callback)(const char *, const char *, double) );2 ลงทะเบียนฟังก์ชันเรียกกลับสำหรับข้อความที่ได้รับทั้งหมด (ข้อความ + ดัชนี + ค่า)
void received( void (* callback)(const char *, const char *, int32_t, double) );3 ลงทะเบียนฟังก์ชันเรียกกลับสำหรับข้อความเฉพาะ (ข้อความ + ค่า)
void received( const char *message, void (* callback)(const char *, const char *, double) );4 ลงทะเบียนฟังก์ชันเรียกกลับสำหรับข้อความเฉพาะ (ข้อความ + ดัชนี + ค่า)
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
พารามิเตอร์ |
พิมพ์ |
คำอธิบาย |
|---|---|---|
|
|
ชื่อข้อความที่จะรอรับ หากละเว้น ระบบจะเรียกใช้ฟังก์ชันเรียกกลับสำหรับข้อความที่ได้รับทั้งหมด |
|
|
ฟังก์ชันที่จะทำงานเมื่อได้รับข้อความ |
ฟังก์ชันนี้ไม่ส่งค่าใดๆ กลับมา
Callback Signature1 รับชื่อผู้ส่ง ชื่อข้อความ และค่าของข้อความ
void callback(const char *, const char *, double)2 รับชื่อผู้ส่ง ชื่อข้อความ ดัชนี และค่า
void callback(const char *, const char *, int32_t, double)
พิมพ์ |
คำอธิบาย |
|---|---|
1st |
ชื่อลิงก์ของผู้ส่ง |
2nd |
ชื่อข้อความที่ได้รับ |
|
ดัชนีที่เกี่ยวข้องกับข้อความนั้น |
|
คุณค่าที่เกี่ยวข้องกับข้อความ |
รหัสสำหรับหุ่นยนต์ตัวที่ 1
// Create the link. message_link link(PORT1, "LeftRightLink", linkType::manager, true); // Send whether screen is pressed on left or right. void screen_pressed() { if (Brain.Screen.xPosition() < 240) { link.send("left"); } else { link.send("right"); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Do not run code UNTIL the Brains are linked. while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); Brain.Screen.pressed(screen_pressed); while (true) { wait(10, msec); } }โค้ดสำหรับหุ่นยนต์ตัวที่ 2
// Create variable to track where screen is pressed. int lastPress = 0; // Update the variable whenever a new message is received. void message_received(const char* message, const char* linkname, double timestamp) { if (strcmp(message, "left") == 0) lastPress = 1; if (strcmp(message, "right") == 0) lastPress = 2; } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link. message_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked. while (!link.isLinked()) { wait(0.1, seconds); } link.received(message_received); // Display if Robot 1's screen was pressed on the left or right while (true) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); if (lastPress == 1) { Brain.Screen.print("Manager pressed LEFT"); } else if (lastPress == 2) { Brain.Screen.print("Manager pressed RIGHT"); } else { Brain.Screen.print("Waiting..."); } wait(0.1, seconds); } }