@horizon36596/zenith-core 0.1.1
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/LICENSE +21 -0
- package/NOTICE +18 -0
- package/README.md +16 -0
- package/dist/canonicalize.d.ts +25 -0
- package/dist/canonicalize.d.ts.map +1 -0
- package/dist/canonicalize.js +199 -0
- package/dist/canonicalize.js.map +1 -0
- package/dist/check.d.ts +26 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +231 -0
- package/dist/check.js.map +1 -0
- package/dist/checks/heading.d.ts +17 -0
- package/dist/checks/heading.d.ts.map +1 -0
- package/dist/checks/heading.js +78 -0
- package/dist/checks/heading.js.map +1 -0
- package/dist/checks/intake.d.ts +28 -0
- package/dist/checks/intake.d.ts.map +1 -0
- package/dist/checks/intake.js +131 -0
- package/dist/checks/intake.js.map +1 -0
- package/dist/checks/motion.d.ts +28 -0
- package/dist/checks/motion.d.ts.map +1 -0
- package/dist/checks/motion.js +252 -0
- package/dist/checks/motion.js.map +1 -0
- package/dist/checks/schedule.d.ts +29 -0
- package/dist/checks/schedule.d.ts.map +1 -0
- package/dist/checks/schedule.js +166 -0
- package/dist/checks/schedule.js.map +1 -0
- package/dist/checks/season.d.ts +6 -0
- package/dist/checks/season.d.ts.map +1 -0
- package/dist/checks/season.js +126 -0
- package/dist/checks/season.js.map +1 -0
- package/dist/continuity.d.ts +38 -0
- package/dist/continuity.d.ts.map +1 -0
- package/dist/continuity.js +69 -0
- package/dist/continuity.js.map +1 -0
- package/dist/diff.d.ts +37 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +258 -0
- package/dist/diff.js.map +1 -0
- package/dist/edit/command.d.ts +4 -0
- package/dist/edit/command.d.ts.map +1 -0
- package/dist/edit/command.js +16 -0
- package/dist/edit/command.js.map +1 -0
- package/dist/edit/errors.d.ts +9 -0
- package/dist/edit/errors.d.ts.map +1 -0
- package/dist/edit/errors.js +12 -0
- package/dist/edit/errors.js.map +1 -0
- package/dist/edit/fields.d.ts +40 -0
- package/dist/edit/fields.d.ts.map +1 -0
- package/dist/edit/fields.js +150 -0
- package/dist/edit/fields.js.map +1 -0
- package/dist/edit/finish.d.ts +15 -0
- package/dist/edit/finish.d.ts.map +1 -0
- package/dist/edit/finish.js +36 -0
- package/dist/edit/finish.js.map +1 -0
- package/dist/edit/groups.d.ts +66 -0
- package/dist/edit/groups.d.ts.map +1 -0
- package/dist/edit/groups.js +277 -0
- package/dist/edit/groups.js.map +1 -0
- package/dist/edit/ids.d.ts +39 -0
- package/dist/edit/ids.d.ts.map +1 -0
- package/dist/edit/ids.js +76 -0
- package/dist/edit/ids.js.map +1 -0
- package/dist/edit/index.d.ts +22 -0
- package/dist/edit/index.d.ts.map +1 -0
- package/dist/edit/index.js +22 -0
- package/dist/edit/index.js.map +1 -0
- package/dist/edit/meta.d.ts +15 -0
- package/dist/edit/meta.d.ts.map +1 -0
- package/dist/edit/meta.js +13 -0
- package/dist/edit/meta.js.map +1 -0
- package/dist/edit/path.d.ts +36 -0
- package/dist/edit/path.d.ts.map +1 -0
- package/dist/edit/path.js +135 -0
- package/dist/edit/path.js.map +1 -0
- package/dist/edit/steps.d.ts +53 -0
- package/dist/edit/steps.d.ts.map +1 -0
- package/dist/edit/steps.js +0 -0
- package/dist/edit/steps.js.map +1 -0
- package/dist/edit/template.d.ts +18 -0
- package/dist/edit/template.d.ts.map +1 -0
- package/dist/edit/template.js +30 -0
- package/dist/edit/template.js.map +1 -0
- package/dist/edit/timing.d.ts +11 -0
- package/dist/edit/timing.d.ts.map +1 -0
- package/dist/edit/timing.js +23 -0
- package/dist/edit/timing.js.map +1 -0
- package/dist/edit/tree.d.ts +32 -0
- package/dist/edit/tree.d.ts.map +1 -0
- package/dist/edit/tree.js +90 -0
- package/dist/edit/tree.js.map +1 -0
- package/dist/estimate.d.ts +48 -0
- package/dist/estimate.d.ts.map +1 -0
- package/dist/estimate.js +443 -0
- package/dist/estimate.js.map +1 -0
- package/dist/findingHelp.d.ts +18 -0
- package/dist/findingHelp.d.ts.map +1 -0
- package/dist/findingHelp.js +114 -0
- package/dist/findingHelp.js.map +1 -0
- package/dist/fix.d.ts +21 -0
- package/dist/fix.d.ts.map +1 -0
- package/dist/fix.js +180 -0
- package/dist/fix.js.map +1 -0
- package/dist/footprint.d.ts +33 -0
- package/dist/footprint.d.ts.map +1 -0
- package/dist/footprint.js +71 -0
- package/dist/footprint.js.map +1 -0
- package/dist/geometry/angle.d.ts +13 -0
- package/dist/geometry/angle.d.ts.map +1 -0
- package/dist/geometry/angle.js +21 -0
- package/dist/geometry/angle.js.map +1 -0
- package/dist/geometry/curve.d.ts +24 -0
- package/dist/geometry/curve.d.ts.map +1 -0
- package/dist/geometry/curve.js +78 -0
- package/dist/geometry/curve.js.map +1 -0
- package/dist/geometry/path.d.ts +29 -0
- package/dist/geometry/path.d.ts.map +1 -0
- package/dist/geometry/path.js +61 -0
- package/dist/geometry/path.js.map +1 -0
- package/dist/geometry/quadrature.d.ts +13 -0
- package/dist/geometry/quadrature.d.ts.map +1 -0
- package/dist/geometry/quadrature.js +57 -0
- package/dist/geometry/quadrature.js.map +1 -0
- package/dist/geometry/sat.d.ts +40 -0
- package/dist/geometry/sat.d.ts.map +1 -0
- package/dist/geometry/sat.js +86 -0
- package/dist/geometry/sat.js.map +1 -0
- package/dist/geometry/vec.d.ts +27 -0
- package/dist/geometry/vec.d.ts.map +1 -0
- package/dist/geometry/vec.js +30 -0
- package/dist/geometry/vec.js.map +1 -0
- package/dist/heading.d.ts +77 -0
- package/dist/heading.d.ts.map +1 -0
- package/dist/heading.js +164 -0
- package/dist/heading.js.map +1 -0
- package/dist/headingRanges.d.ts +48 -0
- package/dist/headingRanges.d.ts.map +1 -0
- package/dist/headingRanges.js +132 -0
- package/dist/headingRanges.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/kinematics.d.ts +63 -0
- package/dist/kinematics.d.ts.map +1 -0
- package/dist/kinematics.js +71 -0
- package/dist/kinematics.js.map +1 -0
- package/dist/ledger.d.ts +49 -0
- package/dist/ledger.d.ts.map +1 -0
- package/dist/ledger.js +136 -0
- package/dist/ledger.js.map +1 -0
- package/dist/load.d.ts +12 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +12 -0
- package/dist/load.js.map +1 -0
- package/dist/mirror.d.ts +81 -0
- package/dist/mirror.d.ts.map +1 -0
- package/dist/mirror.js +282 -0
- package/dist/mirror.js.map +1 -0
- package/dist/plan.d.ts +29 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +159 -0
- package/dist/plan.js.map +1 -0
- package/dist/prBody.d.ts +24 -0
- package/dist/prBody.d.ts.map +1 -0
- package/dist/prBody.js +112 -0
- package/dist/prBody.js.map +1 -0
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +46 -0
- package/dist/provenance.js.map +1 -0
- package/dist/render.d.ts +18 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +464 -0
- package/dist/render.js.map +1 -0
- package/dist/resolve.d.ts +39 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +172 -0
- package/dist/resolve.js.map +1 -0
- package/dist/season.d.ts +65 -0
- package/dist/season.d.ts.map +1 -0
- package/dist/season.js +16 -0
- package/dist/season.js.map +1 -0
- package/dist/sim/commands.d.ts +97 -0
- package/dist/sim/commands.d.ts.map +1 -0
- package/dist/sim/commands.js +185 -0
- package/dist/sim/commands.js.map +1 -0
- package/dist/sim/curves.d.ts +37 -0
- package/dist/sim/curves.d.ts.map +1 -0
- package/dist/sim/curves.js +187 -0
- package/dist/sim/curves.js.map +1 -0
- package/dist/sim/follower.d.ts +124 -0
- package/dist/sim/follower.d.ts.map +1 -0
- package/dist/sim/follower.js +472 -0
- package/dist/sim/follower.js.map +1 -0
- package/dist/sim/ideal.d.ts +103 -0
- package/dist/sim/ideal.d.ts.map +1 -0
- package/dist/sim/ideal.js +393 -0
- package/dist/sim/ideal.js.map +1 -0
- package/dist/sim/index.d.ts +11 -0
- package/dist/sim/index.d.ts.map +1 -0
- package/dist/sim/index.js +10 -0
- package/dist/sim/index.js.map +1 -0
- package/dist/sim/params.d.ts +91 -0
- package/dist/sim/params.d.ts.map +1 -0
- package/dist/sim/params.js +195 -0
- package/dist/sim/params.js.map +1 -0
- package/dist/sim/pedroPath.d.ts +41 -0
- package/dist/sim/pedroPath.d.ts.map +1 -0
- package/dist/sim/pedroPath.js +191 -0
- package/dist/sim/pedroPath.js.map +1 -0
- package/dist/sim/plant.d.ts +59 -0
- package/dist/sim/plant.d.ts.map +1 -0
- package/dist/sim/plant.js +128 -0
- package/dist/sim/plant.js.map +1 -0
- package/dist/sim/residuals.d.ts +36 -0
- package/dist/sim/residuals.d.ts.map +1 -0
- package/dist/sim/residuals.js +86 -0
- package/dist/sim/residuals.js.map +1 -0
- package/dist/sim/simulate.d.ts +27 -0
- package/dist/sim/simulate.d.ts.map +1 -0
- package/dist/sim/simulate.js +924 -0
- package/dist/sim/simulate.js.map +1 -0
- package/dist/sim/types.d.ts +209 -0
- package/dist/sim/types.d.ts.map +1 -0
- package/dist/sim/types.js +2 -0
- package/dist/sim/types.js.map +1 -0
- package/dist/tokens.d.ts +93 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +93 -0
- package/dist/tokens.js.map +1 -0
- package/dist/trace.d.ts +89 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +187 -0
- package/dist/trace.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/unimplemented.d.ts +8 -0
- package/dist/unimplemented.d.ts.map +1 -0
- package/dist/unimplemented.js +11 -0
- package/dist/unimplemented.js.map +1 -0
- package/package.json +59 -0
package/dist/resolve.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { childLists } from "@horizon36596/zenith-schema";
|
|
2
|
+
import { childPrefix, effectiveId } from "./edit/ids.js";
|
|
3
|
+
import { wrapAngle } from "./geometry/angle.js";
|
|
4
|
+
import { makePath } from "./geometry/path.js";
|
|
5
|
+
import { headingFunction } from "./heading.js";
|
|
6
|
+
const ORIGIN = { xIn: 0, yIn: 0, headingRad: 0 };
|
|
7
|
+
/** Resolves waypoint references to poses and `"current"` to the previous step's end pose. */
|
|
8
|
+
export function resolve(auto, waypoints) {
|
|
9
|
+
const findings = [];
|
|
10
|
+
const named = waypoints?.waypoints ?? {};
|
|
11
|
+
const resolvePose = (source, stepId, current, fallbackHeadingRad) => {
|
|
12
|
+
if (source === "current") {
|
|
13
|
+
if (current === null) {
|
|
14
|
+
findings.push({
|
|
15
|
+
severity: "error",
|
|
16
|
+
stepId,
|
|
17
|
+
code: "CONTINUITY",
|
|
18
|
+
message: 'from: "current" needs a previous step that defines where the robot ended.',
|
|
19
|
+
});
|
|
20
|
+
return { ...ORIGIN, headingRad: fallbackHeadingRad };
|
|
21
|
+
}
|
|
22
|
+
return current;
|
|
23
|
+
}
|
|
24
|
+
if ("ref" in source) {
|
|
25
|
+
const waypoint = named[source.ref];
|
|
26
|
+
if (waypoint === undefined) {
|
|
27
|
+
findings.push({
|
|
28
|
+
severity: "error",
|
|
29
|
+
stepId,
|
|
30
|
+
code: "SCHEMA",
|
|
31
|
+
message: `No waypoint named ${JSON.stringify(source.ref)} in waypoints.json.`,
|
|
32
|
+
});
|
|
33
|
+
return { ...(current ?? ORIGIN), headingRad: fallbackHeadingRad };
|
|
34
|
+
}
|
|
35
|
+
return { xIn: waypoint.xIn, yIn: waypoint.yIn, headingRad: waypoint.headingRad };
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
xIn: source.xIn,
|
|
39
|
+
yIn: source.yIn,
|
|
40
|
+
headingRad: source.headingRad ?? fallbackHeadingRad,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const startId = "start";
|
|
44
|
+
const start = auto.start.pose;
|
|
45
|
+
let startPose;
|
|
46
|
+
if ("ref" in start) {
|
|
47
|
+
startPose = resolvePose(start, startId, null, 0);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (start.headingRad === undefined) {
|
|
51
|
+
findings.push({
|
|
52
|
+
severity: "error",
|
|
53
|
+
stepId: startId,
|
|
54
|
+
code: "SCHEMA",
|
|
55
|
+
message: "The start pose needs a headingRad: nothing else can supply the robot's heading.",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
startPose = { xIn: start.xIn, yIn: start.yIn, headingRad: start.headingRad ?? 0 };
|
|
59
|
+
}
|
|
60
|
+
// `together` is set for the members of a parallel group: they all run at once, so every one of
|
|
61
|
+
// them starts where the group started (`"current"` included), not where the member written
|
|
62
|
+
// before it ends. This is the same rule the CONTINUITY check applies.
|
|
63
|
+
const resolveSteps = (steps, prefix, entry, together = false) => {
|
|
64
|
+
const resolved = [];
|
|
65
|
+
let current = entry;
|
|
66
|
+
for (const [index, step] of steps.entries()) {
|
|
67
|
+
if (together)
|
|
68
|
+
current = entry;
|
|
69
|
+
const id = effectiveId(step, index, prefix);
|
|
70
|
+
const startOfStep = current;
|
|
71
|
+
if (step.kind === "path") {
|
|
72
|
+
const segments = [];
|
|
73
|
+
let cursor = current;
|
|
74
|
+
for (const segment of step.segments) {
|
|
75
|
+
const fromPose = resolvePose(segment.from, id, cursor, cursor.headingRad);
|
|
76
|
+
const toPose = resolvePose(segment.to, id, fromPose, fromPose.headingRad);
|
|
77
|
+
const controls = segment.kind === "bezier"
|
|
78
|
+
? segment.control.map((point) => ({ xIn: point.xIn, yIn: point.yIn }))
|
|
79
|
+
: [];
|
|
80
|
+
segments.push({
|
|
81
|
+
kind: segment.kind,
|
|
82
|
+
pointsIn: [
|
|
83
|
+
{ xIn: fromPose.xIn, yIn: fromPose.yIn },
|
|
84
|
+
...controls,
|
|
85
|
+
{ xIn: toPose.xIn, yIn: toPose.yIn },
|
|
86
|
+
],
|
|
87
|
+
fromPose,
|
|
88
|
+
toPose,
|
|
89
|
+
});
|
|
90
|
+
cursor = toPose;
|
|
91
|
+
}
|
|
92
|
+
const endPose = headingForEnd(step, segments, cursor);
|
|
93
|
+
resolved.push({ id, kind: step.kind, step, startPose: startOfStep, endPose, segments });
|
|
94
|
+
current = endPose;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (step.kind === "sequence") {
|
|
98
|
+
// A sequence chains its members exactly like the top level: each starts where the one
|
|
99
|
+
// before it ended, and the group ends where its last member does.
|
|
100
|
+
const children = resolveSteps(step.steps, childPrefix(id, 1, 0), current);
|
|
101
|
+
const endPose = children[children.length - 1]?.endPose ?? current;
|
|
102
|
+
resolved.push({ id, kind: step.kind, step, startPose: startOfStep, endPose, children });
|
|
103
|
+
current = endPose;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (step.kind === "parallel" || step.kind === "branch") {
|
|
107
|
+
const branches = childLists(step);
|
|
108
|
+
const children = [];
|
|
109
|
+
let endPose = current;
|
|
110
|
+
for (const [branchIndex, branch] of branches.entries()) {
|
|
111
|
+
const branchSteps = resolveSteps(branch, childPrefix(id, branches.length, branchIndex), current, step.kind === "parallel");
|
|
112
|
+
children.push(...branchSteps);
|
|
113
|
+
if (step.kind === "parallel") {
|
|
114
|
+
const deadline = step.deadline === undefined
|
|
115
|
+
? undefined
|
|
116
|
+
: branchSteps.find((child) => child.id === step.deadline);
|
|
117
|
+
// The member that decides where the group ends is its deadline, or else the last
|
|
118
|
+
// member that drives: a path, or a sequence or group with a path inside it.
|
|
119
|
+
const mover = deadline ?? [...branchSteps].reverse().find(containsPath);
|
|
120
|
+
if (mover !== undefined)
|
|
121
|
+
endPose = mover.endPose;
|
|
122
|
+
}
|
|
123
|
+
else if (branchIndex === 0) {
|
|
124
|
+
const last = branchSteps[branchSteps.length - 1];
|
|
125
|
+
if (last !== undefined)
|
|
126
|
+
endPose = last.endPose;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
resolved.push({ id, kind: step.kind, step, startPose: startOfStep, endPose, children });
|
|
130
|
+
current = endPose;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
resolved.push({ id, kind: step.kind, step, startPose: startOfStep, endPose: current });
|
|
134
|
+
}
|
|
135
|
+
return resolved;
|
|
136
|
+
};
|
|
137
|
+
return { auto, startPose, steps: resolveSteps(auto.steps, "step", startPose), findings };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* True for a path step, or a group with a path step somewhere inside it: the members of a parallel
|
|
141
|
+
* group that can decide where the robot ends up, and the ones whose exit speed carries on.
|
|
142
|
+
*/
|
|
143
|
+
export function containsPath(step) {
|
|
144
|
+
if (step.kind === "path")
|
|
145
|
+
return true;
|
|
146
|
+
return (step.children ?? []).some(containsPath);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The heading the robot holds at the end of a path step: the mode's own h(1), evaluated over the
|
|
150
|
+
* geometry the step resolved to, which is exactly what `plan` samples at the last point.
|
|
151
|
+
*
|
|
152
|
+
* `tangent`, `tangentReversed` and `facePoint` need the geometry to answer, so this takes the
|
|
153
|
+
* resolved segments rather than trusting the `to` pose's `headingRad`: that pose only says where
|
|
154
|
+
* the robot stops, and a mode that computes the heading overrides whatever it carries. Without
|
|
155
|
+
* this, `resolve` and `plan` disagree about where the next step starts and every stationary step
|
|
156
|
+
* after a path is checked at a heading the robot never holds.
|
|
157
|
+
*
|
|
158
|
+
* With no mode declared the step keeps the heading it arrives with; `plan` raises HEADING_MISSING.
|
|
159
|
+
*/
|
|
160
|
+
function headingForEnd(step, segments, end) {
|
|
161
|
+
const heading = step.heading;
|
|
162
|
+
if (heading === undefined)
|
|
163
|
+
return end;
|
|
164
|
+
if (heading.mode === "constant")
|
|
165
|
+
return { ...end, headingRad: wrapAngle(heading.headingRad) };
|
|
166
|
+
if (segments.length === 0) {
|
|
167
|
+
return heading.mode === "linear" ? { ...end, headingRad: wrapAngle(heading.toRad) } : end;
|
|
168
|
+
}
|
|
169
|
+
const geometry = makePath(segments.map((segment) => segment.pointsIn));
|
|
170
|
+
return { ...end, headingRad: headingFunction(heading, geometry)(1) };
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/season.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Field, Robot } from "@horizon36596/zenith-schema";
|
|
2
|
+
import type { Pose, Vec2 } from "./geometry/vec.js";
|
|
3
|
+
import type { Finding, LedgerRow } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Whatever the season plugin wants to remember between steps. The core never looks inside it: it
|
|
6
|
+
* only threads it through the ledger (site/docs/seasons.md).
|
|
7
|
+
*/
|
|
8
|
+
export type SeasonState = Readonly<Record<string, unknown>>;
|
|
9
|
+
export type TargetId = string;
|
|
10
|
+
/** The plugin interface of site/docs/seasons.md. `season-biobuzz` implements it in M1. */
|
|
11
|
+
export interface SeasonRules {
|
|
12
|
+
/** The `rules.plugin` name in `field.json` that selects this implementation. */
|
|
13
|
+
readonly id: string;
|
|
14
|
+
initialState(field: Field): SeasonState;
|
|
15
|
+
onLaunch(state: SeasonState, target: TargetId, count: number, pose: Pose): SeasonState;
|
|
16
|
+
onCollect(state: SeasonState, containerId: string, count: number): SeasonState;
|
|
17
|
+
currentTarget(state: SeasonState, alliance: "RED" | "BLUE"): TargetId | null;
|
|
18
|
+
legalApproach(state: SeasonState, target: TargetId, pose: Pose, robot: Robot): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The start rules, for a start pose in the frame of `alliance`, the file's own alliance.
|
|
21
|
+
* `field.json`'s `startRules` are written for `field.frame.canonicalAlliance`; a plugin reads them
|
|
22
|
+
* for the other alliance through its own counterparts (its own half, its own loading zone).
|
|
23
|
+
* `alliance` is optional so a plugin written before it existed still type-checks; left out, it
|
|
24
|
+
* means the canonical alliance.
|
|
25
|
+
*/
|
|
26
|
+
startLegal(field: Field, pose: Pose, robot: Robot, alliance?: "RED" | "BLUE"): Finding[];
|
|
27
|
+
summary(state: SeasonState): LedgerRow[];
|
|
28
|
+
/**
|
|
29
|
+
* Optional, and the one addition to the interface as `03` section 6 draws it: the auto says what
|
|
30
|
+
* the robot starts holding (`start.holds`), and the ledger has to get that into the state before
|
|
31
|
+
* the first step runs. A plugin that tracks nothing can leave it out.
|
|
32
|
+
*/
|
|
33
|
+
start?(state: SeasonState, holds: Readonly<Record<string, number>>): SeasonState;
|
|
34
|
+
/** Optional: what the robot is holding now, which the CAPACITY and EMPTY_SHOT checks read. */
|
|
35
|
+
holds?(state: SeasonState): Record<string, number>;
|
|
36
|
+
/**
|
|
37
|
+
* Optional: the author asserting a tip happened, from a command whose registry entry carries
|
|
38
|
+
* `ledger: { tip: "own" }` or from a step's `expect.tip`. It is trusted over whatever the
|
|
39
|
+
* plugin's own model of the season predicted.
|
|
40
|
+
*/
|
|
41
|
+
onTip?(state: SeasonState, which: "own" | "opponent", alliance: "RED" | "BLUE"): SeasonState;
|
|
42
|
+
/** Optional: where on the field a target sits, so TURRET_RANGE can work out the bearing to it. */
|
|
43
|
+
targetPoint?(state: SeasonState, target: TargetId): Vec2 | null;
|
|
44
|
+
/**
|
|
45
|
+
* Optional: the closest pose to this one that `legalApproach` would accept, so LEGAL_APPROACH can
|
|
46
|
+
* offer a "move to legal approach" fix with real coordinates rather than a shrug.
|
|
47
|
+
*/
|
|
48
|
+
nearestLegalApproach?(state: SeasonState, target: TargetId, pose: Pose, robot: Robot): Pose | null;
|
|
49
|
+
/** Optional: a one-line description of what a step did to the state, for the ledger's rows. */
|
|
50
|
+
describe?(before: SeasonState, after: SeasonState): string | null;
|
|
51
|
+
/**
|
|
52
|
+
* Optional: the other alliance's name for a field id, so a mirrored routine expects the hive and
|
|
53
|
+
* the flowers it will actually be in front of. `mirrorAuto` asks this about every id a step's
|
|
54
|
+
* `expect` names; returning `null` means the id has no counterpart and the routine cannot be
|
|
55
|
+
* mirrored, which is refused rather than silently kept.
|
|
56
|
+
*/
|
|
57
|
+
mirrorId?(id: string): string | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The rules used when no season plugin is loaded: nothing is illegal, nothing is tracked. M0's
|
|
61
|
+
* START_ILLEGAL check goes through `startLegal`, so a season package can add the real rule without
|
|
62
|
+
* the core learning anything about the game.
|
|
63
|
+
*/
|
|
64
|
+
export declare const noSeasonRules: SeasonRules;
|
|
65
|
+
//# sourceMappingURL=season.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"season.d.ts","sourceRoot":"","sources":["../src/season.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAErD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,0FAA0F;AAC1F,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACvF,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/E,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC7E,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IACvF;;;;;;OAMG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC;IACzF,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,EAAE,CAAC;IAEzC;;;;OAIG;IACH,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,WAAW,CAAC;IAEjF,8FAA8F;IAC9F,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnD;;;;OAIG;IACH,KAAK,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;IAE7F,kGAAkG;IAClG,WAAW,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;IAEhE;;;OAGG;IACH,oBAAoB,CAAC,CACnB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,GACX,IAAI,GAAG,IAAI,CAAC;IAEf,+FAA+F;IAC/F,QAAQ,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAAC;IAElE;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACtC;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAS3B,CAAC"}
|
package/dist/season.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rules used when no season plugin is loaded: nothing is illegal, nothing is tracked. M0's
|
|
3
|
+
* START_ILLEGAL check goes through `startLegal`, so a season package can add the real rule without
|
|
4
|
+
* the core learning anything about the game.
|
|
5
|
+
*/
|
|
6
|
+
export const noSeasonRules = {
|
|
7
|
+
id: "none",
|
|
8
|
+
initialState: () => ({}),
|
|
9
|
+
onLaunch: (state) => state,
|
|
10
|
+
onCollect: (state) => state,
|
|
11
|
+
currentTarget: () => null,
|
|
12
|
+
legalApproach: () => true,
|
|
13
|
+
startLegal: () => [],
|
|
14
|
+
summary: () => [],
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=season.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"season.js","sourceRoot":"","sources":["../src/season.ts"],"names":[],"mappings":"AA0EA;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,EAAE,EAAE,MAAM;IACV,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IAC1B,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;IAC3B,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI;IACzB,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI;IACzB,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE;IACpB,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;CAClB,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The command tree the runtime builds from an auto file (`robot/auto-runtime/AutoBuilder.java`),
|
|
3
|
+
* reduced to what decides timing: SolversLib's `SequentialCommandGroup`, `ParallelCommandGroup`,
|
|
4
|
+
* `ParallelRaceGroup`, `ParallelDeadlineGroup` and `ConditionalCommand`, the runtime's `AutoStep`,
|
|
5
|
+
* `RobotTimeout`, `WaitRobotTime`, `FollowPath` and `PathMarkers`, and Pedro's follower underneath.
|
|
6
|
+
*
|
|
7
|
+
* The life cycle is the scheduler's: `initialize` once, then each tick `execute` and a look at
|
|
8
|
+
* `isFinished`, then `end(interrupted)`. A group initialises its next member in the same pass that
|
|
9
|
+
* ends the one before, so a member starts on the tick its predecessor ends, and every member,
|
|
10
|
+
* however short, is running for at least one tick.
|
|
11
|
+
*/
|
|
12
|
+
export interface SimCommand {
|
|
13
|
+
initialize(): void;
|
|
14
|
+
execute(): void;
|
|
15
|
+
/** Must give the same answer when asked twice in one pass: groups ask again in `end`. */
|
|
16
|
+
isFinished(): boolean;
|
|
17
|
+
end(interrupted: boolean): void;
|
|
18
|
+
}
|
|
19
|
+
/** The clock the commands read, in whole ticks so a duration compares exactly. */
|
|
20
|
+
export interface SimClock {
|
|
21
|
+
readonly tick: number;
|
|
22
|
+
readonly tickS: number;
|
|
23
|
+
}
|
|
24
|
+
/** Seconds from `startTick` to now, compared the way `WaitRobotTime` compares nanoseconds. */
|
|
25
|
+
export declare const elapsedAtLeast: (clock: SimClock, startTick: number, seconds: number) => boolean;
|
|
26
|
+
/** `WaitRobotTime`, and a named command timed by its `estimateS`. Null seconds waits forever. */
|
|
27
|
+
export declare class TimedCommand implements SimCommand {
|
|
28
|
+
private readonly clock;
|
|
29
|
+
private readonly seconds;
|
|
30
|
+
private startTick;
|
|
31
|
+
constructor(clock: SimClock, seconds: number | null);
|
|
32
|
+
initialize(): void;
|
|
33
|
+
execute(): void;
|
|
34
|
+
isFinished(): boolean;
|
|
35
|
+
end(): void;
|
|
36
|
+
}
|
|
37
|
+
/** `InstantCommand`: finishes on its first look. */
|
|
38
|
+
export declare class InstantCommand implements SimCommand {
|
|
39
|
+
initialize(): void;
|
|
40
|
+
execute(): void;
|
|
41
|
+
isFinished(): boolean;
|
|
42
|
+
end(): void;
|
|
43
|
+
}
|
|
44
|
+
/** `SequentialCommandGroup`. */
|
|
45
|
+
export declare class SequenceCommand implements SimCommand {
|
|
46
|
+
private readonly members;
|
|
47
|
+
private index;
|
|
48
|
+
constructor(members: readonly SimCommand[]);
|
|
49
|
+
initialize(): void;
|
|
50
|
+
execute(): void;
|
|
51
|
+
isFinished(): boolean;
|
|
52
|
+
end(interrupted: boolean): void;
|
|
53
|
+
}
|
|
54
|
+
/** `ParallelCommandGroup`: ends when every member has. */
|
|
55
|
+
export declare class ParallelAllCommand implements SimCommand {
|
|
56
|
+
private readonly members;
|
|
57
|
+
private running;
|
|
58
|
+
constructor(members: readonly SimCommand[]);
|
|
59
|
+
initialize(): void;
|
|
60
|
+
execute(): void;
|
|
61
|
+
isFinished(): boolean;
|
|
62
|
+
end(interrupted: boolean): void;
|
|
63
|
+
}
|
|
64
|
+
/** `ParallelRaceGroup`: ends when the first member does; the rest end interrupted. */
|
|
65
|
+
export declare class RaceCommand implements SimCommand {
|
|
66
|
+
readonly members: readonly SimCommand[];
|
|
67
|
+
private finished;
|
|
68
|
+
constructor(members: readonly SimCommand[]);
|
|
69
|
+
initialize(): void;
|
|
70
|
+
execute(): void;
|
|
71
|
+
isFinished(): boolean;
|
|
72
|
+
end(): void;
|
|
73
|
+
}
|
|
74
|
+
/** `ParallelDeadlineGroup`: ends when the deadline does; whatever is still running is interrupted. */
|
|
75
|
+
export declare class DeadlineCommand implements SimCommand {
|
|
76
|
+
private running;
|
|
77
|
+
private finished;
|
|
78
|
+
private readonly members;
|
|
79
|
+
constructor(deadline: SimCommand, others: readonly SimCommand[]);
|
|
80
|
+
initialize(): void;
|
|
81
|
+
execute(): void;
|
|
82
|
+
isFinished(): boolean;
|
|
83
|
+
end(): void;
|
|
84
|
+
}
|
|
85
|
+
/** `ConditionalCommand`: picks a side as it starts and is that side from then on. */
|
|
86
|
+
export declare class ConditionalCommand implements SimCommand {
|
|
87
|
+
private readonly condition;
|
|
88
|
+
private readonly onTrue;
|
|
89
|
+
private readonly onFalse;
|
|
90
|
+
private selected;
|
|
91
|
+
constructor(condition: () => boolean, onTrue: SimCommand, onFalse: SimCommand);
|
|
92
|
+
initialize(): void;
|
|
93
|
+
execute(): void;
|
|
94
|
+
isFinished(): boolean;
|
|
95
|
+
end(interrupted: boolean): void;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/sim/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** Seconds from `startTick` to now, compared the way `WaitRobotTime` compares nanoseconds. */
|
|
2
|
+
export const elapsedAtLeast = (clock, startTick, seconds) => (clock.tick - startTick) * clock.tickS >= seconds - 1e-9;
|
|
3
|
+
/** `WaitRobotTime`, and a named command timed by its `estimateS`. Null seconds waits forever. */
|
|
4
|
+
export class TimedCommand {
|
|
5
|
+
clock;
|
|
6
|
+
seconds;
|
|
7
|
+
startTick = 0;
|
|
8
|
+
constructor(clock, seconds) {
|
|
9
|
+
this.clock = clock;
|
|
10
|
+
this.seconds = seconds;
|
|
11
|
+
}
|
|
12
|
+
initialize() {
|
|
13
|
+
this.startTick = this.clock.tick;
|
|
14
|
+
}
|
|
15
|
+
execute() { }
|
|
16
|
+
isFinished() {
|
|
17
|
+
return this.seconds !== null && elapsedAtLeast(this.clock, this.startTick, this.seconds);
|
|
18
|
+
}
|
|
19
|
+
end() { }
|
|
20
|
+
}
|
|
21
|
+
/** `InstantCommand`: finishes on its first look. */
|
|
22
|
+
export class InstantCommand {
|
|
23
|
+
initialize() { }
|
|
24
|
+
execute() { }
|
|
25
|
+
isFinished() {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
end() { }
|
|
29
|
+
}
|
|
30
|
+
/** `SequentialCommandGroup`. */
|
|
31
|
+
export class SequenceCommand {
|
|
32
|
+
members;
|
|
33
|
+
index = 0;
|
|
34
|
+
constructor(members) {
|
|
35
|
+
this.members = members;
|
|
36
|
+
}
|
|
37
|
+
initialize() {
|
|
38
|
+
this.index = 0;
|
|
39
|
+
this.members[0]?.initialize();
|
|
40
|
+
}
|
|
41
|
+
execute() {
|
|
42
|
+
const current = this.members[this.index];
|
|
43
|
+
if (current === undefined)
|
|
44
|
+
return;
|
|
45
|
+
current.execute();
|
|
46
|
+
if (current.isFinished()) {
|
|
47
|
+
current.end(false);
|
|
48
|
+
this.index += 1;
|
|
49
|
+
this.members[this.index]?.initialize();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
isFinished() {
|
|
53
|
+
return this.index >= this.members.length;
|
|
54
|
+
}
|
|
55
|
+
end(interrupted) {
|
|
56
|
+
if (interrupted)
|
|
57
|
+
this.members[this.index]?.end(true);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** `ParallelCommandGroup`: ends when every member has. */
|
|
61
|
+
export class ParallelAllCommand {
|
|
62
|
+
members;
|
|
63
|
+
running = [];
|
|
64
|
+
constructor(members) {
|
|
65
|
+
this.members = members;
|
|
66
|
+
}
|
|
67
|
+
initialize() {
|
|
68
|
+
this.running = this.members.map(() => true);
|
|
69
|
+
for (const member of this.members)
|
|
70
|
+
member.initialize();
|
|
71
|
+
}
|
|
72
|
+
execute() {
|
|
73
|
+
this.members.forEach((member, index) => {
|
|
74
|
+
if (!this.running[index])
|
|
75
|
+
return;
|
|
76
|
+
member.execute();
|
|
77
|
+
if (member.isFinished()) {
|
|
78
|
+
member.end(false);
|
|
79
|
+
this.running[index] = false;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
isFinished() {
|
|
84
|
+
return !this.running.some(Boolean);
|
|
85
|
+
}
|
|
86
|
+
end(interrupted) {
|
|
87
|
+
if (!interrupted)
|
|
88
|
+
return;
|
|
89
|
+
this.members.forEach((member, index) => {
|
|
90
|
+
if (this.running[index])
|
|
91
|
+
member.end(true);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** `ParallelRaceGroup`: ends when the first member does; the rest end interrupted. */
|
|
96
|
+
export class RaceCommand {
|
|
97
|
+
members;
|
|
98
|
+
finished = false;
|
|
99
|
+
constructor(members) {
|
|
100
|
+
this.members = members;
|
|
101
|
+
}
|
|
102
|
+
initialize() {
|
|
103
|
+
this.finished = false;
|
|
104
|
+
for (const member of this.members)
|
|
105
|
+
member.initialize();
|
|
106
|
+
}
|
|
107
|
+
execute() {
|
|
108
|
+
for (const member of this.members) {
|
|
109
|
+
member.execute();
|
|
110
|
+
if (member.isFinished())
|
|
111
|
+
this.finished = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
isFinished() {
|
|
115
|
+
return this.finished;
|
|
116
|
+
}
|
|
117
|
+
end() {
|
|
118
|
+
for (const member of this.members)
|
|
119
|
+
member.end(!member.isFinished());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** `ParallelDeadlineGroup`: ends when the deadline does; whatever is still running is interrupted. */
|
|
123
|
+
export class DeadlineCommand {
|
|
124
|
+
running = [];
|
|
125
|
+
finished = false;
|
|
126
|
+
members;
|
|
127
|
+
constructor(deadline, others) {
|
|
128
|
+
this.members = [deadline, ...others];
|
|
129
|
+
}
|
|
130
|
+
initialize() {
|
|
131
|
+
this.finished = false;
|
|
132
|
+
this.running = this.members.map(() => true);
|
|
133
|
+
for (const member of this.members)
|
|
134
|
+
member.initialize();
|
|
135
|
+
}
|
|
136
|
+
execute() {
|
|
137
|
+
this.members.forEach((member, index) => {
|
|
138
|
+
if (!this.running[index])
|
|
139
|
+
return;
|
|
140
|
+
member.execute();
|
|
141
|
+
if (member.isFinished()) {
|
|
142
|
+
member.end(false);
|
|
143
|
+
this.running[index] = false;
|
|
144
|
+
if (index === 0)
|
|
145
|
+
this.finished = true;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
isFinished() {
|
|
150
|
+
return this.finished;
|
|
151
|
+
}
|
|
152
|
+
end() {
|
|
153
|
+
this.members.forEach((member, index) => {
|
|
154
|
+
if (this.running[index])
|
|
155
|
+
member.end(true);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** `ConditionalCommand`: picks a side as it starts and is that side from then on. */
|
|
160
|
+
export class ConditionalCommand {
|
|
161
|
+
condition;
|
|
162
|
+
onTrue;
|
|
163
|
+
onFalse;
|
|
164
|
+
selected;
|
|
165
|
+
constructor(condition, onTrue, onFalse) {
|
|
166
|
+
this.condition = condition;
|
|
167
|
+
this.onTrue = onTrue;
|
|
168
|
+
this.onFalse = onFalse;
|
|
169
|
+
this.selected = onTrue;
|
|
170
|
+
}
|
|
171
|
+
initialize() {
|
|
172
|
+
this.selected = this.condition() ? this.onTrue : this.onFalse;
|
|
173
|
+
this.selected.initialize();
|
|
174
|
+
}
|
|
175
|
+
execute() {
|
|
176
|
+
this.selected.execute();
|
|
177
|
+
}
|
|
178
|
+
isFinished() {
|
|
179
|
+
return this.selected.isFinished();
|
|
180
|
+
}
|
|
181
|
+
end(interrupted) {
|
|
182
|
+
this.selected.end(interrupted);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/sim/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pedro Pathing v3's two curve kinds, as the follower sees them: `paths/curves/Line.java` and
|
|
3
|
+
* `paths/curves/bezier/BezierCurve.java` in core-3.0.0-20260828.185437-17. The closest-point search
|
|
4
|
+
* is Pedro's own (a coarse grid, then Newton on the squared distance), because where the follower
|
|
5
|
+
* thinks it is on the path decides everything it does next, and a better search would be a
|
|
6
|
+
* different follower.
|
|
7
|
+
*
|
|
8
|
+
* Written for speed, since the follower calls these several times a tick: the Bezier is kept in
|
|
9
|
+
* power-basis coefficients (Pedro caches the same product of its characteristic matrix and control
|
|
10
|
+
* points) and evaluated by Horner's rule.
|
|
11
|
+
*/
|
|
12
|
+
export interface XY {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}
|
|
16
|
+
/** `PathBuilder.SAMPLES_PER_SEGMENT`: the runtime's own segment lengths, which markers use. */
|
|
17
|
+
export declare const RUNTIME_LENGTH_SAMPLES = 64;
|
|
18
|
+
export interface SimCurve {
|
|
19
|
+
readonly start: XY;
|
|
20
|
+
readonly end: XY;
|
|
21
|
+
/** Pedro's `length()`. */
|
|
22
|
+
readonly lengthIn: number;
|
|
23
|
+
/** The length `PathBuilder.arcLengthIn` gives the runtime, by 64 chords. */
|
|
24
|
+
readonly runtimeLengthIn: number;
|
|
25
|
+
get(t: number): XY;
|
|
26
|
+
derivative(t: number): XY;
|
|
27
|
+
/** Unit tangent. Pedro throws on a zero derivative; this falls back to the chord. */
|
|
28
|
+
tangent(t: number): XY;
|
|
29
|
+
closestT(x: number, y: number, initialGuess: number): number;
|
|
30
|
+
remainingDistance(t: number): number;
|
|
31
|
+
}
|
|
32
|
+
export declare function makeLine(start: XY, end: XY): SimCurve;
|
|
33
|
+
/** A Bezier of any degree from its control polygon, start and end included. */
|
|
34
|
+
export declare function makeBezier(points: readonly XY[]): SimCurve;
|
|
35
|
+
/** A line for two points, a Bezier for three or more, the way `PathBuilder.geometry` chooses. */
|
|
36
|
+
export declare function makeSimCurve(points: readonly XY[]): SimCurve;
|
|
37
|
+
//# sourceMappingURL=curves.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"curves.d.ts","sourceRoot":"","sources":["../../src/sim/curves.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,EAAE;IACjB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAKD,+FAA+F;AAC/F,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAUzC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;IACnB,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC;IACjB,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IACnB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IAC1B,qFAAqF;IACrF,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7D,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACtC;AAkBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,QAAQ,CAkBrD;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,QAAQ,CA6H1D;AAED,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,QAAQ,CAI5D"}
|