Quickstart¶
Track generation¶
The following minimal example generates a batch of 64 closed-loop race tracks on CUDA.
import warp as wp
wp.init()
from track_gen import TrackGenerator, TrackGenConfig, PerEnvSeededRNG
E, device = 64, "cuda" # or "cpu"
config = TrackGenConfig(num_envs=E, half_width=0.03, device=device)
rng = PerEnvSeededRNG(seeds=0, num_envs=E, device=device)
generator = TrackGenerator(config, rng)
track = generator.generate() # fixed batch: config.num_envs tracks
center = wp.to_torch(track.center).view(E, config.N_max, 3)
outer = wp.to_torch(track.outer).view(E, config.N_max, 3)
inner = wp.to_torch(track.inner).view(E, config.N_max, 3)
valid = wp.to_torch(track.valid).bool()
count = wp.to_torch(track.count)
center[0, : int(count[0])] # real arc-uniform centerline points for env 0
TrackGenerator is fixed-batch. Omit generate()’s argument, or pass the integer
E == config.num_envs; explicit environment-id sequences are rejected because the CUDA
graph captures one fixed batch shape. Results are read via wp.to_torch, which provides
a zero-copy view of the underlying Warp array as a PyTorch tensor. The same Track
instance and Warp buffers are reused on every call, so use track.clone() when you need
an independent snapshot.
Gate sequence generation¶
For drone-style courses where track width is irrelevant, use GateGenerator.
It emits gate centres and orientations directly from native centerline-generator anchors
and skips constant-spacing, XPBD relaxation, and inflation.
import warp as wp
wp.init()
from track_gen import GateGenConfig, GateGenerator, PerEnvSeededRNG
E, device = 64, "cuda"
config = GateGenConfig(
generator="bezier",
gate_ordering="random_pairs",
num_envs=E,
max_gates=32,
gate_width=0.4,
gate_radius=0.025,
gate_solve_iters=8,
device=device,
)
rng = PerEnvSeededRNG(seeds=0, num_envs=E, device=device)
gates = GateGenerator(config, rng).generate()
position = wp.to_torch(gates.position).view(E, config.max_gates, 3)
tangent = wp.to_torch(gates.tangent).view(E, config.max_gates, 3)
valid = wp.to_torch(gates.valid).bool()
GateGenerator follows the same fixed-batch contract as TrackGenerator: the output
batch size is always config.num_envs. Results are read via wp.to_torch for
zero-copy access as PyTorch tensors. The same GateSequence instance and its Warp
buffers are reused on every generate() call; use gates.clone() when you need an
independent snapshot.
The GateSequence fields are:
Field |
Shape |
Meaning |
|---|---|---|
|
|
gate centers ( |
|
|
unit tangent and left-normal at each gate |
|
|
gate endpoints ( |
|
|
per-sequence validity |
|
|
real gates per env; slots |