69 lines
3.2 KiB
TypeScript
69 lines
3.2 KiB
TypeScript
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<string, XyzacGate>;
|
|
recovery: Record<string, unknown> | null;
|
|
machine: typeof DEFAULT_MACHINE;
|
|
};
|
|
|
|
type XyzacPanelSource = {
|
|
simulation_tick?: number;
|
|
state_hash?: string;
|
|
kinematics?: XyzacKinematicsSnapshot;
|
|
xyzac?: XyzacCapabilitySnapshot;
|
|
gates?: Record<string, XyzacGate>;
|
|
authoritative?: Record<string, unknown>;
|
|
visual?: { pose?: Record<string, number>; 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<string, unknown> | undefined) ?? null,
|
|
machine,
|
|
};
|
|
}
|