127 lines
4.8 KiB
JavaScript
127 lines
4.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
|
|
import { getFiveAxisProfile } from "../../app/src/profiles/index.js";
|
|
import { createLinuxCncKinematicsRuntime } from "../../app/src/runtime/linuxcnc-kinematics-runtime.js";
|
|
import { buildRtcpFrame } from "../../app/src/runtime/rtcp-frame.js";
|
|
|
|
const DEG_TO_RAD = Math.PI / 180;
|
|
|
|
const cases = [
|
|
{
|
|
moduleId: "xyzac-trt",
|
|
wasmFile: "linuxcnc_xyzac_trt_kinematics.wasm",
|
|
joints: [10, 20, 30, 25, 40],
|
|
fourthAxis: "A",
|
|
fourthKey: "a",
|
|
axisPose: { x: 10, y: 20, z: 30, a: 25, b: 0, c: 40 },
|
|
kinsType: "tcp-xyzac",
|
|
expectedToolAxis: xyzacToolAxis(25, 40),
|
|
},
|
|
{
|
|
moduleId: "xyzbc-trt",
|
|
wasmFile: "linuxcnc_xyzbc_trt_kinematics.wasm",
|
|
joints: [10, 20, 30, 35, 40],
|
|
fourthAxis: "B",
|
|
fourthKey: "b",
|
|
axisPose: { x: 10, y: 20, z: 30, a: 0, b: 35, c: 40 },
|
|
kinsType: "tcp-xyzbc",
|
|
expectedToolAxis: xyzbcToolAxis(35, 40),
|
|
},
|
|
];
|
|
|
|
for (const testCase of cases) {
|
|
const runtime = await createLinuxCncKinematicsRuntime({
|
|
moduleId: testCase.moduleId,
|
|
switchkinsType: 1,
|
|
});
|
|
const readiness = runtime.readiness();
|
|
|
|
assert.equal(runtime.apiName, "web-rtcp-5axis-linuxcnc-kinematics-runtime");
|
|
assert.equal(runtime.moduleId, testCase.moduleId);
|
|
assert.equal(runtime.loaded, true);
|
|
assert.equal(runtime.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(runtime.semanticBoundary, "linuxcnc_kinematics_wasm_c_abi");
|
|
assert.equal(runtime.executionContext, "direct");
|
|
assert.equal(runtime.wasmFile, testCase.wasmFile);
|
|
assert.equal(runtime.switchkinsType, 1);
|
|
assert.equal(readiness.loaded, true);
|
|
assert.equal(readiness.executionContext, "direct");
|
|
assert.equal(readiness.supportedModules.includes("xyzac-trt"), true);
|
|
assert.equal(readiness.supportedModules.includes("xyzbc-trt"), true);
|
|
assert.equal(runtime.switchRc, 0);
|
|
|
|
const linuxCncKinematicsResult = runtime.frameForJoints(testCase.joints);
|
|
assert.equal(linuxCncKinematicsResult.moduleId, testCase.moduleId);
|
|
assert.equal(linuxCncKinematicsResult.switchkinsType, 1);
|
|
assert.equal(linuxCncKinematicsResult.forward.rc, 0);
|
|
assert.equal(linuxCncKinematicsResult.inverse.rc, 0);
|
|
assert.deepEqual(roundJoints(linuxCncKinematicsResult.inverse.joints), testCase.joints);
|
|
|
|
const frame = buildRtcpFrame({
|
|
axisPose: testCase.axisPose,
|
|
activeLine: 777,
|
|
kinsType: testCase.kinsType,
|
|
rtcpEnabled: true,
|
|
profile: getFiveAxisProfile(testCase.moduleId),
|
|
linuxCncKinematicsResult,
|
|
});
|
|
|
|
assert.equal(frame.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(frame.semanticBoundary, "linuxcnc_kinematics_wasm_c_abi");
|
|
assert.equal(frame.readiness.linuxCncKinematicsReady, true);
|
|
assert.equal(frame.readiness.promotionAllowed, true);
|
|
assert.equal(frame.readiness.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(frame.profileId, testCase.moduleId);
|
|
assert.equal(frame.kinematicsModuleId, testCase.moduleId);
|
|
assert.equal(frame.kinematicsSwitchkinsType, 1);
|
|
assert.equal(frame.kinematicsForwardRc, 0);
|
|
assert.equal(frame.kinematicsInverseRc, 0);
|
|
assert.equal(frame.jointPose[3].axis, testCase.fourthAxis);
|
|
assert.equal(frame.jointPose[3].value, testCase.joints[3]);
|
|
assert.equal(frame.jointPose[4].axis, "C");
|
|
assert.equal(frame.jointPose[4].value, testCase.joints[4]);
|
|
assert.equal(frame.tcpPose.x, linuxCncKinematicsResult.forward.pose.x);
|
|
assert.equal(frame.tcpPose.y, linuxCncKinematicsResult.forward.pose.y);
|
|
assert.equal(frame.tcpPose.z, linuxCncKinematicsResult.forward.pose.z);
|
|
assert.equal(frame.tcpPose.a, linuxCncKinematicsResult.forward.pose.a);
|
|
assert.equal(frame.tcpPose.b, linuxCncKinematicsResult.forward.pose.b);
|
|
assert.equal(frame.tcpPose.c, linuxCncKinematicsResult.forward.pose.c);
|
|
assert.equal(frame.tcpPose[testCase.fourthKey], testCase.axisPose[testCase.fourthKey]);
|
|
assertVectorNear(frame.toolAxisVector, testCase.expectedToolAxis);
|
|
|
|
console.log(`${testCase.moduleId.replace(/-/g, "_")}_kinematics_runtime=ok`);
|
|
}
|
|
|
|
console.log("linuxcnc_kinematics_runtime_smoke=ok");
|
|
console.log("xyzbc_b_axis_tcp_pose_preserved=1");
|
|
|
|
function roundJoints(joints) {
|
|
return joints.map((value) => Math.round(value * 1e6) / 1e6);
|
|
}
|
|
|
|
function xyzacToolAxis(aDegrees, cDegrees) {
|
|
const tilt = aDegrees * DEG_TO_RAD;
|
|
const c = cDegrees * DEG_TO_RAD;
|
|
return {
|
|
x: Math.sin(tilt) * Math.sin(c),
|
|
y: -Math.sin(tilt) * Math.cos(c),
|
|
z: Math.cos(tilt),
|
|
};
|
|
}
|
|
|
|
function xyzbcToolAxis(bDegrees, cDegrees) {
|
|
const tilt = bDegrees * DEG_TO_RAD;
|
|
const c = cDegrees * DEG_TO_RAD;
|
|
return {
|
|
x: Math.sin(tilt) * Math.cos(c),
|
|
y: Math.sin(tilt) * Math.sin(c),
|
|
z: Math.cos(tilt),
|
|
};
|
|
}
|
|
|
|
function assertVectorNear(actual, expected, tolerance = 1e-12) {
|
|
assert.ok(Math.abs(actual.x - expected.x) < tolerance);
|
|
assert.ok(Math.abs(actual.y - expected.y) < tolerance);
|
|
assert.ok(Math.abs(actual.z - expected.z) < tolerance);
|
|
}
|