完善云端RUN执行反馈

This commit is contained in:
2026-06-23 03:59:47 -04:00
parent bb71613051
commit 37604fa5b3
33 changed files with 3724 additions and 534 deletions

View File

@@ -90,17 +90,26 @@ try {
await wait(800);
await captureStep("01-initial-ui", "初始界面", "确认浏览器应用、五轴预览区、G-code 区和 DRO 面板已渲染。");
await page.evaluate(async ({ ini }) => {
await window.webRtcp5AxisSimulation.stageMachineFiles({ iniText: ini, storageMode: "memory" });
}, { ini: iniText });
await page.evaluate(async ({ ini, gcode, sourceRel }) => {
await window.webRtcp5AxisSimulation.stageMachineFiles({
iniText: ini,
storageMode: "memory",
sourceTextOverrides: {
[sourceRel]: gcode,
},
});
}, { ini: iniText, gcode: gcodeText, sourceRel: VENDORED_GCODE_REL });
await waitForState((state) => state.machineFileStaging?.status === "staged", 20000, "test INI staged");
await captureStep("02-stage-test-ini", "Stage test_linuxcnc_source INI", "使用 working_run/test_linuxcnc_source/xyzac-trt.ini 重新 staging machine files。");
await page.select('[data-action="select-linuxcnc-gcode-source"]', VENDORED_GCODE_REL);
await page.evaluate(({ sourceRel }) => {
window.webRtcp5AxisSimulation.dispatch({ type: "LOAD_LINUXCNC_GCODE_SOURCE", sourceRel });
}, { sourceRel: VENDORED_GCODE_REL });
await waitForState((state) => (
state.activeProgram?.endsWith("impeller-7bl-xyzac.ngc") &&
state.programExecutionSourceMode === "linuxcnc-interpreter-wasm" &&
state.taskHalSession?.programPath?.endsWith("impeller-7bl-xyzac.ngc")
state.taskHalSession?.programPath?.endsWith("impeller-7bl-xyzac.ngc") &&
state.loadedSourceBytes === sourceEvidence.gcodeBytes
), 25000, "impeller program loaded");
await waitForCanvasReady();
await wait(1200);
@@ -192,6 +201,8 @@ async function captureRunSample(elapsedMs, name, title) {
taskCycle: state.programRuntimeFeedback?.taskCycle ?? null,
servoCycle: state.programRuntimeFeedback?.cycle ?? null,
historyLength: state.programRuntimeFeedbackHistory?.length || 0,
lineExecution: state.currentLineExecution,
lineExecutionVisible: state.currentLineExecutionVisible,
executedPathPoints: Number(step.dataset.threeExecutedPathPoints || 0),
currentSegmentHighlight: step.dataset.threeCurrentSegmentHighlight,
};
@@ -236,6 +247,7 @@ function addChecks() {
check("TCP/刀轴线可见", previewStep?.dataset?.threeTcpMarker === "sphere" && previewStep?.dataset?.threeToolAxisMarker === "line", `tcp=${previewStep?.dataset?.threeTcpMarker}, axis=${previewStep?.dataset?.threeToolAxisMarker}`),
check("RUN 采样数量", runSamples.length >= 5, `samples=${runSamples.length}`),
check("每行执行高亮同步", runSamples.every((sample) => sample.activeLineMatchesUi), runSamples.map((sample) => `${sample.activeLine}/${sample.activeUiLine}`).join(", ")),
check("程序列表显示每行执行过程", runSamples.every((sample) => sample.lineExecution?.line === sample.activeLine && sample.lineExecutionVisible === true), runSamples.map((sample) => `${sample.activeLine}:${sample.lineExecution?.status || "-"}:${sample.lineExecutionVisible}`).join(", ")),
check("执行轨迹可见", runSamples.every((sample) => sample.executedPathPoints >= 1 && sample.currentSegmentHighlight === "ok"), runSamples.map((sample) => `${sample.executedPathPoints}/${sample.currentSegmentHighlight}`).join(", ")),
check("实时轴值来自 task/HAL feedback", runSamples.every((sample) => sample.feedbackSource === "linuxcnc-task-motion-hal-wasm" && sample.droMatchesAxisPose), runSamples.map((sample) => `${sample.feedbackSource}/${sample.droMatchesAxisPose}`).join(", ")),
check("RUN feed 不是固定 3600 mm/min", movingVelocities.length > 0 && movingVelocities.every((velocity) => Math.abs(velocity - 3600) > 0.001), runSamples.map((sample) => `${sample.elapsedMs}ms=${sample.velocity}`).join(", ")),
@@ -256,6 +268,7 @@ function summarizeState(state) {
machineProfile: state.machineProfile,
iniPath: state.iniConfigReadiness?.path || state.linuxCncIniConfig?.path || null,
selectedGcodeSourceRel: state.machineFileStaging?.selectedGcodeSourceRel || null,
loadedSourceBytes: state.machineFileStaging?.save?.files?.find((file) => file.sourceRel === state.machineFileStaging?.selectedGcodeSourceRel)?.bytes || null,
taskHalProgramPath: state.taskHalSession?.programPath || null,
runState: state.runState,
activeLine: state.activeLine,
@@ -267,6 +280,8 @@ function summarizeState(state) {
axisPose: pickAxes(state.axisPose),
programRuntimeFeedback: state.programRuntimeFeedback,
currentTimingSegment,
currentLineExecution: state.programLineExecution?.[state.activeLine] || null,
currentLineExecutionVisible: Boolean(state.__activeUiLineExecutionText?.includes("F ") && state.__activeUiLineExecutionText?.includes("cycle")),
feedbackHistoryLength: state.programRuntimeFeedbackHistory?.length || 0,
taskHalStatusLoop: state.taskHalStatusLoop,
taskHalStatus: state.taskHalStatus ? {
@@ -316,7 +331,12 @@ async function waitForCanvasReady(timeoutMs = 20000) {
async function getStateWithUi() {
return page.evaluate(() => {
const state = JSON.parse(JSON.stringify(window.webRtcp5AxisSimulation.getState()));
state.__activeUiLine = Number(document.querySelector(".gcode-row.active")?.dataset.programLine || 0);
const activeRow = document.querySelector(".gcode-row.active");
state.__activeUiLine = Number(activeRow?.dataset.programLine || 0);
state.__activeUiLineExecutionText = activeRow?.querySelector("[data-line-execution]")?.textContent || "";
state.loadedSourceBytes = state.machineFileStaging?.save?.files
?.find((file) => file.sourceRel === state.machineFileStaging?.selectedGcodeSourceRel)
?.bytes || null;
return state;
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@@ -0,0 +1,345 @@
{
"generatedAt": "2026-06-23T07:51:30.866Z",
"target": "https://82.156.24.101:8092/",
"steps": [
{
"name": "01-ready",
"screenshot": "/home/meswork/cnc_wams/qa/web-rtcp-5axis-site-test/output/cloud-run-stop-after-deploy/01-ready.png",
"state": {
"runState": "idle",
"activeLine": 1,
"machine": {
"powerOn": true,
"estopActive": false,
"taskState": "on",
"mode": "auto",
"interpState": "idle",
"interpResumeState": "idle",
"taskPaused": false,
"allHomed": true,
"noForceHoming": false,
"jogAxis": "x",
"jogIncrement": 1,
"mdiCommand": "G0 X0 Y0 Z0",
"mdiDistanceMode": "absolute",
"resetCount": 0
},
"rtcpState": "on",
"kinsType": "tcp-xyzac",
"message": "RUN ready: power on, homed, auto mode",
"loop": {
"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"
},
"feedback": {
"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
},
"history": 3,
"lineExecution": {
"status": "idle",
"source": "linuxcnc-task-motion-hal-wasm",
"line": 1,
"feed": 3600,
"requestedFeed": 3600,
"feedMode": null,
"axisPose": {
"x": 0,
"y": 0,
"z": 0,
"a": 0,
"b": 0,
"c": 0
},
"taskCycle": 4,
"servoCycle": 40,
"sampleIndex": 40,
"motionIndex": 0,
"updatedAt": "2026-06-23T07:51:07.542Z"
},
"source": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc"
},
"ui": {
"activeUiLine": 1,
"lineText": "idle | F 3600.0 | X 0.000 | Y 0.000 | Z 0.000 | A 0.000 | C 0.000 | cycle 4/40",
"stopExists": true
}
},
{
"name": "02-running",
"screenshot": "/home/meswork/cnc_wams/qa/web-rtcp-5axis-site-test/output/cloud-run-stop-after-deploy/02-running.png",
"state": {
"runState": "running",
"activeLine": 9,
"machine": {
"powerOn": true,
"estopActive": false,
"taskState": "on",
"mode": "auto",
"interpState": "reading",
"interpResumeState": "reading",
"taskPaused": false,
"allHomed": true,
"noForceHoming": false,
"jogAxis": "x",
"jogIncrement": 1,
"mdiCommand": "G0 X0 Y0 Z0",
"mdiDistanceMode": "absolute",
"resetCount": 0
},
"rtcpState": "on",
"kinsType": "tcp-xyzac",
"message": "task/HAL status tick 5",
"loop": {
"apiName": "web-rtcp-5axis-task-hal-status-loop",
"active": true,
"sequence": 1,
"profileId": "xyzac-trt",
"iniPath": "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"kinematicsModuleId": "xyzac-trt",
"tickCount": 5,
"batchSize": 5,
"intervalMs": 25,
"taskPeriodNs": 10000000,
"servoPeriodNs": 1000000,
"lastStatusAt": "2026-06-23T07:51:21.038Z",
"lastError": null,
"stopReason": null,
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
},
"feedback": {
"apiName": "web-rtcp-5axis-program-runtime-feedback",
"sourceMode": "linuxcnc-task-motion-hal-wasm",
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
"sampleIndex": 340,
"motionIndex": 8,
"line": 9,
"motionProgramLine": 9,
"halProgramLine": 9,
"activeLineSource": "motion-status",
"activeLineHalSynced": true,
"type": "TASK_MOTION",
"timeSeconds": 0,
"axisPose": {
"x": 10.4843,
"y": -17.3304,
"z": 30.0805,
"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": 340,
"taskCycle": 34,
"halChangedPinCount": 0
},
"history": 5,
"lineExecution": {
"status": "running",
"source": "linuxcnc-task-motion-hal-wasm",
"line": 9,
"feed": 2100,
"requestedFeed": 2100,
"feedMode": null,
"axisPose": {
"x": 10.4843,
"y": -17.3304,
"z": 30.0805,
"a": -71.841,
"b": 0,
"c": -35.93
},
"taskCycle": 34,
"servoCycle": 340,
"sampleIndex": 340,
"motionIndex": 8,
"updatedAt": "2026-06-23T07:51:21.038Z"
},
"source": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc"
},
"ui": {
"activeUiLine": 9,
"lineText": "running | F 2100.0 | X 10.484 | Y -17.330 | Z 30.081 | A -71.841 | C -35.930 | cycle 34/340",
"stopExists": true
}
},
{
"name": "03-stopped",
"screenshot": "/home/meswork/cnc_wams/qa/web-rtcp-5axis-site-test/output/cloud-run-stop-after-deploy/03-stopped.png",
"state": {
"runState": "stopped",
"activeLine": 9,
"machine": {
"powerOn": true,
"estopActive": false,
"taskState": "on",
"mode": "auto",
"interpState": "idle",
"interpResumeState": "idle",
"taskPaused": false,
"allHomed": true,
"noForceHoming": false,
"jogAxis": "x",
"jogIncrement": 1,
"mdiCommand": "G0 X0 Y0 Z0",
"mdiDistanceMode": "absolute",
"resetCount": 0
},
"rtcpState": "on",
"kinsType": "tcp-xyzac",
"message": "task/HAL program stopped",
"loop": {
"apiName": "web-rtcp-5axis-task-hal-status-loop",
"active": false,
"sequence": 1,
"profileId": "xyzac-trt",
"iniPath": "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"kinematicsModuleId": "xyzac-trt",
"tickCount": 7,
"batchSize": 5,
"intervalMs": 25,
"taskPeriodNs": 10000000,
"servoPeriodNs": 1000000,
"lastStatusAt": "2026-06-23T07:51:24.831Z",
"lastError": null,
"stopReason": "running",
"semanticBoundary": "js_status_polling_loop_for_linuxcnc_task_hal_motion_status"
},
"feedback": {
"apiName": "web-rtcp-5axis-program-runtime-feedback",
"sourceMode": "linuxcnc-task-motion-hal-wasm",
"semanticBoundary": "linuxcnc_task_motion_hal_wasm_simulation_runtime",
"sampleIndex": 500,
"motionIndex": 8,
"line": 9,
"motionProgramLine": 9,
"halProgramLine": 9,
"activeLineSource": "motion-status",
"activeLineHalSynced": true,
"type": "TASK_MOTION",
"timeSeconds": 0,
"axisPose": {
"x": 7.55697,
"y": -13.2911,
"z": 28.4442,
"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": 500,
"taskCycle": 50,
"halChangedPinCount": 0
},
"history": 9,
"lineExecution": {
"status": "stopped",
"source": "linuxcnc-task-motion-hal-wasm",
"line": 9,
"feed": 2100,
"requestedFeed": 2100,
"feedMode": null,
"axisPose": {
"x": 7.55697,
"y": -13.2911,
"z": 28.4442,
"a": -71.841,
"b": 0,
"c": -35.93
},
"taskCycle": 50,
"servoCycle": 500,
"sampleIndex": 500,
"motionIndex": 8,
"updatedAt": "2026-06-23T07:51:26.643Z"
},
"source": "configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc"
},
"ui": {
"activeUiLine": 9,
"lineText": "stopped | F 2100.0 | X 7.557 | Y -13.291 | Z 28.444 | A -71.841 | C -35.930 | cycle 50/500",
"stopExists": true
}
}
],
"logs": [
{
"type": "warn",
"text": "[.WebGL-0x35b4000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
},
{
"type": "warn",
"text": "[.WebGL-0x35b4000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
},
{
"type": "warn",
"text": "[.WebGL-0x35b4000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
},
{
"type": "warn",
"text": "[.WebGL-0x35b4000f0200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 277 KiB