Galatea — Humanoid Robotic Mannequin and Fashion Robotics Platform
This document specifies the contracts that actually exist in libs/galatea/*.
Every type, schema, enum, state machine, store, and event listed here is
traceable to source. Galatea is a pure library domain: it has no apps/ or
services/ projects. Items not yet implemented are explicitly marked
(planned).
This is a reference document, not a tutorial. The Features doc explains what
each library does and why; this document records exactly what is exported:
field names, constraints, enum values, method signatures, and package structure.
A new engineer reading this doc should treat it as the ground truth for
understanding what they can import from any @galatea/* package.
Table of Contents#
- Domain Scope and Project Layout
- Core Domain Model (
@galatea/core) - Error Taxonomy and Recovery (
@galatea/core) - Runtime Configuration (
@galatea/core) - Physical Constants and Safety Thresholds (
@galatea/core) - Kinematics (
@galatea/kinematics) - Safety (
@galatea/safety) - Choreography and Show Authoring (
@galatea/choreography) - Fleet Orchestration (
@galatea/fleet) - Event Handlers (
@galatea/event-handlers) - Persistence (
@galatea/database) - SDKs (
@galatea/sdk) - Firmware and Hardware Abstraction (Rust manifests)
- Other Library Surfaces
- V2 Vehicle-As-Articulated-Body Modeling Surface
- Technology Stack
- Acceptance Criteria
1. Domain Scope and Project Layout#
Galatea is organised as 20 module directories under libs/galatea/
(established by TODOS Phase 63.1.1.1). Four of those directories — database,
event-handlers, inclusivity, sdk — are split into sub-packages, so the
domain currently builds 36 packages (36 package.json) tracked by 37
project.json files (the four split directories carry an aggregator
project.json in addition to one per sub-package).
The table below maps each module directory to the package names it produces. Directories without sub-packages each produce a single package named after the directory.
| Module directory | Packages |
|---|---|
core |
@galatea/core |
firmware |
@galatea/firmware |
hardware-abstraction |
@galatea/hardware-abstraction |
kinematics |
@galatea/kinematics |
locomotion |
@galatea/locomotion |
whole-body-control |
@galatea/whole-body-control |
pose-engine |
@galatea/pose-engine |
choreography |
@galatea/choreography |
perception |
@galatea/perception |
ai |
@galatea/ai |
garment-management |
@galatea/garment-management |
fleet |
@galatea/fleet |
analytics |
@galatea/analytics |
simulation |
@galatea/simulation |
safety |
@galatea/safety |
communication |
@galatea/communication |
database |
@galatea/database/{event-store,garment-store,pose-store,show-store,telemetry-store} |
event-handlers |
@galatea/event-handlers/{customer-events,garment-events,robot-events,safety-events,show-events} |
inclusivity |
@galatea/inclusivity/{accessibility,body-profiles,cultural-config,multilingual} |
sdk |
@galatea/sdk, @galatea/sdk/show-sdk, @galatea/sdk/analytics-sdk, plus the client-python Python package |
Every package exports GALATEA_LIBRARY_ID and getGalateaLibraryId() from its
src/index.ts. All packages are version: 0.1.0, type: module, with
publishConfig.access: restricted.
2. Core Domain Model (@galatea/core)#
@galatea/core is the dependency-free foundation for the entire domain.
src/index.ts re-exports types/, constants/, utils/, errors/,
config/. Every other @galatea/* package imports from this one. The sections
below document each major module in src/.
2.1 Robot State Types (src/types/robot-state.ts)#
These types represent the complete observable state of a robot at a single point in time. They are used throughout the domain as the authoritative representation of what a robot is doing, where its joints are, and what its sensors are reporting.
The robot has at minimum 52 degrees of freedom:
export const MIN_ROBOT_DOF = 52. All joint vectors are validated against this
floor.
JointSegment (Zod enum JointSegmentSchema)#
JointSegment groups the robot's joints into anatomical regions. It is used to
target commands, apply region-specific safety limits, and annotate sensor data.
head_neck · torso_spine · left_arm · right_arm · left_hand ·
right_hand · left_leg · right_leg · morphing.
JointState / JointStateSchema#
JointState carries the full runtime state of a single joint, including its
position, velocity, applied torque, and the raw electrical and thermal readings
from the actuator. The field constraints reflect physical hardware limits.
| Field | Type | Constraints |
|---|---|---|
jointId |
string |
non-empty (trimmed) |
segment |
JointSegment |
enum |
position |
number |
finite |
velocity |
number |
finite |
torque |
number |
finite |
temperature |
number |
finite, −40 … 180 |
current |
number |
finite, −250 … 250 (Amperes) |
encoderRaw |
number |
non-negative integer |
Vector3 / Quaternion#
These are the fundamental geometric primitives used throughout the domain for
positions, velocities, forces, and orientations. QuaternionSchema additionally
superRefines that the quaternion norm is > 0.0001 to reject degenerate
(zero-length) quaternions that would cause division-by-zero in rotation math.
Vector3 = { x, y, z }, all finite. Quaternion = { x, y, z, w }, all
finite.
Sensor types#
The following types model the outputs of the robot's sensor subsystems. Each type corresponds directly to a hardware sensor category.
ImuState—orientation: Quaternion,angularVelocity: Vector3,linearAcceleration: Vector3.ForceTorqueState—sensorId,frame,force: Vector3,torque: Vector3.TactileTaxelState—taxelId,pressureKPa(non-negative),shearXKPa,shearYKPa,temperature(−20 … 120).TactileSensorState—panelId,contactDetected,taxels[](≥ 1).PressureCellState—cellId,pressureKPa,healthy.PressureArrayState—arrayId,location: PressureArrayLocation,cells[](≥ 1),centerOfPressureMm: { x, y }.ProximityState—sensorId,distanceMm(non-negative),confidence(0 … 1),objectDetected.SensorState— aggregatesimu,forceTorque[],tactile[],pressure[],proximity[]; each array must have ≥ 1 element.
PressureArrayLocation (Zod enum) identifies where each foot/hand pressure
array is mounted: left_foot · right_foot · left_hand · right_hand ·
torso.
BodyMorphState / BodyMorphStateSchema#
BodyMorphState tracks the robot's current body dimension configuration when
the body-morphing subsystem is active. All measurements are in centimeters.
bustCm (50–150), waistCm (40–150), hipsCm (60–160), shouldersCm (25–80),
heightCm (130–220), morphingActive: boolean, lastMorphAt (ISO-8601 with
offset).
GarmentState / GarmentFitStatus#
GarmentFitStatus describes the current state of garment fitting on the robot.
GarmentState associates an outfit identifier with its RFID tags and fit
status; superRefine rejects duplicate RFID tags (a garment cannot have the
same tag twice).
GarmentFitStatus enum: not_fitted · fitting · fitted ·
adjustment_required · invalid_fit. GarmentState =
{ outfitId, rfidTags[] (≥ 1), fitStatus }.
BatteryState#
BatteryState represents the complete electrical state of the robot's power
system, including charge level, voltage, current draw, temperature, health
degradation, and charge cycle count.
stateOfChargePercent (0–100), voltage (≥ 0), current (finite),
temperature (−30 … 100), healthPercent (0–100), cycleCount (non-negative
integer).
RobotOperationMode (Zod enum)#
RobotOperationMode is the top-level mode of the robot's control software.
Transitions between modes are gated by the safety and fleet systems.
booting · idle · teleop · autonomous · show_execution · safe_stop ·
fault.
RobotState / RobotStateSchema#
RobotState is the complete snapshot of a robot at a moment in time. It
aggregates all of the types above. The superRefine pass enforces that
jointStates length matches the joint-vector length and that all jointIds are
unique, preventing partial or contradictory state objects.
| Field | Type | Constraints |
|---|---|---|
robotId |
string |
non-empty |
sequence |
number |
non-negative integer |
timestamp |
string |
ISO-8601 with offset |
operationMode |
RobotOperationMode |
enum |
jointStates |
JointState[] |
≥ MIN_ROBOT_DOF entries |
jointPositions |
number[] |
≥ MIN_ROBOT_DOF, all finite |
jointVelocities |
number[] |
length must equal jointPositions |
jointTorques |
number[] |
length must equal jointPositions |
sensorState |
SensorState |
— |
bodyMorphState |
BodyMorphState |
— |
garmentState |
GarmentState |
— |
batteryState |
BatteryState |
— |
Helpers: parseRobotState(input) and the type guard isRobotState(input).
2.2 Pose and Motion Types (src/types/pose-motion.ts)#
These types describe how the robot moves: individual poses, trajectories through joint space, motion primitives, and the abstract syntax tree used for choreography scripts.
PoseSegmentName(Zod enum) — same nine values asJointSegment.PoseSegmentRange—{ segment, startIndex, endIndex };endIndex >= startIndex.Pose—poseId,label,capturedAt(ISO-8601),jointAngles[](≥MIN_ROBOT_DOF),namedSegments: PoseSegmentRange[](≥ 1).superRefinerejects duplicate segments, out-of-rangeendIndex, and overlapping ranges.PoseCategory(Zod enum) — classifies poses for the pose library and garment compatibility matching:runway·editorial·commercial·lifestyle·dramatic·neutral·transition·gesture.GarmentCompatibility—{ garmentClass, compatibilityScore (0–1) }.PoseMetadata—poseId,category,style,garmentCompatibility[](≥ 1),stabilityScore(0–1),tags[].TrajectoryPoint—atMs,pose,jointVelocityProfile[],jointAccelerationProfile[](both ≥MIN_ROBOT_DOF, lengths must matchpose.jointAngles).VelocityProfile(Zod enum) — describes how joint velocity varies along a trajectory:constant·trapezoidal·minimum_jerk·s_curve·custom.AccelerationProfile(Zod enum) — describes how joint acceleration varies along a trajectory:constant·parabolic·minimum_jerk·s_curve·custom.Trajectory—trajectoryId,name,points[](≥ 2),velocityProfile,accelerationProfile.superRefineenforces strictly increasingatMs.GaitParameters—strideLengthMeters(0.05–2.5),frequencyHz(0.2–4.5),hipSwayMeters(0–0.4),armSwingDegrees(0–90),crossoverRatio(0–1).BlendCurve(Zod enum) — the interpolation curve used when blending between poses:linear·ease_in·ease_out·ease_in_out·cubic·custom.MotionPrimitiveBlending—blendInMs,blendOutMs,blendCurve,compatiblePrimitiveIds[].MotionPrimitive—primitiveId,name,trajectory,gaitParameters,blending.
Choreography AST#
The choreography model is an abstract syntax tree of timed nodes, not a flat
cue list. This structure lets the show engine reason about timing relationships
and validate them before execution. The AST is the runtime representation
produced by parsing a ChoreographyScript.
FormationPattern (Zod enum) — the geometric arrangement of robots on stage:
line · v · arc · grid · staggered · runway_cross. CueDomain (Zod
enum) — which production system a cue targets: lighting · audio · video ·
effects · narration · automation.
The node union ChoreographyAstNode is discriminated by nodeType. Each node
type carries a TimingWindow and node-specific fields:
nodeType |
Extra fields |
|---|---|
motion_call |
timing, primitiveId, robotIds[] (≥ 1) |
formation_change |
timing, formation: FormationSpec |
cue_trigger |
timing, cueId, cueDomain |
wait |
timing |
TimingWindow = { startMs, durationMs }. ChoreographyScript =
{ scriptId, showId, version, totalDurationMs, ast[] (≥ 1) }. superRefine
enforces non-decreasing startMs, that node timing never exceeds
totalDurationMs, and unique cueIds. Parse helpers: parsePose,
parsePoseMetadata, parseTrajectory, parseMotionPrimitive,
parseChoreographyScript.
2.3 Math Utilities (src/utils/)#
@galatea/core also exports math utility modules used throughout the domain.
These are low-level building blocks for the kinematics and control packages.
quaternion.ts, se3.ts (SE(3) rigid-body transforms; exports
toRotationMatrix used by IK), trajectory-interpolation.ts,
procedural-motion.ts.
3. Error Taxonomy and Recovery (@galatea/core)#
Rather than using generic Error objects, Galatea defines a typed error
hierarchy so that error-handling code can make decisions based on which
subsystem failed and how severe the failure is. This section documents that
hierarchy and the recovery infrastructure built on top of it.
3.1 error-taxonomy.ts#
The following enums define the classification axes for Galatea errors. Every error carries a severity and a subsystem identifier, and the escalation routes are derived deterministically from those two values.
GalateaErrorSeverity: info · warning · critical · safety-critical.
GalateaSubsystem: firmware · kinematics · locomotion · perception ·
ai · safety. EscalationRoute: observability-log · operator-console ·
fleet-supervisor · safety-controller · emergency-stop-chain.
resolveEscalationRoutes(severity, subsystem) derives routes deterministically
(e.g. safety-critical always appends emergency-stop-chain). The base
GalateaError class carries code, severity, subsystem, optional context
(robotId, correlationId, metadata), occurredAt (normalised ISO
timestamp), and computed escalationRoutes; toJSON() serialises all of these.
Type guard: isGalateaError(value).
Each subsystem has its own error subclass with a narrowed code union. The table below lists the allowed error codes per subsystem class.
| Class | Code union |
|---|---|
FirmwareError |
motor_fault · sensor_fault · communication_fault · safety_fault |
KinematicsError |
ik_failure · singularity · joint_limit_violation |
LocomotionError |
balance_loss · footstep_failure · gait_fault |
PerceptionError |
slam_failure · detection_failure · camera_fault |
AIError |
policy_confidence_low · ood_detection · inference_timeout |
SafetyError |
force_limit · e_stop · stability_margin |
3.2 error-recovery.ts#
error-recovery.ts provides the infrastructure for automated error recovery,
retry policies, and audit logging. The ErrorRecoveryManager orchestrates the
full lifecycle: classify the error, attempt recovery with backoff, degrade
gracefully if recovery fails, and write an immutable audit record of every
attempt.
RecoverySafeState— the safe state reached after failed recovery:operational·degraded·safe_stop·emergency_stop.RetryBackoffPolicy,RecoveryAuditEventInput,RecoveryAuditEvent.ImmutableRecoveryEventStoreinterface +InMemoryImmutableRecoveryEventStoreimplementation (append-only audit log).RecoveryExecutionOptions<T>,RecoveryExecutionResult<T>,OperatorNotifier.isTransientError(error),resolveDegradationPath(error).ErrorRecoveryManager— orchestrates retry/backoff, degradation, and audit.- Factory helpers:
createTransientFirmwareError,createCriticalSensorError,createSafetyCriticalError,createTransientAIError.
4. Runtime Configuration (@galatea/core)#
src/config/runtime-config.ts defines GalateaRuntimeConfigSchema (a strict
Zod object) and its inferred type GalateaRuntimeConfig. All configuration for
the Galatea runtime — database URLs, messaging brokers, compute device,
per-sensor enable flags, safety overrides, and feature flags — flows through
this single validated schema.
4.1 Config shape#
The config is divided into sections covering infrastructure, hardware capabilities, safety parameters, and feature flags. The table below lists each section and its fields.
| Section | Fields |
|---|---|
database |
primaryUrl, telemetryUrl, eventStoreUrl (all URLs) |
redis |
url |
nats |
servers[] (≥ 1 URL), streamName |
mqtt |
brokerUrl, clientId, optional username/password, qos (0–2) |
compute |
device: ComputeDevice (jetson-thor | jetson-orin) |
sensors |
booleans: imu, forceTorque, tactile, pressure, proximity, camera, lidar |
safetyOverrides |
maxTcpVelocityMmPerSec, forceLimitScale, pressureLimitScale, supportPolygonMarginScale, emergencyStopDecelerationScale |
logging |
level: fatal|error|warn|info|debug|trace |
featureFlags |
booleans: vla, lbm, morphing, showEngine, teleoperation, fleetAnalytics |
safetyOverrides are clamped to CERTIFIED_SAFETY_OVERRIDE_BOUNDS to prevent
operators from inadvertently configuring unsafe parameters:
maxTcpVelocityMmPerSec 50–250, forceLimitScale 0.5–1.0, pressureLimitScale
0.5–1.0, supportPolygonMarginScale 1.0–2.0, emergencyStopDecelerationScale
1.0–1.5.
4.2 Loading#
The config loader supports a layered merge strategy so that defaults can be overridden by file, environment, and in-process overrides without any layer silently winning over a more specific one.
DEFAULT_GALATEA_RUNTIME_CONFIG provides the baseline.
loadGalateaRuntimeConfig(options) deep-merges, in order: defaults → JSON file
(GALATEA_CONFIG_FILE or configFilePath) → environment overlay → explicit
runtimeOverrides; the merged result is validated by the schema.
GalateaRuntimeConfigManager wraps the loader with getConfig(),
getSubsystemConfig(key), reload(), and applyRuntimeOverride().
4.3 Environment variables consumed#
Every field in the config schema has a corresponding environment variable. The following variables are read during config loading.
GALATEA_CONFIG_FILE, GALATEA_DATABASE_PRIMARY_URL,
GALATEA_DATABASE_TELEMETRY_URL, GALATEA_DATABASE_EVENT_STORE_URL,
GALATEA_REDIS_URL, GALATEA_NATS_SERVERS (CSV), GALATEA_NATS_STREAM_NAME,
GALATEA_MQTT_BROKER_URL, GALATEA_MQTT_CLIENT_ID, GALATEA_MQTT_USERNAME,
GALATEA_MQTT_PASSWORD, GALATEA_MQTT_QOS, GALATEA_COMPUTE_DEVICE,
GALATEA_SENSOR_{IMU,FORCE_TORQUE,TACTILE,PRESSURE,PROXIMITY,CAMERA,LIDAR}_ENABLED,
GALATEA_SAFETY_MAX_TCP_VELOCITY_MM_PER_SEC,
GALATEA_SAFETY_FORCE_LIMIT_SCALE, GALATEA_SAFETY_PRESSURE_LIMIT_SCALE,
GALATEA_SAFETY_SUPPORT_POLYGON_MARGIN_SCALE,
GALATEA_SAFETY_ESTOP_DECEL_SCALE, GALATEA_LOG_LEVEL,
GALATEA_FEATURE_{VLA,LBM,MORPHING,SHOW_ENGINE,TELEOPERATION,FLEET_ANALYTICS}.
5. Physical Constants and Safety Thresholds (@galatea/core)#
@galatea/core exports a complete set of physical constants describing the
robot's body geometry, joint kinematic chain, actuator specs, and
safety-critical force limits. These constants are the authoritative source of
truth for physically meaningful values used across the domain — the kinematics
solver, safety monitor, and locomotion controller all read from here.
5.1 physical-constants.ts#
This file defines the robot's kinematic skeleton and the physical properties of every link and actuator.
GALATEA_JOINT_KINEMATIC_CHAIN— the full ordered joint chain built from per-segment templates. For example, thehead_necksegment defines jointsneck_yaw,neck_pitch,neck_roll, andjaw_pitch; theleft_armsegment definesleft_shoulder_pitch/roll/yaw,left_elbow_pitch,left_forearm_roll, andleft_wrist_pitch/yaw. Each entry is aJointKinematicDescriptorwithindex,jointId,segment,parentLinkId,childLinkId,axis.GALATEA_DOF— the chain length (the actual DOF count).GALATEA_JOINT_LIMITS—JointLimitSpec[](lowerAngleRad,upperAngleRad,maxVelocityRadPerSec, …) derived from the chain.GALATEA_DH_PARAMETERS—DenavitHartenbergParameter[].GALATEA_LINK_INERTIA_SPECS—LinkInertiaSpec[].GALATEA_BODY_SEGMENT_LENGTHS—BodySegmentLengthSpec[].GALATEA_ACTUATOR_SPECS—ActuatorSpecification[].GALATEA_SENSOR_SPECS—SensorSpecification[];SensorType=imu·force_torque·tactile·pressure·proximity.- Lookups:
getJointLimitSpec,getDenavitHartenbergParameter,getActuatorSpecification.
5.2 safety-thresholds.ts#
This file encodes the ISO 13482-derived force and pressure limits for each body region, the emergency stop deceleration profiles, and the standstill zone radii. Every safety decision in the force-limiting and emergency-systems modules derives its thresholds from these constants.
BodyRegion (12 regions): skull · forehead · neck · shoulder ·
upper_arm · forearm · hand · chest · abdomen · thigh · calf ·
lower_leg.
MAX_TCP_VELOCITY_NEAR_HUMANS_MM_PER_SEC = 250.BODY_REGION_FORCE_LIMITS— per-regiontransientNewton/quasiStaticNewtonlimits (e.g.skull130 / 65,neck110 / 55,shoulder180 / 90).BODY_REGION_PRESSURE_LIMITS_KPA— per-regionmaxPressureKPa.REDUCED_SUPPORT_POLYGON_MARGIN_METERS—SupportPolygonMargin(front/rear/left/rightmetres).EMERGENCY_STOP_DECELERATION_PROFILES—EmergencyStopDecelerationProfile[], each taggedcategory_0/category_1/category_2with linear/angular deceleration, jerk, and nominal stop time.SAFE_STANDSTILL_ZONE_RADII_METERS.- Helpers:
getForceLimitForBodyRegion,getPressureLimitForBodyRegion,getEmergencyStopProfile,isTcpVelocitySafeNearHumans,isContactForceWithinLimit,isContactPressureWithinLimit,classifyStandstillZonereturningStandstillZoneClassification(touch·approach·outside).
5.3 morphing-constants.ts#
morphing-constants.ts defines the physical operating limits for the
body-morphing subsystem, which controls pneumatic bladders to adjust body
segment dimensions.
MorphProfileCm, MorphMeasurementRangeCm, MorphSpeedLimits,
MorphRepeatabilityTolerance, BladderPneumaticPressureLimits. Constants:
MORPH_MEASUREMENT_RANGES_CM, MORPH_SPEED_LIMITS_CM_PER_SEC,
MORPH_REPEATABILITY_TOLERANCE, BLADDER_PNEUMATIC_PRESSURE_LIMITS_KPA.
Helpers: isMorphProfileWithinRange, clampMorphProfileToRange,
isBladderPressureWithinOperatingRange, isBladderPressureWithinAbsoluteLimit.
6. Kinematics (@galatea/kinematics)#
@galatea/kinematics contains six computation modules. Each module pairs a
TypeScript implementation with a *-rust-manifest.ts describing the planned
Rust crate that will replace the TypeScript for production real-time use. The
TypeScript implementations are fully functional and used in simulation and
development; the Rust crates will be used on the embedded control targets.
The six modules are: forward-kinematics, inverse-kinematics, dynamics,
jacobian-computation, collision-geometry, urdf-parser.
6.1 Forward kinematics (forward-kinematics.ts)#
JointAnglesRad = Readonly<Partial<Record<string, number>>>. Types:
FootContactGeometry, FootContactState, ForwardKinematicsOptions,
FramePose, CenterOfMassEstimate, SupportPolygon,
ForwardKinematicsResult. computeFullBodyForwardKinematics(jointMap) returns
link transforms (4×4 matrices keyed by link ID), a center-of-mass estimate, and
a support polygon. getLinkTransform(...) resolves a single link.
6.2 Inverse kinematics (inverse-kinematics.ts)#
The IK solver is the most complex module in the domain. It resolves multiple competing task objectives (end-effector position, balance, gaze direction, preferred posture) simultaneously using a priority hierarchy and null-space projection. The algorithm is described in the Features doc; this section documents the exact type contracts.
IkTaskType: end_effector · center_of_mass · gaze · posture. The task
union InverseKinematicsTask is discriminated by type. The table below shows
the distinguishing fields for each variant; all tasks also share id, type,
priority, optional weight, and tolerance.
| Variant | Distinguishing fields |
|---|---|
EndEffectorIkTask |
linkId, optional targetPositionMeters / targetOrientation, optional workspaceBounds |
CenterOfMassIkTask |
targetPositionMeters |
GazeIkTask |
targetDirection, optional linkId |
PostureIkTask |
targetJointAnglesRad (partial joint map) |
InverseKinematicsRequest fields: currentJointAnglesRad, tasks[],
dtSeconds, maxIterations, damping, convergenceTolerance,
numericalJacobianStepRad, maxJointVelocityScale, jointLimitMarginRad,
workspaceBounds, selfCollisionAvoidance
({ enabled, minimumHandDistanceMeters }). WorkspaceBounds is an axis-aligned
box (xMin/xMax/yMin/yMax/zMin/zMax metres).
solveWholeBodyInverseKinematics(request) returns InverseKinematicsResult:
backend: 'hierarchical-qp-osqp-compatible', iterations, converged,
jointAnglesRad, jointVelocitiesRadPerSec, taskReports: IkTaskReport[]
(per-task errorNorm, tolerance, satisfied, degraded, optional note),
degradedTaskIds. The algorithm clamps solver parameters, solves
damped-least-squares per priority level, projects lower-priority tasks into the
null space of higher-priority ones, applies joint-limit / velocity constraints,
and optionally enforces hand-to-hand self-collision avoidance.
6.3 Other kinematics modules#
dynamics.ts, jacobian-computation.ts, collision-geometry.ts, and
urdf-parser.ts provide recursive-Newton-Euler dynamics, geometric/analytical
Jacobians, swept-volume / self-collision checks, and URDF/XACRO parsing
respectively. Each module pairs its TypeScript implementation with a
corresponding *-rust-manifest.ts.
7. Safety (@galatea/safety)#
@galatea/safety is organized into eight modules. Safety is the most
architecturally significant package in the domain: its outputs gate every motion
command and its events write to the append-only audit log. The three primary
modules — ISO 13482 compliance, force limiting, and emergency systems — are
documented in detail here.
Eight modules: access-control, audit-logger, emergency-systems,
force-limiting, functional-safety, iso-13482, regulatory-toolkit,
risk-assessment.
7.1 ISO 13482 compliance engine (iso-13482/iso-13482.ts)#
Iso13482ComplianceEngine is a stateful HAZOP + checklist register. It
maintains a database of operating states, hazard entries (with guidewords, risk
scores, and status), and checklist items against specific ISO clause numbers. At
any point, getComplianceSummary and generateComplianceAuditDocument produce
reports that can be used for certification.
OperatingStateId identifies the robot's operational contexts, which are the
subjects of the HAZOP analysis. Eight states are seeded by default: idle ·
walking · customer_interaction · garment_change · charging ·
maintenance · protective_stop · emergency_stop.
HazopGuideWord encodes the structured HAZOP deviation vocabulary: NO_OR_NOT
· MORE · LESS · AS_WELL_AS · PART_OF · REVERSE · OTHER_THAN.
HazopEntryStatus tracks the resolution state of each hazard: open ·
mitigated · accepted · closed.
Iso12100RiskFactors = { severity, probability, exposure }; each factor is
clamped to integer 1–5. assessIso12100Risk computes score = S × P × E and
maps the score to an Iso12100RiskLevel: score ≥ 80 → intolerable,
≥ 45 → high, ≥ 20 → medium, else low; actionRequired is true for
high/intolerable.
ComplianceChecklistStatus: not_started · in_progress · compliant ·
non_compliant · not_applicable. Five DEFAULT_CHECKLIST_ITEMS are seeded
against clauses ISO 13482:2014 §5.4, §5.5, §5.6, §6 and ISO 12100:2010.
Engine methods: listOperatingStates, registerOperatingState,
createHazopEntry, updateHazopEntryStatus, listHazopEntries,
upsertChecklistItem, listChecklistItems, evaluateOperatingStateCoverage,
getComplianceSummary (returns Iso13482ComplianceSummary with hazard totals,
checklist totals, and operating-state coverage),
generateComplianceAuditDocument (returns a ComplianceAuditDocument including
a Markdown audit package). Factory: createIso13482ComplianceEngine.
7.2 Force limiting (force-limiting/force-limiting.ts)#
ForceLimitingEngine evaluates incoming contact samples against the per-body-
region force and pressure limits from safety-thresholds.ts and emits an
action: continue normally, reduce speed, or trigger a protective stop.
ContactEvaluationMode: transient · quasi_static. ForceLimitingAction:
normal · reduce_speed · protective_stop. Types: TactileContactSample,
ForceTorqueContactSample, EvaluateForceLimitingRequest,
BodyRegionForceAssessment, ForceLimitingEvaluationResult,
ForceLimitingValidationScenario, ForceLimitingValidationSuiteResult.
Factory: createForceLimitingEngine.
7.3 Emergency systems (emergency-systems/emergency-systems.ts)#
EmergencySystemsEngine is the stateful manager for emergency stop and
protective stop events. It maintains an event log of every trigger and recovery,
which provides the audit trail required for ISO 13482 compliance.
EmergencyOperatingMode, EmergencyStopCategory (category_0 · category_1),
EmergencyTriggerSource, EmergencyRecoveryAction, EmergencyEventType. State
and request/result types cover E-stop activation and recovery, protective-stop
activation and clearance, and proximity-safety assessment
(ProximitySafetyInput / ProximitySafetyAssessment). EmergencySystemsEngine
maintains an EmergencyEventLogEntry history and exposes an
EmergencySystemsSnapshot. Factory: createEmergencySystemsEngine.
7.4 Other safety modules#
The remaining four modules provide supporting safety infrastructure.
access-control governs operator authorisation. audit-logger maintains the
safety audit trail. functional-safety implements watchdog and heartbeat
monitoring. regulatory-toolkit generates CE/UL documentation.
risk-assessment implements ISO 12100 hazard identification.
8. Choreography and Show Authoring (@galatea/choreography)#
@galatea/choreography provides everything needed to author, validate, and
execute multi-robot fashion shows. It is organized into nine modules. The core
module is show-designer, which maintains the ShowDocument — the central
authored artefact that captures all show content.
Nine modules: show-designer, show-dsl, formation-engine, music-sync,
lighting-bridge, stage-mapper, timing-engine, rehearsal-engine,
show-scheduler.
8.1 Show document model (show-designer/show-designer.ts)#
The ShowDocument is the central authored artefact. It holds all the
information needed to execute a show: which robots participate, their track
events, formations, music sync points, lighting cues, and outfit change timing.
ShowTrackType identifies the type of motion event on a robot's track:
entrance · walk · pose · pivot · exit. FormationType describes the
spatial arrangement of robots: line · v · scatter · pair · arc ·
custom. CollaborationRole identifies what kind of access a collaborator has
to the show document: designer · director · programmer · producer ·
observer.
The ShowDocument schema is:
| Field | Type |
|---|---|
showId |
string |
title |
string |
description |
string? |
durationMs |
number |
createdAtMs / updatedAtMs |
number |
revision |
number |
robots |
ShowRobot[] |
trackEvents |
ShowTrackEvent[] |
formationMarkers |
FormationMarker[] |
musicSyncPoints |
MusicSyncPoint[] |
lightingCues |
LightingCue[] |
outfitChangeTriggers |
OutfitChangeTrigger[] |
Sub-types include ShowRobot (robotId, displayName, optional modelId,
defaultOutfitId), ShowTrackEvent (timed waypoints/poseId/
pivotAngleDeg), FormationMarker (timed robotPositions), MusicSyncPoint
(barNumber, beatInBar, tempoBpm, phraseLabel), LightingCue
(colorHex, intensityPercent, optional artNetUniverse / sacnUniverse /
followRobotId, channelValues), and OutfitChangeTrigger (outfitId,
changeWindowMs, blocking).
8.2 Editing operations#
The show designer uses an operation-based editing model (similar to CRDT
document editors) where every change to a ShowDocument is represented as a
typed operation. This enables optimistic concurrency, undo/redo, and
collaboration.
ShowDesignerOperation is a discriminated union of 16 operation types —
update_show_metadata plus add/update/remove triplets for track_event,
formation_marker, music_sync_point, lighting_cue, and
outfit_change_trigger. ApplyOperationsInput carries optional actorUserId,
baseRevision (optimistic concurrency), summary, and the operations array.
ShowVersionSource identifies how each version was produced: create ·
operations · undo · redo · restore; each edit produces a
ShowVersionRecord. The engine also models real-time collaboration
(CollaborationSession, CollaborationCursor,
CollaborationJoinInput/CollaborationCursorInput), a WebSocket event surface
(ShowDesignerWebSocketEvent, ShowDesignerWebSocketEventType,
ShowDesignerWebSocketListener, SubscribeOptions), and a REST surface
(ShowDesignerRestMethod, ShowDesignerRestRequest,
ShowDesignerRestSuccessResponse<T>, ShowDesignerRestErrorResponse,
ShowDesignerRestResponse<T>).
ShowDesignerApiEngine (factory createShowDesignerApiEngine) implements
createShow, listShows, getShow, applyOperations, version history, and
collaboration. All state is in memory — there is no HTTP server; the REST
types describe a request/response shape the engine can answer in-process.
8.3 Other choreography modules#
The remaining modules handle specialized aspects of show production. show-dsl
provides a textual show description language. formation-engine implements
planFormationLayout and the slot geometry for each formation type.
music-sync performs audio analysis: beats, downbeats, phrase boundaries, and
robot tempo mapping. lighting-bridge translates cues to Art-Net / sACN
protocol messages. stage-mapper handles spatial coordinate mapping between the
show coordinate system and the physical stage. timing-engine implements
PTP-style clock synchronization, grandmaster election, and sub-microsecond
timeline execution planning with skew/jitter metrics. rehearsal-engine runs
shows in reduced-speed mode. show-scheduler provides the ShowSchedulerEngine
to schedule shows, poll for due schedules, and manage per-robot scheduler state.
9. Fleet Orchestration (@galatea/fleet)#
@galatea/fleet manages multiple deployed robots as an operational fleet. It
handles tenant/robot registration, status ingestion, remote command dispatch,
and event streaming. Like the show designer, the core orchestrator is an
in-memory service that exposes a typed API surface rather than a live HTTP
server.
Ten modules: orchestrator, capacity-planning, digital-nervous-system,
federated-learning, health-monitoring, incident-management, ota-updates,
raas-billing, remote-diagnostics, scheduling-engine.
9.1 Fleet orchestrator (orchestrator/fleet-orchestrator.ts)#
FleetTenantTier identifies the subscription level for fleet operators:
starter · pro · enterprise. RobotOperationalMode tracks what each robot
is currently doing: idle · performing · charging · maintenance ·
offline.
Records: FleetTenant, FleetRobotRecord, RobotStatusSnapshot,
RemoteCommandRecord, FleetDashboardSnapshot. Requests:
RegisterTenantRequest, RegisterRobotRequest, ProvisionRobotRequest,
RobotStatusUpdate, DispatchRemoteCommandRequest,
AcknowledgeCommandRequest.
RemoteCommandType enumerates the commands that can be sent to a robot from the
fleet: goto · pose · show_start · show_stop · morph. The
RemoteCommandPayload is the discriminated union carrying the command-specific
parameters. A RemoteCommandRecord tracks the command through its status
lifecycle (queued / sent / …); pendingCommandCount counts queued +
sent records.
FleetApiSurface describes the fleet API as data — RestEndpointDefinition[]
and GrpcMethodDefinition[]. FleetEvent is the orchestrator event type
(carries sequence, type, timestampMs, optional robotId; type includes
status_ingested).
FleetOrchestratorService (factory createFleetOrchestratorService) is an
in-memory service exposing registerTenant, registerRobot, provisionRobot,
listTenantRobots, ingestStatus, getDashboardSnapshot, listCommands,
dispatchRemoteCommand, acknowledgeCommand, and readEventStream.
9.2 Other fleet modules#
The remaining modules address the full operational lifecycle of a robot fleet.
capacity-planning models fleet sizing for upcoming events.
digital-nervous-system provides the fleet-wide telemetry mesh.
federated-learning enables on-device model improvements without centralizing
raw data. health-monitoring tracks per-robot health scores.
incident-management records and routes incidents. ota-updates manages staged
firmware rollout. raas-billing implements robotics-as-a-service billing
metering. remote-diagnostics enables deep inspection of individual robots
without physical access. scheduling-engine manages multi-robot task scheduling
across locations.
10. Event Handlers (@galatea/event-handlers)#
Five sub-packages, each an in-process stateful engine. The design is documented in the architecture doc: these are not message-bus subscribers. Each defines a frozen event-type constant array, a corresponding event type, an event interface, an event-handler class, and a factory. Handlers maintain append-only event logs with listable, filterable event histories.
10.1 robot-events#
The robot-events handler models the complete lifecycle of a robot, from power-on through boot, fault handling, recovery, and shutdown.
ROBOT_LIFECYCLE_STATES (9): offline · booting · ready · degraded ·
faulted · recovering · shutting_down · charging · powered_off.
SUBSYSTEM_STATES (8): offline · initializing · ready · faulted ·
isolated · restarting · recalibrating · shutting_down.
FaultCategory: hardware · software · safety · communications · power
· environmental · unknown. FaultSeverity: low · medium · high ·
critical. RecoveryStrategy: restart_subsystem · recalibrate_subsystem ·
restart_and_recalibrate · manual_intervention. FaultEscalationLevel:
none · operator · remote_engineering · emergency_response.
IsolationMode: degraded_operation · safe_hold · manual_override.
ROBOT_EVENT_TYPES (20 events): robot_registered, boot_started,
subsystem_initialized, self_test_completed, robot_ready, boot_failed,
fault_detected, subsystem_isolated, recovery_attempted, fault_recovered,
fault_recovery_failed, fault_escalated, subsystem_restarted,
subsystem_recalibrated, operation_resumed, shutdown_started,
subsystem_powered_down, state_persisted, charging_started,
shutdown_completed.
RobotLifecycleEventHandlers models seven default subsystems
(power_management, safety_controller, locomotion_controller,
perception_stack, choreography_runtime, garment_interface,
comms_gateway) with boot priorities, dependency graphs, and
restart/calibration flags. It topologically sorts subsystems by dependency and
boot priority, runs boot self-tests, classifies and isolates faults, selects and
executes recovery strategies, escalates, and persists shutdown state. Public
methods: registerRobot, executeBootSequence, handleFault,
restartSubsystem, recalibrateSubsystem, resumeOperation,
executeShutdown, getRobotSnapshot, listFaults, getPersistedState,
listEvents. Factory: createRobotLifecycleEventHandlers.
10.2 safety-events#
SAFETY_EVENT_TYPES (5 events): e_stop_triggered, manual_reset_completed,
force_limit_approached, collision_detected, stability_margin_low.
CollisionSeverity: low · medium · high · critical. The module
re-declares the emergency-systems and force-limiting types it needs and exposes
input/result pairs for each event plus a SafetyRobotSnapshot.
10.3 show-events#
SHOW_LIFECYCLE_STATES (6): draft · ready · running · degraded ·
completed · aborted. SHOW_CUE_TYPES (3): lighting · formation_change ·
outfit_reveal. SHOW_EVENT_TYPES (8 events): show_registered,
robot_readiness_updated, show_started, cue_dispatched,
robot_fault_handled, show_degraded, show_aborted, show_ended.
ShowCueDefinition is a union of LightingCueDefinition,
FormationChangeCueDefinition, OutfitRevealCueDefinition. The handler
registers show definitions, tracks robot readiness, starts shows, dispatches
cues (producing CueDispatchCommands), handles robot faults during a show, and
ends shows.
10.4 garment-events#
GARMENT_EVENT_TYPES (4 events): tag_read, garment_dressed,
garment_undressed, dpp_scanned. GarmentEventHandlers maintains a garment
catalog, RFID/NFC tag reads, dressed/undressed lifecycle,
digital-product-passport scans, and an ActiveRobotGarment view. Factory:
createGarmentEventHandlers.
10.5 customer-events#
CUSTOMER_EVENT_TYPES (3 events): customer_approach, customer_engage,
customer_depart. CustomerInteractionMode tracks the type of interaction
currently in progress: display_mode · engaged_pose · voice_interaction.
CustomerEventHandlers produces CustomerPoseCommand /
CustomerHeadTurnCommand outputs, manages a CustomerVoiceSession via a
CustomerVoiceInteractionAdapter, and tracks CustomerInteractionMetrics.
Factory: createCustomerEventHandlers.
11. Persistence (@galatea/database)#
Five PostgreSQL-backed store packages, each purpose-built for its data access
pattern. Each package exports DDL types, a create*SchemaSql(options) function
that generates CREATE TABLE / CREATE INDEX SQL, build*SqlTemplate(...)
functions for parameterised queries, and a store class that runs against an
injected client. Injecting the client (rather than creating it internally) makes
each store testable without a live database.
11.1 event-store#
The event store is append-only by design. No event can be modified after it is
written — this is a hard architectural requirement for safety audit compliance.
The PostgresEventStore class enforces this at the application level; the
CREATE TABLE DDL removes update and delete privileges.
EventDomain: safety · incident · operator_action · ota_update ·
operational. EventSeverity: info · warning · critical. Types:
OperationalEventRecord, AppendOperationalEventInput,
OperationalEventFilter, EventIntegrityIssue, EventIntegrityReport,
EventStoreSchemaSql, EventStoreSchemaOptions, EventStoreOptions.
createEventStoreSchemaSql, buildEventAppendSqlTemplate,
buildEventQuerySqlTemplate, and the PostgresEventStore class implement the
append-only event log with integrity verification.
11.2 garment-store#
GarmentCategory (enum), GarmentWearSource: rfid · nfc · manual;
FitQuality: excellent · good · adjustment_required · poor. Records:
GarmentCatalogRecord, GarmentRfidMappingRecord, GarmentDppCacheRecord,
GarmentWearHistoryRecord, GarmentFitDataRecord. PostgresGarmentStore
persists the garment catalog, RFID mappings, digital-product-passport cache,
wear history, and fit data, with matching schema / upsert / insert SQL builders.
11.3 pose-store#
The pose store supports both vector similarity search (to find poses similar to a given joint configuration) and full-text search (to find poses by name or tag). These two access patterns require different index types in PostgreSQL.
GALATEA_POSE_JOINT_IDS / GALATEA_POSE_DOF fix the pose vector dimensions.
PoseCategory (enum), PoseRecord, PoseUpsertInput, PoseFilter,
PoseSimilaritySearchOptions / PoseSimilaritySearchResult,
PoseTextSearchOptions / PoseTextSearchResult. Helpers
createJointAngleVectorFromMap / createJointAngleMapFromVector convert
between joint maps and dense vectors. PostgresPoseStore supports vector
similarity search and full-text search over the named-pose library.
11.4 show-store#
ShowExecutionOutcome (enum) records whether a show completed, was aborted, or
degraded. Records: ShowDefinitionRecord, ShowDefinitionVersionRecord,
ShowExecutionRecord. PostgresShowStore persists show definitions, their
version history, and execution records, with recordShowExecution /
finalizeShowExecution inputs.
11.5 telemetry-store#
The telemetry store uses TimescaleDB hypertables to handle the high write rate
of joint-state data (up to 1 kHz × 52 joints per robot). The hypertable
partitions data by time automatically, and the 1m/1h continuous aggregates
enable efficient dashboard queries without scanning raw data.
TimescaleTelemetryStore ingests JointStateTelemetrySampleInput,
BatteryTelemetrySampleInput, and EnvironmentalTelemetrySampleInput; rows are
JointStateTelemetryRow etc. TelemetryAggregateResolution is 1m or 1h,
producing *TelemetryAggregateRows built on NumericAggregateStats.
DEFAULT_TELEMETRY_RETENTION_POLICY and DEFAULT_TELEMETRY_SAMPLING_PROFILE
configure retention and sampling; createTimescaleTelemetrySchemaSql emits the
hypertable schema and a retention sweep returns TelemetryRetentionSweepResult.
Time constants: MINUTE_MS, HOUR_MS, DAY_MS.
12. SDKs (@galatea/sdk)#
The SDK layer provides typed client surfaces that compose the in-memory engines for external consumers. There are four SDK packages: the TypeScript client, the show-authoring SDK, the analytics SDK, and the Python client.
12.1 TypeScript client (@galatea/sdk, src/client-ts/client.ts)#
GalateaClient (factory createGalateaClient) composes three sub-clients over
a GalateaClientBackend. The backend is pluggable, but the default
InMemoryGalateaClientBackend wires all sub-clients to the in-memory engines
for development and testing.
fleet: FleetClient—registerTenant,registerRobot,provisionRobot,listRobots,ingestStatus,getDashboard,getStatus,sendCommand,acknowledgeCommand,listCommands,readEventStream,subscribeRobotStateUpdates.shows: ShowsClient—createShow,listShows,getShow,editShow, scheduler-robot-state upsert/list,scheduleShow,listSchedules,startShow,stopShow,startDueSchedules,stopScheduledShow.analytics: AnalyticsClient— nestsengagement,heatmaps,revenueclients.
InMemoryGalateaClientBackend wires the client to FleetOrchestratorService,
ShowDesignerApiEngine, ShowSchedulerEngine, EngagementTracker,
HeatmapEngine, and RevenueAttributionEngine. There is no HTTP transport,
no client.control, and no IK/telemetry endpoint — the SDK drives the
in-memory engines directly. subscribeRobotStateUpdates polls the
orchestrator's event stream (pollIntervalMs ≥ 50, default 500) and emits
FleetRobotStatusUpdates.
12.2 Show SDK (@galatea/sdk/show-sdk, src/show-sdk.ts)#
The show SDK provides a fluent builder API that hides the complexity of the
ShowDocument schema behind a step-by-step authoring surface. After building a
draft, validateDraft runs a comprehensive set of checks before the show can be
deployed.
ShowAuthoringSdk (factory createShowAuthoringSdk) provides a fluent
ShowAuthoringBuilder (addPathTrack, addPoseTrack, addPivotTrack,
addFormationMarker, addFormationFromTemplate, addMusicSyncPoint,
addMusicSyncPointsFromAnalysis, addLightingCue, addOutfitChangeTrigger,
addMetadataPatch, buildDraft). validateDraft returns a
ShowValidationReport (deployability, issues, metrics, optional timing summary)
— it checks track waypoint/pose/pivot requirements, formation robot proximity,
path-intersection risk, and runs the choreography timing engine against a
one-microsecond synchronisation target. deployDraft validates then persists
via the show designer, throwing ShowDraftValidationError on non-deployable
drafts unless allowUnsafeDeployment is set. MusicSyncExtractionStrategy:
downbeats · phrase_boundaries · every_n_beats.
12.3 Analytics SDK (@galatea/sdk/analytics-sdk)#
The analytics SDK lets consumers define custom events and metrics beyond the
built-in engagement, heatmap, and revenue analytics. It also provides dashboard
widget definitions that feed the reporting-dashboard module.
Custom-event tracking and dashboards: CustomEventSchema,
TrackCustomEventInput, CustomEventRecord, metric definitions
(AggregateMetricDefinition, RatioMetricDefinition), metric evaluation
(MetricQueryInput, MetricPoint, MetricEvaluationResult), and widget
creation inputs (CreateKpiWidgetInput, CreateTimeseriesWidgetInput,
CreateLeaderboardWidgetInput).
12.4 Python client (sdk/client-python)#
The Python client is the primary integration point for ML engineering workflows.
It mirrors the TypeScript SDK's fleet/shows/analytics surface and adds an
MLOpsClient for training pipeline and model management operations.
Package galatea-client-sdk (PyPI name; Python ≥ 3.9, hatchling build,
uv.lock). galatea_client exports GalateaClient, create_client,
InMemoryGalateaBackend, and the sub-clients FleetClient, ShowsClient,
AnalyticsClient, EngagementAnalyticsClient, HeatmapAnalyticsClient,
RevenueAnalyticsClient, MLOpsClient, plus StartDueSchedulesResult and
StopScheduledShowResult.
13. Firmware and Hardware Abstraction (Rust manifests)#
@galatea/firmware and @galatea/hardware-abstraction occupy a unique position
in the domain: they contain no TypeScript implementation logic. Every source
file is a *-rust-manifest.ts that exports a typed manifest describing a
planned Rust crate. The manifest includes the crate path, target MCU/runtime,
capabilities, and supported peripherals. A get*Manifest() accessor returns the
manifest for programmatic use (e.g., for OTA deployment tooling).
This approach means the TypeScript domain has a typed, version-controlled
description of every firmware component, even before the Rust crates are built.
The @galatea/hardware-abstraction TypeScript packages in the other libraries
(kinematics, locomotion, etc.) use these manifests as their description of the
hardware they interface with.
13.1 @galatea/firmware#
Eight modules: motor-drivers, sensor-interfaces, safety-controller,
power-management, comms-bus, rtos-runtime, bootloader, board-support.
As an example, FOC_RUST_DRIVER_MANIFEST (foc-rust-driver-manifest.ts)
specifies: cratePath: 'libs/galatea/firmware/src/motor-drivers/rust-foc',
targetMcu: 'STM32H7', runtime: 'no_std', controlLoopFrequencyHz: 40_000, a
capability list (Clarke/Park transforms, SVPWM, PI current regulators, parameter
identification, CAN-FD telemetry), and
encoderSupport: ['absolute-19bit', 'incremental']. The sensor-interface
manifests target named devices (bno085, mini45, tactile-skin,
foot-pressure, vl53l5cx).
13.2 @galatea/hardware-abstraction#
Nine manifest modules: joint-interface, actuator-profiles, sensor-fusion,
body-morphing, face-system, hand-system, thermal-management,
rfid-reader, tactile-skin.
14. Other Library Surfaces#
This section documents the module structure for the libraries not covered in detail above.
14.1 @galatea/communication#
Six modules, each with both a TypeScript implementation and a Rust manifest:
ethercat-master, canfd-interface, dds-bridge, wifi-mesh,
cloud-connector, ptp-sync.
14.2 @galatea/locomotion#
The largest module by file count: 22 sub-modules. Eight classic locomotion
controllers, each with a Rust manifest — gait-planner, balance-controller,
footstep-planner, push-recovery, stair-navigation, step-controller,
walking-styles, terrain-adaptive-foot-placement. The remaining 14 are
manifest-free procedural-animation modules: procedural-walk-cycle,
procedural-quadruped-locomotion, procedural-arthropod-locomotion,
procedural-snake-locomotion, procedural-fish-swimming,
procedural-bird-flight, procedural-appendage-animation,
procedural-reach-and-grab, procedural-head-look-at, procedural-lip-sync,
procedural-emotion-blending, secondary-motion, wind-reactive-fabric-hair,
and control-rig-integration.
14.3 @galatea/whole-body-control#
Six controllers, each with a Rust manifest: task-space-controller,
impedance-controller, admittance-controller, postural-controller,
center-of-mass, momentum-controller. The task-space controller models
BalanceTaskSpec, LocomotionTaskSpec, HandPositionTaskSpec, GazeTaskSpec,
PostureTaskSpec and exposes computeDynamicallyConsistentPseudoInverse.
14.4 @galatea/pose-engine#
Eight modules, each with a Rust manifest: pose-library (with a separate
pose-import-pipeline), pose-validation, transition-planner,
pose-optimizer, breathing-simulator, micro-movement-gen,
contrapposto-solver, hand-pose-library.
14.5 @galatea/perception#
Nine modules (TypeScript implementations): person-detection,
audience-awareness, garment-recognition, fit-analysis,
obstacle-detection, depth-processing, slam, visual-servoing,
camera-only-perception. PersonDetectionEngine produces anonymous person
detections / tracks (PersonCategory: child · adult · unknown), anonymous
trajectories, and a performance report.
14.6 @galatea/ai#
Sixteen modules: vla-runtime (with vla-finetuning-pipeline),
behavioral-engine, natural-motion-gen, customer-engagement,
llm-interaction, emotion-expression, fashion-trend-ai,
attention-prediction, reinforcement-learning, quiet-locomotion,
end-to-end-control (with reflex-vla-runtime), large-behavior-model (with
lbm-evaluation-suite), motor-cortex-policy, teleoperation
(vr-teleoperation-runtime, sensor-suit-integration), data-collection
(training-data-management), training-infrastructure
(simulation-farm-management, training-pipeline-orchestration). The VLA
runtime supports VlaModelBackend (onnx · tensorrt) and VlaModelPrecision
(fp32 · fp16 · int8).
14.7 @galatea/garment-management#
Eight modules: cloth-manipulation, digital-product-passport,
fabric-safety, fit-validation, outfit-tracking, quick-change
(quick-change-protocol), size-adaptation, wardrobe-scheduler.
OutfitTrackingSystem records OutfitEventType (garment_dressed ·
garment_undressed · garment_swapped) events against an RFID-scanned
inventory.
14.8 @galatea/simulation#
Eight modules: physics-engine, cloth-simulator, digital-twin,
show-preview, rl-training-env, wear-simulator, virtual-showroom,
scenario-tester.
14.9 @galatea/analytics#
Seven modules: ab-testing, engagement-tracker, heatmap-engine,
inventory-bridge, pos-integration, reporting-dashboard,
revenue-attribution.
14.10 @galatea/inclusivity#
Four sub-packages: accessibility, body-profiles, cultural-config,
multilingual. body-profiles defines BodyShape, GenderPresentation
(feminine · masculine · androgynous), SizeSystem (womens_us ·
mens_alpha · custom), the WOMENS_US_SIZES / MENS_ALPHA_SIZES scales,
BodyDimensionsCm, MovementAdaptationConstraints, and BodyProfile.
15. V2 Vehicle-As-Articulated-Body Modeling Surface#
The V2 game project's racing ecosystem reuses Galatea's articulated-body
kinematics to model racing vehicles and their drivers. The
@v2/racing-ecosystem-bridge service (in the V2 monorepo, not in
libs/galatea/) consumes @galatea/kinematics and
@galatea/whole-body-control as one of its source-of-truth packages; Galatea
itself has no dependency on V2.
The bridge treats the car-plus-driver rig as a vehicle-as-articulated-body:
its modelingSurface is literally the string 'vehicle-as-articulated-body'.
It calls createGalateaRigidBodyDynamicsModel() from @galatea/kinematics to
build the mass matrix and gravity-compensation torques over the driver's
JointAnglesRad, and runCenterOfMassTracker from
@galatea/whole-body-control to track the rig's center of mass against its
support polygon. From those it derives a driver-articulation summary that feeds
the racing cook, raising galatea-driver-articulation-unstable when the center
of mass leaves the support polygon and galatea-driver-torque-budget-high when
peak gravity torque exceeds the configured budget.
This is an authoring / content-cook surface only. The bridge rejects any RPC
made from a live race frame and carries mayInfluenceRollback: false, so the
Galatea articulation model is used to author and validate vehicles offline and
never participates in deterministic per-frame race simulation. See
V2/docs/integration/racing-ecosystem-bridge.md;
V2/ue/Tools/check-v2-racing-ecosystem-bridge.py enforces the wiring.
Grounding: apps/v2/racing-ecosystem-bridge/src/racing-ecosystem-bridge.ts;
libs/galatea/kinematics/, libs/galatea/whole-body-control/.
16. Technology Stack#
The table below summarizes the technology choices at each layer of the domain. These choices reflect the domain's dual requirement of high-level TypeScript orchestration and low-level real-time Rust control.
| Layer | Technology |
|---|---|
| Platform language | TypeScript (Node.js, ESM) |
| Real-time firmware | Rust crates (described by *-rust-manifest.ts; no_std, STM32H7) |
| Validation | Zod (@galatea/core schemas) |
| Operational store | PostgreSQL (event-store, garment-store, pose-store, show-store) |
| Telemetry store | TimescaleDB hypertables (telemetry-store) |
| Messaging config | Redis, NATS JetStream, MQTT (config schema only) |
| Python SDK | Python ≥ 3.9, hatchling, uv |
| Build | Nx with @nx/js:tsc |
| Test | Vitest (@nx/vite:test); pytest for the Python client |
| Project tags | scope:galatea, type:lib, layer:domain, plus galatea:<module> |
17. Acceptance Criteria#
These criteria define what must be true for the Galatea domain to be considered correctly implemented. They are written as verifiable, concrete checks rather than aspirational goals.
@galatea/coreexports the Zod-validatedRobotState,Pose,Trajectory,MotionPrimitive, andChoreographyScriptschemas withMIN_ROBOT_DOF = 52enforced, plus the full physical-constant and safety-threshold tables.solveWholeBodyInverseKinematicsresolves prioritisedend_effector/center_of_mass/gaze/posturetasks, reports per-task convergence and degradation, and respects joint-limit, velocity, and self-collision constraints.Iso13482ComplianceEnginemaintains a HAZOP register with ISO 12100 S×P×E risk scoring and produces a Markdown compliance audit document.ShowDesignerApiEngineapplies all 16ShowDesignerOperationtypes under optimistic-concurrency (baseRevision) and records aShowVersionRecordper edit;ShowAuthoringSdk.validateDraftenforces the one-microsecond timing-synchronisation target.FleetOrchestratorServiceregisters tenants/robots, ingests status, dispatches the fiveRemoteCommandTypecommands, and exposes a replayableFleetEventstream.- Each
@galatea/event-handlerspackage exposes a frozen event-type constant, a stateful handler engine, and a filterable event history. - Each
@galatea/databasepackage generates validCREATE TABLE/INDEXSQL and a store class that runs parameterised queries against an injected client. GalateaClient(TypeScript) andgalatea_client.GalateaClient(Python) exposefleet,shows, andanalyticsover an in-memory backend.- Every package builds with
@nx/js:tsc, type-checks withnpx tsc --noEmit, and passes its Vitest suite (npx vitest run).