Liên kết tin nhắn#
Giới thiệu#
Lớp message_link cho phép hai bộ xử lý V5 Brain giao tiếp bằng cách gửi các tin nhắn chuỗi ngắn kèm theo dữ liệu nhỏ tùy chọn. Nó được thiết kế để phối hợp giữa các robot với nhau — chẳng hạn như khởi động các quy trình, chia sẻ kết quả cảm biến hoặc kích hoạt các hành vi trên một robot khác.
Mỗi lần sử dụng send sẽ thêm một tin nhắn vào hàng đợi của V5 Brain được liên kết, và hàng đợi được đọc theo thứ tự vào trước ra trước (FIFO). Nếu nhiều tin nhắn được gửi trước khi V5 Brain khác sử dụng receive, chúng sẽ được lưu trữ và trả về từng tin nhắn một theo thứ tự chúng được gửi. Vì tin nhắn có thể được xếp hàng đợi, việc liên tục gửi cùng một trạng thái trong mỗi vòng lặp có thể tạo ra sự tắc nghẽn; đối với logic cần xử lý nhanh, chỉ gửi khi giá trị thay đổi.
Quan trọng: Cả hai robot phải cùng lúc chạy các dự án sử dụng message_link , nếu không sẽ không có tin nhắn nào được gửi/nhận.
Hàm tạo lớp#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Lớp Destructor#
Hủy đối tượng message_link và giải phóng các tài nguyên liên quan.
virtual ~message_link();
Thông số#
Tham số |
Kiểu |
Sự miêu tả |
|---|---|---|
|
|
Cổng thông minh mà bộ thu phát V5 hoặc cáp thông minh được kết nối, được viết dưới dạng |
|
|
Tên của liên kết tin nhắn. |
|
|
Loại liên kết, hoặc
|
|
|
Cho biết đối tượng message_link có kết nối dây hay không.
|
Ví dụ#
Mã lệnh cho Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredMã lệnh cho Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Chức năng thành viên#
Lớp message_link bao gồm các hàm thành viên sau:
isLinked— Trả về liệu Brain này có đang được kết nối tích cực với Brain được ghép nối của nó hay không.send— Gửi tin nhắn tới Brain được ghép nối.receive— Chờ và trả về tin nhắn đến tiếp theo.received— Đăng ký một hàm được gọi bất cứ khi nào nhận được tin nhắn mới.
Trước khi gọi bất kỳ hàm thành viên message_link , cần phải tạo một thể hiện message_link , như được hiển thị bên dưới:
Mã lệnh cho Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredMã lệnh cho Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Phương thức isLinked trả về giá trị cho biết liệu các V5 Brains trên MessageLink có được ghép nối với nhau hay không.
bool isLinked();
Hàm này không có tham số nào.
Return ValuesHàm này trả về một giá trị boolean.
true– Hai bộ não V5 được ghép nối và đang giao tiếp trên liên kết này.false– Hai bộ não V5 không được ghép nối trên liên kết này.
Nên kiểm tra kỹ xem các thiết bị V5 Brains đã được liên kết chưa trước khi chạy bất kỳ đoạn mã nào khác trong quá trình khởi tạo dự án.
ExamplesMã lệnh cho Robot 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); }Mã lệnh cho Robot 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#
Gửi tin nhắn qua kết nối liên kết.
Available FunctionsParameters1 — Gửi một chuỗi tin nhắn.
int32_t send( const char *message );2 — Gửi một chuỗi tin nhắn với
double.int32_t send( const char *message, double value );3 — Gửi một chuỗi tin nhắn với
int32_tvàdouble.int32_t send( const char *message, int32_t index, double value );
Tham số |
Kiểu |
Sự miêu tả |
|---|---|---|
|
|
Thông điệp cần gửi đến bộ não V5 được liên kết khác. |
|
|
Một số nguyên cần gửi đến bộ não V5 được liên kết khác. |
|
|
Một giá trị kiểu double được gửi đến bộ xử lý V5 Brain còn lại. Giá trị double được định dạng với 4 chữ số thập phân; nếu cung cấp ít hơn số chữ số thập phân, các số 0 ở cuối sẽ được thêm vào cho đến khi hiển thị đủ 4 chữ số. |
Hàm này không trả về bất kỳ giá trị nào.
NotesNếu chỉ có tin nhắn message được gửi đi, thì bộ xử lý V5 Brain được liên kết còn lại sẽ nhận được chính xác tin nhắn đó.
Nếu giá trị value (và chỉ số index nếu được cung cấp), bộ não nhận được một thông điệp được mã hóa duy nhất kết hợp tất cả các trường theo thứ tự này: .message_index_value
Sử dụng link.send(“string”, 1, 2.55) được nhận là .string_1_2.5500.
Mã lệnh cho Robot 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); }Mã lệnh cho Robot 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#
Nhận được tin nhắn từ kết nối liên kết.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Tham số |
Kiểu |
Sự miêu tả |
|---|---|---|
|
|
Bộ đệm để lưu trữ thông điệp đã nhận. |
|
|
Độ dài của vùng đệm. |
|
|
Thời gian chờ (tính bằng mili giây): |
Hàm này trả về số byte đã nhận được.
Notesreceivetrả về tin nhắn tiếp theo trong hàng đợi từ bộ xử lý V5 Brain được liên kết khác. Tin nhắn được đọc theo thứ tự FIFO (tin nhắn cũ nhất chưa đọc trước). Nếu hàng đợi trống khireceiveđược gọi, nó sẽ đợi tối đa đến thời gian chờreceiveđể nhận tin nhắn mới. Nếu không có tin nhắn nào đến trong khoảng thời gian đó,receivetrả về0, và bất kỳ tin nhắn nào được gửi sau đó vẫn nằm trong hàng đợi để được đọc vào lần tiếp theotimeoutđược sử dụng.Nếu bộ não V5 được liên kết khác chỉ gửi chuỗi
string,receivevà trả về chính xác chuỗi đó.Nếu bộ xử lý V5 Brain được liên kết khác gửi một số nguyên và/hoặc số thực, thì
receivesẽ trả về một chuỗi được mã hóa duy nhất kết hợp tất cả các trường theo thứ tự này:.string_integer_floatVí dụ, nếu V5 Brain được liên kết khác sử dụng
link.send(“string”, 1, 2.55), thì việc sử dụnglink.receive()sẽ trả về một chuỗi được mã hóa như.string_1_2.5500. Bạn có thể tách chuỗi được mã hóa này (xem các ví dụ bên dưới) để trích xuất tên thông báo, giá trị số nguyên và số thực.Nếu bạn muốn tránh việc tách/phân tích cú pháp thủ công, hãy sử dụng
receivedđể đăng ký trình xử lý cho một tên tin nhắn cụ thể; trình xử lý sẽ nhận các giá trị đã gửi dưới dạng đối số.
Sử dụng link.send(“string”, 1, 2.55) được nhận là .string_1_2.5500.
Mã lệnh cho Robot 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); }Mã lệnh cho Robot 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#
Đăng ký một hàm để được gọi bất cứ khi nào bộ xử lý V5 nhận được một tin nhắn đã gửi.
Available FunctionsParameters1 Đăng ký hàm gọi lại cho tất cả các tin nhắn đã nhận (tin nhắn + giá trị).
void received( void (* callback)(const char *, const char *, double) );2 Đăng ký hàm gọi lại cho tất cả các tin nhắn đã nhận (tin nhắn + chỉ số + giá trị).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Đăng ký hàm gọi lại cho một thông báo cụ thể (thông báo + giá trị).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Đăng ký hàm gọi lại cho một thông báo cụ thể (thông báo + chỉ số + giá trị).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Tham số |
Kiểu |
Sự miêu tả |
|---|---|---|
|
|
Tên tin nhắn cần lắng nghe. Nếu bỏ qua, hàm callback sẽ chạy cho tất cả các tin nhắn nhận được. |
|
|
Một hàm được thực thi khi nhận được tin nhắn. |
Hàm này không trả về bất kỳ giá trị nào.
Callback Signature1 Nhận tên người gửi, tên tin nhắn và giá trị.
void callback(const char *, const char *, double)2 Nhận tên người gửi, tên tin nhắn, chỉ mục và giá trị.
void callback(const char *, const char *, int32_t, double)
Kiểu |
Sự miêu tả |
|---|---|
1st |
Tên liên kết người gửi. |
2nd |
Tên tin nhắn đã nhận được. |
|
Chỉ số liên quan đến thông báo. |
|
Giá trị gắn liền với thông điệp. |
Mã lệnh cho Robot 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); } }Mã lệnh cho Robot 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); } }