(function () { const root = document.querySelector(".workbench"); const fields = new Map( Array.from(document.querySelectorAll("[data-field]")).map((item) => [item.dataset.field, item]) ); const tabButtons = Array.from(document.querySelectorAll("[data-tab]")); const sources = { grl: "proc main()\n run_path pick_place\nend", abb: "MODULE A120Smoke\n PROC main()\n MoveJ home,v100,fine,tool0;\n ENDPROC\nENDMODULE", fanuc: "/PROG A120SMOKE\n/MN\n 1:J P[1] 40% FINE ;\n/END", kuka: "DEF A120SMOKE()\n PTP HOME\nEND" }; const state = { command: "ready", mode: "auto", motors: "on", pc: 0, joints: [0, 0, 0, 0, 0, 0], tcp: [0, 0, 580, 0, 0, 0], di1: false, do1: false, wait: "none", queue: [], trace: ["ready"], diagnostics: ["ready"], report: "A120-REPORT", tab: "grl" }; function formatArray(values) { return `[${values.map((value) => Number(value).toFixed(value % 1 === 0 ? 0 : 2)).join(", ")}]`; } function setField(name, value) { const item = fields.get(name); if (item) item.textContent = value; } function render() { root?.setAttribute("data-last-command", state.command); root?.setAttribute("data-running", String(state.command === "running")); setField("state", state.command); setField("mode", state.mode); setField("motors", state.motors); setField("pc", `main:${state.pc}`); setField("joints", formatArray(state.joints)); setField("tcp", formatArray(state.tcp)); setField("log", state.trace.at(-1) ?? "ready"); setField("diagnostics", state.diagnostics.at(-1) ?? "ready"); setField("io", `do[1]=${state.do1}, di[1]=${state.di1}`); setField("wait", state.wait); setField("queue", state.queue.length ? state.queue.join(" -> ") : "empty"); setField("trace", `${state.trace.length} events`); setField("reports", state.report); setField("editor", sources[state.tab]); for (const button of tabButtons) { button.setAttribute("aria-pressed", String(button.dataset.tab === state.tab)); } } function pushTrace(message) { state.trace.push(message); state.diagnostics.push(message); } function advanceProgram(stepSize) { state.pc = Math.min(state.pc + stepSize, 4); state.joints = state.joints.map((value, index) => Number((value + (index + 1) * 1.5 * stepSize).toFixed(2))); state.tcp = [ Number((state.tcp[0] + 12 * stepSize).toFixed(2)), Number((state.tcp[1] + 4 * stepSize).toFixed(2)), state.tcp[2], state.tcp[3], state.tcp[4], state.tcp[5] ]; } function handleCommand(command) { state.command = command === "run" ? "running" : command; if (command === "load") { state.pc = 0; state.queue = ["movej home", "run_path pick_place"]; state.wait = "none"; pushTrace("program loaded"); } else if (command === "run") { advanceProgram(2); state.do1 = true; state.wait = state.di1 ? "satisfied" : "waiting di[1]"; state.queue = state.di1 ? ["movel place"] : ["wait di[1]", "movel place"]; pushTrace(state.di1 ? "running path" : "waiting for di[1]"); } else if (command === "pause") { pushTrace("program paused"); } else if (command === "step") { state.command = "paused"; advanceProgram(1); pushTrace(`stepped to main:${state.pc}`); } else if (command === "stop") { state.queue = []; pushTrace("program stopped"); } else if (command === "reset") { state.command = "ready"; state.pc = 0; state.joints = [0, 0, 0, 0, 0, 0]; state.tcp = [0, 0, 580, 0, 0, 0]; state.do1 = false; state.wait = "none"; state.queue = []; pushTrace("controller reset"); } else if (command === "export") { state.report = "A120-REPORT exported"; pushTrace("delivery package exported"); } render(); } for (const button of document.querySelectorAll("[data-command]")) { button.addEventListener("click", () => handleCommand(button.dataset.command ?? "ready")); } for (const button of tabButtons) { button.addEventListener("click", () => { state.tab = button.dataset.tab ?? "grl"; pushTrace(`${state.tab.toUpperCase()} source selected`); render(); }); } document.querySelector("[data-io='di1']")?.addEventListener("click", () => { state.di1 = !state.di1; state.wait = state.di1 ? "satisfied" : "waiting di[1]"; pushTrace(`di[1]=${state.di1}`); render(); }); render(); })();