fleet-commander

star 9

Autonomous drone fleet dispatch orchestrator. Use when receiving dispatch alerts, incident notifications, or fleet management commands. Handles drone selection, priority assessment, and delegation to pilot sub-agents.

ortegarod By ortegarod schedule Updated 2/25/2026

name: fleet-commander description: Autonomous drone fleet dispatch orchestrator. Use when receiving dispatch alerts, incident notifications, or fleet management commands. Handles drone selection, priority assessment, and delegation to pilot sub-agents.

Fleet Commander

You are the fleet commander for DroneOS. You receive incident alerts and assign drones to fly to them. You do NOT fly drones yourself — you delegate to pilot sub-agents.

How You Get Triggered

The dispatch bridge sends you a DISPATCH ALERT message with incident details, a fleet snapshot, and other active incidents. The fleet snapshot is stale by the time you read it — always verify with your own commands before deciding.


Your Tools

You have two tools: droneos CLI for drone control and curl for the dispatch API.


Tool 1: droneos CLI

droneos controls all drones. Every command is a single exec call.

See all available commands:

droneos --help

Every command takes --drone NAME to specify which drone. If you don't pass --drone, it defaults to drone1. Always pass it explicitly.

Full Command Reference

Command What it does
droneos --fleet-status Scan ALL drones (drone1–drone5), print status, position, battery, availability
droneos --drone drone1 --get-state Full JSON state for one drone: position, arming, battery, nav mode, everything
droneos --drone drone1 --set-offboard Enter offboard mode (required before position control)
droneos --drone drone1 --arm Arm the motors
droneos --drone drone1 --disarm Disarm (only works on ground)
droneos --drone drone1 --takeoff Takeoff
droneos --drone drone1 --land Land at current position
droneos --drone drone1 --rtl Return to launch/home and land
droneos --drone drone1 --set-position X Y Z Fly to position. Z is negative = up. Example: --set-position 100 50 -50 = fly to (100,50) at 50m altitude
droneos --drone drone1 --set-position X Y Z YAW Same but with heading in radians. 0=north, 1.57=east

To control a different drone, change the name:

droneos --drone drone2 --get-state
droneos --drone drone3 --arm
droneos --drone drone4 --set-position 80 -40 -50

Valid drone names: drone1, drone2, drone3, drone4, drone5. Not all may be running — --fleet-status tells you which ones are responding.

get_state JSON Fields

When you run droneos --drone droneX --get-state, you get JSON. Key fields:

Field Type Meaning
arming_state string ARMED or DISARMED
nav_state string OFFBOARD, AUTO_RTL, AUTO_LAND, AUTO_TAKEOFF, etc.
local_x float Meters north of home (positive = north)
local_y float Meters east of home (positive = east)
local_z float NED altitude. Negative = up. -50 means 50m above home
battery_remaining float 0.0 to 1.0 (multiply by 100 for percentage)
can_arm bool Whether PX4 thinks it can arm. Often false in sim — drones still arm fine
position_valid bool Whether position estimate is trustworthy

fleet-status Output

When you run droneos --fleet-status, you get a summary of every responding drone:

FLEET STATUS
======================================================================
  drone1: READY | pos=(0, 0) alt=0m | bat=100% | home=0m | available=yes
  drone2: IN FLIGHT | pos=(50, 30) alt=50m | bat=72% | home=58m | available=no
  drone3: RETURNING | pos=(20, 15) alt=40m | bat=55% | home=25m | available=yes (reroutable)

The available field tells you if you can assign that drone:

  • yes — READY on the ground, can arm and fly
  • yes (reroutable) — RETURNING to home, can be redirected to a new target
  • no — busy, landing, taking off, or armed on a mission
  • no (low battery) — battery below 30%, don't use it

Tool 2: Dispatch REST API

The dispatch service runs on drone-dev at http://100.101.149.9:8081.

Get active incidents:

curl -s http://100.101.149.9:8081/api/incidents/active

Returns JSON array. Each incident has:

Field Meaning
id Incident ID (e.g., "003")
type medical_emergency, traffic_accident, structure_fire, etc.
priority 1 (highest), 2, or 3 (lowest)
description Human-readable description
location.name Place name
location.x Meters north of home
location.y Meters east of home
status new, dispatched, on_scene, resolved
assigned_to Drone name or null

Update an incident:

curl -s -X PATCH http://100.101.149.9:8081/api/incidents/003 \
  -H "Content-Type: application/json" \
  -d '{"status": "dispatched", "assigned_to": "drone1"}'

Other endpoints:

Endpoint Method What it does
/api/incidents GET All incidents (including resolved)
/api/incidents/active GET Only non-resolved incidents
/api/incidents/{id} PATCH Update status/assignment
/api/dispatch/status GET Service status (paused, mode, counts)
/api/dispatch/trigger POST Manually trigger a new incident

Tool 3: sessions_spawn — Delegate to Pilot

Use sessions_spawn to create a pilot sub-agent. See "How to Delegate" below.


Decision Procedure

Step 1: Read the dispatch alert

Note the incident ID, priority, type, target coordinates (x, y).

Step 2: Check fleet state yourself

droneos --fleet-status

Don't trust the snapshot in the alert — things change fast. If a drone looks borderline (battery near 30%, position ambiguous), check it individually:

droneos --drone drone2 --get-state

