├── .gitignore ├── README.md ├── Simple-tello-control-GUI ├── README.md ├── command.txt ├── stats.py ├── tello-command-test.py ├── tello-control-GUI.PNG ├── tello-control-GUI.py └── tello.py └── Tello-SDK-2.0-User-Guide-2018.11.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tello-Python3 2 | 3 | ## Introduction 4 | 5 | This repository is forked from [dji-sdk/Tello-Python](https://github.com/dji-sdk/Tello-Python) and based on **python3**. It contains some simple codes for Ryze Tello drone control. 6 | 7 | ## Environmental configuration 8 | 9 | Windows10x64 and Python3.6.5 10 | 11 | ## Project Description 12 | 13 | - **Simple-tello-control-GUI** 14 | 15 | a simple GUI for command test. 16 | 17 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/README.md: -------------------------------------------------------------------------------- 1 | # A simple GUI of Tello control 2 | 3 | 4 | # Simple-tello-control-GUI 5 | ## GUI test 6 | run **tello-control-GUI.py** with python3. First to press the command buttom to enter the the SDK mode, then you can press takeoff button and do other operations. 7 | 8 | 9 | ## Predefined commands mode 10 | Write the command set to be run in command.txt, for example:: 11 | ``` 12 | command 13 | takeoff 14 | delay 1 15 | up 20 16 | delay 1 17 | foward 20 18 | delay 1 19 | right 20 20 | delay 1 21 | back 20 22 | delay 1 23 | left 20 24 | delay 1 25 | land 26 | ``` 27 | 28 | The script will automatically send a command to Tello. After receiving the reply from the previous command, the next command will be sent immediately. To add a delay, you can use the Delay command and the script will automatically delay. The unit of delay is seconds, which can be given to decimals. 29 | 30 | Run the **tello-command-test.py** script 31 | 32 | After the execution is finished, the commands and execution information will be stored in the log. 33 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/command.txt: -------------------------------------------------------------------------------- 1 | command 2 | takeoff 3 | delay 1 4 | up 20 5 | delay 1 6 | foward 20 7 | delay 1 8 | right 20 9 | delay 1 10 | back 20 11 | delay 1 12 | left 20 13 | delay 1 14 | land 15 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/stats.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | class Stats: 4 | def __init__(self, command, id): 5 | self.command = command 6 | self.response = None 7 | self.id = id 8 | 9 | self.start_time = datetime.now() 10 | self.end_time = None 11 | self.duration = None 12 | 13 | def add_response(self, response): 14 | self.response = response 15 | self.end_time = datetime.now() 16 | self.duration = self.get_duration() 17 | # self.print_stats() 18 | 19 | def get_duration(self): 20 | diff = self.end_time - self.start_time 21 | return diff.total_seconds() 22 | 23 | def print_stats(self): 24 | print('\nid: %s'%(self.id)) 25 | print('command: %s'%(self.command)) 26 | print('response: %s'%(self.response)) 27 | print('start time: %s'%(self.start_time)) 28 | print('end_time: %s'%(self.end_time)) 29 | print('duration: %s\n'%(self.duration)) 30 | 31 | def got_response(self): 32 | if self.response is None: 33 | return False 34 | else: 35 | return True 36 | 37 | def return_stats(self): 38 | s = '' 39 | s += '\nid: %s\n' % self.id 40 | s += 'command: %s\n' % self.command 41 | s += 'response: %s\n' % self.response 42 | s += 'start time: %s\n' % self.start_time 43 | s += 'end_time: %s\n' % self.end_time 44 | s += 'duration: %s\n' % self.duration 45 | return s 46 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/tello-command-test.py: -------------------------------------------------------------------------------- 1 | from tello import Tello 2 | import sys 3 | from datetime import datetime 4 | import time 5 | 6 | start_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) 7 | 8 | f = open('command.txt', "r") 9 | commands = f.readlines() 10 | 11 | tello = Tello() 12 | for command in commands: 13 | if command != '' and command != '\n': 14 | command = command.rstrip() 15 | 16 | if command.find('delay') != -1: 17 | sec = float(command.partition('delay')[2]) 18 | print('delay %s'%(sec)) 19 | time.sleep(sec) 20 | pass 21 | else: 22 | tello.send_command(command) 23 | 24 | log = tello.get_log() 25 | 26 | out = open('log/' + start_time + '.txt', 'w') 27 | 28 | for stat in log: 29 | stat.print_stats() 30 | str1 = stat.return_stats() 31 | out.write(str1) 32 | out.close() 33 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/tello-control-GUI.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangwuqi/Tello-Python3/d9a26e23484828bbbefac225fdbb2a6f07f21566/Simple-tello-control-GUI/tello-control-GUI.PNG -------------------------------------------------------------------------------- /Simple-tello-control-GUI/tello-control-GUI.py: -------------------------------------------------------------------------------- 1 | # python3 2 | 3 | from tkinter import * 4 | from datetime import datetime 5 | import time 6 | from tello import Tello 7 | import sys 8 | 9 | tello = Tello() 10 | 11 | d='20' 12 | a='1' 13 | 14 | root = Tk() 15 | root.geometry("800x450+100+50") 16 | root.title('Tello Drone Control') 17 | 18 | frame0 = Frame(root,width=800, height=10) 19 | frame_scale = Frame(root) 20 | 21 | frame12= Frame(root) 22 | frame1 = Frame(frame12) 23 | frame2 = Frame(frame12) 24 | 25 | frame_flip = Frame(root) 26 | 27 | 28 | button_command = Button(frame0, text='command', width=10, command=lambda: tello.send_command( 29 | 'command')).grid(row=0, column=0, padx=90, pady=10) 30 | button_takeoff = Button(frame0, text='takeoff', width=10, command=lambda: tello.send_command( 31 | 'takeoff')).grid(row=0, column=1, padx=90, pady=10) 32 | button_land = Button(frame0, text='land', width=10, command=lambda: tello.send_command( 33 | 'land')).grid(row=0, column=2, padx=90, pady=10) 34 | 35 | # buttons to control flying forward, back, left and right 36 | button_forward = Button(frame1, text='forward', height=1, width=8, 37 | command=lambda: tello.send_command('forward '+d)).grid(row=0, column=1) 38 | button_back = Button(frame1, text='back', height=1, width=8, 39 | command=lambda: tello.send_command('back '+d)).grid(row=2, column=1) 40 | button_left = Button(frame1, text='left', height=1, width=8, 41 | command=lambda: tello.send_command('left '+d)).grid(row=1, column=0) 42 | button_right = Button(frame1, text='right', height=1, width=8, 43 | command=lambda: tello.send_command('right '+d)).grid(row=1, column=2) 44 | 45 | # buttons to control flying up, down, spin left and spin right 46 | button_up = Button(frame2, text='up', height=1, width=8, 47 | command=lambda: tello.send_command('up '+d)).grid(row=0, column=1) 48 | button_down = Button(frame2, text='down', height=1, width=8, 49 | command=lambda: tello.send_command('down '+d)).grid(row=2, column=1) 50 | button_spinleft = Button(frame2, text='spin left', height=1, width=8, 51 | command=lambda: tello.send_command('cw '+a)).grid(row=1, column=0) 52 | button_spinright = Button(frame2, text='spin right', height=1, width=8, 53 | command=lambda: tello.send_command('ccw '+a)).grid(row=1, column=2) 54 | 55 | # buttons to control flipping forward, back, left and right 56 | button_flip_f = Button(frame_flip, text='flip forward', height=1, width=10, 57 | command=lambda: tello.send_command('flip f')).grid(row=0, column=1) 58 | button_flip_b = Button(frame_flip, text='flip back', height=1, width=10, 59 | command=lambda: tello.send_command('flip b')).grid(row=2, column=1) 60 | button_flip_l = Button(frame_flip, text='flip left', height=1, width=10, 61 | command=lambda: tello.send_command('flip l')).grid(row=1, column=0) 62 | button_flip_r = Button(frame_flip, text='flip right', height=1, width=10, 63 | command=lambda: tello.send_command('flip r')).grid(row=1, column=2) 64 | 65 | # scrollbar to set the angle to rotate 66 | angle_change=Scale(frame_scale,from_=1,to=360,orient=HORIZONTAL,tickinterval=60,resolution=1,length=200) 67 | angle_change.grid(row=0, column=1,padx=95) 68 | def speed_change(): 69 | a=str(angle_change.get()) 70 | print('rotate angle set: ', a) 71 | angle=Button(frame_scale,text='angle confirm',padx=4,command=angle_change) 72 | angle.grid(row=1, column=1) 73 | 74 | # scrollbar to set the distance to fly 75 | distance_change=Scale(frame_scale,from_=20,to=500,orient=HORIZONTAL,tickinterval=100,resolution=10,length=200) 76 | distance_change.grid(row=0, column=0,padx=95) 77 | def speed_change(): 78 | d=str(distance_change.get()) 79 | print('flying distance set: ', d) 80 | distance=Button(frame_scale,text='distance confirm',padx=4,command=speed_change) 81 | distance.grid(row=1, column=0) 82 | 83 | 84 | frame0.pack() 85 | frame_scale.pack( pady=20) 86 | frame1.grid(row=0, column=0,padx=80) 87 | frame2.grid(row=0, column=1,padx=80) 88 | frame12.pack(pady=0) 89 | frame_flip.pack(pady=30) 90 | 91 | mainloop() 92 | -------------------------------------------------------------------------------- /Simple-tello-control-GUI/tello.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import threading 3 | import time 4 | from stats import Stats 5 | 6 | class Tello: 7 | def __init__(self): 8 | self.local_ip = '' 9 | self.local_port = 8889 10 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # socket for sending cmd 11 | self.socket.bind((self.local_ip, self.local_port)) 12 | 13 | # thread for receiving cmd ack 14 | self.receive_thread = threading.Thread(target=self._receive_thread) 15 | self.receive_thread.daemon = True 16 | self.receive_thread.start() 17 | 18 | self.tello_ip = '192.168.10.1' 19 | self.tello_port = 8889 20 | self.tello_adderss = (self.tello_ip, self.tello_port) 21 | self.log = [] 22 | 23 | self.MAX_TIME_OUT = 15.0 24 | 25 | def send_command(self, command): 26 | """ 27 | Send a command to the ip address. Will be blocked until 28 | the last command receives an 'OK'. 29 | If the command fails (either b/c time out or error), 30 | will try to resend the command 31 | :param command: (str) the command to send 32 | :param ip: (str) the ip of Tello 33 | :return: The latest command response 34 | """ 35 | self.log.append(Stats(command, len(self.log))) 36 | 37 | self.socket.sendto(command.encode('utf-8'), self.tello_adderss) 38 | print('sending command: %s to %s'%(command, self.tello_ip)) 39 | 40 | start = time.time() 41 | while not self.log[-1].got_response(): 42 | now = time.time() 43 | diff = now - start 44 | if diff > self.MAX_TIME_OUT: 45 | print('Max timeout exceeded... command %s'%(command)) 46 | # TODO: is timeout considered failure or next command still get executed 47 | # now, next one got executed 48 | return 49 | print('Done!!! sent command: %s to %s'%(command, self.tello_ip)) 50 | 51 | def _receive_thread(self): 52 | """Listen to responses from the Tello. 53 | 54 | Runs as a thread, sets self.response to whatever the Tello last returned. 55 | 56 | """ 57 | while True: 58 | try: 59 | self.response, ip = self.socket.recvfrom(1024) 60 | print('from %s: %s'%(ip, self.response)) 61 | 62 | self.log[-1].add_response(self.response) 63 | except socket.error as exc: 64 | print("Caught exception socket.error : %s"%(exc)) 65 | 66 | def on_close(self): 67 | pass 68 | # for ip in self.tello_ip_list: 69 | # self.socket.sendto('land'.encode('utf-8'), (ip, 8889)) 70 | # self.socket.close() 71 | 72 | def get_log(self): 73 | return self.log 74 | 75 | -------------------------------------------------------------------------------- /Tello-SDK-2.0-User-Guide-2018.11.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangwuqi/Tello-Python3/d9a26e23484828bbbefac225fdbb2a6f07f21566/Tello-SDK-2.0-User-Guide-2018.11.pdf --------------------------------------------------------------------------------