Berichtlink#
Invoering#
De klasse message_link maakt het mogelijk dat twee V5 Brains met elkaar communiceren door korte tekenreeksberichten te verzenden met optioneel kleine hoeveelheden data. Deze klasse is ontworpen voor robot-naar-robot-coördinatie, zoals het starten van routines, het delen van sensorresultaten of het activeren van gedragingen op een andere robot.
Elke keer dat send wordt gebruikt, wordt een bericht toegevoegd aan de wachtrij van de gekoppelde V5 Brain, en de wachtrij wordt gelezen volgens het first-in, first-out (FIFO) principe. Als er meerdere berichten worden verzonden voordat de andere V5 Brain receive gebruikt, worden ze één voor één opgeslagen en geretourneerd in de volgorde waarin ze zijn verzonden. Omdat berichten in de wachtrij kunnen staan, kan het herhaaldelijk verzenden van dezelfde status in elke lus een opstopping veroorzaken; voor tijdskritieke logica is het raadzaam alleen te verzenden wanneer waarden veranderen.
Belangrijk: Beide robots moeten tegelijkertijd projecten uitvoeren die gebruikmaken van message_link , anders worden er geen berichten verzonden/ontvangen.
Klasseconstructors#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Klasse-destructor#
Vernietigt het message_link object en geeft de bijbehorende resources vrij.
virtual ~message_link();
Parameters#
Parameter |
Type |
Beschrijving |
|---|---|---|
|
|
De Smart Port waarop de V5 Radio, of de Smart Cable, is aangesloten, wordt weergegeven als |
|
|
De naam van de berichtlink. |
|
|
Het type link, ofwel
|
|
|
Of het message_link-object bedraad is.
|
Voorbeeld#
Code voor Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCode voor Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Lidfuncties#
De klasse message_link bevat de volgende lidfuncties:
isLinked— Geeft aan of dit brein actief verbonden is met het bijbehorende brein.send— Verstuurt een bericht naar het gekoppelde brein.receive— Wacht op het volgende binnenkomende bericht en retourneert dit.received— Registreert een functie die wordt aangeroepen wanneer een nieuw bericht wordt ontvangen.
Voordat er lidfuncties van message_link worden aangeroepen, moet er een instantie van message_link worden aangemaakt, zoals hieronder weergegeven:
Code voor Robot 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCode voor Robot 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
De methode isLinked geeft aan of de V5 Brains op een MessageLink met elkaar gekoppeld zijn.
bool isLinked();
Deze functie heeft geen parameters.
Return ValuesDeze functie retourneert een booleaanse waarde.
true– De twee V5-hersenen zijn gekoppeld en communiceren via deze verbinding.false– De twee V5-hersenen zijn niet gekoppeld op deze link.
Het is goede gewoonte om aan het begin van een project altijd te controleren of de V5 Brains correct zijn gekoppeld voordat er verdere code wordt uitgevoerd.
ExamplesCode voor 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); }Code voor 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#
Verstuurt een bericht via de linkverbinding.
Available FunctionsParameters1 — Verzendt een berichtreeks.
int32_t send( const char *message );2 — Verstuurt een berichtreeks met een
double.int32_t send( const char *message, double value );3 — Verstuurt een berichtreeks met een
int32_ten eendouble.int32_t send( const char *message, int32_t index, double value );
Parameter |
Type |
Beschrijving |
|---|---|---|
|
|
Het bericht dat naar de andere gekoppelde V5-hersenen moet worden gestuurd. |
|
|
Een geheel getal om naar de andere gekoppelde V5 Brain te sturen. |
|
|
Een double om naar de andere gekoppelde V5 Brain te sturen. Doubles worden opgemaakt met 4 decimalen; als er minder decimalen worden opgegeven, worden er nullen achter de komma toegevoegd totdat er 4 worden weergegeven. |
Deze functie retourneert geen waarden.
NotesAls er slechts message worden verzonden, ontvangt de andere gekoppelde V5 Brain precies datzelfde bericht.
Als value (en index indien aanwezig) zijn opgenomen, ontvangt het ontvangende brein één gecodeerd bericht dat alle velden in deze volgorde combineert: .message_index_value
Bij gebruik van link.send(“string”, 1, 2.55) ontvangen als .string_1_2.5500.
Code voor 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); }Code voor 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#
Ontvangt een bericht van de linkverbinding.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parameter |
Type |
Beschrijving |
|---|---|---|
|
|
De buffer om het ontvangen bericht op te slaan. |
|
|
De lengte van de buffer. |
|
|
Hoe lang in milliseconden ontvangt |
Deze functie retourneert het aantal ontvangen bytes.
Notesreceiveen retourneert het volgende bericht uit de wachtrij van de andere gekoppelde V5 Brain. Berichten worden in FIFO-volgorde gelezen (oudste ongelezen eerst). Als de wachtrij leeg is wanneerreceivewordt aangeroepen, wacht het tot de opgegeventimeoutop een nieuw bericht. Als er binnen dat tijdsvenster geen bericht arriveert, retourneertreceive0en blijft elk bericht dat daarna wordt verzonden in de wachtrij staan om te worden gelezen wanneerreceivede volgende keer wordt gebruikt.Als de andere gekoppelde V5 Brain alleen een
string,receiveprecies die string terug.Als de andere gekoppelde V5 Brain een geheel getal en/of een drijvende-kommawaarde heeft verzonden, ontvangt
receiveeen enkele gecodeerde tekenreeks die alle velden in deze volgorde combineert:.string_integer_floatAls de andere gekoppelde V5 Brain bijvoorbeeld
link.send(“string”, 1, 2.55)gebruikt, dan retourneertlink.receive()een gecodeerde tekenreeks zoals.string_1_2.5500Je kunt deze gecodeerde tekenreeks splitsen (zie de voorbeelden hieronder) om de berichtnaam, de gehele getallen en de drijvende-kommawaarden te extraheren.Als je liever handmatig splitsen/parsen vermijdt, gebruik dan
receivedom een handler te registreren voor een specifieke berichtnaam; de handler ontvangt de verzonden waarden als argumenten.
Bij gebruik van link.send(“string”, 1, 2.55) ontvangen als .string_1_2.5500.
Code voor 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); }Code voor 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#
Registreert een functie die wordt aangeroepen wanneer de V5 Brain een verzonden bericht ontvangt.
Available FunctionsParameters1 Registreert een callback voor alle ontvangen berichten (bericht + waarde).
void received( void (* callback)(const char *, const char *, double) );2 Registreert een callback voor alle ontvangen berichten (bericht + index + waarde).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Registreert een callback voor een specifiek bericht (bericht + waarde).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Registreert een callback voor een specifiek bericht (bericht + index + waarde).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parameter |
Type |
Beschrijving |
|---|---|---|
|
|
De naam van het bericht waarnaar geluisterd moet worden. Indien weggelaten, wordt de callback uitgevoerd voor alle ontvangen berichten. |
|
|
Een functie die wordt uitgevoerd wanneer een bericht wordt ontvangen. |
Deze functie retourneert geen waarden.
Callback Signature1 Ontvangt de naam van de afzender, de naam van het bericht en de waarde.
void callback(const char *, const char *, double)2 Ontvangt de naam van de afzender, de naam van het bericht, de index en de waarde.
void callback(const char *, const char *, int32_t, double)
Type |
Beschrijving |
|---|---|
1st |
De naam van de afzenderlink. |
2nd |
De naam van het ontvangen bericht. |
|
De index die aan het bericht is gekoppeld. |
|
De waarde die aan het bericht is gekoppeld. |
Code voor Robot 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); } }Code voor 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); } }