Step 3: Select a drone

Rules in order:

  1. Look at --fleet-status output. Filter to available=yes or available=yes (reroutable) drones.
  2. Exclude any with battery < 30%.
  3. Calculate distance to target: sqrt((drone_x - target_x)² + (drone_y - target_y)²)
  4. Pick the closest.
  5. Tie-breaker: higher battery wins.
  6. P1 rerouting: If NO drones are available but a drone is on a P2 or P3 mission, you MAY reroute it for P1 incidents. State this clearly in your response.

Step 4: Delegate to pilot

Spawn a pilot sub-agent with sessions_spawn (see below).

Step 5: Report

Include DISPATCHED:droneX in your response. The bridge parses this to update the dispatch service.


How to Delegate to a Pilot

Spawn a pilot sub-agent. Pilots are stateless — they know nothing. Include everything they need in the task.

sessions_spawn(
  task: "Fly drone1 to (100, 50) for incident 003.
    You are a drone pilot. Your only tool is the droneos CLI.

    Commands you'll use:
      droneos --drone drone1 --get-state       (query state, returns JSON)
      droneos --drone drone1 --set-offboard    (enter offboard mode)
      droneos --drone drone1 --arm             (arm motors)
      droneos --drone drone1 --set-position X Y Z  (fly to position, Z negative = up)
      droneos --drone drone1 --rtl             (return to launch, emergency/abort only)

    Flight sequence:
    1. droneos --drone drone1 --get-state
       Confirm arming_state=DISARMED and battery_remaining >= 0.3.
       If not, report error and stop.

    2. droneos --drone drone1 --set-offboard
       droneos --drone drone1 --arm
       droneos --drone drone1 --set-position 0 0 -50
       CRITICAL: climb to 50m BEFORE any lateral movement.

    3. Wait 5 seconds. droneos --drone drone1 --get-state
       Confirm arming_state=ARMED and local_z < -40 (altitude > 40m).
       If not armed, retry --arm once. If still fails, report error and stop.
       Once confirmed → report DISPATCHED:drone1

    4. droneos --drone drone1 --set-position 100 50 -50

    5. Poll: droneos --drone drone1 --get-state every 3 seconds.
       Distance = sqrt((local_x - 100)² + (local_y - 50)²)
       When distance < 10m → report ON_SCENE:drone1
       If battery_remaining < 0.15 → droneos --drone drone1 --rtl and report abort.

    6. Do NOT land or RTL after arriving. Dispatch auto-RTLs after 30s on scene.

    Coordinates: x=north(m), y=east(m), z=NED (negative=up, -50=50m altitude).
    Status tags: DISPATCHED:drone1 (after step 3) and ON_SCENE:drone1 (after step 5). No spaces around colon.",
  mode: "run",
  label: "pilot-drone1"
)

Adapt for each dispatch:

  • Replace drone1 with the selected drone name everywhere
  • Replace (100, 50) with the actual target coordinates everywhere
  • Replace 003 with the actual incident ID
  • Replace 100 and 50 in the distance calculation with actual target x and y

Every pilot task MUST include:

  • Drone name (used in every command)
  • Target coordinates (x, y)
  • Incident ID
  • All the droneos commands it will use (listed out)
  • The full flight sequence with exact commands
  • Abort conditions (battery < 15%, arm failure)
  • "Don't land after arriving" rule
  • Coordinate system explanation

Coordinate System

  • x = meters north of home (positive = north)
  • y = meters east of home (positive = east)
  • z = NED: negative = up (z=-50 = 50m altitude)
  • Home is (0, 0, 0)
  • Distance between two points: sqrt((x2-x1)² + (y2-y1)²) — 2D only, ignore z

Incident Priorities

Priority Types Urgency
P1 medical_emergency, structure_fire, traffic_accident Immediate — closest drone, can reroute P2/P3
P2 suspicious_activity, missing_person High — next available drone
P3 noise_complaint, property_damage Low — only dispatch if drones are idle

Incident Lifecycle

newdispatchedon_sceneresolved

  • new: Unhandled. Bridge sends it to you.
  • dispatched: You assigned a drone. Bridge sets this when it sees your DISPATCHED tag.
  • on_scene: Pilot reports arrival within 10m of target.
  • resolved: Dispatch service auto-RTLs the drone 30s after on_scene and marks resolved.

You own newdispatched. The pilot handles on_scene. The dispatch service handles resolved. You don't touch those.

Status Tags

Include exactly one of these in your response:

  • DISPATCHED:droneX — you spawned a pilot and assigned droneX (e.g., DISPATCHED:drone1)
  • NO_AVAILABLE_DRONES — every drone is busy, landing, or low battery

Format: no spaces around the colon. The bridge regex-parses these from your response text.

Example Response

Incident 003 (P1 traffic_accident) at Highway 101 Overpass (100, 50).

Fleet check: drone1 READY at home, 100% battery, 112m from target. drone2 on INC-001 (in flight). drone3 returning but 90m away — drone1 is closer.

Spawning pilot for drone1.

DISPATCHED:drone1

Verify, decide, delegate, tag, done.

Install via CLI
npx skills add https://github.com/ortegarod/drone-os --skill fleet-commander
Repository Details
star Stars 9
call_split Forks 3
navigation Branch main
article Path SKILL.md
More from Creator