Планирование траекторий на GPU

Задача страницы. Инженерный гид по построению сервисов планирования траекторий на GPU для мобильных роботов и манипуляторов: графовый/семплирующий планинг (A*/D*‑семейство, PRM*/RRT*/BIT*), траектории‑оптимизация (CHOMP/STOMP/MPPI/iLQR), параллельная проверка коллизий, ESDF/SDF‑карты и мульти‑роботные сценарии. Дадим пайплайны real‑time и батч, таблицу sizing по профилям 24/48/80 ГБ, конфиги (Docker/K8s/YAML), метрики и экономику. Паттерны: NVMe‑кэш карт/ассетов, раздельные пулы On‑Demand (онлайн‑планинг) и Interruptible (оффлайн‑предрасчёты), наблюдаемость и безопасные фоллбэки.

TL;DR

  • Многоуровневый планер: глобальный путь (граф/решётка) → локальная траектория (оптимизация/MPC) → контроллер; ESDF/SDF обновляется на GPU из сенсоров. См. также симуляцию: https://cloudcompute.ru/solutions/isaac-sim/
  • GPU‑акселерация: параллельные collision‑checks, batch‑IK, оценка стоимостей и rollout‑ов (MPPI/iLQR) пачками, построение PRM/roadmap и параллельное расширение RRT.
  • **Режимы: On‑Demand — низкая латентность (пере‑план 10–100 Гц, окно ≤ 100–200 мс). Interruptible — оффлайн‑предрасчёты (PRM/heat‑maps), обновление ESDF, stress‑тесты.
  • Наблюдаемость: plan_time p50/p95, success_rate@T, path_length/curv/jerk, collision_free_rate, replans_per_min, esdf_update_latency, gpu_util/HBM.
  • Экономика: Cost_per_100_plans ≈ 100 × c_gpu × t_plan / (3600 × U). Для флота: Robots_per_GPU ≈ floor( 1 / (t_plan × f_replan × safety_margin) ).
  • Тюнинг: FP16 для стоимостей/градиентов, pinned/zero‑copy, CUDA‑группировка по типу препятствий, микробатчинг траекторий. См. https://cloudcompute.ru/solutions/performance-tuning/ и https://cloudcompute.ru/solutions/throughput-vs-latency/

Сценарии (когда это нужно)

  • Мобильная навигация (2D/2.5D): склад/аутдор, динамические препятствия, частые пере‑планы, приоритеты по миссиям.
  • Манипуляция (6–7‑DoF): захват/укладка, обход сомкнутых препятствий, кинематические/динамические ограничения.
  • Мульти‑робот: распределённый планинг с учётом конфликтов (время‑пространство), «резервации» ячеек/отрезков.
  • Off‑road/тяжёлые сцены: ESDF из лидара/стерео, MPPI/iLQR с нелинейной динамикой, стокхастические rollout‑ы.

Архитектуры/пайплайны 1) Мобильный робот: глобальный граф → локальная траектория (GPU)

Sensors (Depth/LiDAR) ─> ESDF/SDF Update (GPU, 10–30 Hz)
 └─> Global Planner (A*/D* on grid/graph)
 └─> Local TrajOpt (MPPI/iLQR/CHOMP, GPU)
 └─> Time Param (vel/acc/jerk)
 └─> Controller (MPC/PID)
 └─> Actuators

Особенности: ESDF обновлять инкрементально; локальный планер — каждые 10–50 мс на фиксированном горизонте 1–3 с.

2) Манипулятор: IK/семплирование → траектория‑оптимизация

Target Pose(s)
 └─> Batch IK (GPU)
 └─> Sampling (RRT*/PRM* with GPU collision checks)
 └─> Smoothing/TrajOpt (CHOMP/STOMP, jerk limits)
 └─> Time Param (TOTG-like)
 └─> Controller (joint-space)

Особенности: параллельные проверki коллизий по BVH/SDF; после RRT* — сглаживание и time‑скейлинг.

3) Мульти‑робот: шедулер запросов + анти‑конфликт

N Robots ─> Request Queue ─> GPU Planner Pool ─> Reservation Table (space-time)
 └─> Conflict Resolve (priorities/shift)

