シリアルリンク#
導入#
SerialLinkを使用すると、2つのEXP BrainがVEX Linkを介して生のシリアルデータを送受信することで通信できます。SerialLinkはラベル付きメッセージではなく、バッファ(文字列またはバイト配列)を送信します。そのため、センサーデータのストリーミング、カスタムパケットフォーマットの送信、バイトベースの独自のプロトコルの構築など、高度なロボット間通信に役立ちます。
send を使用するたびに、リンクされた EXP Brain の受信バッファにデータが追加されます。データは到着した順序 (先入れ先出し) で読み取られます。他の EXP Brain が receive を使用する前に複数のバッファが送信された場合、それらはキューに保持され、送信された順序で 1 つずつ返されます。データはキューに格納される可能性があるため、ループごとに大きなバッファを繰り返し送信するとバックログが発生する可能性があります。時間制約のあるリンクでは、必要なデータのみを送信してください。
重要: 両方のロボットは、 SerialLink を使用するプロジェクトを同時に実行する必要があります。そうでない場合、データの送受信は行われません。
This page uses link as the example SerialLink name. Replace it with your own configured name as needed.
利用可能なメソッドの一覧は以下のとおりです。
リンクを作成する#
両方のEXP BrainにSerialLinkを作成して、V5 Robot Radioを使用した無線接続、またはスマートケーブルを使用した有線接続のいずれかで、両者間の通信チャネルを確立し、ロボット同士が生のシリアルデータを送受信できるようにします。
SerialLink(smartport, name, linktype, wired)
パラメータ |
説明 |
|---|---|
|
このリンクに使用されるスマートポートとは、V5 Robot Radioが接続されているポート(無線)またはスマートケーブルが差し込まれているポート(有線)のことです。0 |
|
このリンク |
|
このリンクペアで使用するブレインの役割。各ペアには、1 つのマネージャーと1 つのワーカーが含まれている必要があります。
|
|
オプション。このリンクが有線か無線か:
|
ロボット1のコード
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Manager """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER)ロボット2のコード
""" Create a wireless link in Port 1 name: VEXRoboticsLink123456789 linktype: Worker """ link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER)
利用可能な方法#
SerialLinkの設定が完了し、Brainがリンクされたら、以下の方法を使用して生のシリアルデータを送受信し、応答することができます。
is_linked#
is_linked メソッドは、SerialLink 上の EXP Brain が互いにペアになっているかどうかを返します。
True– 2 つの EXP Brain はペアになっており、このリンクで通信しています。False– このリンクでは、2 つの EXP Brain はペアになっていません。
注: プロジェクトの開始時にEXP Brainがリンクされていることを常に確認してから、さらにコードを実行することをお勧めします。
Usage:
link.is_linked()
パラメータ |
説明 |
|---|---|
このメソッドにはパラメータがありません。 |
ロボット1のコード
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")ロボット2のコード
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)
send#
send 生のシリアルバイトをリンクされたもう一方の EXP Brain に送信します。
When reading that data with receive, receive will only return once it has collected the number of bytes specified by its length parameter. Because of that, if your code always calls receive with a fixed length, you should ensure each message sent with send is exactly that many bytes (often by padding) so the receiver doesn’t block waiting for additional bytes.
正確なバイト数に依存したくない場合は、received を使用してください。これにより、特定の長さを必要とせずに、利用可能なバイトを処理できます。
Usage:
send(buffer)
パラメータ |
説明 |
|---|---|
|
他のリンクされたEXP Brainに送信するデータ。これは、 |
ロボット1のコード
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")ロボット2のコード
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)
receive#
receive リンクされたもう一方の EXP Brain からシリアルデータを FIFO 順 (最も古い未読データが最初に) で返します。
receive は正確なバイト数を待つため、固定長メッセージングでは、各メッセージが期待されるサイズに達するように、 receive を使用する際にパディングが必要になることがよくあります。送信者が send バイト未満しか送信しない場合、 length は残りのバイトを待ち続け、何も返しません。
If the queue is empty and you provide a timeout, receive waits up to that many milliseconds for new data. If nothing arrives in that window, it returns None. Any data sent afterward remains queued to be read later.
Usage:
receive(length, timeout)
パラメータ |
説明 |
|---|---|
|
The number of bytes to receive. |
|
オプション。待機時間(ミリ秒 |
ロボット1のコード
# Send a math problem for the other Brain to solve # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") """ Change whether to "add" or "subtract", then what numbers to use in the operation. """ packet = "add,7,2.5" # Pad with spaces until it's exactly 16 bytes while len(packet) < 16: packet = packet + " " link.send(packet)ロボット2のコード
# Solve the math problem that the other Brain sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() # Receive exactly 16 bytes buffer = link.receive(16) # Remove the added " " padding text = buffer.decode().strip() # Separate the operator and numbers parts = text.split(",") operator = parts[0] a = float(parts[1]) b = float(parts[2]) # Use what operator was sent if operator == "add": result = a + b elif operator == "subtract": result = a - b # If not "add" or "subtract", do nothing else: pass brain.screen.print("Result = ", result)
received#
received EXP Brain がシリアルデータを受信するたびに呼び出される関数を登録します。
Usage:
link.received(callback)
パラメータ |
説明 |
|---|---|
|
EXP Brainがシリアルデータを受信したときに実行される、事前に定義された関数。 |
received のコールバックが2つの引数で呼び出されました。
コールバックシグネチャ:
callback(buffer, length)
口論 |
説明 |
|---|---|
|
A |
|
The number of valid bytes received in |
ロボット1のコード
# Send a message to the other robot # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.MANAGER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 1 - Manager") link.send("HELLO")ロボット2のコード
# Display the message that Robot 1 sends # Create the link link = SerialLink(Ports.PORT1, "VEXRoboticsLink123456789", VexlinkType.WORKER) # Do not run code UNTIL the Brains are linked while not link.is_linked(): wait(0.1, SECONDS) brain.screen.print("Robot 2 - Worker") brain.screen.next_row() def received_message(bytearray, length): # Slice the bytearray to the valid data data = bytearray[:length] # Decode and strip the message before displaying it text = data.decode().strip() brain.screen.print("Got: ", text) # Call received_message whenever a message is received link.received(received_message)