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

Tello4J | Easy out-of-the-box solution to access your Tello Drone from Java

FriwiDev

Member
Joined
Dec 26, 2019
Messages
16
Reaction score
7
Hello there,

today I present you yet another library to access your Tello drone. It supports sending commands, receiving state feedback and receiving the video feed of your drone.


The library is published on the maven central, so using it is quite simple.

Include the library in your project by adding it as a maven dependency:
Code:
<dependency>
    <groupId>me.friwi</groupId>
    <artifactId>tello4j</artifactId>
    <version>1.0.2</version>
</dependency>

Use the API to send instructions to your drone, receive state updates and video frames from the camera of your drone:
Code:
public class FlightPlanExample {
    public static void main(String args[]) {
        //Initialize a wifi drone
        try (TelloDrone drone = new WifiDroneFactory().build()) {
            drone.connect();
            //Subscribe to state updates of our drone (e.g. current speed, attitude)
            drone.addStateListener((o, n) -> {
                //Do sth when switching from one to another state
            });
            //Create a video window to see things with our drones eyes
            drone.addVideoListener(new VideoWindow());
            //...or use a custom video listener to process the single frames
            drone.addVideoListener(frame -> {
                //Do sth when we received a frame
            });
            //...[optional] select which type of frame you want to receive
            // a) [default] BUFFERED_IMAGE: Receive buffered images in each TelloVideoFrame
            // b) JAVACV_FRAME: Receive javacv frames in each TelloVideoFrame to further process them
            // c) BOTH: Receive both frame types in each TelloVideoFrame
            drone.setVideoExportType(TelloVideoExportType.BUFFERED_IMAGE);
            //...and tell the drone to turn on the stream
            drone.setStreaming(true);
            //Now perform a flight plan
            drone.takeoff();
            drone.forward(30);
            drone.turnLeft(90);
            drone.forward(30);
            drone.backward(30);
            drone.flip(FlipDirection.FORWARD);
            drone.turnRight(90);
            drone.backward(30);
            drone.land();
            //Prevent our drone from being closed
            //(the drone is automatically closed when leaving the try-with-resource block)
            while (true) ;
        } catch (TelloNetworkException e) {
            if(e instanceof TelloConnectionTimedOutException){
                //The connection timed out because we did not send commands within the last 15 seconds.
                //The drone safely lands then.
                e.printStackTrace();
            }else {
                //Errors that occurred on the network side (e.g. parsing errors, connect error)
                //can be observed here
                e.printStackTrace();
            }
        } catch (TelloNoValidIMUException e) {
            //Commands that move the drone, apart from "takeoff", "land"
            //and "remote control" can fail due to no valid imu data.
            //This mainly happens when the ground under the drone does not
            //provide enough textual features for the drone to navigate properly.
            e.printStackTrace();
        } catch (TelloGeneralCommandException e) {
            //This exception is thrown when the drone reported an unspecified error
            //to the api. This can happen when the battery is too low for a
            //command to be executed
            e.printStackTrace();
        } catch (TelloCustomCommandException e) {
            //This exception is thrown when the drone reported an error with description
            //to the api. The reason can be obtained with e.getReason()
            e.printStackTrace();
        } catch (TelloCommandTimedOutException e) {
            //This exception is thrown when a command is not answered by the drone for 20 seconds
            e.printStackTrace();
        }
    }
}

I hope you have fun controlling your drone with this small library. If you run into any issues, please report them on GitHub. If you have any questions concerning the library or its usage, feel free to ask here or check out the javadoc at https://friwi.me/tello4j/javadoc/1_0_2/

Sincerely,

~FriwiDev
 
Last edited:
Thank you so much for posting this as I prefer Java given I use it at work. I apparently am brain dead after a long week as I was trying to add in the ffmpeg support on a Windows 10 machine for the video feed and I'm getting the following:

Exception in thread "Frame-Grabber" java.lang.NoClassDefFoundError: org/bytedeco/ffmpeg/global/avutil
at me.friwi.tello4j.wifi.impl.video.TelloFrameGrabberThread.run(TelloFrameGrabberThread.java:40)
Caused by: java.lang.ClassNotFoundException: org.bytedeco.ffmpeg.global.avutil
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

