Make machine configuration authoritative and restore native checkpoints exactly
This commit is contained in:
@@ -3,7 +3,10 @@ import { runtimeResourceFixture } from "./resource-resolver.mjs";
|
||||
import { SIM_CASE_CATALOG, SIM_FILE_INDEX, SIM_HAL_COMPONENTS } from "./sim-case-catalog.mjs";
|
||||
import { isOptionalSourceKey } from "./linuxcnc-source-semantics.mjs";
|
||||
import { MACHINE_DEFINITIONS, machineDefinition } from "./machine-definitions.mjs";
|
||||
import { readTrtGeometry } from "./trt-geometry.mjs";
|
||||
import resources from "./simulation-resources.json" with { type: "json" };
|
||||
import { parseIni } from "./ini-parser.mjs";
|
||||
import { WorkspaceRuntime } from "./runtime.mjs";
|
||||
import { readTrtConfiguration } from "./trt-configuration.mjs";
|
||||
|
||||
export const SIMULATION_CASE_SCHEMA = "simulation-case-bundle.v1";
|
||||
const RESOURCE_KEYS = new Set([
|
||||
@@ -12,53 +15,9 @@ const RESOURCE_KEYS = new Set([
|
||||
"PYVCP", "NGCGUI_SUBFILE", "INTRO_GRAPHIC", "SUBROUTINE_PATH", "REMAP",
|
||||
]);
|
||||
const MANIFEST = new Set(SIM_FILE_INDEX);
|
||||
const PRELOADED_HAL_COMPONENTS = Object.freeze(["corexykins", "lineardeltakins", "motmod", "pid", "rotarydeltakins", "stepgen", "trivkins", "xyzac-trt-kins", "xyzbc-trt-kins", "tpmod", "homemod"]);
|
||||
const CASE_KINEMATICS = Object.freeze({
|
||||
"linuxcnc/configs/sim/axis/corexy/corexy_by_kins.ini": Object.freeze({ type: "corexy", path_mode: "kins" }),
|
||||
"linuxcnc/configs/sim/axis/corexy/corexy_by_hal.ini": Object.freeze({ type: "corexy", path_mode: "hal" }),
|
||||
"linuxcnc/configs/sim/axis/ldelta.ini": Object.freeze({ type: "lineardelta", path_mode: "kins" }),
|
||||
"linuxcnc/configs/sim/axis/rdelta.ini": Object.freeze({ type: "rotarydelta", path_mode: "kins" }),
|
||||
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini": Object.freeze({ type: "xyzac-trt", path_mode: "wasm", coordinates: "XYZAC", joint_count: 5, max_linear_velocity: 35, axis_linear_velocity_limit: 20, max_acceleration: 300, max_jerk: 1000000000, servo_cycle_time: 0.001, task_cycle_time: 0.01, cycle_time: 0.001, switchkins: { 0: "identity", 1: "xyzac", 2: "userk" } }),
|
||||
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini": Object.freeze({ type: "xyzbc-trt", path_mode: "wasm", coordinates: "XYZBC", joint_count: 5, max_linear_velocity: 35, axis_linear_velocity_limit: 20, axis_angular_velocity_limit: 30, max_acceleration: 300, max_jerk: 1000000000, servo_cycle_time: 0.001, task_cycle_time: 0.01, cycle_time: 0.001, switchkins: { 0: "identity", 1: "xyzbc", 2: "userk" } }),
|
||||
});
|
||||
const RUNTIME_FIXTURES = Object.freeze({
|
||||
"linuxcnc/configs/sim/axis/minimal_xyz.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/minimal_xyz_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = minimal_xyz_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated HAL command fixture",
|
||||
}),
|
||||
"linuxcnc/configs/sim/axis/ja_tests/xz/xz.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/ja_tests/xz/xz_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = xz_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated XZ HAL command fixture",
|
||||
}),
|
||||
"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = xz_both_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated XZ BOTH HAL command fixture",
|
||||
}),
|
||||
"linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/ja_tests/xz/xz_both_auto_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = xz_both_auto_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated XZ BOTH AUTO HAL command fixture",
|
||||
}),
|
||||
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt-headless_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = xyzac-trt-headless_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated XYZAC HAL command fixture",
|
||||
}),
|
||||
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini": Object.freeze({
|
||||
generated_hal: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt_cmds.hal",
|
||||
replace: "HALFILE = LIB:basic_sim.tcl",
|
||||
with: "HALFILE = xyzbc-trt_cmds.hal",
|
||||
reason: "LinuxCNC basic_sim.tcl generated XYZBC HAL command fixture",
|
||||
}),
|
||||
});
|
||||
const PRELOADED_HAL_COMPONENTS = Object.freeze(resources.preloaded_hal_components);
|
||||
const CASE_KINEMATICS = Object.freeze(resources.kinematics);
|
||||
const RUNTIME_FIXTURES = Object.freeze(resources.runtime_fixtures);
|
||||
|
||||
function clone(value) { return structuredClone(value); }
|
||||
function text(value) { return typeof value === "string" && value.trim() ? value.trim() : null; }
|
||||
@@ -180,7 +139,8 @@ function resourceReferences(source, content) {
|
||||
}
|
||||
|
||||
export function findSimulationCase(path) {
|
||||
return SIM_CASE_CATALOG.find((entry) => entry.path === path) ?? null;
|
||||
const registered = machineDefinition(path);
|
||||
return SIM_CASE_CATALOG.find((entry) => entry.path === path) ?? (registered ? { path: registered.entrypoint, coordinates: registered.coordinates, label: registered.label, status: "registered" } : null);
|
||||
}
|
||||
|
||||
export async function loadSimulationCase({ path, fetchImpl = globalThis.fetch, baseUrl = "" } = {}) {
|
||||
@@ -243,7 +203,7 @@ export async function loadSimulationCase({ path, fetchImpl = globalThis.fetch, b
|
||||
}
|
||||
}
|
||||
const sourceIni = files[catalog.path];
|
||||
const fixture = RUNTIME_FIXTURES[catalog.path];
|
||||
const fixture = RUNTIME_FIXTURES[catalog.path] ?? RUNTIME_FIXTURES[machine?.runtime_fixture];
|
||||
if (fixture) {
|
||||
if (!inManifest(fixture.generated_hal)) missing.push(fixture.generated_hal);
|
||||
else if (!files[fixture.generated_hal]) {
|
||||
@@ -280,7 +240,23 @@ export async function loadSimulationCase({ path, fetchImpl = globalThis.fetch, b
|
||||
export function toWorkerConfiguration(bundle) {
|
||||
if (!bundle || bundle.schema !== SIMULATION_CASE_SCHEMA) throw new Error("simulation_case_bundle_invalid");
|
||||
const kinematics = CASE_KINEMATICS[bundle.entrypoint] ? clone(CASE_KINEMATICS[bundle.entrypoint]) : null;
|
||||
if (machineDefinition(bundle.entrypoint)) kinematics.offsets = readTrtGeometry(bundle).offsets;
|
||||
const trt = machineDefinition(bundle.entrypoint) ? readTrtConfiguration(bundle) : null;
|
||||
let homeLimits = null;
|
||||
if (!trt) {
|
||||
const parsed = parseIni({ workspace: new WorkspaceRuntime({ files: bundle.files }), entrypoint: bundle.entrypoint });
|
||||
const coordinates = parsed.sections.TRAJ?.COORDINATES?.replace(/\s/g, "").toUpperCase();
|
||||
if (coordinates && /^[XYZABCUVW]+$/.test(coordinates)) {
|
||||
const limits = {};
|
||||
for (const [index, axis] of [...coordinates].entries()) {
|
||||
const section = parsed.sections[`JOINT_${index}`] ?? parsed.sections[`AXIS_${axis}`];
|
||||
if (!section || section.MIN_LIMIT === undefined || section.MAX_LIMIT === undefined) continue;
|
||||
const range = [Number(section.MIN_LIMIT), Number(section.MAX_LIMIT)];
|
||||
if (!range.every(Number.isFinite) || range[0] >= range[1]) throw new Error(`configuration_joint_limits:${index}`);
|
||||
limits[axis.toLowerCase()] = range;
|
||||
}
|
||||
if (Object.keys(limits).length) homeLimits = { coordinates, joint_count: coordinates.length, ...limits };
|
||||
}
|
||||
}
|
||||
return {
|
||||
entrypoint: bundle.entrypoint,
|
||||
files: clone(bundle.files),
|
||||
@@ -288,9 +264,8 @@ export function toWorkerConfiguration(bundle) {
|
||||
state_hash: bundle.state_hash,
|
||||
optional_missing: clone(bundle.optional_missing ?? []),
|
||||
runtime_fixtures: clone(bundle.runtime_fixtures ?? []),
|
||||
...(bundle.entrypoint === "linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini" ? { home_limits: { z: [-240, 100] } } : {}),
|
||||
...(machineDefinition(bundle.entrypoint) ? { home_limits: { joint_count: 5, kinematics_type: machineDefinition(bundle.entrypoint).kinematics_type, coordinates: machineDefinition(bundle.entrypoint).coordinates, ...machineDefinition(bundle.entrypoint).joint_limits } } : {}),
|
||||
...(kinematics ? { kinematics } : {}),
|
||||
...(homeLimits ? { home_limits: homeLimits } : {}),
|
||||
...(trt ?? (kinematics ? { kinematics } : {})),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user