import { describe, expect, it } from "vitest"; import { applyCalibrationRecords, commercialExtensionBoundaries, compareControllerLowSpeedRun, createResourceLibraryTemplate, detectBasicCollisions, generatePathFromGeometry, instantiateProcessTemplate, locateCollisionTime, sampleOlpProject, validateOlpProject } from "../../src/olp/index.js"; describe("OLP geometry, calibration, and multi-robot extensions", () => { it("generates path targets from points, edges, and curves", () => { const pointPath = generatePathFromGeometry( { kind: "points", points: [[500, 0, 0], [600, 0, 0]] }, { pathId: "point_path", speedId: "v_linear", zoneId: "z10" } ); const edgePath = generatePathFromGeometry( { kind: "edge", start: [0, 0, 0], end: [100, 0, 0], samples: 3 }, { pathId: "edge_path" } ); const curvePath = generatePathFromGeometry( { kind: "curve", controlPoints: [[0, 0, 0], [50, 50, 0], [100, 0, 0]], samples: 3 }, { pathId: "curve_path", targetPrefix: "curve" } ); expect(pointPath.targets.map((target) => target.pose)).toEqual([ [500, 0, 0, 0, 0, 0], [600, 0, 0, 0, 0, 0] ]); expect(edgePath.targets.map((target) => target.pose?.[0])).toEqual([0, 50, 100]); expect(curvePath.targets.map((target) => target.name)).toEqual(["curve_00", "curve_01", "curve_02"]); expect(curvePath.path.points.map((point) => point.motion)).toEqual(["movej", "movel", "movel"]); }); it("detects primitive collisions and locates the first time point", () => { const project = sampleOlpProject(); const report = detectBasicCollisions([ { time: 0, pointId: "p0", position: [100, 0, 0] }, { time: 1.25, pointId: "p1", position: [550, 0, -40] } ], project.resources.collisionObjects); expect(report.ok).toBe(false); expect(report.hits).toEqual([ expect.objectContaining({ objectId: "fixture_box", pointId: "p1", time: 1.25 }) ]); expect(locateCollisionTime(report)).toBe(1.25); }); it("saves and applies TCP/frame/base/external-axis calibration records", () => { const project = sampleOlpProject(); const calibrated = applyCalibrationRecords(project, [ { id: "tcp_cal_2", name: "tcp_cal_2", kind: "tcp", targetResourceId: "tool_gripper", poseDelta: [1, 2, 3, 0, 0, 0] }, { id: "fixture_cal_1", name: "fixture_cal_1", kind: "frame", targetResourceId: "frame_fixture", poseDelta: [10, 0, 0, 0, 0, 0] }, { id: "track_cal_1", name: "track_cal_1", kind: "external_axis", targetResourceId: "track_1", axisOffset: 2.5 } ]); expect(calibrated.resources.tools.find((tool) => tool.id === "tool_gripper")?.tcp).toEqual([1, 2, 103, 0, 0, 0]); expect(calibrated.resources.frames.find((frame) => frame.id === "frame_fixture")?.pose).toEqual([810, 0, 0, 0, 0, 0]); expect(calibrated.externalAxes[0]?.metadata).toEqual({ calibrationOffset: 2.5 }); expect(validateOlpProject(calibrated).ok).toBe(true); }); it("creates resource library and process template delivery boundaries", () => { const project = sampleOlpProject(); const library = createResourceLibraryTemplate(project); const template = instantiateProcessTemplate(project.processTemplates[0]!, "pick_op"); const boundaries = commercialExtensionBoundaries(); expect(library).toMatchObject({ robots: [{ id: "robot_1", brand: "abb", model: "IRB120" }], collisionObjects: [{ id: "fixture_box" }] }); expect(template).toEqual({ operationId: "pick_op", operationKind: "handling", defaults: { speedId: "v_linear", zoneId: "z10" }, deliveryTags: ["source", "post", "report"] }); expect(boundaries).toEqual(expect.arrayContaining([ expect.objectContaining({ feature: "cad_kernel", mvp: false }), expect.objectContaining({ feature: "delivery_package", mvp: true }) ])); }); it("reports multi-robot/external-axis low-speed controller verification boundaries", () => { const project = sampleOlpProject(); const report = compareControllerLowSpeedRun([ { pointId: "p01", offline: [500, 0, 0, 0, 0, 0], measured: [501, 0, 0, 0.1, 0, 0], speedPercent: 10 }, { pointId: "p02", offline: [600, 0, 0, 0, 0, 0], measured: [604, 0, 0, 0.5, 0, 0], speedPercent: 10 } ], { positionMm: 5, orientationDeg: 1 }); expect(project.motionGroups[0]).toMatchObject({ robotIds: ["robot_1"], externalAxisIds: ["track_1"] }); expect(report).toMatchObject({ status: "pass", speedPercent: 10, maxPositionErrorMm: 4, maxOrientationErrorDeg: 0.5 }); expect(report.boundaries).toEqual(expect.arrayContaining([ expect.stringContaining("does not open a live controller communication session"), expect.stringContaining("does not include a full CAD kernel") ])); }); });