I'm assuming that it's having trouble finding a DLL, but I double checked Eclipse and it has a path to the DLL in the run parameters. I made sure that the PATH environment variable has the path to where the DLLs are. I downloaded the full ffmpeg 4.2.2 installation and added all the Java elements to the project. Just to eliminate my own build issues, I downloaded the built dlls for 64bit Windows from the ffmpeg.org site. Did you do anything different when you created the installation? I also have the opencv-420.jar in the project as well as javacv.

Your software interface works great to control the drone. I just need to figure out how to get the video out. :)

Thanks for any help,

John
 
Hey there,

you do not only need the ffmpeg library, but also javacv (currently 1.5.2). There is a manual installation guide on the github page of the javacv project: bytedeco/javacv
However, I would recommend using maven instead, it is way easier and works out of the box.

Sincerely,

~FriwiDev

PS: ClassNotFoundException means that you are missing .jar files. You only miss .dlls when you get something with "UnsatifiedLinkError: no <lib> in java.library.path"
 
Version 1.0.2 is out now.

Version 1.0.1 fixed a bug in the remote control command.
Version 1.0.2 adds the possibility to connect to custom remote addresses.
 
Thanks for fixing that bug. When using with Tello EDU, the custom address is needed, especially when controlling multiple drones at the same time.
 
  • Like
Reactions: FriwiDev
Thanks for fixing that bug. When using with Tello EDU, the custom address is needed, especially when controlling multiple drones at the same time.
I personally do not own an EDU drone, so I did not inform myself which additional functionality it comes with. With a normal tello drone, there is no need to change the destination ip.
 
Hello there,

today I present you yet another library to access your Tello drone. It supports sending commands, receiving state feedback and receiving the video feed of your drone.


The library is published on the maven central, so using it is quite simple.

Include the library in your project by adding it as a maven dependency:
Code:
<dependency>
    <groupId>me.friwi</groupId>
    <artifactId>tello4j</artifactId>
    <version>1.0.2</version>
</dependency>

Use the API to send instructions to your drone, receive state updates and video frames from the camera of your drone:
Code:
public class FlightPlanExample {
    public static void main(String args[]) {
        //Initialize a wifi drone
        try (TelloDrone drone = new WifiDroneFactory().build()) {
            drone.connect();
            //Subscribe to state updates of our drone (e.g. current speed, attitude)
            drone.addStateListener((o, n) -> {
                //Do sth when switching from one to another state
            });
            //Create a video window to see things with our drones eyes
            drone.addVideoListener(new VideoWindow());
            //...or use a custom video listener to process the single frames
            drone.addVideoListener(frame -> {
                //Do sth when we received a frame
            });
            //...[optional] select which type of frame you want to receive
            // a) [default] BUFFERED_IMAGE: Receive buffered images in each TelloVideoFrame
            // b) JAVACV_FRAME: Receive javacv frames in each TelloVideoFrame to further process them
            // c) BOTH: Receive both frame types in each TelloVideoFrame
            drone.setVideoExportType(TelloVideoExportType.BUFFERED_IMAGE);
            //...and tell the drone to turn on the stream
            drone.setStreaming(true);
            //Now perform a flight plan
            drone.takeoff();
            drone.forward(30);
            drone.turnLeft(90);
            drone.forward(30);
            drone.backward(30);
            drone.flip(FlipDirection.FORWARD);
            drone.turnRight(90);
            drone.backward(30);
            drone.land();
            //Prevent our drone from being closed
            //(the drone is automatically closed when leaving the try-with-resource block)
            while (true) ;
        } catch (TelloNetworkException e) {
            if(e instanceof TelloConnectionTimedOutException){
                //The connection timed out because we did not send commands within the last 15 seconds.
                //The drone safely lands then.
                e.printStackTrace();
            }else {
                //Errors that occurred on the network side (e.g. parsing errors, connect error)
                //can be observed here
                e.printStackTrace();
            }
        } catch (TelloNoValidIMUException e) {
            //Commands that move the drone, apart from "takeoff", "land"
            //and "remote control" can fail due to no valid imu data.
            //This mainly happens when the ground under the drone does not
            //provide enough textual features for the drone to navigate properly.
            e.printStackTrace();
        } catch (TelloGeneralCommandException e) {
            //This exception is thrown when the drone reported an unspecified error
            //to the api. This can happen when the battery is too low for a
            //command to be executed
            e.printStackTrace();
        } catch (TelloCustomCommandException e) {
            //This exception is thrown when the drone reported an error with description
            //to the api. The reason can be obtained with e.getReason()
            e.printStackTrace();
        } catch (TelloCommandTimedOutException e) {
            //This exception is thrown when a command is not answered by the drone for 20 seconds
            e.printStackTrace();
        }
    }
}

