訊息連結#
介紹#
message_link 類別允許兩個 EXP Brain 透過發送帶有可選小資料的短字串訊息進行通訊。它專為機器人間的協調而設計,例如啟動程式、共享感測器結果或觸發另一個機器人的行為。
每次使用 send 都會在關聯的 EXP Brain 的佇列中加入一則訊息,佇列採用先進先出 (FIFO) 的讀取方式。如果在另一個 EXP Brain 使用 receive 之前發送了多個訊息,這些訊息將被存儲,並按發送順序逐條返回。由於訊息可以排隊,因此在每次循環中重複發送相同的狀態可能會導致積壓;對於時間關鍵型邏輯,僅當值發生變化時才發送訊息。
重要提示:兩個機器人必須同時執行使用 message_link 項目,否則將不會發送/接收任何訊息。
類別建構函數#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
類別析構函數#
銷毀 message_link 物件並釋放相關資源。
virtual ~message_link();
參數#
範圍 |
類型 |
描述 |
|---|---|---|
|
|
V5 無線電或智慧電纜連接的智慧型端口,記為 |
|
|
訊息連結的名稱。 |
|
|
The type of link, either
|
|
|
Whether the message_link object is wired.
|
例子#
機器人 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 方法傳回 MessageLink 上的 EXP Brains 是否彼此配對。
bool isLinked();
此函數沒有任何參數。
Return Values此函數傳回一個布林值。
true– 兩個 EXP 大腦已配對並透過此連結進行通訊。false– 此連結中的兩個 EXP 大腦未配對。
在專案開始時,運行任何其他程式碼之前,最好始終檢查 EXP 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和double的訊息字串。int32_t send( const char *message, int32_t index, double value );
範圍 |
類型 |
描述 |
|---|---|---|
|
|
要傳送給另一個已連線的 EXP Brain 的訊息。 |
|
|
要傳送給另一個已連接的 EXP Brain 的整數。 |
|
|
發送給另一個已連接的 EXP Brain 的雙精度浮點數。雙精確度浮點數預設顯示 4 位小數;如果提供的小數位數少於 4 位,則會在最後加上零,直到顯示 4 位為止。 |
此函數不傳回任何值。
Notes如果只傳送 message ,則另一個連線的 EXP Brain 會收到完全相同的訊息。
如果包含 value (以及提供的 index ),則接收端 Brain 將收到一則編碼後的訊息,該訊息會依照下列順序組合所有欄位: .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傳回來自另一個已連線的 EXP Brain 的下一封已排隊的訊息。訊息以先進先出 (FIFO) 順序讀取(最舊的未讀訊息優先)。如果在呼叫receive時佇列為空,則會等待最多指定的receive時間來接收新訊息。如果在該時間內沒有訊息到達,receive返回0,之後發送的任何訊息都將保留在佇列中,以便在下次使用timeout時讀取。如果另一個連結的 EXP Brain 只發送了字串
stringreceive回傳該字串。如果另一個關聯的 EXP Brain 發送的是整數和/或浮點數,
receive傳回編碼字串,該字串會依以下順序組合所有欄位:.string_integer_float例如,如果另一個連結的 EXP 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#
註冊一個函數,當 EXP 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 的程式碼
// 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(); // Create the link message_link link(PORT1, "LeftRightLink", 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"); 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); } }