# Vehicle geometry

The constraints a vehicle works against: Ackermann steering, steady-state articulation, the coordinated bank, a rigid body on N axles, the rocket equation, and surface-piercing foil lift.

> For the complete index, see [llms.txt](https://robocn.dev/llms.txt). A Markdown version of any page is available by appending `.md` to its URL or by sending an `Accept: text/markdown` header.

## Install

```bash
bunx --bun shadcn@latest add https://robocn.dev/r/vehicle-geometry.json
```

Registry item: `vehicle-geometry` · [`https://robocn.dev/r/vehicle-geometry.json`](https://robocn.dev/r/vehicle-geometry.json)

## Notes

- Everything here is exact geometry except `pitchProgram` and `roadProfile`, which are stated shapes and say so. Nothing integrates a path, a force or a mass.
- Positive is to starboard everywhere — clockwise seen from above — the same sense as every heading in the set. `rollPoint` follows the aircraft convention instead: positive puts the starboard side down.

## Usage

```tsx
import { ackermann, hitchAngle, coordinatedBank, foilRise } from "@/lib/robocn/vehicle"

const rack = ackermann(25, { wheelbase: 120, track: 62 })
rack.inner > rack.outer   // the inner wheel runs on the smaller circle
hitchAngle(25, { wheelbase: 106, track: 60, hitch: 29 }, 57)
coordinatedBank(110, 2100) // degrees
foilRise(32, 18)           // 0 hullborne .. 1 foilborne
```

## API

| name | type | default | description |
| --- | --- | --- | --- |
| `ackermann` | `(steer: number, geometry: SteerGeometry) => AckermannPose` | — | The angle the centreline would need, answered with the two the wheels actually take, plus the radius the rear axle runs on. Exact geometry; the inner wheel always turns harder. |
| `hitchAngle` | `(steer, tractor: TractorGeometry, trailerWheelbase) => number` | — | The steady-state articulation angle of a towed section, signed with the steer. No history, so straightening the rack straightens the vehicle. |
| `coordinatedBank` | `(speed, radius, gravity?) => number` | — | atan(v²/rg), in degrees. An infinite radius or no speed is wings level. |
| `axleRide` | `(surface: (x) => number, positions) => AxleRide` | — | A rigid body on N axles over a surface: the least-squares heave and pitch it settles to, and each axle's own travel from it. |
| `tsiolkovsky / stackDeltaV` | `(massRatio, exhaustVelocity) => number / (stages) => number` | — | vₑ ln(mr), and the sum over the stages still attached. A ratio at or below one is no Δv. |
| `foilLift / foilRise` | `(speed, area, coefficient?, density?) => number / (speed, takeoff) => number` | — | The ideal lift equation, and the rise that follows from it: below the takeoff speed nothing, above it the wetted fraction is (takeoff/v)² and the rest is the climb. |
| `pitchProgram` | `(fraction: number, kick?: number) => number` | — | Illustrative. Degrees from vertical over an ascent: vertical off the pad, kicked over early, most of the turn taken in the middle. Not a solved trajectory. |
| `roadProfile` | `(x, amplitude?, wavelength?) => number` | — | Illustrative. Two sines that do not share a period, so a body running over it never repeats over a short run. |
| `wheelSolid / rollPoint` | `(centre, radius, halfWidth, steer?, steps?) => Vec3[] / (point, depth, roll, centre?) => Vec3` | — | Drawing geometry: a steered wheel as the solid it is, and a profile-elevation point lifted into the world and rolled about the fore-aft axis. Both feed straight into slabPath. |

## Source

- `src/lib/robocn/vehicle.ts`
