Hello Tello Pilot!
Join our DJI Tello community & remove this banner.
Sign up

Using Python API to access the drone camera in picture mode

marcolli

Active member
Joined
Aug 3, 2018
Messages
37
Reaction score
10
Hi everyone, I posted this in the help forum it may be more relevant for this forum.

I'm working on a project where I want to use a python script, run from a computer, to command my drone to fly around and take pictures. My coding experience is quite limited and so far I've been using PyTello and TelloPy APIs to control the drone. With TelloPy I've managed to access the video stream and save screenshots from this. However, this isn't ideal due to the regular pixelation and glitches that form the video stream, which is why I want to access the single picture mode.

From what I've read so far, it seems to me that I need to sent a command to the Tello to take the picture, which seems fairly straightforward to me. However, I'm unsure how to go about saving images to my computer. Based on the implementation chart here and the Go documentation here it seems there is a "Save all pics" command which may be what I'm looking for, or at least a similar command in the drone firmware which would save images to my laptop. Unfortunately, I'm stuck on how to bring these parts together.

If anyone has achieved this through Python, or has any pointers, any help/advice would be greatly appreciated!
 
  • Like
Reactions: Zeno
Update: I've managed to get the picture command to work. As is mentioned in the wiki:
-The "Take Picture" command has to be sent to the drone
-The Tello captures an image and replies with a "File Size" command. The controlling device needs to send an acknowledging ""File Size" command.
-The Tello sends the image data as a series of "File Data" commands containing the image data, split into chunks. Each "piece" of the image is formed of chunks.
-According to the Wiki, each piece must be acknowledged with a "File Data" command sent to the drone. However, my code only started working when I got rid of these acknowledgments.
-Without acknowledgements, the Tello will send the file chunks numerous (anywhere between 2 and 5) times. Checking for duplicates is straightforward as each chunk has an identifying number.
-Simply ignore the duplicates and then re-order them based on their number to build the final JPG data.

I've implemented this in Python as an extension to PinguSoft's pytello library. Although my method might not be completely correct, it has so far worked and produces the expected images.

I'll share the code on the forum on Monday when I'm back at work.
 
  • Like
Reactions: Zeno
I've replied to your PM, but just in case anyone else is interested...

I _think_ the Wiki is correct, but I just added a note to ack the final chunk which may be <8 pieces long.

My Go code seems to work fine and uses the scheme outlined in the wiki - you can see it around lines 307 - 357 of SMerrony/tello
 
After speaking to SMerrony and also ToxicFrog, I agree that the method described in the wiki works as described and is better than my hack. ToxicFrog has managed to implement this in python, I can share the code as soon as I have his permission to do so.

Below is a snippet of the code I've used to implement the picture taking function. This is implemented withing the command receiving thread of the pyTello library.

It takes the chunk data and saves it in a dictionary with "chunkNo" keys and "chunkData" values. This way it is easy to check for any duplicates and ignore them. as well as automatically ordering the chunks correctly. I then use another function to write the data in the dictionary to a file to display the image.

N.b. the reason for having two separate elif commands is that originally I was sending file piece acknowledgments every 8 chunks. As mentioned before, I was unable to get all the data this way, but I would recommend trying to get it to work as I think it is a bit more realiable than my 'hack'!!!

Python:
    elif cmdID == self.TELLO_CMD_FILE_DATA and self.chunkCounter < 7:
#                    print '\nchunk received'
                    p = payload.get_array()
                    FileID = struct.unpack('<H', p[0:2])[0]
                    FilePieceNo = struct.unpack('<I', p[2:6])[0]
                    FileChunkNo = struct.unpack('<I', p[6:10])[0]
                    ChunkLength = struct.unpack('<H', p[10:12])[0]
                    if FileChunkNo in self.chunklog:
                        pass
                    else:
                        self.chunklog[FileChunkNo] = str(list(p[12:(ChunkLength+12)]))[1:-1]

                    
                    self.chunkCounter = (FileChunkNo + 1) % 8

                elif cmdID == self.TELLO_CMD_FILE_DATA and self.chunkCounter == 7:
                    p = payload.get_array()
                    FileID = struct.unpack('<H', p[0:2])[0]
                    FilePieceNo = struct.unpack('<I', p[2:6])[0]
                    FileChunkNo = struct.unpack('<I', p[6:10])[0]
                    ChunkLength = struct.unpack('<H', p[10:12])[0]

                    if FileChunkNo in self.chunklog:
                        pass
                    else:
                        self.chunklog[FileChunkNo] = str(list(p[12:(ChunkLength+12)]))[1:-1]

                    self.chunkCounter = (FileChunkNo + 1) % 8
 
Hi all,
being new to this forum, I was wondering if the code to collect pictures has been posted anywhere?
 

New Posts

Members online

Forum statistics

Threads
5,690
Messages
39,934
Members
17,023
Latest member
Repiv

New Posts