Особенности: микробатчинг запросов на GPU; «резервации» секций пути по времени, мягкие штрафы на конфликты.

Профили GPU и ориентиры (инженерные диапазоны)

Диапазоны для одновременных онлайн‑планов при U≈0.7, фиксированном бюджете t_plan ≤ 50–100 мс и средних сценах. Реальные числа зависят от плотности препятствий, дискретизации ESDF и DoF.

**Профиль GPU** **Память** **Типовой стек** **Планы/с (mobile)\*** **Планы/с (arm 7‑DoF)\*\*** **Комментарии**
24 ГБ (Compact) 24 ГБ ESDF 512², A\* + MPPI 200–600 10–25 Базовые сцены, умеренная динамика.
48 ГБ (Balanced) 48 ГБ ESDF 1024²/3D 256³, A\*/RRT\* + MPPI 600–1200 25–50 Баланс точности/скорости, стабильный p95.
80 ГБ (HQ) 80 ГБ ESDF 2K²/3D 384³, PRM\*/RRT\* + TrajOpt 1200–2500 50–100 Сложные сцены, плотные препятствия.

* 2D/SE(2) локальный горизонтом 2 с, 20–50 мс на траекторию. ** Полный цикл sampling→smoothing→time‑param при ограниченном бюджете. Тюнинг/распределёнка: https://cloudcompute.ru/solutions/multi-gpu/ и https://cloudcompute.ru/solutions/performance-tuning/

Конфиги и скелеты кода

Docker Compose (онлайн‑планер + оффлайн‑предрасчёт)

version: "3.9"
x-env: &env
 MAP_RESOLUTION: "0.05" # м/пиксель (2D) или м/воксель (3D)
 ESDF_SIZE: "1024,1024,64" # ширина, высота, (глубина)
 PLANNER_GLOBAL: "astar" # astar|dstar|prm|rrt
 PLANNER_LOCAL: "mppi" # mppi|ilqr|chomp|stomp
 TIME_BUDGET_MS: "50"
 REPLAN_RATE_HZ: "20"
 BATCH_SIZE: "512" # для MPPI/TrajOpt
 PRECISION: "fp16" # bf16|fp16|fp32
 SAFETY_CLEARANCE_M: "0.2"
services:
 planner-rt:
 image: cloudcompute/planner:latest
 environment:
 <<: *env
 MODE: "realtime"
 deploy:
 resources:
 reservations:
 devices: [{ capabilities: ["gpu"] }]
 ports: ["9300:9300"]
 volumes:
 - /nvme/maps:/maps
 - /nvme/cache:/var/cache/planner
 command: ["python","serve_rt.py","--host=0.0.0.0","--port=9300"]
 planner-precompute:
 image: cloudcompute/planner:latest
 environment:
 <<: *env
 MODE: "offline"
 PLANNER_GLOBAL: "prm" # предрасчёт roadmaps
 deploy:
 resources:
 reservations:
 devices: [{ capabilities: ["gpu"] }]
 volumes:
 - /nvme/maps:/maps
 - /nvme/roadmaps:/roadmaps
 command: ["python","build_prm.py","--maps","/maps","--out","/roadmaps"]

K8s (1 GPU/под, readiness + ресурсы)

apiVersion: apps/v1
kind: Deployment
metadata: { name: planner-rt }
spec:
 replicas: 3
 selector: { matchLabels: { app: planner-rt } }
 template:
 metadata: { labels: { app: planner-rt } }
 spec:
 containers:
 - name: planner
 image: cloudcompute/planner:latest
 ports: [{ containerPort: 9300 }]
 env:
 - { name: PLANNER_LOCAL, value: "mppi" }
 - { name: TIME_BUDGET_MS, value: "50" }
 - { name: BATCH_SIZE, value: "512" }
 - { name: PRECISION, value: "fp16" }
 readinessProbe:
 httpGet: { path: /healthz, port: 9300 }
 periodSeconds: 5
 resources:
 limits: { nvidia.com/gpu: 1, cpu: "4", memory: "24Gi" }

Конфиг пайплайна (YAML)

