Skip to content

Latest commit

 

History

History
551 lines (440 loc) · 8.82 KB

File metadata and controls

551 lines (440 loc) · 8.82 KB

Spot Robot Command Center - API Documentation

Overview

The backend API uses REST endpoints for communication between the React frontend and multiple robots (Boston Dynamics Spot, Ghost Robotics Vision 60) through their respective SDKs.

Base URL

  • Development: http://localhost:8000/api
  • Production: http://<server-ip>:8000/api

Authentication

Authentication uses JWT tokens. Log in to receive a token and pass it in the Authorization header for all API calls.

Response Format

All responses are JSON with the following structure:

Success Response (200 OK)

{
  "success": true,
  "data": { ... }
}

Error Response (400+)

{
  "error": "Error message",
  "code": "ERROR_CODE"
}

Endpoints

Authentication

Login

POST /auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "<your_password>"
}

Response:

{
  "token": "eyJ...",
  "user": "admin"
}

Use token in headers:

Authorization: Bearer eyJ...

Multi-Robot Management

List All Robots

GET /robots
Authorization: Bearer <token>

Response:

{
  "robots": [
    {
      "id": "spot",
      "name": "Boston Dynamics Spot",
      "type": "spot",
      "ip": "192.168.1.199",
      "connected": true,
      "active": true
    },
    {
      "id": "ghost",
      "name": "Ghost Vision 60",
      "type": "ghost_v60",
      "ip": "192.168.168.105",
      "connected": true,
      "active": false
    }
  ]
}

Get Active Robot

GET /robots/active

Response: {"active": "spot"}

Switch Active Robot

POST /robots/active
Content-Type: application/json

{"robot_id": "ghost"}

Response: {"active": "ghost"}