I hope you have fun controlling your drone with this small library. If you run into any issues, please report them on GitHub. If you have any questions concerning the library or its usage, feel free to ask here or check out the javadoc at https://friwi.me/tello4j/javadoc/1_0_2

Hello there,

today I present you yet another library to access your Tello drone. It supports sending commands, receiving state feedback and receiving the video feed of your drone.


The library is published on the maven central, so using it is quite simple.

Include the library in your project by adding it as a maven dependency:
Code:
<dependency>
    <groupId>me.friwi</groupId>
    <artifactId>tello4j</artifactId>
    <version>1.0.2</version>
</dependency>

Use the API to send instructions to your drone, receive state updates and video frames from the camera of your drone:
Code:
public class FlightPlanExample {
    public static void main(String args[]) {
        //Initialize a wifi drone
        try (TelloDrone drone = new WifiDroneFactory().build()) {
            drone.connect();
            //Subscribe to state updates of our drone (e.g. current speed, attitude)
            drone.addStateListener((o, n) -> {
                //Do sth when switching from one to another state
            });
            //Create a video window to see things with our drones eyes
            drone.addVideoListener(new VideoWindow());
            //...or use a custom video listener to process the single frames
            drone.addVideoListener(frame -> {
                //Do sth when we received a frame
            });
            //...[optional] select which type of frame you want to receive
            // a) [default] BUFFERED_IMAGE: Receive buffered images in each TelloVideoFrame
            // b) JAVACV_FRAME: Receive javacv frames in each TelloVideoFrame to further process them
            // c) BOTH: Receive both frame types in each TelloVideoFrame
            drone.setVideoExportType(TelloVideoExportType.BUFFERED_IMAGE);
            //...and tell the drone to turn on the stream
            drone.setStreaming(true);
            //Now perform a flight plan
            drone.takeoff();
            drone.forward(30);
            drone.turnLeft(90);
            drone.forward(30);
            drone.backward(30);
            drone.flip(FlipDirection.FORWARD);
            drone.turnRight(90);
            drone.backward(30);
            drone.land();
            //Prevent our drone from being closed
            //(the drone is automatically closed when leaving the try-with-resource block)
            while (true) ;
        } catch (TelloNetworkException e) {
            if(e instanceof TelloConnectionTimedOutException){
                //The connection timed out because we did not send commands within the last 15 seconds.
                //The drone safely lands then.
                e.printStackTrace();
            }else {
                //Errors that occurred on the network side (e.g. parsing errors, connect error)
                //can be observed here
                e.printStackTrace();
            }
        } catch (TelloNoValidIMUException e) {
            //Commands that move the drone, apart from "takeoff", "land"
            //and "remote control" can fail due to no valid imu data.
            //This mainly happens when the ground under the drone does not
            //provide enough textual features for the drone to navigate properly.
            e.printStackTrace();
        } catch (TelloGeneralCommandException e) {
            //This exception is thrown when the drone reported an unspecified error
            //to the api. This can happen when the battery is too low for a
            //command to be executed
            e.printStackTrace();
        } catch (TelloCustomCommandException e) {
            //This exception is thrown when the drone reported an error with description
            //to the api. The reason can be obtained with e.getReason()
            e.printStackTrace();
        } catch (TelloCommandTimedOutException e) {
            //This exception is thrown when a command is not answered by the drone for 20 seconds
            e.printStackTrace();
        }
    }
}

I hope you have fun controlling your drone with this small library. If you run into any issues, please report them on GitHub. If you have any questions concerning the library or its usage, feel free to ask here or check out the javadoc at https://friwi.me/tello4j/javadoc/1_0_2/

Sincerely,

~FriwiDev
Hello. I can't access the javadocs 404 error. I want to know if it includes a way to determine the drones location. Thanks.
 
I just had a quick look at the code. It uses the SDK, and as far as I can see the SDK does not support drone location.
Except when used with mission pads, but no mission pad code found in that lib
 
I just had a quick look at the code. It uses the SDK, and as far as I can see the SDK does not support drone location.
Except when used with mission pads, but no mission pad code found in that lib
When you mention that it uses the SDK - Is there any other way to communicate with Tello than via SDK?
 

New Posts

Members online

Forum statistics

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

New Posts