In this entry, we aim to control two (with the capability of controlling more) DJI Ryze Tello drones from a single computer.
The Tello quadrocopter recieves commands via the WiFi hotspot it broadcasts. Therefore, to control multiple Tellos in a swarm, we must connect to each drone’s WiFi hotspot and broadcast commands to each drone individually. In order to do this, we need to have one WiFi interface for each drone we want to control. In this example, we will be using an external USB WiFi antenna in addition to our computer’s built-in WiFi card to connect to two Tello drones simultaneously. Specifically, we are using an Amped Wireless UA150C, although any WiFi card compatible with your computer should work. We will be programming on a Linux-based computer.
To begin, we need the identifiers of our computer’s WiFi interfaces. This can be accomplished by typing in the following command in terminal:
Below, you can see the results of this command. The two results that correspond with the two WiFi interfaces I am using are wlp2s0 and wlxf8788c004f09.
Now, we must connect each of our respective WiFi interfaces to the Tello drone we want it to control. This can be easily done by powering on the drones and connecting to them in our WiFi settings. Our two Tellos are broadcasting on networks TELLO-C4FD9 and TELLO-AC069B.
Writing the Code
To communicate with each of the Tello drones, we will connect to them using python. In my case, I need to open sockets on the wlp2s0 and wlxf8788c004f0 interfaces. We need to import the socket and time python libraries — socket will be used for sending commands and time will be used for issuing delays between commands. Thus, our code starts as follows:
import timedrone1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
drone1.setsockopt(socket.SOL_SOCKET, 2, 'wlp2s0')drone2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
drone2.setsockopt(socket.SOL_SOCKET, 2, 'wlxf8788c004f0')
From here, we have some flexibility. We can send any command supported by the official python Tello SDK. In the future, I would like to expand this method to work with the unofficial tellopy repository, which allows for more complex operations such as recieving and processing onboard video, flying with an external controller, and more precise drone control (including pitch, yaw, and roll). For this guide, we will write a simple takeoff and land script. First, we must tell the drones we are going to issue a command. Every Tello drone uses the IP address 192.168.10.1 and port 8889.
drone1.sendto('command'.encode(), 0, ('192.168.10.1', 8889))
drone2.sendto('command'.encode(), 0, ('192.168.10.1', 8889))
Next, we need to issue the command. Below, we issue a takeoff command.
drone1.sendto('takeoff'.encode(), 0, ('192.168.10.1', 8889))
drone2.sendto('takeoff'.encode(), 0, ('192.168.10.1', 8889))
After taking off, we want the program to halt for 5 seconds before issuing a land command. We do this by issuing a 5 second sleep command. Then, we tell the drones to land.
time.sleep(5)drone1.sendto('command'.encode(), 0, ('192.168.10.1', 8889))
drone2.sendto('command'.encode(), 0, ('192.168.10.1', 8889))drone1.sendto('land'.encode(), 0, ('192.168.10.1', 8889))
drone2.sendto('land'.encode(), 0, ('192.168.10.1', 8889))
Now we need to run the program. Open up terminal, navigate into the directory of the python program, and run it as sudo.
sudo python takeoff_and_land.py
Running as sudo will prompt terminal to ask for your password. This is because the socket class requires administrator access. After running, we get the following result:
In this tutorial, I used Ubuntu 18.04. Windows uses a different method of interacting with WiFi interfaces, so I used a unix-based operating system. When trying to run this script on macOS, I got an OSError message stating that the protocols I was trying to interface with were unaccessable. This was frustruating as I use a Mac as my primary machine. I was able to get this working by running Ubuntu in a virtual machine on my Mac, but it was very temperamental. In order to accomplish this on a VM, I used VirtualBox and set my two WiFi interfaces (the built-in WiFi card and the external USB RTL8188S WLAN WiFi antenna) as Bridged Adapters of type PCnet-FAST III (Am79C973). With these settings, the WiFi interfaces were both recognized natively by Ubuntu. Again, however, I would not recommend this as it can be tricky to get everything working correctly. Ideally, this would be run on a native linux environment.