Odkaz na zprávu#
Zavedení#
Třída message_link umožňuje dvěma EXP Brainům komunikovat odesíláním krátkých řetězcových zpráv s volitelnými malými daty. Je navržena pro koordinaci mezi roboty – například pro spouštění rutin, sdílení výsledků senzorů nebo spouštění chování u jiného robota.
Každé použití send přidá zprávu do fronty propojeného EXP Brainu a fronta se čte v systému FIFO (first in, first out). Pokud je odesláno více zpráv předtím, než druhý EXP Brain použije receive, budou uloženy a vráceny jedna po druhé v pořadí, v jakém byly odeslány. Protože se zprávy mohou čekat ve frontě, opakované odesílání stejného stavu v každé smyčce může způsobit nahromadění zpráv; z časově kritické logiky odesílejte pouze při změně hodnot.
Důležité: Oba roboti musí současně spouštět projekty, které používají message_link , jinak nebudou odesílány/přijímány žádné zprávy.
Konstruktory tříd#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Destruktor tříd#
Zničí objekt message_link a uvolní přidružené prostředky.
virtual ~message_link();
Parametry#
Parametr |
Typ |
Popis |
|---|---|---|
|
|
Inteligentní port, ke kterému je připojeno rádio V5 nebo inteligentní kabel, zapsaný jako |
|
|
Název odkazu na zprávu. |
|
|
Typ odkazu, buď
|
|
|
Zda je objekt message_link připojen kabelem.
|
Příklad#
Kód pro robota 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKód pro Robota 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Členské funkce#
Třída message_link obsahuje následující členské funkce:
isLinked— Vrátí, zda je tento mozek aktivně připojen k jeho spárovanému mozku.send— Odešle zprávu spárovanému mozku.receive— Čeká na další příchozí zprávu a vrací ji.received— Registruje funkci, která má být volána při každém přijetí nové zprávy.
Před voláním jakékoli členské funkce message_link musí být vytvořena instance message_link , jak je znázorněno níže:
Kód pro robota 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKód pro Robota 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Metoda isLinked vrací, zda jsou EXP Brains v MessageLinku vzájemně spárovány.
bool isLinked();
Tato funkce nemá žádné parametry.
Return ValuesTato funkce vrací booleovskou hodnotu.
true– Dva EXP mozky jsou spárované a komunikují prostřednictvím tohoto spojení.false– Dva EXP mozky nejsou v tomto odkazu spárovány.
Je dobrým zvykem vždy zkontrolovat, zda jsou EXP Brains propojeny na začátku projektu, než spustíte jakýkoli další kód.
ExamplesKód pro robota 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); }Kód pro Robota 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#
Odešle zprávu přes propojené připojení.
Available FunctionsParameters1 — Odešle řetězec zprávy.
int32_t send( const char *message );2 — Odešle řetězec zprávy s
double.int32_t send( const char *message, double value );3 — Odešle řetězec zprávy s
int32_tadouble.int32_t send( const char *message, int32_t index, double value );
Parametr |
Typ |
Popis |
|---|---|---|
|
|
Zpráva, která se má odeslat druhému propojenému EXP mozku. |
|
|
Celé číslo, které se má poslat do druhého propojeného EXP mozku. |
|
|
Dvojitý údaj, který se odešle do druhého propojeného EXP Brainu. Dvojité údaje jsou formátovány na 4 desetinná místa; pokud je zadáno méně desetinných míst, přidávají se koncové nuly, dokud se nezobrazí 4. |
Tato funkce nevrací žádné hodnoty.
NotesPokud je odeslána pouze message , druhý propojený EXP mozek obdrží tuto přesnou zprávu.
Pokud je zahrnuta hodnota value (a index pokud je zadán), přijímající Brain obdrží jednu zakódovanou zprávu, která kombinuje všechna pole v tomto pořadí: .message_index_value
Použitím link.send(“string”, 1, 2.55) přijata jako .string_1_2.5500.
Kód pro robota 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); }Kód pro Robota 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#
Přijme zprávu z propojeného připojení.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parametr |
Typ |
Popis |
|---|---|---|
|
|
Vyrovnávací paměť pro uložení přijaté zprávy. |
|
|
Délka vyrovnávací paměti. |
|
|
Jak dlouho v milisekundách |
Tato funkce vrací počet přijatých bajtů.
NotesFunkce
receivevrací další zprávu ve frontě z druhého propojeného EXP Brainu. Zprávy se čtou v pořadí FIFO (nejstarší nepřečtené jako první). Pokud je fronta při voláníreceiveprázdná, čeká na novou zprávu až do zadaného časového limitutimeoutreceivevrátí0a všechny zprávy odeslané poté zůstanou ve frontě pro přečtení při příštím použití funkcereceive.Pokud druhý propojený EXP Brain odeslal pouze řetězec
string,receivevrátí přesný řetězec.Pokud druhý propojený EXP Brain odeslal celé číslo a/nebo číslo s plovoucí čárkou,
receivevrátí jeden zakódovaný řetězec, který kombinuje všechna pole v tomto pořadí:.string_integer_floatNapříklad pokud druhý propojený EXP Brain používá
link.send(“string”, 1, 2.55), pak použitílink.receive()vrátí zakódovaný řetězec, například.string_1_2.5500. Tento zakódovaný řetězec můžete rozdělit (viz níže uvedené příklady) a extrahovat tak název zprávy, celé číslo a hodnotu s desetinnou čárkou.Pokud se raději vyhnete ručnímu dělení/parsování, použijte
receivedk registraci obslužné rutiny pro konkrétní název zprávy; obslužná rutina přijímá odeslané hodnoty jako argumenty.
Použitím link.send(“string”, 1, 2.55) přijata jako .string_1_2.5500.
Kód pro robota 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); }Kód pro Robota 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#
Registruje funkci, která má být volána vždy, když EXP Brain přijme odeslanou zprávu.
Available FunctionsParameters1 Registruje zpětné volání pro všechny přijaté zprávy (zpráva + hodnota).
void received( void (* callback)(const char *, const char *, double) );2 Zaregistruje zpětné volání pro všechny přijaté zprávy (zpráva + index + hodnota).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Zaregistruje zpětné volání pro konkrétní zprávu (zpráva + hodnota).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Zaregistruje zpětné volání pro konkrétní zprávu (zpráva + index + hodnota).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parametr |
Typ |
Popis |
|---|---|---|
|
|
Název zprávy, na kterou se má naslouchat. Pokud je vynechán, zpětné volání se spustí pro všechny přijaté zprávy. |
|
Ukazatel funkce |
Funkce, která se provede po přijetí zprávy. |
Tato funkce nevrací žádné hodnoty.
Callback Signature1 Přijme jméno odesílatele, název zprávy a hodnotu.
void callback(const char *, const char *, double)2 Přijme jméno odesílatele, název zprávy, index a hodnotu.
void callback(const char *, const char *, int32_t, double)
Typ |
Popis |
|---|---|
1st |
Název odkazu odesílatele. |
2nd |
Název přijaté zprávy. |
|
Index přidružený ke zprávě. |
|
Hodnota spojená se zprávou. |
Kód pro robota 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); } }Kód pro Robota 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); } }