質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
並列処理

複数の計算が同時に実行される手法

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

pythonの関数で並列処理がしたい

Antlia
Antlia

総合スコア2

並列処理

複数の計算が同時に実行される手法

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1回答

0グッド

1クリップ

940閲覧

投稿2021/06/11 14:52

前提・実現したいこと

制御しているモータの位置情報を取得してUDPで送信したいです。
該当ソースコードのmotor_angle = measurement['position']で「motor_angle」に位置情報が入ると思います。
この位置情報をバイナリ型に変換してUDP通信で送信しデータを受け取る動作がしたいです。
サンプルコードでUDPの送受信はできていますが、データのやり取りの仕方がわかっていません。

発生している問題・エラーメッセージ

エラーは特に出ていませんが、望んでいる挙動をしていません。
下記のコードを実行すると何もない情報を送信しています。
受信側のプログラムで確認すると送信側のIPアドレスとポート番号しか送られてきていません。

該当のソースコード

Pythonコード

import argparse import signal import sys import os import pathlib from time import sleep from concurrent.futures import ThreadPoolExecutor #udp sousinnyou from socket import socket, AF_INET, SOCK_DGRAM current_dir = pathlib.Path(__file__).resolve().parent sys.path.insert(0, str(current_dir) + '/../') # give 1st priority to the directory where pykeigan exists from pykeigan import usbcontroller parser = argparse.ArgumentParser(description='モーターに接続し、各種情報の取得') parser.add_argument('port',metavar='PORT',default='/dev/ttyUSB0',nargs='?',help='モーターのデバイスファイル指定 (default:/dev/ttyUSB0)') args = parser.parse_args() os.system('clear') for i in range(24): print("       ") print("\033[19;2H","---------------------------------------", "\033[2;2H\033[2K", end="",flush=True) motor_angle = 0 """ ---------------------- モーターに接続し、各種情報の取得 ---------------------- """ ##モーター回転情報callback def on_motor_measurement_cb(measurement): print("\033[2;2H\033[2K", end="") print('measurement {} '.format(measurement), end="", flush=True) print(measurement['position']) #global motor_angle motor_angle = measurement['position'] print(motor_angle) ##IMU情報callback def on_motor_imu_measurement_cb(measurement): print("\033[6;2H\033[2K", end="") print('imu_measurement {} '.format(measurement), end="", flush=True) ##ログ情報callback def on_motor_log_cb(log): print("\033[12;2H\033[2K", end="", flush=True) print('log {} '.format(log), end="", flush=True) ##エラー情報callback def on_motor_connection_error_cb(e): print("\033[16;2H\033[2K", end="", flush=True) print('error {} '.format(e), end="", flush=True) # 送信側プログラム # 送信側アドレスの設定 # 送信側IP SrcIP = "127.0.0.1" #PC内で送信するとき #SrcIP = "192.168.0.118" #別端末に送信するとき # 送信側ポート番号 SrcPort = 60000 # 送信側アドレスをtupleに格納 SrcAddr = (SrcIP,SrcPort) # 受信側アドレスの設定 # 受信側IP(受信端末によって変更) DstIP = "127.0.0.5" # 受信側ポート番号 DstPort = 55555 # 受信側アドレスをtupleに格納 DstAddr = (DstIP,DstPort) # ソケット作成 udpClntSock = socket(AF_INET, SOCK_DGRAM) # 送信側アドレスでソケットを設定 udpClntSock.bind(SrcAddr) # 送信データの作成 while True: data = motor_angle # バイナリに変換 #data = data.encode('utf-8') data = bytes(motor_angle)   #print(data) # 受信側アドレスに送信 udpClntSock.sendto(data,DstAddr) #モータの接続 #dev=usbcontroller.USBController('/dev/ttyUSB0',False)#モーターのアドレス 参照 usb-simple-connection.py dev=usbcontroller.USBController(args.port,False)#モーターのアドレス 参照 usb-simple-connection.py dev.on_motor_measurement_value_cb=on_motor_measurement_cb dev.on_motor_imu_measurement_cb=on_motor_imu_measurement_cb dev.on_motor_log_cb=on_motor_log_cb dev.on_motor_connection_error_cb=on_motor_connection_error_cb dev.enable_continual_imu_measurement()#IMUはデフォルトでOFFの為、取得する場合Onにする #モーター動作 dev.set_led(2,255,255,0) sleep(3) dev.enable_action() dev.set_speed(1.0) dev.run_forward() sleep(10) dev.disable_action() """ Exit with key input """ sleep(0.5) while True: print("\033[20;2H", end="",flush=True) print("---------------------------------------") inp = input('Exit:[key input] >>') if inp !=None: dev.set_led(1, 100, 100, 100) dev.disable_action() dev.disconnect() break

試したこと

While文を削除した結果、モータの各情報が取得できていました。
送信データの作成以下をWhile文に入れずに実行するとmotor_angleという文字列が送信されていました。(受信用で確認)
上記のことからWhileを使うことでそちらの処理が優先され、その他の処理(モータの動作)が行われることがなかったので空のデータが送られたのではないかと考えています。
そこでWhile文をUDP送信用の関数に変更したらよいのではないかと思い他サイトを見ていましたがどのように記述すればわからず困っています。

補足情報(FW/ツールのバージョンなど)

Python3で制御しています

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

上記のことからWhileを使うことでそちらの処理が優先され、その他の処理(モータの動作)が行われることがなかったので空のデータが送られたのではないかと考えています。

優先されるというより、while Trueの無限ループになっていて、なかでbreakする処理もないので、
それより後ろの部分は全く実行されません。

python

1# 送信データの作成 2while True: 3 data = motor_angle 4 # バイナリに変換 5 #data = data.encode('utf-8') 6 data = bytes(motor_angle) 7  #print(data) 8 # 受信側アドレスに送信 9 udpClntSock.sendto(data,DstAddr)

whileブロックの中では、motor_angleは上のほうで0が代入されてそれ以降は変化しないので、
bytes(0)(=空バイト列b'')を送信し続けるだけです。
なので下記の結果になります。

受信側のプログラムで確認すると送信側のIPアドレスとポート番号しか送られてきていません。

対処方法ですが、pykeigan というモジュールが、このプログラムの肝になっているので、
それの使い方をちゃんと理解することからスタートしたらよいと思います。
ぱっと見た感じでは、コールバック関数をセットして動作させるようなので、
データを受信したときにどの関数がコールされるのかを調べてみてはどうでしょうか。

単純には、print(motor_angle) しているところで、
UDP送信したらいいんじゃないのかという気がしますが、
それでいいのかはわかりません。

投稿2021/06/12 14:24

bsdfan

総合スコア4044

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Antlia

2021/06/12 18:41

bsdfanさんありがとうございます。 「whileブロックの中では、motor_angleは上のほうで0が代入されてそれ以降は変化しないので、 bytes(0)(=空バイト列b'')を送信し続けるだけです。 なので下記の結果になります。」 の部分について解説ありがとうございます。空のバイト列が送られている理由がわかりました。 単純には、print(motor_angle) しているところで、 UDP送信したらいいんじゃないのかという気がしますが、 それでいいのかはわかりません。 について少し自分で書き直して試してみようと思います。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

並列処理

複数の計算が同時に実行される手法

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。