Files
cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/app/dist/src/runtime/linuxcnc-kinematics-runtime.js
2026-07-02 20:25:37 -04:00

145 lines
4.3 KiB
JavaScript

const DEFAULT_MODULE_ID = "xyzbc-trt";
const DEFAULT_JOINT_COUNT = 5;
const SOURCE_MODE = "source-derived-kinematics-wasm";
const SEMANTIC_BOUNDARY = "linuxcnc_kinematics_wasm_c_abi";
const DEFAULT_SDK_MODULE_URL = "../../../../wasm-port/runtime/sdk/src/linuxcnc-kinematics.js";
export async function createLinuxCncKinematicsRuntime({
moduleId = DEFAULT_MODULE_ID,
moduleOptions = null,
switchkinsType = 0,
jointCount = DEFAULT_JOINT_COUNT,
wasmRoot = null,
sdkModuleUrl = DEFAULT_SDK_MODULE_URL,
} = {}) {
const {
createLinuxCncKinematicsSdk,
linuxCncKinematicsWasmFile,
supportedLinuxCncKinematicsModules,
} = await import(sdkModuleUrl);
const wasmFile = linuxCncKinematicsWasmFile(moduleId);
if (!wasmFile) {
throw new Error(`unsupported LinuxCNC kinematics module: ${moduleId}`);
}
const resolvedModuleOptions = moduleOptions || await createDefaultModuleOptions({ wasmRoot, wasmFile });
const sdk = await createLinuxCncKinematicsSdk({ moduleId, moduleOptions: resolvedModuleOptions });
let activeSwitchkinsType = switchkinsType;
let activeSwitchRc = typeof sdk.switchKinematics === "function"
? sdk.switchKinematics(switchkinsType)
: 0;
return {
apiName: "web-rtcp-5axis-linuxcnc-kinematics-runtime",
moduleId,
wasmFile,
supportedModules: supportedLinuxCncKinematicsModules(),
loaded: true,
sourceMode: SOURCE_MODE,
semanticBoundary: SEMANTIC_BOUNDARY,
executionContext: "direct",
get switchkinsType() {
return activeSwitchkinsType;
},
get switchRc() {
return activeSwitchRc;
},
jointCount,
sdk,
readiness() {
return {
apiName: "web-rtcp-5axis-linuxcnc-kinematics-runtime-readiness",
moduleId,
wasmFile,
supportedModules: supportedLinuxCncKinematicsModules(),
loaded: true,
sourceMode: SOURCE_MODE,
semanticBoundary: SEMANTIC_BOUNDARY,
executionContext: "direct",
switchkinsType: activeSwitchkinsType,
switchRc: activeSwitchRc,
};
},
switchKinematics(nextSwitchkinsType) {
const requestedType = Number(nextSwitchkinsType) || 0;
activeSwitchRc = typeof sdk.switchKinematics === "function"
? sdk.switchKinematics(requestedType)
: 0;
activeSwitchkinsType = requestedType;
return activeSwitchRc;
},
forward(joints, options = {}) {
return sdk.forward(joints, options);
},
inverse(pose, count = jointCount, options = {}) {
return sdk.inverse(pose, count, options);
},
frameForJoints(joints, options = {}) {
const jointValues = Array.from(joints, Number);
const forward = sdk.forward(jointValues, options.forwardOptions || {});
const inverse = sdk.inverse(
forward.pose,
options.jointCount || jointCount,
{ seedJoints: jointValues, ...(options.inverseOptions || {}) },
);
return {
moduleId,
switchkinsType: activeSwitchkinsType,
forward,
inverse,
};
},
};
}
async function createDefaultModuleOptions({ wasmRoot, wasmFile }) {
const quietOptions = {
print() {},
printErr() {},
};
if (!isNodeRuntime()) {
return quietOptions;
}
const [{ readFileSync }, { dirname, resolve }, { fileURLToPath }] = await Promise.all([
import("node:fs"),
import("node:path"),
import("node:url"),
]);
const moduleDir = dirname(fileURLToPath(import.meta.url));
const resolvedWasmRoot = wasmRoot || resolve(moduleDir, "../../../../wasm-port/build/wasm/kinematics");
return {
...quietOptions,
wasmBinary: readFileSync(resolve(resolvedWasmRoot, wasmFile)),
};
}
function isNodeRuntime() {
return typeof process === "object"
&& typeof process.versions === "object"
&& typeof process.versions.node === "string"
&& process.type !== "renderer";
}
export function createLinuxCncKinematicsRuntimeDescriptor(runtime) {
if (!runtime?.loaded) return null;
return {
apiName: runtime.apiName,
moduleId: runtime.moduleId,
wasmFile: runtime.wasmFile,
supportedModules: runtime.supportedModules,
loaded: runtime.loaded,
sourceMode: runtime.sourceMode,
semanticBoundary: runtime.semanticBoundary,
executionContext: runtime.executionContext || "direct",
workerUrl: runtime.workerUrl || null,
switchkinsType: runtime.switchkinsType,
switchRc: runtime.switchRc,
};
}