61 lines
2.8 KiB
JavaScript
61 lines
2.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { ReplayTimeline } from "./replay.mjs";
|
|
import { VirtualDevices } from "./virtual-devices.mjs";
|
|
|
|
const commands = [
|
|
["SPINDLE_COMMAND", { spindle: 0, rpm: 1200, enabled: true }],
|
|
["IO_STEP", { ticks: 20 }],
|
|
["TOOL_PREPARE", { tool: 7, pocket: 3 }],
|
|
["TOOL_PREPARED", { prepared: true }],
|
|
["TOOL_CHANGE", {}],
|
|
["SPINDLE_COMMAND", { spindle: 0, rpm: 0, enabled: false }],
|
|
["IO_STEP", { ticks: 20 }],
|
|
["TOOL_CHANGE", {}],
|
|
["TOOL_CHANGED", { changed: true }],
|
|
["TOOL_ABORT", { reason: 17 }],
|
|
["TOOL_PREPARE", { tool: 7, pocket: 3 }],
|
|
["TOOL_PREPARED", { prepared: true }],
|
|
["TOOL_CHANGE", {}],
|
|
["TOOL_CHANGED", { changed: true }],
|
|
["PROBE_CONFIG", { action: "arm", probe_type: 0 }],
|
|
["PROBE_CONFIG", { action: "update", input: true, position: { x: 1, y: 2, z: 3 } }],
|
|
["LIMIT_SET", { name: "x-positive", active: true }],
|
|
["TOOL_FAULT", { fault: true, reason: 42 }],
|
|
["TOOL_CLEAR_FAULT", {}],
|
|
["TOOL_FAULT", { fault: false, reason: 0 }],
|
|
["TOOL_CLEAR_FAULT", {}],
|
|
["ESTOP", { active: true }],
|
|
["SPINDLE_COMMAND", { spindle: 0, rpm: 100, enabled: true }],
|
|
["ESTOP", { active: false }],
|
|
["IO_RECOVER", {}],
|
|
];
|
|
|
|
function run() {
|
|
const devices = new VirtualDevices();
|
|
const timeline = new ReplayTimeline();
|
|
const scenarios = [];
|
|
let seq = 0;
|
|
const nonfinite = devices.command("SPINDLE_COMMAND", { spindle: 0, rpm: Number.NaN, enabled: true });
|
|
scenarios.push({ kind: "NONFINITE_INPUT", code: nonfinite.code, status: nonfinite.status, state_hash: nonfinite.state_hash });
|
|
for (const [kind, payload] of commands) {
|
|
seq += 1;
|
|
const result = devices.command(kind, payload);
|
|
timeline.appendEvent(seq, devices.state.tick, kind, payload);
|
|
scenarios.push({ kind, code: result.code, status: result.status, state_hash: result.state_hash });
|
|
}
|
|
const replay = new VirtualDevices();
|
|
for (const event of timeline.events.events) replay.applyEvent(event.kind, event.payload);
|
|
return { schema: "virtual-device-fault-sample.v1", scenarios, events: timeline.events.cursor, state_hash: devices.hash(), replay_state_hash: replay.hash(), state_hash_equal: devices.hash() === replay.hash(), final: devices.export() };
|
|
}
|
|
|
|
const first = run();
|
|
const second = run();
|
|
assert.equal(first.state_hash_equal, true);
|
|
assert.equal(first.state_hash, first.replay_state_hash);
|
|
assert.deepEqual(first, second);
|
|
assert.equal(first.scenarios.find((row) => row.kind === "TOOL_CHANGE" && row.code === "sim_io_busy")?.status, "blocked");
|
|
assert.equal(first.scenarios.find((row) => row.kind === "SPINDLE_COMMAND" && row.code === "sim_io_estop")?.status, "blocked");
|
|
assert.equal(first.scenarios.find((row) => row.kind === "TOOL_CLEAR_FAULT" && row.code === "sim_io_fault")?.status, "blocked");
|
|
assert.equal(first.scenarios.find((row) => row.kind === "NONFINITE_INPUT")?.code, "sim_io_nonfinite");
|
|
console.log(JSON.stringify(first));
|