メッセージリンク#
導入#
message_link クラスを使用すると、2 つの EXP Brain が短い文字列メッセージとオプションの小さなデータを送受信することで通信できます。これは、ルーチンの開始、センサー結果の共有、別のロボットの動作のトリガーなど、ロボット間の連携を目的として設計されています。
send を使用するたびに、リンクされた EXP Brain のキューにメッセージが追加され、キューは先入れ先出し (FIFO) で読み取られます。他の EXP Brain が receive を使用する前に複数のメッセージが送信された場合、それらは保存され、送信された順序で 1 つずつ返されます。メッセージはキューに格納できるため、ループごとに同じステータスを繰り返し送信するとバックログが発生する可能性があります。時間制約のあるロジックの場合は、値が変更されたときのみ送信してください。
重要: 両方のロボットは、同時に message_link を使用するプロジェクトを実行している必要があります。そうでない場合、メッセージの送受信は行われません。
クラスコンストラクタ#
message_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
クラスデストラクタ#
message_link オブジェクトを破棄し、関連するリソースを解放します。
virtual ~message_link();
パラメータ#
パラメータ |
タイプ |
説明 |
|---|---|---|
|
|
V5無線機またはスマートケーブルが接続されているスマートポートは、 |
|
|
メッセージリンクの名前。 |
|
|
リンクの種類は、
|
|
|
message_link オブジェクトが有線接続かどうか。
|
例#
ロボット1のコード
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredロボット2のコード
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
メンバーの機能#
message_link クラスには、以下のメンバ関数が含まれています。
isLinked— この Brain がペアになっている Brain にアクティブに接続されているかどうかを返します。send— ペアになっているブレインにメッセージを送信します。receive— 次の受信メッセージを待機し、返します。received— 新しいメッセージが受信されるたびに呼び出される関数を登録します。
message_link メンバー関数を呼び出す前に、以下に示すように、 message_link インスタンスを作成する必要があります。
ロボット1のコード
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredロボット2のコード
// Create a wireless link in Port 1 message_link link = message_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
isLinked メソッドは、MessageLink 上の EXP Brain が互いにペアになっているかどうかを返します。
bool isLinked();
この関数には引数がありません。
Return Valuesこの関数はブール値を返します。
true– 2 つの EXP Brain はペアになっており、このリンクで通信しています。false– このリンクでは、2 つの EXP Brain はペアになっていません。
プロジェクトを開始する前に、EXP Brainが正しくリンクされていることを必ず確認してから、さらにコードを実行することをお勧めします。
Examplesロボット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); }ロボット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#
リンク接続を介してメッセージを送信します。
Available FunctionsParameters1 — メッセージ文字列を送信します。
int32_t send( const char *message );2 —
doubleを重複させたメッセージ文字列を送信します。int32_t send( const char *message, double value );3 —
int32_tとdoubleを含むメッセージ文字列を送信します。int32_t send( const char *message, int32_t index, double value );
パラメータ |
タイプ |
説明 |
|---|---|---|
|
|
他のリンクされたEXP Brainに送信するメッセージ。 |
|
|
他のリンクされたEXP Brainに送信する整数値。 |
|
|
他のリンクされたEXP Brainに送信するdouble型の値。double型は小数点以下4桁まで表示されます。小数点以下の桁数が少ない場合は、4桁になるまで末尾にゼロが追加されます。 |
この関数は値を返しません。
NotesIf only message is sent, the other linked EXP Brain receives that exact message.
value (および指定されている場合は index ) が含まれる場合、受信側の Brain は、すべてのフィールドを次の順序で組み合わせた単一のエンコードされたメッセージを受け取ります: .message_index_value
link.send(“string”, 1, 2.55) は .string_1_2.5500として受信されます。
ロボット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); }ロボット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#
リンク接続からメッセージを受信します。
Available Functionsint32_t receive(
char *buffer,
int32_t length,
int32_t timeoutMs = 500 );
パラメータ |
タイプ |
説明 |
|---|---|---|
|
|
受信したメッセージを格納するためのバッファ。 |
|
|
バッファの長さ。 |
|
|
キューが空の場合にのみ新しいメッセージを待機する時間(ミリ秒 |
この関数は受信したバイト数を返します。
Notesreceivereturns the next queued message from the other linked EXP Brain. Messages are read in FIFO order (oldest unread first). If the queue is empty whenreceiveis called, it waits up to the specifiedtimeoutfor a new message. If no message arrives in that window,receivereturns0, and any message sent afterward remains in the queue to be read the next timereceiveis used.もしリンクされた別のEXP Brainが文字列
stringreceiveはその文字列を正確に返します。他のリンクされた EXP Brain が整数および/または浮動小数点数を送信した場合、
receiveを受信し、すべてのフィールドを次の順序で組み合わせた単一のエンコードされた文字列を返します:.string_integer_float例えば、リンクされた別の EXP Brain が
link.send(“string”, 1, 2.55)を使用している場合、link.receive()を使用すると、.string_1_2.5500のようなエンコードされた文字列が返されます。このエンコードされた文字列を分割して (以下の例を参照)、メッセージ名、整数値、および浮動小数点値を抽出できます。手動での分割/解析を避けたい場合は、
receivedを使用して特定のメッセージ名のハンドラを登録します。ハンドラは送信された値を引数として受け取ります。
link.send(“string”, 1, 2.55) は .string_1_2.5500として受信されます。
ロボット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); }ロボット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#
EXP Brainが送信メッセージを受信するたびに呼び出される関数を登録します。
Available FunctionsParameters1 受信したすべてのメッセージ (メッセージ + 値) のコールバックを登録します。
void received( void (* callback)(const char *, const char *, double) );2 受信したすべてのメッセージ (メッセージ + インデックス + 値) のコールバックを登録します。
void received( void (* callback)(const char *, const char *, int32_t, double) );3 特定のメッセージ (メッセージ + 値) のコールバックを登録します。
void received( const char *message, void (* callback)(const char *, const char *, double) );4 特定のメッセージ (メッセージ + インデックス + 値) のコールバックを登録します。
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
パラメータ |
タイプ |
説明 |
|---|---|---|
|
|
監視対象のメッセージ名。省略した場合、受信したすべてのメッセージに対してコールバックが実行されます。 |
|
関数ポインタ |
メッセージを受信した際に実行される関数。 |
この関数は値を返しません。
Callback Signature1 送信者名、メッセージ名、および値を受け取ります。
void callback(const char *, const char *, double)2 送信者名、メッセージ名、インデックス、および値を受け取ります。
void callback(const char *, const char *, int32_t, double)
タイプ |
説明 |
|---|---|
1st |
送信者リンク名。 |
2nd |
受信したメッセージ名。 |
|
メッセージに関連付けられたインデックス。 |
|
メッセージに関連付けられた値。 |
ロボット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); } }ロボット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); } }