Link do wiadomości#
Wstęp#
Klasa message_link umożliwia dwóm robotom EXP Brain komunikację poprzez wysyłanie krótkich wiadomości z opcjonalnymi małymi danymi. Została zaprojektowana do koordynacji między robotami — na przykład uruchamiania procedur, udostępniania wyników czujników lub wyzwalania zachowań u innego robota.
Każde użycie polecenia send dodaje wiadomość do kolejki połączonego modułu EXP Brain, a kolejka jest odczytywana metodą FIFO (pierwszy wszedł, pierwszy wyszedł). Jeśli wiele wiadomości zostanie wysłanych przed użyciem polecenia receive przez drugi moduł EXP Brain, zostaną one zapisane i zwrócone pojedynczo w kolejności wysłania. Ponieważ wiadomości mogą być kolejkowane, wielokrotne wysyłanie tego samego statusu w każdej pętli może powodować opóźnienia. W przypadku logiki krytycznej czasowo wysyłaj tylko wtedy, gdy wartości się zmienią.
Ważne: Oba roboty muszą jednocześnie obsługiwać projekty wykorzystujące message_link , w przeciwnym razie żadne wiadomości nie zostaną wysłane ani odebrane.
Konstruktory klas#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Destruktor klasy#
Niszczy obiekt message_link i zwalnia powiązane zasoby.
virtual ~message_link();
Parametry#
Parametr |
Typ |
Opis |
|---|---|---|
|
|
Port inteligentny, do którego podłączone jest radio V5 lub kabel inteligentny, zapisany jako |
|
|
Nazwa łącza wiadomości. |
|
|
Typ łącza:
|
|
|
Czy obiekt message_link jest przewodowy.
|
Przykład#
Kod dla Robota 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKod dla Robota 2
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Funkcje członkowskie#
Klasa message_link zawiera następujące funkcje członkowskie:
isLinked— Zwraca informację, czy ten Mózg jest aktywnie połączony ze sparowanym Mózgiem.send— Wysyła wiadomość do sparowanego Mózgu.receive— czeka na następną przychodzącą wiadomość i ją zwraca.otrzymano
received— Rejestruje funkcję, która ma zostać wywołana po otrzymaniu nowej wiadomości.
Przed wywołaniem jakiejkolwiek funkcji członkowskiej message_link należy utworzyć instancję message_link , jak pokazano poniżej:
Kod dla Robota 1
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKod dla 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 zwraca informację, czy mózgi EXP w MessageLink są ze sobą sparowane.
bool isLinked();
Ta funkcja nie ma żadnych parametrów.
Return ValuesTa funkcja zwraca wartość logiczną.
true– Dwa mózgi EXP są sparowane i komunikują się poprzez to łącze.false– Dwa mózgi EXP nie są sparowane w tym łączu.
Dobrą praktyką jest zawsze sprawdzenie na początku projektu, czy EXP Brains są połączone, zanim uruchomisz dalszy kod.
ExamplesKod dla 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); }Kod dla 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#
Wysyła wiadomość przez połączenie łącza.
Available FunctionsParameters1 — Wysyła ciąg wiadomości.
int32_t send( const char *message );2 — Wysyła ciąg wiadomości z podwójnym
double.int32_t send( const char *message, double value );3 — Wysyła ciąg wiadomości zawierający
int32_tidouble.int32_t send( const char *message, int32_t index, double value );
Parametr |
Typ |
Opis |
|---|---|---|
|
|
Wiadomość, którą należy wysłać do drugiego połączonego Mózgu EXP. |
|
|
Liczba całkowita do wysłania do drugiego połączonego mózgu EXP. |
|
|
Wartość podwójna do wysłania do drugiego połączonego Mózgu EXP. Wartości podwójna są formatowane do 4 miejsc po przecinku; jeśli podano mniej miejsc po przecinku, dodawane są zera końcowe, aż do wyświetlenia 4. |
Ta funkcja nie zwraca żadnych wartości.
NotesIf only message is sent, the other linked EXP Brain receives that exact message.
Jeśli uwzględniono wartość value (oraz indeks index , jeśli podano), mózg odbiorczy otrzymuje pojedynczą zakodowaną wiadomość, która łączy wszystkie pola w następującej kolejności: .message_index_value
Używając link.send(“string”, 1, 2.55) jest odbierane jako .string_1_2.5500.
Kod dla 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); }Kod dla 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#
Otrzymuje wiadomość z łącza połączenia.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parametr |
Typ |
Opis |
|---|---|---|
|
|
Bufor do przechowywania odebranej wiadomości. |
|
|
Długość bufora. |
|
|
Czas oczekiwania (w milisekundach) na nową wiadomość ( |
Funkcja ta zwraca liczbę odebranych bajtów.
Notesreceivezwraca kolejną wiadomość w kolejce z drugiego połączonego modułu EXP Brain. Wiadomości są odczytywane w kolejności FIFO (najstarsze nieprzeczytane jako pierwsze). Jeśli kolejka jest pusta w momencie wywołaniareceive, oczekuje ona na nową wiadomość do określonego limitu czasutimeoutJeśli w tym przedziale czasowym nie pojawi się żadna wiadomość,receivezwraca0, a każda wiadomość wysłana później pozostaje w kolejce do odczytania przy następnym użyciureceive.Jeśli drugi połączony EXP Brain wysłał tylko ciąg
string,receivei zwrócił dokładnie ten ciąg.Jeśli drugi połączony mózg EXP wysłał liczbę całkowitą i/lub zmiennoprzecinkową,
receivei zwraca pojedynczy zakodowany ciąg, który łączy wszystkie pola w następującej kolejności:.string_integer_floatNa przykład, jeśli drugi połączony moduł EXP Brain używa
link.send(“string”, 1, 2.55), to użycielink.receive()zwraca zakodowany ciąg znaków, taki jak.string_1_2.5500. Możesz podzielić ten zakodowany ciąg znaków (zobacz przykłady poniżej), aby wyodrębnić nazwę wiadomości, wartości całkowite i zmiennoprzecinkowe.Jeśli wolisz uniknąć ręcznego dzielenia/analizowania, użyj
receivedw celu zarejestrowania obsługi dla określonej nazwy wiadomości; obsługa odbiera wysłane wartości jako argumenty.
Używając link.send(“string”, 1, 2.55) jest odbierane jako .string_1_2.5500.
Kod dla 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); }Kod dla 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#
Rejestruje funkcję, która ma zostać wywołana za każdym razem, gdy EXP Brain otrzyma wysłaną wiadomość.
Available FunctionsParameters1 Rejestruje wywołanie zwrotne dla wszystkich odebranych wiadomości (wiadomość + wartość).
void received( void (* callback)(const char *, const char *, double) );2 Rejestruje wywołanie zwrotne dla wszystkich odebranych wiadomości (wiadomość + indeks + wartość).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Rejestruje wywołanie zwrotne dla określonej wiadomości (wiadomość + wartość).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Rejestruje wywołanie zwrotne dla określonej wiadomości (wiadomość + indeks + wartość).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parametr |
Typ |
Opis |
|---|---|---|
|
|
Nazwa wiadomości, na którą należy czekać. Jeśli pominięto, wywołanie zwrotne zostanie uruchomione dla wszystkich odebranych wiadomości. |
|
Wskaźnik funkcji |
Funkcja wykonywana po otrzymaniu wiadomości. |
Ta funkcja nie zwraca żadnych wartości.
Callback Signature1 Otrzymuje nazwę nadawcy, nazwę wiadomości i wartość.
void callback(const char *, const char *, double)2 Otrzymuje nazwę nadawcy, nazwę wiadomości, indeks i wartość.
void callback(const char *, const char *, int32_t, double)
Typ |
Opis |
|---|---|
1st |
Nazwa łącza nadawcy. |
2nd |
Nazwa otrzymanej wiadomości. |
|
Indeks powiązany z wiadomością. |
|
Wartość powiązana z wiadomością. |
Kod dla 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); } }Kod dla 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); } }