I'm waiting on the green light from work to submit the patches, but I've reverse engineered a few more corners of the protocol and added rudimentary support to TelloPy. (Although I may switch to pytello soon, since its protocol handlers are more complete; TelloPy was just easier to get something up and running
now with.)
TELLO_CMD_PALM_LANDING
Payload: a single zero byte (optional?)
Puts the
Tello in palm-landing mode. Place your hand under it within five seconds and it will land.
TELLO_CMD_SWITCH_PICTURE_VIDEO
Payload: a single byte, 0 for picture mode, 1 for video mode. Other values confuse the
Tello and you'll need to reboot it.
In picture mode, it sends a 960x720 @ 30fps video stream. In video mode, it sends a 1280x720 @ 30fps
cropped stream -- it shows you a bit less horizontally and a lot less vertically than picture mode. So picture mode is actually better for flying, especially if you want maximum downward-looking field of view!
TELLO_CMD_TAKE_PICTURE
Payload: none.
The
Tello will drop a few video frames as it takes the picture, then send a few TELLO_CMD_FILE_SIZE packets. If you ack them (by echoing them back to the
tello unmodified) it will follow with a stream of TELLO_CMD_FILE_DATA packets. Presumably, if you ack those correctly it'll send TELLO_CMD_FILE_COMPLETE, but I haven't figured out how to do that, so instead it sends me multiple copies of the file (!). Or perhaps
I have to send TELLO_CMD_FILE_COMPLETE once I have the whole file?
TELLO_CMD_FILE_SIZE
Payload: Variable. Seems to be either a single zero byte, or: { byte always_0x01; uint32_t file_size; uint16_t unknown; }
Sending TELLO_CMD_TAKE_PICTURE seems to result in two TELLO_CMD_FILE_SIZE packets, one with the actual file size and one containing a single zero.
TELLO_CMD_FILE_DATA
Payload: a 12-byte header followed by the actual file data. The header has the format:
{
uint16_t unknown; // always 0?
uint32_t coarse; // increases by 1 every 8 packets
uint32_t fine; // increases by 1 every packet
uint16_t size;
}
I'm not sure why there are separate "coarse" and "fine" fields; "fine" on its own seems enough. size always seems to be 1024 except for the last packet. The packets will contain duplicates and may be delivered out of order, so it's important to use the coarse/fine values to make sure each one goes in the right place in the file.
The actual image is a normal JPEG once you peel off the headers and reassemble the chunks in the right order.