MAVSDK-Java to dronekit SITL connection on Android


I am building an Android ground control station, using MAVSDK-Java. I’m using dronekit-sitl to run a simulated instance of ArduCopter, and I’m running my app with the Android Studio Emulator. I appear to have a successful connection, but then cannot read telemetry or send commands.

For simulation I am using the command from the dronekit-python library:

dronekit-sitl copter

This launches a SITL instance on my developer machine with the default IP/Port

In my Android app I start a MavsdkServer on, because in the Android Emulator is a special IP address referring to my developer machine localhost:

import io.mavsdk.System;
import io.mavsdk.action.Action;
import io.mavsdk.mavsdkserver.MavsdkServer;
import io.mavsdk.telemetry.Telemetry;
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
import java.util.concurrent.TimeUnit;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.LiveDataReactiveStreams;


MavsdkServer mavServer;
System mDrone;

mavServer = new MavsdkServer();
int mavsdkServerPort ="tcp://");
mDrone = new System("", mavsdkServerPort);

This alone gives the log messages that seem to indicate a successful connection:

11:24:10.831  I  MAVSDK version: v1.4.16
11:24:10.833  D  Running mavsdk_server with connection url: tcp://
11:24:10.833  I  Waiting to discover system on tcp://
11:24:10.858  D  New: System ID: 1 Comp ID: 1
11:24:10.858  D  Component Autopilot (1) added.
11:24:10.858  W  Vehicle type changed (new type: 2, old type: 0)
11:24:10.858  D  Discovered 1 component(s)
11:24:10.859  I  System discovered
11:24:10.864  I  Server started
11:24:10.864  I  Server set to listen on
11:24:10.864  D  mavsdk_server is now running, listening on port 42521

Sending Commands
I attempt to arm and takeoff the simulated drone:


but I get no response in SITL?

Receiving telemetry
I attempt to read one particular value, such as the battery voltage.

public LiveData<Telemetry.Battery> getBattery()
    Flowable<Telemetry.Battery> batteryFlowable;

    batteryFlowable = mDrone.getTelemetry().getBattery()
            .throttleLast(500, TimeUnit.MILLISECONDS)

    // //debug dummy data
    // batteryFlowable = Flowable.intervalRange(0, 21, 0, 500, TimeUnit.MILLISECONDS)
    //                    .repeat()
    //                    .map(aLong -> new Telemetry.Battery(4, (float) (16.8 + aLong * (12.6 - 16.8) / 21), 1 - aLong.floatValue() * 5 * 0.01f));

    return LiveDataReactiveStreams.fromPublisher(batteryFlowable);

Then the observer code:

mViewModel.getBattery().observe(this, b ->
    textView_battery.setText(String.format("%.2f", b.getVoltageV()));

However, the .observe block is never executed. With dummy data uncommented, the observer publishes the values to the UI just fine though.

Overall this has been a challenge due to the lack of documentation of MAVSDK-Java! There are API references for C++, Swift, Python, however MAVSDK-Java only has limited examples in its repository.

I would appreciate some pointers!