Files
linuxcncWebWASM/web/worker/test_authoritative_kinematics_s6.mjs

66 lines
3.6 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import createModule from "../../build-wasm/linuxcnc-sim-core.js";
import { compareEndpoints, createEndpoint, endpointHash } from "./endpoint-replay.mjs";
import { SimSession, CONTEXT_ID } from "./sim-session.mjs";
const wasmBinary = await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url));
async function runCorexy(id, fast) {
const core = await createModule({ wasmBinary });
const session = new SimSession(core, { sessionId: id });
const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: id };
let seq = 0;
const send = (kind, operation_id, payload = {}) => {
seq += 1;
const response = session.accept({ ...base, kind, seq, operation_id, payload });
assert.notEqual(response.kind, "ERROR", `${id}:${kind}:${response.payload?.code ?? "error"}`);
return response;
};
send("HELLO", "hello");
send("SESSION_ATTACH", "attach");
const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", kinematics: "corexy" });
assert.equal(loaded.payload.task.state, "READY");
send("PROGRAM_LOAD", "program", { source: "G0 X4 Y2 Z3\nM2\n", path: "corexy.ngc" });
send("PROGRAM_RUN", "run");
if (fast) send("SIM_STEP", "fast", { cycles: 8 });
else for (let index = 0; index < 8; index += 1) send("SIM_STEP", `step-${index}`, { cycles: 1 });
const endpoint = createEndpoint({ session });
assert.equal(endpoint.authoritative.kinematics.type, "corexy");
assert.deepEqual(endpoint.authoritative.kinematics.joints, [6, 2, 3]);
const checkpoint = session.createCheckpoint();
send("SIM_STEP", "post-checkpoint", { cycles: 1 });
const continuous = createEndpoint({ session });
const recovery = session.restoreCheckpoint(checkpoint, session.timeline.export(), (operation) => operation);
assert.equal(recovery.status, "recovered");
const restored = createEndpoint({ session });
const recoveryParity = compareEndpoints(continuous, restored);
assert.equal(recoveryParity.equal, true, JSON.stringify(recoveryParity));
return { endpoint, recoveryParity, checkpoint, kinematics: endpoint.authoritative.kinematics };
}
const oneX = await runCorexy("authoritative-corexy-1x", false);
const fast = await runCorexy("authoritative-corexy-fast", true);
const modeParity = compareEndpoints(oneX.endpoint, fast.endpoint);
assert.equal(modeParity.equal, true);
const core = await createModule({ wasmBinary });
const unsupported = new SimSession(core, { sessionId: "authoritative-unsupported" });
const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: "authoritative-unsupported" };
unsupported.accept({ ...base, kind: "HELLO", seq: 1, operation_id: "hello" });
unsupported.accept({ ...base, kind: "SESSION_ATTACH", seq: 2, operation_id: "attach" });
const unsupportedResult = unsupported.accept({ ...base, kind: "LOAD_WORKSPACE", seq: 3, operation_id: "unsupported", payload: { root_path: "/workspace", kinematics: "puma" } });
assert.equal(unsupportedResult.kind, "ERROR");
assert.equal(unsupportedResult.payload.code, "authoritative_kinematics_unsupported");
console.log(JSON.stringify({
schema: "authoritative-kinematics-s6-sample.v1",
status: "verified",
context_id: CONTEXT_ID,
supported: { type: "corexy", pose: [4, 2, 3], joints: oneX.kinematics.joints, endpoint_hash: endpointHash(oneX.endpoint) },
parity: { mode: modeParity, recovery: oneX.recoveryParity },
checkpoint_hash: oneX.checkpoint.checkpoint_hash,
unsupported: { type: "puma", code: unsupportedResult.payload.code },
boundaries: ["other non-trivkins families remain queued for later slices", "official LinuxCNC kinematics oracle remains SOURCE_BLOCKED"],
}));