Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | export type PartRole =
| 'FASTENER_PIN' // e.g. 2780 friction pin, 3673 frictionless pin, 6558 3L pin
| 'FASTENER_AXLE' // e.g. cross axles, axle pins
| 'FASTENER_BUSH' // e.g. 3713, 4265c bushes
| 'STRUCTURAL_BEAM' // e.g. technic liftarms, frames 5x7, 11x15
| 'CHASSIS_CORE' // e.g. SPIKE Prime Hub 45601
| 'MOTOR_STATOR' // Fixed motor housing (mounts rigidly to frame)
| 'MOTOR_ROTOR' // Active rotating output disc
| 'WHEEL_RIM' // Wheel hub
| 'WHEEL_TIRE' // Rubber tire
| 'CASTER_SKID' // Passive ball caster or skid
| 'SENSOR_COLOR' // Downward facing color sensor
| 'SENSOR_DISTANCE' // Ultrasonic sensor
| 'CHAIN_LINK' // Flexible / articulated chain or tread link
| 'GENERIC_RIGID';
export interface PartDefinition {
partNumber: string;
name: string;
role: PartRole;
massGrams: number;
dimensions: { x: number; y: number; z: number }; // In mm
colorHex?: number;
}
export interface PlacedPart {
id: string;
partNumber: string;
position: [number, number, number]; // [x, y, z] in mm or LDU
rotation: [number, number, number, number]; // Quaternion [x, y, z, w]
role: PartRole;
colorHex?: number;
submodel?: string;
submodelInstance?: string;
parentClusterId?: string;
meta?: Record<string, unknown>;
}
export interface ConnectionLink {
fromPartId: string;
toPartId: string;
connectionType: 'RIGID_PIN' | 'RIGID_FRAME' | 'REVOLUTE_AXLE' | 'FREE_ROTATION';
jointAxis?: [number, number, number];
anchor?: [number, number, number];
}
export interface ClusteredCompoundBody {
clusterId: string;
name: string;
isRootChassis: boolean;
isFixed?: boolean;
fieldPositionOffset?: [number, number, number];
partIds: string[];
totalMassKg: number;
parts?: PlacedPart[];
// Bounding or compound colliders
colliders: Array<{
shape: 'box' | 'cylinder' | 'sphere';
halfExtents?: [number, number, number];
radius?: number;
halfHeight?: number;
offset: [number, number, number];
rotation: [number, number, number, number];
friction: number;
restitution: number;
}>;
}
export interface ExtractedJoint {
jointId: string;
name: string;
type: 'REVOLUTE' | 'SPHERICAL';
parentClusterId: string;
childClusterId: string;
anchorParent: [number, number, number];
anchorChild: [number, number, number];
axis: [number, number, number];
motorPort?: 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
maxTorqueNm: number;
maxVelocityDegPerSec: number;
}
export interface PartBomEntry {
partNumber: string;
name: string;
count: number;
role: string;
colorHex?: number;
hasAccurateMesh: boolean;
}
import type { FllPhysicsSpec } from './physics-spec';
export interface RobotAssemblySpec {
name: string;
clusters: ClusteredCompoundBody[];
joints: ExtractedJoint[];
parts?: PlacedPart[];
bom?: PartBomEntry[];
physicsSpec?: FllPhysicsSpec;
isPreSolverDisabled?: boolean;
sensors: Array<{
id: string;
type: 'COLOR' | 'DISTANCE' | 'GYRO';
port?: 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
relativePosition: [number, number, number]; // relative to root chassis in meters
relativeOrientation: [number, number, number, number];
}>;
}
|