Skip to content

Getting Started

This guide takes you from a stock DJI drone and remote controller to a live telemetry stream and your first HTTP command.

  1. DJI drone + compatible RC, 5 GHz Wi-Fi access point, ground station computer
  2. Android Studio Koala 2024.1.2
  3. DJI developer account + API key from developer.dji.com
Terminal window
git clone https://github.com/SDU-UAS-Center/lyrebird.git
  1. Open Lyrebird/LyrebirdApp/android-sdk-v5-as in Android Studio.

  2. Create local.properties from the template and set the Android SDK path for your machine:

    Terminal window
    cd Lyrebird/LyrebirdApp/android-sdk-v5-as
    cp local.properties.example local.properties

    Example for a default Linux Android Studio install:

    sdk.dir=/home/your-user/Android/Sdk
  3. Add your DJI API key to local.properties:

    AIRCRAFT_API_KEY="Your_App_Key"
  4. Build and deploy to your RC or Android phone (enable Developer Mode + USB Debugging first).

Terminal window
cd Lyrebird/LyrebirdApp/android-sdk-v5-as
./gradlew :app:assembleCurrentDebug
./gradlew :app:assembleDemoBiomassDebug

The debug APKs are written to:

LyrebirdApp/lyrebird-app/build/outputs/apk/current/debug/Lyrebird-debug.apk
LyrebirdApp/lyrebird-app/build/outputs/apk/demoBiomass/debug/Lyrebird-debug.apk

To build/install a selected variant when an Android device is connected over ADB:

Terminal window
cd LyrebirdApp/android-sdk-v5-as
./auto_install_on_connect.sh current --build
./auto_install_on_connect.sh demo_biomass --build

To only check which APK will be used:

Terminal window
./auto_install_on_connect.sh current --check
./auto_install_on_connect.sh demo_biomass --check
  1. Launch the Lyrebird app on the RC — servers start automatically on the default layout.
  2. Note the Device IP shown in the app, call /config, or use auto-discovery.
  3. Press Enable Virtual Stick (via /send/enableVirtualStick or the app UI) before sending navigation commands.
Terminal window
pip install -e GroundStation/Python # Python interface
pip install -r GroundStation/ROS/requirements.txt # ROS 2 interface
import socket, json
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("192.168.1.100", 8081))
buffer = ""
while True:
buffer += sock.recv(4096).decode('utf-8')
while '\n' in buffer:
line, buffer = buffer.split('\n', 1)
if line.strip():
t = json.loads(line)
print(f"Battery: {t['batteryLevel']}% Alt: {t['location']['altitude']:.1f}m Sats: {t['satelliteCount']}")
import requests
rc = "192.168.1.100"
requests.post(f"http://{rc}:8080/send/takeoff")
requests.post(f"http://{rc}:8080/send/gotoWaypointNoseForward", data="49.306254,4.593728,20,90,5.0")
requests.post(f"http://{rc}:8080/send/navigateTrajectoryDJINative",
data="10.0;49.306,4.593,20;49.307,4.594,25;49.308,4.595,20")
requests.post(f"http://{rc}:8080/send/RTH")
Terminal window
docker compose -f GroundStation/video_test/compose.yaml up -d --build

Open the dashboard at http://localhost:8090. When the dashboard connects to a phone telemetry stream, the app builds a WHIP publish URL such as:

http://<ground-station-ip>:8889/<drone_name>/whip

MediaMTX exposes the matching browser playback endpoint:

http://<ground-station-ip>:8889/<drone_name>/whep

The supported public video example is defined by compose.yaml, mediamtx.yml, and the webapp in GroundStation/video_test/webapp. The older direct WebSocket-signaling viewer/server path has been removed from the public app and ground-station tooling.