Align AXIS control flow and fix pause and program rendering

Document source UI gates, explicit native live-plot clearing, and remaining parity boundaries. Fix pause/resume transport continuity, repeated stepping, coordinate previews, and spindle override state. Optimize large program snapshots and rendering, and cover the control flows with native Tcl, WASM, and browser checks.

Validation: 22 native tests and source/browser checks pass. Worker/App regression: 113 of 123 pass; 10 pre-existing failures remain documented with no new failures.
This commit is contained in:
2026-09-08 10:46:27 +08:00
parent 845075f4a3
commit bade560372
55 changed files with 2495 additions and 286 deletions

View File

@@ -50,7 +50,7 @@ assert.equal(released.payload.status, "verified");
assert.equal(released.payload.device_io.state.estop, 0);
assert.equal(released.payload.device_io.state.ready, 0);
assert.equal(released.payload.task.state, "STOPPED");
assert.equal(released.payload.panel_snapshot.axis_state.machine_state, "ESTOP_RESET");
assert.equal(released.payload.panel_snapshot.axis_state.source_task_state, "STATE_ESTOP_RESET");
const powered = send("POWER", { active: true });
assert.equal(powered.payload.status, "verified");
@@ -97,9 +97,16 @@ const restarted = send("PROGRAM_RESTART");
assert.equal(restarted.payload.status, "verified");
const fullRun = send("PROGRAM_RUN");
assert.equal(fullRun.payload.task.state, "RUNNING");
const completed = send("SIM_STEP", { cycles: 8000 });
let completed = send("SIM_STEP", { cycles: 8000 });
assert.equal(completed.payload.status, "verified");
assert.equal(completed.payload.program.program_status, "completed");
// M2 closes the interpreter before the last trajectory segment drains.
let drainTicks = 0;
for (; drainTicks < 100 && completed.payload.wasm_motion.state.queue_depth > 0; drainTicks += 1) {
assert.equal(completed.payload.panel_snapshot.gates.run.enabled, false);
completed = send("SIM_STEP", { cycles: 1 });
assert.equal(completed.payload.status, "verified");
}
assert.equal(completed.payload.task.state, "STOPPED");
assert.equal(completed.payload.wasm_motion.state.queue_depth, 0);
assert.equal((completed.payload.panel_snapshot.visual.toolpath ?? loaded.payload.panel_snapshot.visual.toolpath).length, 29);
@@ -120,7 +127,7 @@ console.log(JSON.stringify({
active_progress: stepped.payload.panel_snapshot.visual.active_progress,
rtcp_active_type: stepped.payload.panel_snapshot.kinematics.active_type,
rtcp_joint_pose_delta: stepped.payload.panel_snapshot.kinematics.joints.map((value, index) => value - [stepped.payload.panel_snapshot.visual.pose.x, stepped.payload.panel_snapshot.visual.pose.y, stepped.payload.panel_snapshot.visual.pose.z, stepped.payload.panel_snapshot.visual.pose.a, stepped.payload.panel_snapshot.visual.pose.c][index]),
full_run: { cycles: 8000, program_status: completed.payload.program.program_status, task_state: completed.payload.task.state, queue_depth: completed.payload.wasm_motion.state.queue_depth, final_switchkins_type: completed.payload.panel_snapshot.kinematics.active_type },
full_run: { cycles: 8000 + drainTicks, drain_ticks: drainTicks, program_status: completed.payload.program.program_status, task_state: completed.payload.task.state, queue_depth: completed.payload.wasm_motion.state.queue_depth, final_switchkins_type: completed.payload.panel_snapshot.kinematics.active_type },
js_motion_unchanged: session.motion.export().state_hash === jsMotionHash,
state_hash: stepped.payload.panel_snapshot.state_hash,
}));