Nuoseklusis ryšys#
Įvadas#
serial_link klasė leidžia siųsti neapdorotų baitų srautą tarp robotų. Ji skirta robotų tarpusavio ryšiui, kai ir siunčiantis, ir priimantis robotas supranta duomenų srauto turinį.
Kiekvieną kartą panaudojus send, duomenys pridedami prie susieto EXP Brain eilės, o eilė skaitoma FIFO (pirmas įeina, pirmas išeina) principu. Jei prieš tai, kai kitas EXP Brain naudoja gavimą, išsiunčiami keli pranešimai, jie bus saugomi ir grąžinami po vieną tokia tvarka, kokia buvo išsiųsti. Kadangi pranešimai gali būti eilėje, pakartotinis tos pačios būsenos siuntimas kiekviename cikle gali sukelti vėlavimą; laiko požiūriu kritinei logikai siųskite tik tada, kai pasikeičia reikšmės.
Svarbu: Abu robotai vienu metu turi vykdyti projektus, kurie naudoja serial_link , kitaip duomenys nebus siunčiami / gaunami.
Klasės konstruktoriai#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Klasės destruktorius#
Sunaikina serial_link objektą ir išlaisvina susijusius išteklius.
~serial_link();
Parametrai#
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Išmanusis prievadas, prie kurio prijungta pranešimų nuoroda, užrašomas kaip |
|
|
Šios nuorodos pavadinimas. Rekomenduojama, kad ši unikali eilutė būtų pakankamai ilga, kad, „vexos“ ją apdorojus, būtų sukurtas unikalus ID. Netinkamas nuorodos pavadinimas būtų bendrinis, pvz., „vexlink“, nes jį gali naudoti kita komanda. |
|
|
Ryšio tipas –
|
|
|
Ar „serial_link“ objektas yra laidinis (numatytoji reikšmė yra
|
Pastabos#
„VEXlink“ palaiko tiek belaidį, tiek laidinį ryšį, o laidiniams ryšiams rekomenduojama naudoti modifikuotą išmanųjį kabelį, kad būtų išvengta maitinimo nukreipimo problemų.
Belaidžiam ryšiui kiekvienam robotui reikia V5 roboto radijo, prijungto prie išmaniojo prievado.
„VEXlink“ radiją galima naudoti kartu su EXP valdiklio „VEXnet“ radijo imtuvu, kuris turėtų būti prijungtas prie didžiausio numerio „Smart Port“, kad būtų išvengta konfliktų.
Norint sukurti VEXlink, abu EXP Brains turi būti prijungti prie V5 roboto radijo.
Pavyzdys#
1 roboto kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRoboto 2 kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Narių funkcijos#
serial_link klasėje yra šios narių funkcijos:
isLinked– Patikrina, ar EXP smegenys yra suporuotos ir bendrauja šiuo ryšiu.send— Siunčia žinutę suporuotoms smegenims.receive— Laukia ir grąžina kitą gaunamą pranešimą.received— Registruoja funkciją, kuri bus iškviečiama gavus naują pranešimą.
Prieš iškviečiant bet kokias serial_link narių funkcijas, reikia sukurti serial_link egzempliorių, kaip parodyta žemiau:
1 roboto kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRoboto 2 kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Grąžina, ar nuosekliojoje jungtyje esančios EXP Brains yra suporuotos viena su kita.
Available Functionsbool isLinked();
Ši funkcija neturi jokių parametrų.
Return ValuesGrąžina loginę reikšmę, nurodančią, ar EXP Brains yra susietos:
true— The two EXP Brains are paired and communicating on this link.false— The two EXP Brains are not paired on this link.
Prieš paleidžiant bet kokį tolesnį kodą, gera praktika yra visada patikrinti, ar EXP smegenys yra susietos projekto pradžioje.
1 roboto kodas
// Create the link serial_link 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"); Brain.Screen.newLine(); Brain.Screen.print("Sending message..."); // Message to send const char* message = "Hello Robot 2"; // Send the message link.send((uint8_t*)message, strlen(message));
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Buffer to store incoming bytes uint8_t buffer[32] = {0}; int32_t n = link.receive(buffer, sizeof(buffer) - 1); // Null-terminate if (n > 0) { buffer[n] = 0; // Display the message that was sent Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print((char*)buffer); } else { Brain.Screen.newLine(); Brain.Screen.print("No message received"); }
send#
Siunčia žinutę suporuotoms smegenims.
Available Functions1 — Siunčia pranešimą naudodamas baitų buferį.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Siunčia pranešimą naudodamas simbolių buferį.
int32_t send( const char *buffer, int32_t length );
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Buferis, kurį reikia siųsti į kitą susietą EXP smegenų atmintį. |
|
|
Siunčiamo buferio ilgis. |
Grąžina int32_t nurodantį išsiųstų baitų skaičių.
1 roboto kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 1 - Manager"); // Track last sent state uint8_t lastState = 255; // impossible initial value // Tell Robot 2 when the screen is being pressed while (true) { uint8_t state = Brain.Screen.pressing() ? 1 : 0; // Only send if state changed if (state != lastState) { link.send(&state, 1); lastState = state; } wait(0.02, seconds); }
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Track the last state uint8_t lastShown = 255; while (true) { // Variable stores 1 - pressed, 0 - not pressed uint8_t state = 0; int32_t n = link.receive(&state, 1, 200); // Only update screen if state changes if (n == 1 && state != lastShown) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display text if Robot 1's screen is being pressed if (state == 1) { Brain.Screen.print("Manager IS being pressed!"); } else { Brain.Screen.print("Manager is NOT being pressed"); } lastShown = state; } wait(0.02, seconds); }
receive#
Laukia ir grąžina kitą gaunamą pranešimą.
Available FunctionsParameters1 — Gauna pranešimą į simbolių buferį su pasirenkamu skirtuoju laiku.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Buferis gautam pranešimui saugoti. |
|
|
Buferio ilgis. |
|
|
Kiek milisekundėmis |
Grąžina int32_t , nurodantį gautų baitų skaičių.
receivegrąžina kitą eilėje esantį pranešimą iš kitos susietos EXP Brain.Pranešimai skaitomi FIFO tvarka (pirmiausia nuo seniausių neskaitytų).
Jei eilė tuščia, kai iškviečiama komanda
receive, ji laukia naujo pranešimo iki nurodytostimeoutMslaikmačio.Jei per tą langą negaunamas joks pranešimas,
receivegrąžina0, o bet koks vėliau išsiųstas pranešimas lieka eilėje, kad būtų perskaitytas kitą kartą naudojantreceive.
1 roboto kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 1 - Manager"); // Track last sent state uint8_t lastState = 255; // impossible initial value // Tell Robot 2 when the screen is being pressed while (true) { uint8_t state = Brain.Screen.pressing() ? 1 : 0; // Only send if state changed if (state != lastState) { link.send(&state, 1); lastState = state; } wait(0.02, seconds); }
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Track the last state uint8_t lastShown = 255; while (true) { // Variable stores 1 - pressed, 0 - not pressed uint8_t state = 0; int32_t n = link.receive(&state, 1, 200); // Only update screen if state changes if (n == 1 && state != lastShown) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display text if Robot 1's screen is being pressed if (state == 1) { Brain.Screen.print("Manager IS being pressed!"); } else { Brain.Screen.print("Manager is NOT being pressed"); } lastShown = state; } wait(0.02, seconds); }
received#
Registruoja funkciją, kuri bus iškviečiama kaskart, kai EXP Brain gaus išsiųstą pranešimą.
Available Functions1 — Registruoja atgalinio iškvietimo funkciją kiekvienam gautam pranešimui.
void received( void (* callback)(const char *, const char *, double) );
2 — Registruoja grįžtamąjį iškvietimą kiekvienam gautam pranešimui, kuriame yra papildomas int32_t laukas.
void received( void (* callback)(const char *, const char *, int32_t, double) );
3 — Registruoja atgalinį iškvietimą tik toms gautoms žinutėms, kurių pavadinimas sutampa su pranešimu.
void received( const char *message, void (* callback)(const char *, const char *, double) );
Parameters4 — Registruoja atgalinį iškvietimą, iškviečiant tik gautas žinutes, kurių pavadinimas sutampa su pranešimo pavadinimu, kai pranešimo turinys apima papildomą lauką int32_t.
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Atitinkamas pranešimo pavadinimas (eilutė). Kai gauto pranešimo pavadinimas atitinka šią reikšmę, iškviečiama atgalinio iškvietimo |
|
|
Anksčiau apibrėžta funkcija, kuri paleidžiama, kai EXP Brain gauna pranešimą, atitinkantį |
Ši funkcija negrąžina reikšmės.
Notesreceivedatgalinių iškvietimų iškviečiami su keturiais argumentais:
callback(message, linkname, index, value)
Argumentas |
Aprašymas |
|---|---|
|
Gautos žinutės pavadinimas (pavyzdžiui, |
|
Nuorodos, iš kurios buvo gautas pranešimas, pavadinimas. |
|
Sveikasis skaičius, išsiųstas su pranešimu (jei nurodyta). |
|
Su pranešimu siunčiama slankiojo skaičiaus reikšmė (jei nurodyta). |
1 roboto kodas
// Send left or right when pressed void screen_pressed() { if (Brain.Screen.xPosition() < 240) { link.send((uint8_t*)"left", 4); } else { link.send((uint8_t*)"right", 5); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link serial_link 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"); Brain.Screen.pressed(screen_pressed); }
Roboto 2 kodas
// Called when message received void received_callback(uint8_t *buffer, int32_t length) { char msg[32]; // Copy safely and null terminate int n = (length < 31) ? length : 31; memcpy(msg, buffer, n); msg[n] = '\0'; Brain.Screen.clearScreen(); Brain.Screen.setCursor(1,1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display if Robot 1's screen is pressed on left or right if (strcmp(msg, "left") == 0) { Brain.Screen.print("Manager pressed LEFT"); } else if (strcmp(msg, "right") == 0) { Brain.Screen.print("Manager pressed RIGHT"); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link serial_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(received_callback); Brain.Screen.clearScreen(); Brain.Screen.setCursor(1,1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); }