FERRETGame engine over Babylon.js
Ferret

@ferret/physics-engines

steam cylinders with valve gear by crank angle, multi-cylinder piston engines with firing order, ignition and fuel controls, inertia forces on the mounts, and the engine words of the motion language.

16 exports · source in packages/physics-engines/src

Classes

MultiCylinderEngine class

class MultiCylinderEngine implements EngineControl
readonly engines: PistonEngine[]
readonly firing: number[]the crank angle (rad) at which each cylinder fires, within the cycle
readonly spec: MultiEngineSpec
throttleNow: number
constructor(spec: MultiEngineSpec)
torque: (omega: number, theta: number) => number
throttle(v: number)
ignition(advance: number)spark advance before top dead centre for every cylinder, rad
fuel(on: boolean)fuel supply on or off for the whole engine: off is the ignition cut
fuelOn: boolean
cutCylinder(i: number, cut: boolean)cut or restore one cylinder
rpm()
get work()
state()
pin(i: number): numberthe crank pin angle of cylinder i within the turn: it follows from the firing order (1-3-4-2 puts the pins at 0, pi, pi, 0)
applyInertia(omega: number, theta: number, mount: MountLike)

packages/physics-engines/src/engines.ts:83

SteamCylinder class

class SteamCylinder
readonly spec: SteamCylinderSpec
readonly gear: ValveGearthe valve gear: the controls change it while the engine runs
regulator: numberadmission opening 0..1 (the regulator)
readonly area: number
readonly rodArea: number
readonly swept: number
readonly clearanceVolume: number
work: numberwork the gas did on the piston, J; steam taken from the boiler, kg; steam exhausted, kg
steamUsed: number
steamExhausted: number
get pressures(): [number, number]the pressure in each end now, Pa
constructor(spec: SteamCylinderSpec)
stroke(th: number)distance the piston has moved from the head-end dead centre, m
vol(end: number, th: number): numbervolume of end 0 (head) or 1 (crank end) at crank angle th (without the cylinder's own phase)
angleFor(share: number): numberthe crank angle (0..pi, from the head-end dead centre) at which the piston has covered share of the stroke
torque(_omega: number, theta: number, t: number): numberThe torque on the shaft at its angle theta (the cylinder advances its cycle from the angle of the last call); the same shape as a drivetrain source.
inertiaForce(omega: number, theta: number, mass: number): numberthe inertia force of the reciprocating mass and the rod along the cylinder axis, N (positive toward the head), at shaft speed omega and angle theta

packages/physics-engines/src/steam.ts:63

SteamEngine class

class SteamEngine implements EngineControl
readonly cylinders: SteamCylinder[]
readonly spec: SteamEngineSpec
throttleNow: number
constructor(spec: SteamEngineSpec)
torque: (omega: number, theta: number, t: number) => numbera torque source for the drivetrain
throttle(v: number)
cutoff(v: number)
reverse(on: boolean)
rpm()
get work()
get steamUsed()
state()
applyInertia(omega: number, theta: number, mount: MountLike)the inertia forces of the cylinders on the mounts (each along its axis, at its point)

packages/physics-engines/src/engines.ts:39

Functions

engineForms function

function engineForms(br: MotionBridge, reg: EngineRegistry): void

packages/physics-engines/src/forms.ts:18

inertiaAlong function

function inertiaAlong(r: number, l: number, omega: number, theta: number, mass: number): number

The inertia force of a reciprocating mass along its cylinder axis (positive toward the head): minus mass times the piston's acceleration at constant speed.

packages/physics-engines/src/engines.ts:136

Interfaces

BoilerLike interface

interface BoilerLike

The steam cylinder. A double-acting piston on a crank: a chamber on each side of the piston, each a mass of steam as a perfect gas (gamma 1.3, the model of steamWork), fed from a boiler through a port whose opening is a function of the crank angle (the valve gear: lead, cut-off, release, compression) and exhausting to the atmosphere or a condenser. The torque on the crank is the work the gas does over the angle it turned, so the pulsation, the dead centre and the indicator diagram come out of the cycle, not from an averaged power.

Energy: steam admitted brings the enthalpy cp*T of a perfect gas at the boiler's temperature (the boiler itself loses the real enthalpy; the latent heat the model does not use leaves with the exhaust, as it does in a real engine), steam exhausted takes cp*T of the chamber, and the gas does p dV on the piston. The work per cycle is the area of the indicator diagram.

readonly pressure: number
readonly T: number
readonly quality: number
flowThrough(area: number, outside?: number): number
take(kg: number): number

packages/physics-engines/src/steam.ts:13

BoilerSensor interface

interface BoilerSensor

The words of the language for engines and boilers, registered through the bridge so their arguments are checked when a program loads:

  controls (owner only)  (throttle e v) (cutoff e v) (reverse e on) (ignition e rad) (fuel e on)
  sensors                (engine-rpm e) (pressure b) (level b)

A centrifugal governor is then a program: (loop (throttle "engine" (clamp (* 0.002 (- 300 (engine-rpm "engine"))) 0 1)) (wait 0.05)).

readonly pressure: number
readonly volume: number
readonly T: number
readonly water: number

packages/physics-engines/src/forms.ts:12

CylinderMount interface

interface CylinderMount
axis?: Vec3the direction of the cylinder's axis from the crank to the head, in the housing's frame (default up)
point?: Vec3where the cylinder acts on the housing, in the world (or already transformed by the caller)

packages/physics-engines/src/engines.ts:24

EngineControl interface

interface EngineControl

The controls and sensors an engine offers to programs and forms. All are optional: an engine has what makes sense for it.

throttle?(v: number): void
cutoff?(v: number): void
reverse?(on: boolean): void
ignition?(advance: number): void
fuel?(on: boolean): void
rpm?(): number
state?(): Record<string, unknown>

packages/physics-engines/src/engines.ts:14

EngineRegistry interface

interface EngineRegistry
engines: Map<string, EngineControl>
boilers?: Map<string, BoilerSensor>

packages/physics-engines/src/forms.ts:13

MountLike interface

interface MountLike

where the forces of an engine go: a body (or a vessel) at a point of its frame

applyForce(f: Vec3, worldPoint?: Vec3): void

packages/physics-engines/src/engines.ts:11

MultiEngineSpec interface

interface MultiEngineSpec
cylinder: EngineSpecthe cylinders are copies of this one
count: number
order?: number[]firing order, cylinder numbers from 1: [1, 3, 4, 2]; default 1..count
reciprocatingMass?: number
mounts?: CylinderMount[]
cycle?: 'four' | 'two'the four-stroke cycle takes two turns, the two-stroke one

packages/physics-engines/src/engines.ts:72

SteamCylinderSpec interface

interface SteamCylinderSpec
bore: numberbore and crank radius (half the stroke) and rod length, m
crank: number
rod: number
clearance?: numberdead volume at each end as a share of the swept volume (default 0.08)
rodDiameter?: numberpiston rod diameter on the crank end (takes area from that side), m (default 0)
boiler: BoilerLike
inlet: numberport areas: inlet and exhaust, m2, with the valve open
exhaustPort: number
back?: numberpressure the steam is exhausted into, Pa (atmosphere 101325, or a condenser)
gear?: Partial<ValveGear>
phase?: numbercrank angle of this cylinder's pin relative to the shaft, rad (a locomotive's two cylinders stand 90 degrees apart)
gamma?: number
Cd?: numberdischarge coefficient of the ports

