Meddelandelänk#
Introduktion#
Klassen message_link låter två EXP-hjärnor kommunicera genom att skicka korta strängmeddelanden med valfri liten data. Den är utformad för robot-till-robot-koordination – som att starta rutiner, dela sensorresultat eller utlösa beteenden på en annan robot.
Varje gång man använder send läggs ett meddelande till i den länkade EXP Brain-kön, och kön läses först in, först ut (FIFO). Om flera meddelanden skickas innan den andra EXP Brain använder receive, kommer de att lagras och returneras ett i taget i den ordning de skickades. Eftersom meddelanden kan köa kan det skapa en eftersläpning om man upprepar sändningar av samma status i varje loop; för tidskritisk logik, skicka endast när värdena ändras.
Viktigt: Båda robotarna måste köra projekt som använder message_link samtidigt, annars skickas/tas inga meddelanden emot.
Klasskonstruktörer#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Klassförstörare#
Förstör objektet message_link och frigör tillhörande resurser.
virtual ~message_link();
Parametrar#
Parameter |
Typ |
Beskrivning |
|---|---|---|
|
|
Smart Port som V5-radion, eller Smart Cable, är ansluten till, skriven som |
|
|
Namnet på meddelandelänken. |
|
|
Länktypen, antingen
|
|
|
Om message_link-objektet är trådbundet.
|
Exempel#
Kod för robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKod för robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Medlemsfunktioner#
Klassen message_link innehåller följande medlemsfunktioner:
isLinked— Returnerar om denna hjärna är aktivt ansluten till sin parade hjärna.send— Skickar ett meddelande till den parade hjärnan.receive— Väntar på och returnerar nästa inkommande meddelande.received— Registrerar en funktion som ska anropas när ett nytt meddelande tas emot.
Innan några message_link medlemsfunktioner anropas måste en message_link instans skapas, som visas nedan:
Kod för robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKod för 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 metoden returnerar om EXP-hjärnorna på en MessageLink är parade med varandra.
bool isLinked();
Den här funktionen har inga parametrar.
Return ValuesDen här funktionen returnerar ett booleskt värde.
true– De två EXP-hjärnorna är parade ihop och kommunicerar på den här länken.false– De två EXP-hjärnorna är inte parade ihop på den här länken.
Det är god praxis att alltid kontrollera att EXP-hjärnorna är länkade i början av ett projekt innan du kör ytterligare kod.
ExamplesKod för 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); }Kod för 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#
Skickar ett meddelande via länkanslutningen.
Available FunctionsParameters1 — Skickar en meddelandesträng.
int32_t send( const char *message );2 — Skickar en meddelandesträng med värdet
doublesom dubbelvärde.int32_t send( const char *message, double value );3 — Skickar en meddelandesträng med
int32_tochdouble.int32_t send( const char *message, int32_t index, double value );
Parameter |
Typ |
Beskrivning |
|---|---|---|
|
|
Meddelandet som ska skickas till den andra länkade EXP-hjärnan. |
|
|
Ett heltal att skicka till den andra länkade EXP-hjärnan. |
|
|
En dubbel att skicka till den andra länkade EXP-hjärnan. Dubbler formateras till 4 decimaler; om färre decimaler anges läggs efterföljande nollor tills 4 visas. |
Den här funktionen returnerar inga värden.
NotesOm endast message skickas, får den andra länkade EXP-hjärnan exakt det meddelandet.
Om value (och index om det anges) inkluderas, får den mottagande hjärnan ett enda kodat meddelande som kombinerar alla fält i denna ordning: .message_index_value
Med hjälp av link.send(“string”, 1, 2.55) emot som .string_1_2.5500.
Kod för 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); }Kod för 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#
Tar emot ett meddelande från länkanslutningen.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parameter |
Typ |
Beskrivning |
|---|---|---|
|
|
Bufferten för att lagra det mottagna meddelandet. |
|
|
Buffertens längd. |
|
|
Hur länge i millisekunder |
Denna funktion returnerar antalet mottagna byte.
Notesreceivereturnerar nästa meddelande i kö från den andra länkade EXP Brain. Meddelanden läses i FIFO-ordning (äldsta olästa först). Om kön är tom närreceiveanropas, väntar den upp till den angivnatimeoutpå ett nytt meddelande. Om inget meddelande anländer i det fönstret, returnerarreceive0, och alla meddelanden som skickas efteråt finns kvar i kön för att läsas nästa gångreceiveanvänds.Om den andra länkade EXP-hjärnan bara skickade en
string,receiveexakt den strängen.Om den andra länkade EXP Brain skickade ett heltal och/eller flyttal, returnerar
receiveen enda kodad sträng som kombinerar alla fält i denna ordning:.string_integer_floatOm till exempel den andra länkade EXP Brain använder
link.send(“string”, 1, 2.55), returnerarlink.receive()en kodad sträng som.string_1_2.5500. Du kan dela denna kodade sträng (se exemplen nedan) för att extrahera meddelandenamnet, heltal och flyttal.Om du hellre vill undvika manuell delning/parsning, använd
receivedför att registrera en hanterare för ett specifikt meddelandenamn; hanteraren tar emot de skickade värdena som argument.
Med hjälp av link.send(“string”, 1, 2.55) emot som .string_1_2.5500.
Kod för 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); }Kod för 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#
Registrerar en funktion som ska anropas när EXP-hjärnan tar emot ett skickat meddelande.
Available FunctionsParameters1 Registrerar en återuppringning för alla mottagna meddelanden (meddelande + värde).
void received( void (* callback)(const char *, const char *, double) );2 Registrerar en återuppringning för alla mottagna meddelanden (meddelande + index + värde).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Registrerar en återuppringning för ett specifikt meddelande (meddelande + värde).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Registrerar en återanropning för ett specifikt meddelande (meddelande + index + värde).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parameter |
Typ |
Beskrivning |
|---|---|---|
|
|
Meddelandenamnet att lyssna efter. Om det utelämnas körs återanropet för alla mottagna meddelanden. |
|
Funktionspekare |
En funktion som körs när ett meddelande tas emot. |
Den här funktionen returnerar inga värden.
Callback Signature1 Tar emot avsändarnamn, meddelandenamn och värde.
void callback(const char *, const char *, double)2 Tar emot avsändarnamn, meddelandenamn, index och värde.
void callback(const char *, const char *, int32_t, double)
Typ |
Beskrivning |
|---|---|
1st |
Avsändarlänkens namn. |
2nd |
Meddelandenamnet mottogs. |
|
Indexet som är associerat med meddelandet. |
|
Värdet som är kopplat till meddelandet. |
Kod för 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); } }Kod för 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); } }