Plan a collision-free, kinematically feasible parking trajectory for an
Ackermann vehicle in extremely narrow unstructured scenes. Each case
gives a start pose, a goal parking pose, and polygonal obstacles forming
dead-ends, tight corridors and slots barely wider than the car. The
combination of non-convex collision constraints, nonholonomic kinematics
and gear-switch structure makes this NP-hard, and the hardest scenes in
this family defeat most planners outright. Your planner runs on unseen
cases including slots whose channel width is only 1.05–1.15× the car
width — the difficulty-critical knob.
Hard Constraints
Implement solve(case_csv: str, time_limit_s: float) -> np.ndarray in
/app/methods/main/solver.py; keep the entry point importable
(module-level solve). Returning None (no solution) is allowed and
scores the failure penalty on that case.
Output: one trajectory array, rows [t, x, y, theta, v, delta] —
(x, y, theta) is the REAR-AXLE pose, v signed speed (m/s), delta
front steering angle (rad). t[0] = 0, strictly increasing, sample
spacing dt ≤ 0.11 s.
Vehicle: wheelbase 2.8 m, front hang 0.96 m, rear
hang 0.929 m, width 1.942 m. Limits: |v| ≤ 2.5, |dv/dt| ≤ 1.0,
|delta| ≤ 0.75, |d delta/dt| ≤ 0.5.
The sealed verifier re-checks everything: start pose match (1 mm),
discrete kinematic consistency of the rear-axle bicycle model
(trapezoidal rule, 0.02 m/step tolerance), all four limits, collision
of the full vehicle rectangle against every obstacle polygon at every
sample and at ≤ 0.2 m interpolated sub-steps, and terminal condition:
position within 0.10 m, heading within 2°, |v| ≤ 0.05.
Any violation, or no output, scores the failure penalty
T_FAIL = 240 s on that case.
time_limit_s (60) is the per-case computation budget; the verifier
kills the child process on a safety net above it. Computation time is
NOT part of the score — only the hard cap. (The score is deliberately
the transparent variant: parking duration under a hard compute cap.
See provenance.)
Do not read, probe, or special-case anything outside /app; the
hidden cases and anchors are not in your environment.
Trajectories must satisfy the DISCRETE trapezoidal kinematics the verifier checks — generate them with the same integration rule, or drift will trip the 0.02 m consistency tolerance.
The verifier's collision check uses a ≤ 0.1 m step; a trajectory that grazes corners between coarser samples fails.
A child that overruns time_limit_s is killed by the safety net and that case scores 240.
What You Have
/app/parking.py — the full public evaluator: load_case,
check_trajectory (every check above), score. What it reports is
what you are graded on.
/app/data/ — ten visible cases, V1.csv … V10.csv; they
span the full difficulty range, from roomy lots to scenes the weak
baseline cannot solve at all.
/app/methods/main/solver.py — the weak baseline: coarse hybrid A*
(0.4 m grid, 3 steering values, 0.8 m arcs, Reeds-Shepp goal shots)
with a stop-and-steer trajectory profile. It solves easy cases with
slow, long manoeuvres and fails on narrow ones.
Trajectory-generation helper inside the template: a profile builder
that emits trajectories satisfying the verifier's trapezoidal
kinematics exactly — reuse it or replace it.
What You Submit
The whole /app/methods directory; the graded artifact is
methods/main/solver.py with the solve contract above. Anything else
you write under /app stays local; only methods/ is exported.
How It Is Judged
The sealed verifier runs your solve on fourteen hidden cases —
the same geometry family as the visible ones (unstructured lots with
polygonal obstacles, perpendicular and parallel slots, channel widths
down to 1.05× the car width) — and re-validates every trajectory with
its own trusted evaluator in a separate process.
Per case: score = T_park (the trajectory's final time, seconds) if
valid, else 240. The task score is the mean over the hidden cases,
lower is better; the reward curve and its anchors are sealed inside the
verifier.
Metric
mean T_park over the 14 sealed hidden parking cases · lower is better
Trajectory final time in seconds; any invalid or missing trajectory scores 240 s on that case
anchor
held-out
reward
B
shipped template (coarse hybrid A*)
124.20
0.00
R
adaptive verify-and-retry pipeline
93.09
0.30
S
sequential portfolio at 60 s
78.48
0.60
normalisation
m >= B
0
B > m >= R
0.3 * (ln B - ln m) / (ln B - ln R)
R > m >= S
0.3 + 0.3 * (ln R - ln m) / (ln R - ln S)
m < S
1 - 0.4/y, y = 1 + (ln S - ln m)/(ln R - ln S)
m = this run's held-out metric · B = shipped template (coarse hybrid A*) · R = adaptive verify-and-retry pipeline · S = sequential portfolio at 60 s
Cases are averaged first, then mapped once. No upper anchor: past SOTA the hyperbolic cap rises toward 1.0 and never reaches it.
Rollouts
191 minwall clock
$59.55spend
97.3Mtokens
59versions, 45 kept
keptrevertedno scoreturning point
v0Inherited coarse hybrid-A* baseline, unchanged135.3712 min · $0.36
v1Search the hybrid-A* path from the goal backwards, then reverse it55.4728 min · $1.11
v2Near-limit dynamics in the trapezoidal profile: 2.5 m/s, 0.999 m/s^252.7359 min · $1.36
v3Fine terminal-tolerance escape search plus exact validation before returnEscape the slot on a fine lattice seeded from the goal region, then re-check it with the exact evaluator.39.79614 min · $2.03
v4Fine-search cost in execution terms: gear cost 1.2, steering-break cost 1.5Cost the search in the quantity being graded, execution time, instead of path length. 29 gear switches become 12.28.50717 min · $2.70
v5Rank Reeds-Shepp connections by estimated stop/steer execution time27.49819 min · $3.16
v6Bounded multi-resolution reverse portfolio at 0.4/0.6/0.7/0.8 m grids26.82227 min · $4.75
v7Keep incoming steering in the fine-state hash; duration-rank the analytic tailno dev mean logged30 min · $5.38
v8Reeds-Shepp shortcut DAG over fine-lattice endpoint poses26.39232 min · $6.04
v9Retune fine search toward fewer gear changes (gear/steer/heuristic 3/1/1.2)26.32937 min · $7.35
v10Orientation-aware RS plus inflated holonomic-grid heuristic above 20 m26.32942 min · $8.66
v11Extend the shortcut DAG to every coarse and forward portfolio candidate25.24544 min · $9.37
v12Keep unmerged lattice endpoints as shortcut vertices; wider creep trials25.15547 min · $10.37
v13Trim the final primitive into the terminal tolerance box25.12249 min · $10.95
v14Use the exact allowed 1.0 m/s^2 and 0.5 rad/s limits25.12952 min · $11.87
v15Moving-steering profiles consuming 50-100% of the following move25.12953 min · $12.56
v16Enforce the stricter 0.1 m interpolated collision audit when selecting25.12956 min · $13.36
v17Widen fine terminal seeds to +/-0.09 m and +/-1.9 degno dev mean logged61 min · $15.54
v18Align analytic and shortcut cost estimates with the submitted limits25.12962 min · $16.09
v19Enable the grid+RS heuristic on short scenes as well as long ones25.12968 min · $18.23
v20Direction-aware coarse hashing in the post-failure 0.6 m fallback only25.12970 min · $19.12
v21Deduplicate identical merged candidates before trusted validation25.12972 min · $19.83
v22Weight-2 grid/RS A* candidate for start-goal separation above 18 m24.98474 min · $20.85
v23Cap each coarse shortcut-DAG pass at 1.0 s instead of 1.5 s24.98477 min · $22.19
v24Compare four deterministic half-cell hash phasesno dev mean logged80 min · $23.57
v25Gauss-Newton refit overlapping steering ramps with travel, endpoint fixedStop stopping to steer: overlap each ramp with the move around it and refit primitive lengths so the pose still lands.24.72784 min · $24.75
v26Apply the moving-steer refit to three base candidates under one deadline24.64285 min · $25.54
v27Sweep larger 0.8/0.6 m overlap distances before the proven fallbacks24.40588 min · $26.89
v28Prepend 2.0 and 1.2 m overlap trials23.74690 min · $27.91
v29Prepend a saturating 10 m overlap trial23.68492 min · $28.95
v30Refit four base candidates instead of five, at 1.5 s each23.58996 min · $30.93
v31Fractional 0.5/0.75/0.9 saturation in the moving-steer refitno dev mean logged99 min · $32.21
v32Allow the aggressive refit on up to 15 moves, tight slot includedno dev mean logged100 min · $32.82
v33Audit: drop each of the nine pocket manoeuvres, reproject, collision-samplecode unchanged, audit102 min · $33.70
v34Audit: narrow the widest development channel to 2.10, 2.04 and 2.02 mcode unchanged, audit103 min · $34.34
v35Accelerating steering ramp running on into a constant-steer braking profile21.691106 min · $36.08
v36Allow accelerating refits on the 12-move tight-slot shortcutno dev mean logged107 min · $36.72
v37Add a 1.6 m accelerating-overlap trial between saturation and 1.2 m21.612110 min · $37.88
v38Accelerate and refit the fifth-best base candidate too21.612111 min · $38.79
v39Skip the symmetric refit when the accelerating one is valid, best path aside21.612114 min · $40.62
v40Late-acceleration refit at 2.0 m: steer near rest, then accelerate21.401117 min · $42.14
v41Sweep late-acceleration overlap; try 2.2 m before the 2.0 m fallback21.349124 min · $42.99
v42Masked moving-steer refit for the fine fallback, pocket primitives untouched21.112131 min · $43.94
v43Audit: per-transition overlap fits on the nine remaining pocket shuntscode unchanged, audit132 min · $44.19
v44Audit: sweep fine-lattice primitive length 0.045-0.09 m on the tight slotcode unchanged, audit136 min · $44.76
v450.05 m lattice as a second fine fallback when over 22 s of budget is left20.889138 min · $45.13
v46Speed-continuous same-gear profile: steer at speed, refit lengths only20.7147 min · $46.86
v47Carry continuous flow through gear changes with a ramped new-gear speed20.324152 min · $48.14
v48Keep three arc-fraction settings, 0.75/0.90/0.99, for the flow ramp19.658158 min · $49.60
v49Audit: local fraction sweep near 0.78 and across 0.94-0.9999code unchanged, audit162 min · $50.49
v50Continuous flow on the first three same-gear controls of fine fallbacks19.481163 min · $51.03
v51Decouple same-gear flow fraction from gear-change travel; partial trial19.174168 min · $52.38
v52Audit: 99 fraction and gear-distance combinations on one winning candidatecode unchanged, audit171 min · $53.34
v53Add a moderate-flow partial-gear setting: 4.0 m, fraction 0.9, 0.3 m gear18.936175 min · $54.58
v54Set the alternate fine lattice gear-switch cost to 4 after a 2-10 sweep18.927179 min · $55.71
v55Audit: fine steering alphabets, steering costs and heuristic weightscode unchanged, audit186 min · $57.87
v56Audit: rerun the two slowest branches on a 50 s deadline instead of 60code unchanged, audit190 min · $58.89
v57Documentation-only finalisation of the module description18.927190 min · $59.13
v58Final contract and static audit: import, compile, snapshot resolution18.927191 min · $59.47
59 snapshots, 191 min, $59.55. Visible mean 135.4 -> 18.9 s; the last 28 snapshots cost $28.5 of that for 4.7 s of it.