export enum ObjectType { AXIS_LINEAR = 'AXIS_LINEAR', AXIS_ROTARY = 'AXIS_ROTARY', CYLINDER = 'CYLINDER', SWITCH = 'SWITCH', LED = 'LED', } export interface Vec3 { x: number; y: number; z: number; } export interface BaseObject { id: string; name: string; type: ObjectType; position: Vec3; rotation: Vec3; // Euler angles in radians } export interface AxisPositionTrigger { id: string; position: number; condition: '>' | '<'; targetInputPort: number; // Sets this Input bit when condition met } export interface AxisData { id: number; // 0-7 name: string; value: number; target: number; speed: number; type: 'linear' | 'rotary'; } export interface AxisObject extends BaseObject { type: ObjectType.AXIS_LINEAR | ObjectType.AXIS_ROTARY; axisIndex: number; // 0-7, Binds to Global Axis min: number; max: number; triggers: AxisPositionTrigger[]; // Triggers still belong to the physical object placement } export interface CylinderObject extends BaseObject { type: ObjectType.CYLINDER; stroke: number; extended: boolean; currentPosition: number; speed: number; outputPort: number; // Reads this Output bit to extend } export interface SwitchObject extends BaseObject { type: ObjectType.SWITCH; isOn: boolean; isMomentary: boolean; inputPort: number; // Sets this Input bit when pressed } export interface LedObject extends BaseObject { type: ObjectType.LED; isOn: boolean; color: string; outputPort: number; // Reads this Output bit to turn on } // Memory Map Constants export const MEMORY_SIZE = 10000; export const ADDR_USER_START = 0; export const ADDR_USER_END = 7999; export const ADDR_AXIS_BASE = 8000; export const ADDR_AXIS_STRIDE = 100; // Axis Memory Layout (Offsets from Axis Base) export const OFF_AXIS_STATUS = 0; // Uint16 export const OFF_AXIS_CURRENT_POS = 2; // Float32 export const OFF_AXIS_TARGET_POS = 6; // Float32 export const OFF_AXIS_SPEED = 10; // Float32 export const OFF_AXIS_ACCEL = 14; // Float32 export const OFF_AXIS_DECEL = 18; // Float32 export type SimObject = AxisObject | CylinderObject | SwitchObject | LedObject; // Logic Types export enum LogicTriggerType { INPUT_BIT = 'INPUT_BIT', AXIS_COMPARE = 'AXIS_COMPARE', // Deprecated in favor of MEM_COMPARE, but kept for compatibility MEM_COMPARE = 'MEM_COMPARE', } export enum LogicActionType { OUTPUT_COIL = 'OUTPUT_COIL', AXIS_MOVE = 'AXIS_MOVE', // Deprecated in favor of Memory Write MEM_OPERATION = 'MEM_OPERATION', } export enum LogicCondition { IS_ON = 'IS_ON', IS_OFF = 'IS_OFF', GREATER = '>', LESS = '<', EQUAL = '==', GREATER_EQUAL = '>=', LESS_EQUAL = '<=', } export enum LogicMathOp { SET = '=', ADD = '+', SUB = '-', } export enum LogicAction { SET_ON = 'ON', SET_OFF = 'OFF', TOGGLE = 'TOGGLE', MOVE_ABS = 'MOVE_ABS', // Legacy MOVE_REL = 'MOVE_REL', // Legacy } export interface IOLogicRule { id: string; enabled: boolean; // Trigger triggerType: LogicTriggerType; inputPort: number; // For INPUT_BIT // Axis/Memory Trigger triggerAxisIndex: number; // For AXIS_COMPARE (Legacy) triggerCompareOp: LogicCondition; // >, <, == triggerValue: number; // For AXIS_COMPARE (Legacy) or MEM_COMPARE Constant triggerAddress: number; // For MEM_COMPARE (Address to check) // Action actionType: LogicActionType; outputPort: number; // For OUTPUT_COIL action: LogicAction; // For OUTPUT_COIL // Axis Action (Legacy) targetAxisIndex: number; targetAxisValue: number; // Memory Action memAddress: number; // Address to write to memOperation: LogicMathOp; // =, +, - memOperandValue: number; // Value to add/sub/set } // Full Project Export Type export interface ProjectData { version: string; objects: SimObject[]; logicRules: IOLogicRule[]; inputNames: string[]; outputNames: string[]; axes: AxisData[]; // Memory snapshot could be large, maybe store only non-zero or user logic? // For now, we won't persist full RAM, only config. }