実現したいこと
私が実行したいのは以下の通りです。
①TELLOドローンをPythonで自動操縦したい。(プログラムを起動したら勝手に進んでくれる)
②TELLOドローンのカメラで映像をリアルタイムで取得し、カメラ映像をウィドウに表示させたい
③そのカメラ映像をパソコンで保存できるようにしたい
前提
TELLOドローンの自動操縦をしたいと思っています。
下記のソースコードで、②と③は、多少の時差はありますが、受信と保存に成功できました。ただ①の自動操縦がうまくいきません。
最初の前進は、プログラム通り進みましたが、その後の左折が上手く進みません。
プログラム自体エラーはでていないので、どう直せばいいか分かりません。
どこを直せばいいか教えて下さい。
追記、
このサービス初めて登録したのですが、このサービスの規定をわかっていませんでした。
https://qiita.com/yyyyyyyyyyy/questions/3aed233612c3c11f9580
このサイトでも同じ質問をしてしまいました。申し訳ございません。
複数質問した理由は、以前質問したとき、回答数が少なかったため、色々なサイトで
聞きたかったため、今回、このサービスでも登録させていただきました。
import socket import threading import cv2 import numpy as np import av import traceback import time # データ受け取り用の関数 def udp_receiver(): global battery_text global time_text global status_text while True: try: data, server = sock.recvfrom(1518) resp = data.decode(encoding="utf-8").strip() # レスポンスが数字だけならバッテリー残量 if resp.isdecimal(): battery_text = "Battery:" + resp + "%" # 最後の文字がsなら飛行時間 elif resp[-1:] == "s": time_text = "Time:" + resp else: status_text = "Status:" + resp except: pass # 問い合わせ def ask(): while True: try: sent = sock.sendto('battery?'.encode(encoding="utf-8"), TELLO_ADDRESS) except: pass time.sleep(0.5) try: sent = sock.sendto('time?'.encode(encoding="utf-8"), TELLO_ADDRESS) except: pass time.sleep(0.5) # Tello側のローカルIPアドレス(デフォルト)、宛先ポート番号(コマンドモード用) TELLO_IP = '192.168.10.1' TELLO_PORT = 8889 TELLO_ADDRESS = (TELLO_IP, TELLO_PORT) # Telloからの映像受信用のローカルIPアドレス、宛先ポート番号 TELLO_CAMERA_ADDRESS = 'udp://@0.0.0.0:11111' command_text = "None" battery_text = "Battery:" time_text = "Time:" status_text = "Status:" # キャプチャ用のオブジェクト cap = None # データ受信用のオブジェクト備 response = None # 通信用のソケットを作成 # ※アドレスファミリ:AF_INET(IPv4)、ソケットタイプ:SOCK_DGRAM(UDP) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 自ホストで使用するIPアドレスとポート番号を設定 sock.bind(('', TELLO_PORT)) # 問い合わせスレッド起動 ask_thread = threading.Thread(target=ask) ask_thread.setDaemon(True) ask_thread.start() # 受信用スレッドの作成 recv_thread = threading.Thread(target=udp_receiver, args=()) recv_thread.daemon = True recv_thread.start() # コマンドモード sock.sendto('command'.encode('utf-8'), TELLO_ADDRESS) sock.sendto('takeoff'.encode('utf-8'), TELLO_ADDRESS) time.sleep(1) # OpenCVで録画するためのファイル名とファイル形式を指定します filename = "shiken.avi" fourcc = cv2.VideoWriter_fourcc(*"XVID") fps = 30.0 frameSize = (960, 720) # 録画用のオブジェクトを作成します out = cv2.VideoWriter(filename, fourcc, fps, frameSize) # カメラ映像のストリーミング開始 sock.sendto('streamon'.encode('utf-8'), TELLO_ADDRESS) time.sleep(1) if cap is None: cap = cv2.VideoCapture(TELLO_CAMERA_ADDRESS) fps = 30 if not cap.isOpened(): cap.open(TELLO_CAMERA_ADDRESS) time.sleep(5) sock.sendto('forward 200'.encode('utf-8'), TELLO_ADDRESS) time.sleep(1) sock.sendto('left 200'.encode('utf-8'), TELLO_ADDRESS) time.sleep(1) sock.sendto('left 200'.encode('utf-8'), TELLO_ADDRESS) while (cap.isOpened()): ret, frame = cap.read() # 動画フレームが空ならスキップ if frame is None or frame.size == 0: continue # カメラ映像を画面に表示 cv2.imshow('Tello Camera View', frame) out.write(frame) # キー入力を取得 key = cv2.waitKey(1) # qキーで終了 if key == ord('q'): break # ビデオストリーミング停止 sock.sendto('streamoff'.encode('utf-8'), TELLO_ADDRESS) sock.sendto('land'.encode('utf-8'), TELLO_ADDRESS) #保存 cap.release() out.release() cv2.destroyAllWindows()
あなたの回答
tips
プレビュー