@inventure71/paddockjs 3.0.0 → 4.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 +146 -1
- package/INSTALL_AND_UPDATE.md +15 -4
- package/README.md +84 -562
- package/docs/architecture.md +28 -18
- package/docs/composable-layouts.md +77 -0
- package/docs/custom_model_controller.md +4 -4
- package/docs/data-helpers.md +50 -0
- package/docs/data_contract.md +9 -7
- package/docs/getting-started.md +75 -0
- package/docs/headless-environment.md +68 -0
- package/docs/index.md +17 -4
- package/docs/rules.md +6 -2
- package/docs/system_specs.md +49 -6
- package/docs/theming.md +64 -0
- package/docs/training.md +20 -14
- package/docs/troubleshooting.md +76 -0
- package/docs/upgrading-hosts-to-3.md +42 -0
- package/examples/python/README.md +6 -0
- package/examples/python/base_policy_server.py +19 -0
- package/package.json +10 -3
- package/src/api/PaddockSimulatorController.js +78 -22
- package/src/api/runtimeTheme.js +59 -0
- package/src/app/F1SimulatorApp.js +24 -3
- package/src/app/readouts/timingTowerRenderer.js +203 -42
- package/src/app/runtime/frameLoop.js +5 -1
- package/src/config/defaultOptions.js +8 -1
- package/src/config/themeOptions.js +5 -0
- package/src/data/index.d.ts +212 -0
- package/src/data/index.js +14 -0
- package/src/environment/episode.js +11 -1
- package/src/environment/metrics.js +59 -16
- package/src/environment/observationVector.js +50 -33
- package/src/environment/observations.js +89 -20
- package/src/environment/runtime.js +41 -0
- package/src/environment/sensors/carRays.js +48 -37
- package/src/environment/sensors/index.js +501 -97
- package/src/environment/sensors/indexedRayBands.js +134 -46
- package/src/environment/sensors/rayBandTrace.js +1171 -0
- package/src/environment/sensors/rayChannels.js +108 -0
- package/src/environment/sensors/rayConfig.js +71 -25
- package/src/environment/sensors/rayGeometry.js +23 -17
- package/src/environment/sensors/sensorTargets.js +67 -1
- package/src/environment/sensors/surfaceRays.js +130 -89
- package/src/environment/sensors/trackRays.js +115 -1
- package/src/index.d.ts +43 -0
- package/src/index.js +27 -2
- package/src/simulation/collisionGeometry.js +260 -96
- package/src/simulation/pit/pitFlow.js +21 -9
- package/src/simulation/pit/pitQueue.js +5 -3
- package/src/simulation/pit/pitRouteMovement.js +9 -4
- package/src/simulation/pit/pitRouting.js +77 -42
- package/src/simulation/pit/pitState.js +1 -0
- package/src/simulation/pit/pitTireService.js +7 -3
- package/src/simulation/race/raceFinish.js +25 -8
- package/src/simulation/race/raceOrder.js +189 -32
- package/src/simulation/race/raceProgress.js +129 -37
- package/src/simulation/race/raceSetup.js +2 -0
- package/src/simulation/race/raceStep.js +25 -13
- package/src/simulation/raceSimulation.js +20 -17
- package/src/simulation/rules/collisionSteward.js +40 -23
- package/src/simulation/rules/rulesReview.js +77 -56
- package/src/simulation/snapshots/raceSnapshots.js +37 -0
- package/src/simulation/timing/drsTiming.js +143 -30
- package/src/simulation/timing/gapEstimation.js +25 -3
- package/src/simulation/timing/lapTelemetry.js +115 -36
- package/src/simulation/timing/raceTiming.js +5 -1
- package/src/simulation/timing/sectorPerformance.js +104 -26
- package/src/simulation/timing/timingHistory.js +229 -14
- package/src/simulation/timing/timingLines.js +65 -7
- package/src/simulation/track/pitLaneLayout.js +23 -0
- package/src/simulation/track/pitLaneState.js +218 -19
- package/src/simulation/track/spatialQueries.js +67 -11
- package/src/simulation/track/trackMath.js +91 -24
- package/src/simulation/track/trackModel.js +2 -0
- package/src/simulation/track/trackQueryIndex.js +1334 -100
- package/src/simulation/track/trackQueryPitIndex.js +138 -14
- package/src/simulation/track/trackQueryScratch.js +7 -0
- package/src/simulation/track/trackQueryStats.js +25 -0
- package/src/simulation/track/trackSnapshotJson.js +139 -0
- package/src/simulation/track/trackStatePolicy.js +249 -1
- package/src/simulation/vehicle/contactResolution.js +96 -59
- package/src/simulation/vehicle/mainTrackWheelSurface.js +73 -34
- package/src/simulation/vehicle/pitWheelSurface.js +81 -28
- package/src/simulation/vehicle/runoffResponse.js +54 -29
- package/src/simulation/vehicle/vehicleGeometry.js +245 -51
- package/src/simulation/vehicle/vehiclePhysics.js +42 -27
- package/src/simulation/vehicle/vehicleSnapshots.js +23 -0
- package/src/simulation/vehicle/vehicleState.js +6 -0
- package/src/simulation/vehicle/wheelSurface.js +807 -92
- package/src/styles.css +497 -497
|
@@ -195,6 +195,9 @@ export function createEnvironmentRuntime(host) {
|
|
|
195
195
|
episodeState.lastObservationSnapshot = null;
|
|
196
196
|
episodeState.lastRewardSnapshot = null;
|
|
197
197
|
episodeState.drivers?.clear?.();
|
|
198
|
+
episodeState.destroyedCarsById?.clear?.();
|
|
199
|
+
clearObservationScratch(episodeState.observationScratch);
|
|
200
|
+
clearMetricScratch(episodeState.metricScratch);
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
return { reset, step, resetDrivers, getObservation, getState, getActionSpec, getObservationSpec, destroy };
|
|
@@ -292,6 +295,7 @@ function buildResult({
|
|
|
292
295
|
options,
|
|
293
296
|
events,
|
|
294
297
|
controlledDrivers: resultDrivers,
|
|
298
|
+
scratch: episodeState.observationScratch,
|
|
295
299
|
});
|
|
296
300
|
const episode = evaluateEpisode(observationSnapshot, options, episodeState, resultDrivers);
|
|
297
301
|
const metrics = buildDriverMetrics({
|
|
@@ -299,6 +303,7 @@ function buildResult({
|
|
|
299
303
|
previousSnapshot: episodeState.previousSnapshot,
|
|
300
304
|
options: { ...options, controlledDrivers: resultDrivers },
|
|
301
305
|
events,
|
|
306
|
+
scratch: episodeState.metricScratch,
|
|
302
307
|
});
|
|
303
308
|
const rewardEpisodeInfo = buildDriverEpisodeInfo(episodeState, {
|
|
304
309
|
...options,
|
|
@@ -345,6 +350,42 @@ function buildResult({
|
|
|
345
350
|
};
|
|
346
351
|
}
|
|
347
352
|
|
|
353
|
+
function clearObservationScratch(scratch) {
|
|
354
|
+
if (!scratch) return;
|
|
355
|
+
scratch.carsById?.clear?.();
|
|
356
|
+
scratch.eventsByDriver?.clear?.();
|
|
357
|
+
scratch.controlledEventDrivers?.clear?.();
|
|
358
|
+
clearRayBatchContextScratch(scratch.rayBatchContextScratch);
|
|
359
|
+
if (Array.isArray(scratch.eventDriverIds)) scratch.eventDriverIds.length = 0;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function clearRayBatchContextScratch(scratch) {
|
|
363
|
+
if (!scratch) return;
|
|
364
|
+
const arrayKeys = [
|
|
365
|
+
'rayTargets',
|
|
366
|
+
'rayTargetPool',
|
|
367
|
+
'carTargets',
|
|
368
|
+
'rayVectors',
|
|
369
|
+
'sharedRayQueries',
|
|
370
|
+
'rays',
|
|
371
|
+
'rayPool',
|
|
372
|
+
'rayVectorValues',
|
|
373
|
+
'rayVectorValuePool',
|
|
374
|
+
];
|
|
375
|
+
for (let index = 0; index < arrayKeys.length; index += 1) {
|
|
376
|
+
const value = scratch[arrayKeys[index]];
|
|
377
|
+
if (Array.isArray(value)) value.length = 0;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function clearMetricScratch(scratch) {
|
|
382
|
+
if (!scratch) return;
|
|
383
|
+
scratch.previousCarsById?.clear?.();
|
|
384
|
+
scratch.currentCarsById?.clear?.();
|
|
385
|
+
scratch.contactCounts?.clear?.();
|
|
386
|
+
if (Array.isArray(scratch.eventDriverIds)) scratch.eventDriverIds.length = 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
348
389
|
function applyControlledRunoffResponse(sim, options) {
|
|
349
390
|
options?.controlledDrivers?.forEach?.((driverId) => {
|
|
350
391
|
const car = sim?.cars?.find?.((item) => item.id === driverId);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { metersToSimUnits, simUnitsToMeters } from '../../simulation/units.js';
|
|
2
2
|
import { VEHICLE_GEOMETRY } from '../../simulation/vehicle/vehicleGeometry.js';
|
|
3
|
-
import {
|
|
3
|
+
import { getCarRayOrigin, getCarRayVector, intersectAxisAlignedBoxRayScalars } from './rayGeometry.js';
|
|
4
4
|
import { rayDetectableTargets } from './sensorTargets.js';
|
|
5
5
|
|
|
6
6
|
export function estimateCarHit(
|
|
@@ -10,41 +10,53 @@ export function estimateCarHit(
|
|
|
10
10
|
lengthMeters,
|
|
11
11
|
origin = getCarRayOrigin(car),
|
|
12
12
|
targets = rayDetectableTargets(car, snapshot),
|
|
13
|
+
options = {},
|
|
13
14
|
) {
|
|
14
|
-
const ray = getCarRayVector(car, angleDegrees);
|
|
15
|
+
const ray = options.rayVector ?? getCarRayVector(car, angleDegrees);
|
|
16
|
+
if (options.stats) {
|
|
17
|
+
if (options.rayVector) options.stats.callerVectorCount += 1;
|
|
18
|
+
else options.stats.computedVectorCount += 1;
|
|
19
|
+
}
|
|
15
20
|
const maxDistance = metersToSimUnits(lengthMeters);
|
|
16
|
-
let
|
|
21
|
+
let closestTarget = null;
|
|
22
|
+
let closestDistance = Infinity;
|
|
17
23
|
targets.forEach((other) => {
|
|
18
24
|
if (!carRayBroadphaseHit(origin, ray, maxDistance, other)) return;
|
|
19
25
|
const hitDistance = intersectCarFootprint(origin, ray, other);
|
|
20
26
|
if (hitDistance == null || hitDistance > maxDistance) return;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
hit: true,
|
|
25
|
-
distanceSimUnits: hitDistance,
|
|
26
|
-
distanceMeters,
|
|
27
|
-
driverId: other.id,
|
|
28
|
-
targetId: other.id,
|
|
29
|
-
targetType: other.entityType,
|
|
30
|
-
relativeSpeedKph: other.speedKph - car.speedKph,
|
|
31
|
-
};
|
|
27
|
+
if (hitDistance < closestDistance) {
|
|
28
|
+
closestDistance = hitDistance;
|
|
29
|
+
closestTarget = other;
|
|
32
30
|
}
|
|
33
31
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return
|
|
32
|
+
const resultTarget = options.resultTarget ?? null;
|
|
33
|
+
if (resultTarget && options.stats) options.stats.resultTargetCount += 1;
|
|
34
|
+
if (!closestTarget) return writeCarRayMiss(resultTarget ?? {}, lengthMeters);
|
|
35
|
+
return writeCarRayResult(resultTarget ?? {}, car, closestTarget, closestDistance);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
export function createCarRayMiss(lengthMeters) {
|
|
40
|
-
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
return writeCarRayMiss({}, lengthMeters);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function writeCarRayMiss(target, lengthMeters) {
|
|
43
|
+
target.hit = false;
|
|
44
|
+
target.distanceMeters = lengthMeters;
|
|
45
|
+
target.driverId = null;
|
|
46
|
+
target.targetId = null;
|
|
47
|
+
target.targetType = null;
|
|
48
|
+
target.relativeSpeedKph = 0;
|
|
49
|
+
return target;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function writeCarRayResult(target, car, other, distanceSimUnits) {
|
|
53
|
+
target.hit = true;
|
|
54
|
+
target.distanceMeters = simUnitsToMeters(distanceSimUnits);
|
|
55
|
+
target.driverId = other.id;
|
|
56
|
+
target.targetId = other.id;
|
|
57
|
+
target.targetType = other.entityType;
|
|
58
|
+
target.relativeSpeedKph = other.speedKph - car.speedKph;
|
|
59
|
+
return target;
|
|
48
60
|
}
|
|
49
61
|
|
|
50
62
|
function carRayBroadphaseHit(origin, ray, maxDistance, other) {
|
|
@@ -58,18 +70,17 @@ function carRayBroadphaseHit(origin, ray, maxDistance, other) {
|
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
function intersectCarFootprint(origin, ray, other) {
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
73
|
+
const forwardX = Math.cos(other.heading);
|
|
74
|
+
const forwardY = Math.sin(other.heading);
|
|
75
|
+
const rightX = -forwardY;
|
|
76
|
+
const rightY = forwardX;
|
|
77
|
+
const deltaX = origin.x - other.x;
|
|
78
|
+
const deltaY = origin.y - other.y;
|
|
79
|
+
const localOriginX = deltaX * forwardX + deltaY * forwardY;
|
|
80
|
+
const localOriginY = deltaX * rightX + deltaY * rightY;
|
|
81
|
+
const localRayX = ray.x * forwardX + ray.y * forwardY;
|
|
82
|
+
const localRayY = ray.x * rightX + ray.y * rightY;
|
|
72
83
|
const halfLength = VEHICLE_GEOMETRY.bodyLength / 2;
|
|
73
84
|
const halfWidth = VEHICLE_GEOMETRY.bodyWidth / 2;
|
|
74
|
-
return
|
|
85
|
+
return intersectAxisAlignedBoxRayScalars(localOriginX, localOriginY, localRayX, localRayY, halfLength, halfWidth);
|
|
75
86
|
}
|