同步五轴仿真文档和验证证据
493
qa/web-rtcp-5axis-site-test/capture-button-control-evidence.mjs
Normal file
@@ -0,0 +1,493 @@
|
||||
import fs from "node:fs/promises";
|
||||
import http from "node:http";
|
||||
import path from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import puppeteer from "puppeteer-core";
|
||||
import { PNG } from "pngjs";
|
||||
|
||||
const REPO_ROOT = path.resolve("/home/meswork/cnc_wams");
|
||||
const QA_ROOT = path.join(REPO_ROOT, "qa/web-rtcp-5axis-site-test");
|
||||
const OUTPUT_DIR = path.join(QA_ROOT, "output");
|
||||
const CHROME_PATH = process.env.CHROME_PATH || process.env.CHROMIUM || "/usr/bin/google-chrome";
|
||||
const TARGET_URL = process.env.TARGET_URL || "";
|
||||
const APP_URL = process.env.APP_URL || "/web-rtcp-5axis-sim-plan/app/index.html";
|
||||
const EVIDENCE_SCOPE = process.env.EVIDENCE_SCOPE || (TARGET_URL ? "cloud-button-control-evidence" : "button-control-evidence");
|
||||
const SCREENSHOT_DIR = path.join(QA_ROOT, "screenshots", EVIDENCE_SCOPE);
|
||||
const REPORT_BASENAME = `${EVIDENCE_SCOPE}-report`;
|
||||
const JOB_ID = process.env.JOB_ID || `btn-${new Date().toISOString().replace(/[-:.TZ]/g, "").slice(0, 14)}-${randomUUID().slice(0, 8)}`;
|
||||
const REPORT_ID = process.env.REPORT_ID || `report-${JOB_ID}`;
|
||||
|
||||
await fs.mkdir(OUTPUT_DIR, { recursive: true });
|
||||
await fs.mkdir(SCREENSHOT_DIR, { recursive: true });
|
||||
|
||||
let server = null;
|
||||
let targetUrl = TARGET_URL;
|
||||
if (!targetUrl) {
|
||||
server = createStaticServer(REPO_ROOT);
|
||||
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") throw new Error("failed to start static server");
|
||||
targetUrl = `http://127.0.0.1:${address.port}${APP_URL}`;
|
||||
}
|
||||
|
||||
const browser = await puppeteer.launch({
|
||||
headless: true,
|
||||
executablePath: CHROME_PATH,
|
||||
defaultViewport: { width: 1500, height: 1050, deviceScaleFactor: 1 },
|
||||
ignoreHTTPSErrors: true,
|
||||
args: [
|
||||
"--ignore-certificate-errors",
|
||||
"--disable-gpu",
|
||||
"--enable-webgl",
|
||||
"--use-angle=swiftshader",
|
||||
"--enable-unsafe-swiftshader",
|
||||
"--no-sandbox",
|
||||
],
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
const consoleErrors = [];
|
||||
const pageErrors = [];
|
||||
page.on("console", (msg) => {
|
||||
if (msg.type() === "error") consoleErrors.push(msg.text());
|
||||
});
|
||||
page.on("pageerror", (error) => pageErrors.push(error.message));
|
||||
|
||||
const report = {
|
||||
jobId: JOB_ID,
|
||||
reportId: REPORT_ID,
|
||||
evidenceScope: EVIDENCE_SCOPE,
|
||||
generatedAt: new Date().toISOString(),
|
||||
targetUrl,
|
||||
chromePath: CHROME_PATH,
|
||||
screenshotsDir: SCREENSHOT_DIR,
|
||||
steps: [],
|
||||
checks: [],
|
||||
consoleErrors,
|
||||
pageErrors,
|
||||
};
|
||||
|
||||
try {
|
||||
await page.goto(report.targetUrl, { waitUntil: "networkidle2", timeout: 60000 });
|
||||
await page.waitForSelector('[data-shell="gmoccapy-5axis"]', { timeout: 15000 });
|
||||
await page.waitForFunction(() => Boolean(window.webRtcp5AxisSimulation?.getState), { timeout: 15000 });
|
||||
await page.waitForFunction(() => {
|
||||
const canvas = document.querySelector("[data-five-axis-canvas]");
|
||||
return canvas?.dataset?.threeReady === "true";
|
||||
}, { timeout: 20000 });
|
||||
await windowReady();
|
||||
await captureStep("01-initial", "Initial UI", "Browser app loaded before machine preparation.");
|
||||
|
||||
await loadOperatorProgram();
|
||||
await captureStep("02-program-loaded", "Program loaded", "Short operator G-code loaded through LinuxCNC interpreter WASM.");
|
||||
|
||||
await click("power");
|
||||
await waitForState((state) => state.machine.powerOn === true, 10000, "power on");
|
||||
await click("mode-manual");
|
||||
await waitForState((state) => state.machine.mode === "manual", 10000, "manual mode");
|
||||
await captureStep("03-before-home", "Before HOME", "Machine powered on in manual mode before HOME.");
|
||||
|
||||
await click("HOME");
|
||||
await waitForState((state) => state.machine.allHomed === true && state.machine.mode === "manual", 10000, "HOME complete");
|
||||
await captureStep("04-after-home", "After HOME", "HOME command preserves allHomed state in Web/task gate.");
|
||||
|
||||
await click("mode-auto");
|
||||
await waitForState((state) => state.machine.mode === "auto", 10000, "auto mode");
|
||||
await captureStep("05-ready-for-run", "Ready for RUN", "POWER, HOME, AUTO, and loaded G-code are ready before RUN.");
|
||||
|
||||
await click("RUN");
|
||||
await waitForState((state) => (
|
||||
state.runState === "running" &&
|
||||
state.programRuntimeFeedback?.sourceMode === "linuxcnc-task-motion-hal-wasm"
|
||||
), 15000, "RUN active");
|
||||
await wait(250);
|
||||
await captureStep("06-after-run", "After RUN", "RUN starts task/HAL backed program execution.");
|
||||
|
||||
await captureStep("07-before-pause", "Before PAUSE", "Program is running before PAUSE.");
|
||||
await click("PAUSE");
|
||||
await waitForState((state) => state.runState === "paused" && state.machine.taskPaused === true, 10000, "PAUSE active");
|
||||
await captureStep("08-after-pause", "After PAUSE", "PAUSE sets runState paused and taskPaused true.");
|
||||
|
||||
await captureStep("09-before-resume", "Before RESUME", "Program is paused before RESUME.");
|
||||
await click("RESUME");
|
||||
await waitForState((state) => state.runState === "running" && state.machine.interpState === "reading", 10000, "RESUME active");
|
||||
await wait(150);
|
||||
await captureStep("10-after-resume", "After RESUME", "RESUME returns task/HAL execution to running/reading.");
|
||||
|
||||
await click("PAUSE");
|
||||
await waitForState((state) => state.runState === "paused" && state.machine.taskPaused === true, 10000, "PAUSE before STEP");
|
||||
await captureStep("11-before-step", "Before STEP", "Program is paused before STEP.");
|
||||
|
||||
await click("STEP");
|
||||
await waitForState((state) => (
|
||||
state.machine.interpState === "paused" &&
|
||||
state.machine.taskPaused === true &&
|
||||
state.taskHalStatus?.task?.singleStepping === true
|
||||
), 10000, "STEP active");
|
||||
await captureStep("12-after-step", "After STEP", "STEP sends EMC_TASK_PLAN_STEP and leaves task paused with singleStepping true.");
|
||||
|
||||
await captureStep("13-before-stop", "Before STOP", "Paused single-step state before STOP.");
|
||||
await click("STOP");
|
||||
await waitForState((state) => (
|
||||
state.runState === "stopped" &&
|
||||
state.machine.interpState === "idle" &&
|
||||
state.taskHalStatus?.motionStatus?.motion?.aborted === true
|
||||
), 10000, "STOP active");
|
||||
await captureStep("14-after-stop", "After STOP", "STOP aborts task/HAL motion and returns interpreter state to idle.");
|
||||
|
||||
addChecks();
|
||||
report.status = report.checks.every((check) => check.pass) && pageErrors.length === 0 ? "PASS" : "FAIL";
|
||||
|
||||
const jsonPath = path.join(OUTPUT_DIR, `${REPORT_BASENAME}.json`);
|
||||
report.jsonPath = jsonPath;
|
||||
const pdfPath = path.join(OUTPUT_DIR, `${REPORT_BASENAME}.pdf`);
|
||||
report.pdfPath = pdfPath;
|
||||
await fs.writeFile(jsonPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
||||
await writePdfReport(pdfPath, report);
|
||||
console.log(`button_control_evidence_status=${report.status}`);
|
||||
console.log(`button_control_evidence_job_id=${report.jobId}`);
|
||||
console.log(`button_control_evidence_report_id=${report.reportId}`);
|
||||
console.log(`button_control_evidence_json=${jsonPath}`);
|
||||
console.log(`button_control_evidence_pdf=${pdfPath}`);
|
||||
console.log(`button_control_evidence_screenshots=${SCREENSHOT_DIR}`);
|
||||
if (report.status !== "PASS") process.exitCode = 1;
|
||||
} finally {
|
||||
await page.close().catch(() => {});
|
||||
await browser.close().catch(() => {});
|
||||
if (server) await new Promise((resolve) => server.close(resolve));
|
||||
}
|
||||
|
||||
async function windowReady() {
|
||||
await waitForState((state) => (
|
||||
state.kinematicsRuntimeReadiness?.loaded === true &&
|
||||
state.interpreterRuntimeReadiness?.loaded === true &&
|
||||
state.taskHalRuntimeReadiness?.loaded === true
|
||||
), 30000, "runtime readiness");
|
||||
await waitForState((state) => (
|
||||
!state.interpreterExecutionPending &&
|
||||
state.machineFileStaging?.status === "staged"
|
||||
), 30000, "machine file seed ready")
|
||||
.catch(() => null);
|
||||
}
|
||||
|
||||
async function loadOperatorProgram() {
|
||||
await page.evaluate(() => {
|
||||
window.webRtcp5AxisSimulation.dispatch({
|
||||
type: "LOAD_PROGRAM",
|
||||
filename: "button-control-evidence.ngc",
|
||||
content: [
|
||||
"G90 G17",
|
||||
"G0 X0 Y0 Z0 A0 C0",
|
||||
"G1 X10 F120",
|
||||
"G1 Y10",
|
||||
"G1 X20 Y20",
|
||||
"G1 X0 Y0",
|
||||
"G0 Z5",
|
||||
"M2",
|
||||
].join("\n"),
|
||||
});
|
||||
});
|
||||
await waitForState((state) => (
|
||||
state.activeProgram === "button-control-evidence.ngc" &&
|
||||
state.programExecutionSourceMode === "linuxcnc-interpreter-wasm" &&
|
||||
state.programExecution?.summary?.motionEventCount >= 4
|
||||
), 10000, "operator program loaded");
|
||||
}
|
||||
|
||||
async function click(action) {
|
||||
await page.evaluate((selector) => {
|
||||
const button = document.querySelector(selector);
|
||||
if (!button) throw new Error(`missing button ${selector}`);
|
||||
button.click();
|
||||
}, `[data-action="${action}"]`);
|
||||
}
|
||||
|
||||
async function captureStep(name, title, description) {
|
||||
const screenshotPath = path.join(SCREENSHOT_DIR, `${name}.png`);
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
const [state, buttons, canvasDataset, pixelStats] = await Promise.all([
|
||||
getState(),
|
||||
getButtonStates(),
|
||||
getCanvasDataset(),
|
||||
analyzePng(screenshotPath),
|
||||
]);
|
||||
const step = {
|
||||
name,
|
||||
title,
|
||||
description,
|
||||
screenshotPath,
|
||||
pixelStats,
|
||||
buttons,
|
||||
canvasDataset,
|
||||
state: summarizeState(state),
|
||||
};
|
||||
report.steps.push(step);
|
||||
return step;
|
||||
}
|
||||
|
||||
async function writePdfReport(pdfPath, data) {
|
||||
const reportPage = await browser.newPage();
|
||||
const rows = data.checks.map((item) => `
|
||||
<tr>
|
||||
<td>${escapeHtml(item.name)}</td>
|
||||
<td class="${item.pass ? "pass" : "fail"}">${item.pass ? "PASS" : "FAIL"}</td>
|
||||
<td>${escapeHtml(item.detail)}</td>
|
||||
</tr>
|
||||
`).join("");
|
||||
const steps = data.steps.map((step) => `
|
||||
<section>
|
||||
<h2>${escapeHtml(step.name)} - ${escapeHtml(step.title)}</h2>
|
||||
<p>${escapeHtml(step.description)}</p>
|
||||
<p><strong>Screenshot:</strong> ${escapeHtml(step.screenshotPath)}</p>
|
||||
<p><strong>State:</strong> ${escapeHtml(JSON.stringify({
|
||||
runState: step.state.runState,
|
||||
machine: step.state.machine,
|
||||
task: step.state.taskHalStatus?.task,
|
||||
motion: step.state.taskHalStatus?.motionStatus?.motion,
|
||||
}))}</p>
|
||||
</section>
|
||||
`).join("");
|
||||
await reportPage.setContent(`<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 28px; color: #17202a; }
|
||||
h1 { font-size: 22px; margin-bottom: 6px; }
|
||||
h2 { font-size: 16px; margin-top: 18px; }
|
||||
table { border-collapse: collapse; width: 100%; margin-top: 14px; }
|
||||
th, td { border: 1px solid #9aa5b1; padding: 6px; font-size: 11px; vertical-align: top; }
|
||||
th { background: #eef2f7; }
|
||||
.pass { color: #126b37; font-weight: 700; }
|
||||
.fail { color: #a61b1b; font-weight: 700; }
|
||||
.meta { font-size: 12px; line-height: 1.45; }
|
||||
section { break-inside: avoid; border-top: 1px solid #d8dee6; padding-top: 8px; }
|
||||
code { font-family: Consolas, monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Web RTCP 5 Axis Button Control Evidence</h1>
|
||||
<div class="meta">
|
||||
<div><strong>Status:</strong> ${escapeHtml(data.status)}</div>
|
||||
<div><strong>Job ID:</strong> ${escapeHtml(data.jobId)}</div>
|
||||
<div><strong>Report ID:</strong> ${escapeHtml(data.reportId)}</div>
|
||||
<div><strong>Target:</strong> ${escapeHtml(data.targetUrl)}</div>
|
||||
<div><strong>Generated:</strong> ${escapeHtml(data.generatedAt)}</div>
|
||||
<div><strong>Screenshots:</strong> ${escapeHtml(data.screenshotsDir)}</div>
|
||||
</div>
|
||||
<h2>Checks</h2>
|
||||
<table>
|
||||
<thead><tr><th>Check</th><th>Status</th><th>Evidence</th></tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
<h2>Steps</h2>
|
||||
${steps}
|
||||
</body>
|
||||
</html>`, { waitUntil: "load" });
|
||||
await reportPage.pdf({
|
||||
path: pdfPath,
|
||||
format: "A4",
|
||||
printBackground: true,
|
||||
margin: { top: "12mm", right: "10mm", bottom: "12mm", left: "10mm" },
|
||||
});
|
||||
await reportPage.close();
|
||||
}
|
||||
|
||||
async function getState() {
|
||||
return page.evaluate(() => JSON.parse(JSON.stringify(window.webRtcp5AxisSimulation.getState())));
|
||||
}
|
||||
|
||||
async function getButtonStates() {
|
||||
return page.evaluate(() => {
|
||||
const actions = ["RUN", "STOP", "PAUSE", "RESUME", "STEP", "HOME"];
|
||||
return Object.fromEntries(actions.map((action) => {
|
||||
const button = document.querySelector(`[data-action="${action}"]`);
|
||||
return [action, {
|
||||
exists: Boolean(button),
|
||||
disabled: Boolean(button?.disabled),
|
||||
commandReady: button?.dataset?.commandReady || null,
|
||||
ariaDisabled: button?.getAttribute("aria-disabled"),
|
||||
title: button?.getAttribute("title") || "",
|
||||
}];
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
async function getCanvasDataset() {
|
||||
return page.$eval("[data-five-axis-canvas]", (canvas) => ({ ...canvas.dataset }));
|
||||
}
|
||||
|
||||
async function waitForState(predicate, timeoutMs, label) {
|
||||
const started = Date.now();
|
||||
let lastState = null;
|
||||
while (Date.now() - started < timeoutMs) {
|
||||
lastState = await getState();
|
||||
if (predicate(lastState)) return lastState;
|
||||
await wait(50);
|
||||
}
|
||||
throw new Error(`timeout waiting for ${label}: ${JSON.stringify(summarizeState(lastState || {}))}`);
|
||||
}
|
||||
|
||||
function addChecks() {
|
||||
const byName = Object.fromEntries(report.steps.map((step) => [step.name, step]));
|
||||
const afterHome = byName["04-after-home"]?.state;
|
||||
const afterRun = byName["06-after-run"]?.state;
|
||||
const afterPause = byName["08-after-pause"]?.state;
|
||||
const afterResume = byName["10-after-resume"]?.state;
|
||||
const afterStep = byName["12-after-step"]?.state;
|
||||
const afterStop = byName["14-after-stop"]?.state;
|
||||
report.checks.push(
|
||||
check("HOME keeps all axes homed", afterHome?.machine?.allHomed === true, JSON.stringify(afterHome?.machine)),
|
||||
check("RUN uses task/HAL runtime feedback", afterRun?.runState === "running" && afterRun?.programRuntimeFeedback?.sourceMode === "linuxcnc-task-motion-hal-wasm", JSON.stringify(afterRun?.programRuntimeFeedback)),
|
||||
check("PAUSE sets paused state", afterPause?.runState === "paused" && afterPause?.machine?.taskPaused === true, JSON.stringify(afterPause?.machine)),
|
||||
check("RESUME returns to reading", afterResume?.runState === "running" && afterResume?.machine?.interpState === "reading", JSON.stringify(afterResume?.machine)),
|
||||
check("STEP records single stepping", afterStep?.machine?.taskPaused === true && afterStep?.taskHalStatus?.task?.singleStepping === true, JSON.stringify(afterStep?.taskHalStatus?.task)),
|
||||
check("STOP aborts motion", afterStop?.runState === "stopped" && afterStop?.taskHalStatus?.motionStatus?.motion?.aborted === true, JSON.stringify(afterStop?.taskHalStatus?.motionStatus?.motion)),
|
||||
check("Screenshots are nonblank", report.steps.every((step) => step.pixelStats.nonBlackRatio > 0.1), report.steps.map((step) => `${step.name}:${step.pixelStats.nonBlackRatio}`).join(", ")),
|
||||
check("Control buttons expose readiness attributes", report.steps.every((step) => Object.values(step.buttons).every((button) => button.exists && button.commandReady !== null)), "RUN/STOP/PAUSE/RESUME/STEP/HOME"),
|
||||
);
|
||||
}
|
||||
|
||||
function summarizeState(state = {}) {
|
||||
return {
|
||||
activeProgram: state.activeProgram,
|
||||
runState: state.runState,
|
||||
activeLine: state.activeLine,
|
||||
machine: {
|
||||
powerOn: state.machine?.powerOn,
|
||||
taskState: state.machine?.taskState,
|
||||
mode: state.machine?.mode,
|
||||
allHomed: state.machine?.allHomed,
|
||||
interpState: state.machine?.interpState,
|
||||
taskPaused: state.machine?.taskPaused,
|
||||
},
|
||||
axisPose: pickAxes(state.axisPose),
|
||||
dro: pickAxes(state.dro),
|
||||
programRuntimeFeedback: state.programRuntimeFeedback ? {
|
||||
sourceMode: state.programRuntimeFeedback.sourceMode,
|
||||
line: state.programRuntimeFeedback.line,
|
||||
taskCycle: state.programRuntimeFeedback.taskCycle,
|
||||
currentVelocityMmPerMin: state.programRuntimeFeedback.currentVelocityMmPerMin,
|
||||
axisPose: pickAxes(state.programRuntimeFeedback.axisPose),
|
||||
} : null,
|
||||
taskHalStatus: state.taskHalStatus ? {
|
||||
task: {
|
||||
mode: state.taskHalStatus.task?.mode,
|
||||
interpState: state.taskHalStatus.task?.interpState,
|
||||
taskPaused: state.taskHalStatus.task?.taskPaused,
|
||||
singleStepping: state.taskHalStatus.task?.singleStepping,
|
||||
},
|
||||
ui: {
|
||||
activeLine: state.taskHalStatus.ui?.activeLine,
|
||||
taskCycle: state.taskHalStatus.ui?.taskCycle,
|
||||
servoCycle: state.taskHalStatus.ui?.servoCycle,
|
||||
},
|
||||
motionStatus: {
|
||||
motion: {
|
||||
enabled: state.taskHalStatus.motionStatus?.motion?.enabled,
|
||||
paused: state.taskHalStatus.motionStatus?.motion?.paused,
|
||||
aborted: state.taskHalStatus.motionStatus?.motion?.aborted,
|
||||
queueDepth: state.taskHalStatus.motionStatus?.motion?.queueDepth,
|
||||
},
|
||||
},
|
||||
} : null,
|
||||
taskHalStatusLoop: state.taskHalStatusLoop,
|
||||
operatorMessage: state.operatorMessage,
|
||||
};
|
||||
}
|
||||
|
||||
function createStaticServer(rootDir) {
|
||||
return http.createServer(async (request, response) => {
|
||||
try {
|
||||
const requestPath = decodeURIComponent(new URL(request.url || "/", "http://127.0.0.1").pathname);
|
||||
const relativePath = requestPath === "/" ? "/index.html" : requestPath;
|
||||
const targetPath = path.resolve(rootDir, `.${relativePath}`);
|
||||
if (!targetPath.startsWith(rootDir)) {
|
||||
response.writeHead(403);
|
||||
response.end("forbidden");
|
||||
return;
|
||||
}
|
||||
let filePath = targetPath;
|
||||
let stat = await fs.stat(filePath).catch(() => null);
|
||||
if (stat?.isDirectory()) {
|
||||
filePath = path.join(filePath, "index.html");
|
||||
stat = await fs.stat(filePath).catch(() => null);
|
||||
}
|
||||
if (!stat?.isFile()) {
|
||||
response.writeHead(404);
|
||||
response.end("not found");
|
||||
return;
|
||||
}
|
||||
const body = await fs.readFile(filePath);
|
||||
response.writeHead(200, {
|
||||
"Content-Type": contentTypeFor(filePath),
|
||||
"Content-Length": String(body.byteLength),
|
||||
"Cache-Control": "no-store",
|
||||
});
|
||||
response.end(body);
|
||||
} catch (error) {
|
||||
response.writeHead(500);
|
||||
response.end(error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function contentTypeFor(filePath) {
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
return {
|
||||
".css": "text/css; charset=utf-8",
|
||||
".html": "text/html; charset=utf-8",
|
||||
".js": "text/javascript; charset=utf-8",
|
||||
".json": "application/json; charset=utf-8",
|
||||
".mjs": "text/javascript; charset=utf-8",
|
||||
".svg": "image/svg+xml",
|
||||
".wasm": "application/wasm",
|
||||
".xml": "application/xml; charset=utf-8",
|
||||
}[ext] || "application/octet-stream";
|
||||
}
|
||||
|
||||
async function analyzePng(filePath) {
|
||||
const png = PNG.sync.read(await fs.readFile(filePath));
|
||||
let luminanceSum = 0;
|
||||
let nonBlack = 0;
|
||||
for (let index = 0; index < png.data.length; index += 4) {
|
||||
const luminance = png.data[index] * 0.2126 + png.data[index + 1] * 0.7152 + png.data[index + 2] * 0.0722;
|
||||
luminanceSum += luminance;
|
||||
if (luminance > 8) nonBlack += 1;
|
||||
}
|
||||
const total = png.width * png.height;
|
||||
return {
|
||||
width: png.width,
|
||||
height: png.height,
|
||||
averageLuminance: Number((luminanceSum / total).toFixed(2)),
|
||||
nonBlackRatio: Number((nonBlack / total).toFixed(4)),
|
||||
};
|
||||
}
|
||||
|
||||
function pickAxes(value = {}) {
|
||||
return {
|
||||
x: Number(value?.x || 0),
|
||||
y: Number(value?.y || 0),
|
||||
z: Number(value?.z || 0),
|
||||
a: Number(value?.a || 0),
|
||||
b: Number(value?.b || 0),
|
||||
c: Number(value?.c || 0),
|
||||
};
|
||||
}
|
||||
|
||||
function check(name, pass, detail) {
|
||||
return { name, pass: Boolean(pass), detail: String(detail ?? "-") };
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function wait(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { spawnSync } from "node:child_process";
|
||||
|
||||
const REPO_ROOT = "/home/meswork/cnc_wams";
|
||||
const OUTPUT_DIR = path.join(REPO_ROOT, "qa/web-rtcp-5axis-site-test/output");
|
||||
const REPORT_JSON = path.join(OUTPUT_DIR, "native-task-hal-comparison-report.json");
|
||||
const REPORT_MD = path.join(OUTPUT_DIR, "native-task-hal-comparison-report.md");
|
||||
const READINESS_JSON = path.join(REPO_ROOT, "web-rtcp-5axis-sim-plan/build/readiness/native-task-hal-readiness.json");
|
||||
|
||||
await fs.mkdir(OUTPUT_DIR, { recursive: true });
|
||||
|
||||
const phase0 = run("bash", ["wasm-port/tests/native/verify_task_hal_phase0.sh"]);
|
||||
const audit = run("node", ["web-rtcp-5axis-sim-plan/tests/node/verify_native_task_hal_audit.mjs"]);
|
||||
const optInProbe = run("bash", ["wasm-port/tests/native/probe_trt_task_hal_runtime.sh"], {
|
||||
env: { ...process.env, ENABLE_TRT_TASK_HAL_RUNTIME_PROBE: "1" },
|
||||
});
|
||||
const fixtureBaseline = run("bash", ["wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh"], {
|
||||
env: { ...process.env, LD_LIBRARY_PATH: path.join(REPO_ROOT, "linuxcnc/lib") },
|
||||
});
|
||||
|
||||
const ldd = {
|
||||
halcmd: run("ldd", ["linuxcnc/bin/halcmd"]),
|
||||
rs274: run("ldd", ["linuxcnc/bin/rs274"]),
|
||||
linuxcncsvr: run("ldd", ["linuxcnc/bin/linuxcncsvr"]),
|
||||
};
|
||||
|
||||
const readiness = await readJson(READINESS_JSON);
|
||||
const sourceManifest = parseKv(await readText("wasm-port/build/task-hal/verify_task_hal_source_manifest.stdout.log"));
|
||||
const defaultProbe = parseKv(await readText("wasm-port/build/task-hal/probe_trt_task_hal_runtime.stdout.log"));
|
||||
const optInProbeFields = parseKv(optInProbe.stdout);
|
||||
const nativeStderr = await readText("wasm-port/build/native/trt-task-hal-runtime/linuxcnc.stderr.log");
|
||||
|
||||
const hostBlockers = [
|
||||
...missingFromLdd(ldd.halcmd.combined, "halcmd"),
|
||||
...missingFromLdd(ldd.rs274.combined, "rs274"),
|
||||
...missingFromLdd(ldd.linuxcncsvr.combined, "linuxcncsvr"),
|
||||
];
|
||||
if (nativeStderr.includes("/home/cnc/桌面/cnc_wams/linuxcnc/scripts/rip-environment")) {
|
||||
hostBlockers.push({
|
||||
component: "linuxcnc scripts/linuxcnc",
|
||||
blocker: "hardcoded_rip_environment_path_missing",
|
||||
detail: firstLine(nativeStderr),
|
||||
});
|
||||
}
|
||||
|
||||
const checks = [
|
||||
check("phase0 native source/probe gate passes", phase0.status === 0, oneLine(phase0.combined)),
|
||||
check("native readiness audit passes", audit.status === 0, oneLine(audit.combined)),
|
||||
check("source manifest ready", sourceManifest.task_hal_source_manifest_ready === "1", JSON.stringify(sourceManifest)),
|
||||
check("TRT source proof ready", defaultProbe.trt_task_hal_source_proof_ready === "1", JSON.stringify(defaultProbe)),
|
||||
check("host-native runtime blocker captured", optInProbe.status !== 0 && hostBlockers.length > 0, JSON.stringify(hostBlockers)),
|
||||
check("web simulation promotion remains bounded", readiness?.promotionScope === "web_simulation_only", JSON.stringify(readiness?.gates || {})),
|
||||
];
|
||||
|
||||
const report = {
|
||||
apiName: "web-rtcp-5axis-native-task-hal-comparison-report",
|
||||
generatedAt: new Date().toISOString(),
|
||||
status: checks.every((item) => item.pass) ? "PASS_WITH_HOST_NATIVE_RUNTIME_BLOCKER" : "FAIL",
|
||||
scope: "LinuxCNC source/phase0 task-HAL comparison plus attempted host-native TRT runtime probe",
|
||||
commands: {
|
||||
phase0: commandRecord("bash wasm-port/tests/native/verify_task_hal_phase0.sh", phase0),
|
||||
nativeAudit: commandRecord("node web-rtcp-5axis-sim-plan/tests/node/verify_native_task_hal_audit.mjs", audit),
|
||||
optInNativeProbe: commandRecord("ENABLE_TRT_TASK_HAL_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_trt_task_hal_runtime.sh", optInProbe),
|
||||
fixtureBaseline: commandRecord("LD_LIBRARY_PATH=linuxcnc/lib bash wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh", fixtureBaseline),
|
||||
},
|
||||
readiness,
|
||||
sourceManifest,
|
||||
defaultProbe,
|
||||
optInProbeFields,
|
||||
hostBlockers,
|
||||
ldd: Object.fromEntries(Object.entries(ldd).map(([key, value]) => [key, commandRecord(`ldd linuxcnc/bin/${key}`, value)])),
|
||||
checks,
|
||||
conclusion: {
|
||||
nativeTaskHalSourceComparisonReady: true,
|
||||
nativeTransitionLogAvailable: false,
|
||||
nativeTransitionLogBlockedByHostRuntime: true,
|
||||
reason: "Current host cannot start the LinuxCNC native TRT task/HAL runtime: generated LinuxCNC RIP scripts reference an old absolute path and binaries require unavailable host runtime libraries such as GLIBC_2.38/libpython3.13.",
|
||||
boundary: "This completes BTN-013 as an auditable native comparison and blocker record; it does not claim hardware drive, realtime kernel, external user-M process, or tool DB native runtime readiness.",
|
||||
},
|
||||
};
|
||||
|
||||
await fs.writeFile(REPORT_JSON, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
||||
await fs.writeFile(REPORT_MD, renderMarkdown(report), "utf8");
|
||||
|
||||
console.log(`native_task_hal_comparison_status=${report.status}`);
|
||||
console.log(`native_task_hal_comparison_json=${REPORT_JSON}`);
|
||||
console.log(`native_task_hal_comparison_markdown=${REPORT_MD}`);
|
||||
console.log(`native_task_hal_transition_log_available=${report.conclusion.nativeTransitionLogAvailable ? 1 : 0}`);
|
||||
console.log(`native_task_hal_host_blocker_count=${hostBlockers.length}`);
|
||||
|
||||
if (report.status === "FAIL") process.exitCode = 1;
|
||||
|
||||
function run(command, args, options = {}) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: REPO_ROOT,
|
||||
encoding: "utf8",
|
||||
timeout: 30000,
|
||||
...options,
|
||||
});
|
||||
const stdout = result.stdout || "";
|
||||
const stderr = result.stderr || "";
|
||||
return {
|
||||
status: result.status ?? 1,
|
||||
signal: result.signal || null,
|
||||
stdout,
|
||||
stderr,
|
||||
combined: `${stdout}${stderr ? `\n${stderr}` : ""}`.trim(),
|
||||
};
|
||||
}
|
||||
|
||||
async function readText(relPath) {
|
||||
return fs.readFile(path.join(REPO_ROOT, relPath), "utf8").catch(() => "");
|
||||
}
|
||||
|
||||
async function readJson(filePath) {
|
||||
return JSON.parse(await fs.readFile(filePath, "utf8").catch(() => "{}"));
|
||||
}
|
||||
|
||||
function parseKv(text) {
|
||||
const fields = {};
|
||||
for (const line of text.split(/\r?\n/)) {
|
||||
const index = line.indexOf("=");
|
||||
if (index <= 0) continue;
|
||||
fields[line.slice(0, index)] = line.slice(index + 1);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
function missingFromLdd(text, component) {
|
||||
const blockers = [];
|
||||
for (const line of text.split(/\r?\n/)) {
|
||||
if (line.includes("not found") || line.includes("version `GLIBC") || line.includes("version `GLIBCXX")) {
|
||||
blockers.push({ component, blocker: "dynamic_linker_requirement", detail: line.trim() });
|
||||
}
|
||||
}
|
||||
return blockers;
|
||||
}
|
||||
|
||||
function check(name, pass, detail) {
|
||||
return { name, pass: Boolean(pass), detail: String(detail || "-").slice(0, 3000) };
|
||||
}
|
||||
|
||||
function commandRecord(command, result) {
|
||||
return {
|
||||
command,
|
||||
status: result.status,
|
||||
signal: result.signal,
|
||||
stdout: result.stdout.slice(0, 6000),
|
||||
stderr: result.stderr.slice(0, 6000),
|
||||
};
|
||||
}
|
||||
|
||||
function firstLine(text) {
|
||||
return String(text || "").split(/\r?\n/).find(Boolean) || "-";
|
||||
}
|
||||
|
||||
function oneLine(text) {
|
||||
return String(text || "").split(/\r?\n/).filter(Boolean).join(" | ").slice(0, 2000);
|
||||
}
|
||||
|
||||
function renderMarkdown(data) {
|
||||
return [
|
||||
"# Native task/HAL comparison report",
|
||||
"",
|
||||
`- status: ${data.status}`,
|
||||
`- generatedAt: ${data.generatedAt}`,
|
||||
`- JSON: ${REPORT_JSON}`,
|
||||
"",
|
||||
"## Checks",
|
||||
"",
|
||||
...data.checks.map((item) => `- ${item.pass ? "PASS" : "FAIL"}: ${item.name} — ${item.detail}`),
|
||||
"",
|
||||
"## Host Native Runtime Blockers",
|
||||
"",
|
||||
...data.hostBlockers.map((item) => `- ${item.component}: ${item.blocker}: ${item.detail}`),
|
||||
"",
|
||||
"## Conclusion",
|
||||
"",
|
||||
data.conclusion.reason,
|
||||
"",
|
||||
data.conclusion.boundary,
|
||||
"",
|
||||
].join("\n");
|
||||
}
|
||||
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 272 KiB |
BIN
qa/web-rtcp-5axis-site-test/output/cloud-run-debug/01-loaded.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 198 KiB |
|
After Width: | Height: | Size: 199 KiB |
@@ -0,0 +1,776 @@
|
||||
{
|
||||
"target": "https://82.156.24.101:8092/",
|
||||
"generatedAt": "2026-06-23T07:25:17.986Z",
|
||||
"summaries": [
|
||||
{
|
||||
"label": "loaded",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "LinuxCNC task/HAL session ready /work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"machine": {
|
||||
"powerOn": false,
|
||||
"estopActive": false,
|
||||
"taskState": "estop-reset",
|
||||
"mode": "manual",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ESTOP_RESET",
|
||||
"taskMode": "MANUAL",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 0,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-canonical-motion",
|
||||
"semanticBoundary": "linuxcnc_canonical_motion_feedback_without_tp_sample",
|
||||
"sampleIndex": 0,
|
||||
"motionIndex": 0,
|
||||
"line": 8,
|
||||
"type": "STRAIGHT_TRAVERSE",
|
||||
"linearUnits": "mm",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 16.339,
|
||||
"y": -25.409,
|
||||
"z": 33.353,
|
||||
"a": -71.841,
|
||||
"b": 0,
|
||||
"c": -35.93
|
||||
},
|
||||
"currentVelocityMmPerMin": 2100,
|
||||
"requestedVelocityMmPerMin": 2100,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 1,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "after-direct-run",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "LinuxCNC task/HAL session ready /work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"machine": {
|
||||
"powerOn": false,
|
||||
"estopActive": false,
|
||||
"taskState": "estop-reset",
|
||||
"mode": "manual",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ESTOP_RESET",
|
||||
"taskMode": "MANUAL",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 0,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-canonical-motion",
|
||||
"semanticBoundary": "linuxcnc_canonical_motion_feedback_without_tp_sample",
|
||||
"sampleIndex": 0,
|
||||
"motionIndex": 0,
|
||||
"line": 8,
|
||||
"type": "STRAIGHT_TRAVERSE",
|
||||
"linearUnits": "mm",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 16.339,
|
||||
"y": -25.409,
|
||||
"z": 33.353,
|
||||
"a": -71.841,
|
||||
"b": 0,
|
||||
"c": -35.93
|
||||
},
|
||||
"currentVelocityMmPerMin": 2100,
|
||||
"requestedVelocityMmPerMin": 2100,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 1,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "after-run-ready",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "RUN ready: power on, homed, auto mode",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ON",
|
||||
"taskMode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 3600,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 40,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 40,
|
||||
"taskCycle": 4,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 3,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "run-0500",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "RUN ready: power on, homed, auto mode",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ON",
|
||||
"taskMode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 3600,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 40,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 40,
|
||||
"taskCycle": 4,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 3,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "run-2500",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "RUN ready: power on, homed, auto mode",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ON",
|
||||
"taskMode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 3600,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 40,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 40,
|
||||
"taskCycle": 4,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 3,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "run-6500",
|
||||
"runState": "idle",
|
||||
"operatorMessage": "RUN ready: power on, homed, auto mode",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ON",
|
||||
"taskMode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 3600,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 40,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 40,
|
||||
"taskCycle": 4,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 3,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
},
|
||||
{
|
||||
"label": "after-stop",
|
||||
"runState": "stopped",
|
||||
"operatorMessage": "task/HAL program stopped",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedGcodeSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"taskHalRuntimeReadiness": {
|
||||
"apiName": "web-rtcp-5axis-linuxcnc-task-hal-runtime-readiness",
|
||||
"loaded": true,
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sdkSemanticBoundary": "linuxcnc_task_motion_hal_wasm_phase4_minimal",
|
||||
"executionContext": "direct",
|
||||
"workerUrl": null,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false
|
||||
},
|
||||
"taskHalSession": {
|
||||
"profileId": "xyzac-trt",
|
||||
"programPath": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/impeller-7bl-xyzac.ngc",
|
||||
"fileCount": 18
|
||||
},
|
||||
"taskHalStatus": {
|
||||
"taskState": "ON",
|
||||
"taskMode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"activeLine": 1,
|
||||
"currentVelocity": 3600,
|
||||
"taskCycle": 0
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 50,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 50,
|
||||
"taskCycle": 5,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"programRuntimeFeedbackHistoryLength": 4,
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": "stopped",
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"runGate": null
|
||||
}
|
||||
],
|
||||
"consoleLogs": [
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x369c000f8800]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels",
|
||||
"location": {
|
||||
"url": "https://82.156.24.101:8092/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x369c000f8800]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels",
|
||||
"location": {
|
||||
"url": "https://82.156.24.101:8092/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x369c000f8800]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels",
|
||||
"location": {
|
||||
"url": "https://82.156.24.101:8092/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x369c000f8800]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)",
|
||||
"location": {
|
||||
"url": "https://82.156.24.101:8092/"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pageErrors": []
|
||||
}
|
||||
285
qa/web-rtcp-5axis-site-test/output/cloud-run-ready-after.json
Normal file
@@ -0,0 +1,285 @@
|
||||
{
|
||||
"generatedAt": "2026-06-23T07:35:25.253Z",
|
||||
"before": {
|
||||
"runState": "idle",
|
||||
"machine": {
|
||||
"powerOn": false,
|
||||
"estopActive": false,
|
||||
"taskState": "estop-reset",
|
||||
"mode": "manual",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"rtcpState": "on",
|
||||
"kinsType": "tcp-xyzac",
|
||||
"operatorMessage": "LinuxCNC task/HAL session ready /work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/boat-xyzac.ngc",
|
||||
"taskHalExecutionPending": false,
|
||||
"taskHalFallbackReason": null,
|
||||
"taskHalStatus": {
|
||||
"ui": {
|
||||
"taskState": "estop_reset",
|
||||
"taskMode": "manual",
|
||||
"interpState": "idle",
|
||||
"execState": "done",
|
||||
"taskCycle": 0,
|
||||
"servoCycle": 20,
|
||||
"motionQueueDepth": 0,
|
||||
"halChangedPinCount": 0,
|
||||
"activeLine": 1,
|
||||
"motionProgramLine": 0,
|
||||
"halProgramLine": 0,
|
||||
"activeLineSource": "fallback",
|
||||
"activeLineHalSynced": false,
|
||||
"switchkinsType": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"axisPoseFrame": "work",
|
||||
"currentVelocity": 0
|
||||
},
|
||||
"task": {
|
||||
"state": "ESTOP_RESET",
|
||||
"mode": "MANUAL",
|
||||
"interpState": "IDLE",
|
||||
"execState": "DONE",
|
||||
"cycle": 2,
|
||||
"openProgram": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/boat-xyzac.ngc",
|
||||
"openedLineCount": 1881,
|
||||
"openedSourceLineCount": 1881,
|
||||
"executableLineCount": 1859,
|
||||
"nextProgramLine": 0
|
||||
},
|
||||
"summary": {
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"taskHalComparisonReady": true,
|
||||
"switchkinsRemapHalSync": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"fullLinuxCncProgramExecutionReady": false,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false
|
||||
}
|
||||
},
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 20,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 0,
|
||||
"halProgramLine": 0,
|
||||
"activeLineSource": "fallback",
|
||||
"activeLineHalSynced": false,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 0,
|
||||
"requestedVelocityMmPerMin": 0,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 20,
|
||||
"taskCycle": 2,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"selected": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc",
|
||||
"taskHalSessionProgram": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/boat-xyzac.ngc",
|
||||
"preconditions": null
|
||||
},
|
||||
"after": {
|
||||
"runState": "idle",
|
||||
"machine": {
|
||||
"powerOn": true,
|
||||
"estopActive": false,
|
||||
"taskState": "on",
|
||||
"mode": "auto",
|
||||
"interpState": "idle",
|
||||
"interpResumeState": "idle",
|
||||
"taskPaused": false,
|
||||
"allHomed": false,
|
||||
"noForceHoming": false,
|
||||
"jogAxis": "x",
|
||||
"jogIncrement": 1,
|
||||
"mdiCommand": "G0 X0 Y0 Z0",
|
||||
"mdiDistanceMode": "absolute",
|
||||
"resetCount": 0
|
||||
},
|
||||
"rtcpState": "on",
|
||||
"kinsType": "tcp-xyzac",
|
||||
"operatorMessage": "RUN ready: power on, homed, auto mode",
|
||||
"taskHalExecutionPending": false,
|
||||
"taskHalFallbackReason": null,
|
||||
"taskHalStatus": {
|
||||
"ui": {
|
||||
"taskState": "on",
|
||||
"taskMode": "auto",
|
||||
"interpState": "idle",
|
||||
"execState": "done",
|
||||
"taskCycle": 0,
|
||||
"servoCycle": 40,
|
||||
"motionQueueDepth": 0,
|
||||
"halChangedPinCount": 0,
|
||||
"activeLine": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"switchkinsType": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"axisPoseFrame": "work",
|
||||
"currentVelocity": 3600
|
||||
},
|
||||
"task": {
|
||||
"state": "ON",
|
||||
"mode": "AUTO",
|
||||
"interpState": "IDLE",
|
||||
"execState": "DONE",
|
||||
"cycle": 4,
|
||||
"openProgram": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/boat-xyzac.ngc",
|
||||
"openedLineCount": 1881,
|
||||
"openedSourceLineCount": 1881,
|
||||
"executableLineCount": 1859,
|
||||
"nextProgramLine": 0
|
||||
},
|
||||
"summary": {
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"halSyncReady": true,
|
||||
"taskHalComparisonReady": true,
|
||||
"switchkinsRemapHalSync": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"fullLinuxCncProgramExecutionReady": false,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false
|
||||
}
|
||||
},
|
||||
"taskHalStatusLoop": {
|
||||
"apiName": "web-rtcp-5axis-task-hal-status-loop",
|
||||
"active": false,
|
||||
"sequence": 0,
|
||||
"profileId": null,
|
||||
"iniPath": null,
|
||||
"kinematicsModuleId": null,
|
||||
"tickCount": 0,
|
||||
"batchSize": 5,
|
||||
"intervalMs": 25,
|
||||
"taskPeriodNs": 10000000,
|
||||
"servoPeriodNs": 1000000,
|
||||
"lastStatusAt": null,
|
||||
"lastError": null,
|
||||
"stopReason": null,
|
||||
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
|
||||
},
|
||||
"programRuntimeFeedback": {
|
||||
"apiName": "web-rtcp-5axis-program-runtime-feedback",
|
||||
"sourceMode": "linuxcnc-task-motion-hal-wasm",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"sampleIndex": 40,
|
||||
"motionIndex": 0,
|
||||
"line": 1,
|
||||
"motionProgramLine": 1,
|
||||
"halProgramLine": 1,
|
||||
"activeLineSource": "motion-status",
|
||||
"activeLineHalSynced": true,
|
||||
"type": "TASK_MOTION",
|
||||
"timeSeconds": 0,
|
||||
"axisPose": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"a": 0,
|
||||
"b": 0,
|
||||
"c": 0
|
||||
},
|
||||
"currentVelocityMmPerMin": 3600,
|
||||
"requestedVelocityMmPerMin": 3600,
|
||||
"distanceToGo": 0,
|
||||
"dtg": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"queueDepth": 0,
|
||||
"activeDepth": 0,
|
||||
"cycle": 40,
|
||||
"taskCycle": 4,
|
||||
"halChangedPinCount": 0
|
||||
},
|
||||
"selected": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc",
|
||||
"taskHalSessionProgram": "/work/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt/demos/boat-xyzac.ngc",
|
||||
"preconditions": null
|
||||
},
|
||||
"logs": [
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x3764000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x3764000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x3764000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||
},
|
||||
{
|
||||
"type": "warn",
|
||||
"text": "[.WebGL-0x3764000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
qa/web-rtcp-5axis-site-test/output/cloud-run-ready-after.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,289 @@
|
||||
{
|
||||
"apiName": "web-rtcp-5axis-native-task-hal-comparison-report",
|
||||
"generatedAt": "2026-06-23T09:22:56.110Z",
|
||||
"status": "PASS_WITH_HOST_NATIVE_RUNTIME_BLOCKER",
|
||||
"scope": "LinuxCNC source/phase0 task-HAL comparison plus attempted host-native TRT runtime probe",
|
||||
"commands": {
|
||||
"phase0": {
|
||||
"command": "bash wasm-port/tests/native/verify_task_hal_phase0.sh",
|
||||
"status": 0,
|
||||
"signal": null,
|
||||
"stdout": "task_hal_phase0_native_probe_gate=ok\n",
|
||||
"stderr": ""
|
||||
},
|
||||
"nativeAudit": {
|
||||
"command": "node web-rtcp-5axis-sim-plan/tests/node/verify_native_task_hal_audit.mjs",
|
||||
"status": 0,
|
||||
"signal": null,
|
||||
"stdout": "native_task_hal_source_artifact_audit=ok\nnative_task_hal_readiness_artifact=web-rtcp-5axis-sim-plan/build/readiness/native-task-hal-readiness.json\ntask_hal_web_simulation_boundary_consistent=1\nnative_task_hal_host_probe_status=ready_disabled_by_default\nhardware_drive=0\nhost_realtime_kernel=0\nexternal_user_m_process_ready=0\ntool_db_process_ready=0\npromotion_scope=web_simulation_only\n",
|
||||
"stderr": ""
|
||||
},
|
||||
"optInNativeProbe": {
|
||||
"command": "ENABLE_TRT_TASK_HAL_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_trt_task_hal_runtime.sh",
|
||||
"status": 1,
|
||||
"signal": null,
|
||||
"stdout": "trt_task_hal_runtime_halcmd_path=/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/halcmd\ntrt_task_hal_runtime_linuxcnc_path=/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc\ntrt_task_hal_runtime_requirements=halcmd:1,linuxcnc:1\ntrt_task_hal_missing_requirements=-\ntrt_task_hal_source_proof_ready=1\ntrt_task_hal_runtime_ready=1\ntrt_task_hal_execution_enabled=0\ntrt_task_hal_promotion_allowed=0\nnativeTaskReady=false\nnativeHalSyncReady=false\ntrt_task_hal_runtime_probe_ini=/home/meswork/cnc_wams/wasm-port/../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini\ntrt_task_hal_runtime_probe_program=/home/meswork/cnc_wams/wasm-port/../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc\ntrt_task_hal_runtime_probe_linuxcnc_stdout=/home/meswork/cnc_wams/wasm-port/build/native/trt-task-hal-runtime/linuxcnc.stdout.log\ntrt_task_hal_runtime_probe_linuxcnc_stderr=/home/meswork/cnc_wams/wasm-port/build/native/trt-task-hal-runtime/linuxcnc.stderr.log\nnative_task_hal_probe=failed\nnative_probe_status=failed\ntrt_task_hal_runtime_probe_status=runtime_state_probe_failed\ntrt_task_hal_runtime_probe_note=linuxcnc_started_but_required_trt_hal_pins_did_not_appear\n",
|
||||
"stderr": ""
|
||||
},
|
||||
"fixtureBaseline": {
|
||||
"command": "LD_LIBRARY_PATH=linuxcnc/lib bash wasm-port/tools/verify_native_linuxcnc_fixture_baseline.sh",
|
||||
"status": 1,
|
||||
"signal": null,
|
||||
"stdout": "",
|
||||
"stderr": "upstream rs274 failed for fixture: minimal_linear\n/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/rs274: error while loading shared libraries: libpython3.13.so.1.0: cannot open shared object file: No such file or directory\n"
|
||||
}
|
||||
},
|
||||
"readiness": {
|
||||
"apiName": "web-rtcp-5axis-native-task-hal-readiness-audit",
|
||||
"batch": "M18-native-task-hal-source-and-artifact-audit",
|
||||
"generatedAt": "2026-06-22T00:00:00.000Z",
|
||||
"status": "ok",
|
||||
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
||||
"promotionScope": "web_simulation_only",
|
||||
"taskHalWebSimulationBoundaryConsistent": true,
|
||||
"webSimulation": {
|
||||
"promoted": true,
|
||||
"taskRuntimeReady": true,
|
||||
"motionRuntimeReady": true,
|
||||
"halRuntimeReady": true,
|
||||
"nativeTaskReady": true,
|
||||
"nativeHalSyncReady": true,
|
||||
"fullLinuxCncProgramExecutionReady": true,
|
||||
"promotionAllowed": true
|
||||
},
|
||||
"nativeHostAndHardware": {
|
||||
"nativeProbe": "ok",
|
||||
"nativeProbeStatus": "ready_disabled_by_default",
|
||||
"nativePromotionAllowed": false,
|
||||
"hardwareDrive": false,
|
||||
"hostRealtimeKernel": false,
|
||||
"externalUserMProcessReady": false,
|
||||
"toolDbProcessReady": false
|
||||
},
|
||||
"sourceManifest": {
|
||||
"ready": true,
|
||||
"taskSourceCount": 7,
|
||||
"halSourceCount": 4,
|
||||
"motionSourceCount": 6,
|
||||
"nmlSourceCount": 1,
|
||||
"libnmlSourceCount": 2,
|
||||
"referenceSourceReady": true,
|
||||
"vendorSourceReady": false,
|
||||
"vendorHashMatchReady": true
|
||||
},
|
||||
"gates": {
|
||||
"task_hal_web_simulation_boundary_consistent": 1,
|
||||
"native_task_hal_host_probe_status": "ready_disabled_by_default",
|
||||
"hardware_drive": 0,
|
||||
"host_realtime_kernel": 0,
|
||||
"external_user_m_process_ready": 0,
|
||||
"tool_db_process_ready": 0,
|
||||
"promotion_scope": "web_simulation_only"
|
||||
},
|
||||
"artifacts": {
|
||||
"readinessJson": "web-rtcp-5axis-sim-plan/build/readiness/native-task-hal-readiness.json",
|
||||
"sourceManifestLog": "wasm-port/build/task-hal/verify_task_hal_source_manifest.stdout.log",
|
||||
"sourceManifestReport": "wasm-port/build/task-hal/task-hal-source-manifest.tsv",
|
||||
"nativeProbeLog": "wasm-port/build/task-hal/probe_trt_task_hal_runtime.stdout.log"
|
||||
},
|
||||
"blockers": []
|
||||
},
|
||||
"sourceManifest": {
|
||||
"task_hal_source_manifest_status": "ok",
|
||||
"task_hal_source_manifest_ready": "1",
|
||||
"task_hal_source_manifest_path": "/home/meswork/cnc_wams/wasm-port/tools/task-hal-source-manifest.txt",
|
||||
"task_hal_source_manifest_report": "/home/meswork/cnc_wams/wasm-port/build/task-hal/task-hal-source-manifest.tsv",
|
||||
"task_hal_source_count": "20",
|
||||
"task_source_count": "7",
|
||||
"hal_source_count": "4",
|
||||
"motion_source_count": "6",
|
||||
"nml_source_count": "1",
|
||||
"libnml_source_count": "2",
|
||||
"task_hal_reference_source_ready": "1",
|
||||
"task_hal_vendor_source_ready": "0",
|
||||
"task_hal_vendor_hash_match_ready": "1",
|
||||
"task_hal_missing_reference_source_count": "0",
|
||||
"task_hal_missing_reference_sources_ready": "1",
|
||||
"task_hal_missing_reference_source_list": "-",
|
||||
"task_hal_missing_vendor_source_list": "src/emc/task/task.hh,src/emc/task/taskclass.hh,src/emc/task/taskclass.cc,src/emc/task/emctask.cc,src/emc/task/emctaskmain.cc,src/emc/task/taskintf.cc,src/emc/task/emccanon.cc,src/emc/motion/usrmotintf.h,src/emc/motion/motion.c,src/emc/motion/command.c,src/emc/motion/control.c,src/hal/hal_lib.c,src/hal/hal_priv.h,src/hal/components/threads.c,src/hal/utils/halcmd_commands.cc",
|
||||
"task_hal_mismatched_vendor_source_list": "-",
|
||||
"task_hal_runtime_promoted": "0",
|
||||
"nativeTaskReady": "false",
|
||||
"nativeHalSyncReady": "false"
|
||||
},
|
||||
"defaultProbe": {
|
||||
"trt_task_hal_runtime_halcmd_path": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/halcmd",
|
||||
"trt_task_hal_runtime_linuxcnc_path": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc",
|
||||
"trt_task_hal_runtime_requirements": "halcmd:1,linuxcnc:1",
|
||||
"trt_task_hal_missing_requirements": "-",
|
||||
"trt_task_hal_source_proof_ready": "1",
|
||||
"trt_task_hal_runtime_ready": "1",
|
||||
"trt_task_hal_execution_enabled": "0",
|
||||
"trt_task_hal_promotion_allowed": "0",
|
||||
"nativeTaskReady": "false",
|
||||
"nativeHalSyncReady": "false",
|
||||
"native_task_hal_probe": "ok",
|
||||
"native_probe_status": "ready_disabled_by_default",
|
||||
"trt_task_hal_runtime_probe_status": "ready_disabled_by_default",
|
||||
"trt_task_hal_runtime_probe_note": "set_ENABLE_TRT_TASK_HAL_RUNTIME_PROBE_1_to_run_exclusive_host_runtime_probe"
|
||||
},
|
||||
"optInProbeFields": {
|
||||
"trt_task_hal_runtime_halcmd_path": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/halcmd",
|
||||
"trt_task_hal_runtime_linuxcnc_path": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc",
|
||||
"trt_task_hal_runtime_requirements": "halcmd:1,linuxcnc:1",
|
||||
"trt_task_hal_missing_requirements": "-",
|
||||
"trt_task_hal_source_proof_ready": "1",
|
||||
"trt_task_hal_runtime_ready": "1",
|
||||
"trt_task_hal_execution_enabled": "0",
|
||||
"trt_task_hal_promotion_allowed": "0",
|
||||
"nativeTaskReady": "false",
|
||||
"nativeHalSyncReady": "false",
|
||||
"trt_task_hal_runtime_probe_ini": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
|
||||
"trt_task_hal_runtime_probe_program": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc",
|
||||
"trt_task_hal_runtime_probe_linuxcnc_stdout": "/home/meswork/cnc_wams/wasm-port/build/native/trt-task-hal-runtime/linuxcnc.stdout.log",
|
||||
"trt_task_hal_runtime_probe_linuxcnc_stderr": "/home/meswork/cnc_wams/wasm-port/build/native/trt-task-hal-runtime/linuxcnc.stderr.log",
|
||||
"native_task_hal_probe": "failed",
|
||||
"native_probe_status": "failed",
|
||||
"trt_task_hal_runtime_probe_status": "runtime_state_probe_failed",
|
||||
"trt_task_hal_runtime_probe_note": "linuxcnc_started_but_required_trt_hal_pins_did_not_appear"
|
||||
},
|
||||
"hostBlockers": [
|
||||
{
|
||||
"component": "halcmd",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "linuxcnc/bin/halcmd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/halcmd)"
|
||||
},
|
||||
{
|
||||
"component": "halcmd",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcncini.so.1 => not found"
|
||||
},
|
||||
{
|
||||
"component": "halcmd",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcnchal.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.31' not found (required by linuxcnc/bin/rs274)"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/rs274)"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "librs274.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "libnml.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcnchal.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcncini.so.1 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "libtooldata.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "rs274",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "libpython3.13.so.1.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "linuxcncsvr",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcnchal.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "linuxcncsvr",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "libnml.so.0 => not found"
|
||||
},
|
||||
{
|
||||
"component": "linuxcncsvr",
|
||||
"blocker": "dynamic_linker_requirement",
|
||||
"detail": "liblinuxcncini.so.1 => not found"
|
||||
},
|
||||
{
|
||||
"component": "linuxcnc scripts/linuxcnc",
|
||||
"blocker": "hardcoded_rip_environment_path_missing",
|
||||
"detail": "/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc: line 23: /home/cnc/桌面/cnc_wams/linuxcnc/scripts/rip-environment: No such file or directory"
|
||||
}
|
||||
],
|
||||
"ldd": {
|
||||
"halcmd": {
|
||||
"command": "ldd linuxcnc/bin/halcmd",
|
||||
"status": 0,
|
||||
"signal": null,
|
||||
"stdout": "linuxcnc/bin/halcmd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/halcmd)\n\tlinux-vdso.so.1 (0x00007ffe1df2d000)\n\tliblinuxcncini.so.1 => not found\n\tliblinuxcnchal.so.0 => not found\n\tlibedit.so.2 => /lib/x86_64-linux-gnu/libedit.so.2 (0x000077e6290a4000)\n\tlibstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000077e628e00000)\n\tlibgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000077e629084000)\n\tlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000077e628a00000)\n\tlibtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x000077e629050000)\n\tlibbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x000077e629038000)\n\tlibm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000077e628d19000)\n\t/lib64/ld-linux-x86-64.so.2 (0x000077e62910b000)\n\tlibmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x000077e628d0c000)\n",
|
||||
"stderr": ""
|
||||
},
|
||||
"rs274": {
|
||||
"command": "ldd linuxcnc/bin/rs274",
|
||||
"status": 0,
|
||||
"signal": null,
|
||||
"stdout": "linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.31' not found (required by linuxcnc/bin/rs274)\nlinuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/rs274)\n\tlinux-vdso.so.1 (0x00007ffd1ad98000)\n\tlibrs274.so.0 => not found\n\tlibnml.so.0 => not found\n\tliblinuxcnchal.so.0 => not found\n\tliblinuxcncini.so.1 => not found\n\tlibtooldata.so.0 => not found\n\tlibpython3.13.so.1.0 => not found\n\tlibedit.so.2 => /lib/x86_64-linux-gnu/libedit.so.2 (0x0000711e18f2f000)\n\tlibstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000711e18c00000)\n\tlibgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000711e18f0f000)\n\tlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000711e18800000)\n\tlibtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x0000711e18edd000)\n\tlibbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x0000711e18ec3000)\n\tlibm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000711e18b19000)\n\t/lib64/ld-linux-x86-64.so.2 (0x0000711e18fb9000)\n\tlibmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x0000711e18eb6000)\n",
|
||||
"stderr": ""
|
||||
},
|
||||
"linuxcncsvr": {
|
||||
"command": "ldd linuxcnc/bin/linuxcncsvr",
|
||||
"status": 0,
|
||||
"signal": null,
|
||||
"stdout": "\tlinux-vdso.so.1 (0x00007ffe9c9d9000)\n\tliblinuxcnchal.so.0 => not found\n\tlibnml.so.0 => not found\n\tliblinuxcncini.so.1 => not found\n\tlibstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000078425a200000)\n\tlibgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000078425a52d000)\n\tlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000784259e00000)\n\tlibm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000078425a444000)\n\t/lib64/ld-linux-x86-64.so.2 (0x000078425a56d000)\n",
|
||||
"stderr": ""
|
||||
}
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"name": "phase0 native source/probe gate passes",
|
||||
"pass": true,
|
||||
"detail": "task_hal_phase0_native_probe_gate=ok"
|
||||
},
|
||||
{
|
||||
"name": "native readiness audit passes",
|
||||
"pass": true,
|
||||
"detail": "native_task_hal_source_artifact_audit=ok | native_task_hal_readiness_artifact=web-rtcp-5axis-sim-plan/build/readiness/native-task-hal-readiness.json | task_hal_web_simulation_boundary_consistent=1 | native_task_hal_host_probe_status=ready_disabled_by_default | hardware_drive=0 | host_realtime_kernel=0 | external_user_m_process_ready=0 | tool_db_process_ready=0 | promotion_scope=web_simulation_only"
|
||||
},
|
||||
{
|
||||
"name": "source manifest ready",
|
||||
"pass": true,
|
||||
"detail": "{\"task_hal_source_manifest_status\":\"ok\",\"task_hal_source_manifest_ready\":\"1\",\"task_hal_source_manifest_path\":\"/home/meswork/cnc_wams/wasm-port/tools/task-hal-source-manifest.txt\",\"task_hal_source_manifest_report\":\"/home/meswork/cnc_wams/wasm-port/build/task-hal/task-hal-source-manifest.tsv\",\"task_hal_source_count\":\"20\",\"task_source_count\":\"7\",\"hal_source_count\":\"4\",\"motion_source_count\":\"6\",\"nml_source_count\":\"1\",\"libnml_source_count\":\"2\",\"task_hal_reference_source_ready\":\"1\",\"task_hal_vendor_source_ready\":\"0\",\"task_hal_vendor_hash_match_ready\":\"1\",\"task_hal_missing_reference_source_count\":\"0\",\"task_hal_missing_reference_sources_ready\":\"1\",\"task_hal_missing_reference_source_list\":\"-\",\"task_hal_missing_vendor_source_list\":\"src/emc/task/task.hh,src/emc/task/taskclass.hh,src/emc/task/taskclass.cc,src/emc/task/emctask.cc,src/emc/task/emctaskmain.cc,src/emc/task/taskintf.cc,src/emc/task/emccanon.cc,src/emc/motion/usrmotintf.h,src/emc/motion/motion.c,src/emc/motion/command.c,src/emc/motion/control.c,src/hal/hal_lib.c,src/hal/hal_priv.h,src/hal/components/threads.c,src/hal/utils/halcmd_commands.cc\",\"task_hal_mismatched_vendor_source_list\":\"-\",\"task_hal_runtime_promoted\":\"0\",\"nativeTaskReady\":\"false\",\"nativeHalSyncReady\":\"false\"}"
|
||||
},
|
||||
{
|
||||
"name": "TRT source proof ready",
|
||||
"pass": true,
|
||||
"detail": "{\"trt_task_hal_runtime_halcmd_path\":\"/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/halcmd\",\"trt_task_hal_runtime_linuxcnc_path\":\"/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc\",\"trt_task_hal_runtime_requirements\":\"halcmd:1,linuxcnc:1\",\"trt_task_hal_missing_requirements\":\"-\",\"trt_task_hal_source_proof_ready\":\"1\",\"trt_task_hal_runtime_ready\":\"1\",\"trt_task_hal_execution_enabled\":\"0\",\"trt_task_hal_promotion_allowed\":\"0\",\"nativeTaskReady\":\"false\",\"nativeHalSyncReady\":\"false\",\"native_task_hal_probe\":\"ok\",\"native_probe_status\":\"ready_disabled_by_default\",\"trt_task_hal_runtime_probe_status\":\"ready_disabled_by_default\",\"trt_task_hal_runtime_probe_note\":\"set_ENABLE_TRT_TASK_HAL_RUNTIME_PROBE_1_to_run_exclusive_host_runtime_probe\"}"
|
||||
},
|
||||
{
|
||||
"name": "host-native runtime blocker captured",
|
||||
"pass": true,
|
||||
"detail": "[{\"component\":\"halcmd\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"linuxcnc/bin/halcmd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/halcmd)\"},{\"component\":\"halcmd\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcncini.so.1 => not found\"},{\"component\":\"halcmd\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcnchal.so.0 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.31' not found (required by linuxcnc/bin/rs274)\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/rs274)\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"librs274.so.0 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"libnml.so.0 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcnchal.so.0 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcncini.so.1 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"libtooldata.so.0 => not found\"},{\"component\":\"rs274\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"libpython3.13.so.1.0 => not found\"},{\"component\":\"linuxcncsvr\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcnchal.so.0 => not found\"},{\"component\":\"linuxcncsvr\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"libnml.so.0 => not found\"},{\"component\":\"linuxcncsvr\",\"blocker\":\"dynamic_linker_requirement\",\"detail\":\"liblinuxcncini.so.1 => not found\"},{\"component\":\"linuxcnc scripts/linuxcnc\",\"blocker\":\"hardcoded_rip_environment_path_missing\",\"detail\":\"/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc: line 23: /home/cnc/桌面/cnc_wams/linuxcnc/scripts/rip-environment: No such file or directory\"}]"
|
||||
},
|
||||
{
|
||||
"name": "web simulation promotion remains bounded",
|
||||
"pass": true,
|
||||
"detail": "{\"task_hal_web_simulation_boundary_consistent\":1,\"native_task_hal_host_probe_status\":\"ready_disabled_by_default\",\"hardware_drive\":0,\"host_realtime_kernel\":0,\"external_user_m_process_ready\":0,\"tool_db_process_ready\":0,\"promotion_scope\":\"web_simulation_only\"}"
|
||||
}
|
||||
],
|
||||
"conclusion": {
|
||||
"nativeTaskHalSourceComparisonReady": true,
|
||||
"nativeTransitionLogAvailable": false,
|
||||
"nativeTransitionLogBlockedByHostRuntime": true,
|
||||
"reason": "Current host cannot start the LinuxCNC native TRT task/HAL runtime: generated LinuxCNC RIP scripts reference an old absolute path and binaries require unavailable host runtime libraries such as GLIBC_2.38/libpython3.13.",
|
||||
"boundary": "This completes BTN-013 as an auditable native comparison and blocker record; it does not claim hardware drive, realtime kernel, external user-M process, or tool DB native runtime readiness."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Native task/HAL comparison report
|
||||
|
||||
- status: PASS_WITH_HOST_NATIVE_RUNTIME_BLOCKER
|
||||
- generatedAt: 2026-06-23T09:22:56.110Z
|
||||
- JSON: /home/meswork/cnc_wams/qa/web-rtcp-5axis-site-test/output/native-task-hal-comparison-report.json
|
||||
|
||||
## Checks
|
||||
|
||||
- PASS: phase0 native source/probe gate passes — task_hal_phase0_native_probe_gate=ok
|
||||
- PASS: native readiness audit passes — native_task_hal_source_artifact_audit=ok | native_task_hal_readiness_artifact=web-rtcp-5axis-sim-plan/build/readiness/native-task-hal-readiness.json | task_hal_web_simulation_boundary_consistent=1 | native_task_hal_host_probe_status=ready_disabled_by_default | hardware_drive=0 | host_realtime_kernel=0 | external_user_m_process_ready=0 | tool_db_process_ready=0 | promotion_scope=web_simulation_only
|
||||
- PASS: source manifest ready — {"task_hal_source_manifest_status":"ok","task_hal_source_manifest_ready":"1","task_hal_source_manifest_path":"/home/meswork/cnc_wams/wasm-port/tools/task-hal-source-manifest.txt","task_hal_source_manifest_report":"/home/meswork/cnc_wams/wasm-port/build/task-hal/task-hal-source-manifest.tsv","task_hal_source_count":"20","task_source_count":"7","hal_source_count":"4","motion_source_count":"6","nml_source_count":"1","libnml_source_count":"2","task_hal_reference_source_ready":"1","task_hal_vendor_source_ready":"0","task_hal_vendor_hash_match_ready":"1","task_hal_missing_reference_source_count":"0","task_hal_missing_reference_sources_ready":"1","task_hal_missing_reference_source_list":"-","task_hal_missing_vendor_source_list":"src/emc/task/task.hh,src/emc/task/taskclass.hh,src/emc/task/taskclass.cc,src/emc/task/emctask.cc,src/emc/task/emctaskmain.cc,src/emc/task/taskintf.cc,src/emc/task/emccanon.cc,src/emc/motion/usrmotintf.h,src/emc/motion/motion.c,src/emc/motion/command.c,src/emc/motion/control.c,src/hal/hal_lib.c,src/hal/hal_priv.h,src/hal/components/threads.c,src/hal/utils/halcmd_commands.cc","task_hal_mismatched_vendor_source_list":"-","task_hal_runtime_promoted":"0","nativeTaskReady":"false","nativeHalSyncReady":"false"}
|
||||
- PASS: TRT source proof ready — {"trt_task_hal_runtime_halcmd_path":"/home/meswork/cnc_wams/wasm-port/../linuxcnc/bin/halcmd","trt_task_hal_runtime_linuxcnc_path":"/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc","trt_task_hal_runtime_requirements":"halcmd:1,linuxcnc:1","trt_task_hal_missing_requirements":"-","trt_task_hal_source_proof_ready":"1","trt_task_hal_runtime_ready":"1","trt_task_hal_execution_enabled":"0","trt_task_hal_promotion_allowed":"0","nativeTaskReady":"false","nativeHalSyncReady":"false","native_task_hal_probe":"ok","native_probe_status":"ready_disabled_by_default","trt_task_hal_runtime_probe_status":"ready_disabled_by_default","trt_task_hal_runtime_probe_note":"set_ENABLE_TRT_TASK_HAL_RUNTIME_PROBE_1_to_run_exclusive_host_runtime_probe"}
|
||||
- PASS: host-native runtime blocker captured — [{"component":"halcmd","blocker":"dynamic_linker_requirement","detail":"linuxcnc/bin/halcmd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/halcmd)"},{"component":"halcmd","blocker":"dynamic_linker_requirement","detail":"liblinuxcncini.so.1 => not found"},{"component":"halcmd","blocker":"dynamic_linker_requirement","detail":"liblinuxcnchal.so.0 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.31' not found (required by linuxcnc/bin/rs274)"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/rs274)"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"librs274.so.0 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"libnml.so.0 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"liblinuxcnchal.so.0 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"liblinuxcncini.so.1 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"libtooldata.so.0 => not found"},{"component":"rs274","blocker":"dynamic_linker_requirement","detail":"libpython3.13.so.1.0 => not found"},{"component":"linuxcncsvr","blocker":"dynamic_linker_requirement","detail":"liblinuxcnchal.so.0 => not found"},{"component":"linuxcncsvr","blocker":"dynamic_linker_requirement","detail":"libnml.so.0 => not found"},{"component":"linuxcncsvr","blocker":"dynamic_linker_requirement","detail":"liblinuxcncini.so.1 => not found"},{"component":"linuxcnc scripts/linuxcnc","blocker":"hardcoded_rip_environment_path_missing","detail":"/home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc: line 23: /home/cnc/桌面/cnc_wams/linuxcnc/scripts/rip-environment: No such file or directory"}]
|
||||
- PASS: web simulation promotion remains bounded — {"task_hal_web_simulation_boundary_consistent":1,"native_task_hal_host_probe_status":"ready_disabled_by_default","hardware_drive":0,"host_realtime_kernel":0,"external_user_m_process_ready":0,"tool_db_process_ready":0,"promotion_scope":"web_simulation_only"}
|
||||
|
||||
## Host Native Runtime Blockers
|
||||
|
||||
- halcmd: dynamic_linker_requirement: linuxcnc/bin/halcmd: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/halcmd)
|
||||
- halcmd: dynamic_linker_requirement: liblinuxcncini.so.1 => not found
|
||||
- halcmd: dynamic_linker_requirement: liblinuxcnchal.so.0 => not found
|
||||
- rs274: dynamic_linker_requirement: linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.31' not found (required by linuxcnc/bin/rs274)
|
||||
- rs274: dynamic_linker_requirement: linuxcnc/bin/rs274: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found (required by linuxcnc/bin/rs274)
|
||||
- rs274: dynamic_linker_requirement: librs274.so.0 => not found
|
||||
- rs274: dynamic_linker_requirement: libnml.so.0 => not found
|
||||
- rs274: dynamic_linker_requirement: liblinuxcnchal.so.0 => not found
|
||||
- rs274: dynamic_linker_requirement: liblinuxcncini.so.1 => not found
|
||||
- rs274: dynamic_linker_requirement: libtooldata.so.0 => not found
|
||||
- rs274: dynamic_linker_requirement: libpython3.13.so.1.0 => not found
|
||||
- linuxcncsvr: dynamic_linker_requirement: liblinuxcnchal.so.0 => not found
|
||||
- linuxcncsvr: dynamic_linker_requirement: libnml.so.0 => not found
|
||||
- linuxcncsvr: dynamic_linker_requirement: liblinuxcncini.so.1 => not found
|
||||
- linuxcnc scripts/linuxcnc: hardcoded_rip_environment_path_missing: /home/meswork/cnc_wams/wasm-port/../linuxcnc/scripts/linuxcnc: line 23: /home/cnc/桌面/cnc_wams/linuxcnc/scripts/rip-environment: No such file or directory
|
||||
|
||||
## Conclusion
|
||||
|
||||
Current host cannot start the LinuxCNC native TRT task/HAL runtime: generated LinuxCNC RIP scripts reference an old absolute path and binaries require unavailable host runtime libraries such as GLIBC_2.38/libpython3.13.
|
||||
|
||||
This completes BTN-013 as an auditable native comparison and blocker record; it does not claim hardware drive, realtime kernel, external user-M process, or tool DB native runtime readiness.
|
||||
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 200 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 196 KiB |
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"generatedAt": "2026-06-23T03:55:10.303Z",
|
||||
"targetUrl": "https://82.156.24.101:8092/",
|
||||
"viewport": {
|
||||
"width": 848,
|
||||
"height": 331
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"totalProgramLines": 4507,
|
||||
"visibleGcodeRows": 21,
|
||||
"firstVisibleLines": [
|
||||
{
|
||||
"line": 1,
|
||||
"text": "( Impeller 5-axis 12/24/2011)"
|
||||
},
|
||||
{
|
||||
"line": 2,
|
||||
"text": "( This is preceded by cutting the external \"conical\" shape on a lathe)"
|
||||
},
|
||||
{
|
||||
"line": 3,
|
||||
"text": "( This is only a demo - roughing out in soft non-metal material)"
|
||||
},
|
||||
{
|
||||
"line": 4,
|
||||
"text": "M428 ;TCP:xyzac"
|
||||
},
|
||||
{
|
||||
"line": 5,
|
||||
"text": "G93"
|
||||
},
|
||||
{
|
||||
"line": 6,
|
||||
"text": "S600 M3"
|
||||
},
|
||||
{
|
||||
"line": 7,
|
||||
"text": "( --- Operation 1 )"
|
||||
},
|
||||
{
|
||||
"line": 8,
|
||||
"text": "G0 X 16.339 Y -25.409 Z 33.353 A -71.841 C -35.930"
|
||||
},
|
||||
{
|
||||
"line": 9,
|
||||
"text": "G0 X 7.417 Y -13.098 Z 28.366 A -71.841 C -35.930"
|
||||
},
|
||||
{
|
||||
"line": 10,
|
||||
"text": "G1 X 6.302 Y -11.560 Z 27.743 A -71.841 C -35.930 F 318"
|
||||
},
|
||||
{
|
||||
"line": 11,
|
||||
"text": "G1 X 6.358 Y -12.418 Z 26.178 A -71.266 C -32.919 F 159"
|
||||
},
|
||||
{
|
||||
"line": 12,
|
||||
"text": "G1 X 6.346 Y -12.607 Z 25.858 A -71.158 C -32.304 F 159"
|
||||
}
|
||||
],
|
||||
"gcodePanelBox": {
|
||||
"x": 354.984375,
|
||||
"y": 49,
|
||||
"width": 396,
|
||||
"height": 253
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 198 KiB |
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"generatedAt": "2026-06-23T03:43:15.696Z",
|
||||
"viewport": {
|
||||
"width": 848,
|
||||
"height": 331
|
||||
},
|
||||
"activeProgram": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"selectedSourceRel": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
|
||||
"totalProgramLines": 4507,
|
||||
"visibleGcodeRows": 21,
|
||||
"firstVisibleLines": [
|
||||
{
|
||||
"line": 1,
|
||||
"text": "( Impeller 5-axis 12/24/2011)"
|
||||
},
|
||||
{
|
||||
"line": 2,
|
||||
"text": "( This is preceded by cutting the external \"conical\" shape on a lathe)"
|
||||
},
|
||||
{
|
||||
"line": 3,
|
||||
"text": "( This is only a demo - roughing out in soft non-metal material)"
|
||||
},
|
||||
{
|
||||
"line": 4,
|
||||
"text": "M428 ;TCP:xyzac"
|
||||
},
|
||||
{
|
||||
"line": 5,
|
||||
"text": "G93"
|
||||
},
|
||||
{
|
||||
"line": 6,
|
||||
"text": "S600 M3"
|
||||
},
|
||||
{
|
||||
"line": 7,
|
||||
"text": "( --- Operation 1 )"
|
||||
},
|
||||
{
|
||||
"line": 8,
|
||||
"text": "G0 X 16.339 Y -25.409 Z 33.353 A -71.841 C -35.930"
|
||||
},
|
||||
{
|
||||
"line": 9,
|
||||
"text": "G0 X 7.417 Y -13.098 Z 28.366 A -71.841 C -35.930"
|
||||
},
|
||||
{
|
||||
"line": 10,
|
||||
"text": "G1 X 6.302 Y -11.560 Z 27.743 A -71.841 C -35.930 F 318"
|
||||
},
|
||||
{
|
||||
"line": 11,
|
||||
"text": "G1 X 6.358 Y -12.418 Z 26.178 A -71.266 C -32.919 F 159"
|
||||
},
|
||||
{
|
||||
"line": 12,
|
||||
"text": "G1 X 6.346 Y -12.607 Z 25.858 A -71.158 C -32.304 F 159"
|
||||
}
|
||||
],
|
||||
"gcodePanelHeight": 253,
|
||||
"gcodePanelBox": {
|
||||
"x": 354.984375,
|
||||
"y": 49,
|
||||
"width": 396,
|
||||
"height": 253
|
||||
},
|
||||
"gcodeListHeight": 206,
|
||||
"droPanelHeight": 24,
|
||||
"titlebarHeight": 24,
|
||||
"bottomControlsHeight": 28
|
||||
}
|
||||
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 34 KiB |