A self-driving car grows a tree of curved manoeuvres, then reverses into its spot.
A car cannot move sideways, so every path is built from arcs at its tightest turning circle and straight lines, driven forward or in reverse. Between any two poses the shortest such path is one of 48 Reeds-Shepp words, each with a closed-form solution, and the planner scores them with extra cost for reversing and for every gear change. RRT grows a tree from the car by sampling random poses and steering toward them along these curves, keeping only branches where the car's footprint clears every parked car (an oriented box test with the separating axis theorem). RRT* also picks the cheapest parent for each new node and rewires its neighbours through it whenever that is cheaper, so the solution keeps improving toward the optimum; the cost chart shows the staircase, and plain RRT settles for its first, wiggly answer. Then the car drives the result, cyan forward and magenta in reverse, with reverse lights on at every cusp.
Try it. Drag any parked car or the green target and the planner starts over around the new layout. Click an empty bay to park there. Switch between RRT* and RRT to compare (Space), replan (R), go to the next spot (N), or turn the target with Q and E. Once both planners have tried the same spot, the chart marks the other one's cost. Left alone, the car tours the lot from bay to bay.
RRT and RRT* with rewiring
Reeds-Shepp curves
Separating axis collision tests
Isometric projection with an affine ground transform
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a car parking motion planner in JavaScript and the HTML canvas element, using RRT with car-like steering. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Draw a top-down parking lot on a sharp, high-DPI canvas: parked cars as rectangles around one empty spot, and our car as a rectangle with a pose (x, y, heading) at its rear axle.
- Model it as a Dubins car first: it only drives forward, along arcs of a minimum turning radius or straight lines. Write a function that moves a pose by a steering choice (left, straight or right) and a distance.
- Grow an RRT from the car: pick a random pose, find the nearest node by a distance mixing position and heading, try each steering choice for 3 metres, and keep the one ending closest to the sample if the car's rectangle never overlaps a parked car on the way. Draw every branch as a thin curve.
- Sometimes sample the goal itself; when a branch ends close to it, trace the path back to the root and draw it.
Once that works, make it beautiful:
- Replace the steering with Reeds-Shepp curves, which also allow reversing. Implement a few of the classic word families (like CSC and CCC) in closed form, so the tree can steer exactly to a sample and the car can reverse into a parallel spot.
- Upgrade to RRT*: connect each new node to whichever nearby node gives the cheapest path, then rewire neighbours through it when that is cheaper. Plot the best cost over time and watch it fall.
- Animate the car along the final path, with forward segments in one colour and reverse in another.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as an isometric 3D view, Hybrid A* search on a grid of headings, or a cost for gear changes so the car prefers fewer manoeuvres.