Add AC/BC RTCP programs and 3D machine manager
This commit is contained in:
47
scripts/generate_rtcp_teaching_data.mjs
Normal file
47
scripts/generate_rtcp_teaching_data.mjs
Normal file
@@ -0,0 +1,47 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import { createHash } from 'node:crypto';
|
||||
import createModule from '../build-wasm/linuxcnc-sim-core.js';
|
||||
import { WasmXyzacKinematics } from '../web/worker/wasm-xyzac-kinematics.mjs';
|
||||
|
||||
const out = new URL('../docs/teaching/rtcp-five-axis/', import.meta.url);
|
||||
await mkdir(new URL('assets/', out), { recursive: true });
|
||||
const wasm = await readFile(new URL('../build-wasm/linuxcnc-sim-core.wasm', import.meta.url));
|
||||
const core = await createModule({ wasmBinary: wasm });
|
||||
const basePose = { x: 100, y: 0, z: 20, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 };
|
||||
const cases = [];
|
||||
const close = (a, b) => assert.ok(Math.abs(a - b) < 1e-9, `${a} != ${b}`);
|
||||
for (const coordinates of ['XYZAC', 'XYZBC']) {
|
||||
const k = new WasmXyzacKinematics(core, { coordinates, limits: Object.fromEntries([...coordinates.toLowerCase()].map((a) => [a, [-100000, 100000]])) });
|
||||
const samples = [];
|
||||
for (const [tilt, c] of [[0, 0], [0, 45], [0, 90], [30, 0], [30, 45], [30, 90]]) {
|
||||
const p = { ...basePose, c, [coordinates[3].toLowerCase()]: tilt };
|
||||
const ik = k.inverseMode(1, p); assert.equal(ik.status, 'verified');
|
||||
k.selectPhysical(1, ik.joints);
|
||||
const fk = k.forward(ik.joints); assert.equal(fk.status, 'verified');
|
||||
for (const axis of ['x', 'y', 'z']) close(fk.pose[axis], p[axis]);
|
||||
samples.push({ tilt, c, programmed: p, joints: ik.joints, forward: fk.pose });
|
||||
}
|
||||
close(samples[2].joints[0], 0); close(samples[2].joints[1], 100); close(samples[2].joints[2], 20);
|
||||
const direction = k.inverseMode(1, { ...basePose, c: 45, x: 110 }).joints.map((v, i) => v - samples[1].joints[i]);
|
||||
close(direction[0], 10 / Math.sqrt(2)); close(direction[1], 10 / Math.sqrt(2));
|
||||
cases.push({ coordinates, samples, xw_increment_10_at_c45: direction });
|
||||
k.destroy();
|
||||
}
|
||||
const offsets = { x_rot_point: -18, y_rot_point: 14, z_rot_point: 12, x_offset: 22, y_offset: 0, z_offset: -40, tool_offset: 0 };
|
||||
const k = new WasmXyzacKinematics(core, { coordinates: 'XYZBC', ...offsets, limits: Object.fromEntries(['x', 'y', 'z', 'b', 'c'].map((a) => [a, [-100000, 100000]])) });
|
||||
const physical = [0, 0, 44.5858, 4.8675, 179.88];
|
||||
const tcp = k.selectPhysical(1, physical); const tcpPose = { ...tcp.pose };
|
||||
const identity = k.selectPhysical(0, physical);
|
||||
physical.forEach((value, i) => { close(tcp.joints[i], value); close(identity.joints[i], value); });
|
||||
const report = {
|
||||
report_id: 'rtcp-teaching-numerics-v1', status: 'verified',
|
||||
wasm_sha256: createHash('sha256').update(wasm).digest('hex'),
|
||||
convention: 'Native AC: Rx(A) Rz(C); BC: Ry(B) Rz(C). Main teaching examples P=D=tool_offset=0, mm/deg.',
|
||||
cases,
|
||||
switch_example: { offsets, physical, tcp_pose: tcpPose, identity_pose: identity.pose },
|
||||
chord_midpoint: { compensated: [100 / Math.sqrt(2), 100 / Math.sqrt(2), 20], uncompensated_joint_interpolation: [50, 50, 20], distance: 100 - 50 * Math.sqrt(2) },
|
||||
};
|
||||
k.destroy();
|
||||
await writeFile(new URL('numeric-evidence.json', out), JSON.stringify(report, null, 2) + '\n');
|
||||
console.log(JSON.stringify({ report_id: report.report_id, status: report.status, poses: 12, fk_ik_roundtrips: 12, source: report.wasm_sha256 }));
|
||||
Reference in New Issue
Block a user