Nachrichtenlink#
Einführung#
Die Klasse message_link ermöglicht die Kommunikation zwischen zwei EXP Brains durch den Austausch kurzer String-Nachrichten mit optionalen kleinen Datenmengen. Sie ist für die Roboter-zu-Roboter-Koordination konzipiert – beispielsweise zum Starten von Routinen, zum Teilen von Sensordaten oder zum Auslösen von Verhaltensweisen bei einem anderen Roboter.
Jede Verwendung von send fügt eine Nachricht zur Warteschlange des verknüpften EXP Brain hinzu. Die Warteschlange wird nach dem FIFO-Prinzip (First-In, First-Out) gelesen. Werden mehrere Nachrichten gesendet, bevor das andere EXP Brain receive verwendet, werden diese in der Reihenfolge ihres Versands gespeichert und zurückgegeben. Da Nachrichten in einer Warteschlange landen können, kann das wiederholte Senden desselben Status in jeder Schleife zu einem Rückstau führen. Senden Sie daher für zeitkritische Logik nur Nachrichten, wenn sich Werte ändern.
Wichtig: Beide Roboter müssen gleichzeitig Projekte ausführen, die message_link verwenden, sonst werden keine Nachrichten gesendet/empfangen.
Klassenkonstruktoren#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Klassendestruktor#
Zerstört das Objekt message_link ) und gibt die zugehörigen Ressourcen frei.
virtual ~message_link();
Parameter#
Parameter |
Typ |
Beschreibung |
|---|---|---|
|
|
Der Smart Port, an den das V5-Funkgerät oder das Smart Cable angeschlossen ist, wird als |
|
|
Der Name des Nachrichtenlinks. |
|
|
Der Verbindungstyp, entweder
|
|
|
Gibt an, ob das message_link-Objekt kabelgebunden ist.
|
Beispiel#
Code für Roboter 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCode für Roboter 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Mitgliedsfunktionen#
Die Klasse message_link enthält die folgenden Memberfunktionen:
isLinked— Gibt zurück, ob dieses Gehirn aktiv mit seinem gepaarten Gehirn verbunden ist.send— Sendet eine Nachricht an das gepaarte Gehirn.receive— Wartet auf die nächste eingehende Nachricht und gibt sie zurück.received— Registriert eine Funktion, die aufgerufen wird, sobald eine neue Nachricht empfangen wird.
Bevor Sie eine der Memberfunktionen von message_link aufrufen, muss eine Instanz von message_link erstellt werden, wie unten gezeigt:
Code für Roboter 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredCode für Roboter 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Die Methode isLinked gibt zurück, ob die EXP Brains eines MessageLink miteinander gepaart sind.
bool isLinked();
Diese Funktion hat keine Parameter.
Return ValuesDiese Funktion gibt einen booleschen Wert zurück.
true– Die beiden EXP-Gehirne sind gepaart und kommunizieren über diese Verbindung.false– Die beiden EXP Brains sind über diese Verbindung nicht gekoppelt.
Es empfiehlt sich, zu Beginn eines Projekts immer zu überprüfen, ob die EXP Brains verknüpft sind, bevor weiterer Code ausgeführt wird.
ExamplesCode für Roboter 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 für Roboter 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#
Sendet eine Nachricht über die Linkverbindung.
Available FunctionsParameters1 — Sendet eine Nachrichtenzeichenfolge.
int32_t send( const char *message );2 — Sendet eine Nachrichtenzeichenkette mit einer
double.int32_t send( const char *message, double value );3 — Sendet eine Nachrichtenzeichenkette mit einer
int32_tund einerdouble.int32_t send( const char *message, int32_t index, double value );
Parameter |
Typ |
Beschreibung |
|---|---|---|
|
|
Die Nachricht, die an das andere verbundene EXP Brain gesendet werden soll. |
|
|
Eine Ganzzahl, die an das andere verbundene EXP Brain gesendet werden soll. |
|
|
Ein Gleitkommawert (Double) wird an das andere verknüpfte EXP Brain gesendet. Gleitkommazahlen werden auf vier Dezimalstellen formatiert; werden weniger Dezimalstellen angegeben, werden nachfolgende Nullen hinzugefügt, bis vier angezeigt werden. |
Diese Funktion gibt keine Werte zurück.
NotesWenn nur die Nachricht message wird, empfängt das andere verbundene EXP Brain genau diese Nachricht.
Wenn value (und index , falls angegeben) enthalten sind, erhält das empfangende Gehirn eine einzelne kodierte Nachricht, die alle Felder in dieser Reihenfolge kombiniert: .message_index_value
Bei Verwendung link.send(“string”, 1, 2.55) als .string_1_2.5500 empfangen.
Code für Roboter 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 für Roboter 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#
Empfängt eine Nachricht von der Verbindungsverbindung.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parameter |
Typ |
Beschreibung |
|---|---|---|
|
|
Der Puffer zum Speichern der empfangenen Nachricht. |
|
|
Die Länge des Puffers. |
|
|
Wie lange in Millisekunden |
Diese Funktion gibt die Anzahl der empfangenen Bytes zurück.
Notesreceivegibt die nächste Nachricht aus der Warteschlange des anderen verbundenen EXP Brains zurück. Nachrichten werden in FIFO-Reihenfolge gelesen (älteste ungelesene zuerst). Wenn die Warteschlange beim Aufruf vonreceiveleer ist, wartet die Funktion bis zum angegebenen Timeouttimeoutauf eine neue Nachricht. Trifft innerhalb dieses Zeitfensters keine Nachricht ein, gibtreceiveden Wert0zurück, und alle danach gesendeten Nachrichten bleiben in der Warteschlange, um beim nächsten Aufruf vonreceivegelesen zu werden.Wenn das andere verbundene EXP Brain nur eine
string,receiveund gibt genau diese Zeichenkette zurück.Wenn das andere verbundene EXP Brain eine Ganzzahl und/oder eine Gleitkommazahl gesendet hat, gibt
receiveeine einzelne kodierte Zeichenkette zurück, die alle Felder in dieser Reihenfolge kombiniert:.string_integer_floatWenn beispielsweise das andere verknüpfte EXP Brain
link.send(“string”, 1, 2.55)verwendet, gibtlink.receive()eine kodierte Zeichenkette wie.string_1_2.5500zurück. Diese kodierte Zeichenkette lässt sich aufteilen (siehe Beispiele unten), um den Nachrichtennamen, die Ganzzahl- und die Gleitkommawerte zu extrahieren.Wenn Sie das manuelle Aufteilen/Parsen lieber vermeiden möchten, verwenden Sie
received, um einen Handler für einen bestimmten Nachrichtennamen zu registrieren; der Handler empfängt die gesendeten Werte als Argumente.
Bei Verwendung link.send(“string”, 1, 2.55) als .string_1_2.5500 empfangen.
Code für Roboter 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 für Roboter 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#
Registriert eine Funktion, die immer dann aufgerufen wird, wenn das EXP Brain eine gesendete Nachricht empfängt.
Available FunctionsParameters1 Registriert einen Callback für alle empfangenen Nachrichten (Nachricht + Wert).
void received( void (* callback)(const char *, const char *, double) );2 Registriert einen Callback für alle empfangenen Nachrichten (Nachricht + Index + Wert).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Registriert einen Callback für eine bestimmte Nachricht (Nachricht + Wert).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Registriert einen Callback für eine bestimmte Nachricht (Nachricht + Index + Wert).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parameter |
Typ |
Beschreibung |
|---|---|---|
|
|
Der Name der Nachricht, auf die gewartet werden soll. Wird er weggelassen, wird die Callback-Funktion für alle empfangenen Nachrichten ausgeführt. |
|
Funktionszeiger |
Eine Funktion, die beim Empfang einer Nachricht ausgeführt wird. |
Diese Funktion gibt keine Werte zurück.
Callback Signature1 Empfängt Absendername, Nachrichtenname und Wert.
void callback(const char *, const char *, double)2 Empfängt Absendername, Nachrichtenname, Index und Wert.
void callback(const char *, const char *, int32_t, double)
Typ |
Beschreibung |
|---|---|
1st |
Der Absendername. |
2nd |
Der empfangene Nachrichtenname. |
|
Der der Nachricht zugeordnete Index. |
|
Der mit der Nachricht verknüpfte Wert. |
Code für Roboter 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); } }Code für Roboter 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); } }