packages/physics-engines/src/steam.ts:35

SteamEngineSpec interface

interface SteamEngineSpec extends Omit<SteamCylinderSpec, 'phase'>
phases?: number[]the crank angle of each cylinder's pin: a locomotive has two at 90 degrees (default one)
reciprocatingMass?: numbermass of the piston, crosshead and the rod that moves with them, kg (for the inertia force on the mounts)
mounts?: CylinderMount[]

packages/physics-engines/src/engines.ts:32

ValveGear interface

interface ValveGear

The valve events of one end of the cylinder, in fractions of the stroke (cut-off, release, compression) and radians of crank (lead).

cutoff: numbershare of the stroke at which the steam is cut off, 0..1 (the Johnson bar or the link notch)
lead: numbercrank angle before the dead centre at which the port opens, rad
release: numbershare of the stroke at which the exhaust opens
compression: numbershare of the return stroke left when the exhaust closes (what is compressed into the clearance)
reverse: booleanthe engine runs backwards: the events are taken in the other turning direction

packages/physics-engines/src/steam.ts:22

Types

Vec3 type

type Vec3 = [number, number, number]

Whole engines: several cylinders on one crank, with the controls a driver or a program has. Both engines are a TorqueSource for a drivetrain shaft (engine.torque); the reaction on the housing's torque comes from the drivetrain's housings (A0), and applyInertia puts the unbalanced forces of the reciprocating masses on the mounts.

packages/physics-engines/src/engines.ts:9