import type { XyzacCapabilitySnapshot, XyzacKinematicsSnapshot } from "./protocol"; import { DEFAULT_MACHINE, MACHINE_DEFINITIONS } from "../../workspace/machine-definitions.mjs"; export const MACHINE_CASES = MACHINE_DEFINITIONS; export const XYZAC_CASE = DEFAULT_MACHINE.entrypoint; export const XYZAC_AXES: readonly string[] = DEFAULT_MACHINE.axes; export const XYZAC_COMMANDS = { power: "POWER", selectKinematics: "KINEMATICS_SELECT", clearVisual: "VISUAL_CLEAR", } as const; export const XYZAC_KINEMATICS = [ { type: 0, action: "switchkinsIdentity", label: "Identity", mcode: "M429" }, { type: 1, action: "switchkinsXyzac", label: "TCP: XYZAC", mcode: "M428" }, { type: 2, action: "switchkinsUserk", label: "User K", mcode: "M430" }, ] as const; export type XyzacGate = { action: string; enabled: boolean; reason: string; required_type?: number; visual_only?: boolean }; export type XyzacOperationTrace = { operation_id?: string; kind?: string; action?: string | null; phase?: string; reason?: string; response_kind?: string }; export type XyzacPanelView = { status: "ready" | "unavailable"; tick: number; stateHash: string; kinematics: XyzacKinematicsSnapshot | null; capability: XyzacCapabilitySnapshot | null; pose: XyzacKinematicsSnapshot["pose"] | null; joints: number[]; gates: Record; recovery: Record | null; machine: typeof DEFAULT_MACHINE; }; type XyzacPanelSource = { simulation_tick?: number; state_hash?: string; kinematics?: XyzacKinematicsSnapshot; xyzac?: XyzacCapabilitySnapshot; gates?: Record; authoritative?: Record; visual?: { pose?: Record; joints?: number[] }; }; export function projectXyzacPanel(snapshot: XyzacPanelSource | null | undefined): XyzacPanelView { const rawKinematics = snapshot?.kinematics; const rawCapability = snapshot?.xyzac; const machine = MACHINE_DEFINITIONS.find((entry) => entry.coordinates === rawKinematics?.coordinates) ?? DEFAULT_MACHINE; const kinematics = rawKinematics && rawKinematics.coordinates === machine.coordinates && rawKinematics.joint_count === machine.joint_count ? rawKinematics : null; const capability = rawCapability && rawCapability.coordinates === machine.coordinates && rawCapability.joint_count === machine.joint_count ? rawCapability : null; const visualPose = snapshot?.visual?.pose; const poseAxes = [...machine.coordinates.toLowerCase()]; const pose = visualPose && poseAxes.every((axis) => Number.isFinite(visualPose[axis])) ? { ...(kinematics?.pose ?? { x: 0, y: 0, z: 0, a: 0, b: 0, c: 0, u: 0, v: 0, w: 0 }), ...visualPose } : kinematics?.pose ?? null; const visualJoints = snapshot?.visual?.joints; const joints = visualJoints?.length === machine.joint_count ? visualJoints.slice(0, machine.joint_count) : kinematics?.joints ? [...kinematics.joints] : []; return { status: kinematics && capability ? "ready" : "unavailable", tick: snapshot?.simulation_tick ?? 0, stateHash: snapshot?.state_hash ?? "", kinematics, capability, pose, joints, gates: snapshot?.gates ?? {}, recovery: (snapshot?.authoritative?.recovery as Record | undefined) ?? null, machine, }; }