import type { MachineDefinition } from '../types'; import { groupNode, hierarchy, makeMachine, makePart, primitive, standardCameraPresets, thumbnail, tourStep, } from './catalogueHelpers'; const centrifugalParts = [ makePart({ id: 'volute-casing', name: 'Volute casing', group: 'Structure', description: 'Spiral casing collects high-velocity flow from the impeller and converts part of it into pressure.', primitive: primitive('housing', { profile: 'pump-volute', radius: 0.9, outletRadius: 0.22, cutaway: true }), position: [0, 0, 0], material: 'transparent-shell', explodedDirection: [0, 0, -0.9], crossSectionBehavior: 'shell', }), makePart({ id: 'impeller', name: 'Impeller', group: 'Rotating assembly', description: 'Curved vanes add angular momentum to the fluid as the shaft rotates.', primitive: primitive('blade-disk', { blades: 7, radius: 0.52, hubRadius: 0.12, bladeTwist: 38, axis: 'z' }), position: [0, 0, 0], material: 'warm-highlight', explodedDirection: [0, 0, 0.8], }), makePart({ id: 'shaft', name: 'Pump shaft', group: 'Rotating assembly', description: 'Shaft couples external motor torque into the impeller hub.', primitive: primitive('cylinder', { radius: 0.075, depth: 1.2, axis: 'z' }), position: [0, 0, 0], material: 'machined-steel', explodedDirection: [0, -0.65, 0], }), makePart({ id: 'inlet-eye', name: 'Inlet eye', group: 'Flow path', description: 'Axial suction opening where fluid enters the impeller near the hub.', primitive: primitive('pipe', { radius: 0.25, length: 0.7, axis: 'z' }), position: [0, 0, 0.55], material: 'fluid-blue', explodedDirection: [0, 0, 1.1], crossSectionBehavior: 'fluid', }), makePart({ id: 'discharge-nozzle', name: 'Discharge nozzle', group: 'Flow path', description: 'Tangential outlet carrying pressurised fluid away from the volute.', primitive: primitive('pipe', { radius: 0.18, length: 0.82, axis: 'x' }), position: [0.92, 0.42, 0], rotation: [0, 0, -0.15], material: 'fluid-blue', explodedDirection: [1, 0.35, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'wear-ring', name: 'Wear ring', group: 'Sealing', description: 'Replaceable close-clearance ring limiting leakage from discharge side back to suction.', primitive: primitive('torus', { majorRadius: 0.3, tubeRadius: 0.025, axis: 'z' }), position: [0, 0, 0.31], material: 'brass', explodedDirection: [0, 0.4, 0.65], }), makePart({ id: 'mechanical-seal', name: 'Mechanical seal', group: 'Sealing', description: 'Seal faces prevent leakage along the rotating shaft while tolerating motion.', primitive: primitive('seal', { radius: 0.14, thickness: 0.08, axis: 'z' }), position: [0, 0, -0.42], material: 'gasket', explodedDirection: [0, -0.35, -0.55], }), makePart({ id: 'bearings', name: 'Bearing set', group: 'Support', description: 'Bearings support radial and axial loads from impeller hydraulic forces.', primitive: primitive('torus', { majorRadius: 0.18, tubeRadius: 0.035, count: 2, axis: 'z' }), position: [0, 0, -0.72], material: 'bearing-steel', explodedDirection: [0, -0.65, -0.55], }), makePart({ id: 'cavitation-indicator', name: 'Cavitation indicator', group: 'Learning overlays', description: 'Bubble overlay appears near the eye when inlet pressure is too low, illustrating cavitation risk.', primitive: primitive('custom', { profile: 'bubble-cluster', count: 18, radius: 0.28 }), position: [-0.14, 0.05, 0.43], material: 'glass', explodedDirection: [-0.45, 0.45, 0.8], crossSectionBehavior: 'fluid', }), makePart({ id: 'flow-streamlines', name: 'Flow streamlines', group: 'Flow path', description: 'Animated streamlines curve from axial inlet to radial impeller discharge and volute outlet.', primitive: primitive('flow-path', { path: 'centrifugal-pump', arrowCount: 24, spiral: true }), position: [0, 0, 0.1], material: 'fluid-blue', explodedDirection: [0, 0.65, 0.45], crossSectionBehavior: 'fluid', }), ]; const gearPumpParts = [ makePart({ id: 'pump-housing', name: 'Pump housing', group: 'Structure', description: 'Close-clearance housing that traps fluid pockets around the outside of the gears.', primitive: primitive('housing', { profile: 'gear-pump-case', width: 1.9, height: 1.05, depth: 0.62, cutaway: true }), position: [0, 0, 0], material: 'transparent-shell', explodedDirection: [0, 0, -0.75], crossSectionBehavior: 'shell', }), makePart({ id: 'drive-gear', name: 'Drive gear', group: 'Rotating assembly', description: 'Powered external gear whose teeth mesh with the idler gear and carry fluid around the casing.', primitive: primitive('gear', { radius: 0.36, thickness: 0.24, teeth: 14, axis: 'z' }), position: [-0.36, 0, 0], material: 'warm-highlight', explodedDirection: [-0.55, 0.35, 0], }), makePart({ id: 'idler-gear', name: 'Idler gear', group: 'Rotating assembly', description: 'Meshing gear driven by the drive gear; counter-rotates to move fluid from inlet to outlet.', primitive: primitive('gear', { radius: 0.36, thickness: 0.24, teeth: 14, axis: 'z' }), position: [0.36, 0, 0], material: 'machined-steel', explodedDirection: [0.55, 0.35, 0], }), makePart({ id: 'inlet-port', name: 'Inlet port', group: 'Flow path', description: 'Low-pressure opening where expanding tooth spaces draw fluid into the pump.', primitive: primitive('pipe', { radius: 0.16, length: 0.65, axis: 'x' }), position: [-1.05, -0.18, 0], material: 'fluid-blue', explodedDirection: [-0.95, -0.25, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'outlet-port', name: 'Outlet port', group: 'Flow path', description: 'High-pressure outlet where trapped pockets collapse as gear teeth re-mesh.', primitive: primitive('pipe', { radius: 0.16, length: 0.65, axis: 'x' }), position: [1.05, 0.18, 0], material: 'fluid-amber', explodedDirection: [0.95, 0.25, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'crescent-pocket', name: 'Trapped tooth pockets', group: 'Flow path', description: 'Highlighted spaces between gear teeth and housing carry discrete volumes of fluid per revolution.', primitive: primitive('flow-path', { path: 'gear-pump-pocket-loop', pocketCount: 12 }), position: [0, 0, 0.07], material: 'fluid-blue', explodedDirection: [0, 0.6, 0.45], crossSectionBehavior: 'fluid', }), makePart({ id: 'side-plates', name: 'Side plates', group: 'Sealing', description: 'Axial wear plates maintain tight end clearance to limit internal leakage.', primitive: primitive('box', { width: 1.45, height: 0.78, depth: 0.045, count: 2, bevel: 0.03 }), position: [0, 0, 0], material: 'brass', explodedDirection: [0, 0, 0.95], }), makePart({ id: 'drive-shaft', name: 'Drive shaft', group: 'Rotating assembly', description: 'Shaft keyed to the drive gear and coupled to motor or engine power.', primitive: primitive('cylinder', { radius: 0.075, depth: 0.9, axis: 'z' }), position: [-0.36, 0, -0.36], material: 'machined-steel', explodedDirection: [-0.35, 0, -0.85], }), makePart({ id: 'relief-valve', name: 'Relief valve', group: 'Controls', description: 'Spring-loaded bypass protects the pump and downstream circuit from overpressure.', primitive: primitive('valve', { profile: 'spring-poppet', length: 0.62, springTurns: 5 }), position: [0.72, 0.46, 0], material: 'paint-red', explodedDirection: [0.65, 0.75, 0], }), makePart({ id: 'trapped-fluid-volumes', name: 'Displacement volume markers', group: 'Learning overlays', description: 'Pulsing markers count fluid pockets to connect gear tooth volume with displacement per revolution.', primitive: primitive('custom', { profile: 'volume-markers', count: 8 }), position: [0, -0.4, 0.12], material: 'fluid-amber', explodedDirection: [0, -0.65, 0.55], crossSectionBehavior: 'fluid', }), ]; const pistonPumpParts = [ makePart({ id: 'cylinder-block', name: 'Pump cylinder', group: 'Structure', description: 'Pressure cylinder in which piston reciprocation alternately draws in and discharges fluid.', primitive: primitive('cylinder', { radius: 0.32, depth: 1.3, axis: 'x', cutaway: true }), position: [0.22, 0, 0], rotation: [0, 0, 1.5708], material: 'transparent-shell', explodedDirection: [0, 0, -0.75], crossSectionBehavior: 'shell', }), makePart({ id: 'reciprocating-piston', name: 'Reciprocating piston', group: 'Motion conversion', description: 'Piston changes chamber volume to produce suction and pressure strokes.', primitive: primitive('cylinder', { radius: 0.27, depth: 0.18, axis: 'x' }), position: [0.18, 0, 0], rotation: [0, 0, 1.5708], material: 'machined-steel', explodedDirection: [0, 0.55, 0], }), makePart({ id: 'crankshaft', name: 'Crankshaft', group: 'Motion conversion', description: 'Rotating crank provides the sinusoidal piston motion.', primitive: primitive('custom', { profile: 'single-throw-crankshaft', throw: 0.3, mainRadius: 0.08 }), position: [-0.72, 0, 0], rotation: [1.5708, 0, 0], material: 'machined-steel', explodedDirection: [-0.75, 0, 0], }), makePart({ id: 'connecting-rod', name: 'Connecting rod', group: 'Motion conversion', description: 'Link between crank pin and piston rod transmitting alternating load.', primitive: primitive('box', { width: 0.1, height: 0.1, depth: 0.88, rounded: true }), position: [-0.28, 0, 0], rotation: [0, 1.5708, 0], material: 'brushed-steel', explodedDirection: [-0.25, 0.45, 0], }), makePart({ id: 'inlet-valve', name: 'Inlet check valve', group: 'Valves', description: 'One-way valve opens when chamber pressure drops below inlet manifold pressure.', primitive: primitive('valve', { profile: 'check-ball', radius: 0.12, spring: true }), position: [0.45, -0.42, 0], material: 'blue-accent', explodedDirection: [0.35, -0.75, 0], }), makePart({ id: 'outlet-valve', name: 'Outlet check valve', group: 'Valves', description: 'One-way valve opens during the pressure stroke to send fluid into the discharge manifold.', primitive: primitive('valve', { profile: 'check-ball', radius: 0.12, spring: true }), position: [0.45, 0.42, 0], material: 'warm-highlight', explodedDirection: [0.35, 0.75, 0], }), makePart({ id: 'suction-manifold', name: 'Suction manifold', group: 'Flow path', description: 'Low-pressure supply feeding the inlet check valve.', primitive: primitive('pipe', { radius: 0.12, length: 0.8, axis: 'y' }), position: [0.45, -0.82, 0], material: 'fluid-blue', explodedDirection: [0.2, -1, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'discharge-manifold', name: 'Discharge manifold', group: 'Flow path', description: 'High-pressure line receiving pulsating flow from the outlet check valve.', primitive: primitive('pipe', { radius: 0.12, length: 0.8, axis: 'y' }), position: [0.45, 0.82, 0], material: 'fluid-amber', explodedDirection: [0.2, 1, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'pressure-gauge', name: 'Pressure gauge', group: 'Instrumentation', description: 'Gauge needle pulses with discharge pressure to show pulsating pump output.', primitive: primitive('custom', { profile: 'round-gauge', radius: 0.18, needle: true }), position: [0.84, 0.78, 0.18], material: 'glass', explodedDirection: [0.75, 0.95, 0.35], }), makePart({ id: 'pulsation-damper', name: 'Pulsation damper', group: 'Flow path', description: 'Accumulator volume smooths pressure ripple in the discharge line.', primitive: primitive('sphere', { radius: 0.24, squash: [1, 1.35, 1] }), position: [0.88, 0.44, 0], material: 'fluid-amber', explodedDirection: [0.95, 0.55, 0], crossSectionBehavior: 'fluid', }), ]; const hydraulicCylinderParts = [ makePart({ id: 'barrel', name: 'Cylinder barrel', group: 'Structure', description: 'Pressure tube that guides the piston and contains hydraulic fluid.', primitive: primitive('cylinder', { radius: 0.34, depth: 1.85, axis: 'x', cutaway: true }), position: [0, 0, 0], rotation: [0, 0, 1.5708], material: 'transparent-shell', explodedDirection: [0, 0, -0.7], crossSectionBehavior: 'shell', }), makePart({ id: 'piston', name: 'Piston', group: 'Moving assembly', description: 'Internal disk separating cap-end and rod-end chambers; pressure imbalance creates axial force.', primitive: primitive('cylinder', { radius: 0.29, depth: 0.18, axis: 'x' }), position: [-0.08, 0, 0], rotation: [0, 0, 1.5708], material: 'machined-steel', explodedDirection: [0, 0.55, 0], }), makePart({ id: 'piston-rod', name: 'Piston rod', group: 'Moving assembly', description: 'Chrome rod transmits linear force outside the cylinder and reduces effective rod-side area.', primitive: primitive('cylinder', { radius: 0.095, depth: 1.35, axis: 'x' }), position: [0.78, 0, 0], rotation: [0, 0, 1.5708], material: 'brushed-steel', explodedDirection: [0.95, 0, 0], }), makePart({ id: 'rod-seal', name: 'Rod seal', group: 'Sealing', description: 'Dynamic seal around the piston rod that prevents external leakage.', primitive: primitive('seal', { radius: 0.16, thickness: 0.055, axis: 'x' }), position: [0.72, 0, 0], rotation: [0, 0, 1.5708], material: 'gasket', explodedDirection: [0.65, 0.35, 0], }), makePart({ id: 'piston-seal', name: 'Piston seal', group: 'Sealing', description: 'Seal ring on the piston that prevents internal bypass between chambers.', primitive: primitive('seal', { radius: 0.29, thickness: 0.035, axis: 'x' }), position: [-0.08, 0, 0], rotation: [0, 0, 1.5708], material: 'gasket', explodedDirection: [0, 0.75, 0], }), makePart({ id: 'gland', name: 'Rod gland', group: 'Structure', description: 'End assembly retaining rod seals, wiper, and bearing support.', primitive: primitive('cylinder', { radius: 0.35, depth: 0.18, axis: 'x' }), position: [0.78, 0, 0], rotation: [0, 0, 1.5708], material: 'dark-anodized', explodedDirection: [0.8, 0, 0], }), makePart({ id: 'base-port', name: 'Base port', group: 'Hydraulic ports', description: 'Cap-end port; pressure here extends the cylinder.', primitive: primitive('pipe', { radius: 0.07, length: 0.48, axis: 'y' }), position: [-0.74, 0.36, 0], material: 'fluid-blue', explodedDirection: [-0.55, 0.75, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'rod-port', name: 'Rod port', group: 'Hydraulic ports', description: 'Rod-end port; pressure here retracts the cylinder and returns cap-end fluid.', primitive: primitive('pipe', { radius: 0.07, length: 0.48, axis: 'y' }), position: [0.55, 0.36, 0], material: 'fluid-amber', explodedDirection: [0.55, 0.75, 0], crossSectionBehavior: 'fluid', }), makePart({ id: 'end-cap', name: 'End cap', group: 'Structure', description: 'Closed cap-end housing with mounting interface and port drilling.', primitive: primitive('cylinder', { radius: 0.36, depth: 0.18, axis: 'x' }), position: [-0.95, 0, 0], rotation: [0, 0, 1.5708], material: 'dark-anodized', explodedDirection: [-0.95, 0, 0], }), makePart({ id: 'pressure-chamber', name: 'Cap-end pressure chamber', group: 'Fluid volumes', description: 'Blue volume shows the larger effective area that produces extension force.', primitive: primitive('cylinder', { radius: 0.27, depth: 0.72, axis: 'x' }), position: [-0.5, 0, 0], rotation: [0, 0, 1.5708], material: 'fluid-blue', explodedDirection: [-0.35, 0.45, 0.45], crossSectionBehavior: 'fluid', }), makePart({ id: 'return-chamber', name: 'Rod-end chamber', group: 'Fluid volumes', description: 'Amber annular volume has less effective area because the rod occupies part of the piston face.', primitive: primitive('cylinder', { radius: 0.24, depth: 0.65, axis: 'x', hollowCoreRadius: 0.1 }), position: [0.35, 0, 0], rotation: [0, 0, 1.5708], material: 'fluid-amber', explodedDirection: [0.35, 0.45, 0.45], crossSectionBehavior: 'fluid', }), makePart({ id: 'clevis-mount', name: 'Clevis mount', group: 'Mounting', description: 'Pinned mounting interface allowing cylinder force to act through a rotating joint.', primitive: primitive('custom', { profile: 'clevis', pinRadius: 0.07, jawSpacing: 0.2 }), position: [1.55, 0, 0], material: 'machined-steel', explodedDirection: [1.15, 0, 0], }), ]; export const PUMP_AND_FLUID_MACHINES: readonly MachineDefinition[] = [ makeMachine({ id: 'centrifugal-pump', slug: 'centrifugal-pump', title: 'Centrifugal Pump', category: 'pumps-fluid', difficulty: 'Beginner', complexityScore: 46, sortOrder: 15, releasedAt: '2025-02-01', summary: 'Impeller and volute pump with streamlines, seal, wear ring, and cavitation indicator.', description: 'A cutaway centrifugal pump showing impeller blades, volute casing, inlet eye, discharge nozzle, shaft, seal, bearings, wear ring, animated flow, and cavitation overlay. The model focuses on radial energy transfer and pressure recovery in the volute.', keywords: ['centrifugal pump', 'impeller', 'volute', 'cavitation', 'flow', 'pressure'], facts: [ { label: 'Flow principle', value: 'Dynamic pump adds velocity then pressure', kind: 'flow' }, { label: 'Typical efficiency', value: '60-85', unit: '%', kind: 'efficiency' }, { label: 'Typical speed', value: '1450-3600', unit: 'rpm industrial pumps', kind: 'rpm' }, { label: 'Invention milestone', value: '17th-19th century centrifugal pump development', kind: 'date' }, { label: 'Common applications', value: 'Water supply, HVAC, process plants, marine systems', kind: 'application' }, ], relatedMachineIds: ['gear-pump', 'piston-pump', 'turbojet-engine'], thumbnail: thumbnail('Centrifugal Pump', ['impeller', 'volute-casing', 'flow-streamlines'], 'cavitation-indicator'), parts: centrifugalParts, hierarchy: hierarchy([ groupNode('rotating', 'Rotating assembly', ['impeller', 'shaft']), groupNode('casing-flow', 'Casing and flow path', ['volute-casing', 'inlet-eye', 'discharge-nozzle', 'flow-streamlines']), groupNode('sealing-support', 'Sealing and support', ['wear-ring', 'mechanical-seal', 'bearings']), groupNode('learning', 'Learning overlays', ['cavitation-indicator']), ]), cameraPresets: standardCameraPresets(4.7), guidedTour: [ tourStep('overview', 'Radial-flow pump', 'Fluid enters axially at the eye and leaves radially into the volute.', 'isometric', ['inlet-eye', 'impeller', 'volute-casing']), tourStep('impeller', 'Impeller energy transfer', 'Curved vanes spin the fluid outward, increasing velocity and pressure.', 'front', ['impeller', 'flow-streamlines'], { playback: 'play', rpm: 1450 }), tourStep('volute', 'Volute pressure recovery', 'The spiral casing collects flow and slows it to recover static pressure.', 'top', ['volute-casing', 'discharge-nozzle'], { playback: 'play', rpm: 1450 }), tourStep('cavitation', 'Cavitation risk', 'Bubble markers near the inlet eye show what happens if local pressure drops below vapour pressure.', 'front', ['cavitation-indicator', 'inlet-eye'], { explodeDistance: 0.2 }), ], animationModuleId: 'anim-centrifugal-pump', labelsEnabledByDefault: true, }), makeMachine({ id: 'gear-pump', slug: 'gear-pump', title: 'Gear Pump', category: 'pumps-fluid', difficulty: 'Beginner', complexityScore: 43, sortOrder: 16, releasedAt: '2025-02-01', summary: 'External gear pump demonstrating positive displacement per revolution.', description: 'A cutaway external gear pump with drive and idler gears, housing, inlet/outlet ports, side plates, relief valve, and animated trapped-volume markers. The lesson emphasises positive displacement, clearance leakage, and pressure relief.', keywords: ['gear pump', 'positive displacement', 'external gear', 'relief valve', 'fluid pockets'], facts: [ { label: 'Pump type', value: 'Positive displacement', kind: 'flow' }, { label: 'Typical efficiency', value: '70-90', unit: '% volumetric/mechanical', kind: 'efficiency' }, { label: 'Typical speed', value: '500-3000', unit: 'rpm', kind: 'rpm' }, { label: 'Invention milestone', value: 'Industrial rotary pumps matured in the 19th century', kind: 'date' }, { label: 'Common applications', value: 'Oil pumps, hydraulic power packs, fuel transfer', kind: 'application' }, ], relatedMachineIds: ['centrifugal-pump', 'piston-pump', 'wankel-rotary-engine'], thumbnail: thumbnail('Gear Pump', ['drive-gear', 'idler-gear', 'crescent-pocket'], 'trapped-fluid-volumes'), parts: gearPumpParts, hierarchy: hierarchy([ groupNode('rotating', 'Rotating assembly', ['drive-gear', 'idler-gear', 'drive-shaft']), groupNode('flow', 'Flow path', ['inlet-port', 'outlet-port', 'crescent-pocket', 'trapped-fluid-volumes']), groupNode('structure', 'Structure and sealing', ['pump-housing', 'side-plates']), groupNode('control', 'Pressure protection', ['relief-valve']), ]), cameraPresets: standardCameraPresets(4.6), guidedTour: [ tourStep('overview', 'Positive displacement', 'Fluid is trapped in gear tooth spaces and carried around the outside of the gears.', 'isometric', ['drive-gear', 'idler-gear', 'pump-housing']), tourStep('inlet', 'Expanding spaces draw fluid in', 'As teeth unmesh near the inlet, volume increases and pressure drops.', 'front', ['inlet-port', 'drive-gear', 'idler-gear'], { playback: 'play', rpm: 600 }), tourStep('displacement', 'Pockets move around the casing', 'Highlighted volumes travel around the outside rather than through the meshing centre.', 'top', ['crescent-pocket', 'trapped-fluid-volumes'], { playback: 'play', rpm: 600 }), tourStep('relief', 'Pressure relief', 'A spring valve bypasses flow if outlet pressure rises too high.', 'right', ['relief-valve', 'outlet-port'], { explodeDistance: 0.25 }), ], animationModuleId: 'anim-gear-pump', labelsEnabledByDefault: true, }), makeMachine({ id: 'piston-pump', slug: 'piston-pump', title: 'Piston Pump', category: 'pumps-fluid', difficulty: 'Intermediate', complexityScore: 50, sortOrder: 17, releasedAt: '2025-02-01', summary: 'Reciprocating positive-displacement pump with inlet/outlet check valves and pulsation damper.', description: 'This piston pump cutaway shows the cylinder, reciprocating piston, crank drive, connecting rod, check valves, manifolds, gauge, and pulsation damper. The animation maps crank phase to suction and discharge valve timing.', keywords: ['piston pump', 'reciprocating pump', 'check valve', 'pulsation damper', 'positive displacement'], facts: [ { label: 'Pump type', value: 'Positive displacement reciprocating', kind: 'flow' }, { label: 'Typical efficiency', value: '75-92', unit: '%', kind: 'efficiency' }, { label: 'Typical speed', value: '100-1000', unit: 'rpm', kind: 'rpm' }, { label: 'Invention milestone', value: 'Ancient piston pumps; modern high-pressure pumps in 19th-20th century', kind: 'date' }, { label: 'Common applications', value: 'Pressure washers, dosing pumps, hydraulics, water supply', kind: 'application' }, ], relatedMachineIds: ['gear-pump', 'hydraulic-cylinder', 'steam-engine', 'slider-crank'], thumbnail: thumbnail('Piston Pump', ['reciprocating-piston', 'inlet-valve', 'outlet-valve'], 'pressure-gauge'), parts: pistonPumpParts, hierarchy: hierarchy([ groupNode('motion', 'Motion conversion', ['crankshaft', 'connecting-rod', 'reciprocating-piston']), groupNode('fluid-end', 'Fluid end', ['cylinder-block', 'inlet-valve', 'outlet-valve']), groupNode('manifolds', 'Manifolds and pressure smoothing', ['suction-manifold', 'discharge-manifold', 'pulsation-damper']), groupNode('instrumentation', 'Instrumentation', ['pressure-gauge']), ]), cameraPresets: standardCameraPresets(4.9), guidedTour: [ tourStep('overview', 'Crank-driven pump', 'A crank converts rotary input to the piston stroke that changes chamber volume.', 'isometric', ['crankshaft', 'connecting-rod', 'reciprocating-piston']), tourStep('suction', 'Suction stroke', 'The piston retracts, inlet valve opens, and fluid enters from the suction manifold.', 'front', ['reciprocating-piston', 'inlet-valve', 'suction-manifold'], { playback: 'play', rpm: 240 }), tourStep('discharge', 'Pressure stroke', 'The piston advances, outlet valve opens, and fluid is forced into the discharge line.', 'front', ['reciprocating-piston', 'outlet-valve', 'discharge-manifold'], { playback: 'play', rpm: 240 }), tourStep('pulsation', 'Output ripple', 'The gauge and damper show why reciprocating pumps often need pressure smoothing.', 'right', ['pressure-gauge', 'pulsation-damper'], { explodeDistance: 0.2 }), ], animationModuleId: 'anim-piston-pump', labelsEnabledByDefault: true, }), makeMachine({ id: 'hydraulic-cylinder', slug: 'hydraulic-cylinder', title: 'Hydraulic Cylinder', category: 'pumps-fluid', difficulty: 'Beginner', complexityScore: 38, sortOrder: 18, releasedAt: '2025-02-01', summary: 'Double-acting cylinder with extend/retract chambers, seals, ports, and force explanation.', description: 'A double-acting hydraulic cylinder cutaway showing barrel, piston, rod, seals, gland, ports, chambers, end cap, and clevis mount. The guided tour explains pressure area, extension force, retraction force, and why the rod-side chamber has less area.', keywords: ['hydraulic cylinder', 'linear actuator', 'piston area', 'seal', 'extend', 'retract'], facts: [ { label: 'Force equation', value: 'Force = pressure × effective area', kind: 'pressure' }, { label: 'Typical pressure', value: '70-350', unit: 'bar industrial mobile hydraulics', kind: 'pressure' }, { label: 'Efficiency', value: 'High mechanical efficiency; losses dominated by seals and throttling', kind: 'efficiency' }, { label: 'Invention milestone', value: 'Hydraulic press principles from late 18th century; modern cylinders in 20th century', kind: 'date' }, { label: 'Common applications', value: 'Excavators, presses, lifts, clamps, aircraft systems', kind: 'application' }, ], relatedMachineIds: ['piston-pump', 'toggle-clamp', 'rack-and-pinion'], thumbnail: thumbnail('Hydraulic Cylinder', ['barrel', 'piston-rod', 'pressure-chamber'], 'rod-port'), parts: hydraulicCylinderParts, hierarchy: hierarchy([ groupNode('structure', 'Structure', ['barrel', 'gland', 'end-cap', 'clevis-mount']), groupNode('moving', 'Moving assembly', ['piston', 'piston-rod']), groupNode('seals', 'Sealing', ['rod-seal', 'piston-seal']), groupNode('fluid', 'Ports and chambers', ['base-port', 'rod-port', 'pressure-chamber', 'return-chamber']), ]), cameraPresets: standardCameraPresets(4.8), guidedTour: [ tourStep('overview', 'Linear actuator', 'Pressurised fluid acts on the piston area to produce straight-line force.', 'isometric', ['barrel', 'piston', 'piston-rod']), tourStep('extend', 'Extension', 'Pressure at the base port fills the larger cap-end chamber and pushes the rod out.', 'front', ['base-port', 'pressure-chamber', 'piston-rod'], { playback: 'play', rpm: 60 }), tourStep('retract', 'Retraction', 'Pressure at the rod port acts on an annular area because the rod occupies part of the piston face.', 'front', ['rod-port', 'return-chamber', 'piston'], { playback: 'play', rpm: 60 }), tourStep('seals', 'Seal stack', 'Rod and piston seals prevent leakage while allowing sliding motion.', 'right', ['rod-seal', 'piston-seal', 'gland'], { explodeDistance: 0.28 }), ], animationModuleId: 'anim-hydraulic-cylinder', labelsEnabledByDefault: true, }), ];