Планирование траекторий на 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 > budget — уменьшить BATCH\_SIZE/steps, понизить разрешение ESDF, разделить сервисы (global/local).
- success\_rate\_within\_T < target — увеличить TIME\_BUDGET\_MS, ослабить штрафы, включить предрасчёт PRM.
- collision\_free\_rate < 1.0 — увеличить inflation/clearance, актуализировать ESDF/калибровать сенсоры.
- gpu\_mem\_peak/HBM > 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>План > бюджета
</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>порога, калибровать сенсоры
</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-сервер