카테고리 없음

Tello Drone Video 전송(python)

Wood Pecker 2021. 8. 2. 19:37

1. 개요

파이썬 프로그램을 이용하여 Tello 드론의 비디오를 PC로 전송 받아보자.

2. 프로그램

import socket
import cv2

if __name__ == "__main__":
    tello_ip = '192.168.10.1'
    tello_port = 8889
    tello_address = (tello_ip, tello_port)
    mypc_address = ("0.0.0.0", tello_port)
    socket = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
    socket.bind (mypc_address)

    socket.sendto ('command'.encode (' utf-8 '), tello_address)
    socket.sendto ('streamon'.encode (' utf-8 '), tello_address)
    print ("Start streaming")

    capture = cv2.VideoCapture ('udp://0.0.0.0:11111',cv2.CAP_FFMPEG)
    if not capture.isOpened():
        capture.open('udp://0.0.0.0:11111')

    while True:
        ret, frame =capture.read()
        print(ret)
        if(ret):
            cv2.imshow('frame', frame)
        if cv2.waitKey (1)&0xFF == ord ('q'):
            break
    capture.release ()
    cv2.destroyAllWindows ()
    socket.sendto ('streamoff'.encode (' utf-8 '), tello_address)
    pass

프로그램을 실행전에 PC의 와이파이를 드론의 AP에 접속하여야 한다. 프로그램을 시작해 보자. 영상이 보이면 성공이다. 만일 비디오 전송이 안되고 멈춰 있다면 윈도우즈인 경우 FireWall을 의심해 보자. 인바운드 규칙 어딘가에 UDP port 11111을 막었을지 모른다. 설정에서 인바운드 규칙을 검토해본다.

3. 클래스 방식으로 작성

SDK처럼 클래스를 이용하여 객체를 만들어 사용하여 보자.

   import threading
import socket
import time
import cv2
class MyTello:
    def __init__(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # socket for sending cmd
        self.socket.bind(("0.0.0.0", 8889))

        self.tello_address = ("192.168.10.1", 8889)
        self.receive_thread = threading.Thread(target=self.receive_thread)
        self.receive_thread.daemon = True
        self.receive_thread.start()

        self.socket.sendto('command'.encode('utf-8'), self.tello_address)
        print('sent: command')
        time.sleep(1)
        self.socket.sendto('streamon'.encode('utf-8'), self.tello_address)
        print('sent: streamon\r\n')
        self._running = True

    def terminate(self):
        self._running = False
        self.video.release()
        cv2.destroyAllWindows()

    def receive_thread(self):
        while True:
            try:
                self.response, ip = self.socket.recvfrom(3000)
                print(self.response)
            except socket.error as exc:
                print("Caught exception socket.error : %s" % exc)

    def recv(self):
        self.video = cv2.VideoCapture("udp://@0.0.0.0:11111")
        while self._running:
            try:
                ret, frame = self.video.read()
                if ret:
                    cv2.imshow('Tello', frame)
                cv2.waitKey(1)
            except Exception as err:
                print(err)

    def mystart(self):
        self.recv_videoThread = threading.Thread(target=self.recv)
        self.recv_videoThread.daemon = True
        self.recv_videoThread.start()
        pass

    def myStop(self):
        print('myStop')
        self.recvThread.terminate()
        pass

if __name__ == "__main__":
    print("Start program....")
    myTello= MyTello()
    myTello.mystart()
    x = input('Enter Any key to stop')
    myTello.myStop()
    print("\n\nEnd of Program\n")
반응형