Посилання на повідомлення#
Вступ#
Клас message_link дозволяє двом роботам V5 Brains взаємодіяти, надсилаючи короткі рядкові повідомлення з необов’язковими невеликими даними. Він розроблений для координації між роботами, наприклад, для запуску підпрограм, обміну результатами датчиків або запуску поведінки в іншого робота.
Кожне використання 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— Повертає, чи цей Brain активно підключений до свого парного Brain.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 Brains не спарені на цьому зв’язку.
Гарною практикою є завжди перевіряти, чи підключені 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таdouble.int32_t send( const char *message, int32_t index, double value );
Параметр |
Тип |
Опис |
|---|---|---|
|
|
Повідомлення, яке потрібно надіслати іншому підключеному мозку V5. |
|
|
Ціле число для надсилання іншому підключеному V5 Brain. |
|
|
Подвійний номер для надсилання до іншого підключеного V5 Brain. Подвійні номери форматуються до 4 знаків після коми; якщо вказано менше знаків після коми, додаються завершальні нулі, доки не буде показано 4. |
Ця функція не повертає жодних значень.
NotesЯкщо надіслано лише message , інший підключений V5 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повертає наступне повідомлення з черги від іншого підключеного V5 Brain. Повідомлення зчитуються в порядку FIFO (спочатку найстаріші непрочитані). Якщо черга порожня, коли викликаєтьсяreceive, вона очікує нового повідомлення до зазначеногоtimeoutЯкщо в цьому вікні повідомлення не надходить,receiveповертає0, і будь-яке повідомлення, надіслане після цього, залишається в черзі для зчитування під час наступного використанняreceive.Якщо інший пов’язаний 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); } }