All /robot/* endpoints operate on the currently active robot.


Get Gaits (Ghost V60 only)

GET /robot/gait

Response:

{
  "gaits": {
    "0": "TROT_WALK",
    "1": "RUN",
    "2": "HILL",
    "3": "CRAWL",
    "4": "SAND",
    "5": "DOCK",
    "6": "BLIND_STAIRS",
    "7": "HIGH_STEP"
  }
}

Set Gait

POST /robot/gait
Content-Type: application/json

{"gait": 3}

Response: {"success": true, "gait": 3}

Returns 400 if gait control is not supported on the active robot.


Robot Connection

Connect to Robot

POST /robot/connect
Content-Type: application/json

{
  "ip": "192.168.1.100"
}

Response:

{
  "success": true,
  "message": "Connected to robot"
}

Disconnect from Robot

POST /robot/disconnect

Get Connection Status

GET /robot/status

Response:

{
  "connected": true,
  "robot_ip": "192.168.1.100"
}

Robot State

Get Current Robot State

GET /robot/state

Response:

{
  "battery": 87.5,
  "is_powered": 2,
  "timestamp": 1708331400
}

Fields:

  • battery - Battery percentage (0-100)
  • is_powered - Power state (0=OFF, 1=UNKNOWN, 2=ON)
  • timestamp - Unix timestamp

Get Robot Pose (Odom Frame)

GET /robot/pose
Authorization: Bearer <token>

Returns the robot's current pose in the odom frame as position + quaternion. Used by the multi-robot RL coordination API.

Response:

{
  "x": 1.23,
  "y": -0.45,
  "z": 0.52,
  "qx": 0.0,
  "qy": 0.0,
  "qz": 0.1736,
  "qw": 0.9848,
  "frame": "odom"
}

Fields:

  • x, y, z - Position in odom frame (meters)
  • qx, qy, qz, qw - Orientation quaternion in odom frame
  • frame - Always "odom"

Robot Control

Go To Waypoint

POST /robot/goto
Authorization: Bearer <token>
Content-Type: application/json

{
  "x": 2.0,
  "y": 1.0,
  "yaw": 0.5,
  "frame": "odom"
}

Sends the robot to an SE2 waypoint. Returns immediately without blocking. Robot must be powered on and standing; returns 409 if not. Used by the multi-robot RL coordination API.

Parameters:

  • x - Target x position in meters (required)
  • y - Target y position in meters (required)
  • yaw - Target heading in radians (optional, default 0.0)
  • frame - Reference frame (optional, default "odom")

Response (200):

{
  "status": "success",
  "x": 2.0,
  "y": 1.0,
  "yaw": 0.5,
  "frame": "odom"
}

Error (409 - not standing/powered):

{
  "error": "Robot motors are not powered on"
}

Stand Command

POST /robot/stand

Response:

{
  "success": true,
  "message": "Stand command sent"
}

Sit Command

POST /robot/sit

Move Robot

POST /robot/move
Content-Type: application/json

{
  "vx": 0.5,
  "vy": 0.0,
  "v_rot": 0.0
}

Parameters:

  • vx - Forward/backward velocity in m/s (-2.0 to 2.0)
  • vy - Left/right (lateral) velocity in m/s (-2.0 to 2.0)
  • v_rot - Rotation velocity in rad/s (-2.0 to 2.0)

Response:

{
  "success": true
}

Stop All Movement

POST /robot/stop

Safety

Get Obstacle Avoidance State

GET /robot/obstacle_avoidance

Response:

{
  "enabled": true
}

Set Obstacle Avoidance State

POST /robot/obstacle_avoidance
Content-Type: application/json

{
  "enabled": false
}

Response:

{
  "success": true,
  "enabled": false
}

Camera Operations

List Available Cameras

GET /cameras

Response:

{
  "cameras": [
    {
      "name": "back_rgb",
      "image_type": "RGB"
    },
    {
      "name": "front_rgb",
      "image_type": "RGB"
    },
    {
      "name": "left_rgb",
      "image_type": "RGB"
    },
    {
      "name": "right_rgb",
      "image_type": "RGB"
    }
  ]
}

Get Single Camera Frame

GET /camera/{camera_name}/image

Response:

  • Content-Type: image/jpeg
  • Binary JPEG image data

Example (with token for img tags):

GET /camera/frontleft_fisheye_image/image?token=eyJ...

Stream Camera (MJPEG)

GET /camera/{camera_name}/stream

Response:

  • Content-Type: multipart/x-mixed-replace; boundary=frame
  • Continuous MJPEG stream

Example:

<img src="/api/camera/frontleft_fisheye_image/stream?token=eyJ..." />

Error Codes

Code Status Meaning
200 OK Request successful
400 Bad Request Invalid parameters
500 Server Error Internal server error
503 Unavailable Robot not connected

Rate Limiting

No rate limiting is currently implemented. In production, implement appropriate rate limiting.

Pagination

Not applicable - all endpoints return complete data.

Filtering

Not applicable - robot commands are global.

Examples

JavaScript (Fetch API)

// Connect to robot
async function connectToRobot(ip) {
  const response = await fetch('/api/robot/connect', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ ip })
  });
  return await response.json();
}

// Get robot state
async function getRobotState() {
  const response = await fetch('/api/robot/state');
  return await response.json();
}

// Move robot
async function moveRobot(vx, vy, v_rot) {
  const response = await fetch('/api/robot/move', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ vx, vy, v_rot })
  });
  return await response.json();
}

// Stand
async function standUp() {
  const response = await fetch('/api/robot/stand', {
    method: 'POST'
  });
  return await response.json();
}

Python (Requests)

import requests

BASE_URL = "http://localhost:5000/api"

# Connect to robot
response = requests.post(
    f"{BASE_URL}/robot/connect",
    json={"ip": "192.168.1.100"}
)
print(response.json())

# Get robot state
response = requests.get(f"{BASE_URL}/robot/state")
print(response.json())

# Move robot
response = requests.post(
    f"{BASE_URL}/robot/move",
    json={"vx": 0.5, "vy": 0, "v_rot": 0}
)
print(response.json())

CURL

# Connect to robot
curl -X POST http://localhost:5000/api/robot/connect \
  -H "Content-Type: application/json" \
  -d '{"ip":"192.168.1.100"}'

# Get robot state
curl http://localhost:5000/api/robot/state

# Move robot forward
curl -X POST http://localhost:5000/api/robot/move \
  -H "Content-Type: application/json" \
  -d '{"vx":0.5,"vy":0,"v_rot":0}'

# Sit down
curl -X POST http://localhost:5000/api/robot/sit

# Stop
curl -X POST http://localhost:5000/api/robot/stop

WebSocket Upgrade Path

Currently using HTTP polling for state updates. Consider upgrading to WebSocket for:

  • Real-time state updates
  • Lower latency
  • Bidirectional communication
  • Better performance with multiple camera streams

Performance Metrics

  • Connection establishment: ~500-2000ms
  • State update latency: 100-500ms
  • Camera frame latency: 50-200ms (MJPEG)
  • Typical bandwidth: 2-5 Mbps per camera stream

Version

API Version: 1.0.0
Last Updated: February 19, 2026