Skip to content

Installation ​

To run FTS EMU, you'll need to install QGroundControl and the EMU Docker Compose stack. You can run EMU on a separate machine (for example, a GPU-equipped server) and QGroundControl on your local machine.

Set license key ​

You should have a license key that was sent to you via email. If you can't locate your license key or don't have one, please contact your sales representative.

1. Save license Key ​

Once you have located your license key, run the following command, replacing <your-license-key> with the key from your email:

bash
mkdir -p ~/.leip && echo "<your-license-key>" > ~/.leip/license.key

2. Export license key as an environment variable ​

The Docker Compose file requires LEIP_LICENSE_KEY to be set as an environment variable. Run the following to export it from the key file:

bash
export LEIP_LICENSE_KEY=$(cat ~/.leip/license.key)

NOTE

You will need to rerun this command in any new shell session before running docker compose commands.

3. Log in to container repository ​

Log in to Latent AI's container repository with the following command:

bash
cat ~/.leip/license.key | docker login containers.latentai.io -u latentai --password-stdin

Install QGroundControl ​

NOTE

The QGroundControl binary provided here is built for Ubuntu 24.04. If you need a build for a different OS or version, please contact us.

Download the QGroundControl binary:

bash
wget https://dist-release.latentai.io/qgc/latest/QGroundControl.AppImage -O QGroundControl.AppImage
chmod +x QGroundControl.AppImage

Launch QGroundControl:

bash
./QGroundControl.AppImage

First-time launch settings ​

NOTE

Replace ${ip} below with the IP address of the machine running the EMU stack. If EMU is running locally alongside QGroundControl, use localhost or 127.0.0.1.

Before flying, configure the following in QGroundControl:

  1. Application Settings > Comm Links > Add:
    1. Name: FTS
    2. Type: UDP
    3. Port: 18570
    4. Server: {ip}:18570
  2. Application Settings > Video:
    1. Source: RTSP Video Stream
    2. RTSP URL: rtsp://{ip}:8554/Drone1/DownCamera/Annotated
  3. Application Settings > Fly View > Virtual Joystick:
    1. Enabled: True
  4. Application Settings > Maps:
    1. Provider: CustomURL
    2. Type: Custom
  5. Application Settings > Maps > Custom Map URL:
    1. Server URL: http://{ip}:8100/{z}/{x}/{y}.png
  6. Main Screen > Hold/Position > More > Edit Displayed Flight Modes:
    1. Toggle "Offboard" to enabled

Install EMU ​

In a new directory, create a docker-compose.yml with the following contents:

yaml
name: emu-homing

services:
  control:
    image: ${EMU_REGISTRY:-containers.latentai.io/latent-emu}/control:${EMU_TAG:-latest}
    restart: unless-stopped
    network_mode: service:engine
    depends_on:
      engine:
        condition: service_healthy

  engine:
    image: ${EMU_REGISTRY:-containers.latentai.io/latent-emu}/engine:${EMU_TAG:-latest}
    restart: unless-stopped
    environment:
      EMU_SCENE_ID: ${EMU_MAP_NAME:-OpenLevel1}
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities:
                - gpu

  homing:
    image: ${HKS_REGISTRY:-containers.latentai.io/latent-hks}:${HKS_TAG:-latest}
    restart: unless-stopped
    depends_on:
      world:
        condition: service_healthy
      homing-cache:
        condition: service_completed_successfully
    environment:
      DISPLAY: :${HKS_HOMING_DISPLAY:-1}
      HKS_MEDIA_HOST: media:8554
      HKS_WORLD_HOST: world:8100
      HKS_CONTROL_HOST: proxy:5760
      HKS_HOMING_AUTO: 1
      HKS_HOMING_DISPLAY: ${HKS_HOMING_DISPLAY:-1}
      HKS_HOMING_TRACKER: ${HKS_HOMING_TRACKER:-sam2}
      HKS_HOMING_INPUT: media:8554/Drone1/DownCamera
      HKS_HOMING_OUTPUT: media:8554/Drone1/DownCamera/Annotated
      LEIP_LICENSE_KEY: ${LEIP_LICENSE_KEY}
    volumes:
      - hks-homing-lre:/root/.cache/lre
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities:
                - gpu

  homing-cache:
    image: ${HKS_REGISTRY:-containers.latentai.io/latent-hks}:${HKS_TAG:-latest}
    restart: no
    command: |
      python -c "
      import os
      if os.environ.get('HKS_HOMING_TRACKER', 'sam2') in ['latent', 'latenttracker']:
          from objecttracker_latenttracker import ObjectTrackerLatentTracker
          ObjectTrackerLatentTracker()
      "
    environment:
      LEIP_LICENSE_KEY: ${LEIP_LICENSE_KEY}
      HKS_HOMING_TRACKER: ${HKS_HOMING_TRACKER:-sam2}
    volumes:
      - hks-homing-lre:/root/.cache/lre
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities:
                - gpu

  media:
    image: ${EMU_REGISTRY:-containers.latentai.io/latent-emu}/media:${EMU_TAG:-latest}
    restart: unless-stopped
    ports:
      - 8554:8554
      - 9997:9997

  proxy:
    image: ${EMU_REGISTRY:-containers.latentai.io/latent-emu}/proxy:${EMU_TAG:-latest}
    restart: unless-stopped
    environment:
      EMU_PROXY_PORT: 5760
      EMU_PROXY_CONTROL_HOST: engine
      EMU_PROXY_CONTROL_PORT: 18570
    depends_on:
      world:
        condition: service_healthy
    ports:
      - 5760:5760
      - 14540:5760
      - 14550:5760
      - 18570:5760

  world:
    image: ${EMU_REGISTRY:-containers.latentai.io/latent-emu}/world:${EMU_TAG:-latest}
    restart: unless-stopped
    environment:
      EMU_SCENE_ID: ${EMU_SCENE_ID:-OpenLevel1}
      EMU_WORLD_MEDIA_HOST: media
      EMU_WORLD_ENGINE_HOST: engine
    depends_on:
      control:
        condition: service_healthy
      engine:
        condition: service_healthy
      media:
        condition: service_healthy

volumes:
  hks-homing-lre: