Align pause resume and abort lifecycle
This commit is contained in:
@@ -1862,7 +1862,7 @@ export class SimSession {
|
||||
if (this.xyzacProgram) {
|
||||
const result = this.xyzacProgram.start();
|
||||
if (result.status === "verified") { this.wasmMotion.setPaused(false); this.task.setMode("AUTO"); if (this.task.state.state === "STOPPED") this.task.recover(); this.task.transition("RUNNING"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("running", program.execution_source_line ?? program.current_line); }
|
||||
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
|
||||
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), wasm_motion: this.wasmMotion.read(), motion: this.wasmMotionProjection(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
|
||||
}
|
||||
const result = this.program.start();
|
||||
if (result.status === "verified") {
|
||||
@@ -1885,30 +1885,40 @@ export class SimSession {
|
||||
case "PROGRAM_PAUSE": case "PROGRAM_RESUME": case "PROGRAM_ABORT": {
|
||||
const action = input.kind === "PROGRAM_PAUSE" ? "pause" : input.kind === "PROGRAM_RESUME" ? "resume" : "abort";
|
||||
if (this.xyzacProgram) {
|
||||
this.pendingXyzacMotion = null;
|
||||
this.pendingProgramControl = 0;
|
||||
this.pendingTaskSync = 0;
|
||||
this.pendingServoSync = 0;
|
||||
this.xyzacExecutionWaitNextMotion = false;
|
||||
this.xyzacExecutionWaitSamples = 0;
|
||||
this.xyzacLastEnqueuedKinematicsMode = 0;
|
||||
this.xyzacDeferredPhysicalSwitchMode = null;
|
||||
this.xyzacDeferredBlockedActiveId = 0;
|
||||
this.xyzacDeferredControlMotionType = 0;
|
||||
this.xyzacQueuedLookaheadTargetId = 0;
|
||||
this.xyzacAllowQueuedLookahead = false;
|
||||
this.xyzacLastServoActiveId = 0;
|
||||
this.xyzacLastQueuedMotion = null;
|
||||
this.xyzacDeferredPhysicalPose = null;
|
||||
this.xyzacDeferredPhysicalPoseApplied = false;
|
||||
this.xyzacAppendDeferredOnActive = false;
|
||||
// PAUSE/RESUME are interpreter and TP state transitions. They must
|
||||
// preserve the pending canonical block and queued lookahead so a
|
||||
// resume continues the exact WASM trajectory. ABORT is the only
|
||||
// edge that clears the task/TP handoff state.
|
||||
if (action === "abort") {
|
||||
this.pendingXyzacMotion = null;
|
||||
this.pendingProgramControl = 0;
|
||||
this.pendingTaskSync = 0;
|
||||
this.pendingServoSync = 0;
|
||||
this.xyzacExecutionWaitNextMotion = false;
|
||||
this.xyzacExecutionWaitSamples = 0;
|
||||
this.xyzacLastEnqueuedKinematicsMode = 0;
|
||||
this.xyzacDeferredPhysicalSwitchMode = null;
|
||||
this.xyzacDeferredBlockedActiveId = 0;
|
||||
this.xyzacDeferredControlMotionType = 0;
|
||||
this.xyzacQueuedLookaheadTargetId = 0;
|
||||
this.xyzacAllowQueuedLookahead = false;
|
||||
this.xyzacLastServoActiveId = 0;
|
||||
this.xyzacLastQueuedMotion = null;
|
||||
this.xyzacDeferredPhysicalPose = null;
|
||||
this.xyzacDeferredPhysicalPoseApplied = false;
|
||||
this.xyzacAppendDeferredOnActive = false;
|
||||
}
|
||||
const result = this.xyzacProgram[action]();
|
||||
if (result.status === "verified") {
|
||||
if (action === "pause") { call(this.core, "sim_protocol_pause"); this.wasmMotion.setPaused(true); this.task.transition("PAUSED"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("paused", program.execution_source_line ?? program.current_line); }
|
||||
else if (action === "resume") { call(this.core, "sim_protocol_resume"); this.wasmMotion.setPaused(false); this.task.transition("RUNNING"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("running", program.execution_source_line ?? program.current_line); }
|
||||
// sim_protocol_accept has already applied the transport edge;
|
||||
// calling sim_protocol_pause/resume a second time would return a
|
||||
// false ERR_STATE. The LinuxCNC WASM TP remains authoritative for
|
||||
// the actual pause/resume motion transition.
|
||||
if (action === "pause") { this.wasmMotion.setPaused(true); this.task.transition("PAUSED"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("paused", program.execution_source_line ?? program.current_line); }
|
||||
else if (action === "resume") { this.wasmMotion.setPaused(false); this.task.transition("RUNNING"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("running", program.execution_source_line ?? program.current_line); }
|
||||
else { this.wasmMotion.abort(); this.task.transition("STOPPED"); const program = this.xyzacProgram.snapshot(); this.task.setProgram("aborted", program.execution_source_line ?? program.current_line); }
|
||||
}
|
||||
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
|
||||
return finish(this.envelope(result.status === "verified" ? "COMMAND_RESULT" : "ERROR", input, { ...result, program: this.xyzacProgram.snapshot(), task: this.task.export(), wasm_motion: this.wasmMotion.read(), motion: this.wasmMotionProjection(), motion_authority: "wasm", command: input.kind, operation_id: input.operation_id ?? null }), result.status === "verified" ? "verified" : "failed");
|
||||
}
|
||||
const result = this.program[action]();
|
||||
if (result.status === "verified") {
|
||||
|
||||
@@ -50,6 +50,13 @@ for (const [kind, payload, reason] of [["HOME", { all: true }, "xyzac_interp_run
|
||||
assert.equal(blocked.payload.gate_reason, reason, kind);
|
||||
}
|
||||
assert.equal(send("PROGRAM_PAUSE").payload.task.state, "PAUSED");
|
||||
const abortedWhilePaused = send("PROGRAM_ABORT");
|
||||
assert.equal(abortedWhilePaused.payload.task.state, "STOPPED");
|
||||
assert.equal(abortedWhilePaused.payload.task.program_status, "aborted");
|
||||
assert.equal(abortedWhilePaused.payload.wasm_motion.state.queue_depth, 0);
|
||||
assert.equal(send("PROGRAM_RESTART").payload.task.program_status, "loaded");
|
||||
assert.equal(send("PROGRAM_RUN").payload.task.state, "RUNNING");
|
||||
assert.equal(send("PROGRAM_PAUSE").payload.task.state, "PAUSED");
|
||||
assert.equal(send("PROGRAM_RESUME").payload.task.state, "RUNNING");
|
||||
assert.equal(send("POWER", { active: false }).payload.task.state, "STOPPED");
|
||||
assert.equal(send("POWER", { active: true }).payload.panel_snapshot.axis_state.machine_state, "ON");
|
||||
|
||||
Reference in New Issue
Block a user