Link da mensagem#
Introdução#
A classe message_link permite que dois EXP Brains comuniquem enviando mensagens de texto curtas com pequenos dados opcionais. Foi concebida para a coordenação entre robôs — como iniciar rotinas, partilhar resultados de sensores ou desencadear comportamentos noutro robô.
Cada utilização de send adiciona uma mensagem à fila do EXP Brain ligado, e a fila é lida pela ordem de chegada (FIFO). Se forem enviadas várias mensagens antes de o outro EXP Brain utilizar receive, estas serão armazenadas e devolvidas uma de cada vez, pela ordem em que foram enviadas. Como as mensagens podem ser colocadas em fila, enviar repetidamente o mesmo estado a cada iteração do ciclo pode criar uma acumulação; para lógica crítica em termos de tempo, envie apenas quando os valores se alteram.
Importante: Ambos os robots devem estar a executar projetos que utilizem message_link em simultâneo, caso contrário, não será enviada/recebida qualquer mensagem.
Construtores de Classes#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Destrutor de classes#
Destrói o objeto message_link ) e liberta os recursos associados.
virtual ~message_link();
Parâmetros#
Parâmetro |
Tipo |
Descrição |
|---|---|---|
|
|
A porta inteligente à qual o rádio V5 ou o cabo inteligente está ligado é escrita como |
|
|
O nome do link da mensagem. |
|
|
O tipo de ligação, seja
|
|
|
Indica se o objeto message_link é cablado.
|
Exemplo#
Código para o Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCódigo para o Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Funções de membro#
A classe message_link inclui as seguintes funções membro:
isLinked— Retorna se este Cérebro está ativamente ligado ao seu Cérebro emparelhado.send— Envia uma mensagem para o Brain emparelhado.receive— Aguarda e devolve a próxima mensagem recebida.received— Regista uma função a chamar sempre que uma nova mensagem é recebida.
Antes de chamar qualquer função membro de message_link , deve ser criada uma instância de message_link ), como se mostra abaixo:
Código para o Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCódigo para o Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
O método isLinked retorna se os EXP Brains num MessageLink estão emparelhados entre si.
bool isLinked();
Esta função não tem parâmetros.
Return ValuesEsta função retorna um valor booleano.
true– Os dois EXP Brains estão emparelhados e a comunicar neste link.false– Os dois cérebros EXP não estão emparelhados neste link.
É uma boa prática verificar sempre se os EXP Brains estão ligados no início de um projeto, antes de executar qualquer outro código.
ExamplesCódigo para o 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); }Código para o 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#
Envia uma mensagem através da ligação de ligação.
Available FunctionsParameters1 — Envia uma sequência de mensagens.
int32_t send( const char *message );2 — Envia uma string de mensagem com um
double.int32_t send( const char *message, double value );3 — Envia uma string de mensagem com um
int32_te umdouble.int32_t send( const char *message, int32_t index, double value );
Parâmetro |
Tipo |
Descrição |
|---|---|---|
|
|
A mensagem a enviar para o outro EXP Brain ligado. |
|
|
Um número inteiro para enviar ao outro EXP Brain ligado. |
|
|
Um valor double para enviar para o outro EXP Brain ligado. Os valores double são formatados com 4 casas decimais; se forem fornecidas menos casas decimais, são adicionados zeros à direita até que sejam apresentados 4. |
Esta função não devolve qualquer valor.
NotesSe apenas a mensagem message for enviada, o outro EXP Brain ligado receberá exatamente essa mensagem.
Se o valor value (e o índice index , se fornecido), o receptor Brain receberá uma única mensagem codificada que combina todos os campos por esta ordem: .message_index_value
A utilização de link.send(“string”, 1, 2.55) é recebido como .string_1_2.5500.
Código para o 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); }Código para o 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#
Recebe uma mensagem da ligação de ligação.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parâmetro |
Tipo |
Descrição |
|---|---|---|
|
|
O buffer para armazenar a mensagem recebida. |
|
|
O comprimento do buffer. |
|
|
Em milissegundos, o tempo de espera é de |
Esta função devolve o número de bytes recebidos.
Notesreceivereturns the next queued message from the other linked EXP Brain. Messages are read in FIFO order (oldest unread first). If the queue is empty whenreceiveis called, it waits up to the specifiedtimeoutfor a new message. If no message arrives in that window,receivereturns0, and any message sent afterward remains in the queue to be read the next timereceiveis used.Se o outro EXP Brain ligado enviar apenas uma string
string,receivee devolverá exactamente essa string.Se o outro EXP Brain ligado enviar um número inteiro e/ou de ponto flutuante,
receivee devolve uma única string codificada que combina todos os campos por esta ordem:.string_integer_floatPor exemplo, se o outro EXP Brain ligado utilizar
link.send(“string”, 1, 2.55), então a utilização delink.receive()devolve uma string codificada como.string_1_2.5500. Pode dividir esta string codificada (ver exemplos abaixo) para extrair o nome da mensagem, valores inteiros e de ponto flutuante.Se preferir evitar a divisão/análise manual, utilize
receivedpara registar um manipulador para um nome de mensagem específico; o manipulador recebe os valores enviados como argumentos.
A utilização de link.send(“string”, 1, 2.55) é recebido como .string_1_2.5500.
Código para o 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); }Código para o 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#
Regista uma função a ser chamada sempre que o EXP Brain receber uma mensagem enviada.
Available FunctionsParameters1 Regista um retorno de chamada para todas as mensagens recebidas (mensagem + valor).
void received( void (* callback)(const char *, const char *, double) );2 Regista um callback para todas as mensagens recebidas (mensagem + índice + valor).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Regista uma função de callback para uma mensagem específica (mensagem + valor).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Regista uma função de callback para uma mensagem específica (mensagem + índice + valor).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parâmetro |
Tipo |
Descrição |
|---|---|---|
|
|
O nome da mensagem a monitorizar. Se for omitido, o retorno de chamada será executado para todas as mensagens recebidas. |
|
Ponteiro de função |
Uma função que é executada quando uma mensagem é recebida. |
Esta função não devolve qualquer valor.
Callback Signature1 Recebe o nome do remetente, o nome da mensagem e o valor.
void callback(const char *, const char *, double)2 Recebe o nome do remetente, o nome da mensagem, o índice e o valor.
void callback(const char *, const char *, int32_t, double)
Tipo |
Descrição |
|---|---|
1st |
O nome do link do remetente. |
2nd |
Nome da mensagem recebida. |
|
O índice associado à mensagem. |
|
O valor associado à mensagem. |
Código para o Robot 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); } }Código para o 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); } }