@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
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { TIMEOUT_TIGHT_MULTIPLE } from "../kinematics.js";
|
|
2
|
+
/**
|
|
3
|
+
* The checks about the shape of the routine rather than its geometry: TIME_BUDGET, TIMEOUT_TIGHT,
|
|
4
|
+
* STATIONARY_MARKER, MOVES_ROBOT and PROVENANCE
|
|
5
|
+
* (site/docs/checks-and-findings.md).
|
|
6
|
+
*/
|
|
7
|
+
/** The label an inline pose is taken to carry when it has none (`03` section 4, PROVENANCE). */
|
|
8
|
+
export const INHERITED_PROVENANCE = "SET FROM EDITOR";
|
|
9
|
+
/** TIME_BUDGET: the routine over the period. Nominal over is a warning, optimistic over an error. */
|
|
10
|
+
export function checkTimeBudget(estimate, field) {
|
|
11
|
+
const periodS = field.periods?.autoS;
|
|
12
|
+
if (estimate === null || periodS === undefined || estimate.nominalS === null)
|
|
13
|
+
return [];
|
|
14
|
+
const findings = [];
|
|
15
|
+
if ((estimate.lowS ?? estimate.nominalS) > periodS) {
|
|
16
|
+
findings.push({
|
|
17
|
+
severity: "error",
|
|
18
|
+
stepId: "total",
|
|
19
|
+
code: "TIME_BUDGET",
|
|
20
|
+
message: `Even the optimistic end of the estimate, ${(estimate.lowS ?? estimate.nominalS).toFixed(1)} s, is over the ${periodS.toFixed(0)} s autonomous period.`,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
else if (estimate.nominalS > periodS) {
|
|
24
|
+
findings.push({
|
|
25
|
+
severity: "warning",
|
|
26
|
+
stepId: "total",
|
|
27
|
+
code: "TIME_BUDGET",
|
|
28
|
+
message: `The routine is estimated at ${estimate.nominalS.toFixed(1)} s against a ${periodS.toFixed(0)} s autonomous period; only the optimistic end of the band fits.`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (estimate.hasUnknown && estimate.nominalS <= periodS) {
|
|
32
|
+
// Two different kinds of "unknown" reach here. A step with no estimate at all counts as zero
|
|
33
|
+
// seconds, so the total understates the routine; a step that ends on a sensor contributes the
|
|
34
|
+
// seconds it would take to drive the whole path, which it can only beat. Saying "lower bound"
|
|
35
|
+
// about the second kind would be wrong, so they are reported apart.
|
|
36
|
+
const rows = Object.values(estimate.byStepId);
|
|
37
|
+
const unpriced = rows.some((row) => row.unknown && row.nominalS === null);
|
|
38
|
+
findings.push({
|
|
39
|
+
severity: "info",
|
|
40
|
+
stepId: "total",
|
|
41
|
+
code: "TIME_BUDGET",
|
|
42
|
+
message: unpriced
|
|
43
|
+
? `The total of ${estimate.nominalS.toFixed(1)} s is a lower bound: at least one step has no estimate, so the routine may not fit the ${periodS.toFixed(0)} s period.`
|
|
44
|
+
: `The total of ${estimate.nominalS.toFixed(1)} s is an upper bound: at least one step ends on a condition rather than at the end of its path, so the routine may come in under it.`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return findings;
|
|
48
|
+
}
|
|
49
|
+
/** TIMEOUT_TIGHT: a step whose timeout leaves it almost no room over its own estimate. */
|
|
50
|
+
export function checkTimeouts(steps, estimate) {
|
|
51
|
+
if (estimate === null)
|
|
52
|
+
return [];
|
|
53
|
+
const findings = [];
|
|
54
|
+
for (const step of steps) {
|
|
55
|
+
const timeoutS = "timeoutS" in step.step ? step.step.timeoutS : undefined;
|
|
56
|
+
const nominalS = estimate.byStepId[step.id]?.nominalS;
|
|
57
|
+
if (timeoutS === undefined || nominalS === null || nominalS === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
if (timeoutS >= nominalS * TIMEOUT_TIGHT_MULTIPLE)
|
|
60
|
+
continue;
|
|
61
|
+
findings.push({
|
|
62
|
+
severity: "info",
|
|
63
|
+
stepId: step.id,
|
|
64
|
+
code: "TIMEOUT_TIGHT",
|
|
65
|
+
message: `The timeout of ${timeoutS.toFixed(1)} s is under ${String(TIMEOUT_TIGHT_MULTIPLE)} times this step's estimate of ${nominalS.toFixed(2)} s, so a slow run will be cut short.`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return findings;
|
|
69
|
+
}
|
|
70
|
+
/** STATIONARY_MARKER: a marker that fires a command the robot is meant to be standing still for. */
|
|
71
|
+
export function checkStationaryMarkers(steps, robot) {
|
|
72
|
+
const findings = [];
|
|
73
|
+
for (const step of steps) {
|
|
74
|
+
if (step.step.kind !== "path")
|
|
75
|
+
continue;
|
|
76
|
+
for (const marker of step.step.markers ?? []) {
|
|
77
|
+
const spec = robot.commands.find((command) => command.name === marker.command.name);
|
|
78
|
+
if (spec?.stationary !== true)
|
|
79
|
+
continue;
|
|
80
|
+
findings.push({
|
|
81
|
+
severity: "warning",
|
|
82
|
+
stepId: step.id,
|
|
83
|
+
...("t" in marker.at ? { t: marker.at.t } : {}),
|
|
84
|
+
code: "STATIONARY_MARKER",
|
|
85
|
+
message: `The marker runs ${marker.command.name}, which robot.json marks as stationary, while this path is still moving.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return findings;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* MOVES_ROBOT: a command whose registry entry says it drives the robot leaves the end pose unknown,
|
|
93
|
+
* so whatever follows has to start from wherever it actually ended.
|
|
94
|
+
*
|
|
95
|
+
* It takes the flattened list: a command that drives the robot does so inside a parallel group or a
|
|
96
|
+
* branch arm too, and the step after it is no better placed to name a fixed pose for having been
|
|
97
|
+
* nested.
|
|
98
|
+
*/
|
|
99
|
+
export function checkMovesRobot(steps, robot) {
|
|
100
|
+
const findings = [];
|
|
101
|
+
const movesRobot = new Set(robot.commands.filter((command) => command.movesRobot === true).map((command) => command.name));
|
|
102
|
+
let after = null;
|
|
103
|
+
for (const step of steps) {
|
|
104
|
+
if (after !== null && step.step.kind === "path") {
|
|
105
|
+
const first = step.step.segments[0];
|
|
106
|
+
if (first !== undefined && first.from !== "current") {
|
|
107
|
+
findings.push({
|
|
108
|
+
severity: "error",
|
|
109
|
+
stepId: step.id,
|
|
110
|
+
code: "MOVES_ROBOT",
|
|
111
|
+
message: `${after} moves the robot, so nobody knows where it ended; this step must start from "current" rather than a fixed pose.`,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (step.step.kind === "command") {
|
|
116
|
+
after = movesRobot.has(step.step.name) ? step.step.name : null;
|
|
117
|
+
}
|
|
118
|
+
else if (step.step.kind === "path" || step.step.kind === "wait") {
|
|
119
|
+
after = null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return findings;
|
|
123
|
+
}
|
|
124
|
+
/** PROVENANCE: an inline pose with no label, which is taken to be the editor's own. */
|
|
125
|
+
export function checkProvenance(steps) {
|
|
126
|
+
const findings = [];
|
|
127
|
+
for (const step of steps) {
|
|
128
|
+
if (step.step.kind !== "path")
|
|
129
|
+
continue;
|
|
130
|
+
let unlabelled = 0;
|
|
131
|
+
for (const segment of step.step.segments) {
|
|
132
|
+
const ends = [segment.from, segment.to];
|
|
133
|
+
for (const end of ends) {
|
|
134
|
+
if (end === "current" || "ref" in end)
|
|
135
|
+
continue;
|
|
136
|
+
if (end.provenance === undefined)
|
|
137
|
+
unlabelled += 1;
|
|
138
|
+
}
|
|
139
|
+
if (segment.kind === "bezier") {
|
|
140
|
+
unlabelled += segment.control.filter((point) => point.provenance === undefined).length;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (unlabelled === 0)
|
|
144
|
+
continue;
|
|
145
|
+
findings.push({
|
|
146
|
+
severity: "info",
|
|
147
|
+
stepId: step.id,
|
|
148
|
+
code: "PROVENANCE",
|
|
149
|
+
message: unlabelled === 1
|
|
150
|
+
? `One pose on this step carries no provenance, so it is taken as ${INHERITED_PROVENANCE}.`
|
|
151
|
+
: `${String(unlabelled)} poses on this step carry no provenance, so they are taken as ${INHERITED_PROVENANCE}.`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return findings;
|
|
155
|
+
}
|
|
156
|
+
/** Runs every scheduling check over a plan. */
|
|
157
|
+
export function checkSchedule(estimate, robot, field, steps) {
|
|
158
|
+
return [
|
|
159
|
+
...checkTimeBudget(estimate, field),
|
|
160
|
+
...checkTimeouts(steps, estimate),
|
|
161
|
+
...checkStationaryMarkers(steps, robot),
|
|
162
|
+
...checkMovesRobot(steps, robot),
|
|
163
|
+
...checkProvenance(steps),
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/checks/schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Robot } from "@horizon36596/zenith-schema";
|
|
2
|
+
import type { LedgerRun } from "../ledger.js";
|
|
3
|
+
import type { SeasonRules } from "../season.js";
|
|
4
|
+
import type { Finding, Plan } from "../types.js";
|
|
5
|
+
export declare function checkSeason(plan: Plan, robot: Robot, season: SeasonRules, run: LedgerRun): Finding[];
|
|
6
|
+
//# sourceMappingURL=season.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"season.d.ts","sourceRoot":"","sources":["../../src/checks/season.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAO,IAAI,EAAY,MAAM,aAAa,CAAC;AAiChE,wBAAgB,WAAW,CACzB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,SAAS,GACb,OAAO,EAAE,CA2GX"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { wrapAngle } from "../geometry/angle.js";
|
|
2
|
+
/**
|
|
3
|
+
* The checks that need the ledger and the season plugin: LEGAL_APPROACH, TURRET_RANGE, CAPACITY
|
|
4
|
+
* and EMPTY_SHOT (site/docs/checks-and-findings.md). The core still knows
|
|
5
|
+
* nothing about the game; it asks the plugin and reports the answer.
|
|
6
|
+
*/
|
|
7
|
+
const degrees = (rad) => `${((rad * 180) / Math.PI).toFixed(0)} degrees`;
|
|
8
|
+
const total = (holds) => Object.values(holds).reduce((sum, value) => sum + value, 0);
|
|
9
|
+
/** Every step in the order the ledger walked them, parallel and branch children included. */
|
|
10
|
+
function flatten(steps) {
|
|
11
|
+
const flat = [];
|
|
12
|
+
for (const step of steps) {
|
|
13
|
+
flat.push(step);
|
|
14
|
+
if (step.children !== undefined)
|
|
15
|
+
flat.push(...flatten(step.children));
|
|
16
|
+
}
|
|
17
|
+
return flat;
|
|
18
|
+
}
|
|
19
|
+
/** The leg that put the robot where it is standing, which is the one a move fix has to rewrite. */
|
|
20
|
+
function drivingStepBefore(flat, stepId) {
|
|
21
|
+
const index = flat.findIndex((step) => step.id === stepId);
|
|
22
|
+
for (let before = index - 1; before >= 0; before -= 1) {
|
|
23
|
+
const candidate = flat[before];
|
|
24
|
+
if (candidate !== undefined && candidate.kind === "path")
|
|
25
|
+
return candidate;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
export function checkSeason(plan, robot, season, run) {
|
|
30
|
+
const findings = [];
|
|
31
|
+
const flat = flatten(plan.steps);
|
|
32
|
+
const poseOf = new Map(flat.map((step) => [step.id, step.startPose]));
|
|
33
|
+
const capacity = robot.capacity;
|
|
34
|
+
const turret = robot.shooter?.turretRangeRad;
|
|
35
|
+
const startHolds = season.holds === undefined ? {} : season.holds(run.initialState);
|
|
36
|
+
if (capacity !== undefined && total(startHolds) > capacity.max) {
|
|
37
|
+
findings.push({
|
|
38
|
+
severity: "error",
|
|
39
|
+
stepId: "start",
|
|
40
|
+
code: "CAPACITY",
|
|
41
|
+
message: `The auto starts holding ${String(total(startHolds))} ${capacity.elementKind}, over the ${String(capacity.max)} the robot can carry.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
for (const entry of run.entries) {
|
|
45
|
+
const pose = poseOf.get(entry.stepId) ?? plan.startPose;
|
|
46
|
+
const held = season.holds === undefined ? {} : season.holds(entry.before);
|
|
47
|
+
if (entry.launched > 0) {
|
|
48
|
+
const target = entry.target;
|
|
49
|
+
// LEGAL_APPROACH: the ledger's current target has to be legally approachable from here.
|
|
50
|
+
if (target !== null && !season.legalApproach(entry.before, target, pose, robot)) {
|
|
51
|
+
const fixes = [];
|
|
52
|
+
const legal = season.nearestLegalApproach === undefined
|
|
53
|
+
? null
|
|
54
|
+
: season.nearestLegalApproach(entry.before, target, pose, robot);
|
|
55
|
+
const driving = drivingStepBefore(flat, entry.stepId);
|
|
56
|
+
if (legal !== null && driving !== null) {
|
|
57
|
+
fixes.push({
|
|
58
|
+
kind: "moveToLegalApproach",
|
|
59
|
+
stepId: driving.id,
|
|
60
|
+
label: `Move the end of ${driving.id} to the legal approach band`,
|
|
61
|
+
params: {
|
|
62
|
+
xIn: legal.xIn,
|
|
63
|
+
yIn: legal.yIn,
|
|
64
|
+
...(Number.isFinite(legal.headingRad) ? { headingRad: legal.headingRad } : {}),
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
findings.push({
|
|
69
|
+
severity: "error",
|
|
70
|
+
stepId: entry.stepId,
|
|
71
|
+
code: "LEGAL_APPROACH",
|
|
72
|
+
message: `This step launches at ${target} from a pose that is not a legal approach to it.`,
|
|
73
|
+
geometry: { pointIn: { xIn: pose.xIn, yIn: pose.yIn } },
|
|
74
|
+
...(fixes.length === 0 ? {} : { fixes }),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// TURRET_RANGE: the bearing from the chassis to the target has to be inside the turret's arc.
|
|
78
|
+
const point = target === null || season.targetPoint === undefined
|
|
79
|
+
? null
|
|
80
|
+
: season.targetPoint(entry.before, target);
|
|
81
|
+
if (point !== null && turret !== undefined) {
|
|
82
|
+
const bearingRad = wrapAngle(Math.atan2(point.yIn - pose.yIn, point.xIn - pose.xIn) - pose.headingRad);
|
|
83
|
+
if (bearingRad < turret.minRad || bearingRad > turret.maxRad) {
|
|
84
|
+
findings.push({
|
|
85
|
+
severity: "warning",
|
|
86
|
+
stepId: entry.stepId,
|
|
87
|
+
code: "TURRET_RANGE",
|
|
88
|
+
message: `The target sits ${degrees(bearingRad)} off the nose here, outside the turret's range of ${degrees(turret.minRad)} to ${degrees(turret.maxRad)}.`,
|
|
89
|
+
geometry: { pointIn: point },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// EMPTY_SHOT: firing with nothing in the hopper.
|
|
94
|
+
if (total(held) === 0) {
|
|
95
|
+
findings.push({
|
|
96
|
+
severity: "warning",
|
|
97
|
+
stepId: entry.stepId,
|
|
98
|
+
code: "EMPTY_SHOT",
|
|
99
|
+
message: "This step launches, and the ledger says the robot is holding nothing.",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (entry.launched > total(held)) {
|
|
103
|
+
findings.push({
|
|
104
|
+
severity: "warning",
|
|
105
|
+
stepId: entry.stepId,
|
|
106
|
+
code: "EMPTY_SHOT",
|
|
107
|
+
message: `This step launches ${String(entry.launched)}, and the ledger says the robot is holding only ${String(total(held))}.`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// CAPACITY: collecting more than the robot can hold on top of what it already has.
|
|
112
|
+
if (entry.collected !== null && capacity !== undefined) {
|
|
113
|
+
const wanted = total(held) + entry.collected.count;
|
|
114
|
+
if (wanted > capacity.max) {
|
|
115
|
+
findings.push({
|
|
116
|
+
severity: "error",
|
|
117
|
+
stepId: entry.stepId,
|
|
118
|
+
code: "CAPACITY",
|
|
119
|
+
message: `This step collects ${String(entry.collected.count)} from ${entry.collected.containerId} on top of ${String(total(held))} already aboard, which is ${String(wanted)} against a capacity of ${String(capacity.max)}.`,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return findings;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=season.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"season.js","sourceRoot":"","sources":["../../src/checks/season.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Step } from "@horizon36596/zenith-schema";
|
|
2
|
+
import { type Pose, type Vec2 } from "./geometry/vec.js";
|
|
3
|
+
import type { ResolvedSegment } from "./resolve.js";
|
|
4
|
+
/** The gap two segment endpoints may leave before it is a CONTINUITY error, in inches. */
|
|
5
|
+
export declare const CONTINUITY_TOLERANCE_IN = 0.5;
|
|
6
|
+
/**
|
|
7
|
+
* What the continuity walk needs of a step: a resolved step (`resolve`) and a planned one (`plan`)
|
|
8
|
+
* both have this shape, so the check and the editor's insert-in-the-middle read one definition.
|
|
9
|
+
*/
|
|
10
|
+
export interface ContinuityNode {
|
|
11
|
+
id: string;
|
|
12
|
+
step: Step;
|
|
13
|
+
endPose: Pose | null;
|
|
14
|
+
segments?: readonly ResolvedSegment[];
|
|
15
|
+
/** A branch's children are its `then` steps followed by its `else` steps, as `resolve` lays them. */
|
|
16
|
+
children?: readonly ContinuityNode[];
|
|
17
|
+
}
|
|
18
|
+
/** One place where the robot would have to jump. */
|
|
19
|
+
export interface ContinuityGap {
|
|
20
|
+
stepId: string;
|
|
21
|
+
/** `start`: the step does not begin where the robot was. `segment`: a segment does not begin where the one before it ended. */
|
|
22
|
+
where: "start" | "segment";
|
|
23
|
+
/** For a `segment` gap, the 0-based index of the segment that starts away from the last. */
|
|
24
|
+
segmentIndex?: number;
|
|
25
|
+
gapIn: number;
|
|
26
|
+
/** Where the step or segment starts. */
|
|
27
|
+
pointIn: Vec2;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Every gap over `toleranceIn`, depth first in document order.
|
|
31
|
+
*
|
|
32
|
+
* A sequence chains like the top level: its first member starts where the robot was and each later
|
|
33
|
+
* one where the member before it ended. Every member of a parallel group, and the first step of each
|
|
34
|
+
* side of a branch, starts from the pose the group started at, not from wherever the member before
|
|
35
|
+
* it happened to finish: two paths in a `parallel` both begin where the robot was.
|
|
36
|
+
*/
|
|
37
|
+
export declare function continuityGaps(steps: readonly ContinuityNode[], entry: Pose, toleranceIn?: number): ContinuityGap[];
|
|
38
|
+
//# sourceMappingURL=continuity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.d.ts","sourceRoot":"","sources":["../src/continuity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAY,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,0FAA0F;AAC1F,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,qGAAqG;IACrG,QAAQ,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACtC;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,+HAA+H;IAC/H,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,OAAO,EAAE,IAAI,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,KAAK,EAAE,IAAI,EACX,WAAW,GAAE,MAAgC,GAC5C,aAAa,EAAE,CAsDjB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { distance } from "./geometry/vec.js";
|
|
2
|
+
/** The gap two segment endpoints may leave before it is a CONTINUITY error, in inches. */
|
|
3
|
+
export const CONTINUITY_TOLERANCE_IN = 0.5;
|
|
4
|
+
/**
|
|
5
|
+
* Every gap over `toleranceIn`, depth first in document order.
|
|
6
|
+
*
|
|
7
|
+
* A sequence chains like the top level: its first member starts where the robot was and each later
|
|
8
|
+
* one where the member before it ended. Every member of a parallel group, and the first step of each
|
|
9
|
+
* side of a branch, starts from the pose the group started at, not from wherever the member before
|
|
10
|
+
* it happened to finish: two paths in a `parallel` both begin where the robot was.
|
|
11
|
+
*/
|
|
12
|
+
export function continuityGaps(steps, entry, toleranceIn = CONTINUITY_TOLERANCE_IN) {
|
|
13
|
+
const gaps = [];
|
|
14
|
+
let previous = null;
|
|
15
|
+
for (const step of steps) {
|
|
16
|
+
const startPose = previous?.endPose ?? entry;
|
|
17
|
+
if (step.children !== undefined) {
|
|
18
|
+
if (step.step.kind === "sequence") {
|
|
19
|
+
gaps.push(...continuityGaps(step.children, startPose, toleranceIn));
|
|
20
|
+
}
|
|
21
|
+
else if (step.step.kind === "parallel") {
|
|
22
|
+
for (const child of step.children) {
|
|
23
|
+
gaps.push(...continuityGaps([child], startPose, toleranceIn));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (step.step.kind === "branch") {
|
|
27
|
+
const thenCount = step.step.then.length;
|
|
28
|
+
gaps.push(...continuityGaps(step.children.slice(0, thenCount), startPose, toleranceIn));
|
|
29
|
+
gaps.push(...continuityGaps(step.children.slice(thenCount), startPose, toleranceIn));
|
|
30
|
+
}
|
|
31
|
+
previous = step;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const segments = step.segments;
|
|
35
|
+
if (segments !== undefined) {
|
|
36
|
+
for (let i = 1; i < segments.length; i += 1) {
|
|
37
|
+
const before = segments[i - 1];
|
|
38
|
+
const after = segments[i];
|
|
39
|
+
if (before === undefined || after === undefined)
|
|
40
|
+
continue;
|
|
41
|
+
const gapIn = distance(before.toPose, after.fromPose);
|
|
42
|
+
if (gapIn > toleranceIn) {
|
|
43
|
+
gaps.push({
|
|
44
|
+
stepId: step.id,
|
|
45
|
+
where: "segment",
|
|
46
|
+
segmentIndex: i,
|
|
47
|
+
gapIn,
|
|
48
|
+
pointIn: { xIn: after.fromPose.xIn, yIn: after.fromPose.yIn },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const first = segments[0];
|
|
53
|
+
if (first !== undefined) {
|
|
54
|
+
const gapIn = distance(startPose, first.fromPose);
|
|
55
|
+
if (gapIn > toleranceIn) {
|
|
56
|
+
gaps.push({
|
|
57
|
+
stepId: step.id,
|
|
58
|
+
where: "start",
|
|
59
|
+
gapIn,
|
|
60
|
+
pointIn: { xIn: first.fromPose.xIn, yIn: first.fromPose.yIn },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
previous = step;
|
|
66
|
+
}
|
|
67
|
+
return gaps;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.js","sourceRoot":"","sources":["../src/continuity.ts"],"names":[],"mappings":"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"}
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Auto, type Step } from "@horizon36596/zenith-schema";
|
|
2
|
+
import type { AutoDiff, Estimate, PoseDelta } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The step-level structural diff two versions of a routine are reviewed through
|
|
5
|
+
* (site/docs/github.md).
|
|
6
|
+
*
|
|
7
|
+
* It is keyed on step id, not on position, because a review wants to say "the second volley moved
|
|
8
|
+
* two inches" rather than "eleven lines changed". A step without an id in the file is keyed on its
|
|
9
|
+
* position in the list it sits in, exactly as `resolve` names it, so the two views agree.
|
|
10
|
+
*
|
|
11
|
+
* Both functions are pure and deterministic: the same pair of documents always gives the same
|
|
12
|
+
* changes in the same order, which is what lets a bot rewrite one comment in place.
|
|
13
|
+
*/
|
|
14
|
+
/** A step, and where it sits in the document. */
|
|
15
|
+
interface Entry {
|
|
16
|
+
id: string;
|
|
17
|
+
step: Step;
|
|
18
|
+
/** The list the step is a member of: `steps`, or `<owner id>.steps`, `.then`, `.else`. */
|
|
19
|
+
list: string;
|
|
20
|
+
/** Its position in that list. */
|
|
21
|
+
index: number;
|
|
22
|
+
/** Its position in a walk of the whole document, which is the order changes are reported in. */
|
|
23
|
+
order: number;
|
|
24
|
+
}
|
|
25
|
+
/** Walks the whole step tree in document order, naming every step the way `resolve` names it. */
|
|
26
|
+
export declare function walkSteps(steps: readonly Step[]): Entry[];
|
|
27
|
+
/** Every pose that moved between two versions of a path step, named by where it sits. */
|
|
28
|
+
export declare function poseDeltas(before: Step, after: Step): PoseDelta[];
|
|
29
|
+
/** The step-level structural diff between two routines. */
|
|
30
|
+
export declare function diff(a: Auto, b: Auto): AutoDiff;
|
|
31
|
+
/**
|
|
32
|
+
* The diff as markdown, for a pull request comment or the CLI. Passing the two estimates adds what
|
|
33
|
+
* the change costs in seconds, which is usually the question being asked.
|
|
34
|
+
*/
|
|
35
|
+
export declare function diffToMarkdown(autoDiff: AutoDiff, estimateA?: Estimate, estimateB?: Estimate): string;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,IAAI,EAA8B,KAAK,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAE3G,OAAO,KAAK,EAAE,QAAQ,EAAkB,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEhF;;;;;;;;;;GAUG;AAEH,iDAAiD;AACjD,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC;IACX,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,KAAK,EAAE,MAAM,CAAC;CACf;AAqBD,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,KAAK,EAAE,CAazD;AAgDD,yFAAyF;AACzF,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,SAAS,EAAE,CA0BjE;AAuDD,2DAA2D;AAC3D,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,QAAQ,CA4F/C;AAmBD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,SAAS,CAAC,EAAE,QAAQ,EACpB,SAAS,CAAC,EAAE,QAAQ,GACnB,MAAM,CAqCR"}
|