API

Control the drone and receive telemetry via WebSocket. Python, JavaScript, or any language.

Quick Start

1 Download the starter kit and unzip it

unzip dremian-api-starter-kit.zip
pip install -r requirements.txt

Contains: proxy.py, fly.py, requirements.txt, README.txt

2 Open sim.dremian.com/simulator.html in your browser

3 Run the proxy and the example (two terminals)

python3 proxy.py
python3 fly.py

The drone spawns at 50m with a payload, holds altitude, and 8 targets (3 drones + 5 vehicles) appear in the scene.

What's in fly.py

import asyncio, json, websockets

async def fly():
    async with websockets.connect("ws://localhost:8080") as ws:

        # --- Configure the drone ---
        # Set drone mass to 2.5 kg and add a 0.8 kg payload
        for key, val in [("drone_mass", 2.5), ("dronePayloadMass", 0.8)]:
            await ws.send(json.dumps({
                "type": "set_setting",
                "data": {"key": key, "value": val}
            }))

        # --- Spawn targets in front of the drone ---
        await ws.send(json.dumps({
            "type": "set_setting",
            "data": {"key": "targets", "value": {
                "drone": {
                    "count": 3,
                    "height_range": [30, 80],
                    "distance_range": [50, 300],
                    "speed": 10
                },
                "vehicle": {
                    "count": 5,
                    "distance_range": [100, 500],
                    "speed": 8
                }
            }}
        }))

        # --- Teleport drone to 50 m altitude ---
        await ws.send(json.dumps({
            "type": "command",
            "data": {"command": "setPosition", "params": {
                "latitude": 50.45, "longitude": 30.52, "altitude": 50,
                "roll": 0, "pitch": 0, "yaw": 0
            }}
        }))

        # --- Start telemetry + camera at 30 FPS ---
        await ws.send(json.dumps({
            "type": "camera_stream_multi",
            "data": {"cameraId": "camera1", "active": True, "rate": 30, "quality": 0.3}
        }))

        # --- Altitude hold — simple P controller ---
        target_alt = 50.0
        async for msg in ws:
            data = json.loads(msg)
            if data["type"] != "camera_frame_multi":
                continue

            state = data["data"]["droneState"]
            alt   = state["position"]["altitude"]
            error = target_alt - alt
            throttle = max(-1, min(1, 0.45 + error * 0.02))

            await ws.send(json.dumps({
                "type": "control",
                "data": {"roll": 0, "pitch": 0, "yaw": 0, "throttle": throttle}
            }))

            # Count visible targets
            targets = data["data"].get("targets", [])
            print(f"\rAlt: {alt:6.1f}m  Thr: {throttle:.2f}  Targets: {len(targets)}", end="")

asyncio.run(fly())

Fly the Drone

Send stick inputs every frame. All values -1 to 1.

{"type": "control", "data": {"roll": 0, "pitch": 0, "yaw": 0, "throttle": 0.5}}
FieldDescription
rollLeft / right
pitchForward / backward
yawRotate left / right
throttleDown / up

Teleport the Drone

Place the drone anywhere on the globe. Altitude is meters above ground.

{"type": "command", "data": {"command": "setPosition", "params": {
    "latitude": 50.45, "longitude": 30.52, "altitude": 50,
    "roll": 0, "pitch": 0, "yaw": 0
}}}

Stream Camera & Telemetry

Start a camera stream to receive JPEG frames with full drone state at the requested FPS.

{"type": "camera_stream_multi", "data": {
    "cameraId": "camera1",
    "active": true,
    "rate": 30,
    "quality": 0.3
}}

You receive camera_frame_multi messages:

{
  "type": "camera_frame_multi",
  "data": {
    "cameraId": "camera1",
    "frame": "data:image/jpeg;base64,...",
    "droneState": {
      "position":    {"latitude": 50.45, "longitude": 30.52, "altitude": 12.3},
      "orientation": {"roll": 1.2, "pitch": -0.5, "yaw": 45.3},
      "velocity":    {"vx": 0.1, "vy": 0.0, "vz": -0.02}
    },
    "targets": [...]
  }
}
Telemetry fieldUnit
altitudeMeters above ground
roll, pitch, yawDegrees (yaw from North)
vx, vy, vzm/s (North, East, Down)
targetsArray of visible targets in the scene

Spawn Targets

Populate the scene with moving targets. They reposition automatically when the drone teleports.

{"type": "set_setting", "data": {"key": "targets", "value": {
    "drone":   {"count": 3,  "height_range": [30, 80],    "distance_range": [50, 300],   "speed": 10},
    "plane":   {"count": 2,  "height_range": [500, 2000], "distance_range": [100, 3000], "speed": 40, "evasive": 50},
    "vehicle": {"count": 5,  "distance_range": [100, 500],  "speed": 8},
    "fennek":  {"count": 2,  "distance_range": [50, 400],   "speed": 12}
}}}
TypeDescription
droneAerial quadcopter targets
planeFixed-wing aircraft (evasive: 0-100 intensity)
vehicleGround vehicles (always at ground level)
fennekReconnaissance ground vehicle
ParameterDescription
countNumber of targets to spawn
height_range[min, max] altitude in meters (aerial only)
distance_range[min, max] distance from drone in meters
speedMovement speed in m/s
evasiveEvasive maneuver intensity 0-100 (planes only)

Place Targets at Exact Positions

Use spawns to place targets at specific NED offsets (meters relative to the drone). down is negative for altitude (e.g. -50 = 50m above ground).

{"type": "set_setting", "data": {"key": "targets", "value": {
    "drone": {
        "count": 2,
        "speed": 5,
        "spawns": [
            {
                "position": {"north": 100, "east": 50,  "down": -40},
                "waypoint": {"north": 200, "east": 100, "down": -40}
            },
            {
                "position": {"north": -50, "east": 200, "down": -60}
            }
        ]
    },
    "vehicle": {
        "count": 1,
        "speed": 8,
        "spawns": [
            {"position": {"north": 300, "east": 0, "down": 0}}
        ]
    }
}}}
FieldDescription
positionSpawn location in NED meters relative to drone
waypointOptional first waypoint — sets initial heading
northMeters north (positive) or south (negative)
eastMeters east (positive) or west (negative)
downMeters down — use negative for altitude (e.g. -50 = 50m AGL)

When spawns is provided, height_range and distance_range are ignored for those targets. If count exceeds the number of spawns, extra targets use random placement.

Configure the Simulation

Change any setting at runtime via set_setting. Changes are session-only by default.

{"type": "set_setting", "data": {"key": "droneWindStrength", "value": 1.5}}

Drone Physics

KeyDescription
dronePresetDrone type: quadcopter_5inch, quadcopter, quadcopter_10inch, winged
dronePayloadMassPayload mass in kg (0-20)
drone_massBase mass in kg
drone_thrustMotor thrust in kg
drone_dragDrag coefficient
drone_wing_areaWing area in m² (enables lift when > 0)
drone_max_rateMax rotation rate in deg/s

Camera

KeyDescription
droneCameraFOVField of view in degrees (30-120)
droneCameraPitchCamera tilt in degrees (-90 to 90)
cameraVisionModenormal or thermal

Environment

KeyDescription
droneWindStrengthWind intensity (0-2)
timeOfDayauto, day, or night
noiseProfileSensor noise: none, low, medium, high, extreme

Send {"type": "get_schema"} to discover all available settings with their types, ranges, and defaults.