@aura3d/physics 1.5.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ArcadeCharacterController.d.ts +53 -0
- package/dist/ArcadeCharacterController.d.ts.map +1 -0
- package/dist/ArcadeCharacterController.js +98 -0
- package/dist/ArcadeCharacterController.js.map +1 -0
- package/dist/ArcadeVehicleTelemetry.d.ts +162 -0
- package/dist/ArcadeVehicleTelemetry.d.ts.map +1 -0
- package/dist/ArcadeVehicleTelemetry.js +363 -0
- package/dist/ArcadeVehicleTelemetry.js.map +1 -0
- package/dist/CharacterController.d.ts +52 -0
- package/dist/CharacterController.d.ts.map +1 -1
- package/dist/CharacterController.js +380 -7
- package/dist/CharacterController.js.map +1 -1
- package/dist/Constraint.d.ts +20 -4
- package/dist/Constraint.d.ts.map +1 -1
- package/dist/Constraint.js +34 -60
- package/dist/Constraint.js.map +1 -1
- package/dist/FightingCharacterController.d.ts +32 -0
- package/dist/FightingCharacterController.d.ts.map +1 -0
- package/dist/FightingCharacterController.js +76 -0
- package/dist/FightingCharacterController.js.map +1 -0
- package/dist/MeshBVH.d.ts +72 -0
- package/dist/MeshBVH.d.ts.map +1 -0
- package/dist/MeshBVH.js +244 -0
- package/dist/MeshBVH.js.map +1 -0
- package/dist/PathFollowDriver.d.ts +162 -0
- package/dist/PathFollowDriver.d.ts.map +1 -0
- package/dist/PathFollowDriver.js +163 -0
- package/dist/PathFollowDriver.js.map +1 -0
- package/dist/PhysicsDebugDraw.d.ts +40 -1
- package/dist/PhysicsDebugDraw.d.ts.map +1 -1
- package/dist/PhysicsDebugDraw.js +87 -17
- package/dist/PhysicsDebugDraw.js.map +1 -1
- package/dist/PhysicsWorld.d.ts +37 -18
- package/dist/PhysicsWorld.d.ts.map +1 -1
- package/dist/PhysicsWorld.js +231 -630
- package/dist/PhysicsWorld.js.map +1 -1
- package/dist/RacingLineProfile.d.ts +116 -0
- package/dist/RacingLineProfile.d.ts.map +1 -0
- package/dist/RacingLineProfile.js +181 -0
- package/dist/RacingLineProfile.js.map +1 -0
- package/dist/Raycast.d.ts +11 -0
- package/dist/Raycast.d.ts.map +1 -1
- package/dist/Raycast.js +62 -8
- package/dist/Raycast.js.map +1 -1
- package/dist/RigidBody.d.ts +16 -9
- package/dist/RigidBody.d.ts.map +1 -1
- package/dist/RigidBody.js +23 -75
- package/dist/RigidBody.js.map +1 -1
- package/dist/SurfaceQuery.d.ts +72 -0
- package/dist/SurfaceQuery.d.ts.map +1 -0
- package/dist/SurfaceQuery.js +89 -0
- package/dist/SurfaceQuery.js.map +1 -0
- package/dist/VehicleDynamics.d.ts +10 -0
- package/dist/VehicleDynamics.d.ts.map +1 -1
- package/dist/VehicleDynamics.js +31 -3
- package/dist/VehicleDynamics.js.map +1 -1
- package/dist/VehicleMotion.d.ts +125 -0
- package/dist/VehicleMotion.d.ts.map +1 -0
- package/dist/VehicleMotion.js +373 -0
- package/dist/VehicleMotion.js.map +1 -0
- package/dist/index.d.ts +62 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -17
- package/dist/index.js.map +1 -1
- package/dist/solverless-entry.d.ts +41 -0
- package/dist/solverless-entry.d.ts.map +1 -0
- package/dist/solverless-entry.js +40 -0
- package/dist/solverless-entry.js.map +1 -0
- package/dist/solverless.d.ts +37 -0
- package/dist/solverless.d.ts.map +1 -0
- package/dist/solverless.js +36 -0
- package/dist/solverless.js.map +1 -0
- package/dist/world-entry.d.ts +31 -0
- package/dist/world-entry.d.ts.map +1 -0
- package/dist/world-entry.js +30 -0
- package/dist/world-entry.js.map +1 -0
- package/dist/world.d.ts +18 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +17 -0
- package/dist/world.js.map +1 -0
- package/package.json +10 -2
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns a path plus a speed target into steering, throttle and brake for `createVehicleMotion`.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* The library shipped the two hard halves of AI driving — `createVehicleMotion` for the tyre and
|
|
7
|
+
* yaw dynamics, `createRacingLineProfile` for the speed a corner can be taken at — and nothing to
|
|
8
|
+
* join them. Every racing route therefore hand-rolled its own driver, and hand-rolled drivers all
|
|
9
|
+
* fail the same way. The obvious formulation, a Stanley controller that steers on
|
|
10
|
+
* `headingError + atan2(crossTrack, speed)`, is stable on gentle curves and diverges on a hairpin:
|
|
11
|
+
*
|
|
12
|
+
* 1. Heading error grows faster than the car can rotate, so the steering command saturates.
|
|
13
|
+
* 2. Saturated at full lock, the controller has no authority left and the car runs wide.
|
|
14
|
+
* 3. Once outside the road the nearest point on the path stops advancing, so `progress` latches.
|
|
15
|
+
* A latched progress freezes the speed target and the curvature feedforward.
|
|
16
|
+
* 4. The now-constant cross-track term flips sign every frame as the car crosses the path
|
|
17
|
+
* centreline, and the car saws away from the track at full lock — measured on the certified
|
|
18
|
+
* circuit as progress stuck at 0.2789 for 8,700 consecutive frames while lateral offset grew to
|
|
19
|
+
* 43 units, i.e. 98 road widths from a 0.439-wide road.
|
|
20
|
+
*
|
|
21
|
+
* The failure is not the vehicle's. Held at a fixed speed, the same car corners at radius
|
|
22
|
+
* 0.32-0.55 against a hairpin that demands 0.80, so it has ~40% radius margin. It was the
|
|
23
|
+
* controller throwing that margin away.
|
|
24
|
+
*
|
|
25
|
+
* ## What this does instead
|
|
26
|
+
*
|
|
27
|
+
* Pure pursuit: aim at a point a lookahead distance *along the path* and solve the arc that reaches
|
|
28
|
+
* it. This is bounded by construction — the arc to a point at a known distance has a known
|
|
29
|
+
* curvature, so the command cannot run away the way an unbounded error term can. Three properties
|
|
30
|
+
* matter for the hairpin case:
|
|
31
|
+
*
|
|
32
|
+
* - **Lookahead scales with speed** (`lookaheadTime * speed`, clamped to `[minLookahead,
|
|
33
|
+
* maxLookahead]`). Time-based lookahead means the car looks a fixed duration ahead rather than a
|
|
34
|
+
* fixed distance, which is what makes one gain work at both 2 and 12 units/second.
|
|
35
|
+
* - **The target is measured along arc length, not straight-line distance.** On a hairpin the point
|
|
36
|
+
* 0.8 units ahead along the road is nearly behind the car in a straight line; chord-based
|
|
37
|
+
* lookahead skips the corner entirely and cuts to the exit.
|
|
38
|
+
* - **Progress advances monotonically** from the driver's own integrated distance, so being off the
|
|
39
|
+
* road cannot latch it. This is the direct fix for failure 3 above: the driver keeps a running
|
|
40
|
+
* distance and only accepts a measured progress that is ahead of it, within a rejoin window.
|
|
41
|
+
*
|
|
42
|
+
* Speed control is a PI-free proportional law with an explicit brake/throttle split, because a
|
|
43
|
+
* single signed axis fed to a vehicle that has separate `driveForce` and `brakeForce` produces
|
|
44
|
+
* asymmetric response that reads as the car refusing to slow for corners.
|
|
45
|
+
*
|
|
46
|
+
* The driver is pure and allocation-free per step: no `three`, no renderer, no route names, no
|
|
47
|
+
* game-specific branch. Any path that can answer "where am I along you" and "what is your point at
|
|
48
|
+
* distance d" can be driven, which is why the input is two callbacks rather than a route type.
|
|
49
|
+
*/
|
|
50
|
+
export interface PathFollowSample {
|
|
51
|
+
/** Path point at the requested distance. */
|
|
52
|
+
readonly x: number;
|
|
53
|
+
readonly y: number;
|
|
54
|
+
/** Tangent heading at that point, radians, atan2(dy, dx) convention. */
|
|
55
|
+
readonly heading: number;
|
|
56
|
+
/** Signed curvature at that point, 1/radius. Positive turns left. */
|
|
57
|
+
readonly curvature: number;
|
|
58
|
+
}
|
|
59
|
+
export interface PathFollowContact {
|
|
60
|
+
/** Distance along the path of the closest point to the car. */
|
|
61
|
+
readonly distance: number;
|
|
62
|
+
/** Signed lateral offset of the car from the path, positive to the left of travel. */
|
|
63
|
+
readonly signedOffset: number;
|
|
64
|
+
}
|
|
65
|
+
export interface PathFollowDriverOptions {
|
|
66
|
+
/** Total path length in world units. */
|
|
67
|
+
readonly length: number;
|
|
68
|
+
/** True when the path loops. Defaults to true. */
|
|
69
|
+
readonly closed?: boolean | undefined;
|
|
70
|
+
/** Path point at an absolute distance along the path. Must handle wrap on a closed path. */
|
|
71
|
+
sampleAt(distance: number): PathFollowSample;
|
|
72
|
+
/** Closest point on the path to a world position. */
|
|
73
|
+
contactAt(x: number, y: number): PathFollowContact;
|
|
74
|
+
/** Target speed at a distance along the path, world units per second. */
|
|
75
|
+
speedAt(distance: number): number;
|
|
76
|
+
/** Vehicle wheelbase, world units. Sets how much steer angle a given arc needs. */
|
|
77
|
+
readonly wheelbase: number;
|
|
78
|
+
/** Vehicle maximum steer angle, radians, matching `createVehicleMotion`. */
|
|
79
|
+
readonly maxSteerAngle: number;
|
|
80
|
+
/**
|
|
81
|
+
* Seconds of travel to look ahead. Larger is smoother and cuts corners more; smaller tracks the
|
|
82
|
+
* line tighter and saturates sooner.
|
|
83
|
+
*
|
|
84
|
+
* The default is measured, not guessed. Swept over the certified circuit at 5,400 frames per
|
|
85
|
+
* cell, off-track time is dominated by this parameter and barely moves with grip margin, which is
|
|
86
|
+
* what identifies the original failure as tracking geometry rather than tyre grip:
|
|
87
|
+
*
|
|
88
|
+
* ```text
|
|
89
|
+
* lookaheadTime 0.12 0.18 0.25 0.30 0.35 0.45 0.55 0.70 0.90
|
|
90
|
+
* off-track % 5.4 4.3 3.3 3.5 5.4 12.8 20.3 33.6 44.0
|
|
91
|
+
* saturated % 8.5 5.0 3.2 1.4 0.7 1.7 4.6 5.4 4.7
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* 0.25 is the minimum. Below it the car tracks so tightly that it saturates on corner entry
|
|
95
|
+
* (8.5% of frames at full lock); above it the aim point cuts inside the apex and the car runs
|
|
96
|
+
* wide. Full sweep in `tests/unit/physics/racing-line-profile.test.ts`.
|
|
97
|
+
*/
|
|
98
|
+
readonly lookaheadTime?: number | undefined;
|
|
99
|
+
/** Lookahead floor, world units, so a stopped car still has a target. */
|
|
100
|
+
readonly minLookahead?: number | undefined;
|
|
101
|
+
/** Lookahead ceiling, world units, so a fast straight does not aim past the next corner. */
|
|
102
|
+
readonly maxLookahead?: number | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Extra steer per unit of lateral offset, used only to close a standing offset that pure pursuit
|
|
105
|
+
* alone converges on slowly. Applied through `atan2` against speed so it fades as speed rises.
|
|
106
|
+
*
|
|
107
|
+
* 2.5 measured best on the certified circuit (3.3% off-track versus 4.2% at 0.6), and unlike a
|
|
108
|
+
* Stanley cross-track gain it cannot destabilise the loop on its own because the `atan2` bounds
|
|
109
|
+
* its contribution to under a quarter turn regardless of how large the offset grows.
|
|
110
|
+
*/
|
|
111
|
+
readonly crossTrackGain?: number | undefined;
|
|
112
|
+
/** Throttle/brake proportional gain on speed error, per world unit per second. */
|
|
113
|
+
readonly speedGain?: number | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* How far ahead of the car the speed target is read, in seconds of travel. Braking has to start
|
|
116
|
+
* before the corner, so a driver that reads the target at its own position always enters too
|
|
117
|
+
* fast. Defaults to 0.35.
|
|
118
|
+
*/
|
|
119
|
+
readonly speedPreviewTime?: number | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* How far the measured progress may sit behind the driver's integrated distance before the driver
|
|
122
|
+
* accepts it as a genuine rejoin rather than a stale nearest-point match. World units.
|
|
123
|
+
* Defaults to 8% of `length`.
|
|
124
|
+
*/
|
|
125
|
+
readonly rejoinWindow?: number | undefined;
|
|
126
|
+
}
|
|
127
|
+
export interface PathFollowCommand {
|
|
128
|
+
/** 0..1, feed straight to `VehicleMotion.step`. */
|
|
129
|
+
readonly throttle: number;
|
|
130
|
+
/** 0..1. */
|
|
131
|
+
readonly brake: number;
|
|
132
|
+
/** -1..1. */
|
|
133
|
+
readonly steer: number;
|
|
134
|
+
/** Distance along the path the driver believes it is at. Monotonic on a closed path. */
|
|
135
|
+
readonly distance: number;
|
|
136
|
+
/** Progress 0..1 derived from `distance`. */
|
|
137
|
+
readonly progress: number;
|
|
138
|
+
/** Signed lateral offset used for this command. */
|
|
139
|
+
readonly signedOffset: number;
|
|
140
|
+
/** Speed the driver is currently asking for. */
|
|
141
|
+
readonly targetSpeed: number;
|
|
142
|
+
/** Lookahead distance used, world units. Exposed for tuning and for tests. */
|
|
143
|
+
readonly lookahead: number;
|
|
144
|
+
/** True while the steering command is at full lock, which means the driver is out of authority. */
|
|
145
|
+
readonly saturated: boolean;
|
|
146
|
+
}
|
|
147
|
+
export interface PathFollowDriver {
|
|
148
|
+
readonly kind: "aura-path-follow-driver";
|
|
149
|
+
/** Compute the command for the current vehicle state. Does not mutate the vehicle. */
|
|
150
|
+
step(state: {
|
|
151
|
+
readonly x: number;
|
|
152
|
+
readonly z: number;
|
|
153
|
+
readonly heading: number;
|
|
154
|
+
readonly speed: number;
|
|
155
|
+
}): PathFollowCommand;
|
|
156
|
+
/** Reset the integrated distance, e.g. after placing the car on the grid. */
|
|
157
|
+
reset(distance?: number): void;
|
|
158
|
+
/** Laps completed since reset, counted from monotonic distance rather than progress wrap. */
|
|
159
|
+
readonly lapsCompleted: number;
|
|
160
|
+
}
|
|
161
|
+
export declare function createPathFollowDriver(options: PathFollowDriverOptions): PathFollowDriver;
|
|
162
|
+
//# sourceMappingURL=PathFollowDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PathFollowDriver.d.ts","sourceRoot":"","sources":["../../../../packages/physics/src/PathFollowDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns a path plus a speed target into steering, throttle and brake for `createVehicleMotion`.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* The library shipped the two hard halves of AI driving — `createVehicleMotion` for the tyre and
|
|
7
|
+
* yaw dynamics, `createRacingLineProfile` for the speed a corner can be taken at — and nothing to
|
|
8
|
+
* join them. Every racing route therefore hand-rolled its own driver, and hand-rolled drivers all
|
|
9
|
+
* fail the same way. The obvious formulation, a Stanley controller that steers on
|
|
10
|
+
* `headingError + atan2(crossTrack, speed)`, is stable on gentle curves and diverges on a hairpin:
|
|
11
|
+
*
|
|
12
|
+
* 1. Heading error grows faster than the car can rotate, so the steering command saturates.
|
|
13
|
+
* 2. Saturated at full lock, the controller has no authority left and the car runs wide.
|
|
14
|
+
* 3. Once outside the road the nearest point on the path stops advancing, so `progress` latches.
|
|
15
|
+
* A latched progress freezes the speed target and the curvature feedforward.
|
|
16
|
+
* 4. The now-constant cross-track term flips sign every frame as the car crosses the path
|
|
17
|
+
* centreline, and the car saws away from the track at full lock — measured on the certified
|
|
18
|
+
* circuit as progress stuck at 0.2789 for 8,700 consecutive frames while lateral offset grew to
|
|
19
|
+
* 43 units, i.e. 98 road widths from a 0.439-wide road.
|
|
20
|
+
*
|
|
21
|
+
* The failure is not the vehicle's. Held at a fixed speed, the same car corners at radius
|
|
22
|
+
* 0.32-0.55 against a hairpin that demands 0.80, so it has ~40% radius margin. It was the
|
|
23
|
+
* controller throwing that margin away.
|
|
24
|
+
*
|
|
25
|
+
* ## What this does instead
|
|
26
|
+
*
|
|
27
|
+
* Pure pursuit: aim at a point a lookahead distance *along the path* and solve the arc that reaches
|
|
28
|
+
* it. This is bounded by construction — the arc to a point at a known distance has a known
|
|
29
|
+
* curvature, so the command cannot run away the way an unbounded error term can. Three properties
|
|
30
|
+
* matter for the hairpin case:
|
|
31
|
+
*
|
|
32
|
+
* - **Lookahead scales with speed** (`lookaheadTime * speed`, clamped to `[minLookahead,
|
|
33
|
+
* maxLookahead]`). Time-based lookahead means the car looks a fixed duration ahead rather than a
|
|
34
|
+
* fixed distance, which is what makes one gain work at both 2 and 12 units/second.
|
|
35
|
+
* - **The target is measured along arc length, not straight-line distance.** On a hairpin the point
|
|
36
|
+
* 0.8 units ahead along the road is nearly behind the car in a straight line; chord-based
|
|
37
|
+
* lookahead skips the corner entirely and cuts to the exit.
|
|
38
|
+
* - **Progress advances monotonically** from the driver's own integrated distance, so being off the
|
|
39
|
+
* road cannot latch it. This is the direct fix for failure 3 above: the driver keeps a running
|
|
40
|
+
* distance and only accepts a measured progress that is ahead of it, within a rejoin window.
|
|
41
|
+
*
|
|
42
|
+
* Speed control is a PI-free proportional law with an explicit brake/throttle split, because a
|
|
43
|
+
* single signed axis fed to a vehicle that has separate `driveForce` and `brakeForce` produces
|
|
44
|
+
* asymmetric response that reads as the car refusing to slow for corners.
|
|
45
|
+
*
|
|
46
|
+
* The driver is pure and allocation-free per step: no `three`, no renderer, no route names, no
|
|
47
|
+
* game-specific branch. Any path that can answer "where am I along you" and "what is your point at
|
|
48
|
+
* distance d" can be driven, which is why the input is two callbacks rather than a route type.
|
|
49
|
+
*/
|
|
50
|
+
function clamp(value, min, max) {
|
|
51
|
+
return value < min ? min : value > max ? max : value;
|
|
52
|
+
}
|
|
53
|
+
function wrapAngle(value) {
|
|
54
|
+
let angle = value;
|
|
55
|
+
while (angle > Math.PI)
|
|
56
|
+
angle -= 2 * Math.PI;
|
|
57
|
+
while (angle < -Math.PI)
|
|
58
|
+
angle += 2 * Math.PI;
|
|
59
|
+
return angle;
|
|
60
|
+
}
|
|
61
|
+
export function createPathFollowDriver(options) {
|
|
62
|
+
const length = options.length;
|
|
63
|
+
if (!Number.isFinite(length) || length <= 0) {
|
|
64
|
+
throw new Error(`createPathFollowDriver requires a positive length, received ${String(options.length)}`);
|
|
65
|
+
}
|
|
66
|
+
const closed = options.closed !== false;
|
|
67
|
+
const wheelbase = Math.max(1e-4, options.wheelbase);
|
|
68
|
+
const maxSteerAngle = Math.max(1e-4, options.maxSteerAngle);
|
|
69
|
+
const lookaheadTime = options.lookaheadTime ?? 0.25;
|
|
70
|
+
const minLookahead = options.minLookahead ?? Math.max(wheelbase * 0.7, length / 160);
|
|
71
|
+
const maxLookahead = Math.max(minLookahead, options.maxLookahead ?? length / 8);
|
|
72
|
+
const crossTrackGain = options.crossTrackGain ?? 2.5;
|
|
73
|
+
const speedGain = options.speedGain ?? 2;
|
|
74
|
+
const speedPreviewTime = options.speedPreviewTime ?? 0.35;
|
|
75
|
+
const rejoinWindow = options.rejoinWindow ?? length * 0.08;
|
|
76
|
+
let travelled = 0;
|
|
77
|
+
let laps = 0;
|
|
78
|
+
function advance(measured) {
|
|
79
|
+
if (!closed) {
|
|
80
|
+
travelled = Math.max(travelled, measured);
|
|
81
|
+
return travelled;
|
|
82
|
+
}
|
|
83
|
+
/*
|
|
84
|
+
* `measured` is a nearest-point match on a wrapped path, so it can legitimately jump backwards
|
|
85
|
+
* across the start line. Compare in the wrapped frame and only accept forward motion, or a
|
|
86
|
+
* backward step small enough to be a genuine correction rather than a stale match from the far
|
|
87
|
+
* side of the circuit.
|
|
88
|
+
*/
|
|
89
|
+
const currentWrapped = ((travelled % length) + length) % length;
|
|
90
|
+
let delta = measured - currentWrapped;
|
|
91
|
+
if (delta > length / 2)
|
|
92
|
+
delta -= length;
|
|
93
|
+
if (delta < -length / 2)
|
|
94
|
+
delta += length;
|
|
95
|
+
if (delta > 0 || delta > -rejoinWindow) {
|
|
96
|
+
travelled += delta;
|
|
97
|
+
const nextLaps = Math.floor(travelled / length);
|
|
98
|
+
if (nextLaps > laps)
|
|
99
|
+
laps = nextLaps;
|
|
100
|
+
}
|
|
101
|
+
return travelled;
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
kind: "aura-path-follow-driver",
|
|
105
|
+
get lapsCompleted() {
|
|
106
|
+
return laps;
|
|
107
|
+
},
|
|
108
|
+
reset(distance = 0) {
|
|
109
|
+
travelled = distance;
|
|
110
|
+
laps = 0;
|
|
111
|
+
},
|
|
112
|
+
step(state) {
|
|
113
|
+
const contact = options.contactAt(state.x, state.z);
|
|
114
|
+
const distance = advance(contact.distance);
|
|
115
|
+
const speed = Math.max(0, state.speed);
|
|
116
|
+
const lookahead = clamp(lookaheadTime * speed, minLookahead, maxLookahead);
|
|
117
|
+
const aim = options.sampleAt(distance + lookahead);
|
|
118
|
+
/*
|
|
119
|
+
* Pure pursuit: with the aim point expressed in the car's frame, the arc through it has
|
|
120
|
+
* curvature `2 * lateralOffset / chord^2`. Deriving curvature from the geometry rather than
|
|
121
|
+
* from a heading-error gain is what bounds the command: a reachable point yields a reachable
|
|
122
|
+
* arc.
|
|
123
|
+
*/
|
|
124
|
+
const dx = aim.x - state.x;
|
|
125
|
+
const dy = aim.y - state.z;
|
|
126
|
+
const cosH = Math.cos(state.heading);
|
|
127
|
+
const sinH = Math.sin(state.heading);
|
|
128
|
+
const forward = dx * cosH + dy * sinH;
|
|
129
|
+
const lateralToAim = -dx * sinH + dy * cosH;
|
|
130
|
+
const chordSquared = dx * dx + dy * dy;
|
|
131
|
+
let curvature = chordSquared > 1e-9 ? (2 * lateralToAim) / chordSquared : 0;
|
|
132
|
+
/*
|
|
133
|
+
* If the aim point is behind the car the arc solution degenerates — it points the car at a
|
|
134
|
+
* target it has already passed and can produce a near-zero command exactly when the car most
|
|
135
|
+
* needs to turn. Fall back to closing the heading error to the path tangent, which always has
|
|
136
|
+
* the right sign.
|
|
137
|
+
*/
|
|
138
|
+
if (forward <= 0) {
|
|
139
|
+
curvature = Math.sign(wrapAngle(aim.heading - state.heading) || 1) * (1 / Math.max(1e-4, wheelbase));
|
|
140
|
+
}
|
|
141
|
+
const steerFromArc = Math.atan(wheelbase * curvature);
|
|
142
|
+
const crossTerm = Math.atan2(crossTrackGain * -contact.signedOffset, Math.max(0.5, speed));
|
|
143
|
+
const steer = clamp((steerFromArc + crossTerm) / maxSteerAngle, -1, 1);
|
|
144
|
+
const previewDistance = distance + Math.max(lookahead, speedPreviewTime * speed);
|
|
145
|
+
const targetSpeed = options.speedAt(previewDistance);
|
|
146
|
+
const speedError = targetSpeed - speed;
|
|
147
|
+
const throttle = speedError > 0 ? Math.min(1, speedError * speedGain) : 0;
|
|
148
|
+
const brake = speedError < 0 ? Math.min(1, -speedError * speedGain) : 0;
|
|
149
|
+
return {
|
|
150
|
+
throttle,
|
|
151
|
+
brake,
|
|
152
|
+
steer,
|
|
153
|
+
distance,
|
|
154
|
+
progress: closed ? (((distance / length) % 1) + 1) % 1 : clamp(distance / length, 0, 1),
|
|
155
|
+
signedOffset: contact.signedOffset,
|
|
156
|
+
targetSpeed,
|
|
157
|
+
lookahead,
|
|
158
|
+
saturated: Math.abs(steer) >= 0.999
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=PathFollowDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PathFollowDriver.js","sourceRoot":"","sources":["../../../../packages/physics/src/PathFollowDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,47 @@ export type DebugLine = {
|
|
|
4
4
|
readonly from: Vec3;
|
|
5
5
|
readonly to: Vec3;
|
|
6
6
|
readonly color: Vec3;
|
|
7
|
+
/**
|
|
8
|
+
* What this line represents, so a consumer can filter or legend it.
|
|
9
|
+
*
|
|
10
|
+
* Without a category every line is an anonymous coloured segment, and a debug overlay that
|
|
11
|
+
* cannot say "these are contacts and those are joints" is decoration rather than a tool.
|
|
12
|
+
*/
|
|
13
|
+
readonly category?: DebugLineCategory;
|
|
7
14
|
};
|
|
15
|
+
export type DebugLineCategory = "collider" | "sensor" | "contact" | "normal" | "joint" | "sleeping" | "raycast";
|
|
16
|
+
/** A raycast to draw, so a developer can see the query they cannot otherwise observe. */
|
|
17
|
+
export type DebugRaycast = {
|
|
18
|
+
readonly origin: Vec3;
|
|
19
|
+
readonly direction: Vec3;
|
|
20
|
+
readonly distance: number;
|
|
21
|
+
/** True when the ray hit something; drawn in a different colour. */
|
|
22
|
+
readonly hit?: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type PhysicsDebugDrawOptions = {
|
|
25
|
+
/** Draw contact points and their normals. */
|
|
26
|
+
readonly contacts?: boolean;
|
|
27
|
+
/** Draw joint anchors and the segment between them. */
|
|
28
|
+
readonly joints?: boolean;
|
|
29
|
+
/** Tint sleeping bodies differently from awake ones. */
|
|
30
|
+
readonly sleeping?: boolean;
|
|
31
|
+
/** Extra rays to visualise, which the world cannot know about. */
|
|
32
|
+
readonly raycasts?: readonly DebugRaycast[];
|
|
33
|
+
/** Length of a drawn contact normal, in world units. */
|
|
34
|
+
readonly normalLength?: number;
|
|
35
|
+
};
|
|
36
|
+
type DebugWorld = Pick<PhysicsWorld, "colliders" | "getBody"> & Partial<Pick<PhysicsWorld, "snapshot" | "constraints">>;
|
|
8
37
|
export declare class PhysicsDebugDraw {
|
|
9
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Build debug geometry for a world.
|
|
40
|
+
*
|
|
41
|
+
* WS-1.7 asks for colliders, contacts, normals, joints, sleeping state and raycasts. Only
|
|
42
|
+
* colliders existed, which is why the capability sat at "unproven with 0 consumers" — there was
|
|
43
|
+
* not enough here for a route to consume.
|
|
44
|
+
*
|
|
45
|
+
* Options default to off so the existing single-argument call keeps its previous output exactly.
|
|
46
|
+
*/
|
|
47
|
+
buildLines(world: DebugWorld, options?: PhysicsDebugDrawOptions): readonly DebugLine[];
|
|
10
48
|
}
|
|
49
|
+
export {};
|
|
11
50
|
//# sourceMappingURL=PhysicsDebugDraw.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhysicsDebugDraw.d.ts","sourceRoot":"","sources":["../../../../packages/physics/src/PhysicsDebugDraw.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"PhysicsDebugDraw.d.ts","sourceRoot":"","sources":["../../../../packages/physics/src/PhysicsDebugDraw.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,UAAU,GACV,SAAS,CAAC;AAEd,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAC5C,wDAAwD;IACxD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,KAAK,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,aAAa,CAAC,CAAC,CAAC;AAE1D,qBAAa,gBAAgB;IAC3B;;;;;;;;OAQG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,uBAA4B,GAAG,SAAS,SAAS,EAAE;CAuE3F"}
|
package/dist/PhysicsDebugDraw.js
CHANGED
|
@@ -1,18 +1,88 @@
|
|
|
1
1
|
export class PhysicsDebugDraw {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Build debug geometry for a world.
|
|
4
|
+
*
|
|
5
|
+
* WS-1.7 asks for colliders, contacts, normals, joints, sleeping state and raycasts. Only
|
|
6
|
+
* colliders existed, which is why the capability sat at "unproven with 0 consumers" — there was
|
|
7
|
+
* not enough here for a route to consume.
|
|
8
|
+
*
|
|
9
|
+
* Options default to off so the existing single-argument call keeps its previous output exactly.
|
|
10
|
+
*/
|
|
11
|
+
buildLines(world, options = {}) {
|
|
3
12
|
const lines = [];
|
|
13
|
+
const snapshot = options.contacts || options.sleeping ? world.snapshot?.() : undefined;
|
|
14
|
+
const sleepingIds = new Set();
|
|
15
|
+
if (options.sleeping && snapshot) {
|
|
16
|
+
for (const body of snapshot.bodies) {
|
|
17
|
+
if (body.sleeping)
|
|
18
|
+
sleepingIds.add(body.id);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
4
21
|
for (const collider of world.colliders()) {
|
|
5
22
|
const body = world.getBody(collider.bodyId);
|
|
6
23
|
if (!body) {
|
|
7
24
|
continue;
|
|
8
25
|
}
|
|
9
|
-
appendColliderLines(lines, collider, body.position);
|
|
26
|
+
appendColliderLines(lines, collider, body.position, sleepingIds.has(body.id));
|
|
27
|
+
}
|
|
28
|
+
if (options.contacts && snapshot) {
|
|
29
|
+
const normalLength = options.normalLength ?? 0.25;
|
|
30
|
+
for (const contact of snapshot.contacts) {
|
|
31
|
+
const point = contact.point;
|
|
32
|
+
if (!point)
|
|
33
|
+
continue;
|
|
34
|
+
// A short cross at the contact point, then the normal as a ray out of it. Penetration is
|
|
35
|
+
// the number that matters for "is this body inside that one", so it tints the cross.
|
|
36
|
+
const penetrating = contact.penetration > 1e-4;
|
|
37
|
+
const crossColor = penetrating ? [1, 0.2, 0.2] : [0.2, 1, 0.4];
|
|
38
|
+
const size = normalLength * 0.25;
|
|
39
|
+
lines.push({ from: [point[0] - size, point[1], point[2]], to: [point[0] + size, point[1], point[2]], color: crossColor, category: "contact" });
|
|
40
|
+
lines.push({ from: [point[0], point[1] - size, point[2]], to: [point[0], point[1] + size, point[2]], color: crossColor, category: "contact" });
|
|
41
|
+
lines.push({
|
|
42
|
+
from: point,
|
|
43
|
+
to: [
|
|
44
|
+
point[0] + contact.normal[0] * normalLength,
|
|
45
|
+
point[1] + contact.normal[1] * normalLength,
|
|
46
|
+
point[2] + contact.normal[2] * normalLength
|
|
47
|
+
],
|
|
48
|
+
color: [1, 1, 0.3],
|
|
49
|
+
category: "normal"
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (options.joints && world.constraints) {
|
|
54
|
+
for (const constraint of world.constraints()) {
|
|
55
|
+
const a = world.getBody(constraint.bodyA.id);
|
|
56
|
+
const b = world.getBody(constraint.bodyB.id);
|
|
57
|
+
if (!a || !b)
|
|
58
|
+
continue;
|
|
59
|
+
// The segment between the two bodies a joint connects. A joint that has come apart is
|
|
60
|
+
// visible as a segment that keeps growing, which is exactly the failure mode that made
|
|
61
|
+
// the former silent backend divergence so hard to spot.
|
|
62
|
+
lines.push({ from: a.position, to: b.position, color: [0.9, 0.4, 1], category: "joint" });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const ray of options.raycasts ?? []) {
|
|
66
|
+
const length = Number.isFinite(ray.distance) ? ray.distance : 1;
|
|
67
|
+
lines.push({
|
|
68
|
+
from: ray.origin,
|
|
69
|
+
to: [
|
|
70
|
+
ray.origin[0] + ray.direction[0] * length,
|
|
71
|
+
ray.origin[1] + ray.direction[1] * length,
|
|
72
|
+
ray.origin[2] + ray.direction[2] * length
|
|
73
|
+
],
|
|
74
|
+
color: ray.hit ? [1, 0.35, 0.35] : [0.5, 0.5, 0.55],
|
|
75
|
+
category: "raycast"
|
|
76
|
+
});
|
|
10
77
|
}
|
|
11
78
|
return lines;
|
|
12
79
|
}
|
|
13
80
|
}
|
|
14
|
-
function appendColliderLines(lines, collider, position) {
|
|
15
|
-
|
|
81
|
+
function appendColliderLines(lines, collider, position, sleeping = false) {
|
|
82
|
+
// Sleeping bodies are drawn dim: a body that has gone to sleep and should not have is otherwise
|
|
83
|
+
// indistinguishable from one that is simply not moving.
|
|
84
|
+
const color = sleeping ? [0.4, 0.42, 0.5] : collider.sensor ? [1, 0.75, 0] : [0.1, 0.8, 1];
|
|
85
|
+
const category = sleeping ? "sleeping" : collider.sensor ? "sensor" : "collider";
|
|
16
86
|
if (collider.shape.kind === "box") {
|
|
17
87
|
const h = collider.shape.halfExtents;
|
|
18
88
|
const corners = [
|
|
@@ -27,24 +97,24 @@ function appendColliderLines(lines, collider, position) {
|
|
|
27
97
|
];
|
|
28
98
|
const pairs = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]];
|
|
29
99
|
for (const [a, b] of pairs) {
|
|
30
|
-
lines.push({ from: corners[a], to: corners[b], color });
|
|
100
|
+
lines.push({ from: corners[a], to: corners[b], color, category });
|
|
31
101
|
}
|
|
32
102
|
}
|
|
33
103
|
else if (collider.shape.kind === "sphere") {
|
|
34
104
|
const r = collider.shape.radius;
|
|
35
|
-
lines.push({ from: [position[0] - r, position[1], position[2]], to: [position[0] + r, position[1], position[2]], color });
|
|
36
|
-
lines.push({ from: [position[0], position[1] - r, position[2]], to: [position[0], position[1] + r, position[2]], color });
|
|
37
|
-
lines.push({ from: [position[0], position[1], position[2] - r], to: [position[0], position[1], position[2] + r], color });
|
|
105
|
+
lines.push({ from: [position[0] - r, position[1], position[2]], to: [position[0] + r, position[1], position[2]], color, category });
|
|
106
|
+
lines.push({ from: [position[0], position[1] - r, position[2]], to: [position[0], position[1] + r, position[2]], color, category });
|
|
107
|
+
lines.push({ from: [position[0], position[1], position[2] - r], to: [position[0], position[1], position[2] + r], color, category });
|
|
38
108
|
}
|
|
39
109
|
else if (collider.shape.kind === "plane") {
|
|
40
|
-
lines.push({ from: [-10, position[1], 0], to: [10, position[1], 0], color });
|
|
41
|
-
lines.push({ from: [0, position[1], -10], to: [0, position[1], 10], color });
|
|
110
|
+
lines.push({ from: [-10, position[1], 0], to: [10, position[1], 0], color, category });
|
|
111
|
+
lines.push({ from: [0, position[1], -10], to: [0, position[1], 10], color, category });
|
|
42
112
|
}
|
|
43
113
|
else if (collider.shape.kind === "capsule") {
|
|
44
114
|
const r = collider.shape.radius;
|
|
45
115
|
const h = collider.shape.halfHeight;
|
|
46
|
-
lines.push({ from: [position[0], position[1] - h - r, position[2]], to: [position[0], position[1] + h + r, position[2]], color });
|
|
47
|
-
lines.push({ from: [position[0] - r, position[1], position[2]], to: [position[0] + r, position[1], position[2]], color });
|
|
116
|
+
lines.push({ from: [position[0], position[1] - h - r, position[2]], to: [position[0], position[1] + h + r, position[2]], color, category });
|
|
117
|
+
lines.push({ from: [position[0] - r, position[1], position[2]], to: [position[0] + r, position[1], position[2]], color, category });
|
|
48
118
|
}
|
|
49
119
|
else if (collider.shape.kind === "mesh" || collider.shape.kind === "convex-hull") {
|
|
50
120
|
const { vertices, indices } = collider.shape;
|
|
@@ -52,9 +122,9 @@ function appendColliderLines(lines, collider, position) {
|
|
|
52
122
|
const a = translate(vertices[indices[index]], position);
|
|
53
123
|
const b = translate(vertices[indices[index + 1]], position);
|
|
54
124
|
const c = translate(vertices[indices[index + 2]], position);
|
|
55
|
-
lines.push({ from: a, to: b, color });
|
|
56
|
-
lines.push({ from: b, to: c, color });
|
|
57
|
-
lines.push({ from: c, to: a, color });
|
|
125
|
+
lines.push({ from: a, to: b, color, category });
|
|
126
|
+
lines.push({ from: b, to: c, color, category });
|
|
127
|
+
lines.push({ from: c, to: a, color, category });
|
|
58
128
|
}
|
|
59
129
|
}
|
|
60
130
|
else {
|
|
@@ -69,9 +139,9 @@ function appendColliderLines(lines, collider, position) {
|
|
|
69
139
|
for (let row = 0; row < shape.rows; row += 1) {
|
|
70
140
|
for (let column = 0; column < shape.columns; column += 1) {
|
|
71
141
|
if (column + 1 < shape.columns)
|
|
72
|
-
lines.push({ from: sample(row, column), to: sample(row, column + 1), color });
|
|
142
|
+
lines.push({ from: sample(row, column), to: sample(row, column + 1), color, category });
|
|
73
143
|
if (row + 1 < shape.rows)
|
|
74
|
-
lines.push({ from: sample(row, column), to: sample(row + 1, column), color });
|
|
144
|
+
lines.push({ from: sample(row, column), to: sample(row + 1, column), color, category });
|
|
75
145
|
}
|
|
76
146
|
}
|
|
77
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhysicsDebugDraw.js","sourceRoot":"","sources":["../../../../packages/physics/src/PhysicsDebugDraw.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PhysicsDebugDraw.js","sourceRoot":"","sources":["../../../../packages/physics/src/PhysicsDebugDraw.ts"],"names":[],"mappings":"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"}
|