Add ABB120 demo suite and docs

This commit is contained in:
wangdequan
2026-06-28 20:58:18 +08:00
parent 84a5b54195
commit 65187499d6
820 changed files with 215410 additions and 211 deletions

View File

@@ -2,20 +2,32 @@
box-sizing: border-box; box-sizing: border-box;
} }
:root {
color-scheme: light;
--ink: #1f2933;
--muted: #5d6972;
--line: #c7d0d6;
--panel: #f8fafb;
--panel-strong: #ffffff;
--accent: #1f7a8c;
--accent-dark: #14566a;
--rail: #dde5e9;
}
body { body {
margin: 0; margin: 0;
font-family: Arial, sans-serif; font-family: Arial, "Microsoft YaHei", sans-serif;
color: #1f2933; color: var(--ink);
background: #eef2f4; background: #eef2f4;
} }
.workbench { .workbench {
min-height: 100vh; min-height: 100vh;
display: grid; display: grid;
grid-template-columns: 240px minmax(320px, 1fr) 280px; grid-template-columns: 240px minmax(360px, 1fr) 300px;
grid-template-rows: 48px minmax(280px, 1fr) 180px; grid-template-rows: auto minmax(280px, 1fr) minmax(230px, 34vh);
gap: 1px; gap: 1px;
background: #c7d0d6; background: var(--line);
} }
.command-bar, .command-bar,
@@ -24,24 +36,74 @@ body {
.pendant, .pendant,
.editor, .editor,
.bottom-panel { .bottom-panel {
background: #f8fafb; background: var(--panel);
} }
.command-bar { .command-bar {
grid-column: 1 / 4; grid-column: 1 / 4;
display: flex; display: grid;
flex-wrap: wrap; grid-template-columns: auto minmax(220px, 360px) repeat(7, auto) minmax(260px, 1fr);
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 8px 12px; padding: 8px 12px;
min-width: 0;
}
.station-title {
display: grid;
gap: 2px;
min-width: 150px;
}
.station-title span,
.program-picker span,
.frame-control span {
color: var(--muted);
font-size: 12px;
}
.program-picker,
.frame-control {
display: grid;
gap: 3px;
min-width: 0;
}
.program-picker select,
.frame-control input {
width: 100%;
min-width: 0;
}
button,
select {
min-height: 32px;
border: 1px solid #9aa8b2;
background: var(--panel-strong);
color: var(--ink);
border-radius: 4px;
font: inherit;
} }
button { button {
min-height: 32px; padding: 0 10px;
border: 1px solid #9aa8b2; white-space: nowrap;
background: #ffffff; }
color: #1f2933;
border-radius: 4px; button:hover,
select:hover {
border-color: var(--accent);
}
button[aria-pressed="true"] {
background: var(--accent-dark);
color: #ffffff;
border-color: var(--accent-dark);
}
output {
color: var(--muted);
font-size: 12px;
} }
.object-tree { .object-tree {
@@ -58,7 +120,11 @@ button {
.object-tree ul { .object-tree ul {
margin: 0; margin: 0;
padding-left: 18px; padding-left: 18px;
line-height: 1.8; line-height: 1.75;
}
.object-tree li {
overflow-wrap: anywhere;
} }
.viewport { .viewport {
@@ -75,10 +141,20 @@ button {
width: calc(100% - 48px); width: calc(100% - 48px);
} }
.viewport circle {
fill: var(--accent-dark);
}
[data-path-current] {
fill: #b8542f;
stroke: #ffffff;
stroke-width: 3;
}
.robot-arm { .robot-arm {
position: absolute; position: absolute;
left: 12%; left: 12%;
top: 20%; top: 18%;
width: 62%; width: 62%;
height: 48%; height: 48%;
} }
@@ -114,7 +190,7 @@ button {
.pendant dl { .pendant dl {
display: grid; display: grid;
grid-template-columns: 84px 1fr; grid-template-columns: 78px minmax(0, 1fr);
gap: 8px; gap: 8px;
margin: 0; margin: 0;
} }
@@ -123,6 +199,11 @@ button {
font-weight: 700; font-weight: 700;
} }
.pendant dd {
margin: 0;
overflow-wrap: anywhere;
}
.editor { .editor {
grid-column: 1 / 3; grid-column: 1 / 3;
padding: 12px; padding: 12px;
@@ -138,43 +219,126 @@ button {
.editor pre { .editor pre {
margin: 0; margin: 0;
padding: 12px; padding: 12px;
background: #1f2933; min-height: 150px;
background: #202a33;
color: #f8fafb; color: #f8fafb;
overflow: auto; overflow: auto;
line-height: 1.45;
border-radius: 4px;
} }
.bottom-panel { .bottom-panel {
grid-column: 1 / 4;
padding: 12px; padding: 12px;
display: grid; display: grid;
grid-template-columns: repeat(7, minmax(100px, 1fr)); grid-template-columns: repeat(9, minmax(100px, 1fr));
gap: 8px; gap: 8px;
overflow: auto; overflow: auto;
} }
.bottom-panel div { .bottom-panel > div {
border: 1px solid #c7d0d6; border: 1px solid var(--line);
padding: 8px; padding: 8px;
background: #ffffff; background: var(--panel-strong);
display: grid; display: grid;
gap: 6px; gap: 6px;
min-width: 0; min-width: 0;
align-content: start;
} }
.bottom-panel span { .bottom-panel span {
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
@media (max-width: 840px) { .bottom-panel progress {
width: 100%;
height: 8px;
}
.steps-panel,
.trajectory-panel {
grid-column: 1 / -1;
min-height: 150px;
}
.steps-table-wrap,
.trajectory-table-wrap {
overflow: auto;
border: 1px solid var(--line);
max-height: 260px;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
th,
td {
border-bottom: 1px solid #e1e7eb;
border-right: 1px solid #e1e7eb;
padding: 6px 7px;
text-align: left;
white-space: nowrap;
}
th {
position: sticky;
top: 0;
z-index: 1;
background: var(--rail);
}
tr[aria-current="true"] td {
background: #e6f2f4;
color: #0f4d5d;
font-weight: 700;
}
tr[data-step-state="active"] td {
background: #fff2cc;
color: #6f4b00;
font-weight: 700;
}
tr[data-step-state="complete"] td {
background: #f4f7f8;
color: var(--muted);
}
@media (max-width: 1180px) {
.command-bar {
grid-template-columns: auto minmax(200px, 1fr) repeat(7, auto);
}
.frame-control {
grid-column: 1 / -1;
}
}
@media (max-width: 900px) {
.workbench { .workbench {
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: auto; grid-template-rows: auto;
} }
.command-bar, .command-bar,
.editor { .editor,
.bottom-panel {
grid-column: auto; grid-column: auto;
} }
.command-bar {
grid-template-columns: 1fr 1fr;
}
.station-title,
.program-picker,
.frame-control {
grid-column: 1 / -1;
}
.bottom-panel { .bottom-panel {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }
@@ -183,3 +347,33 @@ button {
min-height: 300px; min-height: 300px;
} }
} }
@media (max-width: 560px) {
.command-bar {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.command-bar button {
padding: 0 6px;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.station-title,
.program-picker,
.frame-control {
grid-column: 1 / -1;
}
.bottom-panel {
grid-template-columns: 1fr;
}
.robot-arm {
left: 4%;
width: 80%;
transform: scale(0.85);
transform-origin: left top;
}
}

View File

@@ -7,9 +7,16 @@
<link rel="stylesheet" href="./virtual-controller.css"> <link rel="stylesheet" href="./virtual-controller.css">
</head> </head>
<body> <body>
<main class="workbench" data-robot="abb_irb120_3_58"> <main class="workbench" data-robot="abb_irb120_3_58" data-suite="working2-abb120-spec" data-job="W2-JOB-latest">
<header class="command-bar"> <header class="command-bar">
<strong>ABB120 Station</strong> <div class="station-title">
<strong>ABB120 Station</strong>
<span data-field="job">W2-JOB-latest</span>
</div>
<label class="program-picker">
<span>Program</span>
<select data-program-select aria-label="Program"></select>
</label>
<button type="button" data-command="load">Load</button> <button type="button" data-command="load">Load</button>
<button type="button" data-command="run">Run</button> <button type="button" data-command="run">Run</button>
<button type="button" data-command="pause">Pause</button> <button type="button" data-command="pause">Pause</button>
@@ -17,21 +24,28 @@
<button type="button" data-command="stop">Stop</button> <button type="button" data-command="stop">Stop</button>
<button type="button" data-command="reset">Reset</button> <button type="button" data-command="reset">Reset</button>
<button type="button" data-command="export">Export</button> <button type="button" data-command="export">Export</button>
<label class="frame-control">
<span>Sample</span>
<input type="range" min="0" max="0" value="0" data-frame-slider aria-label="Execution sample">
<output data-field="frame">0 / 0</output>
</label>
</header> </header>
<aside class="object-tree"> <aside class="object-tree">
<h2>Station</h2> <h2>Station</h2>
<ul> <ul data-object-tree>
<li>Robot: abb_irb120_3_58</li> <li>Robot: abb_irb120_3_58</li>
<li>Tool: tool0</li> <li>Tool: tool0</li>
<li>Frame: world</li> <li>Frame: world</li>
<li>Path: pick_place</li> <li>Path: pick_place</li>
<li>Operation: pick_op</li> <li>Program: W2_60_IOWaitPulse</li>
<li>Program: main</li> <li>Suite: working2-abb120-spec</li>
<li>Reports</li> <li>Job: W2-JOB-latest</li>
</ul> </ul>
</aside> </aside>
<section class="viewport" aria-label="station viewport"> <section class="viewport" aria-label="station viewport">
<div class="robot-arm"> <div class="robot-arm" aria-hidden="true">
<span class="joint j1"></span> <span class="joint j1"></span>
<span class="link l1"></span> <span class="link l1"></span>
<span class="joint j2"></span> <span class="joint j2"></span>
@@ -41,23 +55,27 @@
<span class="joint j4"></span> <span class="joint j4"></span>
</div> </div>
<svg viewBox="0 0 480 240" role="img" aria-label="path trace"> <svg viewBox="0 0 480 240" role="img" aria-label="path trace">
<path d="M70 170 C150 80 260 80 410 150" fill="none" stroke="#1f7a8c" stroke-width="4"/> <path data-path-trace d="M70 170 C150 80 260 80 410 150" fill="none" stroke="#1f7a8c" stroke-width="4"/>
<circle cx="70" cy="170" r="6"/> <circle data-path-start cx="70" cy="170" r="6"/>
<circle cx="250" cy="90" r="6"/> <circle data-path-current cx="70" cy="170" r="8"/>
<circle cx="410" cy="150" r="6"/> <circle data-path-end cx="410" cy="150" r="6"/>
</svg> </svg>
</section> </section>
<aside class="pendant"> <aside class="pendant">
<h2>Controller</h2> <h2>Controller</h2>
<dl> <dl>
<dt>State</dt><dd data-field="state">ready</dd> <dt>State</dt><dd data-field="state">ready</dd>
<dt>Program</dt><dd data-field="program">W2_60_IOWaitPulse</dd>
<dt>Mode</dt><dd data-field="mode">auto</dd> <dt>Mode</dt><dd data-field="mode">auto</dd>
<dt>Motors</dt><dd data-field="motors">on</dd> <dt>Motors</dt><dd data-field="motors">on</dd>
<dt>PC</dt><dd data-field="pc">main:0</dd> <dt>PC</dt><dd data-field="pc">main:0</dd>
<dt>Time</dt><dd data-field="runtime">0 / 0 s @ 50 ms</dd>
<dt>Joints</dt><dd data-field="joints">[0, 0, 0, 0, 0, 0]</dd> <dt>Joints</dt><dd data-field="joints">[0, 0, 0, 0, 0, 0]</dd>
<dt>TCP</dt><dd data-field="tcp">[0, 0, 580, 0, 0, 0]</dd> <dt>TCP</dt><dd data-field="tcp">pos [0.374, 0, 0.63] q [0, 0.707107, 0, 0.707107]</dd>
</dl> </dl>
</aside> </aside>
<section class="editor"> <section class="editor">
<nav> <nav>
<button type="button" data-tab="grl" aria-pressed="true">GRL</button> <button type="button" data-tab="grl" aria-pressed="true">GRL</button>
@@ -69,6 +87,7 @@
run_path pick_place run_path pick_place
end</pre> end</pre>
</section> </section>
<section class="bottom-panel"> <section class="bottom-panel">
<div><strong>Log</strong><span data-field="log">ready</span></div> <div><strong>Log</strong><span data-field="log">ready</span></div>
<div><strong>Diagnostics</strong><span data-field="diagnostics">ready</span></div> <div><strong>Diagnostics</strong><span data-field="diagnostics">ready</span></div>
@@ -76,7 +95,54 @@ end</pre>
<div><strong>Wait</strong><span data-field="wait">none</span></div> <div><strong>Wait</strong><span data-field="wait">none</span></div>
<div><strong>Motion Queue</strong><span data-field="queue">empty</span></div> <div><strong>Motion Queue</strong><span data-field="queue">empty</span></div>
<div><strong>Trace</strong><span data-field="trace">0 events</span></div> <div><strong>Trace</strong><span data-field="trace">0 events</span></div>
<div><strong>Reports</strong><span data-field="reports">A120-REPORT</span></div> <div><strong>Reports</strong><span data-field="reports">W2-REPORT</span></div>
<div><strong>Parser</strong><span data-field="parser">idle</span><progress data-parser-progress max="1" value="0" aria-label="Parser progress"></progress></div>
<div><strong>Storage</strong><span data-field="storage">checking browser storage</span></div>
<div class="steps-panel">
<strong>Program Steps</strong>
<span data-field="step-status">step 0</span>
<div class="steps-table-wrap">
<table>
<thead>
<tr>
<th>#</th>
<th>Time</th>
<th>Line</th>
<th>Step</th>
<th>Source</th>
<th>Motion/Target</th>
<th>Samples</th>
</tr>
</thead>
<tbody data-step-table></tbody>
</table>
</div>
</div>
<div class="trajectory-panel">
<strong>Trajectory Frames</strong>
<span data-field="frame-time">t=0 s</span>
<div class="trajectory-table-wrap">
<table>
<thead>
<tr>
<th>#</th>
<th>t</th>
<th>Motion</th>
<th>Target</th>
<th>TCP XYZ</th>
<th>TCP Q</th>
<th>J1</th>
<th>J2</th>
<th>J3</th>
<th>J4</th>
<th>J5</th>
<th>J6</th>
</tr>
</thead>
<tbody data-frame-table></tbody>
</table>
</div>
</div>
</section> </section>
</main> </main>
<script src="./virtual-controller.js"></script> <script src="./virtual-controller.js"></script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,548 @@
import { createHash } from "node:crypto";
import {
copyFileSync,
cpSync,
existsSync,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
statSync,
writeFileSync
} from "node:fs";
import { basename, dirname, join, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
const webRoot = join(root, "kdl-wasm", "web");
const deployRoot = join(webRoot, "test-results", "deploy");
const appRoot = join(webRoot, "app");
const specRoot = join(webRoot, "tests", "fixtures", "abb120", "spec-programs");
const resultRoot = join(webRoot, "test-results", "abb120-spec");
const uiResultRoot = join(webRoot, "test-results", "virtual-controller");
const working2Root = join(root, "working2");
const docsRoot = join(root, "work", "doc");
const jobId = getArg("--job") ?? latestJobId();
const generatedAt = new Date();
const releaseId = getArg("--release") ?? `${formatShanghaiId(generatedAt)}-${jobId}`;
const packageName = `kdl-olp-demo-${releaseId}`;
const packageDir = join(deployRoot, packageName);
const zipPath = join(deployRoot, `${packageName}.zip`);
const jobDir = join(resultRoot, jobId);
const manifest = readJson(join(specRoot, "manifest.json"));
const job = readJson(join(jobDir, "job.json"));
const report = readJson(join(jobDir, "report.json"));
const uiEvidence = readJson(join(uiResultRoot, "evidence.json"));
assertReportIsDeployable(report);
assertJobMatchesInputs(job, report, manifest);
assertSafeDeployPath(packageDir);
mkdirSync(deployRoot, { recursive: true });
rmSync(packageDir, { recursive: true, force: true });
mkdirSync(packageDir, { recursive: true });
copyTree(appRoot, join(packageDir, "app"));
copyTree(specRoot, join(packageDir, "spec-programs"));
copyTree(jobDir, join(packageDir, "test-results", "abb120-spec", jobId));
copyTree(uiResultRoot, join(packageDir, "test-results", "virtual-controller"));
copyDocs(join(packageDir, "docs"));
copyWorking2Docs(join(packageDir, "docs", "working2"));
const demoManifest = buildDemoManifest();
writeJson(join(packageDir, "demo-manifest.json"), demoManifest);
writeFileSync(join(packageDir, "index.html"), indexHtml(demoManifest), "utf8");
writeFileSync(join(packageDir, "README.md"), packageReadme(demoManifest), "utf8");
zipDirectory(packageDir, zipPath);
const zip = {
path: slash(relative(root, zipPath)),
bytes: statSync(zipPath).size,
sha256: sha256File(zipPath)
};
const summary = {
release_id: releaseId,
generated_at: generatedAt.toISOString(),
job_id: jobId,
package_dir: slash(relative(root, packageDir)),
zip,
program_count: demoManifest.program_count,
report_fail: report.summary.fail
};
writeJson(join(packageDir, "demo-build-summary.json"), summary);
writeJson(join(deployRoot, `${packageName}.summary.json`), summary);
console.log(JSON.stringify(summary, null, 2));
function buildDemoManifest() {
const levelCounts = countLevels(manifest.programs);
const programs = manifest.programs.map((entry) => {
const jobProgram = job.programs.find((program) => program.program_id === entry.program_id);
return {
program_id: entry.program_id,
file: entry.file,
source: `spec-programs/${entry.file}`,
coverage_level: entry.coverage_level,
spec_sections: entry.spec_sections,
expected_status: entry.expected_status,
status: jobProgram?.status ?? "missing",
diagnostics: jobProgram?.diagnostics?.map((diagnostic) => diagnostic.code).filter(Boolean) ?? [],
artifacts: artifactLinks(entry.program_id)
};
});
return {
release_id: releaseId,
generated_at: generatedAt.toISOString(),
suite_id: manifest.suite_id,
job_id: job.job_id,
robot_id: manifest.robot_id,
spec_source: manifest.spec_source,
program_count: manifest.programs.length,
runtime_programs: levelCounts.Runtime,
static_programs: levelCounts.Static,
post_programs: levelCounts.Post,
entry: "app/virtual-controller.html",
virtual_controller_entry: "app/virtual-controller.html",
report_json: `test-results/abb120-spec/${job.job_id}/report.json`,
report_html: `test-results/abb120-spec/${job.job_id}/report.html`,
job_json: `test-results/abb120-spec/${job.job_id}/job.json`,
program_manifest: "spec-programs/manifest.json",
screenshots: {
desktop: "test-results/virtual-controller/virtual-controller-desktop.png",
mobile: "test-results/virtual-controller/virtual-controller-mobile.png",
evidence: "test-results/virtual-controller/evidence.json"
},
docs: [
{
title: "GRL user manual",
href: "docs/grl-user-manual.docx",
kind: "docx"
},
{
title: "OLP test document",
href: "docs/olp-test-document.docx",
kind: "docx"
},
{
title: "Working2 acceptance evidence",
href: "docs/working2/acceptance-evidence.md",
kind: "markdown"
}
],
coverage: report.coverage,
summary: report.summary,
programs
};
}
function artifactLinks(programId) {
const base = `test-results/abb120-spec/${job.job_id}/programs/${programId}`;
return {
compile: `${base}/compile.json`,
controller: `${base}/controller.json`,
motion_queue: `${base}/motion-queue.json`,
trace: `${base}/trace.json`,
io: `${base}/io.json`,
trajectory: `${base}/trajectory.json`,
post_report: `${base}/post-report.json`,
roundtrip: `${base}/roundtrip.json`
};
}
function copyDocs(targetDir) {
mkdirSync(targetDir, { recursive: true });
const docs = [
["GRL功能语法逻辑与程序创建使用手册.docx", "grl-user-manual.docx"],
["通用机器人离线编程系统测试文档.docx", "olp-test-document.docx"]
];
for (const [doc, alias] of docs) {
const source = join(docsRoot, doc);
if (!existsSync(source)) {
throw new Error(`Required document is missing: ${source}`);
}
copyFileSync(source, join(targetDir, doc));
copyFileSync(source, join(targetDir, alias));
}
}
function copyWorking2Docs(targetDir) {
mkdirSync(targetDir, { recursive: true });
for (const entry of readdirSync(working2Root, { withFileTypes: true })) {
if (entry.isFile() && entry.name.endsWith(".md")) {
copyFileSync(join(working2Root, entry.name), join(targetDir, entry.name));
}
}
const aliases = {
"01-项目功能内容.md": "project-scope.md",
"02-项目程序开发详细步骤.md": "development-steps.md",
"03-推进台账.md": "progress-log.md",
"04-任务矩阵.md": "task-matrix.md",
"05-验收证据.md": "acceptance-evidence.md",
"06-决策记录.md": "decisions.md",
"07-服务器发布与演示包实施方案.md": "server-deploy-plan.md"
};
for (const [sourceName, aliasName] of Object.entries(aliases)) {
const source = join(working2Root, sourceName);
if (existsSync(source)) {
copyFileSync(source, join(targetDir, aliasName));
}
}
const manifestDir = join(working2Root, "programs");
if (existsSync(manifestDir)) {
copyTree(manifestDir, join(targetDir, "programs"));
const manifestSource = join(manifestDir, "manifest.md");
if (existsSync(manifestSource)) {
copyFileSync(manifestSource, join(targetDir, "program-manifest.md"));
}
}
}
function indexHtml(demoManifest) {
const rows = demoManifest.programs.map((program) => `
<tr>
<td><a href="${escapeAttr(program.source)}">${escapeHtml(program.program_id)}</a></td>
<td>${escapeHtml(program.coverage_level)}</td>
<td>${escapeHtml(program.status)}</td>
<td>${escapeHtml(program.spec_sections.join(", "))}</td>
<td><a href="${escapeAttr(program.artifacts.compile)}">compile</a></td>
</tr>`).join("");
return `<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>KDL OLP Demo ${escapeHtml(demoManifest.release_id)}</title>
<style>
:root {
color-scheme: light;
--ink: #172026;
--muted: #5e6a71;
--line: #cfd7dc;
--panel: #f6f8f9;
--accent: #1f7a8c;
--accent-2: #7b6d3a;
font-family: Arial, "Microsoft YaHei", sans-serif;
}
* { box-sizing: border-box; }
body { margin: 0; color: var(--ink); background: #ffffff; }
header { padding: 28px 32px 18px; border-bottom: 1px solid var(--line); background: var(--panel); }
h1 { margin: 0 0 10px; font-size: 28px; line-height: 1.2; letter-spacing: 0; }
p { margin: 0; color: var(--muted); line-height: 1.55; }
main { max-width: 1180px; margin: 0 auto; padding: 24px 24px 40px; }
.actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0 24px; }
.actions a { color: #fff; background: var(--accent); text-decoration: none; padding: 10px 13px; border-radius: 6px; font-weight: 700; }
.actions a.secondary { background: var(--accent-2); }
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 24px; }
.summary div { border: 1px solid var(--line); border-radius: 6px; padding: 12px; background: #fff; }
.summary strong { display: block; font-size: 22px; }
section { margin-top: 28px; }
h2 { font-size: 18px; margin: 0 0 12px; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { border: 1px solid var(--line); padding: 9px 10px; text-align: left; vertical-align: top; }
th { background: var(--panel); }
img { max-width: 100%; height: auto; border: 1px solid var(--line); border-radius: 6px; }
.screens { display: grid; grid-template-columns: minmax(0, 2fr) minmax(220px, 1fr); gap: 16px; align-items: start; }
@media (max-width: 760px) {
header { padding: 22px 18px 14px; }
main { padding: 18px 14px 32px; }
h1 { font-size: 23px; }
.screens { grid-template-columns: 1fr; }
table { font-size: 13px; }
th, td { padding: 7px; }
}
</style>
</head>
<body>
<header>
<h1>KDL OLP ABB120 Working2 Demo</h1>
<p>Release ${escapeHtml(demoManifest.release_id)} / Job ${escapeHtml(demoManifest.job_id)} / Suite ${escapeHtml(demoManifest.suite_id)}</p>
</header>
<main>
<nav class="actions" aria-label="demo links">
<a href="${escapeAttr(demoManifest.virtual_controller_entry)}">Open virtual controller</a>
<a href="${escapeAttr(demoManifest.report_html)}" class="secondary">Open report</a>
<a href="${escapeAttr(demoManifest.program_manifest)}" class="secondary">Program manifest</a>
<a href="demo-manifest.json" class="secondary">Demo manifest</a>
</nav>
<div class="summary">
<div><span>Programs</span><strong>${demoManifest.program_count}</strong></div>
<div><span>Runtime</span><strong>${demoManifest.runtime_programs}</strong></div>
<div><span>Static</span><strong>${demoManifest.static_programs}</strong></div>
<div><span>Post</span><strong>${demoManifest.post_programs}</strong></div>
<div><span>Fail</span><strong>${demoManifest.summary.fail}</strong></div>
</div>
<section>
<h2>Program Evidence</h2>
<table>
<thead><tr><th>Program</th><th>Layer</th><th>Status</th><th>Spec Sections</th><th>Artifact</th></tr></thead>
<tbody>${rows}
</tbody>
</table>
</section>
<section>
<h2>Screenshots</h2>
<div class="screens">
<a href="${escapeAttr(demoManifest.screenshots.desktop)}"><img src="${escapeAttr(demoManifest.screenshots.desktop)}" alt="Virtual controller desktop screenshot"></a>
<a href="${escapeAttr(demoManifest.screenshots.mobile)}"><img src="${escapeAttr(demoManifest.screenshots.mobile)}" alt="Virtual controller mobile screenshot"></a>
</div>
</section>
<section>
<h2>Documents</h2>
<table>
<tbody>
${demoManifest.docs.map((doc) => `<tr><td>${escapeHtml(doc.title)}</td><td><a href="${escapeAttr(doc.href)}">${escapeHtml(doc.href)}</a></td></tr>`).join("\n ")}
</tbody>
</table>
</section>
</main>
</body>
</html>
`;
}
function packageReadme(demoManifest) {
return [
`# KDL OLP demo ${demoManifest.release_id}`,
"",
`Job: ${demoManifest.job_id}`,
`Suite: ${demoManifest.suite_id}`,
`Programs: ${demoManifest.program_count}`,
`Report: ${demoManifest.report_html}`,
`Virtual controller: ${demoManifest.virtual_controller_entry}`,
"",
"Serve this directory as the HTTPS document root for the demo port."
].join("\n");
}
function latestJobId() {
if (!existsSync(resultRoot)) {
throw new Error(`No ABB120 spec result directory found: ${resultRoot}`);
}
const jobs = readdirSync(resultRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory() && entry.name.startsWith("W2-JOB-"))
.map((entry) => ({
name: entry.name,
mtimeMs: statSync(join(resultRoot, entry.name)).mtimeMs
}))
.sort((left, right) => right.mtimeMs - left.mtimeMs || right.name.localeCompare(left.name));
if (jobs.length === 0) {
throw new Error(`No W2-JOB-* result directories found in ${resultRoot}`);
}
return jobs[0].name;
}
function assertReportIsDeployable(report) {
if (report.summary?.programs !== 19) {
throw new Error(`Expected report.summary.programs=19, got ${report.summary?.programs}`);
}
if (report.summary?.fail !== 0) {
throw new Error(`Expected report.summary.fail=0, got ${report.summary?.fail}`);
}
if (report.coverage?.missingSections?.length !== 0) {
throw new Error(`Expected no missing sections, got ${report.coverage.missingSections.join(",")}`);
}
}
function assertJobMatchesInputs(job, report, manifest) {
if (job.job_id !== jobId || report.job_id !== jobId) {
throw new Error(`Job id mismatch: requested ${jobId}, job=${job.job_id}, report=${report.job_id}`);
}
if (job.suite_id !== manifest.suite_id || report.suite_id !== manifest.suite_id) {
throw new Error("Suite id mismatch between manifest, job, and report");
}
if (manifest.programs.length !== 19 || job.programs.length !== 19) {
throw new Error(`Expected 19 programs, manifest=${manifest.programs.length}, job=${job.programs.length}`);
}
}
function countLevels(programs) {
return programs.reduce((counts, program) => {
counts[program.coverage_level] = (counts[program.coverage_level] ?? 0) + 1;
return counts;
}, { Runtime: 0, Static: 0, Post: 0 });
}
function copyTree(source, target) {
if (!existsSync(source)) {
throw new Error(`Required path is missing: ${source}`);
}
mkdirSync(dirname(target), { recursive: true });
cpSync(source, target, { recursive: true, force: true });
}
function readJson(file) {
return JSON.parse(readFileSync(file, "utf8"));
}
function writeJson(file, value) {
mkdirSync(dirname(file), { recursive: true });
writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
function zipDirectory(sourceDir, destinationFile) {
const files = walkFiles(sourceDir).sort((left, right) => left.localeCompare(right));
const chunks = [];
const central = [];
let offset = 0;
for (const file of files) {
const data = readFileSync(file);
const name = slash(relative(sourceDir, file));
const nameBuffer = Buffer.from(name, "utf8");
const stat = statSync(file);
const { time, date } = dosDateTime(stat.mtime);
const crc = crc32(data);
const local = Buffer.alloc(30);
local.writeUInt32LE(0x04034b50, 0);
local.writeUInt16LE(20, 4);
local.writeUInt16LE(0x0800, 6);
local.writeUInt16LE(0, 8);
local.writeUInt16LE(time, 10);
local.writeUInt16LE(date, 12);
local.writeUInt32LE(crc, 14);
local.writeUInt32LE(data.length, 18);
local.writeUInt32LE(data.length, 22);
local.writeUInt16LE(nameBuffer.length, 26);
local.writeUInt16LE(0, 28);
chunks.push(local, nameBuffer, data);
const header = Buffer.alloc(46);
header.writeUInt32LE(0x02014b50, 0);
header.writeUInt16LE(20, 4);
header.writeUInt16LE(20, 6);
header.writeUInt16LE(0x0800, 8);
header.writeUInt16LE(0, 10);
header.writeUInt16LE(time, 12);
header.writeUInt16LE(date, 14);
header.writeUInt32LE(crc, 16);
header.writeUInt32LE(data.length, 20);
header.writeUInt32LE(data.length, 24);
header.writeUInt16LE(nameBuffer.length, 28);
header.writeUInt16LE(0, 30);
header.writeUInt16LE(0, 32);
header.writeUInt16LE(0, 34);
header.writeUInt16LE(0, 36);
header.writeUInt32LE(0, 38);
header.writeUInt32LE(offset, 42);
central.push(header, nameBuffer);
offset += local.length + nameBuffer.length + data.length;
}
const centralOffset = offset;
const centralSize = central.reduce((total, chunk) => total + chunk.length, 0);
const end = Buffer.alloc(22);
end.writeUInt32LE(0x06054b50, 0);
end.writeUInt16LE(0, 4);
end.writeUInt16LE(0, 6);
end.writeUInt16LE(files.length, 8);
end.writeUInt16LE(files.length, 10);
end.writeUInt32LE(centralSize, 12);
end.writeUInt32LE(centralOffset, 16);
end.writeUInt16LE(0, 20);
rmSync(destinationFile, { force: true });
writeFileSync(destinationFile, Buffer.concat([...chunks, ...central, end]));
}
function sha256File(file) {
return createHash("sha256").update(readFileSync(file)).digest("hex");
}
function formatShanghaiId(date) {
const parts = new Intl.DateTimeFormat("en-CA", {
timeZone: "Asia/Shanghai",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
}).formatToParts(date);
const value = Object.fromEntries(parts.map((part) => [part.type, part.value]));
return `${value.year}${value.month}${value.day}-${value.hour}${value.minute}${value.second}`;
}
function getArg(name) {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : undefined;
}
function slash(value) {
return value.split(sep).join("/");
}
function psSingleQuoted(value) {
return `'${String(value).replaceAll("'", "''")}'`;
}
function assertSafeDeployPath(path) {
const allowedRoot = resolve(deployRoot) + sep;
const resolved = resolve(path);
if (!resolved.startsWith(allowedRoot)) {
throw new Error(`Refusing to modify path outside deploy root: ${resolved}`);
}
}
function escapeHtml(value) {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;");
}
function escapeAttr(value) {
return escapeHtml(value);
}
function walkFiles(dir) {
const files = [];
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...walkFiles(fullPath));
} else if (entry.isFile()) {
files.push(fullPath);
}
}
return files;
}
function dosDateTime(date) {
const year = Math.max(1980, date.getFullYear());
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = Math.floor(date.getSeconds() / 2);
return {
time: (hours << 11) | (minutes << 5) | seconds,
date: ((year - 1980) << 9) | (month << 5) | day
};
}
var crcTable;
function crc32(buffer) {
crcTable ??= createCrcTable();
let crc = 0xffffffff;
for (const byte of buffer) {
crc = crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);
}
return (crc ^ 0xffffffff) >>> 0;
}
function createCrcTable() {
const table = new Uint32Array(256);
for (let index = 0; index < 256; index += 1) {
let value = index;
for (let bit = 0; bit < 8; bit += 1) {
value = (value & 1) ? (0xedb88320 ^ (value >>> 1)) : (value >>> 1);
}
table[index] = value >>> 0;
}
return table;
}

View File

@@ -0,0 +1,184 @@
param(
[string]$ZipPath,
[string]$Target = "ubuntu@82.156.24.101",
[string]$RemoteRoot = "/opt/kdl-olp-demo/8095",
[string]$BaseUrl = "https://82.156.24.101:8095",
[switch]$Sudo,
[switch]$NoSudo,
[switch]$SkipSmoke
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..\..")
$DeployRoot = Join-Path $RepoRoot "kdl-wasm\web\test-results\deploy"
if ([string]::IsNullOrWhiteSpace($ZipPath)) {
$ZipPath = Get-ChildItem -LiteralPath $DeployRoot -Filter "kdl-olp-demo-*.zip" |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1 -ExpandProperty FullName
}
if ([string]::IsNullOrWhiteSpace($ZipPath) -or -not (Test-Path -LiteralPath $ZipPath)) {
throw "Demo zip not found. Run: npm run demo:build"
}
$ZipPath = (Resolve-Path -LiteralPath $ZipPath).Path
$ZipName = Split-Path -Leaf $ZipPath
if ($ZipName -notmatch '^kdl-olp-demo-(.+)\.zip$') {
throw "Zip name must match kdl-olp-demo-<release_id>.zip: $ZipName"
}
$ReleaseId = $Matches[1]
$RemoteZip = "/tmp/$ZipName"
$RemoteRelease = "$RemoteRoot/releases/$ReleaseId"
function Invoke-Remote {
param([string]$Command)
ssh -o StrictHostKeyChecking=accept-new $Target $Command
if ($LASTEXITCODE -ne 0) {
throw "Remote command failed: $Command"
}
}
function Remote-Cmd {
param([string]$Command)
if ($script:UseSudo) {
return "sudo sh -lc " + (Quote-Sh $Command)
}
return "sh -lc " + (Quote-Sh $Command)
}
function Quote-Sh {
param([string]$Value)
return "'" + ($Value -replace "'", "'\''") + "'"
}
function Get-RemoteParent {
param([string]$Path)
$Normalized = $Path.TrimEnd("/")
$Index = $Normalized.LastIndexOf("/")
if ($Index -le 0) {
return "/"
}
return $Normalized.Substring(0, $Index)
}
$RemoteParent = Get-RemoteParent $RemoteRoot
Write-Host "Deploying $ZipName to ${Target}:$RemoteRoot"
scp -o StrictHostKeyChecking=accept-new $ZipPath "${Target}:$RemoteZip"
if ($LASTEXITCODE -ne 0) {
throw "scp upload failed"
}
$script:UseSudo = $false
if ($Sudo) {
$script:UseSudo = $true
} elseif (-not $NoSudo) {
ssh -o StrictHostKeyChecking=accept-new $Target "test -w $(Quote-Sh $RemoteParent)"
if ($LASTEXITCODE -ne 0) {
ssh -o StrictHostKeyChecking=accept-new $Target "sudo -n true"
if ($LASTEXITCODE -eq 0) {
$script:UseSudo = $true
} else {
throw "Remote root is not writable and passwordless sudo is unavailable. Re-run with a writable -RemoteRoot or configure sudo."
}
}
}
$prepare = @(
"set -eu"
"mkdir -p $(Quote-Sh "$RemoteRoot/releases")"
"rm -rf $(Quote-Sh $RemoteRelease)"
"mkdir -p $(Quote-Sh $RemoteRelease)"
"unzip -q -o $(Quote-Sh $RemoteZip) -d $(Quote-Sh $RemoteRelease)"
"test -f $(Quote-Sh "$RemoteRelease/index.html")"
"test -f $(Quote-Sh "$RemoteRelease/demo-manifest.json")"
"test -f $(Quote-Sh "$RemoteRelease/app/virtual-controller.html")"
"if [ -L $(Quote-Sh "$RemoteRoot/current") ] || [ -e $(Quote-Sh "$RemoteRoot/current") ]; then rm -f $(Quote-Sh "$RemoteRoot/previous"); ln -sfn `"`$(readlink -f $(Quote-Sh "$RemoteRoot/current"))`" $(Quote-Sh "$RemoteRoot/previous"); fi"
"ln -sfn $(Quote-Sh "$RemoteRelease") $(Quote-Sh "$RemoteRoot/current")"
"rm -f $(Quote-Sh $RemoteZip)"
) -join "; "
Invoke-Remote (Remote-Cmd $prepare)
$restart = "if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files kdl-site-8095.service >/dev/null 2>&1; then systemctl restart kdl-site-8095; fi"
Invoke-Remote (Remote-Cmd $restart)
$smoke = @{
release_id = $ReleaseId
zip = $ZipPath
target = $Target
remote_root = $RemoteRoot
remote_release = $RemoteRelease
base_url = $BaseUrl
deployed_at = (Get-Date).ToUniversalTime().ToString("o")
urls = @()
}
if (-not $SkipSmoke) {
$nodeSmoke = @"
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const baseUrl = "$BaseUrl";
const get = async (path) => {
const response = await fetch(baseUrl + path);
const buffer = Buffer.from(await response.arrayBuffer());
if (response.status !== 200) {
throw new Error(path + " returned " + response.status);
}
return {
path,
status: response.status,
bytes: buffer.length,
text: buffer.toString("utf8")
};
};
const manifestResponse = await get("/demo-manifest.json");
const manifest = JSON.parse(manifestResponse.text);
const jobId = manifest.job_id;
const paths = [
"/",
"/demo-manifest.json",
"/spec-programs/manifest.json",
"/app/virtual-controller.html",
"/test-results/abb120-spec/" + jobId + "/report.json",
"/test-results/abb120-spec/" + jobId + "/report.html",
"/test-results/virtual-controller/virtual-controller-desktop.png",
"/test-results/virtual-controller/virtual-controller-mobile.png"
];
const urls = [];
for (const path of paths) {
const result = path === "/demo-manifest.json" ? manifestResponse : await get(path);
urls.push({ url: baseUrl + path, status: result.status, bytes: result.bytes });
}
const reportResponse = await get("/test-results/abb120-spec/" + jobId + "/report.json");
const report = JSON.parse(reportResponse.text);
if (Number(manifest.program_count) !== 19) {
throw new Error("Expected program_count=19, got " + manifest.program_count);
}
if (Number(report.summary.fail) !== 0) {
throw new Error("Expected summary.fail=0, got " + report.summary.fail);
}
console.log(JSON.stringify({
job_id: jobId,
program_count: Number(manifest.program_count),
summary_fail: Number(report.summary.fail),
urls
}));
"@
$nodeOutput = $nodeSmoke | node --input-type=module
if ($LASTEXITCODE -ne 0) {
throw "Smoke check failed"
}
$nodeSmokeResult = $nodeOutput | Select-Object -Last 1 | ConvertFrom-Json
$smoke.job_id = $nodeSmokeResult.job_id
$smoke.program_count = [int]$nodeSmokeResult.program_count
$smoke.summary_fail = [int]$nodeSmokeResult.summary_fail
$smoke.urls = @($nodeSmokeResult.urls)
}
$SmokePath = Join-Path $DeployRoot "kdl-olp-demo-$ReleaseId.deploy.json"
$smoke | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $SmokePath -Encoding UTF8
$smoke | ConvertTo-Json -Depth 8

View File

@@ -0,0 +1,610 @@
import { execFileSync } from "node:child_process";
import {
copyFileSync,
existsSync,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
statSync,
writeFileSync
} from "node:fs";
import { dirname, join, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
const webRoot = join(root, "kdl-wasm", "web");
const resultRoot = join(webRoot, "test-results", "abb120-spec");
const specRoot = join(webRoot, "tests", "fixtures", "abb120", "spec-programs");
const virtualControllerEvidencePath = join(webRoot, "test-results", "virtual-controller", "evidence.json");
const outputPath = join(root, "work", "doc", "通用机器人离线编程系统测试文档.docx");
const stagingRoot = join(webRoot, "test-results", "docx-build");
const jobId = process.argv[2] ?? latestJobId();
const jobDir = join(resultRoot, jobId);
const job = readJson(join(jobDir, "job.json"));
const report = readJson(join(jobDir, "report.json"));
const manifest = readJson(join(jobDir, "manifest.json"));
const uiEvidence = readJson(virtualControllerEvidencePath);
const generatedAt = formatShanghaiTime(new Date());
const descriptionByProgram = {
W2_00_MinimalModule: "最小模块、language/module/proc main、常量 speed/zone、joint_target、MoveJ 基础执行。",
W2_10_DataTargetToolFrame: "数据类型、tool、frame、pose、poseq、joint_target、pose_target、工具和工件坐标切换。",
W2_20_ExpressionMath: "算术、比较、逻辑、括号、单位后缀、pi/e、三角函数和编译期求值。",
W2_30_MotionAllTypes: "MoveJ、MoveL、MoveC、set_tool、set_frame、set_speed、set_zone 和 inline 参数优先级。",
W2_40_PathEvents: "path defaults/source、point、event before/after/at distance、run_path。",
W2_50_OperationProcess: "operation kind/process/start_action/end_action、run_operation。",
W2_60_IOWaitPulse: "io.di/do/ai/ao/gi/go/ri/ro、wait、timeout、on_timeout、pulse 和边沿条件。",
W2_70_ControlFlow: "if/elseif/else、while、for、switch、break、continue 流程控制。",
W2_80_ProcFuncCall: "proc、in/out/inout、call、return、func 返回值和作用域。",
W2_90_ExceptionAlarm: "alarm、raise、try/catch/finally、trap/task P1 边界诊断。",
W2_99_FullSpecExample: "完整示例,覆盖 tool/frame、path、operation、IO event、run_operation 和回 home。",
W2_E10_ExpressionDiagnostics: "表达式负向测试:未知符号、未知函数、参数数量、数学域、除零、单位不匹配。",
W2_E20_SemanticDiagnostics: "语义负向测试重复符号、out/inout 非左值、缺失调用目标、函数副作用、缺失目标。",
W2_E30_MotionDiagnostics: "运动负向测试:关节限位、不可达 pose、空 path 等 KDL/Path 诊断。",
W2_E40_ControlFlowDiagnostics: "流程控制负向测试:非法 break/continue、jump、重复 case、非常量 case、缺失 label。",
W2_E50_RuntimeTimeout: "运行时超时负向测试wait timeout、on_timeout、报警 source map。",
W2_P10_BrandHints: "品牌提示后处理测试post_hint、@brand.* 消费或报告。",
W2_P20_CrossBrandMotion: "跨品牌运动后处理ABB/FANUC/KUKA motion、speed、zone、IO、wait 映射。",
W2_P30_Roundtrip: "后处理和导入回读测试post 后 ABB import roundtrip记录差异和警告。"
};
const commandResults = [
{
command: "npm run typecheck",
scope: "TypeScript 静态类型检查",
process: "执行 tsc -p kdl-wasm/web/tsconfig.json --noEmit检查 Web、GRL、runtime、post 和 suite 代码类型。",
result: "通过,未输出 TypeScript 错误。"
},
{
command: "npm test",
scope: "全量 Vitest 自动化测试",
process: "执行 vitest run --config kdl-wasm/web/vitest.config.ts覆盖 KDL、GRL、runtime、controller、post/import、workspace、report、docs 和 ABB120 integration。",
result: "通过41 个 test files、155 个 tests 全部 passed。"
},
{
command: "npm run suite:abb120-spec",
scope: "ABB120 GRL 规范程序套件",
process: "读取 manifest.json 和 19 个 GRL 程序,逐项执行 parse、semantic compile、runtime/static/post 检查,并输出 job/report/program artifacts。",
result: `通过,生成 ${job.job_id}programs=${report.summary.programs}pass=${report.summary.pass}expected diagnostic=${report.summary.diagnostic}fail=${report.summary.fail}missingSections=${report.coverage.missingSections.length}`
},
{
command: "npm run verify:virtual-controller",
scope: "虚拟控制器 UI 和截图验证",
process: "使用 Chrome DevTools Protocol 打开 virtual-controller.html分别验证 desktop/mobile 视口、点击 load/run/DI1、检查主要面板、状态、wait 和横向溢出,并截图。",
result: `通过desktop=${uiEvidence.desktop.screenshotBytes} bytesmobile=${uiEvidence.mobile.screenshotBytes} bytesstate=${uiEvidence.desktop.state}/${uiEvidence.mobile.state}wait=${uiEvidence.desktop.wait}/${uiEvidence.mobile.wait}`
}
];
const programs = job.programs.map((program) => {
const sourcePath = join(specRoot, program.file);
return {
...program,
manifestEntry: manifest.programs.find((entry) => entry.program_id === program.program_id),
sourcePath,
source: readFileSync(sourcePath, "utf8")
};
});
buildDocx();
console.log(JSON.stringify({ outputPath, jobId, programs: programs.length }, null, 2));
function buildDocx() {
assertSafeStaging(stagingRoot);
rmSync(stagingRoot, { recursive: true, force: true });
mkdirSync(join(stagingRoot, "_rels"), { recursive: true });
mkdirSync(join(stagingRoot, "docProps"), { recursive: true });
mkdirSync(join(stagingRoot, "word", "_rels"), { recursive: true });
mkdirSync(join(stagingRoot, "word", "media"), { recursive: true });
const images = copyImages();
writeFileSync(join(stagingRoot, "[Content_Types].xml"), contentTypesXml(), "utf8");
writeFileSync(join(stagingRoot, "_rels", ".rels"), packageRelsXml(), "utf8");
writeFileSync(join(stagingRoot, "docProps", "core.xml"), corePropsXml(), "utf8");
writeFileSync(join(stagingRoot, "docProps", "app.xml"), appPropsXml(), "utf8");
writeFileSync(join(stagingRoot, "word", "styles.xml"), stylesXml(), "utf8");
writeFileSync(join(stagingRoot, "word", "_rels", "document.xml.rels"), documentRelsXml(images), "utf8");
writeFileSync(join(stagingRoot, "word", "document.xml"), documentXml(images), "utf8");
if (existsSync(outputPath)) {
rmSync(outputPath, { force: true });
}
zipDirectory(stagingRoot, outputPath);
}
function copyImages() {
const images = [
{
id: "rIdImage1",
fileName: "virtual-controller-desktop.png",
source: uiEvidence.desktop.screenshot,
title: "虚拟控制器桌面端截图",
cx: 5943600,
cy: 3962400
},
{
id: "rIdImage2",
fileName: "virtual-controller-mobile.png",
source: uiEvidence.mobile.screenshot,
title: "虚拟控制器移动端截图",
cx: 2743200,
cy: 5943600
}
];
for (const image of images) {
copyFileSync(image.source, join(stagingRoot, "word", "media", image.fileName));
}
return images;
}
function documentXml(images) {
const body = [];
body.push(heading("通用机器人离线编程系统测试文档", 1));
body.push(p(`生成时间:${generatedAt}`));
body.push(p(`测试对象:通用机器人离线编程系统 / ABB IRB120 虚拟控制器 / GRL 规范程序套件`));
body.push(p(`工作区:${root}`));
body.push(p(`最新测试 job${job.job_id}`));
body.push(heading("一、测试结论", 1));
body.push(table([
["项目", "结果"],
["测试结论", "通过。本轮未发现非预期失败5 个 diagnostic 程序为预期负向测试。"],
["规范覆盖", `覆盖章节 ${report.coverage.coveredSections.join("、")};缺失章节:${report.coverage.missingSections.length === 0 ? "无" : report.coverage.missingSections.join("、")}`],
["程序统计", `${report.summary.programs} 个 GRL 规范程序pass=${report.summary.pass}expected diagnostic=${report.summary.diagnostic}fail=${report.summary.fail}`],
["测试层级", `Runtime=${report.coverage.runtimePrograms}Static=${report.coverage.staticPrograms}Post=${report.coverage.postPrograms}`],
["主要证据", `${relative(jobDir)}${relative(dirname(uiEvidence.desktop.screenshot))}`]
]));
body.push(heading("二、测试范围", 1));
body.push(p("本次测试覆盖离线编程系统的语法解析、语义编译、KDL 运动规划接口、虚拟控制器状态机、IO/wait/pulse、路径和工艺操作、异常报警、三品牌后处理、导入回读、工作台 UI 响应和截图证据。"));
body.push(table([
["范围", "覆盖内容"],
["GRL 语言", "词法、顶层结构、类型系统、表达式、目标点、速度、zone、motion、path、operation、IO、流程控制、proc/func、异常和 P1 边界。"],
["运动与 KDL", "ABB IRB120 fixture、MoveJ/MoveL/MoveC、path planning、joint limit、unreachable target、trajectory summary。"],
["虚拟控制器", "loadProgram、start、stepInto、hold、resume、stepMotion、stop、resetFault、runtime trace、motion queue、IO image。"],
["后处理与导入", "ABB/FANUC/KUKA 输出文件、post report、ABB import roundtrip。"],
["用户界面", "virtual-controller.html 桌面端和移动端渲染、交互、主要面板可见性和截图。"]
]));
body.push(heading("三、测试命令与执行过程", 1));
body.push(table([
["命令", "测试内容", "执行过程", "执行结果"],
...commandResults.map((item) => [item.command, item.scope, item.process, item.result])
]));
body.push(heading("四、截图证据", 1));
body.push(p(`截图验证应用:${uiEvidence.app}`));
body.push(p(`Chrome${uiEvidence.chrome}`));
body.push(heading("4.1 桌面端截图", 2));
body.push(p(`视口:${uiEvidence.desktop.viewport.width}x${uiEvidence.desktop.viewport.height}state=${uiEvidence.desktop.state}wait=${uiEvidence.desktop.wait}trace=${uiEvidence.desktop.trace};截图:${relative(uiEvidence.desktop.screenshot)}`));
body.push(imageParagraph(images[0], 1));
body.push(heading("4.2 移动端截图", 2));
body.push(p(`视口:${uiEvidence.mobile.viewport.width}x${uiEvidence.mobile.viewport.height}deviceScaleFactor=${uiEvidence.mobile.viewport.deviceScaleFactor}state=${uiEvidence.mobile.state}wait=${uiEvidence.mobile.wait}trace=${uiEvidence.mobile.trace};截图:${relative(uiEvidence.mobile.screenshot)}`));
body.push(imageParagraph(images[1], 2));
body.push(heading("五、规范覆盖矩阵", 1));
body.push(table([
["规范章节", "覆盖层级", "程序"],
...manifest.coverage_matrix.map((item) => [
String(item.spec_section),
item.coverage_level,
item.program_ids.join("、")
])
]));
body.push(heading("六、全部测试程序明细与源码", 1));
for (const [index, program] of programs.entries()) {
appendProgramSection(body, program, index + 1);
}
body.push(heading("七、主要产物索引", 1));
body.push(table([
["产物", "路径"],
["job.json", relative(join(jobDir, "job.json"))],
["report.json", relative(join(jobDir, "report.json"))],
["report.html", relative(join(jobDir, "report.html"))],
["manifest.json", relative(join(jobDir, "manifest.json"))],
["桌面端截图", relative(uiEvidence.desktop.screenshot)],
["移动端截图", relative(uiEvidence.mobile.screenshot)],
["UI evidence.json", relative(virtualControllerEvidencePath)]
]));
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"
xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex"
xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex"
xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex"
xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex"
xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex"
xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex"
xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex"
xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink"
xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:oel="http://schemas.microsoft.com/office/2019/extlst"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"
xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"
xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du"
xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"
mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16du wp14">
<w:body>
${body.join("\n")}
<w:sectPr>
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="850" w:header="708" w:footer="708" w:gutter="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="312"/>
</w:sectPr>
</w:body>
</w:document>`;
}
function appendProgramSection(body, program, index) {
const expectedDiagnostics = program.manifestEntry?.expected_diagnostics ?? [];
const actualCodes = [...new Set(program.diagnostics.map((diagnostic) => diagnostic.code))];
body.push(heading(`6.${index} ${program.program_id}`, 2));
body.push(table([
["字段", "内容"],
["测试内容", descriptionByProgram[program.program_id] ?? "按 manifest 执行规范测试。"],
["源码文件", relative(program.sourcePath)],
["覆盖层级", program.coverage_level],
["覆盖章节", program.spec_sections.join("、")],
["预期状态", program.expected_status],
["实际状态", program.status],
["预期诊断", expectedDiagnostics.length === 0 ? "无" : expectedDiagnostics.join("、")],
["实际诊断代码", actualCodes.length === 0 ? "无" : actualCodes.join("、")],
["输入哈希", program.input_hash],
["源码行数", String(program.source.split(/\r?\n/).length)]
]));
body.push(heading("测试过程", 3));
for (const step of programSteps(program)) {
body.push(p(step));
}
body.push(heading("执行结果摘要", 3));
body.push(table(programResultRows(program)));
if (program.controller?.commands?.length) {
body.push(heading("虚拟控制器命令轨迹", 3));
body.push(table([
["命令", "前状态", "后状态", "结果", "诊断"],
...program.controller.commands.map((command) => [
command.command,
command.before ?? "",
command.after ?? "",
command.result ?? "",
command.diagnostics.length === 0 ? "无" : command.diagnostics.map((diagnostic) => diagnostic.code).join("、")
])
]));
}
body.push(heading("证据文件", 3));
body.push(table([
["类型", "路径"],
...Object.entries(program.artifacts).map(([key, value]) => [key, relative(join(resultRoot, value))])
]));
body.push(heading("程序源码", 3));
body.push(codeBlock(program.source));
}
function programSteps(program) {
const steps = [
`1. 读取源码 ${relative(program.sourcePath)},加载 program_id、spec_sections、coverage_level、expected_status 和 expected_diagnostics。`,
"2. 执行 parseGrl完成词法、语法、模块结构和 source map 解析。",
"3. 执行 compileSemanticProgram生成语义 IR、符号表、procedure/path/operation、KDL motion/path request 和诊断列表。"
];
if (program.coverage_level === "Runtime") {
steps.push(`4. 加载 IR 到 VirtualController${manifest.runtime_commands.join(" -> ")} 执行控制器命令,采集 controller snapshot、motion queue、runtime trace、IO image 和 trajectory summary。`);
steps.push("5. 对比实际状态与 manifest 预期状态;对比实际诊断代码与 expected_diagnostics写入 compile/controller/motion-queue/trace/io/trajectory/post/roundtrip 证据。");
} else if (program.coverage_level === "Static") {
steps.push("4. 执行 static preflight diagnostics覆盖表达式、语义、运动、path、流程控制等负向检查不要求进入 happy-path 运行。");
steps.push("5. 对比实际诊断代码与 expected_diagnostics确认 diagnostic 状态为预期负向结果,并写入 compile 及各类空/摘要证据文件。");
} else {
steps.push("4. 执行 postProcessAllBrands生成 ABB/FANUC/KUKA 输出文件名和 post report。");
steps.push("5. 执行 ABB import roundtrip 摘要检查,记录 pass/warn/fail 与导入诊断,并写入 post-report/roundtrip 证据。");
}
return steps;
}
function programResultRows(program) {
const rows = [
["项目", "结果"],
["解析", program.compile.parsed ? "parsed=true" : "parsed=false"],
["模块名", program.compile.moduleName ?? ""],
["sourceMapEntries", String(program.compile.sourceMapEntries)],
["symbol/procedure/path/operation", `${program.compile.symbolCount}/${program.compile.procedureCount}/${program.compile.pathCount}/${program.compile.operationCount}`],
["KDL motion/path requests", `${program.compile.kdlMotionRequests}/${program.compile.kdlPathRequests}`],
["状态", program.status]
];
if (program.controller) {
rows.push(["controller final state", program.controller.snapshot.state.state]);
rows.push(["runtime trace events", String(program.trace?.length ?? 0)]);
rows.push(["motion queue items", String(program.motionQueue?.items?.length ?? 0)]);
rows.push(["IO image count", String(Object.keys(program.io?.image ?? {}).length)]);
}
if (program.trajectory) {
rows.push(["trajectory sample/duration", `${program.trajectory.sampleCount}/${program.trajectory.duration}`]);
}
if (program.post) {
rows.push(["post filenames", program.post.filenames.join("、")]);
rows.push(["post report codes", program.post.report.length === 0 ? "无" : [...new Set(program.post.report.map((issue) => issue.code))].join("、")]);
}
if (program.roundtrip) {
rows.push(["roundtrip", `${program.roundtrip.status}; ${program.roundtrip.diagnostics.map((diagnostic) => diagnostic.code).join("、") || "无诊断"}`]);
}
rows.push(["诊断数量", String(program.diagnostics.length)]);
return rows;
}
function heading(text, level) {
return paragraph(text, `Heading${Math.min(level, 3)}`);
}
function p(text) {
return paragraph(text, "BodyText");
}
function paragraph(text, style) {
return `<w:p><w:pPr><w:pStyle w:val="${style}"/></w:pPr>${run(text)}</w:p>`;
}
function run(text) {
return `<w:r><w:t xml:space="preserve">${escapeXml(String(text))}</w:t></w:r>`;
}
function codeBlock(text) {
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
const lines = normalized.endsWith("\n") ? normalized.slice(0, -1).split("\n") : normalized.split("\n");
return lines.map((line) =>
`<w:p><w:pPr><w:pStyle w:val="Code"/></w:pPr><w:r><w:t xml:space="preserve">${escapeXml(line === "" ? " " : line)}</w:t></w:r></w:p>`
).join("\n");
}
function table(rows) {
const width = Math.floor(9000 / Math.max(1, rows[0]?.length ?? 1));
return `<w:tbl>
<w:tblPr><w:tblStyle w:val="TableGrid"/><w:tblW w:w="0" w:type="auto"/><w:tblLook w:val="04A0"/></w:tblPr>
${rows.map((row, rowIndex) => `<w:tr>${row.map((cell) => tableCell(cell, width, rowIndex === 0)).join("")}</w:tr>`).join("\n")}
</w:tbl>`;
}
function tableCell(text, width, header) {
return `<w:tc>
<w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr>
<w:p><w:pPr>${header ? "<w:pStyle w:val=\"TableHeader\"/>" : ""}</w:pPr>${run(text)}</w:p>
</w:tc>`;
}
function imageParagraph(image, docPrId) {
return `<w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${image.cx}" cy="${image.cy}"/>
<wp:effectExtent l="0" t="0" r="0" b="0"/>
<wp:docPr id="${docPrId}" name="${escapeXml(image.title)}"/>
<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr><pic:cNvPr id="${docPrId}" name="${escapeXml(image.fileName)}"/><pic:cNvPicPr/></pic:nvPicPr>
<pic:blipFill><a:blip r:embed="${image.id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>
<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${image.cx}" cy="${image.cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing></w:r></w:p>`;
}
function contentTypesXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Default Extension="png" ContentType="image/png"/>
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>`;
}
function packageRelsXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
</Relationships>`;
}
function documentRelsXml(images) {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
${images.map((image) => `<Relationship Id="${image.id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${image.fileName}"/>`).join("\n")}
</Relationships>`;
}
function corePropsXml() {
const iso = new Date().toISOString();
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:dcmitype="http://purl.org/dc/dcmitype/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dc:title>通用机器人离线编程系统测试文档</dc:title>
<dc:creator>Codex</dc:creator>
<cp:lastModifiedBy>Codex</cp:lastModifiedBy>
<dcterms:created xsi:type="dcterms:W3CDTF">${iso}</dcterms:created>
<dcterms:modified xsi:type="dcterms:W3CDTF">${iso}</dcterms:modified>
</cp:coreProperties>`;
}
function appPropsXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
<Application>Codex</Application>
<DocSecurity>0</DocSecurity>
<ScaleCrop>false</ScaleCrop>
<Company>KDL Work</Company>
<LinksUpToDate>false</LinksUpToDate>
<SharedDoc>false</SharedDoc>
<HyperlinksChanged>false</HyperlinksChanged>
<AppVersion>16.0000</AppVersion>
</Properties>`;
}
function stylesXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:style w:type="paragraph" w:default="1" w:styleId="Normal">
<w:name w:val="Normal"/>
<w:qFormat/>
<w:rPr><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="21"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="BodyText">
<w:name w:val="Body Text"/>
<w:basedOn w:val="Normal"/>
<w:pPr><w:spacing w:after="120" w:line="276" w:lineRule="auto"/></w:pPr>
<w:rPr><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="21"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="360" w:after="180"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="32"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading2">
<w:name w:val="heading 2"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="280" w:after="140"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="27"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading3">
<w:name w:val="heading 3"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="180" w:after="100"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="23"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Code">
<w:name w:val="Code"/>
<w:basedOn w:val="Normal"/>
<w:pPr><w:spacing w:before="0" w:after="0" w:line="240" w:lineRule="auto"/></w:pPr>
<w:rPr><w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Consolas"/><w:sz w:val="16"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="TableHeader">
<w:name w:val="Table Header"/>
<w:basedOn w:val="Normal"/>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="20"/></w:rPr>
</w:style>
<w:style w:type="table" w:default="1" w:styleId="TableNormal">
<w:name w:val="Normal Table"/>
<w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr>
</w:style>
<w:style w:type="table" w:styleId="TableGrid">
<w:name w:val="Table Grid"/>
<w:basedOn w:val="TableNormal"/>
<w:tblPr><w:tblBorders><w:top w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:left w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:bottom w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:right w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:insideH w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:insideV w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/></w:tblBorders></w:tblPr>
</w:style>
</w:styles>`;
}
function latestJobId() {
const jobs = readdirSync(resultRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory() && existsSync(join(resultRoot, entry.name, "job.json")))
.map((entry) => ({
name: entry.name,
mtimeMs: statSync(join(resultRoot, entry.name, "job.json")).mtimeMs
}))
.sort((a, b) => b.mtimeMs - a.mtimeMs);
if (jobs.length === 0) {
throw new Error(`No abb120 spec job found in ${resultRoot}`);
}
return jobs[0].name;
}
function readJson(path) {
return JSON.parse(readFileSync(path, "utf8"));
}
function relative(path) {
return path.replace(`${root}${sep}`, "").replaceAll("\\", "/");
}
function escapeXml(value) {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&apos;");
}
function psSingleQuoted(value) {
return `'${String(value).replaceAll("'", "''")}'`;
}
function zipDirectory(sourceDir, destinationFile) {
const script = [
"Add-Type -AssemblyName System.IO.Compression.FileSystem",
`$src = ${psSingleQuoted(sourceDir)}`,
`$dst = ${psSingleQuoted(destinationFile)}`,
"if (Test-Path -LiteralPath $dst) { Remove-Item -LiteralPath $dst -Force }",
"[System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst)"
].join("\n");
execFileSync("powershell", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], {
stdio: "inherit"
});
}
function assertSafeStaging(path) {
const allowedRoot = join(webRoot, "test-results") + sep;
const resolved = resolve(path);
if (!resolved.startsWith(allowedRoot)) {
throw new Error(`Refusing to clear staging path outside test-results: ${resolved}`);
}
}
function formatShanghaiTime(date) {
const parts = new Intl.DateTimeFormat("zh-CN", {
timeZone: "Asia/Shanghai",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
}).formatToParts(date);
const value = Object.fromEntries(parts.map((part) => [part.type, part.value]));
return `${value.year}-${value.month}-${value.day} ${value.hour}:${value.minute}:${value.second} Asia/Shanghai`;
}

View File

@@ -0,0 +1,598 @@
import { execFileSync } from "node:child_process";
import {
copyFileSync,
existsSync,
mkdirSync,
readFileSync,
rmSync,
writeFileSync
} from "node:fs";
import { join, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
const webRoot = join(root, "kdl-wasm", "web");
const docRoot = join(root, "work", "doc");
const stagingRoot = join(webRoot, "test-results", "grl-manual-docx-build");
const outputPath = join(docRoot, "GRL功能语法逻辑与程序创建使用手册.docx");
const flowDir = join(docRoot, "通用机器人项目功能与数据流程图-png");
const flowImages = [
{ source: join(flowDir, "flow-01.png"), title: "系统功能总览图", cx: 5943600, cy: 3343275 },
{ source: join(flowDir, "flow-02.png"), title: "GRL 到 IR 编译流程图", cx: 5943600, cy: 3343275 },
{ source: join(flowDir, "flow-03.png"), title: "运动规划与 KDL 数据流图", cx: 5943600, cy: 3343275 },
{ source: join(flowDir, "flow-04.png"), title: "虚拟控制器执行流程图", cx: 5943600, cy: 3343275 },
{ source: join(flowDir, "flow-05.png"), title: "后处理与导入回读流程图", cx: 5943600, cy: 3343275 }
];
const uiImages = [
{
source: join(webRoot, "test-results", "virtual-controller", "virtual-controller-desktop.png"),
title: "虚拟控制器桌面端界面",
cx: 5943600,
cy: 3962400
},
{
source: join(webRoot, "test-results", "virtual-controller", "virtual-controller-mobile.png"),
title: "虚拟控制器移动端界面",
cx: 2743200,
cy: 5943600
}
];
const smokeSourcePath = join(webRoot, "tests", "fixtures", "abb120", "programs", "A120_00_Smoke.grl");
const blendSourcePath = join(webRoot, "tests", "fixtures", "abb120", "programs", "A120_20_CartesianBlend.grl");
const ioSourcePath = join(webRoot, "tests", "fixtures", "abb120", "spec-programs", "runtime", "W2_60_IOWaitPulse.grl");
const fullExamplePath = join(webRoot, "tests", "fixtures", "abb120", "spec-programs", "runtime", "W2_99_FullSpecExample.grl");
const generatedAt = formatShanghaiTime(new Date());
buildDocx();
console.log(JSON.stringify({ outputPath }, null, 2));
function buildDocx() {
assertSafeStaging(stagingRoot);
rmSync(stagingRoot, { recursive: true, force: true });
mkdirSync(join(stagingRoot, "_rels"), { recursive: true });
mkdirSync(join(stagingRoot, "docProps"), { recursive: true });
mkdirSync(join(stagingRoot, "word", "_rels"), { recursive: true });
mkdirSync(join(stagingRoot, "word", "media"), { recursive: true });
const images = copyImages([...flowImages, ...uiImages]);
writeFileSync(join(stagingRoot, "[Content_Types].xml"), contentTypesXml(), "utf8");
writeFileSync(join(stagingRoot, "_rels", ".rels"), packageRelsXml(), "utf8");
writeFileSync(join(stagingRoot, "docProps", "core.xml"), corePropsXml(), "utf8");
writeFileSync(join(stagingRoot, "docProps", "app.xml"), appPropsXml(), "utf8");
writeFileSync(join(stagingRoot, "word", "styles.xml"), stylesXml(), "utf8");
writeFileSync(join(stagingRoot, "word", "_rels", "document.xml.rels"), documentRelsXml(images), "utf8");
writeFileSync(join(stagingRoot, "word", "document.xml"), documentXml(images), "utf8");
if (existsSync(outputPath)) {
rmSync(outputPath, { force: true });
}
zipDirectory(stagingRoot, outputPath);
}
function documentXml(images) {
const body = [];
body.push(heading("GRL 功能、语法逻辑与程序创建使用手册", 1));
body.push(p(`生成时间:${generatedAt}`));
body.push(p("适用对象:通用机器人离线编程系统用户、工艺工程师、自动编程开发人员、虚拟调试人员。"));
body.push(p("手册目标:用中文说明 GRL 的功能边界、语法逻辑、程序对象关系、创建程序步骤、仿真检查和后处理输出方式,并通过图示和源码示例帮助用户快速编写可运行程序。"));
body.push(heading("一、GRL 是什么", 1));
body.push(p("GRL全称 Generic Robot Language是本离线编程系统中的通用机器人程序语言。它不是 ABB、FANUC 或 KUKA 任一品牌语言的拷贝而是把多品牌机器人共同具备的目标点、运动、路径、工艺、IO、流程控制、异常和后处理语义抽象为统一文本。"));
body.push(table([
["目标", "说明"],
["统一描述", "用同一套 GRL 描述机器人程序、路径、工艺动作和 IO 逻辑。"],
["可编译", "GRL 经 lexer/parser/semantic analyzer 编译为统一 Executable IR。"],
["可仿真", "IR 可进入虚拟控制器运行,产生 trace、motion queue、IO image 和诊断。"],
["可后处理", "同一 IR 可输出 ABB RAPID、FANUC LS/TP 风格文本、KUKA KRL 原型程序。"],
["可维护", "文本稳定、可读、可 diff适合版本管理和自动生成。"]
]));
body.push(heading("二、系统功能总览", 1));
body.push(p("离线编程系统从项目数据、机器人模型和 GRL 程序出发经过语义编译、KDL 运动规划、虚拟控制器执行、诊断报告和多品牌后处理,形成完整离线开发闭环。"));
body.push(imageWithCaption(images[0], 1, "图 1 系统功能总览图"));
body.push(table([
["模块", "主要职责"],
["GRL 源码", "声明工具、坐标系、目标点、速度、zone、path、operation 和 proc。"],
["编译器", "把源码解析为 AST做符号解析、单位归一化、语义检查生成 IR 和 KDL request。"],
["KDL 运动规划", "处理 FK、IK、MoveJ、MoveL、MoveC、Path planning、可达性和轨迹采样。"],
["虚拟控制器", "执行 IR维护程序计数器、调用栈、报警队列、IO 镜像、运动队列和 trace。"],
["后处理器", "按 ABB/FANUC/KUKA 规则输出品牌程序,并记录无法保真映射的转换报告。"]
]));
body.push(heading("三、GRL 程序基本结构", 1));
body.push(p("一个 GRL 文件通常由 language 声明、module 声明、数据声明、目标点、路径、工艺操作和 main 子程序组成。最小程序只需要定义模块入口和一条运动。"));
body.push(codeBlock(readFileSync(smokeSourcePath, "utf8")));
body.push(table([
["结构", "作用"],
["language grl 0.1", "声明语言版本,便于后续兼容升级。"],
["module", "程序模块,类似 ABB MODULE、KUKA DEF 文件或 FANUC 程序容器。"],
["const/persistent/var", "声明常量、持久数据或局部变量。"],
["target", "声明 joint_target 或 pose_target。"],
["proc main()", "默认入口程序。虚拟控制器从 main 开始执行。"],
["movej/movel/movec", "基础运动指令,最终进入 KDL 规划或品牌后处理。"]
]));
body.push(heading("四、对象模型和语法逻辑", 1));
body.push(p("GRL 的语法逻辑建议按“数据先声明、路径再组织、工艺再封装、入口只调用”的方式理解。手写小程序可以直接在 main 中写运动,自动编程和复杂工艺应优先生成 path 和 operation。"));
body.push(imageWithCaption(images[1], 2, "图 2 GRL 到 IR 编译流程图"));
body.push(table([
["对象", "语法", "使用建议"],
["工具", "persistent tool gripper = tool { ... }", "描述 TCP、质量、重心。运动时通过 tool 参数或 path defaults 引用。"],
["坐标系", "persistent frame fixture = frame { ... }", "描述工件坐标或基坐标。目标点和路径应显式绑定 frame。"],
["速度", "const speed v = linear(300 mm/s) / joint(50 %)", "按运动类型选择 joint、linear、angular。"],
["过渡", "const zone z10 = z(10 mm) / fine / cnt(30)", "fine 精确到点z/cnt/continuous 用于连续过渡。"],
["目标点", "target pick = pose_target { pose: pose(...) }", "关节目标用 joint_target笛卡尔点用 pose_target。"],
["路径", "path pick_path { defaults ... point ... event ... }", "自动编程优先生成 path点名保持稳定。"],
["工艺", "operation pick_op { kind: handling path: pick_path ... }", "封装路径、工艺参数、start_action/end_action。"],
["入口程序", "proc main() run_operation pick_op end", "入口程序保持短,便于调试和后处理。"]
]));
body.push(heading("五、表达式、单位和常量求值", 1));
body.push(p("GRL 支持带单位表达式。编译器会在需要常量的位置做单位归一化,例如 mm 转 m、deg 转 rad、ms 转 s、% 转比例。这样同一程序在仿真和后处理中使用统一数值。"));
body.push(table([
["类别", "示例", "说明"],
["长度", "100 mm、0.25 m", "内部统一为 meter。"],
["角度", "90 deg、1.57 rad", "内部统一为 radian。"],
["时间", "200 ms、2 s", "内部统一为 second。"],
["速度", "linear(300 mm/s)、joint(50 %)", "分别表示 TCP 线速度和关节速度比例。"],
["数学函数", "atan2(0, 1)、max(50 mm/s, 150 mm/s)", "支持常用三角函数和数值函数。"],
["单位检查", "10 mm + 2 s", "不同维度相加会产生诊断。"]
]));
body.push(heading("六、运动语法", 1));
body.push(p("运动指令分为 MoveJ、MoveL、MoveC 三类。MoveJ 走关节空间MoveL 走 TCP 直线MoveC 走 TCP 圆弧。每条运动最终都需要确定 target、speed、zone、tool 和 frame。"));
body.push(imageWithCaption(images[2], 3, "图 3 运动规划与 KDL 数据流图"));
body.push(table([
["指令", "语法", "语义", "品牌映射"],
["movej", "movej home speed v_joint zone fine", "关节空间运动,适合回零和快速接近。", "ABB MoveJ / FANUC J / KUKA PTP"],
["movel", "movel pick speed v_linear zone z10", "TCP 直线运动,适合接近、加工、搬运直线段。", "ABB MoveL / FANUC L / KUKA LIN"],
["movec", "movec via mid target arc_end speed v zone z10", "TCP 圆弧运动,通过 via 点到终点。", "ABB MoveC / FANUC C / KUKA CIRC"],
["run_path", "run_path cart_path", "执行已声明路径。", "可展开为品牌运动语句"],
["run_operation", "run_operation pick_op", "执行工艺操作,包含 action 和 path。", "按品牌能力展开或报告"]
]));
body.push(p("下面是当前工作区中的笛卡尔混合路径示例,包含 tool/frame、表达式速度、zone clamp、MoveL、MoveC 和 run_path。"));
body.push(codeBlock(readFileSync(blendSourcePath, "utf8")));
body.push(heading("七、Path 和 Operation", 1));
body.push(p("Path 是离线编程的核心对象,适合承载 CAD 曲线、示教点、工艺采样点和路径事件。Operation 是对 Path 的工艺封装,适合表达搬运、焊接、喷涂、打磨、上下料等任务。"));
body.push(table([
["写法", "说明"],
["defaults", "为路径点设置默认 speed、zone、tool、frame减少重复。"],
["source", "记录 CAD 曲线、采样间距、规划来源等元数据。"],
["point", "定义路径点和该点运动方式。"],
["event before/after/at", "定义路径事件,例如到点后开夹爪、距离某点前开焊接。"],
["operation process", "记录工艺参数,例如 gripper、weld_mode、paint_recipe。"],
["start_action/end_action", "操作开始或结束时执行 IO、wait、pulse 等动作。"]
]));
body.push(heading("八、IO、wait 和 pulse", 1));
body.push(p("GRL 中的 IO 使用统一引用格式io.di、io.do、io.ai、io.ao、io.gi、io.go、io.ri、io.ro 和 io.alias。离线系统运行时维护虚拟 IO 镜像,程序、用户和脚本都可以写入这份镜像。"));
body.push(table([
["语法", "含义"],
["io.do[1] = true", "写数字输出。"],
["io.ao[1] = 0.75", "写模拟输出。"],
["wait io.di[1] == true timeout 2 s", "等待输入满足条件,超时产生诊断或报警。"],
["wait all(...)", "所有条件满足才继续。"],
["wait any(...)", "任一条件满足即继续。"],
["rising/falling/changed", "边沿或变化检测。"],
["pulse io.do[2] duration 100 ms", "输出置 true持续指定时间后自动复位。"]
]));
body.push(codeBlock(readFileSync(ioSourcePath, "utf8")));
body.push(heading("九、流程控制、子程序和异常", 1));
body.push(p("GRL 支持结构化控制和子程序。简单运行逻辑写在 proc 中,纯计算逻辑写在 func 中。func 默认不应产生运动、IO、wait、pulse 等副作用。"));
body.push(table([
["能力", "语法", "说明"],
["条件", "if / elseif / else / end", "按布尔条件选择执行分支。"],
["循环", "while、for to step", "执行重复逻辑break/continue 必须处于合法块内。"],
["多分支", "switch / case / default", "case 必须是常量表达式,不能重复。"],
["子程序", "proc name(in int slot) ... end", "可定义 in/out/inout 参数。"],
["函数", "func bool ok() return ... end", "有返回值,建议无副作用。"],
["报警", "alarm ID \"message\" severity warning", "进入虚拟控制器报警队列。"],
["异常", "raise、try/catch/finally", "P0 支持基础语义,复杂品牌恢复分阶段扩展。"]
]));
body.push(heading("十、从零创建一个 GRL 程序", 1));
body.push(p("建议按以下顺序创建程序。先保证数据和坐标清楚,再组织路径和工艺,最后在 main 中调用。"));
body.push(table([
["步骤", "操作", "检查点"],
["1", "创建 .grl 文件,写 language 和 module。", "模块名使用 ASCII 标识符,文件 UTF-8。"],
["2", "声明 tool 和 frame。", "TCP、质量、工件坐标单位明确。"],
["3", "声明 speed 和 zone。", "速度和过渡统一命名,例如 v_fast、v_pick、z10。"],
["4", "声明 target。", "home 用 joint_target工艺点用 pose_target。"],
["5", "创建 path。", "设置 defaults点名按 p000/p001 或语义名称稳定输出。"],
["6", "添加 path event 或 operation action。", "夹具、等待、脉冲、工艺开关不要散落在 main 中。"],
["7", "创建 operation。", "把 path 和工艺参数封装成可复用操作。"],
["8", "编写 proc main。", "只做 set_tool/set_frame、run_operation、回 home 等主流程。"],
["9", "运行编译和测试。", "执行 npm test 或 suite检查 diagnostics、trace、motion queue。"],
["10", "后处理输出。", "检查 ABB/FANUC/KUKA 转换报告,不支持项不能忽略。"]
]));
body.push(heading("十一、完整程序模板", 1));
body.push(p("下面给出一个可直接改写的模板,适合搬运、上下料、夹具动作和基础路径。"));
body.push(codeBlock(`language grl 0.1
module DemoPickPlace
persistent tool gripper = tool {
tcp: pose(0 mm, 0 mm, 120 mm, 0 deg, 0 deg, 0 deg),
mass: 1.5 kg
}
persistent frame fixture = frame {
origin: pose(800 mm, 0 mm, 0 mm, 0 deg, 0 deg, 0 deg)
}
const speed v_joint = joint(50 %)
const speed v_pick = linear(250 mm/s)
const zone z10 = z(10 mm)
const zone zf = fine
target home = joint_target { joints: [0 deg, 0 deg, 0 deg, 0 deg, 0 deg, 0 deg] }
target pick = pose_target { pose: pose(500 mm, 100 mm, 200 mm, 180 deg, 0 deg, 90 deg), tool: gripper, frame: fixture }
target place = pose_target { pose: pose(650 mm, -100 mm, 200 mm, 180 deg, 0 deg, 90 deg), tool: gripper, frame: fixture }
path pick_path {
defaults { speed: v_pick, zone: z10, tool: gripper, frame: fixture }
point approach movel pick offset z 100 mm
point at_pick movel pick zone zf
event after at_pick io.do[1] = true
event after at_pick wait io.di[1] == true timeout 2 s on_timeout alarm "Clamp close timeout"
point leave movel pick offset z 100 mm
}
operation pick_op {
kind: handling
path: pick_path
process { gripper: "main_clamp" }
}
proc main()
set_tool gripper
set_frame fixture
movej home speed v_joint zone zf
run_operation pick_op
movej home speed v_joint zone zf
end
end`));
body.push(heading("十二、编译、仿真和截图验证", 1));
body.push(imageWithCaption(images[3], 4, "图 4 虚拟控制器执行流程图"));
body.push(p("编译后,虚拟控制器会加载 IR从 main 开始执行,采集运行 trace、motion queue、IO image、报警队列和诊断。桌面端和移动端界面可用于检查程序结构、状态、编辑器、面板和运行结果。"));
body.push(imageWithCaption(images[5], 6, "图 5 虚拟控制器桌面端界面"));
body.push(imageWithCaption(images[6], 7, "图 6 虚拟控制器移动端界面"));
body.push(table([
["命令", "用途"],
["npm run typecheck", "检查 TypeScript 类型。"],
["npm test", "运行 KDL、GRL、runtime、post/import、integration 全量测试。"],
["npm run suite:abb120-spec", "运行 19 个 ABB120 GRL 规范程序,生成 job/report/program 证据。"],
["npm run verify:virtual-controller", "打开虚拟控制器 HTML执行交互并生成桌面/移动截图。"]
]));
body.push(heading("十三、后处理和跨品牌输出", 1));
body.push(imageWithCaption(images[4], 5, "图 7 后处理与导入回读流程图"));
body.push(table([
["GRL", "ABB RAPID", "FANUC LS/TP", "KUKA KRL"],
["module", "MODULE", "/PROG 或模块", "DEF/.src"],
["proc", "PROC", "CALL 子程序", "DEF 子程序"],
["movej", "MoveJ", "J P[...] ", "PTP"],
["movel", "MoveL", "L P[...] ", "LIN"],
["movec", "MoveC", "C P[...] ", "CIRC"],
["io.do[1] = true", "SetDO do1, 1", "DO[1]=ON", "$OUT[1]=TRUE"],
["wait io.di[1] == true", "WaitDI di1, 1", "WAIT DI[1]=ON", "WAIT FOR $IN[1]==TRUE"]
]));
body.push(p("后处理器遇到品牌不支持或只能近似表达的语义时,应写入转换报告。用户必须检查报告,再到真实控制器中做品牌校验和现场低速试运行。"));
body.push(heading("十四、常见诊断和处理建议", 1));
body.push(table([
["诊断", "常见原因", "处理方式"],
["GRL_EXPR_UNKNOWN_SYMBOL", "表达式引用未声明常量或变量。", "检查拼写和声明顺序。"],
["GRL_EXPR_UNIT_MISMATCH", "不同物理单位混合计算。", "统一长度、时间、角度或速度维度。"],
["GRL_TARGET_NOT_FOUND", "运动或路径点引用不存在目标点。", "补充 target 或修正名称。"],
["KDL_TARGET_UNREACHABLE", "笛卡尔点超出机器人工作空间。", "调整目标点、工具、坐标系或机器人配置。"],
["KDL_JOINT_LIMIT", "目标关节超过限位。", "修改 joint_target 或使用 IK 可达姿态。"],
["GRL_PATH_EMPTY", "path 没有 point。", "至少添加一个 point。"],
["VC_WAIT_TIMEOUT", "wait 条件在 timeout 内未满足。", "检查 IO 输入、脚本、超时时间和 on_timeout 动作。"],
["GRL_POST_UNSUPPORTED", "目标品牌后处理暂不支持该语义。", "查看转换报告,必要时改写为品牌可支持结构。"]
]));
body.push(heading("十五、编写规范建议", 1));
body.push(table([
["建议", "说明"],
["名称稳定", "target、path point、operation 命名稳定,便于 diff 和回读。"],
["显式单位", "自动生成程序尽量输出 mm、deg、mm/s、ms 等单位。"],
["入口简短", "main 中只保留主流程调用,复杂路径放入 path/operation。"],
["默认集中", "path defaults 中集中设置 speed、zone、tool、frame。"],
["IO 事件贴近路径", "与路径点相关的夹具和工艺开关写成 event。"],
["诊断必看", "error 必须修复warning 必须人工确认info 可作为转换记录。"],
["先仿真后后处理", "先通过 GRL 编译和虚拟控制器,再输出品牌程序。"],
["真实运行前校验", "后处理程序必须经过品牌控制器验证和现场低速试运行。"]
]));
body.push(heading("十六、参考完整示例", 1));
body.push(p("以下是规范套件中的完整示例程序,覆盖 tool/frame、path、operation、IO event、run_operation 和回 home可作为复杂程序的参考。"));
body.push(codeBlock(readFileSync(fullExamplePath, "utf8")));
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"
mc:Ignorable="w14 w15 w16se wp14">
<w:body>
${body.join("\n")}
<w:sectPr>
<w:pgSz w:w="11906" w:h="16838"/>
<w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="850" w:header="708" w:footer="708" w:gutter="0"/>
<w:cols w:space="708"/>
<w:docGrid w:linePitch="312"/>
</w:sectPr>
</w:body>
</w:document>`;
}
function copyImages(imageInputs) {
return imageInputs.map((image, index) => {
const fileName = `image-${String(index + 1).padStart(2, "0")}.png`;
copyFileSync(image.source, join(stagingRoot, "word", "media", fileName));
return {
...image,
id: `rIdImage${index + 1}`,
fileName
};
});
}
function heading(text, level) {
return paragraph(text, `Heading${Math.min(level, 3)}`);
}
function p(text) {
return paragraph(text, "BodyText");
}
function paragraph(text, style) {
return `<w:p><w:pPr><w:pStyle w:val="${style}"/></w:pPr>${run(text)}</w:p>`;
}
function run(text) {
return `<w:r><w:t xml:space="preserve">${escapeXml(String(text))}</w:t></w:r>`;
}
function table(rows) {
const width = Math.floor(9200 / Math.max(1, rows[0]?.length ?? 1));
return `<w:tbl>
<w:tblPr><w:tblStyle w:val="TableGrid"/><w:tblW w:w="0" w:type="auto"/><w:tblLook w:val="04A0"/></w:tblPr>
${rows.map((row, rowIndex) => `<w:tr>${row.map((cell) => tableCell(cell, width, rowIndex === 0)).join("")}</w:tr>`).join("\n")}
</w:tbl>`;
}
function tableCell(text, width, header) {
return `<w:tc>
<w:tcPr><w:tcW w:w="${width}" w:type="dxa"/></w:tcPr>
<w:p><w:pPr>${header ? "<w:pStyle w:val=\"TableHeader\"/>" : ""}</w:pPr>${run(text)}</w:p>
</w:tc>`;
}
function codeBlock(text) {
const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
const lines = normalized.endsWith("\n") ? normalized.slice(0, -1).split("\n") : normalized.split("\n");
return lines.map((line) =>
`<w:p><w:pPr><w:pStyle w:val="Code"/></w:pPr><w:r><w:t xml:space="preserve">${escapeXml(line === "" ? " " : line)}</w:t></w:r></w:p>`
).join("\n");
}
function imageWithCaption(image, docPrId, caption) {
return `${imageParagraph(image, docPrId)}${paragraph(caption, "Caption")}`;
}
function imageParagraph(image, docPrId) {
return `<w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${image.cx}" cy="${image.cy}"/>
<wp:effectExtent l="0" t="0" r="0" b="0"/>
<wp:docPr id="${docPrId}" name="${escapeXml(image.title)}"/>
<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr><pic:cNvPr id="${docPrId}" name="${escapeXml(image.fileName)}"/><pic:cNvPicPr/></pic:nvPicPr>
<pic:blipFill><a:blip r:embed="${image.id}"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>
<pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${image.cx}" cy="${image.cy}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing></w:r></w:p>`;
}
function contentTypesXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Default Extension="png" ContentType="image/png"/>
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>`;
}
function packageRelsXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
</Relationships>`;
}
function documentRelsXml(images) {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rIdStyles" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
${images.map((image) => `<Relationship Id="${image.id}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/${image.fileName}"/>`).join("\n")}
</Relationships>`;
}
function corePropsXml() {
const iso = new Date().toISOString();
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dc:title>GRL 功能语法逻辑与程序创建使用手册</dc:title>
<dc:creator>Codex</dc:creator>
<cp:lastModifiedBy>Codex</cp:lastModifiedBy>
<dcterms:created xsi:type="dcterms:W3CDTF">${iso}</dcterms:created>
<dcterms:modified xsi:type="dcterms:W3CDTF">${iso}</dcterms:modified>
</cp:coreProperties>`;
}
function appPropsXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
<Application>Codex</Application>
<DocSecurity>0</DocSecurity>
<ScaleCrop>false</ScaleCrop>
<Company>KDL Work</Company>
<LinksUpToDate>false</LinksUpToDate>
<SharedDoc>false</SharedDoc>
<HyperlinksChanged>false</HyperlinksChanged>
<AppVersion>16.0000</AppVersion>
</Properties>`;
}
function stylesXml() {
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:style w:type="paragraph" w:default="1" w:styleId="Normal">
<w:name w:val="Normal"/>
<w:qFormat/>
<w:rPr><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="21"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="BodyText">
<w:name w:val="Body Text"/>
<w:basedOn w:val="Normal"/>
<w:pPr><w:spacing w:after="120" w:line="276" w:lineRule="auto"/></w:pPr>
<w:rPr><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="21"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Caption">
<w:name w:val="Caption"/>
<w:basedOn w:val="Normal"/>
<w:pPr><w:jc w:val="center"/><w:spacing w:after="160"/></w:pPr>
<w:rPr><w:i/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="18"/><w:color w:val="475569"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="360" w:after="180"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="32"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading2">
<w:name w:val="heading 2"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="280" w:after="140"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="27"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Heading3">
<w:name w:val="heading 3"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="BodyText"/>
<w:qFormat/>
<w:pPr><w:keepNext/><w:spacing w:before="180" w:after="100"/></w:pPr>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="23"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="Code">
<w:name w:val="Code"/>
<w:basedOn w:val="Normal"/>
<w:pPr><w:spacing w:before="0" w:after="0" w:line="240" w:lineRule="auto"/></w:pPr>
<w:rPr><w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Consolas"/><w:sz w:val="16"/></w:rPr>
</w:style>
<w:style w:type="paragraph" w:styleId="TableHeader">
<w:name w:val="Table Header"/>
<w:basedOn w:val="Normal"/>
<w:rPr><w:b/><w:rFonts w:ascii="Microsoft YaHei" w:hAnsi="Microsoft YaHei" w:eastAsia="Microsoft YaHei"/><w:sz w:val="20"/></w:rPr>
</w:style>
<w:style w:type="table" w:default="1" w:styleId="TableNormal">
<w:name w:val="Normal Table"/>
<w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr>
</w:style>
<w:style w:type="table" w:styleId="TableGrid">
<w:name w:val="Table Grid"/>
<w:basedOn w:val="TableNormal"/>
<w:tblPr><w:tblBorders><w:top w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:left w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:bottom w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:right w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:insideH w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/><w:insideV w:val="single" w:sz="4" w:space="0" w:color="B7C1CC"/></w:tblBorders></w:tblPr>
</w:style>
</w:styles>`;
}
function escapeXml(value) {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&apos;");
}
function psSingleQuoted(value) {
return `'${String(value).replaceAll("'", "''")}'`;
}
function zipDirectory(sourceDir, destinationFile) {
const script = [
"Add-Type -AssemblyName System.IO.Compression.FileSystem",
`$src = ${psSingleQuoted(sourceDir)}`,
`$dst = ${psSingleQuoted(destinationFile)}`,
"if (Test-Path -LiteralPath $dst) { Remove-Item -LiteralPath $dst -Force }",
"[System.IO.Compression.ZipFile]::CreateFromDirectory($src, $dst)"
].join("\n");
execFileSync("powershell", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], {
stdio: "inherit"
});
}
function assertSafeStaging(path) {
const allowedRoot = join(webRoot, "test-results") + sep;
const resolved = resolve(path);
if (!resolved.startsWith(allowedRoot)) {
throw new Error(`Refusing to clear staging path outside test-results: ${resolved}`);
}
}
function formatShanghaiTime(date) {
const parts = new Intl.DateTimeFormat("zh-CN", {
timeZone: "Asia/Shanghai",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
}).formatToParts(date);
const value = Object.fromEntries(parts.map((part) => [part.type, part.value]));
return `${value.year}-${value.month}-${value.day} ${value.hour}:${value.minute}:${value.second} Asia/Shanghai`;
}

View File

@@ -0,0 +1,101 @@
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { runAbb120SpecSuite } from "../src/suites/abb120SpecSuite.js";
const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const specRoot = join(webRoot, "tests", "fixtures", "abb120", "spec-programs");
const manifest = JSON.parse(readFileSync(join(specRoot, "manifest.json"), "utf8"));
const programs = manifest.programs.map((entry: { program_id: string; file: string }) => ({
program_id: entry.program_id,
file: entry.file,
text: readFileSync(join(specRoot, entry.file), "utf8")
}));
const job = runAbb120SpecSuite(manifest, programs, {
gitRevision: process.env.GIT_REVISION ?? "working-tree"
});
const outputRoot = resolve(webRoot, "test-results", "abb120-spec", job.job_id);
mkdirSync(outputRoot, { recursive: true });
writeFileSync(join(outputRoot, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
writeFileSync(join(outputRoot, "job.json"), `${JSON.stringify(job, null, 2)}\n`);
writeFileSync(join(outputRoot, "report.json"), `${JSON.stringify(reportJson(job), null, 2)}\n`);
writeFileSync(join(outputRoot, "report.html"), reportHtml(job));
for (const program of job.programs) {
const programDir = join(outputRoot, "programs", program.program_id);
mkdirSync(programDir, { recursive: true });
writeFileSync(join(programDir, "compile.json"), `${JSON.stringify(program.compile, null, 2)}\n`);
writeFileSync(join(programDir, "controller.json"), `${JSON.stringify(program.controller ?? {}, null, 2)}\n`);
writeFileSync(join(programDir, "motion-queue.json"), `${JSON.stringify(program.motionQueue ?? {}, null, 2)}\n`);
writeFileSync(join(programDir, "trace.json"), `${JSON.stringify(program.trace ?? [], null, 2)}\n`);
writeFileSync(join(programDir, "io.json"), `${JSON.stringify(program.io ?? {}, null, 2)}\n`);
writeFileSync(join(programDir, "trajectory.json"), `${JSON.stringify(program.trajectory ?? {}, null, 2)}\n`);
writeFileSync(join(programDir, "post-report.json"), `${JSON.stringify(program.post ?? {}, null, 2)}\n`);
writeFileSync(join(programDir, "roundtrip.json"), `${JSON.stringify(program.roundtrip ?? {}, null, 2)}\n`);
}
console.log(JSON.stringify({
job_id: job.job_id,
outputRoot,
programs: job.programs.length,
missingSections: job.coverage.missingSections
}, null, 2));
function reportJson(job: ReturnType<typeof runAbb120SpecSuite>) {
return {
job_id: job.job_id,
suite_id: job.suite_id,
robot_id: job.robot_id,
coverage: job.coverage,
summary: {
programs: job.programs.length,
pass: job.programs.filter((program) => program.status === "pass").length,
diagnostic: job.programs.filter((program) => program.status === "diagnostic").length,
fail: job.programs.filter((program) => program.status === "fail").length
},
diagnostics: job.programs.flatMap((program) =>
program.diagnostics.map((diagnostic) => ({
program_id: program.program_id,
...diagnostic
}))
)
};
}
function reportHtml(job: ReturnType<typeof runAbb120SpecSuite>): string {
const rows = job.programs.map((program) =>
`<tr><td>${escapeHtml(program.program_id)}</td><td>${escapeHtml(program.coverage_level)}</td><td>${escapeHtml(program.status)}</td><td>${program.diagnostics.length}</td></tr>`
).join("\n");
return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${escapeHtml(job.job_id)}</title>
<style>
body { font-family: Arial, sans-serif; margin: 24px; color: #1f2933; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccd5dd; padding: 8px; text-align: left; }
th { background: #eef2f4; }
</style>
</head>
<body>
<h1>${escapeHtml(job.job_id)}</h1>
<p>Suite ${escapeHtml(job.suite_id)} / Robot ${escapeHtml(job.robot_id)}</p>
<p>Covered sections: ${job.coverage.coveredSections.join(", ")}</p>
<table>
<thead><tr><th>Program</th><th>Layer</th><th>Status</th><th>Diagnostics</th></tr></thead>
<tbody>${rows}</tbody>
</table>
</body>
</html>
`;
}
function escapeHtml(value: unknown): string {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;");
}

View File

@@ -0,0 +1,209 @@
import { execFileSync } from "node:child_process";
import {
existsSync,
mkdirSync,
readdirSync,
readFileSync,
rmSync,
statSync,
writeFileSync
} from "node:fs";
import { dirname, extname, join, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
const root = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
const webRoot = join(root, "kdl-wasm", "web");
const deployRoot = join(webRoot, "test-results", "deploy");
const zipPath = resolve(process.argv[2] ?? latestZipPath());
const extractRoot = join(deployRoot, "_verify", zipBasename(zipPath));
assertSafeVerifyPath(extractRoot);
rmSync(extractRoot, { recursive: true, force: true });
mkdirSync(extractRoot, { recursive: true });
expandZip(zipPath, extractRoot);
const manifest = readJson(join(extractRoot, "demo-manifest.json"));
const report = readJson(join(extractRoot, manifest.report_json));
const programManifest = readJson(join(extractRoot, manifest.program_manifest));
const grlFiles = walkFiles(join(extractRoot, "spec-programs")).filter((file) => extname(file).toLowerCase() === ".grl");
const requiredFiles = [
"index.html",
"demo-manifest.json",
"README.md",
"app/virtual-controller.html",
"app/virtual-controller.css",
"app/virtual-controller.js",
"spec-programs/manifest.json",
manifest.job_json,
manifest.report_json,
manifest.report_html,
manifest.screenshots.desktop,
manifest.screenshots.mobile,
manifest.screenshots.evidence,
"docs/GRL功能语法逻辑与程序创建使用手册.docx",
"docs/通用机器人离线编程系统测试文档.docx",
"docs/working2/README.md",
"docs/working2/05-验收证据.md"
];
const checks = [];
for (const file of requiredFiles) {
checks.push(checkFile(file));
}
checks.push(check("program_count", manifest.program_count === 19, `program_count=${manifest.program_count}`));
checks.push(check("manifest_programs", programManifest.programs.length === 19, `manifest programs=${programManifest.programs.length}`));
checks.push(check("grl_files", grlFiles.length === 19, `grl files=${grlFiles.length}`));
checks.push(check("summary_fail", report.summary.fail === 0, `summary.fail=${report.summary.fail}`));
checks.push(check("report_programs", report.summary.programs === 19, `report programs=${report.summary.programs}`));
checks.push(check("runtime_programs", manifest.runtime_programs === 12, `runtime=${manifest.runtime_programs}`));
checks.push(check("static_programs", manifest.static_programs === 4, `static=${manifest.static_programs}`));
checks.push(check("post_programs", manifest.post_programs === 3, `post=${manifest.post_programs}`));
checks.push(check("missing_sections", Array.isArray(report.coverage.missingSections) && report.coverage.missingSections.length === 0, `missing=${report.coverage.missingSections?.join(",") ?? "n/a"}`));
checks.push(check("relative_urls", allManifestUrlsAreRelative(manifest), "manifest URLs are relative"));
for (const program of manifest.programs) {
checks.push(checkFile(program.source));
checks.push(checkFile(program.artifacts.compile));
}
for (const doc of manifest.docs ?? []) {
checks.push(checkFile(doc.href));
}
const runtimeFramePrograms = manifest.programs.filter((program) => program.coverage_level === "Runtime");
let frameProgramCount = 0;
for (const program of runtimeFramePrograms) {
const trajectory = readJson(join(extractRoot, program.artifacts.trajectory));
const frames = Array.isArray(trajectory.frames) ? trajectory.frames : [];
const hasFrameState = frames.some((frame) =>
Array.isArray(frame.joints) &&
frame.joints.length === 6 &&
Array.isArray(frame.tcp?.position) &&
frame.tcp.position.length === 3 &&
Array.isArray(frame.tcp?.quaternion) &&
frame.tcp.quaternion.length === 4
);
if (hasFrameState) frameProgramCount += 1;
}
checks.push(check(
"runtime_trajectory_frames",
frameProgramCount > 0,
`${frameProgramCount}/${runtimeFramePrograms.length} runtime programs include frame joints and TCP`
));
const failed = checks.filter((item) => !item.ok);
const summary = {
zip: zipPath,
extract_root: extractRoot,
release_id: manifest.release_id,
job_id: manifest.job_id,
program_count: manifest.program_count,
grl_files: grlFiles.length,
summary_fail: report.summary.fail,
checks,
ok: failed.length === 0
};
writeFileSync(join(deployRoot, `${zipBasename(zipPath)}.verify.json`), `${JSON.stringify(summary, null, 2)}\n`, "utf8");
console.log(JSON.stringify(summary, null, 2));
if (failed.length > 0) {
throw new Error(`Demo package verification failed: ${failed.map((item) => item.name).join(", ")}`);
}
function checkFile(relativePath) {
const file = join(extractRoot, relativePath);
const exists = existsSync(file);
return check(`file:${relativePath}`, exists && statSync(file).isFile(), exists ? `${statSync(file).size} bytes` : "missing");
}
function check(name, ok, details) {
return { name, ok: Boolean(ok), details };
}
function allManifestUrlsAreRelative(value) {
const urls = [];
collectUrls(value, urls);
return urls.every((url) => !/^[a-z]+:\/\//i.test(url) && !/^[a-z]:[\\/]/i.test(url) && !url.startsWith("/") && !url.includes("\\"));
}
function collectUrls(value, urls) {
if (Array.isArray(value)) {
value.forEach((item) => collectUrls(item, urls));
return;
}
if (!value || typeof value !== "object") return;
for (const [key, item] of Object.entries(value)) {
if (typeof item === "string" && (key === "href" || key.includes("json") || key.includes("html") || key.includes("entry") || key.includes("manifest") || key.includes("source") || key.includes("screenshot") || key.includes("report") || key.includes("compile") || key.includes("controller") || key.includes("trace") || key.includes("trajectory") || key.includes("roundtrip") || key.includes("io") || key.includes("queue"))) {
urls.push(item);
} else {
collectUrls(item, urls);
}
}
}
function expandZip(source, destination) {
const script = [
"Add-Type -AssemblyName System.IO.Compression.FileSystem",
`$src = ${psSingleQuoted(source)}`,
`$dst = ${psSingleQuoted(destination)}`,
"if (Test-Path -LiteralPath $dst) { Remove-Item -LiteralPath $dst -Recurse -Force }",
"New-Item -ItemType Directory -Force -Path $dst | Out-Null",
"[System.IO.Compression.ZipFile]::ExtractToDirectory($src, $dst)"
].join("\n");
execFileSync("powershell", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], {
stdio: "inherit"
});
}
function latestZipPath() {
if (!existsSync(deployRoot)) {
throw new Error(`No deploy output directory found: ${deployRoot}`);
}
const zips = readdirSync(deployRoot, { withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name.startsWith("kdl-olp-demo-") && entry.name.endsWith(".zip"))
.map((entry) => ({
path: join(deployRoot, entry.name),
mtimeMs: statSync(join(deployRoot, entry.name)).mtimeMs
}))
.sort((left, right) => right.mtimeMs - left.mtimeMs);
if (zips.length === 0) {
throw new Error(`No kdl-olp-demo-*.zip files found in ${deployRoot}`);
}
return zips[0].path;
}
function walkFiles(dir) {
const files = [];
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...walkFiles(fullPath));
} else if (entry.isFile()) {
files.push(fullPath);
}
}
return files;
}
function readJson(file) {
return JSON.parse(readFileSync(file, "utf8"));
}
function zipBasename(file) {
return file.split(/[\\/]/).at(-1).replace(/\.zip$/i, "");
}
function psSingleQuoted(value) {
return `'${String(value).replaceAll("'", "''")}'`;
}
function assertSafeVerifyPath(path) {
const allowedRoot = resolve(join(deployRoot, "_verify")) + sep;
const resolved = resolve(path);
if (!resolved.startsWith(allowedRoot)) {
throw new Error(`Refusing to modify path outside verify root: ${resolved}`);
}
}

View File

@@ -0,0 +1,508 @@
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { basename, join, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { spawn } from "node:child_process";
const root = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
const appHtml = resolve(root, "kdl-wasm/web/app/virtual-controller.html");
const outputDir = resolve(root, "kdl-wasm/web/test-results/virtual-controller");
const chromeBin = process.env.CHROME_BIN ?? defaultChromeBin();
const targetUrl = process.argv[2] ?? pathToFileURL(appHtml).href;
const isRemote = /^https?:\/\//i.test(targetUrl);
mkdirSync(outputDir, { recursive: true });
const evidence = await verifyButtonFlow(targetUrl);
const evidencePath = join(outputDir, isRemote ? "button-evidence-public.json" : "button-evidence.json");
writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`);
console.log(JSON.stringify(evidence, null, 2));
async function verifyButtonFlow(url) {
const browser = await launchChrome("buttons");
try {
const client = await connect(browser.websocketUrl);
await client.send("Page.enable");
await client.send("Runtime.enable");
await client.send("Network.enable");
await client.send("Emulation.setDeviceMetricsOverride", {
width: 1440,
height: 960,
deviceScaleFactor: 1,
mobile: false
});
await client.send("Page.navigate", { url });
await waitForLoad(client);
const initial = await waitForProbe(
client,
(probe) => probe.title === "ABB120 Virtual Controller"
&& probe.frameTotal > 0
&& probe.samplePeriodSec === 0.05
&& probe.stepRows > 0
&& probe.activeStepRows === 1
&& (!isRemote || probe.programOptions.length >= 10),
"initial controller render",
12_000
);
if (isRemote && initial.programOptions.length < 10) {
throw new Error(`remote manifest did not populate enough programs: ${initial.programOptions.length}`);
}
await clickCommand(client, "load");
const afterLoadClick = await sleepAndProbe(client, 120);
if (!["load", "loading", "parsing", "ready"].includes(afterLoadClick.state)) {
throw new Error(`Load did not show an active state, got ${afterLoadClick.state}`);
}
if (!afterLoadClick.log.includes(afterLoadClick.program)) {
throw new Error(`Load did not write the active program to the log: ${afterLoadClick.log}`);
}
const afterParse = await waitForProbe(
client,
(probe) => probe.state === "ready"
&& probe.parser.includes("parsed")
&& probe.parserProgress === 1
&& probe.stepRows > 1
&& probe.frameRows === probe.sourceFrameTotal,
"Load parse stream",
4000
);
if (afterLoadClick.state === "parsing") {
if (!afterLoadClick.parser.includes("parsing")) {
throw new Error(`Load did not expose parser progress: ${afterLoadClick.parser}`);
}
if (afterLoadClick.frameRows >= afterParse.frameRows && afterParse.frameRows > 1) {
throw new Error(`Trajectory did not grow during parsing: ${afterLoadClick.frameRows} -> ${afterParse.frameRows}`);
}
}
await clickCommand(client, "run");
const afterRun = await waitForProbe(
client,
(probe) => probe.state === "running" && probe.running,
"Run command",
1200
);
if (!afterRun.wait.includes("waiting") && !afterRun.wait.includes("satisfied")) {
throw new Error(`Run did not update wait state: ${afterRun.wait}`);
}
assertProgramSteps(afterRun, "Run command");
await sleep(700);
await clickCommand(client, "pause");
const afterPause = await waitForProbe(client, (probe) => probe.state === "paused", "Pause command", 1000);
assertProgramSteps(afterPause, "Pause command");
await clickCommand(client, "step");
const afterStep = await waitForProbe(client, (probe) => probe.state === "paused", "Step command", 1000);
const expectedStepFrame = afterPause.frameCurrent < afterPause.frameTotal
? afterPause.frameCurrent + 1
: afterPause.frameCurrent;
if (afterStep.frameCurrent !== expectedStepFrame) {
throw new Error(`Step sample mismatch: expected ${expectedStepFrame}, got ${afterStep.frameCurrent}`);
}
assertProgramSteps(afterStep, "Step command");
await clickCommand(client, "stop");
const afterStop = await waitForProbe(client, (probe) => probe.state === "stopped", "Stop command", 1000);
await clickCommand(client, "reset");
const afterReset = await waitForProbe(
client,
(probe) => probe.state === "ready" && probe.frameCurrent === 1,
"Reset command",
1000
);
await clickCommand(client, "export");
const afterExport = await sleepAndProbe(client, 150);
if (!afterExport.log.includes("exported") && !afterExport.reports.includes("exported")) {
throw new Error(`Export did not update log/report fields: ${afterExport.log} / ${afterExport.reports}`);
}
const fullSpecId = afterExport.programOptions.find((id) => id.startsWith("W2_99_"));
let afterProgramSwitch = afterExport;
if (fullSpecId) {
await selectProgram(client, fullSpecId);
afterProgramSwitch = await waitForProbe(
client,
(probe) => probe.program === fullSpecId
&& probe.state === "ready"
&& probe.sourceFrameTotal >= 20
&& probe.frameTotal >= 39
&& probe.stepRows >= 8
&& probe.activeStepRows === 1,
`${fullSpecId} program switch`,
isRemote ? 12_000 : 4_000
);
assertTcpAndJoints(afterProgramSwitch, fullSpecId);
}
const afterCacheWarm = await waitForProbe(
client,
(probe) => !isRemote || probe.storageState.writes >= 3,
"OPFS cache warmup",
isRemote ? 12_000 : 1500
);
const offlineCache = await verifyOfflineCache(client, afterCacheWarm);
await client.close();
return {
targetUrl: url,
chrome: chromeBin,
initial,
afterLoadClick,
afterRun,
afterPause,
afterStep,
afterStop,
afterReset,
afterExport,
afterProgramSwitch,
offlineCache
};
} finally {
browser.close();
}
}
async function verifyOfflineCache(client, beforeOffline) {
if (!isRemote) {
return { skipped: true, reason: "local file target does not require network-offline cache proof" };
}
const cacheProgram = beforeOffline.program
?? beforeOffline.programOptions.find((id) => id === "W2_60_IOWaitPulse")
?? beforeOffline.programOptions[0];
if (!cacheProgram) throw new Error("No program available for offline cache check");
await evaluate(client, `() => {
const app = window.__virtualController;
app.programCache.clear();
app.programLoads.clear();
app.assetTextCache.clear();
return true;
}`);
await client.send("Network.emulateNetworkConditions", {
offline: true,
latency: 0,
downloadThroughput: 0,
uploadThroughput: 0
});
await selectProgram(client, cacheProgram);
const offline = await waitForProbe(
client,
(probe) => probe.program === cacheProgram
&& probe.state === "ready"
&& probe.sourceFrameTotal >= 4
&& probe.storageState.hits > beforeOffline.storageState.hits,
"offline OPFS program load",
5000
);
if (offline.storageState.mode !== "OPFS") {
throw new Error(`Expected OPFS mode during offline load, got ${offline.storageState.mode}`);
}
assertTcpAndJoints(offline, cacheProgram);
return {
program: cacheProgram,
mode: offline.storageState.mode,
hitsBefore: beforeOffline.storageState.hits,
hitsAfter: offline.storageState.hits,
frame: offline.frame,
storage: offline.storage
};
}
async function clickCommand(client, command) {
return evaluate(client, `() => {
const button = document.querySelector("[data-command='${command}']");
if (!button) throw new Error("Missing command ${command}");
button.click();
return true;
}`);
}
async function selectProgram(client, programId) {
return evaluate(client, `() => {
const select = document.querySelector("[data-program-select]");
if (!select) throw new Error("Missing program select");
select.value = ${JSON.stringify(programId)};
select.dispatchEvent(new Event("change", { bubbles: true }));
return select.value;
}`);
}
function assertTcpAndJoints(probe, label) {
if (!/\[[^\]]+\]/.test(probe.joints) || probe.joints.split(",").length < 6) {
throw new Error(`${label}: joints field is not a 6-axis vector: ${probe.joints}`);
}
if (!probe.tcp.includes("pos [") || !probe.tcp.includes(" q [")) {
throw new Error(`${label}: TCP field is incomplete: ${probe.tcp}`);
}
if (probe.frameRows !== probe.sourceFrameTotal) {
throw new Error(`${label}: frame table rows ${probe.frameRows} != source frame total ${probe.sourceFrameTotal}`);
}
if (probe.samplePeriodSec !== 0.05) {
throw new Error(`${label}: expected 50ms sample period, got ${probe.samplePeriodSec}`);
}
assertProgramSteps(probe, label);
}
function assertProgramSteps(probe, label) {
if (probe.stepRows < 1) {
throw new Error(`${label}: program step table did not render rows`);
}
if (probe.activeStepRows !== 1) {
throw new Error(`${label}: expected one active program step, got ${probe.activeStepRows}`);
}
if (!probe.stepStatus.includes("/") || !probe.stepStatus.includes("line")) {
throw new Error(`${label}: step status is incomplete: ${probe.stepStatus}`);
}
if (!probe.activeStepText.includes("@50ms") && !probe.activeStepText.includes("line")) {
throw new Error(`${label}: active step does not expose execution detail: ${probe.activeStepText}`);
}
}
async function sleepAndProbe(client, ms) {
await sleep(ms);
return evaluate(client, pageProbeSource());
}
async function waitForProbe(client, predicate, label, timeoutMs) {
const started = Date.now();
let lastProbe;
while (Date.now() - started < timeoutMs) {
lastProbe = await evaluate(client, pageProbeSource());
if (predicate(lastProbe)) return lastProbe;
await sleep(100);
}
throw new Error(`${label} timed out. Last probe: ${JSON.stringify(lastProbe)}`);
}
function pageProbeSource() {
return `() => {
const field = (name) => document.querySelector("[data-field='" + name + "']")?.textContent?.trim() ?? "";
const frame = field("frame");
const frameMatch = frame.match(/(\\d+)\\s*\\/\\s*(\\d+)/);
const app = window.__virtualController;
return {
title: document.title,
state: field("state"),
program: field("program"),
wait: field("wait"),
log: field("log"),
reports: field("reports"),
storage: field("storage"),
joints: field("joints"),
tcp: field("tcp"),
frame,
frameCurrent: frameMatch ? Number(frameMatch[1]) : 0,
frameTotal: frameMatch ? Number(frameMatch[2]) : 0,
frameRows: document.querySelectorAll("[data-frame-table] tr").length,
frameTime: field("frame-time"),
parser: field("parser"),
parserProgress: Number(document.querySelector("[data-parser-progress]")?.value ?? 0),
stepStatus: field("step-status"),
stepRows: document.querySelectorAll("[data-step-table] tr").length,
activeStepRows: document.querySelectorAll("[data-step-table] tr[data-step-state='active']").length,
activeStepText: document.querySelector("[data-step-table] tr[data-step-state='active']")?.textContent?.trim() ?? "",
programOptions: Array.from(document.querySelectorAll("[data-program-select] option")).map((item) => item.value),
running: document.querySelector(".workbench")?.dataset.running === "true",
playbackTime: Number(app?.playbackTime ?? 0),
samplePeriodSec: Number(app?.samplePeriodSec ?? 0),
sampleIndex: Number(app?.currentSampleIndex ?? 0),
sourceFrameIndex: Number(app?.currentFrameIndex ?? 0),
sourceFrameTotal: Array.isArray(app?.programCache?.get?.(app?.selectedProgramId)?.trajectory?.frames)
? app.programCache.get(app.selectedProgramId).trajectory.frames.length
: document.querySelectorAll("[data-frame-table] tr").length,
storageState: app?.storage ? { ...app.storage } : {},
parseStream: app?.parseStream ? { ...app.parseStream, timer: Boolean(app.parseStream.timer) } : {},
errors: Array.isArray(window.__vcErrors) ? [...window.__vcErrors] : []
};
}`;
}
function launchChrome(name) {
const userDataDir = mkdtempSync(join(tmpdir(), `kdl-vc-${name}-`));
const child = spawn(chromeBin, [
"--headless=new",
"--disable-gpu",
"--no-sandbox",
"--disable-dev-shm-usage",
"--ignore-certificate-errors",
"--remote-debugging-port=0",
`--user-data-dir=${userDataDir}`,
"about:blank"
], { stdio: ["ignore", "pipe", "pipe"] });
let log = "";
let settled = false;
const cleanup = () => {
child.kill("SIGTERM");
setTimeout(() => {
rmSync(userDataDir, {
recursive: true,
force: true,
maxRetries: 5,
retryDelay: 100
});
}, 250).unref();
};
return new Promise((resolveLaunch, reject) => {
const timeout = setTimeout(() => {
if (!settled) {
settled = true;
cleanup();
reject(new Error(`Chrome did not expose DevTools endpoint. ${log}`));
}
}, 15_000);
const onData = (chunk) => {
log += chunk.toString();
const match = log.match(/DevTools listening on (ws:\/\/[^\s]+)/);
if (!match || settled) return;
settled = true;
clearTimeout(timeout);
findPageWebsocket(match[1]).then((pageWebsocketUrl) => {
resolveLaunch({
websocketUrl: pageWebsocketUrl,
close: cleanup
});
}, (error) => {
cleanup();
reject(error);
});
};
child.stdout.on("data", onData);
child.stderr.on("data", onData);
child.on("error", (error) => {
if (!settled) {
settled = true;
clearTimeout(timeout);
cleanup();
reject(error);
}
});
child.on("exit", (code) => {
if (!settled) {
settled = true;
clearTimeout(timeout);
cleanup();
reject(new Error(`${basename(chromeBin)} exited early with ${code}. ${log}`));
}
});
});
}
async function findPageWebsocket(browserWebsocketUrl) {
const endpoint = new URL(browserWebsocketUrl);
const baseUrl = `http://${endpoint.host}`;
const started = Date.now();
let lastError;
while (Date.now() - started < 5000) {
try {
const response = await fetch(`${baseUrl}/json/list`);
const targets = await response.json();
const page = targets.find((target) => target.type === "page" && target.webSocketDebuggerUrl);
if (page?.webSocketDebuggerUrl) return page.webSocketDebuggerUrl;
} catch (error) {
lastError = error;
}
await sleep(100);
}
throw new Error(`Could not find Chrome page target. ${lastError instanceof Error ? lastError.message : ""}`);
}
function connect(websocketUrl) {
const socket = new WebSocket(websocketUrl);
let nextId = 1;
const pending = new Map();
socket.addEventListener("message", (event) => {
const message = JSON.parse(event.data.toString());
if (!message.id) return;
const request = pending.get(message.id);
if (!request) return;
pending.delete(message.id);
if (message.error) {
request.reject(new Error(`${message.error.code}: ${message.error.message}`));
} else {
request.resolve(message.result ?? {});
}
});
return new Promise((resolveClient, reject) => {
socket.addEventListener("open", () => {
resolveClient({
send(method, params = {}) {
const id = nextId++;
socket.send(JSON.stringify({ id, method, params }));
return new Promise((resolveSend, rejectSend) => {
pending.set(id, { resolve: resolveSend, reject: rejectSend });
});
},
close() {
socket.close();
}
});
}, { once: true });
socket.addEventListener("error", reject, { once: true });
});
}
function waitForLoad(client) {
return new Promise((resolveLoad, reject) => {
const started = Date.now();
const poll = async () => {
try {
const ready = await evaluate(client, "() => document.readyState");
if (ready === "complete") {
resolveLoad();
return;
}
if (Date.now() - started > 10_000) {
reject(new Error("Timed out waiting for document.readyState complete"));
return;
}
setTimeout(poll, 100);
} catch (error) {
reject(error);
}
};
poll();
});
}
async function evaluate(client, expression) {
const result = await client.send("Runtime.evaluate", {
expression: `(${expression})()`,
awaitPromise: true,
returnByValue: true
});
if (result.exceptionDetails) {
throw new Error(result.exceptionDetails.text ?? "Runtime.evaluate failed");
}
return result.result.value;
}
function sleep(ms) {
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
}
function defaultChromeBin() {
if (process.platform !== "win32") return "/usr/bin/google-chrome";
const candidates = [
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
process.env.LOCALAPPDATA
? join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe")
: "",
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe"
];
return candidates.find((candidate) => candidate && existsSync(candidate)) ?? "chrome.exe";
}

View File

@@ -52,13 +52,18 @@ async function verifyViewport(viewport) {
await client.send("Page.navigate", { url: pathToFileURL(appHtml).href }); await client.send("Page.navigate", { url: pathToFileURL(appHtml).href });
await waitForLoad(client); await waitForLoad(client);
const initial = await evaluate(client, pageProbeSource()); const initial = await waitForProbe(
client,
(probe) => probe.parserProgress === 1 && !probe.parser.includes("parsing"),
"initial parse",
4000
);
assertProbe(initial, viewport.name, "initial"); assertProbe(initial, viewport.name, "initial");
await evaluate(client, clickCommandSource("load")); await evaluate(client, clickCommandSource("load"));
await evaluate(client, clickCommandSource("run")); await evaluate(client, clickCommandSource("run"));
await evaluate(client, clickIoSource()); await evaluate(client, clickIoSource());
const afterRun = await evaluate(client, pageProbeSource()); const afterRun = await waitForProbe(client, (probe) => probe.state === "running", "run", 1200);
assertProbe(afterRun, viewport.name, "after run"); assertProbe(afterRun, viewport.name, "after run");
if (afterRun.state !== "running") { if (afterRun.state !== "running") {
throw new Error(`${viewport.name}: expected state running, got ${afterRun.state}`); throw new Error(`${viewport.name}: expected state running, got ${afterRun.state}`);
@@ -91,6 +96,7 @@ async function verifyViewport(viewport) {
screenshot: viewport.screenshotPath, screenshot: viewport.screenshotPath,
screenshotBytes: pngBytes, screenshotBytes: pngBytes,
state: afterRun.state, state: afterRun.state,
parser: afterRun.parser,
wait: afterRun.wait, wait: afterRun.wait,
trace: afterRun.trace, trace: afterRun.trace,
visiblePanels: afterRun.visiblePanels visiblePanels: afterRun.visiblePanels
@@ -257,6 +263,17 @@ function waitForLoad(client) {
}); });
} }
async function waitForProbe(client, predicate, label, timeoutMs) {
const started = Date.now();
let lastProbe;
while (Date.now() - started < timeoutMs) {
lastProbe = await evaluate(client, pageProbeSource());
if (predicate(lastProbe)) return lastProbe;
await new Promise((resolveRetry) => setTimeout(resolveRetry, 100));
}
throw new Error(`${label} timed out. Last probe: ${JSON.stringify(lastProbe)}`);
}
async function evaluate(client, expression) { async function evaluate(client, expression) {
const result = await client.send("Runtime.evaluate", { const result = await client.send("Runtime.evaluate", {
expression: `(${expression})()`, expression: `(${expression})()`,
@@ -288,7 +305,12 @@ function pageProbeSource() {
wait: field("wait"), wait: field("wait"),
queue: field("queue"), queue: field("queue"),
trace: field("trace"), trace: field("trace"),
parser: field("parser"),
parserProgress: Number(document.querySelector("[data-parser-progress]")?.value ?? 0),
editor: field("editor"), editor: field("editor"),
stepRows: document.querySelectorAll("[data-step-table] tr").length,
activeStepRows: document.querySelectorAll("[data-step-table] tr[data-step-state='active']").length,
stepStatus: field("step-status"),
running: document.querySelector(".workbench")?.dataset.running === "true", running: document.querySelector(".workbench")?.dataset.running === "true",
visiblePanels, visiblePanels,
viewport: box(".viewport"), viewport: box(".viewport"),
@@ -325,6 +347,9 @@ function assertProbe(probe, viewportName, phase) {
if (!probe.editor.includes("proc main") && !probe.editor.includes("MoveJ") && !probe.editor.includes("PTP")) { if (!probe.editor.includes("proc main") && !probe.editor.includes("MoveJ") && !probe.editor.includes("PTP")) {
throw new Error(`${viewportName}/${phase}: editor source did not render`); throw new Error(`${viewportName}/${phase}: editor source did not render`);
} }
if (probe.stepRows < 1 || probe.activeStepRows !== 1 || !probe.stepStatus.includes("line")) {
throw new Error(`${viewportName}/${phase}: program steps did not render correctly`);
}
if (!probe.viewport || probe.viewport.width < 100 || probe.viewport.height < 100) { if (!probe.viewport || probe.viewport.width < 100 || probe.viewport.height < 100) {
throw new Error(`${viewportName}/${phase}: viewport is too small`); throw new Error(`${viewportName}/${phase}: viewport is too small`);
} }

View File

@@ -87,6 +87,10 @@ class ControlFlowParser {
instructions.push(this.finishJump(this.previous(), context)); instructions.push(this.finishJump(this.previous(), context));
continue; continue;
} }
if (this.matchKeyword("try")) {
instructions.push(this.finishRawBlock(this.previous(), "try"));
continue;
}
if (this.checkKeyword("end")) { if (this.checkKeyword("end")) {
throw controlError("GRL_CONTROL_UNEXPECTED_END", "Unexpected end in procedure body", this.peek()); throw controlError("GRL_CONTROL_UNEXPECTED_END", "Unexpected end in procedure body", this.peek());
} }
@@ -311,6 +315,29 @@ class ControlFlowParser {
}; };
} }
private finishRawBlock(start: GrlToken, blockKeyword: string): RawProcedureStatement {
const tokens: GrlToken[] = [start];
let nestedBlocks = 0;
while (!this.isAtEnd()) {
const token = this.advance();
tokens.push(token);
if (token.kind === "keyword" && token.raw === "end") {
if (nestedBlocks === 0) {
break;
}
nestedBlocks -= 1;
} else if (token.kind === "keyword" && ["if", "while", "for", "switch", "try"].includes(token.raw)) {
nestedBlocks += 1;
}
}
return {
kind: "RAW_STATEMENT",
text: `${blockKeyword} block`,
tokens,
sourceMap: tokenSourceMap(start)
};
}
private parseBooleanLineExpression(start: GrlToken): ControlExpression { private parseBooleanLineExpression(start: GrlToken): ControlExpression {
const expression = this.parseLineExpressionUntil(start, []); const expression = this.parseLineExpressionUntil(start, []);
if (!isBooleanCondition(expression.tokens as GrlToken[])) { if (!isBooleanCondition(expression.tokens as GrlToken[])) {

View File

@@ -339,6 +339,9 @@ class IoStatementParser {
} }
private matchKeyword(keyword: string): boolean { private matchKeyword(keyword: string): boolean {
if (this.isAtEnd()) {
return false;
}
const token = this.peek(); const token = this.peek();
if ((token.kind === "keyword" || token.kind === "identifier") && token.raw === keyword) { if ((token.kind === "keyword" || token.kind === "identifier") && token.raw === keyword) {
this.advance(); this.advance();
@@ -348,6 +351,9 @@ class IoStatementParser {
} }
private checkKeyword(keyword: string): boolean { private checkKeyword(keyword: string): boolean {
if (this.isAtEnd()) {
return false;
}
const token = this.peek(); const token = this.peek();
return (token.kind === "keyword" || token.kind === "identifier") && token.raw === keyword; return (token.kind === "keyword" || token.kind === "identifier") && token.raw === keyword;
} }

View File

@@ -1,5 +1,6 @@
export { export {
compileGrlDataDeclaration, compileGrlDataDeclaration,
compileGrlConstantValue,
compileGrlTargetDeclaration, compileGrlTargetDeclaration,
compileOffsetExpression, compileOffsetExpression,
compileSpeedExpression, compileSpeedExpression,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,440 @@
{
"suite_id": "working2-abb120-spec",
"robot_id": "abb_irb120_3_58",
"spec_source": "work/doc/通用机器人编程语法规范.md",
"program_root": "kdl-wasm/web/tests/fixtures/abb120/spec-programs",
"runtime_commands": [
"loadProgram",
"start",
"stepInto",
"hold",
"resume",
"stepMotion",
"stop",
"resetFault"
],
"programs": [
{
"program_id": "W2_00_MinimalModule",
"file": "runtime/W2_00_MinimalModule.grl",
"coverage_level": "Runtime",
"spec_sections": [
4,
5,
6,
9,
10,
23
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_10_DataTargetToolFrame",
"file": "runtime/W2_10_DataTargetToolFrame.grl",
"coverage_level": "Runtime",
"spec_sections": [
6,
8,
9
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_20_ExpressionMath",
"file": "runtime/W2_20_ExpressionMath.grl",
"coverage_level": "Runtime",
"spec_sections": [
7,
9,
13
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_30_MotionAllTypes",
"file": "runtime/W2_30_MotionAllTypes.grl",
"coverage_level": "Runtime",
"spec_sections": [
8,
9,
10
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_40_PathEvents",
"file": "runtime/W2_40_PathEvents.grl",
"coverage_level": "Runtime",
"spec_sections": [
11,
13,
19
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_50_OperationProcess",
"file": "runtime/W2_50_OperationProcess.grl",
"coverage_level": "Runtime",
"spec_sections": [
12,
13
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_60_IOWaitPulse",
"file": "runtime/W2_60_IOWaitPulse.grl",
"coverage_level": "Runtime",
"spec_sections": [
13
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_70_ControlFlow",
"file": "runtime/W2_70_ControlFlow.grl",
"coverage_level": "Runtime",
"spec_sections": [
14
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_80_ProcFuncCall",
"file": "runtime/W2_80_ProcFuncCall.grl",
"coverage_level": "Runtime",
"spec_sections": [
15
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_90_ExceptionAlarm",
"file": "runtime/W2_90_ExceptionAlarm.grl",
"coverage_level": "Runtime",
"spec_sections": [
16,
17
],
"expected_status": "pass",
"expected_diagnostics": [
"GRL_P1_UNIMPLEMENTED"
]
},
{
"program_id": "W2_E10_ExpressionDiagnostics",
"file": "static/W2_E10_ExpressionDiagnostics.grl",
"coverage_level": "Static",
"spec_sections": [
7,
22
],
"expected_status": "diagnostic",
"expected_diagnostics": [
"GRL_EXPR_UNKNOWN_SYMBOL",
"GRL_EXPR_UNKNOWN_FUNCTION",
"GRL_EXPR_ARITY",
"GRL_EXPR_DOMAIN",
"GRL_EXPR_DIV_ZERO",
"GRL_EXPR_UNIT_MISMATCH"
]
},
{
"program_id": "W2_E20_SemanticDiagnostics",
"file": "static/W2_E20_SemanticDiagnostics.grl",
"coverage_level": "Static",
"spec_sections": [
6,
15,
22
],
"expected_status": "diagnostic",
"expected_diagnostics": [
"GRL_SYMBOL_DUPLICATE",
"GRL_ARGUMENT_NOT_LVALUE",
"GRL_CALL_TARGET_NOT_FOUND",
"GRL_FUNC_SIDE_EFFECT",
"GRL_TARGET_NOT_FOUND"
]
},
{
"program_id": "W2_E30_MotionDiagnostics",
"file": "error/W2_E30_MotionDiagnostics.grl",
"coverage_level": "Static",
"spec_sections": [
8,
9,
10,
11,
22
],
"expected_status": "diagnostic",
"expected_diagnostics": [
"KDL_JOINT_LIMIT",
"KDL_TARGET_UNREACHABLE",
"GRL_PATH_EMPTY"
]
},
{
"program_id": "W2_E40_ControlFlowDiagnostics",
"file": "static/W2_E40_ControlFlowDiagnostics.grl",
"coverage_level": "Static",
"spec_sections": [
14,
22
],
"expected_status": "diagnostic",
"expected_diagnostics": [
"GRL_BREAK_OUTSIDE_FLOW",
"GRL_CONTINUE_OUTSIDE_LOOP",
"GRL_JUMP_INTO_BLOCK",
"GRL_SWITCH_CASE_DUPLICATE",
"GRL_SWITCH_CASE_NOT_CONSTANT",
"GRL_LABEL_NOT_FOUND"
]
},
{
"program_id": "W2_E50_RuntimeTimeout",
"file": "error/W2_E50_RuntimeTimeout.grl",
"coverage_level": "Runtime",
"spec_sections": [
13,
16
],
"expected_status": "diagnostic",
"expected_diagnostics": [
"VC_WAIT_TIMEOUT"
]
},
{
"program_id": "W2_P10_BrandHints",
"file": "post/W2_P10_BrandHints.grl",
"coverage_level": "Post",
"spec_sections": [
18,
20
],
"expected_status": "pass",
"expected_diagnostics": [
"GRL_POST_HINT_IGNORED"
]
},
{
"program_id": "W2_P20_CrossBrandMotion",
"file": "post/W2_P20_CrossBrandMotion.grl",
"coverage_level": "Post",
"spec_sections": [
20
],
"expected_status": "pass",
"expected_diagnostics": []
},
{
"program_id": "W2_P30_Roundtrip",
"file": "post/W2_P30_Roundtrip.grl",
"coverage_level": "Post",
"spec_sections": [
19,
20,
21
],
"expected_status": "pass",
"expected_diagnostics": []
}
],
"coverage_matrix": [
{
"spec_section": 4,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_00_MinimalModule"
]
},
{
"spec_section": 5,
"coverage_level": "Runtime",
"program_ids": [
"W2_00_MinimalModule"
]
},
{
"spec_section": 6,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_10_DataTargetToolFrame",
"W2_E20_SemanticDiagnostics"
]
},
{
"spec_section": 7,
"coverage_level": "Runtime/Static/Post",
"program_ids": [
"W2_20_ExpressionMath",
"W2_E10_ExpressionDiagnostics",
"W2_P20_CrossBrandMotion"
]
},
{
"spec_section": 8,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_10_DataTargetToolFrame",
"W2_E30_MotionDiagnostics"
]
},
{
"spec_section": 9,
"coverage_level": "Runtime/Post",
"program_ids": [
"W2_20_ExpressionMath",
"W2_30_MotionAllTypes",
"W2_P20_CrossBrandMotion"
]
},
{
"spec_section": 10,
"coverage_level": "Runtime/Static/Post",
"program_ids": [
"W2_30_MotionAllTypes",
"W2_E30_MotionDiagnostics",
"W2_P20_CrossBrandMotion"
]
},
{
"spec_section": 11,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_40_PathEvents",
"W2_E30_MotionDiagnostics"
]
},
{
"spec_section": 12,
"coverage_level": "Runtime/Post",
"program_ids": [
"W2_50_OperationProcess",
"W2_P30_Roundtrip"
]
},
{
"spec_section": 13,
"coverage_level": "Runtime",
"program_ids": [
"W2_60_IOWaitPulse",
"W2_E50_RuntimeTimeout"
]
},
{
"spec_section": 14,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_70_ControlFlow",
"W2_E40_ControlFlowDiagnostics"
]
},
{
"spec_section": 15,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_80_ProcFuncCall",
"W2_E20_SemanticDiagnostics"
]
},
{
"spec_section": 16,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_90_ExceptionAlarm",
"W2_E50_RuntimeTimeout"
]
},
{
"spec_section": 17,
"coverage_level": "Static",
"program_ids": [
"W2_90_ExceptionAlarm"
]
},
{
"spec_section": 18,
"coverage_level": "Post",
"program_ids": [
"W2_P10_BrandHints"
]
},
{
"spec_section": 19,
"coverage_level": "Post",
"program_ids": [
"W2_P30_Roundtrip"
]
},
{
"spec_section": 20,
"coverage_level": "Post",
"program_ids": [
"W2_P20_CrossBrandMotion"
]
},
{
"spec_section": 21,
"coverage_level": "Runtime/Static",
"program_ids": [
"W2_00_MinimalModule",
"W2_E10_ExpressionDiagnostics"
]
},
{
"spec_section": 22,
"coverage_level": "Static",
"program_ids": [
"W2_E10_ExpressionDiagnostics",
"W2_E20_SemanticDiagnostics",
"W2_E30_MotionDiagnostics",
"W2_E40_ControlFlowDiagnostics",
"W2_E50_RuntimeTimeout"
]
},
{
"spec_section": 23,
"coverage_level": "Static",
"program_ids": [
"W2_00_MinimalModule"
]
},
{
"spec_section": 24,
"coverage_level": "Runtime",
"program_ids": [
"W2_P30_Roundtrip"
]
},
{
"spec_section": 25,
"coverage_level": "Runtime/Static/Post",
"program_ids": [
"W2_00_MinimalModule",
"W2_10_DataTargetToolFrame",
"W2_20_ExpressionMath",
"W2_30_MotionAllTypes",
"W2_40_PathEvents",
"W2_50_OperationProcess",
"W2_60_IOWaitPulse",
"W2_70_ControlFlow",
"W2_80_ProcFuncCall",
"W2_90_ExceptionAlarm",
"W2_P20_CrossBrandMotion"
]
}
]
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2MinimalModule",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 1,
"kdlMotionRequests": 1,
"kdlPathRequests": 0,
"symbolCount": 4,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,455 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "completed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "stopped",
"result": "completed",
"diagnostics": []
},
{
"command": "stepMotion",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 1,
"callStack": [
{
"procedure": "main",
"pc": 1
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2MinimalModule",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2MinimalModule"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 7,
"column": 5
}
},
"sourceMap": {
"line": 7,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 7,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_00_MinimalModule-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_00_MinimalModule-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,82 @@
{
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 7,
"column": 5
}
},
"sourceMap": {
"line": 7,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 7,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,8 @@
{
"filenames": [
"W2MinimalModule.mod",
"W2MinimalModule.ls",
"W2MinimalModule.src"
],
"report": []
}

View File

@@ -0,0 +1,72 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2MinimalModule",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2MinimalModule"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:7:5",
"sourceMap": {
"line": 7,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 4,
"duration": 0.24,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2DataTargetToolFrame",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 3,
"kdlMotionRequests": 3,
"kdlPathRequests": 0,
"symbolCount": 19,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,872 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "stopped",
"result": "completed",
"diagnostics": []
},
{
"command": "stepMotion",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 3,
"callStack": [
{
"procedure": "main",
"pc": 3
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2DataTargetToolFrame",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2DataTargetToolFrame"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:43:5",
"sourceMap": {
"line": 43,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:43:5",
"sourceMap": {
"line": 43,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 41,
"column": 5
}
},
"sourceMap": {
"line": 41,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 41,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
-0.4000000033993267,
0.5000000042491584,
0,
0.20000000169966334,
0
],
"id": "approach"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 42,
"column": 5
}
},
"sourceMap": {
"line": 42,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEJ",
"target": {
"joints": [
0,
-0.4000000033993267,
0.5000000042491584,
0,
0.20000000169966334,
0
],
"id": "approach"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 42,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0.03,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "pick_q"
},
"speed": {
"kind": "linear",
"velocity": 0.12
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 43,
"column": 5
}
},
"sourceMap": {
"line": 43,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_3",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0.03,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "pick_q"
},
"speed": {
"kind": "linear",
"velocity": 0.12
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 43,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_10_DataTargetToolFrame-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_10_DataTargetToolFrame-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,416 @@
{
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 41,
"column": 5
}
},
"sourceMap": {
"line": 41,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 41,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
-0.4000000033993267,
0.5000000042491584,
0,
0.20000000169966334,
0
],
"id": "approach"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 42,
"column": 5
}
},
"sourceMap": {
"line": 42,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEJ",
"target": {
"joints": [
0,
-0.4000000033993267,
0.5000000042491584,
0,
0.20000000169966334,
0
],
"id": "approach"
},
"speed": {
"kind": "joint_percent",
"value": 0.4
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 42,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0.03,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "pick_q"
},
"speed": {
"kind": "linear",
"velocity": 0.12
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 43,
"column": 5
}
},
"sourceMap": {
"line": 43,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_3",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0.03,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "pick_q"
},
"speed": {
"kind": "linear",
"velocity": 0.12
},
"zone": {
"kind": "distance",
"value": 0.005
},
"tool": {
"position": [
0,
0,
0.1
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 43,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,8 @@
{
"filenames": [
"W2DataTargetToolFrame.mod",
"W2DataTargetToolFrame.ls",
"W2DataTargetToolFrame.src"
],
"report": []
}

View File

@@ -0,0 +1,155 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2DataTargetToolFrame",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2DataTargetToolFrame"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:41:5",
"sourceMap": {
"line": 41,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:42:5",
"sourceMap": {
"line": 42,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:43:5",
"sourceMap": {
"line": 43,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:43:5",
"sourceMap": {
"line": 43,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 12,
"duration": 0.72,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0.5,
0.03,
-0.5,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2ExpressionMath",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 3,
"kdlMotionRequests": 2,
"kdlPathRequests": 0,
"symbolCount": 9,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,631 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "stopped",
"result": "completed",
"diagnostics": []
},
{
"command": "stepMotion",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 3,
"callStack": [
{
"procedure": "main",
"pc": 3
}
],
"scopeStack": [
{
"id": "global",
"variables": {
"$wait:main:2": 0
}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ExpressionMath",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ExpressionMath"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "wait",
"procedure": "main",
"pc": 2,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0.2617993877991494,
-0.5235987755982988,
0,
0.2617993877991494,
0.05235987755982989
],
"id": "home"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 16,
"column": 5
}
},
"sourceMap": {
"line": 16,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0.2617993877991494,
-0.5235987755982988,
0,
0.2617993877991494,
0.05235987755982989
],
"id": "home"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 16,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.45,
0.04,
0.3
],
"quaternion": [
0,
0,
0.3826834323650897,
0.9238795325112867
]
},
"id": "pick"
},
"speed": {
"kind": "linear",
"velocity": 0.15000000000000002
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.45,
0.04,
0.3
],
"quaternion": [
0,
0,
0.3826834323650897,
0.9238795325112867
]
},
"id": "pick"
},
"speed": {
"kind": "linear",
"velocity": 0.15000000000000002
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 17,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_20_ExpressionMath-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_20_ExpressionMath-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,172 @@
{
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0.2617993877991494,
-0.5235987755982988,
0,
0.2617993877991494,
0.05235987755982989
],
"id": "home"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 16,
"column": 5
}
},
"sourceMap": {
"line": 16,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0.2617993877991494,
-0.5235987755982988,
0,
0.2617993877991494,
0.05235987755982989
],
"id": "home"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 16,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.45,
0.04,
0.3
],
"quaternion": [
0,
0,
0.3826834323650897,
0.9238795325112867
]
},
"id": "pick"
},
"speed": {
"kind": "linear",
"velocity": 0.15000000000000002
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.45,
0.04,
0.3
],
"quaternion": [
0,
0,
0.3826834323650897,
0.9238795325112867
]
},
"id": "pick"
},
"speed": {
"kind": "linear",
"velocity": 0.15000000000000002
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 17,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,8 @@
{
"filenames": [
"W2ExpressionMath.mod",
"W2ExpressionMath.ls",
"W2ExpressionMath.src"
],
"report": []
}

View File

@@ -0,0 +1,156 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ExpressionMath",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ExpressionMath"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "wait",
"procedure": "main",
"pc": 2,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 8,
"duration": 0.48,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0.45,
0.04,
-0.2,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2MotionAllTypes",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 3,
"kdlMotionRequests": 3,
"kdlPathRequests": 0,
"symbolCount": 10,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,936 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "stopped",
"result": "completed",
"diagnostics": []
},
{
"command": "stepMotion",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 3,
"callStack": [
{
"procedure": "main",
"pc": 3
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2MotionAllTypes",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2MotionAllTypes"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEC",
"source": {
"kind": "MOVEC",
"id": "main:MOVEC:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEC",
"source": {
"kind": "MOVEC",
"id": "main:MOVEC:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.45
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.45
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 17,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "start"
},
"speed": {
"kind": "linear",
"velocity": 0.15
},
"zone": {
"kind": "distance",
"value": 0.01
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 18,
"column": 5
}
},
"sourceMap": {
"line": 18,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "start"
},
"speed": {
"kind": "linear",
"velocity": 0.15
},
"zone": {
"kind": "distance",
"value": 0.01
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 18,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEC",
"target": {
"pose": {
"position": [
0.6,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "finish"
},
"via": {
"pose": {
"position": [
0.55,
0.05,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "mid"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 19,
"column": 5
}
},
"sourceMap": {
"line": 19,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_3",
"motion": "MOVEC",
"target": {
"pose": {
"position": [
0.6,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "finish"
},
"via": {
"pose": {
"position": [
0.55,
0.05,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "mid"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 19,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_30_MotionAllTypes-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_30_MotionAllTypes-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,480 @@
{
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.45
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"sourceMap": {
"line": 17,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.45
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 17,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_2",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "start"
},
"speed": {
"kind": "linear",
"velocity": 0.15
},
"zone": {
"kind": "distance",
"value": 0.01
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 18,
"column": 5
}
},
"sourceMap": {
"line": 18,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_2",
"motion": "MOVEL",
"target": {
"pose": {
"position": [
0.5,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "start"
},
"speed": {
"kind": "linear",
"velocity": 0.15
},
"zone": {
"kind": "distance",
"value": 0.01
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 18,
"column": 5
}
}
]
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEC",
"target": {
"pose": {
"position": [
0.6,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "finish"
},
"via": {
"pose": {
"position": [
0.55,
0.05,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "mid"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 19,
"column": 5
}
},
"sourceMap": {
"line": 19,
"column": 5
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_3",
"motion": "MOVEC",
"target": {
"pose": {
"position": [
0.6,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "finish"
},
"via": {
"pose": {
"position": [
0.55,
0.05,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"tool": {
"id": "gripper"
},
"frame": {
"id": "fixture"
},
"id": "mid"
},
"speed": {
"kind": "linear",
"velocity": 0.1
},
"zone": {
"kind": "fine"
},
"tool": {
"position": [
0,
0,
0.08
],
"quaternion": [
0,
0,
0,
1
]
},
"frame": {
"position": [
0.8,
0,
0
],
"quaternion": [
0,
0,
0,
1
]
},
"sourceMap": {
"line": 19,
"column": 5
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,8 @@
{
"filenames": [
"W2MotionAllTypes.mod",
"W2MotionAllTypes.ls",
"W2MotionAllTypes.src"
],
"report": []
}

View File

@@ -0,0 +1,155 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2MotionAllTypes",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2MotionAllTypes"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 1,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEL",
"source": {
"kind": "MOVEL",
"id": "main:MOVEL:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEC",
"source": {
"kind": "MOVEC",
"id": "main:MOVEC:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEC",
"source": {
"kind": "MOVEC",
"id": "main:MOVEC:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"id": 8
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 12,
"duration": 0.72,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0.6,
0,
-0.5,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2PathEvents",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 7,
"kdlMotionRequests": 0,
"kdlPathRequests": 1,
"symbolCount": 8,
"procedureCount": 1,
"pathCount": 1,
"operationCount": 0
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_40_PathEvents-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,731 @@
{
"items": [
{
"id": "mq_1",
"kind": "path",
"source": {
"kind": "path",
"pathId": "generated_path",
"instruction": {
"kind": "RUN_PATH",
"pathId": "generated_path",
"sourceMap": {
"line": 24,
"column": 5
}
},
"sourceMap": {
"line": 24,
"column": 5
}
},
"request": {
"pathId": "generated_path",
"startJoints": [
0,
0,
0,
0,
0,
0
],
"segments": [
{
"id": "p_home",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"targetId": "home",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 16,
"column": 18
},
"source": {
"type": "cad_curve",
"id": "edge_032",
"sample_distance": 0.005
}
},
{
"id": "p_pick",
"motion": "MOVEJ",
"target": {
"joints": [
0.20000000169966334,
-0.3500000029744108,
0.4500000038242425,
0.10000000084983167,
-0.20000000169966334,
0.300000002549495
],
"id": "pick"
},
"targetId": "pick",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 18,
"column": 18
},
"source": {
"type": "cad_curve",
"id": "edge_032",
"sample_distance": 0.005
}
},
{
"id": "p_place",
"motion": "MOVEJ",
"target": {
"joints": [
-0.3500000029744108,
-0.2500000021245792,
0.3500000029744108,
-0.2500000021245792,
0.1500000012747475,
-0.4000000033993267
],
"id": "place"
},
"targetId": "place",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "distance",
"value": 0.01
},
"sourceMap": {
"line": 20,
"column": 19
},
"source": {
"type": "cad_curve",
"id": "edge_032",
"sample_distance": 0.005
}
}
],
"events": [
{
"id": "event_0",
"timing": "before",
"pointId": "p_pick",
"kind": "io",
"sourceMap": {
"line": 17,
"column": 25
},
"data": {
"statement": "io . do [ 10 ] = true",
"tokens": [
{
"kind": "keyword",
"raw": "io",
"value": "io",
"range": {
"start": {
"offset": 703,
"line": 17,
"column": 25
},
"end": {
"offset": 705,
"line": 17,
"column": 27
}
}
},
{
"kind": "punctuation",
"raw": ".",
"value": ".",
"range": {
"start": {
"offset": 705,
"line": 17,
"column": 27
},
"end": {
"offset": 706,
"line": 17,
"column": 28
}
}
},
{
"kind": "identifier",
"raw": "do",
"value": "do",
"range": {
"start": {
"offset": 706,
"line": 17,
"column": 28
},
"end": {
"offset": 708,
"line": 17,
"column": 30
}
}
},
{
"kind": "punctuation",
"raw": "[",
"value": "[",
"range": {
"start": {
"offset": 708,
"line": 17,
"column": 30
},
"end": {
"offset": 709,
"line": 17,
"column": 31
}
}
},
{
"kind": "number",
"raw": "10",
"value": 10,
"range": {
"start": {
"offset": 709,
"line": 17,
"column": 31
},
"end": {
"offset": 711,
"line": 17,
"column": 33
}
}
},
{
"kind": "punctuation",
"raw": "]",
"value": "]",
"range": {
"start": {
"offset": 711,
"line": 17,
"column": 33
},
"end": {
"offset": 712,
"line": 17,
"column": 34
}
}
},
{
"kind": "operator",
"raw": "=",
"value": "=",
"range": {
"start": {
"offset": 713,
"line": 17,
"column": 35
},
"end": {
"offset": 714,
"line": 17,
"column": 36
}
}
},
{
"kind": "keyword",
"raw": "true",
"value": "true",
"range": {
"start": {
"offset": 715,
"line": 17,
"column": 37
},
"end": {
"offset": 719,
"line": 17,
"column": 41
}
}
}
]
}
},
{
"id": "event_1",
"timing": "after",
"pointId": "p_pick",
"kind": "wait",
"sourceMap": {
"line": 19,
"column": 24
},
"data": {
"statement": "wait io . di [ 10 ] == true timeout 2 s on_timeout alarm \"pick sensor timeout\"",
"tokens": [
{
"kind": "keyword",
"raw": "wait",
"value": "wait",
"range": {
"start": {
"offset": 780,
"line": 19,
"column": 24
},
"end": {
"offset": 784,
"line": 19,
"column": 28
}
}
},
{
"kind": "keyword",
"raw": "io",
"value": "io",
"range": {
"start": {
"offset": 785,
"line": 19,
"column": 29
},
"end": {
"offset": 787,
"line": 19,
"column": 31
}
}
},
{
"kind": "punctuation",
"raw": ".",
"value": ".",
"range": {
"start": {
"offset": 787,
"line": 19,
"column": 31
},
"end": {
"offset": 788,
"line": 19,
"column": 32
}
}
},
{
"kind": "identifier",
"raw": "di",
"value": "di",
"range": {
"start": {
"offset": 788,
"line": 19,
"column": 32
},
"end": {
"offset": 790,
"line": 19,
"column": 34
}
}
},
{
"kind": "punctuation",
"raw": "[",
"value": "[",
"range": {
"start": {
"offset": 790,
"line": 19,
"column": 34
},
"end": {
"offset": 791,
"line": 19,
"column": 35
}
}
},
{
"kind": "number",
"raw": "10",
"value": 10,
"range": {
"start": {
"offset": 791,
"line": 19,
"column": 35
},
"end": {
"offset": 793,
"line": 19,
"column": 37
}
}
},
{
"kind": "punctuation",
"raw": "]",
"value": "]",
"range": {
"start": {
"offset": 793,
"line": 19,
"column": 37
},
"end": {
"offset": 794,
"line": 19,
"column": 38
}
}
},
{
"kind": "operator",
"raw": "==",
"value": "==",
"range": {
"start": {
"offset": 795,
"line": 19,
"column": 39
},
"end": {
"offset": 797,
"line": 19,
"column": 41
}
}
},
{
"kind": "keyword",
"raw": "true",
"value": "true",
"range": {
"start": {
"offset": 798,
"line": 19,
"column": 42
},
"end": {
"offset": 802,
"line": 19,
"column": 46
}
}
},
{
"kind": "identifier",
"raw": "timeout",
"value": "timeout",
"range": {
"start": {
"offset": 803,
"line": 19,
"column": 47
},
"end": {
"offset": 810,
"line": 19,
"column": 54
}
}
},
{
"kind": "number",
"raw": "2 s",
"value": 2,
"range": {
"start": {
"offset": 811,
"line": 19,
"column": 55
},
"end": {
"offset": 814,
"line": 19,
"column": 58
}
},
"unit": {
"raw": "s",
"kind": "time",
"siUnit": "s",
"normalizedValue": 2
}
},
{
"kind": "identifier",
"raw": "on_timeout",
"value": "on_timeout",
"range": {
"start": {
"offset": 815,
"line": 19,
"column": 59
},
"end": {
"offset": 825,
"line": 19,
"column": 69
}
}
},
{
"kind": "keyword",
"raw": "alarm",
"value": "alarm",
"range": {
"start": {
"offset": 826,
"line": 19,
"column": 70
},
"end": {
"offset": 831,
"line": 19,
"column": 75
}
}
},
{
"kind": "string",
"raw": "\"pick sensor timeout\"",
"value": "pick sensor timeout",
"range": {
"start": {
"offset": 832,
"line": 19,
"column": 76
},
"end": {
"offset": 853,
"line": 19,
"column": 97
}
}
}
]
}
},
{
"id": "event_2",
"timing": "at",
"pointId": "p_place",
"distance": 0.01,
"kind": "pulse",
"sourceMap": {
"line": 21,
"column": 37
},
"data": {
"statement": "pulse io . do [ 11 ] duration 100 ms",
"tokens": [
{
"kind": "keyword",
"raw": "pulse",
"value": "pulse",
"range": {
"start": {
"offset": 929,
"line": 21,
"column": 37
},
"end": {
"offset": 934,
"line": 21,
"column": 42
}
}
},
{
"kind": "keyword",
"raw": "io",
"value": "io",
"range": {
"start": {
"offset": 935,
"line": 21,
"column": 43
},
"end": {
"offset": 937,
"line": 21,
"column": 45
}
}
},
{
"kind": "punctuation",
"raw": ".",
"value": ".",
"range": {
"start": {
"offset": 937,
"line": 21,
"column": 45
},
"end": {
"offset": 938,
"line": 21,
"column": 46
}
}
},
{
"kind": "identifier",
"raw": "do",
"value": "do",
"range": {
"start": {
"offset": 938,
"line": 21,
"column": 46
},
"end": {
"offset": 940,
"line": 21,
"column": 48
}
}
},
{
"kind": "punctuation",
"raw": "[",
"value": "[",
"range": {
"start": {
"offset": 940,
"line": 21,
"column": 48
},
"end": {
"offset": 941,
"line": 21,
"column": 49
}
}
},
{
"kind": "number",
"raw": "11",
"value": 11,
"range": {
"start": {
"offset": 941,
"line": 21,
"column": 49
},
"end": {
"offset": 943,
"line": 21,
"column": 51
}
}
},
{
"kind": "punctuation",
"raw": "]",
"value": "]",
"range": {
"start": {
"offset": 943,
"line": 21,
"column": 51
},
"end": {
"offset": 944,
"line": 21,
"column": 52
}
}
},
{
"kind": "identifier",
"raw": "duration",
"value": "duration",
"range": {
"start": {
"offset": 945,
"line": 21,
"column": 53
},
"end": {
"offset": 953,
"line": 21,
"column": 61
}
}
},
{
"kind": "number",
"raw": "100 ms",
"value": 100,
"range": {
"start": {
"offset": 954,
"line": 21,
"column": 62
},
"end": {
"offset": 960,
"line": 21,
"column": 68
}
},
"unit": {
"raw": "ms",
"kind": "time",
"siUnit": "s",
"normalizedValue": 0.1
}
}
]
}
}
],
"sampleTime": 0.02,
"source": {
"type": "cad_curve",
"id": "edge_032",
"sample_distance": 0.005
}
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,27 @@
{
"filenames": [
"W2PathEvents.mod",
"W2PathEvents.ls",
"W2PathEvents.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,72 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2PathEvents",
"source": {
"kind": "RUN_PATH",
"id": "main:RUN_PATH:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2PathEvents"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "RUN_PATH",
"source": {
"kind": "RUN_PATH",
"id": "main:RUN_PATH:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "RUN_PATH",
"source": {
"kind": "RUN_PATH",
"id": "main:RUN_PATH:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 12,
"duration": 0.72,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
-0.3500000029744108,
-0.2500000021245792,
0.3500000029744108,
-0.2500000021245792,
0.15000000127474747,
-0.4000000033993266
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2OperationProcess",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 4,
"kdlMotionRequests": 0,
"kdlPathRequests": 1,
"symbolCount": 6,
"procedureCount": 1,
"pathCount": 1,
"operationCount": 1
}

View File

@@ -0,0 +1,500 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "completed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "stopped",
"result": "completed",
"diagnostics": []
},
{
"command": "stepMotion",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 1,
"callStack": [
{
"procedure": "main",
"pc": 1
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2OperationProcess",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2OperationProcess"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "RUN_OPERATION",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "RUN_OPERATION",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "action",
"status": "done",
"source": {
"kind": "action",
"operationId": "pick_op",
"actionKind": "start_action",
"statement": "io . do [ 1 ] = true",
"sourceMap": {
"line": 19,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": []
}
},
{
"id": "mq_2",
"kind": "path",
"source": {
"kind": "path",
"pathId": "op_path",
"operationId": "pick_op",
"instruction": {
"kind": "RUN_PATH",
"pathId": "op_path",
"sourceMap": {
"line": 24,
"column": 5
}
},
"sourceMap": {
"line": 24,
"column": 5
}
},
"request": {
"pathId": "op_path",
"startJoints": [
0,
0,
0,
0,
0,
0
],
"segments": [
{
"id": "p0",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"targetId": "home",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 8,
"column": 14
}
}
],
"sampleTime": 0.02
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "action",
"status": "done",
"source": {
"kind": "action",
"operationId": "pick_op",
"actionKind": "end_action",
"statement": "io . do [ 1 ] = false",
"sourceMap": {
"line": 21,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": []
}
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_50_OperationProcess-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [
"op_path"
],
"operationIds": [
"pick_op"
],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_50_OperationProcess-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,123 @@
{
"items": [
{
"id": "mq_1",
"kind": "action",
"status": "done",
"source": {
"kind": "action",
"operationId": "pick_op",
"actionKind": "start_action",
"statement": "io . do [ 1 ] = true",
"sourceMap": {
"line": 19,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": []
}
},
{
"id": "mq_2",
"kind": "path",
"source": {
"kind": "path",
"pathId": "op_path",
"operationId": "pick_op",
"instruction": {
"kind": "RUN_PATH",
"pathId": "op_path",
"sourceMap": {
"line": 24,
"column": 5
}
},
"sourceMap": {
"line": 24,
"column": 5
}
},
"request": {
"pathId": "op_path",
"startJoints": [
0,
0,
0,
0,
0,
0
],
"segments": [
{
"id": "p0",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"targetId": "home",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 8,
"column": 14
}
}
],
"sampleTime": 0.02
},
"status": "queued"
},
{
"id": "mq_3",
"kind": "action",
"status": "done",
"source": {
"kind": "action",
"operationId": "pick_op",
"actionKind": "end_action",
"statement": "io . do [ 1 ] = false",
"sourceMap": {
"line": 21,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": []
}
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,27 @@
{
"filenames": [
"W2OperationProcess.mod",
"W2OperationProcess.ls",
"W2OperationProcess.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_OPERATION is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_OPERATION is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_OPERATION is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,72 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2OperationProcess",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2OperationProcess"
},
"id": 1
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 0,
"instructionKind": "RUN_OPERATION",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "RUN_OPERATION",
"source": {
"kind": "RUN_OPERATION",
"id": "main:RUN_OPERATION:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 4,
"duration": 0.24,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2IOWaitPulse",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 12,
"kdlMotionRequests": 0,
"kdlPathRequests": 1,
"symbolCount": 5,
"procedureCount": 1,
"pathCount": 1,
"operationCount": 0
}

View File

@@ -0,0 +1,253 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75,
"io.do[1]": true,
"io.ao[1]": 0.75,
"io.go[1]": 3,
"io.do[2]": true
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0,
"writer": "program",
"target": {
"domain": "do",
"index": 1,
"raw": "io.do[1]"
},
"value": true,
"kind": "write"
},
{
"id": 11,
"time": 0,
"writer": "program",
"target": {
"domain": "ao",
"index": 1,
"raw": "io.ao[1]"
},
"value": 0.75,
"kind": "write"
},
{
"id": 12,
"time": 0,
"writer": "program",
"target": {
"domain": "go",
"index": 1,
"raw": "io.go[1]"
},
"value": 3,
"kind": "write"
},
{
"id": 13,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 14,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 15,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 16,
"time": 0.1,
"writer": "program",
"target": {
"domain": "do",
"index": 2,
"raw": "io.do[2]"
},
"value": true,
"kind": "pulse_set"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_60_IOWaitPulse-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,279 @@
{
"items": [
{
"id": "mq_1",
"kind": "path",
"source": {
"kind": "path",
"pathId": "io_path",
"instruction": {
"kind": "RUN_PATH",
"pathId": "io_path",
"sourceMap": {
"line": 21,
"column": 5
}
},
"sourceMap": {
"line": 21,
"column": 5
}
},
"request": {
"pathId": "io_path",
"startJoints": [
0,
0,
0,
0,
0,
0
],
"segments": [
{
"id": "p0",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"targetId": "home",
"speed": {
"kind": "joint_percent",
"value": 0.35000000000000003
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 8,
"column": 14
}
}
],
"events": [
{
"id": "event_0",
"timing": "at",
"pointId": "p0",
"distance": 0.01,
"kind": "pulse",
"sourceMap": {
"line": 9,
"column": 35
},
"data": {
"statement": "pulse io . do [ 20 ] duration 50 + 50 ms",
"tokens": [
{
"kind": "keyword",
"raw": "pulse",
"value": "pulse",
"range": {
"start": {
"offset": 286,
"line": 9,
"column": 35
},
"end": {
"offset": 291,
"line": 9,
"column": 40
}
}
},
{
"kind": "keyword",
"raw": "io",
"value": "io",
"range": {
"start": {
"offset": 292,
"line": 9,
"column": 41
},
"end": {
"offset": 294,
"line": 9,
"column": 43
}
}
},
{
"kind": "punctuation",
"raw": ".",
"value": ".",
"range": {
"start": {
"offset": 294,
"line": 9,
"column": 43
},
"end": {
"offset": 295,
"line": 9,
"column": 44
}
}
},
{
"kind": "identifier",
"raw": "do",
"value": "do",
"range": {
"start": {
"offset": 295,
"line": 9,
"column": 44
},
"end": {
"offset": 297,
"line": 9,
"column": 46
}
}
},
{
"kind": "punctuation",
"raw": "[",
"value": "[",
"range": {
"start": {
"offset": 297,
"line": 9,
"column": 46
},
"end": {
"offset": 298,
"line": 9,
"column": 47
}
}
},
{
"kind": "number",
"raw": "20",
"value": 20,
"range": {
"start": {
"offset": 298,
"line": 9,
"column": 47
},
"end": {
"offset": 300,
"line": 9,
"column": 49
}
}
},
{
"kind": "punctuation",
"raw": "]",
"value": "]",
"range": {
"start": {
"offset": 300,
"line": 9,
"column": 49
},
"end": {
"offset": 301,
"line": 9,
"column": 50
}
}
},
{
"kind": "identifier",
"raw": "duration",
"value": "duration",
"range": {
"start": {
"offset": 302,
"line": 9,
"column": 51
},
"end": {
"offset": 310,
"line": 9,
"column": 59
}
}
},
{
"kind": "number",
"raw": "50",
"value": 50,
"range": {
"start": {
"offset": 311,
"line": 9,
"column": 60
},
"end": {
"offset": 313,
"line": 9,
"column": 62
}
}
},
{
"kind": "operator",
"raw": "+",
"value": "+",
"range": {
"start": {
"offset": 314,
"line": 9,
"column": 63
},
"end": {
"offset": 315,
"line": 9,
"column": 64
}
}
},
{
"kind": "number",
"raw": "50 ms",
"value": 50,
"range": {
"start": {
"offset": 316,
"line": 9,
"column": 65
},
"end": {
"offset": 321,
"line": 9,
"column": 70
}
},
"unit": {
"raw": "ms",
"kind": "time",
"siUnit": "s",
"normalizedValue": 0.05
}
}
]
}
}
],
"sampleTime": 0.02
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,27 @@
{
"filenames": [
"W2IOWaitPulse.mod",
"W2IOWaitPulse.ls",
"W2IOWaitPulse.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RUN_PATH is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,493 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2IOWaitPulse",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:12:5",
"sourceMap": {
"line": 12,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2IOWaitPulse"
},
"id": 1
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 0,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:12:5",
"sourceMap": {
"line": 12,
"column": 5
},
"procedureId": "main"
},
"data": {
"result": [
{
"id": 10,
"time": 0,
"writer": "program",
"target": {
"domain": "do",
"index": 1,
"raw": "io.do[1]"
},
"value": true,
"kind": "write"
}
]
},
"id": 2
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 1,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:12:5",
"sourceMap": {
"line": 12,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 1,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"data": {
"result": [
{
"id": 11,
"time": 0,
"writer": "program",
"target": {
"domain": "ao",
"index": 1,
"raw": "io.ao[1]"
},
"value": 0.75,
"kind": "write"
}
]
},
"id": 5
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 2,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 2,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"data": {
"result": [
{
"id": 12,
"time": 0,
"writer": "program",
"target": {
"domain": "go",
"index": 1,
"raw": "io.go[1]"
},
"value": 3,
"kind": "write"
}
]
},
"id": 7
},
{
"time": 0,
"kind": "io",
"procedure": "main",
"pc": 3,
"instructionKind": "IO_WRITE",
"source": {
"kind": "IO_WRITE",
"id": "main:IO_WRITE:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"id": 8
},
{
"time": 0,
"kind": "wait",
"procedure": "main",
"pc": 3,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:15:5",
"sourceMap": {
"line": 15,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 9
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 4,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:15:5",
"sourceMap": {
"line": 15,
"column": 5
},
"procedureId": "main"
},
"id": 10
},
{
"time": 0,
"kind": "wait",
"procedure": "main",
"pc": 4,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 11
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:16:5",
"sourceMap": {
"line": 16,
"column": 5
},
"procedureId": "main"
},
"id": 12
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"message": "Execution exceeded 3 steps",
"source": {
"kind": "WAIT",
"id": "main:WAIT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 13
},
{
"time": 0.1,
"kind": "wait",
"procedure": "main",
"pc": 5,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 14
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 6,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 15
},
{
"time": 0.1,
"kind": "wait",
"procedure": "main",
"pc": 6,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 16
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 7,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 17
},
{
"time": 0.1,
"kind": "wait",
"procedure": "main",
"pc": 7,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"data": {
"status": "satisfied",
"elapsed": 0
},
"id": 18
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 8,
"instructionKind": "WAIT",
"source": {
"kind": "WAIT",
"id": "main:WAIT:19:5",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "main"
},
"id": 19
},
{
"time": 0.1,
"kind": "io",
"procedure": "main",
"pc": 8,
"instructionKind": "PULSE",
"source": {
"kind": "PULSE",
"id": "main:PULSE:20:5",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "main"
},
"data": {
"result": [
{
"id": 16,
"time": 0.1,
"writer": "program",
"target": {
"domain": "do",
"index": 2,
"raw": "io.do[2]"
},
"value": true,
"kind": "pulse_set"
}
]
},
"id": 20
},
{
"time": 0.1,
"kind": "io",
"procedure": "main",
"pc": 9,
"instructionKind": "PULSE",
"source": {
"kind": "PULSE",
"id": "main:PULSE:20:5",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "main"
},
"id": 21
},
{
"time": 0.1,
"kind": "motion",
"procedure": "main",
"pc": 9,
"instructionKind": "RUN_PATH",
"source": {
"kind": "RUN_PATH",
"id": "main:RUN_PATH:21:5",
"sourceMap": {
"line": 21,
"column": 5
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 22
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 10,
"instructionKind": "RUN_PATH",
"source": {
"kind": "RUN_PATH",
"id": "main:RUN_PATH:21:5",
"sourceMap": {
"line": 21,
"column": 5
},
"procedureId": "main"
},
"id": 23
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 4,
"duration": 0.24,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2ControlFlow",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 14,
"kdlMotionRequests": 0,
"kdlPathRequests": 0,
"symbolCount": 8,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,610 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
}
]
},
{
"command": "stepMotion",
"before": "running",
"after": "running",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 8,
"callStack": [
{
"procedure": "main",
"pc": 8
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
},
{
"id": "else:0",
"variables": {
"i": 1
}
},
{
"id": "for:3",
"variables": {}
},
{
"id": "switch:5",
"variables": {}
}
],
"alarmQueue": [
{
"id": "NOT_READY",
"message": "not ready",
"severity": "error",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"time": 0
},
{
"id": "MODE1",
"message": "mode 1",
"severity": "error",
"source": {
"kind": "ALARM",
"id": "main:ALARM:27:9",
"sourceMap": {
"line": 27,
"column": 9
},
"procedureId": "main"
},
"time": 0.1
}
],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ControlFlow",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ControlFlow"
},
"id": 1
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "EXEC_IF",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "main"
},
"id": 2
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 3
},
{
"time": 0,
"kind": "alarm",
"procedure": "main",
"pc": 1,
"message": "not ready",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"data": {
"alarmId": "NOT_READY",
"severity": "error"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "EXEC_WHILE",
"source": {
"kind": "EXEC_WHILE",
"id": "main:EXEC_WHILE:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 4,
"instructionKind": "EXEC_FOR",
"source": {
"kind": "EXEC_FOR",
"id": "main:EXEC_FOR:22:5",
"sourceMap": {
"line": 22,
"column": 5
},
"procedureId": "main"
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:23:7",
"sourceMap": {
"line": 23,
"column": 7
},
"procedureId": "main"
},
"id": 8
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"message": "Execution exceeded 3 steps",
"source": {
"kind": "EXEC_SWITCH",
"id": "main:EXEC_SWITCH:25:5",
"sourceMap": {
"line": 25,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 9
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 6,
"instructionKind": "EXEC_SWITCH",
"source": {
"kind": "EXEC_SWITCH",
"id": "main:EXEC_SWITCH:25:5",
"sourceMap": {
"line": 25,
"column": 5
},
"procedureId": "main"
},
"id": 10
},
{
"time": 0.1,
"kind": "diagnostic",
"procedure": "main",
"pc": 7,
"instructionKind": "BREAK",
"source": {
"kind": "BREAK",
"id": "main:BREAK:28:9",
"sourceMap": {
"line": 28,
"column": 9
},
"procedureId": "main"
},
"diagnostic": {
"severity": "info",
"code": "VC_BREAK",
"message": "BREAK reached",
"sourceMap": {
"line": 28,
"column": 9
}
},
"id": 11
},
{
"time": 0.1,
"kind": "alarm",
"procedure": "main",
"pc": 7,
"message": "mode 1",
"source": {
"kind": "ALARM",
"id": "main:ALARM:27:9",
"sourceMap": {
"line": 27,
"column": 9
},
"procedureId": "main"
},
"data": {
"alarmId": "MODE1",
"severity": "error"
},
"id": 12
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 8,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:27:9",
"sourceMap": {
"line": 27,
"column": 9
},
"procedureId": "main"
},
"id": 13
}
],
"completed": true
},
"motion": {
"items": [],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_70_ControlFlow-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_70_ControlFlow-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,5 @@
{
"items": [],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,153 @@
{
"filenames": [
"W2ControlFlow.mod",
"W2ControlFlow.ls",
"W2ControlFlow.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_WHILE is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_FOR is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_SWITCH is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "BREAK is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_WHILE is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_FOR is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_SWITCH is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "BREAK is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_WHILE is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_FOR is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_SWITCH is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "BREAK is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,253 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ControlFlow",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ControlFlow"
},
"id": 1
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "EXEC_IF",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "main"
},
"id": 2
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 3
},
{
"time": 0,
"kind": "alarm",
"procedure": "main",
"pc": 1,
"message": "not ready",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"data": {
"alarmId": "NOT_READY",
"severity": "error"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:16:7",
"sourceMap": {
"line": 16,
"column": 7
},
"procedureId": "main"
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "EXEC_WHILE",
"source": {
"kind": "EXEC_WHILE",
"id": "main:EXEC_WHILE:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 6
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 4,
"instructionKind": "EXEC_FOR",
"source": {
"kind": "EXEC_FOR",
"id": "main:EXEC_FOR:22:5",
"sourceMap": {
"line": 22,
"column": 5
},
"procedureId": "main"
},
"id": 7
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:23:7",
"sourceMap": {
"line": 23,
"column": 7
},
"procedureId": "main"
},
"id": 8
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"message": "Execution exceeded 3 steps",
"source": {
"kind": "EXEC_SWITCH",
"id": "main:EXEC_SWITCH:25:5",
"sourceMap": {
"line": 25,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 9
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 6,
"instructionKind": "EXEC_SWITCH",
"source": {
"kind": "EXEC_SWITCH",
"id": "main:EXEC_SWITCH:25:5",
"sourceMap": {
"line": 25,
"column": 5
},
"procedureId": "main"
},
"id": 10
},
{
"time": 0.1,
"kind": "diagnostic",
"procedure": "main",
"pc": 7,
"instructionKind": "BREAK",
"source": {
"kind": "BREAK",
"id": "main:BREAK:28:9",
"sourceMap": {
"line": 28,
"column": 9
},
"procedureId": "main"
},
"diagnostic": {
"severity": "info",
"code": "VC_BREAK",
"message": "BREAK reached",
"sourceMap": {
"line": 28,
"column": 9
}
},
"id": 11
},
{
"time": 0.1,
"kind": "alarm",
"procedure": "main",
"pc": 7,
"message": "mode 1",
"source": {
"kind": "ALARM",
"id": "main:ALARM:27:9",
"sourceMap": {
"line": 27,
"column": 9
},
"procedureId": "main"
},
"data": {
"alarmId": "MODE1",
"severity": "error"
},
"id": 12
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 8,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:27:9",
"sourceMap": {
"line": 27,
"column": 9
},
"procedureId": "main"
},
"id": 13
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 0,
"duration": 0,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2ProcFuncCall",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 9,
"kdlMotionRequests": 0,
"kdlPathRequests": 0,
"symbolCount": 8,
"procedureCount": 3,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,523 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
}
]
},
{
"command": "stepMotion",
"before": "running",
"after": "running",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 5,
"callStack": [
{
"procedure": "main",
"pc": 5
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ProcFuncCall",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ProcFuncCall"
},
"id": 1
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 2
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 3
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "read_part",
"pc": 0,
"instructionKind": "CALL",
"message": "Call read_part",
"source": {
"kind": "CALL",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "read_part"
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "read_part",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "read_part:RAW_STATEMENT:8:5",
"sourceMap": {
"line": 8,
"column": 5
},
"procedureId": "read_part"
},
"id": 6
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 3,
"message": "Execution exceeded 3 steps",
"source": {
"kind": "CALL",
"id": "main:CALL:20:5",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 7
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "increment_retry",
"pc": 0,
"instructionKind": "CALL",
"message": "Call increment_retry",
"source": {
"kind": "CALL",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "increment_retry"
},
"id": 8
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "increment_retry",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "increment_retry:RAW_STATEMENT:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "increment_retry"
},
"id": 9
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "EXEC_IF",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:21:5",
"sourceMap": {
"line": 21,
"column": 5
},
"procedureId": "main"
},
"id": 10
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "RETURN",
"source": {
"kind": "RETURN",
"id": "main:RETURN:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"id": 11
}
],
"currentSource": {
"kind": "RETURN",
"id": "main:RETURN:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"completed": true
},
"motion": {
"items": [],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_80_ProcFuncCall-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_80_ProcFuncCall-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,5 @@
{
"items": [],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,117 @@
{
"filenames": [
"W2ProcFuncCall.mod",
"W2ProcFuncCall.ls",
"W2ProcFuncCall.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RETURN is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RETURN is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "CALL is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "EXEC_IF is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RETURN is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,202 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ProcFuncCall",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ProcFuncCall"
},
"id": 1
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:17:5",
"sourceMap": {
"line": 17,
"column": 5
},
"procedureId": "main"
},
"id": 2
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 3
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:18:5",
"sourceMap": {
"line": 18,
"column": 5
},
"procedureId": "main"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "read_part",
"pc": 0,
"instructionKind": "CALL",
"message": "Call read_part",
"source": {
"kind": "CALL",
"sourceMap": {
"line": 19,
"column": 5
},
"procedureId": "read_part"
},
"id": 5
},
{
"time": 0,
"kind": "instruction",
"procedure": "read_part",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "read_part:RAW_STATEMENT:8:5",
"sourceMap": {
"line": 8,
"column": 5
},
"procedureId": "read_part"
},
"id": 6
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 3,
"message": "Execution exceeded 3 steps",
"source": {
"kind": "CALL",
"id": "main:CALL:20:5",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 7
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "increment_retry",
"pc": 0,
"instructionKind": "CALL",
"message": "Call increment_retry",
"source": {
"kind": "CALL",
"sourceMap": {
"line": 20,
"column": 5
},
"procedureId": "increment_retry"
},
"id": 8
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "increment_retry",
"pc": 1,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "increment_retry:RAW_STATEMENT:11:5",
"sourceMap": {
"line": 11,
"column": 5
},
"procedureId": "increment_retry"
},
"id": 9
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "EXEC_IF",
"source": {
"kind": "EXEC_IF",
"id": "main:EXEC_IF:21:5",
"sourceMap": {
"line": 21,
"column": 5
},
"procedureId": "main"
},
"id": 10
},
{
"time": 0.1,
"kind": "instruction",
"procedure": "main",
"pc": 5,
"instructionKind": "RETURN",
"source": {
"kind": "RETURN",
"id": "main:RETURN:24:5",
"sourceMap": {
"line": 24,
"column": 5
},
"procedureId": "main"
},
"id": 11
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 0,
"duration": 0,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,36 @@
{
"parsed": true,
"moduleName": "W2ExceptionAlarm",
"astKind": "Program",
"semanticChecks": [
"language/module/proc",
"const/var/persistent symbols",
"tool/frame/speed/zone",
"joint_target/pose_target",
"movej/movel/movec",
"path/point/event/run_path",
"operation/run_operation",
"io/wait/pulse",
"if/elseif/else/while/for/switch",
"call/return/break/continue",
"proc parameter directions",
"func returns and side effects",
"alarm/raise/try/catch",
"source map propagation",
"KDL motion request bridge",
"KDL path request bridge",
"duplicate symbol diagnostics",
"missing reference diagnostics",
"P1 unsupported diagnostics",
"operation action expansion",
"path event expansion",
"raw statement preservation"
],
"sourceMapEntries": 5,
"kdlMotionRequests": 1,
"kdlPathRequests": 0,
"symbolCount": 6,
"procedureCount": 1,
"pathCount": 0,
"operationCount": 0
}

View File

@@ -0,0 +1,606 @@
{
"commands": [
{
"command": "loadProgram",
"before": "unloaded",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "start",
"before": "stopped",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
}
]
},
{
"command": "stepInto",
"before": "paused",
"after": "paused",
"result": "executed",
"diagnostics": []
},
{
"command": "hold",
"before": "paused",
"after": "hold",
"result": "ok",
"diagnostics": []
},
{
"command": "resume",
"before": "hold",
"after": "running",
"result": "blocked",
"diagnostics": [
{
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
}
]
},
{
"command": "stepMotion",
"before": "running",
"after": "running",
"result": "ok",
"diagnostics": []
},
{
"command": "stop",
"before": "paused",
"after": "stopped",
"result": "ok",
"diagnostics": []
},
{
"command": "resetFault",
"before": "stopped",
"after": "stopped",
"result": "ok",
"diagnostics": []
}
],
"snapshot": {
"state": {
"state": "stopped",
"diagnostics": []
},
"runtime": {
"loaded": true,
"procedure": "main",
"pc": 5,
"callStack": [
{
"procedure": "main",
"pc": 5
}
],
"scopeStack": [
{
"id": "global",
"variables": {}
},
{
"id": "main",
"variables": {}
}
],
"alarmQueue": [
{
"id": "START",
"message": "start",
"severity": "info",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"time": 0
}
],
"trace": [
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ExceptionAlarm",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ExceptionAlarm"
},
"id": 1
},
{
"time": 0,
"kind": "alarm",
"procedure": "main",
"pc": 0,
"message": "start",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"data": {
"alarmId": "START",
"severity": "info"
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"id": 5
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:15:7",
"sourceMap": {
"line": 15,
"column": 7
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 6
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:15:7",
"sourceMap": {
"line": 15,
"column": 7
},
"procedureId": "main"
},
"id": 7
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 4,
"instructionKind": "UNSUPPORTED_RUNTIME",
"source": {
"kind": "UNSUPPORTED_RUNTIME",
"id": "main:UNSUPPORTED_RUNTIME:22:5",
"sourceMap": {
"line": 22,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "warning",
"code": "VC_UNSUPPORTED_RUNTIME",
"message": "enable interrupt is parsed but not executable in P0",
"sourceMap": {
"line": 22,
"column": 5
}
},
"id": 8
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"instructionKind": "UNSUPPORTED_RUNTIME",
"source": {
"kind": "UNSUPPORTED_RUNTIME",
"id": "main:UNSUPPORTED_RUNTIME:23:5",
"sourceMap": {
"line": 23,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "warning",
"code": "VC_UNSUPPORTED_RUNTIME",
"message": "disable interrupt is parsed but not executable in P0",
"sourceMap": {
"line": 23,
"column": 5
}
},
"id": 9
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"message": "Execution exceeded 3 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 10
}
],
"completed": true
},
"motion": {
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.3
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 15,
"column": 7
}
},
"sourceMap": {
"line": 15,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.3
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 15,
"column": 7
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
},
"io": {
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_90_ExceptionAlarm-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
},
"bridge": {
"pathIds": [],
"operationIds": [],
"diagnostics": []
}
}
}

View File

@@ -0,0 +1,201 @@
{
"time": 0.1,
"image": {
"io.di[1]": true,
"io.di[2]": false,
"io.di[3]": true,
"io.di[4]": false,
"io.di[5]": true,
"io.di[6]": false,
"io.di[7]": true,
"io.di[10]": true,
"io.ai[2]": 0.75
},
"events": [
{
"id": 1,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 1,
"raw": "io.di[1]"
},
"value": true,
"kind": "script"
},
{
"id": 2,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 2,
"raw": "io.di[2]"
},
"value": false,
"kind": "script"
},
{
"id": 3,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 3,
"raw": "io.di[3]"
},
"value": true,
"kind": "script"
},
{
"id": 4,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 4,
"raw": "io.di[4]"
},
"value": false,
"kind": "script"
},
{
"id": 5,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": false,
"kind": "script"
},
{
"id": 6,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": true,
"kind": "script"
},
{
"id": 7,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": false,
"kind": "script"
},
{
"id": 8,
"time": 0,
"writer": "script",
"target": {
"domain": "di",
"index": 10,
"raw": "io.di[10]"
},
"value": true,
"kind": "script"
},
{
"id": 9,
"time": 0,
"writer": "script",
"target": {
"domain": "ai",
"index": 2,
"raw": "io.ai[2]"
},
"value": 0.75,
"kind": "script"
},
{
"id": 10,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"previous": false,
"value": true,
"kind": "script"
},
{
"id": 11,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"previous": true,
"value": false,
"kind": "script"
},
{
"id": 12,
"time": 0.1,
"writer": "script",
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"previous": false,
"value": true,
"kind": "script"
}
],
"diagnostics": [],
"scripts": [
{
"name": "W2_90_ExceptionAlarm-edge-script",
"nextIndex": 3,
"elapsed": 0.1,
"steps": [
{
"delay": 0.02,
"target": {
"domain": "di",
"index": 5,
"raw": "io.di[5]"
},
"value": true
},
{
"delay": 0.04,
"target": {
"domain": "di",
"index": 6,
"raw": "io.di[6]"
},
"value": false
},
{
"delay": 0.06,
"target": {
"domain": "di",
"index": 7,
"raw": "io.di[7]"
},
"value": true
}
],
"done": true
}
]
}

View File

@@ -0,0 +1,82 @@
{
"items": [
{
"id": "mq_1",
"kind": "motion",
"source": {
"kind": "instruction",
"instruction": {
"kind": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.3
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 15,
"column": 7
}
},
"sourceMap": {
"line": 15,
"column": 7
}
},
"request": {
"startJoints": [
0,
0,
0,
0,
0,
0
],
"sampleTime": 0.02,
"segments": [
{
"id": "motion_1",
"motion": "MOVEJ",
"target": {
"joints": [
0,
0,
0,
0,
0,
0
],
"id": "home"
},
"speed": {
"kind": "joint_percent",
"value": 0.3
},
"zone": {
"kind": "fine"
},
"sourceMap": {
"line": 15,
"column": 7
}
}
]
},
"status": "queued"
}
],
"activeIndex": 0,
"virtualTime": 0.1
}

View File

@@ -0,0 +1,81 @@
{
"filenames": [
"W2ExceptionAlarm.mod",
"W2ExceptionAlarm.ls",
"W2ExceptionAlarm.src"
],
"report": [
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by abb prototype postprocessor",
"brand": "abb"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by fanuc prototype postprocessor",
"brand": "fanuc"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "ALARM is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "RAW_STATEMENT is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by kuka prototype postprocessor",
"brand": "kuka"
},
{
"code": "GRL_POST_UNSUPPORTED",
"severity": "warning",
"message": "UNSUPPORTED_RUNTIME is not supported by kuka prototype postprocessor",
"brand": "kuka"
}
]
}

View File

@@ -0,0 +1,201 @@
[
{
"time": 0,
"kind": "load",
"procedure": "main",
"pc": 0,
"message": "Loaded W2ExceptionAlarm",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"data": {
"moduleName": "W2ExceptionAlarm"
},
"id": 1
},
{
"time": 0,
"kind": "alarm",
"procedure": "main",
"pc": 0,
"message": "start",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"data": {
"alarmId": "START",
"severity": "info"
},
"id": 2
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 1,
"instructionKind": "ALARM",
"source": {
"kind": "ALARM",
"id": "main:ALARM:13:5",
"sourceMap": {
"line": 13,
"column": 5
},
"procedureId": "main"
},
"id": 3
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 1,
"message": "Execution exceeded 1 steps",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 1 steps"
},
"id": 4
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 2,
"instructionKind": "RAW_STATEMENT",
"source": {
"kind": "RAW_STATEMENT",
"id": "main:RAW_STATEMENT:14:5",
"sourceMap": {
"line": 14,
"column": 5
},
"procedureId": "main"
},
"id": 5
},
{
"time": 0,
"kind": "motion",
"procedure": "main",
"pc": 2,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:15:7",
"sourceMap": {
"line": 15,
"column": 7
},
"procedureId": "main"
},
"data": {
"queued": true
},
"id": 6
},
{
"time": 0,
"kind": "instruction",
"procedure": "main",
"pc": 3,
"instructionKind": "MOVEJ",
"source": {
"kind": "MOVEJ",
"id": "main:MOVEJ:15:7",
"sourceMap": {
"line": 15,
"column": 7
},
"procedureId": "main"
},
"id": 7
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 4,
"instructionKind": "UNSUPPORTED_RUNTIME",
"source": {
"kind": "UNSUPPORTED_RUNTIME",
"id": "main:UNSUPPORTED_RUNTIME:22:5",
"sourceMap": {
"line": 22,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "warning",
"code": "VC_UNSUPPORTED_RUNTIME",
"message": "enable interrupt is parsed but not executable in P0",
"sourceMap": {
"line": 22,
"column": 5
}
},
"id": 8
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"instructionKind": "UNSUPPORTED_RUNTIME",
"source": {
"kind": "UNSUPPORTED_RUNTIME",
"id": "main:UNSUPPORTED_RUNTIME:23:5",
"sourceMap": {
"line": 23,
"column": 5
},
"procedureId": "main"
},
"diagnostic": {
"severity": "warning",
"code": "VC_UNSUPPORTED_RUNTIME",
"message": "disable interrupt is parsed but not executable in P0",
"sourceMap": {
"line": 23,
"column": 5
}
},
"id": 9
},
{
"time": 0,
"kind": "diagnostic",
"procedure": "main",
"pc": 5,
"message": "Execution exceeded 3 steps",
"diagnostic": {
"severity": "error",
"code": "VC_STEP_LIMIT_EXCEEDED",
"message": "Execution exceeded 3 steps"
},
"id": 10
}
]

View File

@@ -0,0 +1,21 @@
{
"sampleCount": 4,
"duration": 0.24,
"startJoints": [
0,
0,
0,
0,
0,
0
],
"endJoints": [
0,
0,
0,
0,
0,
0
],
"diagnostics": []
}

View File

@@ -0,0 +1,11 @@
{
"parsed": false,
"semanticChecks": [],
"sourceMapEntries": 0,
"kdlMotionRequests": 0,
"kdlPathRequests": 0,
"symbolCount": 0,
"procedureCount": 0,
"pathCount": 0,
"operationCount": 0
}

Some files were not shown because too many files have changed in this diff Show More