Ссылка на сообщение#
Введение#
Класс 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 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 необходимо создать экземпляр 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 возвращает значение, указывающее, связаны ли элементы EXP Brains в объекте MessageLink друг с другом.
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. |
|
|
Число типа double для отправки на другой связанный модуль EXP Brain. Число типа double форматируется до 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. Если в течение этого времени сообщение не поступает,timeoutвозвращает0, и любое сообщение, отправленное после этого, остается в очереди для чтения при следующем использовании функцииreceive.Если другой связанный EXP Brain отправил только строку
string,receiveвернут именно эту строку.Если другой связанный 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); } }