Viestilinkki#
Johdanto#
message_link -luokka antaa kahden EXP-aivon kommunikoida lähettämällä lyhyitä merkkijonoviestejä, jotka sisältävät valinnaisesti pientä dataa. Se on suunniteltu robottien väliseen koordinointiin – kuten rutiinien käynnistämiseen, anturitulosten jakamiseen tai toisen robotin toiminnan käynnistämiseen.
Jokainen send -funktion käyttökerta lisää viestin linkitetyn EXP Brainin jonoon, ja jono luetaan FIFO-periaatteella (first-in, first-out). Jos useita viestejä lähetetään ennen kuin toinen EXP Brain käyttää receive -funktiota, ne tallennetaan ja palautetaan yksi kerrallaan lähetysjärjestyksessä. Koska viestit voivat jonottaa, saman tilan toistuva lähettäminen jokaisessa silmukassa voi luoda ruuhkan; aikakriittisissä logiikoissa viesti lähetetään vain, kun arvot muuttuvat.
Tärkeää: Molempien robottien on oltava käynnissä projekteissa, jotka käyttävät message_link tä samanaikaisesti, muuten viestejä ei lähetetä/vastaanoteta.
Luokanrakentajat#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Luokan tuhoaja#
Tuhoaa message_link -objektin ja vapauttaa siihen liittyvät resurssit.
virtual ~message_link();
Parametrit#
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Älyportti, johon V5-radio tai älykaapeli on kytketty, kirjoitetaan muodossa |
|
|
Viestilinkin nimi. |
|
|
Linkin tyyppi, joko
|
|
|
Onko message_link-objekti langallinen.
|
Esimerkki#
Robotin 1 koodi
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobotin 2 koodi
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Jäsenten toiminnot#
Luokka message_link sisältää seuraavat jäsenfunktiot:
isLinked— Palauttaa, onko tämä aivo aktiivisesti yhteydessä paritettuun aivoonsa.send— Lähettää viestin parilliselle aivolle.receive— Odottaa seuraavaa saapuvaa viestiä ja palauttaa sen.received— Rekisteröi funktion kutsuttavaksi aina, kun uusi viesti vastaanotetaan.
Before calling any message_link member functions, a message_link instance must be created, as shown below:
Robotin 1 koodi
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobotin 2 koodi
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
isLinked -metodi palauttaa, ovatko MessageLinkin EXP-aivot paritettuja toisiinsa.
bool isLinked();
Tällä funktiolla ei ole parametreja.
Return ValuesTämä funktio palauttaa totuusarvon.
true– Kaksi EXP-aivoa on yhdistetty ja kommunikoivat tämän linkin kautta.false– Kahta EXP-aivoa ei ole yhdistetty tällä linkillä.
On hyvä käytäntö tarkistaa aina projektin alussa, että EXP-aivot on linkitetty ennen minkään muun koodin suorittamista.
ExamplesRobotin 1 koodi
// 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); }Robotin 2 koodi
// 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#
Lähettää viestin linkkiyhteyden kautta.
Available FunctionsParameters1 — Lähettää viestimerkkijonon.
int32_t send( const char *message );2 — Lähettää viestimerkkijonon, jossa on
double.int32_t send( const char *message, double value );3 — Lähettää viestimerkkijonon, jossa on
int32_tjadouble.int32_t send( const char *message, int32_t index, double value );
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Toiselle linkitetylle EXP-aivolle lähetettävä viesti. |
|
|
Kokonaisluku, joka lähetetään toiseen linkitettyyn EXP Brainiin. |
|
|
Tuplaluku lähetettäväksi toiseen linkitettyyn EXP-aivoon. Tuplaluvut muotoillaan neljän desimaalin tarkkuudella; jos desimaaleja on vähemmän, niiden loppuun lisätään nollia, kunnes niitä on enää neljä. |
Tämä funktio ei palauta mitään arvoja.
NotesJos lähetetään vain message , toinen linkitetty EXP-aivot vastaanottavat tarkalleen kyseisen viestin.
Jos value (ja index jos sellainen on), vastaanottava aivot saavat yhden koodatun viestin, joka yhdistää kaikki kentät tässä järjestyksessä: .message_index_value
Käyttämällä funktiota link.send(“string”, 1, 2.55) vastaanotetaan muodossa .string_1_2.5500.
Robotin 1 koodi
// 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); }Robotin 2 koodi
// 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#
Vastaanottaa viestin linkkiyhteydeltä.
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Puskuri, johon vastaanotettu viesti tallennetaan. |
|
|
Puskurin pituus. |
|
|
Kuinka kauan millisekunteina viesti |
Tämä funktio palauttaa vastaanotettujen tavujen määrän.
Notesreceivepalauttaa seuraavan jonossa olevan viestin toisesta linkitetystä EXP Brainista. Viestit luetaan FIFO-järjestyksessä (vanhin lukematon ensin). Jos jono on tyhjä, kunreceivekutsutaan, se odottaa uutta viestiä määritettyyntimeoutasti. Jos viestiä ei saavu kyseiseen ikkunaan,receivepalauttaa arvon0, ja kaikki sen jälkeen lähetetyt viestit jäävät jonoon luettavaksi seuraavalla kerralla, kunreceivekäytetään.Jos toinen linkitetty EXP Brain lähetti vain
string,receivepalauttaa tarkalleen kyseisen merkkijonon.Jos toinen linkitetty EXP Brain lähetti kokonaisluvun ja/tai liukulukun,
receivepalauttaa yhden koodatun merkkijonon, joka yhdistää kaikki kentät tässä järjestyksessä:.string_integer_floatJos esimerkiksi toinen linkitetty EXP Brain käyttää
link.send(“string”, 1, 2.55), niinlink.receive()palauttaa koodatun merkkijonon, kuten.string_1_2.5500Voit jakaa tämän koodatun merkkijonon (katso alla olevat esimerkit) purkaaksesi viestin nimen, kokonaisluvun ja liukulukujen arvot.Jos haluat mieluummin välttää manuaalisen jakamisen/jäsentämisen, käytä
receivedrekisteröidäksesi käsittelijän tietylle viestin nimelle; käsittelijä vastaanottaa lähetetyt arvot argumentteina.
Käyttämällä funktiota link.send(“string”, 1, 2.55) vastaanotetaan muodossa .string_1_2.5500.
Robotin 1 koodi
// 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); }Robotin 2 koodi
// 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#
Rekisteröi funktion, jota kutsutaan aina, kun EXP Brain vastaanottaa lähetetyn viestin.
Available FunctionsParameters1 Rekisteröi takaisinsoiton kaikille vastaanotetuille viesteille (viesti + arvo).
void received( void (* callback)(const char *, const char *, double) );2 Rekisteröi takaisinsoiton kaikille vastaanotetuille viesteille (viesti + indeksi + arvo).
void received( void (* callback)(const char *, const char *, int32_t, double) );3 Rekisteröi takaisinkutsutoiminnon tietylle viestille (viesti + arvo).
void received( const char *message, void (* callback)(const char *, const char *, double) );4 Rekisteröi takaisinkutsutoiminnon tietylle viestille (viesti + indeksi + arvo).
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Kuunneltavan viestin nimi. Jos tämä jätetään pois, takaisinkutsu suoritetaan kaikille vastaanotetuille viesteille. |
|
Funktio-osoitin |
Funktio, joka suoritetaan, kun viesti vastaanotetaan. |
Tämä funktio ei palauta mitään arvoja.
Callback Signature1 Vastaanottaa lähettäjän nimen, viestin nimen ja arvon.
void callback(const char *, const char *, double)2 Vastaanottaa lähettäjän nimen, viestin nimen, indeksin ja arvon.
void callback(const char *, const char *, int32_t, double)
Tyyppi |
Kuvaus |
|---|---|
1st |
Lähettäjän linkin nimi. |
2nd |
Vastaanotetun viestin nimi. |
|
Viestiin liittyvä indeksi. |
|
Viestiin liittyvä arvo. |
Robotin 1 koodi
// 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); } }Robotin 2 koodi
// 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); } }