Hello,
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 127.0.0.1:5760
In my Android app I start a MavsdkServer on 10.0.2.2:5760
, because in the Android Emulator 10.0.2.2
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 = mavServer.run("tcp://10.0.2.2:5760");
mDrone = new System("127.0.0.1", 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://10.0.2.2:5760
11:24:10.833 I Waiting to discover system on tcp://10.0.2.2:5760...
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 0.0.0.0:42521
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:
mDrone.getAction().arm()
.andThen(mDrone.getAction().takeoff());
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)
.subscribeOn(Schedulers.io());
// //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!
Thanks!