前提・実現したいこと
[Python]telloEduで編隊飛行を行った際のカメラ映像の取得方法を教えてください。
この質問は以下のサイトでマルチポストしています。
分かったこと、補足説明や解決方法はどちらのサイトにも更新します。
http://qiita.com/tiffany1098/questions/70c0cbfba80ec8ffa1f1
UDPやIPアドレスについてあまり詳しくないため、間違っていましたらご指摘お願いします。
発生している問題
tellopyなどは使わず、TelloSDK2.0のコマンド送信によるプログラムを書いています。
TelloEdu1台での飛行時のカメラ映像は「command」の次に「streamon」とコマンドを送信したのち、OpecCVで
cap = cv2.VideoCapture('udp://0.0.0.0:11111')
ret,frame = cap.read()
cv2.imshow('',frame)
と書きtelloの映像を取得していました。1台の時はこの方法でPC画面に映像を表示させることに成功しました。
しかし、telloEDU3台の編隊飛行の際はこの方法では成功しません。実行画面ではstreamon OK まで進み、その後何も起こりません。3台使うことによりカメラのUDPが変わるなど、何か原因があると思うのですがそれが分かりません。
telloEDUの編隊飛行(前進、後退などの単純な動き)自体はうまくいっています。
#補足説明
tello 1台のときはtello自体がwifiアクセスポイントとなります。
telloのIPアドレス、ポート番号は公式通りに
('192.168.10.1',8889)
を使用しています。
映像受信時のUDPも公式通りに
('udp://0.0.0.0:11111')
を使用しています。
tello3台のときは
wifiルーターにtello3台とパソコンをつなげているため、IPアドレスが変わるため
ドローン1:('192.168.100.112',8889)
ドローン2:('192.168.100.113',8889)
ドローン3:('192.168.100.114',8889)
を使用しています。このIPアドレスはwifiにつなげた状態でパソコンでIPアドレススキャナーのアプリでスキャンして得ました。
映像受信時のUDPは1台の時と変わらず
('udp://0.0.0.0:11111')
を使用していますが、映像を取得できませんでした。「streamon」はきちんと送れているようなので、telloのIPアドレスは正しく、映像受信時のUDPが間違っているのではないかと考えています。
IPアドレスを変更するとUDPも変わるのでしょうか。変わるとしても、変更後の値が分かりません。そもそも編隊飛行ではカメラを使えないのでしょうか。
ご回答宜しくお願い致します。
#試したこと
①
https://joho-ka.mints.ne.jp/multi-camras-with-opencv?doing_wp_cron=1599214242.8721311092376708984375
こちらのサイトのcapture = cv2.VideoCapture(i)のiの値を変えていく方法はうまくいきませんでした。この方法はパソコンに直接つなぐタイプのカメラにしか使えないようで、通信で映像を取得するtelloには使うことができませんでした。
②
wi-fiルーターにパソコンとドローン3台ではなく、1台のみ接続し試しました。
ドローン1:('192.168.100.112',8889)
('udp://0.0.0.0:11111')
で試しましたが、「streamon OK」で止まり、映像の取得はできませんでした。
つまり、混信以前のUDPなどが間違っていることになるのでしょうか。
Python
1#試したこと② 2import socket 3import threading 4import time 5import cv2 6 7event = threading.Event() 8 9sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 10sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True) 11sock.bind(('',9000)) 12 13tello1_address = ('192.168.100.112',8889) 14 15def send_command1(msg): 16 print(msg) 17 msg = msg.encode(encoding="utf-8") 18 sock.sendto(msg,tello1_address) 19 event.wait() 20 event.clear() 21 22def send_command2(msg): 23 print(msg) 24 msg = msg.encode(encoding="utf-8") 25 sock.sendto(msg,tello2_address) 26 event.wait() 27 event.clear() 28 29def send_command3(msg): 30 print(msg) 31 msg = msg.encode(encoding="utf-8") 32 sock.sendto(msg,tello3_address) 33 event.wait() 34 event.clear() 35 36def send_command(msg): 37 print(msg,msg,msg, sep='\n', end='\n') 38 msg = msg.encode(encoding="utf-8") 39 sock.sendto(msg,tello1_address) 40 sock.sendto(msg,tello2_address) 41 sock.sendto(msg,tello3_address) 42 event.wait() 43 event.clear() 44 45def send_command12(msg1,msg2): 46 print(msg1,msg2, sep='\n', end='\n') 47 msg1 = msg1.encode(encoding="utf-8") 48 msg2 = msg2.encode(encoding="utf-8") 49 sock.sendto(msg1,tello1_address) 50 sock.sendto(msg2,tello2_address) 51 event.wait() 52 event.clear() 53 54def send_command23(msg2,msg3): 55 print(msg2,msg3, sep='\n', end='\n') 56 msg2 = msg2.encode(encoding="utf-8") 57 msg3 = msg3.encode(encoding="utf-8") 58 sock.sendto(msg2,tello2_address) 59 sock.sendto(msg3,tello3_address) 60 event.wait() 61 event.clear() 62 63def send_command13(msg1,msg3): 64 print(msg1,msg3, sep='\n', end='\n') 65 msg1 = msg1.encode(encoding="utf-8") 66 msg3 = msg3.encode(encoding="utf-8") 67 sock.sendto(msg1,tello1_address) 68 sock.sendto(msg3,tello3_address) 69 event.wait() 70 event.clear() 71 72def send_command123(msg1,msg2,msg3): 73 print(msg1,msg2,msg3, sep='\n', end='\n') 74 msg1 = msg1.encode(encoding="utf-8") 75 msg2 = msg2.encode(encoding="utf-8") 76 msg3 = msg3.encode(encoding="utf-8") 77 sock.sendto(msg1,tello1_address) 78 sock.sendto(msg2,tello2_address) 79 sock.sendto(msg3,tello3_address) 80 event.wait() 81 event.clear() 82 83def recv(): 84 while True: 85 try: 86 data,server = sock.recvfrom(1518) 87 print(data.decode(encoding="utf-8")) 88 event.set() 89 except Exception: 90 break 91recvThread = threading.Thread(target=recv) 92recvThread.start() 93 94 95def main(): 96 try: 97 send_command1('command') 98 send_command1('streamon') 99 100 cap1 = cv2.VideoCapture('udp://0.0.0.0:11111') 101 102 while True: 103 ret,frame1 = cap1.read() 104 cv2.imshow('TelloEDU1',frame1) 105 106 key = cv2.waitKey(1) 107 if key == 27: 108 break 109 110 111 except Exception as ex: 112 print(ex) 113 finally: 114 cap1.release() 115 cv2.destroyAllWindows() 116 send_command1('streamoff') 117 sock.close() 118 print('--- END ---') 119 120if __name__ == '__main__': 121 main()
③
('192.168.10.1',8889)と('udp://0.0.0.0:11111')がセットになっている(対になっている)可能性があるか調べました。wi-fiルーターにパソコンとドローンを1台接続し、ドローンは192.168.10.1に割り振られるようにルーター側で設定しました。
この方法もうまくいかず、「streamon OK」で止まりました。
④
ドローン自体をwi-fiアクセスポイントとしたとき(パソコンとドローンを1対1で接続)、
('192.168.10.1',8889)('udp://0.0.0.0:11111')
('192.168.10.1',8889)('udp://127.0.0.1:11111')
('192.168.10.1',8889)('udp://192.168.10.2:11111')
のように映像受信時のIPアドレスを変えても、映像を受信できました。
⑤
wi-fiルーターではなく、ドローンをwi-fiのアクセスポイントとしたとき、このアクセスポイントに他のドローンも接続できるか試しましたができませんでした。
該当のソースコード
Python
1import socket 2import threading 3import time 4import cv2 5''' 6from formationflight.multi_1.tello1 import Tello1 7from formationflight.multi_1.tello2 import Tello2 8from formationflight.multi_1.tello3 import Tello3 9 10tello1 = Tello1() 11tello2 = Tello2() 12tello3 = Tello3() 13''' 14 15event = threading.Event() 16 17sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 18sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True) 19sock.bind(('',9000)) 20 21tello1_address = ('192.168.100.112',8889) 22tello2_address = ('192.168.100.113',8889) 23tello3_address = ('192.168.100.114',8889) 24 25def send_command1(msg): 26 print(msg) 27 msg = msg.encode(encoding="utf-8") 28 sock.sendto(msg,tello1_address) 29 event.wait() 30 event.clear() 31 32def send_command2(msg): 33 print(msg) 34 msg = msg.encode(encoding="utf-8") 35 sock.sendto(msg,tello2_address) 36 event.wait() 37 event.clear() 38 39def send_command3(msg): 40 print(msg) 41 msg = msg.encode(encoding="utf-8") 42 sock.sendto(msg,tello3_address) 43 event.wait() 44 event.clear() 45 46def send_command(msg): 47 print(msg,msg,msg, sep='\n', end='\n') 48 msg = msg.encode(encoding="utf-8") 49 sock.sendto(msg,tello1_address) 50 sock.sendto(msg,tello2_address) 51 sock.sendto(msg,tello3_address) 52 event.wait() 53 event.clear() 54 55def send_command12(msg1,msg2): 56 print(msg1,msg2, sep='\n', end='\n') 57 msg1 = msg1.encode(encoding="utf-8") 58 msg2 = msg2.encode(encoding="utf-8") 59 sock.sendto(msg1,tello1_address) 60 sock.sendto(msg2,tello2_address) 61 event.wait() 62 event.clear() 63 64def send_command23(msg2,msg3): 65 print(msg2,msg3, sep='\n', end='\n') 66 msg2 = msg2.encode(encoding="utf-8") 67 msg3 = msg3.encode(encoding="utf-8") 68 sock.sendto(msg2,tello2_address) 69 sock.sendto(msg3,tello3_address) 70 event.wait() 71 event.clear() 72 73def send_command13(msg1,msg3): 74 print(msg1,msg3, sep='\n', end='\n') 75 msg1 = msg1.encode(encoding="utf-8") 76 msg3 = msg3.encode(encoding="utf-8") 77 sock.sendto(msg1,tello1_address) 78 sock.sendto(msg3,tello3_address) 79 event.wait() 80 event.clear() 81 82def send_command123(msg1,msg2,msg3): 83 print(msg1,msg2,msg3, sep='\n', end='\n') 84 msg1 = msg1.encode(encoding="utf-8") 85 msg2 = msg2.encode(encoding="utf-8") 86 msg3 = msg3.encode(encoding="utf-8") 87 sock.sendto(msg1,tello1_address) 88 sock.sendto(msg2,tello2_address) 89 sock.sendto(msg3,tello3_address) 90 event.wait() 91 event.clear() 92 93def recv(): 94 while True: 95 try: 96 data,server = sock.recvfrom(1518) 97 print(data.decode(encoding="utf-8")) 98 event.set() 99 except Exception: 100 break 101recvThread = threading.Thread(target=recv) 102recvThread.start() 103 104 105def main(): 106 try: 107 send_command('command') 108 send_command1('streamon') 109 110 cap1 = cv2.VideoCapture('udp://0.0.0.0:11111') 111 #cap2 = cv2.VideoCapture('udp://0.0.0.0:11111') 112 #cap3 = cv2.VideoCapture('udp://0.0.0.0:11111') 113 114 while True: 115 ret,frame1 = cap1.read() 116 cv2.imshow('TelloEDU',frame1) 117 118 key = cv2.waitKey(1) 119 if key == 27: 120 break 121 122 123 except Exception as ex: 124 print(ex) 125 finally: 126 cap.release() 127 cv2.destroyAllWindows() 128 send_command('streamoff') 129 sock.close() 130 print('--- END ---') 131 132if __name__ == '__main__': 133 main()
補足情報(FW/ツールのバージョンなど)
python 3.7.6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/05 08:49
2020/09/05 13:03
2020/09/07 03:34 編集
2020/09/07 04:11
2020/09/07 13:14
2020/09/08 03:52