Automated Drone Flight: Circular Flight

In this post, we are programming a more complex non-interactive flight mission for a TELLO EDU drone. As a foundation, we are using the information from this past post. The objective is to obtain a circular flight path or spiraling flight path for our drone while it records an element of interest inside the circle.


It isn't easy to maintain a circular path, a fixed distance to the center while rotating to face the circle's center. As all aircraft, including N-copters, have coupled displacements; it is difficult to move in a plane without affecting movement on other planes unless it is perfectly compensated. In our quadcopter case, rotation to face the center, yaw axis motion requires a differential in rotators speed that affects our sideways, along the circle line, movement. We will try to compensate this coupling for a fixed circle before we add interactively controlled station keeping.


Code-wise we are not changing much from our previous mission in terms of control. We have first to import the required Python libraries and connect to our drone:

import cv2from threading import Thread
from djitellopy import Tello
import osfrom time import sleep

tello = Tello()
tello.connect()
tello.query_battery()

We are adding more on-video information to our flight this time so that we modify our recording function to be this:

def videoRec():
    
    # Set video parameters:
    cmd = 'setresolution {}'.format('high')
    tello.send_control_command(cmd)
    cmd = 'setfps {}'.format('high')
    tello.send_control_command(cmd)
    
    # Set text overaly parameters:
    font                   = cv2.FONT_HERSHEY_SIMPLEX
    bottomLeftCornerOfText = (10,500)
    fontScale              = 1
    fontColor              = (255,255,255)
    lineType               = 2
        
    FPS = 30
    codec = 'h264'
    fourcc = cv2.VideoWriter_fourcc(*codec)
    
    # Start the drone stream:
    tello.streamon()
    sleep(0.1)
    
    # Grab a frame to check size:
    img = tello.get_frame_read().frame
    shape = (img.shape[1], img.shape[0])
        
    i = len(os.listdir(record_dir))
    video_file = cv2.VideoWriter(f'{record_dir}/test_flight_{i+1}.mp4', 
                                 fourcc, FPS, shape)
    while True:
        img = tello.get_frame_read().frame
        altitude = tello.get_height()
        pitch = tello.get_pitch()
        roll = tello.get_roll()
        yaw = tello.get_yaw()
        distance = tello.get_distance_tof()
        
        alt_txt = f'Height: {altitude/100:.2f}'
        pitch_txt = f'Pitch: {pitch}'
        roll_txt = f'Roll: {roll}'
        yaw_txt = f'Yaw: {yaw}'
        distance_txt = f'Distance: {distance}'
        
        info_txt = [alt_txt, 
                    pitch_txt, 
                    roll_txt, 
                    yaw_txt,
                    distance_txt]
        
        i = 0
        for txt in info_txt:
            x = bottomLeftCornerOfText[1]
            y = bottomLeftCornerOfText[0]
            position = ()
            cv2.putText(img, txt, 
            (y, x+i*50), 
            font, 
            fontScale,
            fontColor,
            lineType)
            i = i+1
        
        cv2.imshow ('Drone Video Feed', img)
        
        video_file.write(img)
        sleep(1/FPS)
        
        k = cv2.waitKey(1)
        if k == 27:         
        # wait for ESC key to exit and terminate feed.
            cv2.destroyAllWindows()
            video_file.release()
            tello.streamoff()
            break
    return 0

We are adding pitch, roll, yaw,, and covered flight distance into our screen. We will check in these test flights that movement sensors are providing readable information for our future interactive flights.


Our circular flight mission is this:

# Rotate in a Circle
def mission_B():
    tello.send_rc_control(0,0,0,0)
    sleep(0.1)
    # Turns motors on:
    tello.send_rc_control(-100,-100,-100,100)
    sleep(2)
    tello.send_rc_control(0,10,20,0)
    sleep(3)
    tello.send_rc_control(0,0,0,0)
    sleep(2)
    
    v_up = 0
    for _ in range(4):
        tello.send_rc_control(40, -5, v_up, -35)
        sleep(4)
        tello.send_rc_control(0,0,0,0)
        sleep(0.5)
    tello.land()
    return 0


This flight mission will execute 4 separate 90º circle arcs while pointing our drone into the center of the circle. We can command our drone to go up or down at the same time by altering v_up. The radius of the circle should be approximately 80 cm in this case. Then launching the recording thread and the mission thread can be achieved by:

#This thread runs receiving video feed.
receive_video_thread = Thread(target=videoRec)
receive_video_thread.daemon = True
receive_video_thread.start()
# Please wait until the video feed is up# to caputure the full flight.

And:

#This thread starts the flight pattern.
flight = mission_B
mission_thread = Thread(target=flight)
mission_thread.daemon = True
mission_thread.start()
receive_video_thread.join()
mission_thread.join()

The video feed takes a while to arrive, so it is easier to wait until there is a video feed to start the mission. This delay can be solved by inspecting the size of the video record file in the flight mission code, launching only when the video starts actually recoding. A more elegant and costly method is to check the UDP packets for the first h264 encoded frames. In any case, the flight results are these, using the same parameters, and outdoors, subjected to light winds and uneven terrain. The tree is for reference only:


The circular mission without in-flight interaction is prone to many errors; this flight shows a major distortion in the liftoff, and very light winds, sending the circle center off:


An active mode of flight that can correct the position mid-flight is needed to trace a perfect circle in the presence of disturbances. We will cover this method in another post.


Do not hesitate to contact us if you require quantitative model development, deployment, verification, or validation. We will also be glad to help you with your machine learning or artificial intelligence challenges when applied to asset management, automation, or intelligence gathering from satellite, drone, or fixed-point imagery.

11 views0 comments

Recent Posts

See All