Enlace del mensaje#
Introducción#
La clase message_link permite que dos cerebros EXP se comuniquen enviando mensajes de cadena corta con datos pequeños opcionales. Está diseñado para la coordinación de robot a robot, como iniciar rutinas, compartir resultados de sensores o activar comportamientos en otro robot.
Cada uso de send agrega un mensaje a la cola del cerebro EXP vinculado, y la cola se lee primero en entrar, primero en salir (FIFO). Si se envían varios mensajes antes de que el otro EXP Brain use receive, se almacenarán y devolverán uno a la vez en el orden en que se enviaron. Debido a que los mensajes pueden ponerse en cola, enviar repetidamente el mismo estado en cada bucle puede crear retraso; para la lógica de tiempo crítico, envíe solo cuando cambien los valores.
Importante: Ambos robots deben estar ejecutando proyectos que usen message_link al mismo tiempo, o no se enviarán/recibirán mensajes.
Constructores de clase#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Destructor de clase#
Destruye el objeto message_link y libera los recursos asociados.
virtual ~message_link();
Parámetros#
Parámetro |
Tipo |
Descripción |
|---|---|---|
|
|
El puerto inteligente al que está conectado la radio V5, o el cable inteligente, escrito como |
|
|
El nombre del enlace del mensaje. |
|
|
El tipo de enlace, ya sea
|
|
|
Si el objeto message_link está cableado.
|
Ejemplo#
Código para 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 Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Funciones de los miembros#
La clase message_link incluye las siguientes funciones de miembro:
isLinked— Devuelve si este cerebro está conectado activamente a su cerebro emparejado.send— Envía un mensaje al cerebro emparejado.receive— Espera y devuelve el siguiente mensaje entrante.received— Registra una función que se llamará cada vez que se reciba un nuevo mensaje.
Antes de llamar a cualquier función miembro de message_link, se debe crear una instancia de message_link, como se muestra a continuación:
Código para 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 Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
isLinked el método isLinked devuelve si los cerebros EXP en un MessageLink están emparejados entre sí.
bool isLinked();
Esta función no tiene ningún parámetro.
Return ValuesEsta función devuelve un valor booleano.
true– Los dos cerebros EXP están emparejados y se comunican en este enlace.false– Los dos cerebros EXP no están emparejados en este enlace.
Es una buena práctica verificar siempre para asegurarse de que los cerebros EXP estén vinculados al comienzo de un proyecto antes de ejecutar cualquier código adicional.
ExamplesCódigo para 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 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#
Envía un mensaje a través de la conexión de enlace.
Available FunctionsParameters1 — Envía una cadena de mensajes.
int32_t send( const char *message );2 — Envía una cadena de mensajes con un
double.int32_t send( const char *message, double value );3 — Envía una cadena de mensajes con un
int32_ty undouble.int32_t send( const char *message, int32_t index, double value );
Parámetro |
Tipo |
Descripción |
|---|---|---|
|
|
El mensaje a enviar al otro cerebro EXP vinculado. |
|
|
Un entero para enviar al otro cerebro EXP vinculado. |
|
|
Un doble para enviar al otro cerebro EXP vinculado. Los dobles se formatean con 4 decimales; si se proporcionan menos decimales, se agregan ceros al final hasta que se muestren 4. |
Esta función no devuelve ningún valor.
NotesSi solo se envía el mensaje message , el otro EXP Brain vinculado recibe ese mismo mensaje.
Si se incluyen el value (y el index si se proporciona), el cerebro receptor recibe un único mensaje codificado que combina todos los campos en este orden: .message_index_value
Usando link.send(“string”, 1, 2.55) se recibe como .string_1_2.5500.
Código para 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 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#
Recibe un mensaje de la conexión de enlace.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parámetro |
Tipo |
Descripción |
|---|---|---|
|
|
El búfer para almacenar el mensaje recibido. |
|
|
La longitud del búfer. |
|
|
Cuánto tiempo en milisegundos |
Esta función devuelve el número de bytes recibidos.
Notesreceivedevuelve el siguiente mensaje en cola del otro EXP Brain vinculado. Los mensajes se leen en orden FIFO (el más antiguo sin leer primero). Si la cola está vacía cuando se llama areceive, espera hasta el tiempo de esperareceivepara un nuevo mensaje. Si no llega ningún mensaje en ese intervalo,receivedevuelve0, y cualquier mensaje enviado posteriormente permanece en la cola para ser leído la próxima vez que se utilicetimeout.Si el otro cerebro EXP vinculado envió solo una
string,receivedevuelve esa cadena exacta.Si el otro cerebro EXP vinculado envió un número entero y/o flotante,
receivedevuelve una sola cadena codificada que combina todos los campos en este orden:.string_integer_floatPor ejemplo, si el otro cerebro EXP vinculado usa
link.send(“string”, 1, 2.55), entonceslink.receive()devuelve una cadena codificada como.string_1_2.5500. Puede dividir esta cadena codificada (consulte los ejemplos a continuación) para extraer el nombre del mensaje, el número entero y los valores flotantes.Si prefiere evitar la división/análisis manual, use
receivedpara registrar un controlador para un nombre de mensaje específico; el controlador recibe los valores enviados como argumentos.
Usando link.send(“string”, 1, 2.55) se recibe como .string_1_2.5500.
Código para 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 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#
Registra una función para ser llamada cada vez que el Cerebro EXP recibe un mensaje enviado.
Available FunctionsParameters1 Registra una devolución de llamada para todos los mensajes recibidos (mensaje + valor).
void received( void (* callback)(const char *, const char *, double) );2 Registra una devolución de llamada para todos los mensajes recibidos (mensaje + índice + valor).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Registra una devolución de llamada para un mensaje específico (mensaje + valor).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Registra una devolución de llamada para un mensaje específico (mensaje + índice + valor).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parámetro |
Tipo |
Descripción |
|---|---|---|
|
|
El nombre del mensaje para escuchar. Si se omite, la devolución de llamada se ejecuta para todos los mensajes recibidos. |
|
Puntero de función |
Una función que se ejecuta cuando se recibe un mensaje. |
Esta función no devuelve ningún valor.
Callback Signature1 Recibe el nombre del remitente, el nombre del mensaje y el valor.
void callback(const char *, const char *, double)2 Recibe el nombre del remitente, el nombre del mensaje, el índice y el valor.
void callback(const char *, const char *, int32_t, double)
Tipo |
Descripción |
|---|---|
1st |
El nombre del enlace del remitente. |
2nd |
El nombre del mensaje recibido. |
|
El índice asociado al mensaje. |
|
El valor asociado al mensaje. |
Código para 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 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); } }