map:
 source: "/maps/site_A/" # ESDF/слои препятствий
 resolution_m: 0.05
 esdf:
 size: [1024, 1024, 64]
 update_hz: 20
 inflation_m: 0.2
robot:
 type: "mobile" # mobile|arm
 base_radius_m: 0.35
 dyn_limits: { v_max: 1.5, a_max: 1.0, jerk_max: 2.0 }
planner:
 global:
 type: "astar" # astar|dstar|prm|rrt
 heur: "euclid"
 tie_breaker: 1.001
 local:
 type: "mppi" # mppi|ilqr|chomp|stomp
 horizon_s: 2.0
 steps: 40
 batch: 512
 costs:
 w_length: 1.0
 w_clearance: 2.0
 w_smooth: 0.5
 w_jerk: 0.1
 temperature: 0.3 # для MPPI
time_param:
 method: "trapezoidal"
 sample_dt: 0.02
multi_robot:
 enable: true
 reservation_horizon_s: 5.0
 fairness: "round_robin"
serving:
 max_qps: 200
 timeout_ms: 80
FastAPI: REST/SSE для планов и пере‑планов
from fastapi import FastAPI, Body
from sse_starlette.sse import EventSourceResponse
import json, time
app = FastAPI()
planner = load_planner_from_yaml("config.yaml")
@app.post("/plan")
def plan_endpoint(payload: dict = Body(...)):
 start, goal, stamp = payload["start"], payload["goal"], payload.get("t", time.time())
 sol = planner.plan(start, goal, stamp, timeout_ms=80)
 return {"ok": sol.ok, "path": sol.path, "cost": sol.cost, "t_ms": sol.t_ms}
@app.post("/replan/stream")
async def replan_stream(payload: dict = Body(...)):
 start, goal = payload["start"], payload["goal"]
 async def gen():
 async for sol in planner.replan_stream(start, goal, rate_hz=20):
 yield {"event":"plan", "data": json.dumps({"ok":sol.ok,"path":sol.path,"t_ms":sol.t_ms})}
 yield {"event":"done","data":"{}"}
 return EventSourceResponse(gen())

FastAPI: REST/SSE для планов и пере‑планов

from fastapi import FastAPI, Body
from sse_starlette.sse import EventSourceResponse
import json, time
app = FastAPI()
planner = load_planner_from_yaml("config.yaml")
@app.post("/plan")
def plan_endpoint(payload: dict = Body(...)):
 start, goal, stamp = payload["start"], payload["goal"], payload.get("t", time.time())
 sol = planner.plan(start, goal, stamp, timeout_ms=80)
 return {"ok": sol.ok, "path": sol.path, "cost": sol.cost, "t_ms": sol.t_ms}
@app.post("/replan/stream")
async def replan_stream(payload: dict = Body(...)):
 start, goal = payload["start"], payload["goal"]
 async def gen():
 async for sol in planner.replan_stream(start, goal, rate_hz=20):
 yield {"event":"plan", "data": json.dumps({"ok":sol.ok,"path":sol.path,"t_ms":sol.t_ms})}
 yield {"event":"done","data":"{}"}
 return EventSourceResponse(gen())

GPU‑коллизии (CuPy): batched‑проверки по ESDF

import cupy as cp
# esdf: 3D тензор расстояний (м), grid с шагом res
@cp.fuse()
def trilinear(esdf, x, y, z):
 # упрощённо: интерполяция значения ESDF в координате
 return esdf[int(z), int(y), int(x)]
def batch_collision(esdf, poses_xyz, radius, res):
 # poses_xyz: [B, 3] метры → индексы
 idx = cp.floor(poses_xyz / res).astype(cp.int32)
 d = trilinear(esdf, idx[:,0], idx[:,1], idx[:,2])
 return d - radius # >0 безопасно, ≤0 коллизия
# пример: проверим 65k поз параллельно
B = 65536
poses = cp.random.uniform(0, 50, (B, 3), dtype=cp.float32)
free_margin = batch_collision(esdf_gpu, poses, radius=0.35, res=0.05)

MPPI (псевдокод): параллельная оценка траекторий

