Choosing a Centerline Generator¶
track_gen ships six registered centerline generators. The
generator is selected by passing generator=... to TrackGenConfig (or
GateGenConfig):
from track_gen import TrackGenConfig
config = TrackGenConfig(generator="bezier", num_envs=64, device="cuda")
All six generators are fully supported and deterministic in (seed, config) — byte-identical
run-to-run per device (both CPU and CUDA; repulsive included, via its analytic-adjoint
gradient). Five of the six —
every one except repulsive — are graph-capturable; repulsive is a host-driven,
non-graph-capturable optimizer that runs eagerly on CUDA every call and is roughly 1000×
slower (see Repulsive Generator). The choice is about track shape variety and
relaxation cost (and, for repulsive, generation cost), not correctness.
The Six Generators¶
Name |
Best for |
|---|---|
|
General-purpose racing tracks; the original generator with the widest parameter surface (corner count, Bezier-handle radius, edginess, style sampling). Good starting point for most workflows. |
|
Tracks with stronger lobes, pinches, and straights; the midpoint-displacement layer adds more variety than plain angle-sort Bezier, and the Catmull-Rom smoothing is lighter than a full Bezier assembly. |
|
Smooth, centered, nearly-convex tracks with low relaxation burden; starts from a closed radial representation so it is smooth and centered by construction. Good when you want consistent roundish shapes. |
|
Tracks built from a fixed site cloud with an angular-anchor cycle; tends to produce irregular, site-density-driven shapes distinct from the corner-polygon families. Useful for layout diversity. |
|
Organic, continuously-undulating “flowing” loops in the style of Gymnasium CarRacing; the bounded-turn steering gives it a different character from the star-shaped families. |
|
Dense, foldy serpentine circuits grown by self-repulsion around random obstacles; the foldiest family by far, but ~1000× slower and not graph-capturable — use only when the shape is worth the generation cost. |
How to Set the Generator¶
Pass the generator name as a string to the config constructor. The name is
looked up through the production generator registry at TrackGenerator
(or GateGenerator) construction time:
from track_gen import TrackGenerator, TrackGenConfig, PerEnvSeededRNG
import warp as wp
wp.init()
E, device = 64, "cuda"
# Switch generators by changing this one field. "repulsive" is ~1000x slower than
# the other five (it is not graph-capturable) — see docs/generators/repulsive.rst.
for name in ("bezier", "hull", "polar", "voronoi", "checkpoint", "repulsive"):
config = TrackGenConfig(generator=name, num_envs=E, device=device)
rng = PerEnvSeededRNG(seeds=0, num_envs=E, device=device)
track = TrackGenerator(config, rng).generate()
print(f"{name}: done")
To list all registered generators at runtime:
from track_gen._src.generator_registry import available
print(available())
Note
The Fourier generator lives in track_gen._experimental and is
unsupported — it is not on the Warp pipeline and receives no
compatibility guarantees.
Generator-Specific Parameters¶
Each generator has its own set of shape knobs. A few examples:
"bezier"—min_num_points,max_num_points,rad,edgy,handle_clamp_frac,style_sampling(and the*_rangefields that go with it)."hull"—hull_displacement(controls the strength of midpoint lobes and pinches)."polar"—polar_num_knots,polar_radial_jitter,polar_angular_jitter."voronoi"—voronoi_num_sites,voronoi_site_layout,voronoi_control_points,voronoi_radial_variation."checkpoint"—checkpoint_count,checkpoint_turn_rate,checkpoint_steer_gain,checkpoint_best_of_k."repulsive"—repulsive_grow_mult_min/_max,repulsive_domain_frac,repulsive_ratchet_rate,repulsive_obstacle_count_min/_max(and more — see Repulsive Generator).
All generator-specific fields live on TrackGenConfig (and GateGenConfig)
alongside the shared pipeline fields. Unrelated generator fields are silently
ignored, so you can prepare a single config with all knobs set and switch only
the generator string.
Deep-Dive References¶
Detailed descriptions of each generator’s algorithm, knobs, and tradeoffs:
Bezier Generator — Bézier corner-sort deep dive
Hull Generator — Hull midpoint-displacement deep dive
Polar Generator — Polar spline deep dive
Voronoi Generator — Voronoi site-field deep dive
Checkpoint Generator — Checkpoint-steering deep dive
Repulsive Generator — Repulsive-growth deep dive (the non-graph-capturable one)
Generator Benchmarks — Side-by-side quality, diversity, and speed metrics
Writing a Generator — contract every registered generator must satisfy