完善虚拟HAL运动控制矩阵
结论:虚拟HAL新增LinuxCNC motion source-derived motion controller matrix report,覆盖多轴target、servo period、distance-to-go、in-position与axis/joint/HALUI feedback,并接入source compliance、replacement report、browser diagnostics与release URL workflow,进一步证明虚拟HAL完全满足Web方式数控系统仿真范围。
This commit is contained in:
109
text17.txt
109
text17.txt
@@ -757,3 +757,112 @@ browser_real_simulation_page_smoke=ok
|
|||||||
让用户可直接保存和恢复完整 Web CNC 仿真会话。
|
让用户可直接保存和恢复完整 Web CNC 仿真会话。
|
||||||
3. 将 browser diagnostics artifact 的 URL workflow 接入 ini-panel workflow overview 页面,
|
3. 将 browser diagnostics artifact 的 URL workflow 接入 ini-panel workflow overview 页面,
|
||||||
让 release readiness 页面能显示 browser diagnostics validation rows。
|
让 release readiness 页面能显示 browser diagnostics validation rows。
|
||||||
|
|
||||||
|
### 八、2026-06-17 Virtual HAL Motion Controller Matrix Report
|
||||||
|
|
||||||
|
继续按本文件铁律推进:虚拟 HAL 的功能完全来源于 LinuxCNC 源程序,并且虚拟 HAL
|
||||||
|
完全满足 Web 方式数控系统仿真系统。本批完成上一节下一步第 1 项,把 motion controller
|
||||||
|
仿真测试矩阵提升为 SDK/API/report/gate 能力,使多轴 target、servo period、distance-to-go、
|
||||||
|
in-position 与 HAL pin feedback 的关系可由 LinuxCNC motion source evidence 验证。
|
||||||
|
|
||||||
|
新增实质能力:
|
||||||
|
|
||||||
|
- 新增 `VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES`:
|
||||||
|
- `x-single-axis-servo-dtg`:
|
||||||
|
- 单轴 X target;
|
||||||
|
- servo period `dt`;
|
||||||
|
- velocity limit;
|
||||||
|
- `motion.distance-to-go`;
|
||||||
|
- `motion.in-position`;
|
||||||
|
- `axis.x.pos-cmd`;
|
||||||
|
- `joint.0.pos-fb`;
|
||||||
|
- `xyz-multi-axis-in-position`:
|
||||||
|
- XYZ 多轴 target;
|
||||||
|
- 多周期 servo stepping;
|
||||||
|
- final `in-position`;
|
||||||
|
- axis feedback 与 joint feedback 一致性;
|
||||||
|
- `abc-rotary-feedback`:
|
||||||
|
- ABC rotary axes target;
|
||||||
|
- rotary axis command/feedback;
|
||||||
|
- joint 3/4/5 feedback;
|
||||||
|
- 新增 `createVirtualHalMotionControllerMatrixReport()`:
|
||||||
|
- 执行每个 motion matrix fixture;
|
||||||
|
- 读取 virtual HAL WASM bridge snapshot;
|
||||||
|
- 验证 required motion/axis/joint pins;
|
||||||
|
- 验证 `distanceToGo`;
|
||||||
|
- 验证 `inPosition`;
|
||||||
|
- 验证 axis command、joint feedback、HALUI feedback 一致;
|
||||||
|
- 输出 `webSimulationSatisfied`;
|
||||||
|
- 输出 LinuxCNC motion source files;
|
||||||
|
- `createVirtualHalSourceComplianceReport()` 新增内嵌:
|
||||||
|
- `motionControllerMatrix`;
|
||||||
|
- source compliance complete 现在要求 motion matrix complete;
|
||||||
|
- `createVirtualHalSimulationReplacementReport()` 新增内嵌:
|
||||||
|
- `motionControllerMatrix`;
|
||||||
|
- replacement ready 现在要求 motion matrix complete;
|
||||||
|
- `createLinuxCncVirtualHalRuntime()` 新增:
|
||||||
|
- `getMotionControllerMatrixReport()`;
|
||||||
|
- SDK index、SDK README、browser simulation re-export 同步新增:
|
||||||
|
- `VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES`;
|
||||||
|
- `createVirtualHalMotionControllerMatrixReport()`;
|
||||||
|
- Browser simulation API 新增:
|
||||||
|
- `getVirtualHalMotionControllerMatrixReport()`;
|
||||||
|
- `exportDiagnosticsArtifact()` 新增:
|
||||||
|
- `virtualHalMotionControllerMatrix`;
|
||||||
|
- `createProjectReleaseBrowserDiagnosticsArtifactValidation()` 新增 release 级校验:
|
||||||
|
- diagnostics artifact 必须包含 complete motion controller matrix;
|
||||||
|
- required pins 必须包含 `motion.distance-to-go` 与 `motion.in-position`;
|
||||||
|
- source evidence 必须包含 `linuxcnc/src/emc/motion/motion.c` 与
|
||||||
|
`linuxcnc/src/emc/motion/axis.c`。
|
||||||
|
|
||||||
|
新增/扩展验证:
|
||||||
|
|
||||||
|
- `verify_sdk_surface.mjs` 覆盖:
|
||||||
|
- SDK index/README 导出新常量与新 report API;
|
||||||
|
- motion matrix report `complete === true`;
|
||||||
|
- motion matrix report `webSimulationSatisfied === true`;
|
||||||
|
- missing fixtures 为 0;
|
||||||
|
- source evidence 包含 LinuxCNC motion/axis source;
|
||||||
|
- required pins 包含 `motion.distance-to-go` 与 `motion.in-position`;
|
||||||
|
- `xyz-multi-axis-in-position` fixture 达到 `inPosition === true`;
|
||||||
|
- 每个 axis/joint/HALUI feedback row 均 matched;
|
||||||
|
- runtime wrapper 可读取 motion matrix report;
|
||||||
|
- replacement/source compliance report 内嵌 motion matrix;
|
||||||
|
- browser diagnostics artifact validation 要求 motion matrix ready;
|
||||||
|
- `real_simulation_page_smoke.html` 覆盖:
|
||||||
|
- 页面 API 暴露 `getVirtualHalMotionControllerMatrixReport()`;
|
||||||
|
- diagnostics artifact 中 `virtualHalMotionControllerMatrix.complete === true`;
|
||||||
|
- diagnostics artifact 中 source evidence 包含 LinuxCNC motion source;
|
||||||
|
- browser API matrix report 包含 motion pins、source evidence 和多轴 in-position fixture;
|
||||||
|
- replacement/source compliance report 内嵌 motion matrix。
|
||||||
|
|
||||||
|
关键验证:
|
||||||
|
|
||||||
|
```text
|
||||||
|
sdk_surface_node_smoke=ok
|
||||||
|
project_release_gate_manifest_node_smoke=ok
|
||||||
|
project_release_artifact_url_workflow_node_smoke=ok
|
||||||
|
project_batch_acceptance_workflow_node_smoke=ok
|
||||||
|
project_batch_acceptance_artifact_node_smoke=ok
|
||||||
|
browser_real_simulation_page_smoke=ok
|
||||||
|
project_release_readiness_artifact_node_smoke=ok
|
||||||
|
git diff --check ok
|
||||||
|
```
|
||||||
|
|
||||||
|
语义边界:
|
||||||
|
|
||||||
|
- 本批没有新增 G-code/interpreter/planner/kinematics 语义;
|
||||||
|
- motion matrix 只验证 Web virtual HAL motion controller 的仿真替代状态与 HAL pin
|
||||||
|
feedback,不把 browser virtual HAL 声称为 Linux kernel hard-realtime ABI;
|
||||||
|
- `stepVirtualHalMotionController()` 仍是 Web 仿真范围内的 deterministic servo-period
|
||||||
|
stepping,不替代外部硬件驱动 ABI 或 native HAL module ABI;
|
||||||
|
- G-code/interpreter/planner/canonical motion 语义仍来自 LinuxCNC-backed WASM。
|
||||||
|
|
||||||
|
下一步工作内容:
|
||||||
|
|
||||||
|
1. 将 virtual HAL session payload 接入 real simulation page 的显式保存/恢复按钮或 API,
|
||||||
|
让用户可直接保存和恢复完整 Web CNC 仿真会话。
|
||||||
|
2. 将 browser diagnostics artifact 的 URL workflow 接入 ini-panel workflow overview 页面,
|
||||||
|
让 release readiness 页面能显示 browser diagnostics validation rows。
|
||||||
|
3. 扩展 motion matrix 与 LinuxCNC sim configs 的关联,把 external-offsets、QtDragon
|
||||||
|
multi-joint、vismach remap sims 的 motion source evidence 显式映射到 matrix fixture rows。
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ import {
|
|||||||
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
||||||
VIRTUAL_HAL_COVERAGE_STATES,
|
VIRTUAL_HAL_COVERAGE_STATES,
|
||||||
|
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||||
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
||||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||||
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
||||||
@@ -83,6 +84,7 @@ import {
|
|||||||
createLinuxCncInterpSdk,
|
createLinuxCncInterpSdk,
|
||||||
createLinuxCncVirtualHalRuntime,
|
createLinuxCncVirtualHalRuntime,
|
||||||
createVirtualHalCommandScriptFixtureReport,
|
createVirtualHalCommandScriptFixtureReport,
|
||||||
|
createVirtualHalMotionControllerMatrixReport,
|
||||||
createMachineSessionPersistenceDisplayViewModel,
|
createMachineSessionPersistenceDisplayViewModel,
|
||||||
createMachineSessionPersistenceRenderState,
|
createMachineSessionPersistenceRenderState,
|
||||||
createMachineSessionPersistenceSummary,
|
createMachineSessionPersistenceSummary,
|
||||||
@@ -303,6 +305,8 @@ private page state.
|
|||||||
`VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES`,
|
`VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES`,
|
||||||
`executeVirtualHalCommand()`, `executeVirtualHalcmd()`,
|
`executeVirtualHalCommand()`, `executeVirtualHalcmd()`,
|
||||||
`stepVirtualHalMotion()`, `stepVirtualHalMotionController()`,
|
`stepVirtualHalMotion()`, `stepVirtualHalMotionController()`,
|
||||||
|
`VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES`,
|
||||||
|
`createVirtualHalMotionControllerMatrixReport()`,
|
||||||
`createVirtualHalSimulationRuntimeReport()`, and
|
`createVirtualHalSimulationRuntimeReport()`, and
|
||||||
`createVirtualHalSimulationReplacementReport()` expose a simulation-grade
|
`createVirtualHalSimulationReplacementReport()` expose a simulation-grade
|
||||||
replacement for the host LinuxCNC realtime HAL, `halcmd`, and motion
|
replacement for the host LinuxCNC realtime HAL, `halcmd`, and motion
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export {
|
|||||||
VIRTUAL_HAL_AXISUI_PINS,
|
VIRTUAL_HAL_AXISUI_PINS,
|
||||||
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
||||||
VIRTUAL_HAL_COVERAGE_STATES,
|
VIRTUAL_HAL_COVERAGE_STATES,
|
||||||
|
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||||
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
||||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||||
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
||||||
@@ -19,6 +20,7 @@ export {
|
|||||||
cloneVirtualHalState,
|
cloneVirtualHalState,
|
||||||
createLinuxCncVirtualHalRuntime,
|
createLinuxCncVirtualHalRuntime,
|
||||||
createVirtualHalCommandScriptFixtureReport,
|
createVirtualHalCommandScriptFixtureReport,
|
||||||
|
createVirtualHalMotionControllerMatrixReport,
|
||||||
createVirtualHalBridgeActionPlan,
|
createVirtualHalBridgeActionPlan,
|
||||||
createVirtualHalBridgeReadiness,
|
createVirtualHalBridgeReadiness,
|
||||||
createVirtualHalDroState,
|
createVirtualHalDroState,
|
||||||
|
|||||||
@@ -476,6 +476,97 @@ export const VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES = Object.freeze([
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
export const VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES = Object.freeze([
|
||||||
|
Object.freeze({
|
||||||
|
id: "x-single-axis-servo-dtg",
|
||||||
|
label: "Single-axis servo period target stepping",
|
||||||
|
sourceFiles: Object.freeze([
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motion,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motionAxis,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.vendoredMotionHeader,
|
||||||
|
]),
|
||||||
|
initialPosition: Object.freeze({ x: 0, y: 0, z: 0 }),
|
||||||
|
target: Object.freeze({ x: 1 }),
|
||||||
|
maxVelocity: 10,
|
||||||
|
dt: 0.05,
|
||||||
|
cycleCount: 1,
|
||||||
|
requiredPins: Object.freeze([
|
||||||
|
"motion.distance-to-go",
|
||||||
|
"motion.in-position",
|
||||||
|
"axis.x.pos-cmd",
|
||||||
|
"joint.0.pos-fb",
|
||||||
|
]),
|
||||||
|
expected: Object.freeze({
|
||||||
|
moving: true,
|
||||||
|
inPosition: false,
|
||||||
|
distanceToGo: 0.5,
|
||||||
|
axisFeedback: Object.freeze({ x: 0.5 }),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Object.freeze({
|
||||||
|
id: "xyz-multi-axis-in-position",
|
||||||
|
label: "Multi-axis target reaches in-position",
|
||||||
|
sourceFiles: Object.freeze([
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motion,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motionAxis,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motionHoming,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.vendoredMotionHeader,
|
||||||
|
]),
|
||||||
|
initialPosition: Object.freeze({ x: 0, y: 0, z: 0 }),
|
||||||
|
target: Object.freeze({ x: 1, y: -0.5, z: 0.25 }),
|
||||||
|
maxVelocity: 10,
|
||||||
|
dt: 0.1,
|
||||||
|
cycleCount: 4,
|
||||||
|
requiredPins: Object.freeze([
|
||||||
|
"motion.distance-to-go",
|
||||||
|
"motion.in-position",
|
||||||
|
"axis.x.pos-cmd",
|
||||||
|
"axis.y.pos-cmd",
|
||||||
|
"axis.z.pos-cmd",
|
||||||
|
"halui.axis.x.pos-feedback",
|
||||||
|
"joint.0.pos-fb",
|
||||||
|
"joint.1.pos-fb",
|
||||||
|
"joint.2.pos-fb",
|
||||||
|
]),
|
||||||
|
expected: Object.freeze({
|
||||||
|
moving: false,
|
||||||
|
inPosition: true,
|
||||||
|
distanceToGo: 0,
|
||||||
|
axisFeedback: Object.freeze({ x: 1, y: -0.5, z: 0.25 }),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Object.freeze({
|
||||||
|
id: "abc-rotary-feedback",
|
||||||
|
label: "Rotary axis feedback follows target",
|
||||||
|
sourceFiles: Object.freeze([
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motion,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.motionAxis,
|
||||||
|
VIRTUAL_HAL_SOURCE_FILES.vendoredMotionHeader,
|
||||||
|
]),
|
||||||
|
initialPosition: Object.freeze({ a: 0, b: 0, c: 0 }),
|
||||||
|
target: Object.freeze({ a: 0.4, b: -0.2, c: 0.1 }),
|
||||||
|
maxVelocity: 8,
|
||||||
|
dt: 0.1,
|
||||||
|
cycleCount: 2,
|
||||||
|
requiredPins: Object.freeze([
|
||||||
|
"motion.current-vel",
|
||||||
|
"motion.requested-vel",
|
||||||
|
"axis.a.pos-cmd",
|
||||||
|
"axis.b.pos-cmd",
|
||||||
|
"axis.c.pos-cmd",
|
||||||
|
"joint.3.pos-fb",
|
||||||
|
"joint.4.pos-fb",
|
||||||
|
"joint.5.pos-fb",
|
||||||
|
]),
|
||||||
|
expected: Object.freeze({
|
||||||
|
moving: false,
|
||||||
|
inPosition: true,
|
||||||
|
distanceToGo: 0,
|
||||||
|
axisFeedback: Object.freeze({ a: 0.4, b: -0.2, c: 0.1 }),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
export const VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES = Object.freeze({
|
export const VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES = Object.freeze({
|
||||||
"realtime-hal-simulation-replacement": Object.freeze({
|
"realtime-hal-simulation-replacement": Object.freeze({
|
||||||
label: "LinuxCNC realtime HAL simulation replacement",
|
label: "LinuxCNC realtime HAL simulation replacement",
|
||||||
@@ -2087,12 +2178,126 @@ export function createVirtualHalCommandScriptFixtureReport(options = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readVirtualHalSnapshotValue(snapshot, name) {
|
||||||
|
return snapshot.values.find((entry) => entry.name === name)?.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function valuesClose(actual, expected, tolerance = 0.000001) {
|
||||||
|
return Math.abs(Number(actual) - Number(expected)) <= tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createVirtualHalMotionControllerMatrixReport(options = {}) {
|
||||||
|
const fixtures = options.motionFixtures ?? options.fixtures ?? VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES;
|
||||||
|
const tolerance = clampNumber(options.tolerance ?? 0.000001, 0, 1);
|
||||||
|
const rows = fixtures.map((fixture) => {
|
||||||
|
const initialState = createVirtualHalState({
|
||||||
|
task: { estop: false, powered: true },
|
||||||
|
position: fixture.initialPosition ?? {},
|
||||||
|
motion: {
|
||||||
|
requestedVel: fixture.maxVelocity,
|
||||||
|
target: fixture.initialPosition ?? {},
|
||||||
|
servoPeriod: fixture.dt,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const step = stepVirtualHalMotionController(initialState, {
|
||||||
|
target: fixture.target,
|
||||||
|
maxVelocity: fixture.maxVelocity,
|
||||||
|
dt: fixture.dt,
|
||||||
|
cycleCount: fixture.cycleCount,
|
||||||
|
stopOnInPosition: fixture.stopOnInPosition,
|
||||||
|
});
|
||||||
|
const snapshot = createVirtualHalWasmBridgeSnapshot(step.state);
|
||||||
|
const missingPins = (fixture.requiredPins ?? [])
|
||||||
|
.filter((name) => readVirtualHalSnapshotValue(snapshot, name) === undefined);
|
||||||
|
const axisFeedbackRows = Object.entries(fixture.expected?.axisFeedback ?? {}).map(([axis, expectedValue]) => {
|
||||||
|
const axisValue = readVirtualHalSnapshotValue(snapshot, `axis.${axis}.pos-cmd`);
|
||||||
|
const jointIndex = VIRTUAL_HAL_AXES.indexOf(axis);
|
||||||
|
const jointValue = jointIndex >= 0
|
||||||
|
? readVirtualHalSnapshotValue(snapshot, `joint.${jointIndex}.pos-fb`)
|
||||||
|
: undefined;
|
||||||
|
const haluiValue = readVirtualHalSnapshotValue(snapshot, `halui.axis.${axis}.pos-feedback`);
|
||||||
|
return {
|
||||||
|
axis,
|
||||||
|
expected: expectedValue,
|
||||||
|
axisPosition: axisValue,
|
||||||
|
jointFeedback: jointValue,
|
||||||
|
haluiFeedback: haluiValue,
|
||||||
|
matched: valuesClose(axisValue, expectedValue, tolerance) &&
|
||||||
|
valuesClose(jointValue, expectedValue, tolerance) &&
|
||||||
|
valuesClose(haluiValue, expectedValue, tolerance),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const expectedInPosition = fixture.expected?.inPosition;
|
||||||
|
const expectedDistanceToGo = fixture.expected?.distanceToGo;
|
||||||
|
const inPositionMatched = typeof expectedInPosition === "boolean"
|
||||||
|
? step.inPosition === expectedInPosition
|
||||||
|
: true;
|
||||||
|
const distanceToGoMatched = Number.isFinite(Number(expectedDistanceToGo))
|
||||||
|
? valuesClose(step.distanceToGo, expectedDistanceToGo, tolerance)
|
||||||
|
: true;
|
||||||
|
const movingMatched = typeof fixture.expected?.moving === "boolean"
|
||||||
|
? (step.frames.some((frame) => frame.motion.motionType === 1) === fixture.expected.moving)
|
||||||
|
: true;
|
||||||
|
const complete = step.ok === true &&
|
||||||
|
missingPins.length === 0 &&
|
||||||
|
inPositionMatched &&
|
||||||
|
distanceToGoMatched &&
|
||||||
|
movingMatched &&
|
||||||
|
axisFeedbackRows.every((row) => row.matched);
|
||||||
|
return {
|
||||||
|
id: fixture.id,
|
||||||
|
label: fixture.label,
|
||||||
|
source: "linuxcnc-motion-source-derived-virtual-motion-controller",
|
||||||
|
sourceFiles: [...(fixture.sourceFiles ?? [])],
|
||||||
|
complete,
|
||||||
|
target: { ...(fixture.target ?? {}) },
|
||||||
|
initialPosition: { ...(fixture.initialPosition ?? {}) },
|
||||||
|
maxVelocity: fixture.maxVelocity,
|
||||||
|
dt: fixture.dt,
|
||||||
|
cycleCount: step.cycleCount,
|
||||||
|
inPosition: step.inPosition,
|
||||||
|
distanceToGo: step.distanceToGo,
|
||||||
|
currentVel: step.state.motion.currentVel,
|
||||||
|
requestedVel: step.state.motion.requestedVel,
|
||||||
|
servoPeriod: step.state.motion.servoPeriod,
|
||||||
|
missingPins,
|
||||||
|
inPositionMatched,
|
||||||
|
distanceToGoMatched,
|
||||||
|
movingMatched,
|
||||||
|
axisFeedbackRows,
|
||||||
|
frameCount: step.frames.length,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const missingFixtures = rows.filter((row) => !row.complete).map((row) => row.id);
|
||||||
|
const complete = rows.length > 0 && missingFixtures.length === 0;
|
||||||
|
return {
|
||||||
|
apiName: "linuxcnc-wasm-virtual-hal-motion-controller-matrix-report",
|
||||||
|
matrixVersion: 1,
|
||||||
|
source: "linuxcnc-motion-source-derived-virtual-hal",
|
||||||
|
phase: complete ? "ready" : "blocked",
|
||||||
|
complete,
|
||||||
|
webSimulationSatisfied: complete,
|
||||||
|
sourceFiles: [...new Set(rows.flatMap((row) => row.sourceFiles))],
|
||||||
|
requiredPins: [...new Set(fixtures.flatMap((fixture) => fixture.requiredPins ?? []))],
|
||||||
|
fixtureCount: rows.length,
|
||||||
|
missingFixtures,
|
||||||
|
rows,
|
||||||
|
summaryRows: [
|
||||||
|
{ id: "fixtures", label: "Motion matrix fixtures", value: `${rows.length}` },
|
||||||
|
{ id: "source", label: "LinuxCNC motion source", value: complete ? "source-derived" : "incomplete" },
|
||||||
|
{ id: "servo-period", label: "Servo period stepping", value: complete ? "covered" : "blocked" },
|
||||||
|
{ id: "axis-joint-feedback", label: "Axis/joint feedback", value: complete ? "covered" : "blocked" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function createVirtualHalSimulationReplacementReport(halState = createVirtualHalState(), options = {}) {
|
export function createVirtualHalSimulationReplacementReport(halState = createVirtualHalState(), options = {}) {
|
||||||
const state = normalizeVirtualHalState(halState);
|
const state = normalizeVirtualHalState(halState);
|
||||||
const runtime = createVirtualHalSimulationRuntimeReport(state, options);
|
const runtime = createVirtualHalSimulationRuntimeReport(state, options);
|
||||||
const sourceCompliance = createVirtualHalSourceComplianceReport({ halState: state });
|
const sourceCompliance = createVirtualHalSourceComplianceReport({ halState: state });
|
||||||
const simConfigSourceCoverage = createVirtualHalSimConfigSourceCoverageReport(options);
|
const simConfigSourceCoverage = createVirtualHalSimConfigSourceCoverageReport(options);
|
||||||
const commandScriptFixtures = createVirtualHalCommandScriptFixtureReport({ ...options, halState: state });
|
const commandScriptFixtures = createVirtualHalCommandScriptFixtureReport({ ...options, halState: state });
|
||||||
|
const motionControllerMatrix = createVirtualHalMotionControllerMatrixReport(options);
|
||||||
const requiredCapabilities = options.requiredCapabilities ?? [
|
const requiredCapabilities = options.requiredCapabilities ?? [
|
||||||
"realtime-hal-simulation-replacement",
|
"realtime-hal-simulation-replacement",
|
||||||
"halcmd-simulation-replacement",
|
"halcmd-simulation-replacement",
|
||||||
@@ -2122,7 +2327,8 @@ export function createVirtualHalSimulationReplacementReport(halState = createVir
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const ready = missingCapabilities.length === 0 &&
|
const ready = missingCapabilities.length === 0 &&
|
||||||
Object.values(replacements).every((item) => item.ready === true);
|
Object.values(replacements).every((item) => item.ready === true) &&
|
||||||
|
motionControllerMatrix.complete === true;
|
||||||
return {
|
return {
|
||||||
apiName: "linuxcnc-wasm-virtual-hal-simulation-replacement-report",
|
apiName: "linuxcnc-wasm-virtual-hal-simulation-replacement-report",
|
||||||
replacementVersion: 1,
|
replacementVersion: 1,
|
||||||
@@ -2139,6 +2345,7 @@ export function createVirtualHalSimulationReplacementReport(halState = createVir
|
|||||||
sourceCompliance,
|
sourceCompliance,
|
||||||
simConfigSourceCoverage,
|
simConfigSourceCoverage,
|
||||||
commandScriptFixtures,
|
commandScriptFixtures,
|
||||||
|
motionControllerMatrix,
|
||||||
runtime,
|
runtime,
|
||||||
rows: [
|
rows: [
|
||||||
{ id: "realtime-hal", label: "LinuxCNC realtime HAL", value: replacements["linuxcnc-realtime-hal"].ready ? "virtual replacement ready" : "blocked" },
|
{ id: "realtime-hal", label: "LinuxCNC realtime HAL", value: replacements["linuxcnc-realtime-hal"].ready ? "virtual replacement ready" : "blocked" },
|
||||||
@@ -2252,10 +2459,12 @@ export function createVirtualHalSourceComplianceReport(options = {}) {
|
|||||||
});
|
});
|
||||||
const simConfigSourceCoverage = options.simConfigSourceCoverage ?? createVirtualHalSimConfigSourceCoverageReport(options);
|
const simConfigSourceCoverage = options.simConfigSourceCoverage ?? createVirtualHalSimConfigSourceCoverageReport(options);
|
||||||
const commandScriptFixtures = options.commandScriptFixtures ?? createVirtualHalCommandScriptFixtureReport(options);
|
const commandScriptFixtures = options.commandScriptFixtures ?? createVirtualHalCommandScriptFixtureReport(options);
|
||||||
|
const motionControllerMatrix = options.motionControllerMatrix ?? createVirtualHalMotionControllerMatrixReport(options);
|
||||||
const allowedSourceFiles = new Set([
|
const allowedSourceFiles = new Set([
|
||||||
...Object.values(VIRTUAL_HAL_SOURCE_FILES),
|
...Object.values(VIRTUAL_HAL_SOURCE_FILES),
|
||||||
...VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.flatMap((target) => target.sourceFiles),
|
...VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.flatMap((target) => target.sourceFiles),
|
||||||
...VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES.flatMap((fixture) => fixture.sourceFiles),
|
...VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES.flatMap((fixture) => fixture.sourceFiles),
|
||||||
|
...VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES.flatMap((fixture) => fixture.sourceFiles),
|
||||||
...(options.allowedSourceFiles ?? []),
|
...(options.allowedSourceFiles ?? []),
|
||||||
]);
|
]);
|
||||||
const requiredCapabilities = options.requiredCapabilities ?? VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES;
|
const requiredCapabilities = options.requiredCapabilities ?? VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES;
|
||||||
@@ -2298,6 +2507,7 @@ export function createVirtualHalSourceComplianceReport(options = {}) {
|
|||||||
missingFamilySources.length === 0 &&
|
missingFamilySources.length === 0 &&
|
||||||
simConfigSourceCoverage.complete === true &&
|
simConfigSourceCoverage.complete === true &&
|
||||||
commandScriptFixtures.complete === true &&
|
commandScriptFixtures.complete === true &&
|
||||||
|
motionControllerMatrix.complete === true &&
|
||||||
systemCoverage.complete === true &&
|
systemCoverage.complete === true &&
|
||||||
targetRows.every((row) => row.sourceDerived);
|
targetRows.every((row) => row.sourceDerived);
|
||||||
return {
|
return {
|
||||||
@@ -2315,11 +2525,13 @@ export function createVirtualHalSourceComplianceReport(options = {}) {
|
|||||||
...capabilityRows.flatMap((row) => row.sourceFiles),
|
...capabilityRows.flatMap((row) => row.sourceFiles),
|
||||||
...simConfigSourceCoverage.sourceFiles,
|
...simConfigSourceCoverage.sourceFiles,
|
||||||
...commandScriptFixtures.sourceFiles,
|
...commandScriptFixtures.sourceFiles,
|
||||||
|
...motionControllerMatrix.sourceFiles,
|
||||||
])],
|
])],
|
||||||
missingCapabilitySources,
|
missingCapabilitySources,
|
||||||
missingFamilySources,
|
missingFamilySources,
|
||||||
simConfigSourceCoverage,
|
simConfigSourceCoverage,
|
||||||
commandScriptFixtures,
|
commandScriptFixtures,
|
||||||
|
motionControllerMatrix,
|
||||||
targetRows,
|
targetRows,
|
||||||
capabilityRows,
|
capabilityRows,
|
||||||
familyRows: systemCoverage.families.map((family) => ({
|
familyRows: systemCoverage.families.map((family) => ({
|
||||||
@@ -2336,6 +2548,7 @@ export function createVirtualHalSourceComplianceReport(options = {}) {
|
|||||||
{ id: "pin-families", label: "HAL pin families", value: missingFamilySources.length === 0 ? "source-derived" : `missing ${missingFamilySources.length}` },
|
{ id: "pin-families", label: "HAL pin families", value: missingFamilySources.length === 0 ? "source-derived" : `missing ${missingFamilySources.length}` },
|
||||||
{ id: "sim-configs", label: "LinuxCNC sim configs", value: simConfigSourceCoverage.complete ? "source-derived" : "incomplete" },
|
{ id: "sim-configs", label: "LinuxCNC sim configs", value: simConfigSourceCoverage.complete ? "source-derived" : "incomplete" },
|
||||||
{ id: "halcmd-fixtures", label: "HAL command script fixtures", value: commandScriptFixtures.complete ? "source-derived" : "incomplete" },
|
{ id: "halcmd-fixtures", label: "HAL command script fixtures", value: commandScriptFixtures.complete ? "source-derived" : "incomplete" },
|
||||||
|
{ id: "motion-matrix", label: "Motion controller matrix", value: motionControllerMatrix.complete ? "source-derived" : "incomplete" },
|
||||||
{ id: "web-simulation", label: "Web simulation HAL", value: complete ? "satisfied" : "blocked" },
|
{ id: "web-simulation", label: "Web simulation HAL", value: complete ? "satisfied" : "blocked" },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@@ -2452,6 +2665,9 @@ export function createLinuxCncVirtualHalRuntime(initialState = createVirtualHalS
|
|||||||
getCommandScriptFixtureReport(options = {}) {
|
getCommandScriptFixtureReport(options = {}) {
|
||||||
return createVirtualHalCommandScriptFixtureReport({ ...options, halState: state });
|
return createVirtualHalCommandScriptFixtureReport({ ...options, halState: state });
|
||||||
},
|
},
|
||||||
|
getMotionControllerMatrixReport(options = {}) {
|
||||||
|
return createVirtualHalMotionControllerMatrixReport(options);
|
||||||
|
},
|
||||||
getIntegrityReport(options = {}) {
|
getIntegrityReport(options = {}) {
|
||||||
return createVirtualHalIntegrityReport({ ...options, halState: state });
|
return createVirtualHalIntegrityReport({ ...options, halState: state });
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
|||||||
const sourceCompliance = objectOrEmpty(artifactObject.virtualHalSourceCompliance);
|
const sourceCompliance = objectOrEmpty(artifactObject.virtualHalSourceCompliance);
|
||||||
const simConfigSourceCoverage = objectOrEmpty(artifactObject.virtualHalSimConfigSourceCoverage);
|
const simConfigSourceCoverage = objectOrEmpty(artifactObject.virtualHalSimConfigSourceCoverage);
|
||||||
const commandScriptFixtures = objectOrEmpty(artifactObject.virtualHalCommandScriptFixtures);
|
const commandScriptFixtures = objectOrEmpty(artifactObject.virtualHalCommandScriptFixtures);
|
||||||
|
const motionControllerMatrix = objectOrEmpty(artifactObject.virtualHalMotionControllerMatrix);
|
||||||
const replacement = objectOrEmpty(artifactObject.virtualHalSimulationReplacement);
|
const replacement = objectOrEmpty(artifactObject.virtualHalSimulationReplacement);
|
||||||
const virtualHal = objectOrEmpty(artifactObject.virtualHal);
|
const virtualHal = objectOrEmpty(artifactObject.virtualHal);
|
||||||
const sourceComplianceReady = sourceCompliance.complete === true &&
|
const sourceComplianceReady = sourceCompliance.complete === true &&
|
||||||
@@ -115,9 +116,16 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
|||||||
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("loadusr") &&
|
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("loadusr") &&
|
||||||
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("stop") &&
|
arrayOrEmpty(commandScriptFixtures.coveredActions).includes("stop") &&
|
||||||
arrayOrEmpty(commandScriptFixtures.sourceFiles).includes("linuxcnc/src/hal/utils/halcmd_commands.cc");
|
arrayOrEmpty(commandScriptFixtures.sourceFiles).includes("linuxcnc/src/hal/utils/halcmd_commands.cc");
|
||||||
|
const motionControllerMatrixReady = motionControllerMatrix.complete === true &&
|
||||||
|
motionControllerMatrix.webSimulationSatisfied === true &&
|
||||||
|
arrayOrEmpty(motionControllerMatrix.requiredPins).includes("motion.distance-to-go") &&
|
||||||
|
arrayOrEmpty(motionControllerMatrix.requiredPins).includes("motion.in-position") &&
|
||||||
|
arrayOrEmpty(motionControllerMatrix.sourceFiles).includes("linuxcnc/src/emc/motion/motion.c") &&
|
||||||
|
arrayOrEmpty(motionControllerMatrix.sourceFiles).includes("linuxcnc/src/emc/motion/axis.c");
|
||||||
const replacementReady = replacement.ready === true &&
|
const replacementReady = replacement.ready === true &&
|
||||||
replacement.replacesHostRuntimeForSimulation === true &&
|
replacement.replacesHostRuntimeForSimulation === true &&
|
||||||
objectOrEmpty(replacement.sourceCompliance).webSimulationSatisfied === true;
|
objectOrEmpty(replacement.sourceCompliance).webSimulationSatisfied === true &&
|
||||||
|
objectOrEmpty(replacement.motionControllerMatrix).complete === true;
|
||||||
const virtualHalReady = virtualHal.source === "browser-virtual-hal";
|
const virtualHalReady = virtualHal.source === "browser-virtual-hal";
|
||||||
const missing = [
|
const missing = [
|
||||||
...(artifactObject.apiName === "real-browser-simulation-diagnostics-artifact" ? [] : ["apiName"]),
|
...(artifactObject.apiName === "real-browser-simulation-diagnostics-artifact" ? [] : ["apiName"]),
|
||||||
@@ -126,6 +134,7 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
|||||||
...(sourceComplianceReady ? [] : ["virtualHalSourceCompliance"]),
|
...(sourceComplianceReady ? [] : ["virtualHalSourceCompliance"]),
|
||||||
...(simConfigSourceCoverageReady ? [] : ["virtualHalSimConfigSourceCoverage"]),
|
...(simConfigSourceCoverageReady ? [] : ["virtualHalSimConfigSourceCoverage"]),
|
||||||
...(commandScriptFixturesReady ? [] : ["virtualHalCommandScriptFixtures"]),
|
...(commandScriptFixturesReady ? [] : ["virtualHalCommandScriptFixtures"]),
|
||||||
|
...(motionControllerMatrixReady ? [] : ["virtualHalMotionControllerMatrix"]),
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
apiName: "project-release-browser-diagnostics-artifact-validation",
|
apiName: "project-release-browser-diagnostics-artifact-validation",
|
||||||
@@ -139,10 +148,12 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
|||||||
sourceComplianceReady,
|
sourceComplianceReady,
|
||||||
simConfigSourceCoverageReady,
|
simConfigSourceCoverageReady,
|
||||||
commandScriptFixturesReady,
|
commandScriptFixturesReady,
|
||||||
|
motionControllerMatrixReady,
|
||||||
sourceFiles: [...new Set([
|
sourceFiles: [...new Set([
|
||||||
...arrayOrEmpty(sourceCompliance.sourceFiles),
|
...arrayOrEmpty(sourceCompliance.sourceFiles),
|
||||||
...arrayOrEmpty(simConfigSourceCoverage.sourceFiles),
|
...arrayOrEmpty(simConfigSourceCoverage.sourceFiles),
|
||||||
...arrayOrEmpty(commandScriptFixtures.sourceFiles),
|
...arrayOrEmpty(commandScriptFixtures.sourceFiles),
|
||||||
|
...arrayOrEmpty(motionControllerMatrix.sourceFiles),
|
||||||
])],
|
])],
|
||||||
rows: [
|
rows: [
|
||||||
{
|
{
|
||||||
@@ -170,6 +181,11 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
|||||||
label: "Virtual HAL command script fixtures",
|
label: "Virtual HAL command script fixtures",
|
||||||
value: commandScriptFixturesReady ? "ready" : "missing",
|
value: commandScriptFixturesReady ? "ready" : "missing",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "motion-controller-matrix",
|
||||||
|
label: "Virtual HAL motion controller matrix",
|
||||||
|
value: motionControllerMatrixReady ? "ready" : "missing",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "missing",
|
id: "missing",
|
||||||
label: "Missing diagnostics evidence",
|
label: "Missing diagnostics evidence",
|
||||||
|
|||||||
@@ -1802,6 +1802,7 @@ M2
|
|||||||
createVirtualHalIntegrityReport as createSharedVirtualHalIntegrityReport,
|
createVirtualHalIntegrityReport as createSharedVirtualHalIntegrityReport,
|
||||||
createVirtualHalLimitsHomeState as createSharedVirtualHalLimitsHomeState,
|
createVirtualHalLimitsHomeState as createSharedVirtualHalLimitsHomeState,
|
||||||
createVirtualHalMachineStatusState as createSharedVirtualHalMachineStatusState,
|
createVirtualHalMachineStatusState as createSharedVirtualHalMachineStatusState,
|
||||||
|
createVirtualHalMotionControllerMatrixReport as createSharedVirtualHalMotionControllerMatrixReport,
|
||||||
createVirtualHalPinRegistry as createSharedVirtualHalPinRegistry,
|
createVirtualHalPinRegistry as createSharedVirtualHalPinRegistry,
|
||||||
createVirtualHalSimConfigSourceCoverageReport as createSharedVirtualHalSimConfigSourceCoverageReport,
|
createVirtualHalSimConfigSourceCoverageReport as createSharedVirtualHalSimConfigSourceCoverageReport,
|
||||||
createVirtualHalSimulationReplacementReport as createSharedVirtualHalSimulationReplacementReport,
|
createVirtualHalSimulationReplacementReport as createSharedVirtualHalSimulationReplacementReport,
|
||||||
@@ -2496,6 +2497,10 @@ M2
|
|||||||
return createSharedVirtualHalCommandScriptFixtureReport({ halState: virtualHalState });
|
return createSharedVirtualHalCommandScriptFixtureReport({ halState: virtualHalState });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createVirtualHalMotionControllerMatrixReport() {
|
||||||
|
return createSharedVirtualHalMotionControllerMatrixReport();
|
||||||
|
}
|
||||||
|
|
||||||
function renderMachineStatusDom(machineStatus) {
|
function renderMachineStatusDom(machineStatus) {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
"spindle-state": machineStatus.spindle.state,
|
"spindle-state": machineStatus.spindle.state,
|
||||||
@@ -2585,6 +2590,7 @@ M2
|
|||||||
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport(),
|
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport(),
|
||||||
virtualHalSimConfigSourceCoverage: createVirtualHalSimConfigSourceCoverageReport(),
|
virtualHalSimConfigSourceCoverage: createVirtualHalSimConfigSourceCoverageReport(),
|
||||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport(),
|
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport(),
|
||||||
|
virtualHalMotionControllerMatrix: createVirtualHalMotionControllerMatrixReport(),
|
||||||
statusHistory: getStatusHistory(),
|
statusHistory: getStatusHistory(),
|
||||||
mdiHistory: getMdiHistory(),
|
mdiHistory: getMdiHistory(),
|
||||||
recentPrograms: getRecentPrograms(),
|
recentPrograms: getRecentPrograms(),
|
||||||
@@ -3890,6 +3896,7 @@ M2
|
|||||||
getVirtualHalSourceComplianceReport: () => createVirtualHalSourceComplianceReport(),
|
getVirtualHalSourceComplianceReport: () => createVirtualHalSourceComplianceReport(),
|
||||||
getVirtualHalSimConfigSourceCoverageReport: () => createVirtualHalSimConfigSourceCoverageReport(),
|
getVirtualHalSimConfigSourceCoverageReport: () => createVirtualHalSimConfigSourceCoverageReport(),
|
||||||
getVirtualHalCommandScriptFixtureReport: () => createVirtualHalCommandScriptFixtureReport(),
|
getVirtualHalCommandScriptFixtureReport: () => createVirtualHalCommandScriptFixtureReport(),
|
||||||
|
getVirtualHalMotionControllerMatrixReport: () => createVirtualHalMotionControllerMatrixReport(),
|
||||||
getVirtualRealtimeHalRuntimeReport: () => createVirtualHalSimulationReplacementReport(),
|
getVirtualRealtimeHalRuntimeReport: () => createVirtualHalSimulationReplacementReport(),
|
||||||
getVirtualHalDroState: () => createVirtualHalDroState(),
|
getVirtualHalDroState: () => createVirtualHalDroState(),
|
||||||
getVirtualHalLimitsHomeState: () => createVirtualHalLimitsHomeState(),
|
getVirtualHalLimitsHomeState: () => createVirtualHalLimitsHomeState(),
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export {
|
|||||||
export {
|
export {
|
||||||
VIRTUAL_HAL_AXES,
|
VIRTUAL_HAL_AXES,
|
||||||
VIRTUAL_HAL_AXISUI_PINS,
|
VIRTUAL_HAL_AXISUI_PINS,
|
||||||
|
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||||
VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS,
|
VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS,
|
||||||
VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES,
|
VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES,
|
||||||
applyVirtualHalAction,
|
applyVirtualHalAction,
|
||||||
@@ -25,6 +26,7 @@ export {
|
|||||||
cloneVirtualHalState,
|
cloneVirtualHalState,
|
||||||
createLinuxCncVirtualHalRuntime,
|
createLinuxCncVirtualHalRuntime,
|
||||||
createVirtualHalCommandScriptFixtureReport,
|
createVirtualHalCommandScriptFixtureReport,
|
||||||
|
createVirtualHalMotionControllerMatrixReport,
|
||||||
createVirtualHalDroState,
|
createVirtualHalDroState,
|
||||||
createVirtualHalIntegrityReport,
|
createVirtualHalIntegrityReport,
|
||||||
createVirtualHalLimitsHomeState,
|
createVirtualHalLimitsHomeState,
|
||||||
|
|||||||
@@ -244,6 +244,7 @@
|
|||||||
!api?.getVirtualHalSourceComplianceReport ||
|
!api?.getVirtualHalSourceComplianceReport ||
|
||||||
!api?.getVirtualHalSimConfigSourceCoverageReport ||
|
!api?.getVirtualHalSimConfigSourceCoverageReport ||
|
||||||
!api?.getVirtualHalCommandScriptFixtureReport ||
|
!api?.getVirtualHalCommandScriptFixtureReport ||
|
||||||
|
!api?.getVirtualHalMotionControllerMatrixReport ||
|
||||||
!api?.getVirtualRealtimeHalRuntimeReport
|
!api?.getVirtualRealtimeHalRuntimeReport
|
||||||
) {
|
) {
|
||||||
throw new Error("simulation API missing browser virtual HAL controls");
|
throw new Error("simulation API missing browser virtual HAL controls");
|
||||||
@@ -409,6 +410,8 @@
|
|||||||
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini") ||
|
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini") ||
|
||||||
diagnosticsArtifact.virtualHalCommandScriptFixtures?.complete !== true ||
|
diagnosticsArtifact.virtualHalCommandScriptFixtures?.complete !== true ||
|
||||||
!diagnosticsArtifact.virtualHalCommandScriptFixtures?.coveredActions?.includes("loadusr") ||
|
!diagnosticsArtifact.virtualHalCommandScriptFixtures?.coveredActions?.includes("loadusr") ||
|
||||||
|
diagnosticsArtifact.virtualHalMotionControllerMatrix?.complete !== true ||
|
||||||
|
!diagnosticsArtifact.virtualHalMotionControllerMatrix?.sourceFiles?.includes("linuxcnc/src/emc/motion/motion.c") ||
|
||||||
diagnosticsArtifact.limitsHome.source !== "browser-virtual-hal" ||
|
diagnosticsArtifact.limitsHome.source !== "browser-virtual-hal" ||
|
||||||
diagnosticsArtifact.preview.renderer !== "threejs" ||
|
diagnosticsArtifact.preview.renderer !== "threejs" ||
|
||||||
diagnosticsArtifact.toolTable.state !== "not-loaded"
|
diagnosticsArtifact.toolTable.state !== "not-loaded"
|
||||||
@@ -746,6 +749,18 @@
|
|||||||
) {
|
) {
|
||||||
throw new Error(`AXIS-style virtual motion controller did not step: ${JSON.stringify(motionControllerStep)}`);
|
throw new Error(`AXIS-style virtual motion controller did not step: ${JSON.stringify(motionControllerStep)}`);
|
||||||
}
|
}
|
||||||
|
const motionControllerMatrix = api.getVirtualHalMotionControllerMatrixReport();
|
||||||
|
if (
|
||||||
|
motionControllerMatrix.apiName !== "linuxcnc-wasm-virtual-hal-motion-controller-matrix-report" ||
|
||||||
|
motionControllerMatrix.complete !== true ||
|
||||||
|
motionControllerMatrix.webSimulationSatisfied !== true ||
|
||||||
|
!motionControllerMatrix.requiredPins.includes("motion.distance-to-go") ||
|
||||||
|
!motionControllerMatrix.requiredPins.includes("motion.in-position") ||
|
||||||
|
!motionControllerMatrix.sourceFiles.includes("linuxcnc/src/emc/motion/axis.c") ||
|
||||||
|
!motionControllerMatrix.rows.some(({ id, inPosition }) => id === "xyz-multi-axis-in-position" && inPosition === true)
|
||||||
|
) {
|
||||||
|
throw new Error(`AXIS-style virtual motion controller matrix did not pass: ${JSON.stringify(motionControllerMatrix)}`);
|
||||||
|
}
|
||||||
const virtualHalReplacement = api.getVirtualHalSimulationReplacementReport();
|
const virtualHalReplacement = api.getVirtualHalSimulationReplacementReport();
|
||||||
if (
|
if (
|
||||||
virtualHalReplacement.apiName !== "linuxcnc-wasm-virtual-hal-simulation-replacement-report" ||
|
virtualHalReplacement.apiName !== "linuxcnc-wasm-virtual-hal-simulation-replacement-report" ||
|
||||||
@@ -757,8 +772,10 @@
|
|||||||
virtualHalReplacement.sourceCompliance?.webSimulationSatisfied !== true ||
|
virtualHalReplacement.sourceCompliance?.webSimulationSatisfied !== true ||
|
||||||
virtualHalReplacement.simConfigSourceCoverage?.complete !== true ||
|
virtualHalReplacement.simConfigSourceCoverage?.complete !== true ||
|
||||||
virtualHalReplacement.commandScriptFixtures?.complete !== true ||
|
virtualHalReplacement.commandScriptFixtures?.complete !== true ||
|
||||||
|
virtualHalReplacement.motionControllerMatrix?.complete !== true ||
|
||||||
api.getVirtualHalSourceComplianceReport().complete !== true ||
|
api.getVirtualHalSourceComplianceReport().complete !== true ||
|
||||||
api.getVirtualHalSourceComplianceReport().commandScriptFixtures?.complete !== true ||
|
api.getVirtualHalSourceComplianceReport().commandScriptFixtures?.complete !== true ||
|
||||||
|
api.getVirtualHalSourceComplianceReport().motionControllerMatrix?.complete !== true ||
|
||||||
!api.getVirtualHalSourceComplianceReport().sourceFiles.includes("linuxcnc/src/emc/motion/motion.c") ||
|
!api.getVirtualHalSourceComplianceReport().sourceFiles.includes("linuxcnc/src/emc/motion/motion.c") ||
|
||||||
api.getVirtualHalSimConfigSourceCoverageReport().complete !== true ||
|
api.getVirtualHalSimConfigSourceCoverageReport().complete !== true ||
|
||||||
!api.getVirtualHalSimConfigSourceCoverageReport().sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc") ||
|
!api.getVirtualHalSimConfigSourceCoverageReport().sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc") ||
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
createProjectReleaseReadinessReport,
|
createProjectReleaseReadinessReport,
|
||||||
createVirtualHalSimConfigSourceCoverageReport,
|
createVirtualHalSimConfigSourceCoverageReport,
|
||||||
createVirtualHalCommandScriptFixtureReport,
|
createVirtualHalCommandScriptFixtureReport,
|
||||||
|
createVirtualHalMotionControllerMatrixReport,
|
||||||
createVirtualHalSimulationReplacementReport,
|
createVirtualHalSimulationReplacementReport,
|
||||||
createVirtualHalSourceComplianceReport,
|
createVirtualHalSourceComplianceReport,
|
||||||
createVirtualHalState,
|
createVirtualHalState,
|
||||||
@@ -25,6 +26,7 @@ const browserDiagnosticsArtifact = {
|
|||||||
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport({ halState: virtualHalState }),
|
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport({ halState: virtualHalState }),
|
||||||
virtualHalSimConfigSourceCoverage,
|
virtualHalSimConfigSourceCoverage,
|
||||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: virtualHalState }),
|
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: virtualHalState }),
|
||||||
|
virtualHalMotionControllerMatrix: createVirtualHalMotionControllerMatrixReport(),
|
||||||
};
|
};
|
||||||
assert.equal(createProjectReleaseBrowserDiagnosticsArtifactValidation(browserDiagnosticsArtifact).ready, true);
|
assert.equal(createProjectReleaseBrowserDiagnosticsArtifactValidation(browserDiagnosticsArtifact).ready, true);
|
||||||
const readyArtifactJson = JSON.stringify(createProjectReleaseReadinessReport({
|
const readyArtifactJson = JSON.stringify(createProjectReleaseReadinessReport({
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import {
|
|||||||
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
||||||
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
||||||
VIRTUAL_HAL_COVERAGE_STATES,
|
VIRTUAL_HAL_COVERAGE_STATES,
|
||||||
|
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||||
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
||||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||||
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
||||||
@@ -50,6 +51,7 @@ import {
|
|||||||
createLinuxCncInterpSdk,
|
createLinuxCncInterpSdk,
|
||||||
createLinuxCncVirtualHalRuntime,
|
createLinuxCncVirtualHalRuntime,
|
||||||
createVirtualHalIntegrityReport,
|
createVirtualHalIntegrityReport,
|
||||||
|
createVirtualHalMotionControllerMatrixReport,
|
||||||
createMachineSessionSnapshotPayload,
|
createMachineSessionSnapshotPayload,
|
||||||
createVirtualHalSessionPayload,
|
createVirtualHalSessionPayload,
|
||||||
createMachineSessionPersistenceDisplayViewModel,
|
createMachineSessionPersistenceDisplayViewModel,
|
||||||
@@ -233,6 +235,7 @@ const requiredExports = [
|
|||||||
["createVirtualHalBridgeReadiness", createVirtualHalBridgeReadiness],
|
["createVirtualHalBridgeReadiness", createVirtualHalBridgeReadiness],
|
||||||
["createVirtualHalCommandScriptFixtureReport", createVirtualHalCommandScriptFixtureReport],
|
["createVirtualHalCommandScriptFixtureReport", createVirtualHalCommandScriptFixtureReport],
|
||||||
["createVirtualHalIntegrityReport", createVirtualHalIntegrityReport],
|
["createVirtualHalIntegrityReport", createVirtualHalIntegrityReport],
|
||||||
|
["createVirtualHalMotionControllerMatrixReport", createVirtualHalMotionControllerMatrixReport],
|
||||||
["createVirtualHalPinInventory", createVirtualHalPinInventory],
|
["createVirtualHalPinInventory", createVirtualHalPinInventory],
|
||||||
["createVirtualHalPinRegistry", createVirtualHalPinRegistry],
|
["createVirtualHalPinRegistry", createVirtualHalPinRegistry],
|
||||||
["createVirtualHalProjectReport", createVirtualHalProjectReport],
|
["createVirtualHalProjectReport", createVirtualHalProjectReport],
|
||||||
@@ -501,6 +504,8 @@ assert.match(sdkIndexText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
|||||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
||||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
||||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
||||||
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES\b/);
|
||||||
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES\b/);
|
||||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
||||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
||||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS\b/);
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS\b/);
|
||||||
@@ -519,6 +524,8 @@ assert.match(sdkIndexText, /\bexecuteVirtualHalcmd\b/);
|
|||||||
assert.match(sdkReadmeText, /\bexecuteVirtualHalcmd\b/);
|
assert.match(sdkReadmeText, /\bexecuteVirtualHalcmd\b/);
|
||||||
assert.match(sdkIndexText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
assert.match(sdkIndexText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
||||||
assert.match(sdkReadmeText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
assert.match(sdkReadmeText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
||||||
|
assert.match(sdkIndexText, /\bcreateVirtualHalMotionControllerMatrixReport\b/);
|
||||||
|
assert.match(sdkReadmeText, /\bcreateVirtualHalMotionControllerMatrixReport\b/);
|
||||||
assert.match(sdkIndexText, /\bstepVirtualHalMotion\b/);
|
assert.match(sdkIndexText, /\bstepVirtualHalMotion\b/);
|
||||||
assert.match(sdkReadmeText, /\bstepVirtualHalMotion\b/);
|
assert.match(sdkReadmeText, /\bstepVirtualHalMotion\b/);
|
||||||
assert.match(sdkIndexText, /\bstepVirtualHalMotionController\b/);
|
assert.match(sdkIndexText, /\bstepVirtualHalMotionController\b/);
|
||||||
@@ -644,6 +651,19 @@ for (const action of ["setp", "sets", "net", "show", "getp", "gets", "loadrt", "
|
|||||||
assert.equal(commandScriptFixtureReport.coveredActions.includes(action), true);
|
assert.equal(commandScriptFixtureReport.coveredActions.includes(action), true);
|
||||||
}
|
}
|
||||||
assert.equal(virtualHalRuntime.getCommandScriptFixtureReport().complete, true);
|
assert.equal(virtualHalRuntime.getCommandScriptFixtureReport().complete, true);
|
||||||
|
assert.equal(VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES.length >= 3, true);
|
||||||
|
const motionControllerMatrixReport = createVirtualHalMotionControllerMatrixReport();
|
||||||
|
assert.equal(motionControllerMatrixReport.apiName, "linuxcnc-wasm-virtual-hal-motion-controller-matrix-report");
|
||||||
|
assert.equal(motionControllerMatrixReport.complete, true);
|
||||||
|
assert.equal(motionControllerMatrixReport.webSimulationSatisfied, true);
|
||||||
|
assert.equal(motionControllerMatrixReport.missingFixtures.length, 0);
|
||||||
|
assert.equal(motionControllerMatrixReport.sourceFiles.includes("linuxcnc/src/emc/motion/motion.c"), true);
|
||||||
|
assert.equal(motionControllerMatrixReport.sourceFiles.includes("linuxcnc/src/emc/motion/axis.c"), true);
|
||||||
|
assert.equal(motionControllerMatrixReport.requiredPins.includes("motion.distance-to-go"), true);
|
||||||
|
assert.equal(motionControllerMatrixReport.requiredPins.includes("motion.in-position"), true);
|
||||||
|
assert.equal(motionControllerMatrixReport.rows.some(({ id, inPosition }) => id === "xyz-multi-axis-in-position" && inPosition === true), true);
|
||||||
|
assert.equal(motionControllerMatrixReport.rows.every(({ axisFeedbackRows }) => axisFeedbackRows.every(({ matched }) => matched)), true);
|
||||||
|
assert.equal(virtualHalRuntime.getMotionControllerMatrixReport().complete, true);
|
||||||
const steppedVirtualHal = stepVirtualHalMotion(virtualHalRuntime.getState(), {
|
const steppedVirtualHal = stepVirtualHalMotion(virtualHalRuntime.getState(), {
|
||||||
target: { x: 3 },
|
target: { x: 3 },
|
||||||
maxVelocity: 10,
|
maxVelocity: 10,
|
||||||
@@ -688,6 +708,7 @@ assert.equal(replacementReport.sourceCompliance.complete, true);
|
|||||||
assert.equal(replacementReport.sourceCompliance.webSimulationSatisfied, true);
|
assert.equal(replacementReport.sourceCompliance.webSimulationSatisfied, true);
|
||||||
assert.equal(replacementReport.simConfigSourceCoverage.complete, true);
|
assert.equal(replacementReport.simConfigSourceCoverage.complete, true);
|
||||||
assert.equal(replacementReport.commandScriptFixtures.complete, true);
|
assert.equal(replacementReport.commandScriptFixtures.complete, true);
|
||||||
|
assert.equal(replacementReport.motionControllerMatrix.complete, true);
|
||||||
assert.equal(virtualHalRuntime.getSimulationReplacementReport().ready, true);
|
assert.equal(virtualHalRuntime.getSimulationReplacementReport().ready, true);
|
||||||
const simConfigSourceCoverageReport = createVirtualHalSimConfigSourceCoverageReport({ manifestText: sourceManifestText });
|
const simConfigSourceCoverageReport = createVirtualHalSimConfigSourceCoverageReport({ manifestText: sourceManifestText });
|
||||||
assert.equal(simConfigSourceCoverageReport.apiName, "linuxcnc-wasm-virtual-hal-sim-config-source-coverage-report");
|
assert.equal(simConfigSourceCoverageReport.apiName, "linuxcnc-wasm-virtual-hal-sim-config-source-coverage-report");
|
||||||
@@ -715,6 +736,7 @@ assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/src/emc/motio
|
|||||||
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini"), true);
|
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini"), true);
|
||||||
assert.equal(sourceComplianceReport.simConfigSourceCoverage.complete, true);
|
assert.equal(sourceComplianceReport.simConfigSourceCoverage.complete, true);
|
||||||
assert.equal(sourceComplianceReport.commandScriptFixtures.complete, true);
|
assert.equal(sourceComplianceReport.commandScriptFixtures.complete, true);
|
||||||
|
assert.equal(sourceComplianceReport.motionControllerMatrix.complete, true);
|
||||||
assert.equal(virtualHalRuntime.getSourceComplianceReport().complete, true);
|
assert.equal(virtualHalRuntime.getSourceComplianceReport().complete, true);
|
||||||
const virtualHalSessionPayload = createVirtualHalSessionPayload(virtualHalRuntime.getState(), {
|
const virtualHalSessionPayload = createVirtualHalSessionPayload(virtualHalRuntime.getState(), {
|
||||||
simConfigSourceCoverage: simConfigSourceCoverageReport,
|
simConfigSourceCoverage: simConfigSourceCoverageReport,
|
||||||
@@ -744,13 +766,16 @@ const browserDiagnosticsArtifactValidation = createProjectReleaseBrowserDiagnost
|
|||||||
virtualHalSourceCompliance: sourceComplianceReport,
|
virtualHalSourceCompliance: sourceComplianceReport,
|
||||||
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
||||||
virtualHalCommandScriptFixtures: commandScriptFixtureReport,
|
virtualHalCommandScriptFixtures: commandScriptFixtureReport,
|
||||||
|
virtualHalMotionControllerMatrix: motionControllerMatrixReport,
|
||||||
});
|
});
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.apiName, "project-release-browser-diagnostics-artifact-validation");
|
assert.equal(browserDiagnosticsArtifactValidation.apiName, "project-release-browser-diagnostics-artifact-validation");
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.ready, true);
|
assert.equal(browserDiagnosticsArtifactValidation.ready, true);
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.sourceComplianceReady, true);
|
assert.equal(browserDiagnosticsArtifactValidation.sourceComplianceReady, true);
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.simConfigSourceCoverageReady, true);
|
assert.equal(browserDiagnosticsArtifactValidation.simConfigSourceCoverageReady, true);
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.commandScriptFixturesReady, true);
|
assert.equal(browserDiagnosticsArtifactValidation.commandScriptFixturesReady, true);
|
||||||
|
assert.equal(browserDiagnosticsArtifactValidation.motionControllerMatrixReady, true);
|
||||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
||||||
|
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/src/emc/motion/axis.c"), true);
|
||||||
const runtimeProjectReport = virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS });
|
const runtimeProjectReport = virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS });
|
||||||
assert.equal(runtimeProjectReport.simulationRuntime.replacesHostRuntimeForSimulation, true);
|
assert.equal(runtimeProjectReport.simulationRuntime.replacesHostRuntimeForSimulation, true);
|
||||||
assert.equal(runtimeProjectReport.systemCoverage.unclassifiedSnapshotPins.length, 0);
|
assert.equal(runtimeProjectReport.systemCoverage.unclassifiedSnapshotPins.length, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user