@inventure71/paddockjs 0.3.0 → 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/CHANGELOG.md +91 -0
- package/INSTALL_AND_UPDATE.md +5 -2
- package/README.md +328 -13
- package/docs/architecture.md +150 -41
- package/docs/concepts.md +22 -3
- package/docs/custom_model_controller.md +329 -0
- package/docs/data_contract.md +474 -34
- package/docs/data_model.md +1 -1
- package/docs/index.md +1 -0
- package/docs/learnings.md +23 -1
- package/docs/rules.md +169 -21
- package/docs/system_specs.md +56 -20
- package/docs/training.md +369 -25
- package/examples/python/README.md +62 -0
- package/examples/python/base_policy_server.py +191 -0
- package/examples/python/requirements.txt +2 -0
- package/examples/train-basic-policy.mjs +5 -6
- package/examples/trainingData.mjs +133 -0
- package/package.json +15 -4
- package/src/api/PaddockSimulatorController.js +36 -2
- package/src/app/BrowserExpertAdapter.js +367 -9
- package/src/app/F1SimulatorApp.js +615 -940
- package/src/app/banners/bannerFormatters.js +55 -0
- package/src/app/banners/raceDataBannerController.js +141 -0
- package/src/app/banners/stewardMessageController.js +99 -0
- package/src/app/camera/cameraConstants.js +21 -0
- package/src/app/camera/cameraController.js +265 -0
- package/src/app/camera/cameraGeometry.js +176 -0
- package/src/app/domBindings.js +14 -1
- package/src/app/readouts/carOverviewRenderer.js +109 -0
- package/src/app/readouts/controlStateRenderer.js +37 -0
- package/src/app/readouts/raceStatusRenderer.js +133 -0
- package/src/app/readouts/readoutFormatters.js +58 -0
- package/src/app/readouts/telemetryRenderer.js +113 -0
- package/src/app/readouts/timingTowerRenderer.js +177 -0
- package/src/app/rendering/appAssets.js +38 -0
- package/src/app/rendering/carRenderer.js +286 -0
- package/src/app/rendering/displayUtils.js +22 -0
- package/src/app/rendering/drsTrailRenderer.js +90 -0
- package/src/app/rendering/expertSensorRenderer.js +126 -0
- package/src/app/rendering/pitLaneStatusRenderer.js +50 -0
- package/src/app/rendering/replayGhostRenderer.js +124 -0
- package/src/app/rendering/trackRenderer.js +25 -0
- package/src/app/runtime/frameLoop.js +66 -0
- package/src/app/runtime/runtimeTiming.js +34 -0
- package/src/app/runtime/runtimeVisibility.js +45 -0
- package/src/config/defaultOptions.js +24 -4
- package/src/environment/actions.js +38 -7
- package/src/environment/controllerLoop.js +246 -0
- package/src/environment/episode.js +86 -2
- package/src/environment/evaluation.js +206 -0
- package/src/environment/index.d.ts +638 -6
- package/src/environment/index.js +14 -0
- package/src/environment/metrics.js +159 -0
- package/src/environment/observationOptions.js +33 -0
- package/src/environment/observations.js +500 -43
- package/src/environment/options.js +41 -2
- package/src/environment/recorder.js +28 -0
- package/src/environment/runtime.js +260 -24
- package/src/environment/scenarios.js +249 -0
- package/src/environment/sensors/bodySenses.js +23 -0
- package/src/environment/sensors/boundarySenses.js +17 -0
- package/src/environment/sensors/carRays.js +75 -0
- package/src/environment/sensors/contactSenses.js +32 -0
- package/src/environment/sensors/index.js +157 -0
- package/src/environment/sensors/indexedRayBands.js +103 -0
- package/src/environment/sensors/nearbyCars.js +52 -0
- package/src/environment/sensors/opponentRadar.js +65 -0
- package/src/environment/sensors/rayConfig.js +110 -0
- package/src/environment/sensors/rayDefaults.js +6 -0
- package/src/environment/sensors/rayGeometry.js +60 -0
- package/src/environment/sensors/rayGuards.js +19 -0
- package/src/environment/sensors/sensorTargets.js +60 -0
- package/src/environment/sensors/surfaceRays.js +296 -0
- package/src/environment/sensors/trackRays.js +261 -0
- package/src/environment/sensors.js +1 -257
- package/src/environment/specs.js +188 -9
- package/src/environment/workerProtocol.js +64 -0
- package/src/index.d.ts +533 -7
- package/src/index.js +26 -0
- package/src/rendering/proceduralTrackAsset.js +20 -510
- package/src/rendering/renderSnapshot.js +38 -12
- package/src/rendering/track/finishLineRenderer.js +34 -0
- package/src/rendering/track/gridRenderer.js +47 -0
- package/src/rendering/track/offsetStrokeSafety.js +136 -0
- package/src/rendering/track/pitLaneRenderer.js +248 -0
- package/src/rendering/track/trackMaterialRenderer.js +326 -0
- package/src/rendering/track/trackRenderConstants.js +38 -0
- package/src/rendering/track/trackRenderGeometry.js +94 -0
- package/src/simulation/collisionGeometry.js +214 -0
- package/src/simulation/driver/driverControlConstants.js +28 -0
- package/src/simulation/driver/driverController.js +47 -0
- package/src/simulation/driver/driverInput.js +28 -0
- package/src/simulation/driver/driverMath.js +6 -0
- package/src/simulation/driver/driverPersonality.js +25 -0
- package/src/simulation/driver/edgeRecovery.js +48 -0
- package/src/simulation/driver/racingControls.js +399 -0
- package/src/simulation/driver/racingLinePlan.js +166 -0
- package/src/simulation/driver/recoveryDynamics.js +38 -0
- package/src/simulation/driver/rejoinControls.js +213 -0
- package/src/simulation/driver/safetyCarControls.js +35 -0
- package/src/simulation/driver/trafficScan.js +51 -0
- package/src/simulation/driverController.js +4 -253
- package/src/simulation/participants/participantInteractions.js +120 -0
- package/src/simulation/pit/pitFlow.js +234 -0
- package/src/simulation/pit/pitIntent.js +92 -0
- package/src/simulation/pit/pitOccupancy.js +47 -0
- package/src/simulation/pit/pitPenaltyService.js +71 -0
- package/src/simulation/pit/pitQueue.js +55 -0
- package/src/simulation/pit/pitRouteMovement.js +160 -0
- package/src/simulation/pit/pitRouting.js +319 -0
- package/src/simulation/pit/pitService.js +41 -0
- package/src/simulation/pit/pitServiceConstants.js +21 -0
- package/src/simulation/pit/pitServiceProfile.js +45 -0
- package/src/simulation/pit/pitSnapshots.js +61 -0
- package/src/simulation/pit/pitState.js +113 -0
- package/src/simulation/pit/pitTireService.js +92 -0
- package/src/simulation/race/classification.js +104 -0
- package/src/simulation/race/gridPenalties.js +37 -0
- package/src/simulation/race/raceControlState.js +38 -0
- package/src/simulation/race/raceDistance.js +32 -0
- package/src/simulation/race/raceFinish.js +65 -0
- package/src/simulation/race/raceLifecycle.js +71 -0
- package/src/simulation/race/raceOrder.js +113 -0
- package/src/simulation/race/raceProgress.js +124 -0
- package/src/simulation/race/raceSetup.js +93 -0
- package/src/simulation/race/raceStep.js +80 -0
- package/src/simulation/race/redFlag.js +15 -0
- package/src/simulation/race/retirements.js +44 -0
- package/src/simulation/race/safetyCar.js +86 -0
- package/src/simulation/race/stalledDnf.js +86 -0
- package/src/simulation/raceSimulation.js +386 -1012
- package/src/simulation/replay/replayGhosts.js +128 -0
- package/src/simulation/rules/collisionSteward.js +69 -0
- package/src/simulation/rules/moduleConfig.js +72 -0
- package/src/simulation/rules/penaltyConfig.js +99 -0
- package/src/simulation/rules/penaltyEvents.js +18 -0
- package/src/simulation/rules/penaltyLedger.js +153 -0
- package/src/simulation/rules/penaltyStats.js +26 -0
- package/src/simulation/rules/pitLaneSpeedingSteward.js +71 -0
- package/src/simulation/rules/ruleConfigMerge.js +41 -0
- package/src/simulation/rules/ruleDefaults.js +85 -0
- package/src/simulation/rules/rulesReview.js +141 -0
- package/src/simulation/rules/rulesetPresets.js +47 -0
- package/src/simulation/rules/tireRequirementSteward.js +29 -0
- package/src/simulation/rules/trackLimitsSteward.js +85 -0
- package/src/simulation/rulesConfig.js +34 -0
- package/src/simulation/snapshots/raceSnapshots.js +192 -0
- package/src/simulation/timing/drsTiming.js +87 -0
- package/src/simulation/timing/gapEstimation.js +38 -0
- package/src/simulation/timing/lapTelemetry.js +182 -0
- package/src/simulation/timing/raceTiming.js +15 -0
- package/src/simulation/timing/sectorPerformance.js +60 -0
- package/src/simulation/timing/timingConstants.js +5 -0
- package/src/simulation/timing/timingHistory.js +46 -0
- package/src/simulation/timing/timingLines.js +79 -0
- package/src/simulation/track/centerlineSpline.js +59 -0
- package/src/simulation/track/drsZones.js +67 -0
- package/src/simulation/track/pitLaneAccess.js +103 -0
- package/src/simulation/track/pitLaneLayout.js +395 -0
- package/src/simulation/track/pitLaneState.js +160 -0
- package/src/simulation/track/proceduralCenterline.js +237 -0
- package/src/simulation/track/sampleGeometry.js +49 -0
- package/src/simulation/track/spatialQueries.js +154 -0
- package/src/simulation/track/startStraight.js +141 -0
- package/src/simulation/track/trackConstants.js +109 -0
- package/src/simulation/track/trackGenerationOptions.js +283 -0
- package/src/simulation/track/trackMath.js +241 -0
- package/src/simulation/track/trackModel.js +240 -0
- package/src/simulation/track/trackQueryIndex.js +945 -0
- package/src/simulation/track/trackSectors.js +19 -0
- package/src/simulation/track/trackStatePolicy.js +24 -0
- package/src/simulation/track/trackValidation.js +98 -0
- package/src/simulation/trackModel.js +1 -628
- package/src/simulation/units.js +6 -4
- package/src/simulation/vehicle/contactResolution.js +116 -0
- package/src/simulation/vehicle/mainTrackWheelSurface.js +82 -0
- package/src/simulation/vehicle/pitWheelSurface.js +69 -0
- package/src/simulation/vehicle/runoffResponse.js +88 -0
- package/src/simulation/vehicle/surfacePriority.js +28 -0
- package/src/simulation/vehicle/vehicleGeometry.js +247 -0
- package/src/simulation/vehicle/vehiclePhysics.js +363 -0
- package/src/simulation/vehicle/vehicleSnapshots.js +316 -0
- package/src/simulation/vehicle/vehicleState.js +186 -0
- package/src/simulation/vehicle/wheelSurface.js +150 -0
- package/src/simulation/vehicleGeometry.js +1 -0
- package/src/simulation/vehiclePhysics.js +1 -104
- package/src/simulation/warmup/runtimeWarmup.js +224 -0
- package/src/simulation/wheelSurface.js +1 -0
- package/src/styles.css +342 -42
- package/src/ui/bannerTemplates.js +69 -0
- package/src/ui/cameraControlsTemplate.js +20 -0
- package/src/ui/carOverviewTemplate.js +33 -0
- package/src/ui/componentTemplates.js +20 -426
- package/src/ui/raceCanvasTemplate.js +69 -0
- package/src/ui/raceControlStatusBanner.js +39 -0
- package/src/ui/raceControlsTemplate.js +36 -0
- package/src/ui/shellTemplate.js +6 -5
- package/src/ui/telemetryDrawerTemplate.js +55 -0
- package/src/ui/telemetryTemplates.js +136 -0
- package/src/ui/templateUtils.js +23 -0
- package/src/ui/timingTowerTemplate.js +34 -0
|
@@ -1,10 +1,127 @@
|
|
|
1
1
|
export type TireCompound = 'S' | 'M' | 'H';
|
|
2
|
+
export type PaddockPhysicsMode = 'arcade' | 'simulator';
|
|
3
|
+
export type PaddockProceduralTrackProfile = 'race' | 'training-short' | 'training-medium' | 'training-technical';
|
|
4
|
+
|
|
5
|
+
export interface PaddockProceduralTrackOptions {
|
|
6
|
+
profile?: PaddockProceduralTrackProfile;
|
|
7
|
+
minLengthMeters?: number;
|
|
8
|
+
maxLengthMeters?: number;
|
|
9
|
+
startStraightMeters?: number;
|
|
10
|
+
includePitLane?: boolean;
|
|
11
|
+
length?: {
|
|
12
|
+
minMeters?: number;
|
|
13
|
+
maxMeters?: number;
|
|
14
|
+
};
|
|
15
|
+
startStraight?: {
|
|
16
|
+
gridMeters?: number;
|
|
17
|
+
exitMeters?: number;
|
|
18
|
+
blendMeters?: number;
|
|
19
|
+
lockExtraMeters?: number;
|
|
20
|
+
};
|
|
21
|
+
pitLane?: {
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
};
|
|
24
|
+
shape?: {
|
|
25
|
+
scale?: number;
|
|
26
|
+
cornerDensity?: number;
|
|
27
|
+
variation?: number;
|
|
28
|
+
};
|
|
29
|
+
validation?: {
|
|
30
|
+
minClearanceMultiplier?: number;
|
|
31
|
+
minShapeVariation?: number;
|
|
32
|
+
minNonAdjacentArcMeters?: number;
|
|
33
|
+
maxLocalTurnRadians?: number;
|
|
34
|
+
maxSampleHeadingDeltaRadians?: number;
|
|
35
|
+
};
|
|
36
|
+
attempts?: {
|
|
37
|
+
primary?: number;
|
|
38
|
+
fallback?: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type PaddockStabilityState = 'stable' | 'understeer' | 'oversteer' | 'spin-risk' | 'destroyed';
|
|
43
|
+
export type PaddockPitIntent = 0 | 1 | 2;
|
|
44
|
+
export type PaddockScenarioPreset = 'cornering' | 'off-track-recovery' | 'overtaking-pack' | 'pit-entry';
|
|
45
|
+
export type PaddockParticipantInteractionProfile =
|
|
46
|
+
| 'normal'
|
|
47
|
+
| 'isolated-training'
|
|
48
|
+
| 'batch-training'
|
|
49
|
+
| 'phantom-race'
|
|
50
|
+
| 'time-trial-overlay';
|
|
51
|
+
|
|
52
|
+
export interface PaddockParticipantInteraction {
|
|
53
|
+
profile: PaddockParticipantInteractionProfile;
|
|
54
|
+
collidable: boolean;
|
|
55
|
+
detectableByRays: boolean;
|
|
56
|
+
detectableAsNearby: boolean;
|
|
57
|
+
blocksPitLane: boolean;
|
|
58
|
+
affectsRaceOrder: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type PaddockParticipantInteractionOverride =
|
|
62
|
+
Partial<PaddockParticipantInteraction> & { profile?: PaddockParticipantInteractionProfile };
|
|
63
|
+
|
|
64
|
+
export interface PaddockParticipantInteractionsOptions {
|
|
65
|
+
defaultProfile?: PaddockParticipantInteractionProfile;
|
|
66
|
+
drivers?: Record<string, PaddockParticipantInteractionOverride>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface PaddockReplayGhostTrajectorySample {
|
|
70
|
+
timeSeconds: number;
|
|
71
|
+
x: number;
|
|
72
|
+
y: number;
|
|
73
|
+
headingRadians: number;
|
|
74
|
+
speedKph?: number;
|
|
75
|
+
progressMeters?: number;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface PaddockReplayGhostOptions {
|
|
79
|
+
id: string;
|
|
80
|
+
label?: string;
|
|
81
|
+
color?: string;
|
|
82
|
+
opacity?: number;
|
|
83
|
+
visible?: boolean;
|
|
84
|
+
trajectory: PaddockReplayGhostTrajectorySample[];
|
|
85
|
+
sensors?: {
|
|
86
|
+
detectableByRays?: boolean;
|
|
87
|
+
detectableAsNearby?: boolean;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface PaddockReplayGhostSnapshot {
|
|
92
|
+
id: string;
|
|
93
|
+
label: string;
|
|
94
|
+
color: string;
|
|
95
|
+
opacity: number;
|
|
96
|
+
visible: boolean;
|
|
97
|
+
previousX: number;
|
|
98
|
+
previousY: number;
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
previousHeading: number;
|
|
102
|
+
heading: number;
|
|
103
|
+
speedKph: number;
|
|
104
|
+
progressMeters: number;
|
|
105
|
+
timeSeconds: number;
|
|
106
|
+
sensors: {
|
|
107
|
+
detectableByRays: boolean;
|
|
108
|
+
detectableAsNearby: boolean;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
2
111
|
|
|
3
112
|
export interface TeamData {
|
|
4
113
|
id?: string;
|
|
5
114
|
name?: string;
|
|
6
115
|
color?: string;
|
|
7
116
|
icon?: string;
|
|
117
|
+
pitCrew?: PaddockPitCrewStats;
|
|
118
|
+
pitCrewStats?: PaddockPitCrewStats;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface PaddockPitCrewStats {
|
|
122
|
+
speed?: number;
|
|
123
|
+
consistency?: number;
|
|
124
|
+
reliability?: number;
|
|
8
125
|
}
|
|
9
126
|
|
|
10
127
|
export interface SimulatorDriver {
|
|
@@ -37,8 +154,52 @@ export interface RaceEvent {
|
|
|
37
154
|
[key: string]: unknown;
|
|
38
155
|
}
|
|
39
156
|
|
|
157
|
+
export type PaddockRulesetName = 'paddock' | 'custom' | 'grandPrix2025' | 'fia2025';
|
|
158
|
+
|
|
159
|
+
export interface PaddockPenaltyEntry {
|
|
160
|
+
id: string;
|
|
161
|
+
type: string;
|
|
162
|
+
at: number;
|
|
163
|
+
lap: number;
|
|
164
|
+
driverId: string;
|
|
165
|
+
strictness: number;
|
|
166
|
+
status: PaddockPenaltyStatus;
|
|
167
|
+
penaltySeconds: number;
|
|
168
|
+
pendingPenaltySeconds?: number;
|
|
169
|
+
consequences: PaddockPenaltyConsequence[];
|
|
170
|
+
serviceType?: 'driveThrough' | 'stopGo' | null;
|
|
171
|
+
serviceRequired?: boolean;
|
|
172
|
+
serviceServedAt?: number | null;
|
|
173
|
+
appliedAt?: number;
|
|
174
|
+
cancelledAt?: number;
|
|
175
|
+
unserved?: boolean;
|
|
176
|
+
positionDrop?: number;
|
|
177
|
+
gridDrop?: number;
|
|
178
|
+
disqualified?: boolean;
|
|
179
|
+
reason?: string;
|
|
180
|
+
otherCarId?: string;
|
|
181
|
+
aheadDriverId?: string;
|
|
182
|
+
atFaultDriverId?: string;
|
|
183
|
+
sharedFault?: boolean;
|
|
184
|
+
impactSpeedKph?: number;
|
|
185
|
+
impactSpeedThresholdKph?: number;
|
|
186
|
+
[key: string]: unknown;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export type PaddockPenaltyConsequence =
|
|
190
|
+
| { type: 'warning' }
|
|
191
|
+
| { type: 'time'; seconds: number }
|
|
192
|
+
| { type: 'driveThrough'; conversionSeconds?: number }
|
|
193
|
+
| { type: 'stopGo'; seconds?: number; conversionSeconds?: number }
|
|
194
|
+
| { type: 'positionDrop'; positions: number }
|
|
195
|
+
| { type: 'gridDrop'; positions: number }
|
|
196
|
+
| { type: 'disqualification' };
|
|
197
|
+
|
|
198
|
+
export type PaddockPenaltyStatus = 'issued' | 'served' | 'applied' | 'cancelled';
|
|
199
|
+
|
|
40
200
|
export interface RaceSnapshot {
|
|
41
201
|
time: number;
|
|
202
|
+
physicsMode: PaddockPhysicsMode;
|
|
42
203
|
totalLaps: number;
|
|
43
204
|
raceControl: {
|
|
44
205
|
mode: string;
|
|
@@ -47,7 +208,9 @@ export interface RaceSnapshot {
|
|
|
47
208
|
};
|
|
48
209
|
track: Record<string, unknown>;
|
|
49
210
|
cars: Array<Record<string, unknown>>;
|
|
211
|
+
replayGhosts: PaddockReplayGhostSnapshot[];
|
|
50
212
|
events: RaceEvent[];
|
|
213
|
+
penalties: PaddockPenaltyEntry[];
|
|
51
214
|
[key: string]: unknown;
|
|
52
215
|
}
|
|
53
216
|
|
|
@@ -55,27 +218,129 @@ export interface PaddockAction {
|
|
|
55
218
|
steering: number;
|
|
56
219
|
throttle: number;
|
|
57
220
|
brake: number;
|
|
221
|
+
pitIntent?: PaddockPitIntent;
|
|
222
|
+
pitCompound?: TireCompound | string;
|
|
223
|
+
pitTargetCompound?: TireCompound | string;
|
|
58
224
|
}
|
|
59
225
|
|
|
60
226
|
export type PaddockActionMap = Record<string, PaddockAction>;
|
|
61
227
|
|
|
228
|
+
export interface PaddockRaceRules {
|
|
229
|
+
ruleset?: PaddockRulesetName;
|
|
230
|
+
profile?: PaddockRulesetName;
|
|
231
|
+
modules?: {
|
|
232
|
+
pitStops?: {
|
|
233
|
+
enabled?: boolean;
|
|
234
|
+
pitLaneSpeedLimitKph?: number;
|
|
235
|
+
defaultStopSeconds?: number;
|
|
236
|
+
variability?: {
|
|
237
|
+
enabled?: boolean;
|
|
238
|
+
perfect?: boolean;
|
|
239
|
+
speedImpactSeconds?: number;
|
|
240
|
+
consistencyJitterSeconds?: number;
|
|
241
|
+
issueChance?: number;
|
|
242
|
+
issueMaxDelaySeconds?: number;
|
|
243
|
+
};
|
|
244
|
+
doubleStacking?: boolean;
|
|
245
|
+
maxConcurrentPitLaneCars?: number;
|
|
246
|
+
minimumPitLaneGapMeters?: number;
|
|
247
|
+
tirePitRequestThresholdPercent?: number;
|
|
248
|
+
tirePitCommitThresholdPercent?: number;
|
|
249
|
+
};
|
|
250
|
+
tireStrategy?: {
|
|
251
|
+
enabled?: boolean;
|
|
252
|
+
compounds?: TireCompound[];
|
|
253
|
+
mandatoryDistinctDryCompounds?: number | null;
|
|
254
|
+
};
|
|
255
|
+
tireDegradation?: {
|
|
256
|
+
enabled?: boolean;
|
|
257
|
+
};
|
|
258
|
+
stalledDnf?: {
|
|
259
|
+
enabled?: boolean;
|
|
260
|
+
maxStoppedSeconds?: number;
|
|
261
|
+
speedThresholdKph?: number;
|
|
262
|
+
};
|
|
263
|
+
penalties?: {
|
|
264
|
+
enabled?: boolean;
|
|
265
|
+
stewardStrictness?: number;
|
|
266
|
+
trackLimits?: {
|
|
267
|
+
strictness?: number;
|
|
268
|
+
warningsBeforePenalty?: number;
|
|
269
|
+
relaxedMarginMeters?: number;
|
|
270
|
+
timePenaltySeconds?: number;
|
|
271
|
+
consequences?: PaddockPenaltyConsequence[];
|
|
272
|
+
};
|
|
273
|
+
collision?: {
|
|
274
|
+
strictness?: number;
|
|
275
|
+
timePenaltySeconds?: number;
|
|
276
|
+
consequences?: PaddockPenaltyConsequence[];
|
|
277
|
+
minimumSeverity?: number;
|
|
278
|
+
relaxedSeverityMargin?: number;
|
|
279
|
+
minimumImpactSpeedKph?: number;
|
|
280
|
+
relaxedImpactSpeedKph?: number;
|
|
281
|
+
};
|
|
282
|
+
tireRequirement?: {
|
|
283
|
+
strictness?: number;
|
|
284
|
+
timePenaltySeconds?: number;
|
|
285
|
+
consequences?: PaddockPenaltyConsequence[];
|
|
286
|
+
};
|
|
287
|
+
pitLaneSpeeding?: {
|
|
288
|
+
strictness?: number;
|
|
289
|
+
speedLimitKph?: number;
|
|
290
|
+
marginKph?: number;
|
|
291
|
+
relaxedMarginKph?: number;
|
|
292
|
+
timePenaltySeconds?: number;
|
|
293
|
+
consequences?: PaddockPenaltyConsequence[];
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
weather?: { enabled?: boolean };
|
|
297
|
+
reliability?: { enabled?: boolean };
|
|
298
|
+
fuelLoad?: { enabled?: boolean };
|
|
299
|
+
};
|
|
300
|
+
drsDetectionSeconds?: number;
|
|
301
|
+
safetyCarSpeed?: number;
|
|
302
|
+
safetyCarLeadDistance?: number;
|
|
303
|
+
safetyCarGap?: number;
|
|
304
|
+
collisionRestitution?: number;
|
|
305
|
+
standingStart?: boolean;
|
|
306
|
+
startLightCount?: number;
|
|
307
|
+
startLightInterval?: number;
|
|
308
|
+
startLightsOutHold?: number;
|
|
309
|
+
}
|
|
310
|
+
|
|
62
311
|
export interface PaddockSensorRayResult {
|
|
312
|
+
id?: string;
|
|
63
313
|
angleDegrees: number;
|
|
64
314
|
angleRadians: number;
|
|
65
315
|
lengthMeters: number;
|
|
316
|
+
roadEdge: {
|
|
317
|
+
hit: boolean;
|
|
318
|
+
distanceMeters: number;
|
|
319
|
+
kind: 'exit' | 'entry' | null;
|
|
320
|
+
};
|
|
66
321
|
track: {
|
|
67
322
|
hit: boolean;
|
|
68
323
|
distanceMeters: number;
|
|
69
324
|
kind: 'exit' | 'entry' | null;
|
|
70
325
|
};
|
|
326
|
+
kerb: PaddockSurfaceRayHit;
|
|
327
|
+
illegalSurface: PaddockSurfaceRayHit;
|
|
71
328
|
car: {
|
|
72
329
|
hit: boolean;
|
|
73
330
|
distanceMeters: number;
|
|
74
331
|
driverId: string | null;
|
|
332
|
+
targetId?: string | null;
|
|
333
|
+
targetType?: 'car' | 'replayGhost' | null;
|
|
75
334
|
relativeSpeedKph: number;
|
|
76
335
|
};
|
|
77
336
|
}
|
|
78
337
|
|
|
338
|
+
export interface PaddockSurfaceRayHit {
|
|
339
|
+
hit: boolean;
|
|
340
|
+
distanceMeters: number;
|
|
341
|
+
surface: string | null;
|
|
342
|
+
}
|
|
343
|
+
|
|
79
344
|
export interface PaddockNearbyCarObservation {
|
|
80
345
|
id: string;
|
|
81
346
|
relativeForwardMeters: number;
|
|
@@ -84,15 +349,29 @@ export interface PaddockNearbyCarObservation {
|
|
|
84
349
|
relativeSpeedKph: number;
|
|
85
350
|
relativeHeadingRadians: number;
|
|
86
351
|
ahead: boolean;
|
|
352
|
+
behind: boolean;
|
|
87
353
|
sameLap: boolean;
|
|
354
|
+
closingRateMetersPerSecond: number;
|
|
355
|
+
timeToContactSeconds: number | null;
|
|
356
|
+
leftOverlap: boolean;
|
|
357
|
+
rightOverlap: boolean;
|
|
358
|
+
entityType?: 'car' | 'replayGhost';
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export interface PaddockTrackLookaheadObservation {
|
|
362
|
+
distanceMeters: number;
|
|
363
|
+
curvature: number;
|
|
364
|
+
headingDeltaRadians: number;
|
|
88
365
|
}
|
|
89
366
|
|
|
90
367
|
export interface PaddockDriverObservationObject {
|
|
368
|
+
profile: string;
|
|
91
369
|
self: {
|
|
92
370
|
id: string;
|
|
93
371
|
speedKph: number;
|
|
94
372
|
speedMetersPerSecond: number;
|
|
95
373
|
headingRadians: number;
|
|
374
|
+
yawRateRadiansPerSecond: number;
|
|
96
375
|
steeringAngleRadians: number;
|
|
97
376
|
throttle: number;
|
|
98
377
|
brake: number;
|
|
@@ -103,19 +382,66 @@ export interface PaddockDriverObservationObject {
|
|
|
103
382
|
trackHeadingErrorRadians: number;
|
|
104
383
|
onTrack: boolean;
|
|
105
384
|
surface: string;
|
|
385
|
+
inPitLane: boolean;
|
|
386
|
+
pitLanePart: 'entry' | 'fast-lane' | 'working-lane' | 'exit' | 'service-box' | 'garage-box' | null;
|
|
387
|
+
pitBoxId: string | null;
|
|
106
388
|
tireEnergy: number | null;
|
|
389
|
+
pitIntent: PaddockPitIntent;
|
|
390
|
+
pitTargetCompound: TireCompound | string | null;
|
|
391
|
+
pitStopStatus: 'pending' | 'entering' | 'queued' | 'servicing' | 'exiting' | 'completed' | null;
|
|
392
|
+
pitStopPhase: 'entry' | 'queue' | 'queue-release' | 'penalty' | 'service' | 'exit' | null;
|
|
393
|
+
pitStopServiceRemainingSeconds: number | null;
|
|
394
|
+
pitStopPenaltyServiceRemainingSeconds: number | null;
|
|
395
|
+
pitStopsCompleted: number;
|
|
396
|
+
lateralG: number;
|
|
397
|
+
longitudinalG: number;
|
|
398
|
+
gripUsage: number;
|
|
399
|
+
slipAngleRadians: number;
|
|
400
|
+
tractionLimited: boolean;
|
|
401
|
+
stabilityState: PaddockStabilityState;
|
|
402
|
+
destroyed: boolean;
|
|
403
|
+
destroyReason: string | null;
|
|
404
|
+
};
|
|
405
|
+
trackRelation: {
|
|
406
|
+
lateralOffsetMeters: number;
|
|
407
|
+
headingErrorRadians: number;
|
|
408
|
+
legalWidthMeters: number;
|
|
409
|
+
leftBoundaryMeters: number;
|
|
410
|
+
rightBoundaryMeters: number;
|
|
411
|
+
onLegalSurface: boolean;
|
|
412
|
+
surface: string;
|
|
107
413
|
};
|
|
414
|
+
contactPatches: PaddockContactPatchObservation[];
|
|
108
415
|
race: {
|
|
109
416
|
position: number;
|
|
110
417
|
totalCars: number;
|
|
111
418
|
raceMode: string;
|
|
419
|
+
pitLaneOpen: boolean;
|
|
420
|
+
redFlag: boolean;
|
|
112
421
|
totalLaps: number;
|
|
113
422
|
};
|
|
423
|
+
track: {
|
|
424
|
+
lengthMeters: number;
|
|
425
|
+
widthMeters: number;
|
|
426
|
+
curvature: number;
|
|
427
|
+
lookahead: PaddockTrackLookaheadObservation[];
|
|
428
|
+
};
|
|
114
429
|
rays: PaddockSensorRayResult[];
|
|
115
430
|
nearbyCars: PaddockNearbyCarObservation[];
|
|
116
431
|
events: RaceEvent[];
|
|
117
432
|
}
|
|
118
433
|
|
|
434
|
+
export interface PaddockContactPatchObservation {
|
|
435
|
+
id: 'front-left' | 'front-right' | 'rear-left' | 'rear-right' | string;
|
|
436
|
+
present: boolean;
|
|
437
|
+
signedOffsetMeters: number;
|
|
438
|
+
crossTrackErrorMeters: number;
|
|
439
|
+
surface: string;
|
|
440
|
+
surfaceCode: number;
|
|
441
|
+
onLegalSurface: boolean;
|
|
442
|
+
inPitLane: boolean;
|
|
443
|
+
}
|
|
444
|
+
|
|
119
445
|
export interface PaddockObservationSchemaEntry {
|
|
120
446
|
name: string;
|
|
121
447
|
unit?: string;
|
|
@@ -123,30 +449,56 @@ export interface PaddockObservationSchemaEntry {
|
|
|
123
449
|
}
|
|
124
450
|
|
|
125
451
|
export interface PaddockDriverObservation {
|
|
126
|
-
object
|
|
127
|
-
vector
|
|
128
|
-
schema
|
|
452
|
+
object?: PaddockDriverObservationObject;
|
|
453
|
+
vector?: number[] | Float32Array;
|
|
454
|
+
schema?: PaddockObservationSchemaEntry[];
|
|
129
455
|
events: RaceEvent[];
|
|
130
456
|
}
|
|
131
457
|
|
|
458
|
+
export type PaddockWarmupPolicy = 'config-change' | 'always' | 'never';
|
|
459
|
+
|
|
460
|
+
export interface PaddockWarmupOptions {
|
|
461
|
+
enabled?: boolean;
|
|
462
|
+
policy?: PaddockWarmupPolicy;
|
|
463
|
+
steps?: number;
|
|
464
|
+
}
|
|
465
|
+
|
|
132
466
|
export interface PaddockEnvironmentOptions {
|
|
133
467
|
drivers: SimulatorDriver[];
|
|
134
468
|
entries?: ChampionshipEntryBlueprint[];
|
|
135
469
|
controlledDrivers: string[];
|
|
136
470
|
seed?: number;
|
|
137
471
|
trackSeed?: number;
|
|
472
|
+
trackGeneration?: PaddockProceduralTrackOptions;
|
|
473
|
+
trackQueryIndex?: boolean;
|
|
138
474
|
totalLaps?: number;
|
|
139
475
|
frameSkip?: number;
|
|
476
|
+
physicsMode?: PaddockPhysicsMode;
|
|
477
|
+
rules?: PaddockRaceRules;
|
|
478
|
+
participantInteractions?: PaddockParticipantInteractionsOptions;
|
|
479
|
+
replayGhosts?: PaddockReplayGhostOptions[];
|
|
140
480
|
actionPolicy?: 'strict' | 'report';
|
|
141
481
|
scenario?: {
|
|
142
482
|
participants?: 'all' | 'controlled-only' | string[];
|
|
143
483
|
nonControlled?: 'ai';
|
|
484
|
+
preset?: PaddockScenarioPreset;
|
|
485
|
+
placements?: Record<string, PaddockScenarioPlacement>;
|
|
486
|
+
traffic?: PaddockScenarioTrafficPlacement[];
|
|
144
487
|
};
|
|
145
488
|
sensors?: {
|
|
146
489
|
rays?: {
|
|
147
490
|
enabled?: boolean;
|
|
148
491
|
anglesDegrees?: number[];
|
|
149
492
|
lengthMeters?: number;
|
|
493
|
+
defaultLengthMeters?: number;
|
|
494
|
+
layout?: 'compact' | 'driver-front-heavy' | 'lidar-lite' | string;
|
|
495
|
+
rays?: Array<number | {
|
|
496
|
+
id?: string;
|
|
497
|
+
angleDegrees: number;
|
|
498
|
+
lengthMeters?: number;
|
|
499
|
+
}>;
|
|
500
|
+
channels?: Array<'roadEdge' | 'kerb' | 'illegalSurface' | 'car'>;
|
|
501
|
+
precision?: 'driver' | 'debug';
|
|
150
502
|
detectTrack?: boolean;
|
|
151
503
|
detectCars?: boolean;
|
|
152
504
|
};
|
|
@@ -157,11 +509,45 @@ export interface PaddockEnvironmentOptions {
|
|
|
157
509
|
};
|
|
158
510
|
};
|
|
159
511
|
sensorsByDriver?: Record<string, PaddockEnvironmentOptions['sensors']>;
|
|
512
|
+
observation?: {
|
|
513
|
+
profile?: 'default' | 'physical-driver' | 'debug-map' | string;
|
|
514
|
+
output?: 'full' | 'vector' | 'object';
|
|
515
|
+
includeSchema?: boolean;
|
|
516
|
+
vectorType?: 'array' | 'float32';
|
|
517
|
+
lookaheadMeters?: number[];
|
|
518
|
+
};
|
|
519
|
+
result?: {
|
|
520
|
+
stateOutput?: 'full' | 'minimal' | 'none';
|
|
521
|
+
resetDriversObservationScope?: 'all' | 'reset';
|
|
522
|
+
};
|
|
523
|
+
warmup?: PaddockWarmupOptions | boolean;
|
|
160
524
|
episode?: {
|
|
161
525
|
maxSteps?: number;
|
|
162
526
|
endOnRaceFinish?: boolean;
|
|
163
527
|
};
|
|
164
528
|
reward?: (payload: PaddockRewardContext) => number;
|
|
529
|
+
externalRenderer?: PaddockExternalRendererHook | ((frame: PaddockExternalRenderFrame) => void);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export interface PaddockExternalRendererHook {
|
|
533
|
+
onFrame(frame: PaddockExternalRenderFrame): void;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export interface PaddockScenarioPlacement {
|
|
537
|
+
distanceMeters?: number;
|
|
538
|
+
startDistanceMeters?: number;
|
|
539
|
+
offsetMeters?: number;
|
|
540
|
+
speedKph?: number;
|
|
541
|
+
headingErrorRadians?: number;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export interface PaddockScenarioTrafficPlacement {
|
|
545
|
+
driverId: string;
|
|
546
|
+
relativeTo: string;
|
|
547
|
+
deltaDistanceMeters?: number;
|
|
548
|
+
offsetMeters?: number;
|
|
549
|
+
speedKph?: number;
|
|
550
|
+
headingErrorRadians?: number;
|
|
165
551
|
}
|
|
166
552
|
|
|
167
553
|
export interface PaddockRewardContext {
|
|
@@ -171,6 +557,8 @@ export interface PaddockRewardContext {
|
|
|
171
557
|
action: PaddockAction | undefined;
|
|
172
558
|
events: RaceEvent[];
|
|
173
559
|
state: { snapshot: RaceSnapshot };
|
|
560
|
+
metrics: PaddockEnvironmentDriverMetrics;
|
|
561
|
+
episode: PaddockDriverRuntimeState;
|
|
174
562
|
}
|
|
175
563
|
|
|
176
564
|
export interface PaddockProgressRewardWeights {
|
|
@@ -195,12 +583,14 @@ export interface PaddockActionSpec {
|
|
|
195
583
|
steering: { min: -1; max: 1; unit: 'normalized' };
|
|
196
584
|
throttle: { min: 0; max: 1; unit: 'normalized' };
|
|
197
585
|
brake: { min: 0; max: 1; unit: 'normalized' };
|
|
586
|
+
pitIntent: { values: [0, 1, 2]; unit: 'request'; optional: true };
|
|
587
|
+
pitCompound: { values: string[]; unit: 'compound'; optional: true };
|
|
198
588
|
};
|
|
199
589
|
};
|
|
200
590
|
}
|
|
201
591
|
|
|
202
592
|
export interface PaddockObservationSpec {
|
|
203
|
-
version:
|
|
593
|
+
version: 2 | 4;
|
|
204
594
|
controlledDrivers: string[];
|
|
205
595
|
object: Record<string, unknown>;
|
|
206
596
|
vector: {
|
|
@@ -208,14 +598,193 @@ export interface PaddockObservationSpec {
|
|
|
208
598
|
};
|
|
209
599
|
}
|
|
210
600
|
|
|
601
|
+
export interface PaddockRolloutTransition {
|
|
602
|
+
observation: Record<string, PaddockDriverObservation>;
|
|
603
|
+
action: PaddockActionMap;
|
|
604
|
+
reward: null | Record<string, number>;
|
|
605
|
+
nextObservation: Record<string, PaddockDriverObservation>;
|
|
606
|
+
terminated: boolean;
|
|
607
|
+
truncated: boolean;
|
|
608
|
+
info: PaddockEnvironmentResult['info'];
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export interface PaddockRolloutRecorder {
|
|
612
|
+
recordStep(
|
|
613
|
+
previousResult: PaddockEnvironmentResult,
|
|
614
|
+
action: PaddockActionMap,
|
|
615
|
+
nextResult: PaddockEnvironmentResult
|
|
616
|
+
): PaddockRolloutTransition;
|
|
617
|
+
clear(): void;
|
|
618
|
+
toJSON(): PaddockRolloutTransition[];
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
export interface PaddockEvaluationCase {
|
|
622
|
+
name: string;
|
|
623
|
+
seed?: number;
|
|
624
|
+
trackSeed?: number;
|
|
625
|
+
maxSteps?: number;
|
|
626
|
+
scenario?: PaddockEnvironmentOptions['scenario'];
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
export interface PaddockEvaluationDriverMetrics {
|
|
630
|
+
distanceMeters: number;
|
|
631
|
+
lapProgressMeters: number;
|
|
632
|
+
offTrackSteps: number;
|
|
633
|
+
contactCount: number;
|
|
634
|
+
recoverySuccess: boolean;
|
|
635
|
+
passCount: number;
|
|
636
|
+
lapTimeSeconds: number | null;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export interface PaddockEvaluationCaseReport {
|
|
640
|
+
name: string;
|
|
641
|
+
seed?: number;
|
|
642
|
+
trackSeed?: number;
|
|
643
|
+
steps: number;
|
|
644
|
+
done: boolean;
|
|
645
|
+
endReason: string | null;
|
|
646
|
+
metrics: Record<string, PaddockEvaluationDriverMetrics>;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export interface PaddockEvaluationReport {
|
|
650
|
+
cases: PaddockEvaluationCaseReport[];
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
export type PaddockPolicyLike =
|
|
654
|
+
| ((observation: PaddockDriverObservation, context: Record<string, unknown>) => PaddockAction)
|
|
655
|
+
| { predict(observation: PaddockDriverObservation, context: Record<string, unknown>): PaddockAction };
|
|
656
|
+
|
|
657
|
+
export interface PaddockDriverControllerContext {
|
|
658
|
+
runtime: PaddockControllerRuntime;
|
|
659
|
+
mode: string;
|
|
660
|
+
actionRepeat: number;
|
|
661
|
+
controlledDrivers: string[];
|
|
662
|
+
actionSpec: PaddockActionSpec;
|
|
663
|
+
observationSpec: PaddockObservationSpec;
|
|
664
|
+
result: PaddockEnvironmentResult | unknown;
|
|
665
|
+
previousResult: PaddockEnvironmentResult | unknown | null;
|
|
666
|
+
observation: Record<string, PaddockDriverObservation>;
|
|
667
|
+
orderedObservations: Array<{
|
|
668
|
+
driverId: string;
|
|
669
|
+
index: number;
|
|
670
|
+
observation: PaddockDriverObservation | null;
|
|
671
|
+
vector: number[] | Float32Array | null;
|
|
672
|
+
}>;
|
|
673
|
+
metrics: Record<string, PaddockEnvironmentDriverMetrics>;
|
|
674
|
+
events: RaceEvent[];
|
|
675
|
+
info: PaddockEnvironmentResult['info'] | unknown | null;
|
|
676
|
+
previousActions: PaddockActionMap;
|
|
677
|
+
orderedPreviousActions: Array<PaddockAction | null>;
|
|
678
|
+
actions: PaddockActionMap | null;
|
|
679
|
+
policyStep: number;
|
|
680
|
+
runtimeStep: number;
|
|
681
|
+
heldFramesRemaining: number;
|
|
682
|
+
actionIndex: number;
|
|
683
|
+
resetDriverIds: string[];
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export interface PaddockExternalRenderFrame {
|
|
687
|
+
snapshot: RaceSnapshot;
|
|
688
|
+
observation: Record<string, unknown>;
|
|
689
|
+
meta?: Record<string, unknown> | null;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export interface PaddockExternalRendererSource {
|
|
693
|
+
subscribe(onFrame: (frame: PaddockExternalRenderFrame) => void): () => void;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
export interface PaddockExternalRendererState {
|
|
697
|
+
attached: boolean;
|
|
698
|
+
lastMeta: Record<string, unknown> | null;
|
|
699
|
+
lastFrameAt: number | null;
|
|
700
|
+
lastError: string | null;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
export interface PaddockDriverController {
|
|
704
|
+
init?(context: PaddockDriverControllerContext): void | Promise<void>;
|
|
705
|
+
reset?(context: PaddockDriverControllerContext): void | Promise<void>;
|
|
706
|
+
decideBatch(context: PaddockDriverControllerContext): PaddockActionMap | Promise<PaddockActionMap>;
|
|
707
|
+
onStep?(context: PaddockDriverControllerContext): void | Promise<void>;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
export interface PaddockControllerRuntime {
|
|
711
|
+
reset(options?: unknown): PaddockEnvironmentResult | unknown;
|
|
712
|
+
step(actions: PaddockActionMap): PaddockEnvironmentResult | unknown;
|
|
713
|
+
resetDrivers?(
|
|
714
|
+
placements: Record<string, PaddockScenarioPlacement>,
|
|
715
|
+
resultOptions?: PaddockEnvironmentResultOptions
|
|
716
|
+
): PaddockEnvironmentResult | unknown;
|
|
717
|
+
getObservation(): Record<string, PaddockDriverObservation>;
|
|
718
|
+
getState?(options?: { output?: 'full' | 'minimal' | 'none' }): PaddockEnvironmentResult['state'] | unknown;
|
|
719
|
+
getActionSpec(): PaddockActionSpec;
|
|
720
|
+
getObservationSpec(): PaddockObservationSpec;
|
|
721
|
+
destroy?(): void;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
export interface PaddockDriverControllerLoopOptions {
|
|
725
|
+
runtime: PaddockControllerRuntime;
|
|
726
|
+
controller: PaddockDriverController;
|
|
727
|
+
actionRepeat?: number;
|
|
728
|
+
mode?: string;
|
|
729
|
+
scheduler?: null | ((callback: () => void | Promise<void>) => unknown);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
export interface PaddockDriverControllerLoop {
|
|
733
|
+
readonly result: PaddockEnvironmentResult | unknown | null;
|
|
734
|
+
readonly actionSpec: PaddockActionSpec | null;
|
|
735
|
+
readonly observationSpec: PaddockObservationSpec | null;
|
|
736
|
+
readonly stats: {
|
|
737
|
+
policyStep: number;
|
|
738
|
+
runtimeStep: number;
|
|
739
|
+
heldFramesRemaining: number;
|
|
740
|
+
actions: PaddockActionMap | null;
|
|
741
|
+
actionRepeat: number;
|
|
742
|
+
lastDecisionMs: number;
|
|
743
|
+
running: boolean;
|
|
744
|
+
lastError: unknown | null;
|
|
745
|
+
};
|
|
746
|
+
reset(options?: unknown): Promise<PaddockEnvironmentResult | unknown>;
|
|
747
|
+
resetDrivers(
|
|
748
|
+
placements: Record<string, PaddockScenarioPlacement>,
|
|
749
|
+
resultOptions?: PaddockEnvironmentResultOptions
|
|
750
|
+
): Promise<PaddockEnvironmentResult | unknown>;
|
|
751
|
+
step(): Promise<PaddockEnvironmentResult | unknown>;
|
|
752
|
+
stepFrame(): Promise<PaddockEnvironmentResult | unknown>;
|
|
753
|
+
start(): void;
|
|
754
|
+
stop(): void;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
export interface PaddockEnvironmentWorkerMessage {
|
|
758
|
+
id?: string | number | null;
|
|
759
|
+
type: 'reset' | 'resetDrivers' | 'step' | 'getActionSpec' | 'getObservationSpec' | 'getObservation' | 'getState' | 'destroy' | string;
|
|
760
|
+
options?: Partial<PaddockEnvironmentOptions>;
|
|
761
|
+
actions?: PaddockActionMap;
|
|
762
|
+
placements?: Record<string, PaddockScenarioPlacement>;
|
|
763
|
+
resultOptions?: PaddockEnvironmentResultOptions;
|
|
764
|
+
stateOptions?: { output?: 'full' | 'minimal' | 'none' };
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export interface PaddockEnvironmentWorkerResponse {
|
|
768
|
+
id: string | number | null;
|
|
769
|
+
ok: boolean;
|
|
770
|
+
type: string;
|
|
771
|
+
result?: unknown;
|
|
772
|
+
error?: string;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
export interface PaddockEnvironmentWorkerProtocol {
|
|
776
|
+
handle(message: PaddockEnvironmentWorkerMessage): PaddockEnvironmentWorkerResponse;
|
|
777
|
+
}
|
|
778
|
+
|
|
211
779
|
export interface PaddockEnvironmentResult {
|
|
212
780
|
observation: Record<string, PaddockDriverObservation>;
|
|
213
781
|
reward: null | Record<string, number>;
|
|
782
|
+
metrics: Record<string, PaddockEnvironmentDriverMetrics>;
|
|
214
783
|
terminated: boolean;
|
|
215
784
|
truncated: boolean;
|
|
216
785
|
done: boolean;
|
|
217
786
|
events: RaceEvent[];
|
|
218
|
-
state: { snapshot: RaceSnapshot };
|
|
787
|
+
state: { snapshot: RaceSnapshot } | null;
|
|
219
788
|
info: {
|
|
220
789
|
step: number;
|
|
221
790
|
elapsedSeconds: number;
|
|
@@ -224,18 +793,81 @@ export interface PaddockEnvironmentResult {
|
|
|
224
793
|
controlledDrivers: string[];
|
|
225
794
|
actionErrors: string[];
|
|
226
795
|
endReason: string | null;
|
|
796
|
+
drivers: Record<string, PaddockDriverRuntimeState>;
|
|
227
797
|
};
|
|
228
798
|
}
|
|
229
799
|
|
|
800
|
+
export type PaddockEnvironmentSnapshotResult = PaddockEnvironmentResult & {
|
|
801
|
+
state: { snapshot: RaceSnapshot };
|
|
802
|
+
};
|
|
803
|
+
|
|
230
804
|
export interface PaddockEnvironment {
|
|
231
805
|
reset(options?: Partial<PaddockEnvironmentOptions>): PaddockEnvironmentResult;
|
|
806
|
+
resetDrivers(
|
|
807
|
+
placements: Record<string, PaddockScenarioPlacement>,
|
|
808
|
+
resultOptions?: PaddockEnvironmentResultOptions
|
|
809
|
+
): PaddockEnvironmentResult;
|
|
232
810
|
step(actions: PaddockActionMap): PaddockEnvironmentResult;
|
|
233
811
|
getObservation(): PaddockEnvironmentResult['observation'];
|
|
234
|
-
getState(): PaddockEnvironmentResult['state'];
|
|
812
|
+
getState(options?: { output?: 'full' | 'minimal' | 'none' }): PaddockEnvironmentResult['state'];
|
|
235
813
|
getActionSpec(): PaddockActionSpec;
|
|
236
814
|
getObservationSpec(): PaddockObservationSpec;
|
|
237
815
|
destroy(): void;
|
|
238
816
|
}
|
|
239
817
|
|
|
818
|
+
export interface PaddockEnvironmentResultOptions {
|
|
819
|
+
stateOutput?: 'full' | 'minimal' | 'none';
|
|
820
|
+
observationScope?: 'all' | 'reset';
|
|
821
|
+
resetDriversObservationScope?: 'all' | 'reset';
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
export interface PaddockDriverRuntimeState {
|
|
825
|
+
terminated: boolean;
|
|
826
|
+
truncated: boolean;
|
|
827
|
+
endReason: string | null;
|
|
828
|
+
episodeStep: number;
|
|
829
|
+
episodeId: number;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
export interface PaddockEnvironmentDriverMetrics {
|
|
833
|
+
progressDeltaMeters: number;
|
|
834
|
+
legalProgressDeltaMeters: number;
|
|
835
|
+
offTrack: boolean;
|
|
836
|
+
kerb: boolean;
|
|
837
|
+
fullyOutsideWhiteLine: boolean;
|
|
838
|
+
severeCut: boolean;
|
|
839
|
+
destroyed: boolean;
|
|
840
|
+
destroyReason: string | null;
|
|
841
|
+
under30kph: boolean;
|
|
842
|
+
spinOrBackwards: boolean;
|
|
843
|
+
completedLap: boolean;
|
|
844
|
+
lapTimeSeconds: number | null;
|
|
845
|
+
contactCount: number;
|
|
846
|
+
}
|
|
847
|
+
|
|
240
848
|
export function createPaddockEnvironment(options: PaddockEnvironmentOptions): PaddockEnvironment;
|
|
849
|
+
export function createPaddockDriverControllerLoop(options: PaddockDriverControllerLoopOptions): PaddockDriverControllerLoop;
|
|
241
850
|
export function createProgressReward(options?: PaddockProgressRewardOptions): (context: PaddockRewardContext) => number;
|
|
851
|
+
export function createRolloutRecorder(): PaddockRolloutRecorder;
|
|
852
|
+
export function createRolloutTransition(
|
|
853
|
+
previousResult: PaddockEnvironmentResult,
|
|
854
|
+
action: PaddockActionMap,
|
|
855
|
+
nextResult: PaddockEnvironmentResult
|
|
856
|
+
): PaddockRolloutTransition;
|
|
857
|
+
export const ENVIRONMENT_SCENARIO_PRESETS: readonly PaddockScenarioPreset[];
|
|
858
|
+
export const DEFAULT_EVALUATION_CASES: readonly PaddockEvaluationCase[];
|
|
859
|
+
export function createEvaluationTracker(initialResult: PaddockEnvironmentSnapshotResult): {
|
|
860
|
+
update(result: PaddockEnvironmentSnapshotResult): void;
|
|
861
|
+
finish(): Record<string, PaddockEvaluationDriverMetrics>;
|
|
862
|
+
};
|
|
863
|
+
export function runEnvironmentEvaluation(options: {
|
|
864
|
+
baseOptions: PaddockEnvironmentOptions;
|
|
865
|
+
policy: PaddockPolicyLike;
|
|
866
|
+
cases?: PaddockEvaluationCase[];
|
|
867
|
+
createEnvironment?: (options: PaddockEnvironmentOptions) => PaddockEnvironment;
|
|
868
|
+
}): PaddockEvaluationReport;
|
|
869
|
+
export function createEnvironmentWorkerProtocol(env: PaddockEnvironment): PaddockEnvironmentWorkerProtocol;
|
|
870
|
+
export function handleEnvironmentMessage(
|
|
871
|
+
env: PaddockEnvironment,
|
|
872
|
+
message: PaddockEnvironmentWorkerMessage
|
|
873
|
+
): PaddockEnvironmentWorkerResponse;
|