├── .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
--------------------------------------------------------------------------------