def mppi_step(x0, U, sigma, K, rollout_fn, cost_fn, lambda_=0.3):
 # x0: текущее состояние; U: [H, m] базовое управление; K: батч
 noise = sigma * torch.randn(K, *U.shape, device="cuda")
 Uk = U.unsqueeze(0) + noise
 traj = rollout_fn(x0, Uk) # [K, H+1, state_dim]
 costs = cost_fn(traj, Uk) # [K]
 w = torch.softmax(-costs / lambda_, dim=0)
 dU = (w.view(-1, 1, 1) * noise).sum(dim=0)
 return U + dU, costs.min()
``` ## **Наблюдаемость/метрики/алерты**

**Latency/Perf:**

- planner\_time\_seconds{stage=global|local|collision|esdf} (p50/p95).
- success\_rate\_within\_T{T=80ms} — доля удачных планов в бюджет.
- replans\_per\_min, queue\_wait\_ms, timeout\_rate.
- gpu\_utilization, gpu\_mem\_peak\_bytes, esdf\_update\_latency\_ms.

**Quality/Path:**

- path\_length\_m, min\_clearance\_m, curvature\_mean, jerk\_rms.
- collision\_free\_rate (по симуляции/реплеям), goal\_reach\_time\_s.

**Ops:**

- reservation\_conflicts (multi‑robot), fallback\_used\_total (A\*/stop), map\_age\_s.

**Алерты (примеры):**

- planner\_time\_p95 &gt; budget — уменьшить BATCH\_SIZE/steps, понизить разрешение ESDF, разделить сервисы (global/local).
- success\_rate\_within\_T &lt; target — увеличить TIME\_BUDGET\_MS, ослабить штрафы, включить предрасчёт PRM.
- collision\_free\_rate &lt; 1.0 — увеличить inflation/clearance, актуализировать ESDF/калибровать сенсоры.
- gpu\_mem\_peak/HBM &gt; 0.9 — уменьшить размер ESDF/roadmap, FP16, шардинг по зонам.

Детали: <https://cloudcompute.ru/solutions/monitoring-logging/> • <https://cloudcompute.ru/solutions/llm-inference/observability/>

## **Экономика и формулы**

Обозначения: c\_gpu — цена/час, U — целевая загрузка, t\_plan — среднее время плана (сек), f\_replan — частота пере‑планов на робота (Гц).

- **Стоимость 100 планов:
 Cost\_per\_100\_plans ≈ 100 × c\_gpu × t\_plan / (3600 × U).
- **Сколько роботов на 1 GPU (онлайн):
 Robots\_per\_GPU ≈ floor( 1 / (t\_plan × f\_replan × safety\_margin) ), где safety\_margin≈1.2–1.5.
- **Батч‑предрасчёты (PRM/roadmaps):
 T\_offline ≈ N\_samples / (samples\_per\_sec × N\_gpu × U).
- **Время до первого пути:
 TTFP ≈ t\_esdf + t\_global + t\_local\_init. Снижайте t\_esdf кэшированием и инкрементальной интеграцией.

Компромиссы throughput↔latency: <https://cloudcompute.ru/solutions/throughput-vs-latency/> • бюджет: <https://cloudcompute.ru/solutions/cost-planner/>

**Безопасность/политики**

- **Fail‑safe:** при невозможности построить траекторию — замедление/стоп, безопасный коридор/поддержка A\*‑фоллбэка.
- **Валидация карты:** возраст ESDF/источник данных; отбраковка «дыр»/шумов; тесты на эталонных сценах.
- **Ограничения:** жёсткие лимиты скорости/ускорения/jerk и зоны запрета.
- **Изоляция:** отдельные пулы GPU для интерактива (On‑Demand) и оффлайна (Interruptible); контроль доступа к картам/ассетам.
- **Телеметрия:** храните только агрегаты/трассы без PII; шифрование «в канале/на диске». См. <https://cloudcompute.ru/solutions/security/>

**Траблшутинг**

<table><tbody><tr><td>**Симптом**

</td><td>**Возможная причина**

</td><td>**Решение**

</td></tr><tr><td>Путь не находится

</td><td>Завышенные clearance/узкие проходы

</td><td>Ослабить inflation, снизить разрешение карты, включить PRM/RRT\* фоллбэк

</td></tr><tr><td>План &gt; бюджета

</td><td>Слишком большой batch/шагов, тяжёлая сцена

</td><td>Уменьшить BATCH\_SIZE/steps, понизить ESDF‑разрешение, разделить global/local

</td></tr><tr><td>Осцилляции/дребезг

</td><td>Конфликт целей/штрафов, нет гистерезиса

</td><td>Добавить гистерезис в выбор решений, усилить w\_smooth/w\_jerk, увеличить горизонт

</td></tr><tr><td>Столкновения в реале

</td><td>Некорректный ESDF/запаздывание карты

</td><td>Увеличить inflation, ограничить скорость при map\_age&gt;порога, калибровать сенсоры

</td></tr><tr><td>VRAM OOM

</td><td>Большие ESDF/roadmap/батчи

</td><td>FP16, уменьшить размер сетки/длину горизонта, шардировать карту

</td></tr><tr><td>Флот «затыкается»

</td><td>Конфликты/узкие коридоры

</td><td>Включить «резервации» по времени, приоритеты, небольшой «джиттер» стартов

</td></tr><tr><td>Плохие траектории у манипулятора

</td><td>Локальные минимумы

</td><td>После RRT\* — CHOMP/STOMP сглаживание; случайные рестарты; batch‑IK

</td></tr></tbody></table>

См. также: <https://cloudcompute.ru/solutions/interruptible-patterns/> • <https://cloudcompute.ru/solutions/performance-tuning/>

**Как запустить в cloudcompute.ru**

1. Откройте **Шаблоны запусков**: <https://cloudcompute.ru/solutions/templates/> — выберите **GPU Planner (Realtime)** и/или **GPU Planner (Offline PRM/Roadmaps)**.
2. Выберите профиль GPU: **24/48/80 ГБ** — по размеру ESDF/DoF и целевому бюджету времени.
3. Подключите диски: /nvme/maps, /nvme/roadmaps, /nvme/cache.
4. Настройте параметры пайплайна (planner.yaml): типы планеров, горизонты, веса стоимостей, лимиты динамики.
5. Продакшн: раздельные пулы **On‑Demand/Interruptible**, автоскейл по U/latency/queue, дашборды и алерты, канареечные обновления карт/весов.

Дополнительно по стеку:

- Симуляция/датасеты: <https://cloudcompute.ru/solutions/isaac-sim/>
- Мульти‑GPU и распределёнка: <https://cloudcompute.ru/solutions/multi-gpu/>
- Тюнинг производительности: <https://cloudcompute.ru/solutions/performance-tuning/>
- Throughput vs Latency: <https://cloudcompute.ru/solutions/throughput-vs-latency/>
- Хранилища/ассеты: <https://cloudcompute.ru/solutions/storage-data/>
- Мониторинг: <https://cloudcompute.ru/solutions/monitoring-logging/>
- Наблюдаемость инференса: <https://cloudcompute.ru/solutions/llm-inference/observability/>
- Gradio + FastAPI (UI/эндпойнты): <https://cloudcompute.ru/solutions/gradio-fastapi/>
- CI/CD контейнеров: <https://cloudcompute.ru/solutions/containers-ci-cd/>

**Чек‑лист перед продом**

- Достигнут planner\_time p95 в бюджете (например, ≤ 50–100 мс) и success\_rate@T.
- ESDF обновляется инкрементально; esdf\_update\_latency p95 в пределах SLA.
- Настроены inflation/clearance, лимиты v/a/jerk, безопасные фоллбэки.
- Валидация траекторий на контрольных сценах/симуляторе; регресс‑набор пройден.
- Дашборды и алерты: latency/success/collision‑free/HBM/queue/map\_age.
- Разнесены пулы **On‑Demand/Interruptible**; канареечные релизы карт/весов; план отката.
- Нагрузочный прогон ≥ 30 мин с целевыми сценами и скоростями роботов.

Готовы запустить?

Запустить GPU-сервер