@ferret/physics-mechanisms
drivetrains of shafts and couplings, gears, clutches, turbines, tooth strength.
Read the guide: how to use it →
Classes
Drivetrain class
class Drivetrainreadonly shafts: Shaft[] | |
readonly couplings: Coupling[] | |
time: number | |
onEvent: ((e: MachineEvent) => void) | null | |
stall: { speed: number; torque: number; time: number; } | A driven shaft that holds under stallSpeed rad/s with a driving torque above stallTorque N m for stallTime s has stalled (stall event; again with stalled: false when it turns). |
readonly energy: { work: number; loss: number; friction: number; } | energy accounting, J |
shaft(d: ShaftDef): Shaft | |
find(name: string) | |
coupling(name: string) | |
gear(name: string, a: Shaft, b: Shaft, za: number, zb: number, o: { efficiency?: number; internal?: boolean; limit?: number; backlash?: number } = {}) | External gears: z_a·omega_a + z_b·omega_b = 0 (reverses); internal keeps the direction. backlash (rad of the first shaft) leaves the teeth a gap:
inside it nothing is transmitted, at either flank the mesh locks (the impact loses the kinetic energy of the closing speed) and it lets go when the torque reverses. |
worm(name: string, worm: Shaft, wheel: Shaft, starts: number, zw: number, lead: number, mu: number) | A worm (one shaft) driving a wheel of zw teeth with starts threads; lead is the lead angle (rad), mu the thread friction. |
belt(name: string, a: Shaft, b: Shaft, da: number, db: number, o: { mu?: number; wrap?: number; tension?: number; wedge?: number; toothed?: boolean; efficiency?: number; limit?: number } = {}) | Belt or chain over pulleys of diameters da and db, same direction. A belt slips beyond the capstan limit; a chain (toothed) does not. |
planetary(name: string, sun: Shaft, ring: Shaft, carrier: Shaft, zs: number, zr: number, efficiency = 1) | Sun (a), ring (b), carrier (c) by the Willis relation z_s·omega_s + z_r·omega_r = (z_s + z_r)·omega_c. |
differential(name: string, left: Shaft, right: Shaft, carrier: Shaft, efficiency = 1) | omega_1 + omega_2 = 2·omega_carrier: the carrier torque splits equally. |
cardan(name: string, input: Shaft, output: Shaft, beta: number, phase = 0) | Hooke's joint at the angle beta between the shafts; beta = 0 is a constant-velocity joint. |
speed(name: string, s: Shaft, w: (t: number) => number) | Holds a shaft to a given speed (a prescribed drive). |
speedSource(name: string, s: Shaft, o: { speed?: number; ramp?: number } = {}): SpeedSource | A speed source: a shaft of infinite inertia that sets its own speed, optionally along a ramp. The gears, belts and clutches
behind it feel real torques (a gear can still strip, a clutch still slip); only the shaft is eternal. torque and power read what it delivers. |
clutch(name: string, a: Shaft, b: Shaft, capacity: number) | Friction clutch: couples a and b up to capacity x command. |
gearbox(name: string, input: Shaft, output: Shaft, model: CouplingModel) | A gearbox between input and output: omega_out = omega_in / ratio for the engaged gear, nothing in neutral, a friction cone while a synchroniser
drags the gear to the shaft speed. The ratio list, the sleeves and the selector belong to the model (see Gearbox in gearbox.ts), which sets the
relation and the capacity of the coupling in every sub-step; the solver treats it as a clutch whose capacity is the cone torque, or infinite once the
dogs are in. |
impact(c: Coupling) | The kinetic energy of a closing speed is lost when a coupling locks while its sides still differ: books the shortfall of this step to c. |
readonly controls: Map<string, { set(command: unknown): unknown; state?(): unknown; }> | Named controls a game or a wire sets with machine.set (a throttle, a pedal): they are not couplings. |
brake(name: string, s: Shaft, capacity: number) | Brake: holds a shaft against the frame up to capacity x command. |
freewheel(name: string, a: Shaft, b: Shaft) | One-way element: b can overrun a but never lag behind it. |
drive(s: Shaft, f: TorqueSource) | Add a torque (a motor, a load, a turbine) acting on a shaft. |
attach(s: Shaft, r: Reciprocator) | |
kinetic(): number | |
step(dt: number, substeps = 1) | |
balance(): number | The kinetic energy plus the losses and friction less the work of the external torques: should stay near zero. |
packages/physics-mechanisms/src/drivetrain.ts:140
Gearbox class
class Gearbox implements CouplingModelThe selector and synchronisers of a gearbox, attached to a gearbox coupling of a drivetrain (see Gearbox.attach).
A shift is the sequence a real selector goes through: the sleeve of the engaged gear is pulled out (needs the load off the dogs), the finger crosses to the rail of the wanted gear (if it is another sleeve), the sleeve runs to the blocker ring, and there the cone drags the gear to the shaft speed with T = mu·F·r_m / sin(alpha) while the blocker holds the sleeve back until the speed difference is gone; then the sleeve passes the blocker and the dogs go in. With the speeds matched and the load off, the sequence takes nominal_time_s of the sleeve. Without the clutch the cone cannot drag the engine: it slips against the blocker, heats and wears, grinds after grindAfter and the shift is given up after refuseAfter (the gear stays in neutral).
readonly gears: Map<GearId, GearDef> | |
readonly syncs: Map<string, SyncUnit> | |
coupling: Coupling | |
train: Drivetrain | |
input: Shaft | |
output: Shaft | |
engaged: GearDef | null | the gear locked to the output (dogs in), or null in neutral / during a shift |
active: GearDef | null | the gear whose sleeve is displaced from neutral (engaged or in the middle of a shift) |
target: GearDef | 'N' | null | |
phase: Phase | |
effort: number | selector effort: the shift force relative to the nominal one |
gate: string | |
oilTemperature: number | |
status: ShiftStatus | |
power: { in: number; out: number; loss: number; } | power through the box over the last sub-step, W, and its losses |
energy: { in: number; out: number; loss: number; } | |
readonly opt: Required<Omit<GearboxOptions, 'gearJ' | 'dt' | 'life'>> | |
life: GearboxLife | |
constructor(readonly spec: GearboxSpec, o: GearboxOptions = {}) | |
reflectedInertia(idlerJ = 0): number | Reflected onto the input shaft: every free gear turns at omega_in / ratio, the idler of reverse at omega_in * z_in / z_idler. |
attach(train: Drivetrain, input: Shaft, output: Shaft, name = 'gearbox'): Coupling | |
command(cmd: unknown): { ok: boolean; gear?: string; reason?: string } | { gear: 3 }, { gear: 'R' }, { gear: 0 } or 'N' for neutral, and { effort: 1.5 } for the force on the lever relative to nominal. |
get gear(): GearId | 'N' | the gear that is in, or 'N' |
pre(h: number) | |
post(h: number) | |
nodeAngles(): { node: string; angle?: number; slide?: number; scale?: number; axis: [number, number, number] }[] | angle (rad) of the nodes that turn with the box but are not shafts of the drivetrain: the free gears (meshed with the input), the idler, the sleeves' slide |
meshFrequencies(): number[] | Tooth-mesh frequencies (Hz) of the meshes that carry load: z·n/60 (life.whine() has the harmonics and levels). |
state() |
packages/physics-mechanisms/src/gearbox.ts:138
GearboxLife class
class GearboxLifereadonly net: ThermalNet | |
readonly churn: Churn[] | |
readonly bearings: BearingDef[] | |
readonly rattlers: Rattler[] | |
readonly audio: SoundEvent[] | |
readonly opt: Required<LifeOptions> | |
level: number | oil level as a fraction of the nominal (1 = the spec's oil_level_z) and the height it stands at, mm |
readonly nu40: number | |
readonly levelNominal: number | |
readonly levelBottom: number | |
metalPpm: number | |
churnPower: number | |
readonly pitting: Record<string, number> | damage by pitting (1 = pitted) of each gear's mesh and of the final drive |
readonly pitted: Set<string> | |
readonly bearingLoss: { power: number; energy: number; } | |
rattleRate: number | |
rattleIntensity: number | |
constructor(private gb: Gearbox, private spec: GearboxSpec, o: LifeOptions = {}) | |
get oilTemperature() | |
get viscosity() | |
get levelZ() | oil level height, mm (spec z axis: up is positive) |
setLevel(f: number) | |
get coldFactor() | how much heavier a shift is in cold oil than at 40 °C: the sleeve and fork push through oil |
dip(axisZ: number, r: number) | immersion depth (mm) of a gear of tip radius r (mm) on an axis at height z (mm) |
attach(input: Shaft, output: Shaft) | register the oil-dipping gears, the shaft drags and the bearings; called by Gearbox.attach |
watchFinalDrive(fd: Coupling, diff: Coupling, carrier: Shaft) | the final drive and differential: their losses heat the oil, the crown dips and wears |
post(h: number, c: { meshLoss: number; coneLoss: number; cone: SyncUnit | null }) | |
drain(): SoundEvent[] | hand the queued sound events to the audio layer |
clunk(gear: string, intensity: number) | |
grind(gear: string, grinding: boolean, intensity: number) | |
whine() | mesh whine of the loaded meshes: f = z·n/60 and its first harmonics, louder with load and with pitting |
state() |
packages/physics-mechanisms/src/gearbox-life.ts:68
SpeedSource class
class SpeedSourceA prescribed shaft speed that can be changed along a linear ramp (see Drivetrain.speedSource).
coupling: Coupling | |
target: number | the speed asked for, rad/s |
constructor(private readonly dt: Drivetrain, readonly shaft: Shaft, speed: number) | |
at(t: number): number | The speed at drivetrain time t. |
setSpeed(w: number, ramp = 0) | Go to w rad/s over ramp seconds (at once when 0), from the speed it has now. |
get torque() | the torque the source puts on its shaft over the last step, N·m (what the gears behind it carry) |
get power() | the power it delivers, W |
packages/physics-mechanisms/src/drivetrain.ts:119
ThermalNet class
class ThermalNetreadonly nodes: Map<string, { C: number; T: number; }> | |
constructor(readonly ambient: number) | |
add(name: string, C: number, T = this.ambient) | |
link(a: string, b: string, G: number) | |
toAir(a: string, G: () => number) | |
heat(name: string, J: number) | |
T(name: string) | |
step(h: number) |
packages/physics-mechanisms/src/gearbox-life.ts:13
Functions
buildTransaxle function
function buildTransaxle(train: Drivetrain, spec: GearboxSpec, o: TransaxleOptions = {}): TransaxleBuild the transaxle drivetrain from spec.json into train. Shaft names: flywheel, Shaft_In, Shaft_Out, Diff_Carrier, Halfshaft_L, Halfshaft_R. Controls (machine.set { element, command }): gearbox ({gear, effort}), clutch (engagement 0..1, a coupling), throttle (0..1), brake (0..1).
packages/physics-mechanisms/src/gearbox.ts:544
cardanAngle function
function cardanAngle(theta: number, beta: number, near: number): numberOutput angle of Hooke's joint, continuous with near (tan(out) = tan(in) / cos(beta)).
packages/physics-mechanisms/src/drivetrain.ts:553
cardanRatio function
function cardanRatio(theta: number, beta: number): numberHooke's joint: the output / input speed ratio, the derivative of tan(out) = tan(in) / cos(beta), with the angles measured from the plane of the bend: cos(beta) / (1 - sin²(beta)·cos²(theta)). The extremes are 1/cos(beta) and cos(beta).
packages/physics-mechanisms/src/drivetrain.ts:548
cpCurve function
function cpCurve: (cpMax?: number, peak?: number) => (lambda: number) => numberA typical Cp(lambda) curve with its peak at peak (tip-speed ratio) and height cpMax (clamped to Betz): a parabola, zero at 0 and at twice the peak.
packages/physics-mechanisms/src/turbines.ts:10
crankSlider function
function crankSlider: (r: number, l: number) => (theta: number) => numberCrank-slider position, x = r·cos(theta) + sqrt(l² − r²·sin²(theta)).
packages/physics-mechanisms/src/drivetrain.ts:560
gasPower function
function gasPower(o: { eta: number; mdot: number; cp: number; T1: number; pressureRatio: number; gamma?: number }): numberPower of a gas or steam turbine, W: P = eta·mdot·cp·T1·(1 − (1/PR)^((gamma−1)/gamma)).
packages/physics-mechanisms/src/turbines.ts:31
gauss function
function gauss(A: number[][], b: number[]): number[]packages/physics-mechanisms/src/drivetrain.ts:526
gearInertia function
function gearInertia(z: number, mn: number, beta: number, b: number, rho = 7850): numberPlaceholder inertia of a gear until drivetrain.json has the measured one: a rim with a web, 60 % of the solid disc.
packages/physics-mechanisms/src/gearbox.ts:492
lewisForce function
function lewisForce: (sigma: number, module: number, width: number, Y?: number) => numberLewis tooth bending limit: the tangential force (N) a tooth of module m (m) and face width b (m) carries at allowable stress sigma and form factor Y.
packages/physics-mechanisms/src/drivetrain.ts:562
lewisY function
function lewisY: (z: number, beta?: number) => numberLewis form factor from the virtual tooth count (z / cos³ beta): the usual fit Y = 0.484 - 2.87 / z.
packages/physics-mechanisms/src/gearbox.ts:42
machines function
function machines(train: Drivetrain = new Drivetrain()): MachineCapabilitypackages/physics-mechanisms/src/index.ts:41
meshStiffness function
function meshStiffness(b: number, rb: number, cPrime = 14e9): { linear: number; torsional: number }Stiffness of a mesh across the face width b: the pair of teeth together bend and flatten by about 1/(14 GPa) of the load per metre of width (a spur pair of steel, c' ≈ 14 N/(µm·mm)); the torsional stiffness at base radius rb (m) is that times rb², N·m/rad.
packages/physics-mechanisms/src/drivetrain.ts:587
oilViscosity function
function oilViscosity: (nu40: number, T: number) => numberKinematic viscosity of the oil (cSt) at T °C from its value at 40 °C: about a factor 7 between 40 and 100 °C for a gear oil.
packages/physics-mechanisms/src/gearbox-life.ts:37
pairLimit function
function pairLimit(p: { mn: number; z1: number; z2: number; beta: number; b: number }, sigmaF: number, sigmaH: number, E = 210e9)The tangential force (N) one pair of teeth carries before the weaker of Lewis bending (either gear, at the allowable bending stress) and the Hertz pressure (allowable flank pressure) is reached, and the torque on the first gear it stands for (N·m).
packages/physics-mechanisms/src/gearbox.ts:48
propeller function
function propeller(o: { rho: number; diameter: number; kt: number; kq: number })A propeller: thrust (N) and the shaft torque it needs, from the thrust and torque coefficients, T = kt·rho·n²·D⁴.
packages/physics-mechanisms/src/turbines.ts:42
pumpLoad function
function pumpLoad(o: { flow: (omega: number) => number; rise: (omega: number) => number; eta: number }): TorqueSourceA pump, fan or compressor as a load: shaft power = flow x pressure rise / efficiency, as a torque against rotation.
packages/physics-mechanisms/src/turbines.ts:37
registerMachineCommands function
function registerMachineCommands(c: { register(name: string, description: string, fn: (a: any) => unknown): unknown }, train: Drivetrain)The machine.* commands on any registry with register(name, description, fn).
packages/physics-mechanisms/src/index.ts:132
toothContactLimit function
function toothContactLimit(b: number, d1: number, d2: number, m1: FlankMaterial = STEEL_FLANK, m2: FlankMaterial = m1, alpha = (20 * Math.PI) / 180): numberThe tangential force a pair of teeth carries before the Hertz pressure reaches the weaker flank's allowable value, N: the inverse of toothContactPressure.
packages/physics-mechanisms/src/drivetrain.ts:579
toothContactPressure function
function toothContactPressure(Ft: number, b: number, d1: number, d2: number, m1: FlankMaterial = STEEL_FLANK, m2: FlankMaterial = m1, alpha = (20 * Math.PI) / 180): numberHertz contact of two teeth at the pitch point as two cylinders of the radii of curvature d·sin(α)/2 pressed along the face width b (m): the
pressure for a tangential tooth force Ft (N) on pitch diameters d1, d2 (m) at pressure angle α. Zero when a diameter or the width is not above zero.
packages/physics-mechanisms/src/drivetrain.ts:572
waterPower function
function waterPower: (eta: number, flow: number, head: number, rho?: number, g?: number) => numberPower of a water turbine, W: P = eta·rho·g·Q·H.
packages/physics-mechanisms/src/turbines.ts:23
waterTurbine function
function waterTurbine(o: { eta: number; flow: () => number; head: () => number; rho?: number }): TorqueSourceA water turbine as a torque: the power from the head and flow, divided by the speed (with a floor so it starts from rest).
packages/physics-mechanisms/src/turbines.ts:26
windPower function
function windPower: (rho: number, area: number, v: number, cp: number) => numberPower of a wind turbine, W: P = ½·rho·A·v³·Cp, with Cp never above the Betz limit.
packages/physics-mechanisms/src/turbines.ts:7
windTurbine function
function windTurbine(o: { rho?: number; radius: number; wind: () => number; cp?: (lambda: number) => number }): TorqueSourceA wind turbine as a torque on its shaft: T = P / omega with P from the tip-speed ratio.
packages/physics-mechanisms/src/turbines.ts:13
Interfaces
BodyBinding interface
interface BodyBindingBody mode: a shaft turns a kinematic body of the kernel (a paddle, a wheel, a turntable, a crane's jib) about a pivot and an axis, so the machine moves things in the world; what the world does back (the contacts' impulses about the axis) is a load torque on the shaft, so a paddle that meets a crate slows, and one that meets what it cannot move jams.
packages/physics-mechanisms/src/index.ts:26
Coupled interface
interface CoupledA rotor joined to a dynamic body by a viscous coupling: it puts damping x (shaft speed - body speed about the axis) on the body and
takes the same from the shaft, so angular momentum is kept and the shaft slips against a load it cannot turn (the joint, the kernel's
hinge, holds the body to its axis). Stable while damping x dt stays below the smaller of the inertias.
packages/physics-mechanisms/src/index.ts:39
Coupling interface
interface Couplingreadonly id: number | |
readonly name: string | |
readonly kind: CouplingKind | |
shafts: Shaft[] | |
a: number[] | coefficients of sum(a_k·omega_k) = 0 (or = speed for 'speed'); the first shaft has 1 |
efficiency: number | |
capacity: number | torque capacity N·m (friction couplings), scaled by command for a clutch and a brake |
command: number | |
limit?: number | tooth or belt limit on the torque through the coupling, N·m; it breaks beyond it |
state: 'stuck' | 'slip' | 'free' | 'locked' | |
slipDir: number | |
broken: boolean | |
torque: number | torque through the coupling over the last step (on its first shaft), N·m |
lead?: number | worm: lead angle (rad) and friction coefficient |
mu?: number | |
beta?: number | cardan: shaft angle beta (rad) and the orientation of the fork on the input shaft |
phase?: number | |
lash?: number | backlash: the free play (rad of the first shaft), where the teeth are inside it (rad), and the flank in contact (+1, -1; 0 = in the gap) |
lashPhi?: number | |
lashSide?: number | |
speed?: (t: number) => number | |
loss: number | energy lost in the coupling, J |
model?: CouplingModel |
packages/physics-mechanisms/src/drivetrain.ts:78
CouplingBase interface
interface CouplingBasename: string | |
efficiency?: number |
packages/physics-mechanisms/src/drivetrain.ts:74
CouplingModel interface
interface CouplingModelBehaviour a coupling takes from outside the solver (the synchronisers of a gearbox): pre runs at the start of every sub-step and sets what the
solver reads (a, capacity, efficiency), post runs after the speeds are solved and advances the model's own state.
pre?(h: number): void | |
post?(h: number): void | |
command?(cmd: unknown): unknown | a command object from machine.set |
state?(): unknown |
packages/physics-mechanisms/src/drivetrain.ts:66
DrivetrainFile interface
interface DrivetrainFilebuild/drivetrain.json as far as the machine reads it: the measured inertias and the node names.
shafts?: Record<string, unknown> | |
nodes?: { sleeves?: Record<string, string>; forks?: Record<string, string>; rails?: Record<string, string>; oil?: string; housing?: string[] } |
packages/physics-mechanisms/src/gearbox.ts:35
Engine interface
interface Enginethrottle: number | |
ripple: number | |
idle: number | |
peak: number | |
limit: number | |
torque(omega: number): number |
packages/physics-mechanisms/src/gearbox.ts:519
FlankMaterial interface
interface FlankMaterialMaterial of a tooth flank for the contact check: Young's modulus (Pa), Poisson's ratio, the allowable Hertz pressure (Pa, from the pitting fatigue limit).
E: number | |
nu: number | |
sigmaH: number |
packages/physics-mechanisms/src/drivetrain.ts:565
GearboxOptions interface
interface GearboxOptionsgrindAfter?: number | time the cone may slip against the blocker before it is felt as a grind (s), and before the shift is given up (s) |
refuseAfter?: number | |
passSpeed?: number | speed difference (rad/s on the input shaft) under which the blocker lets the sleeve pass |
releaseTorque?: number | torque on the dogs (N·m, input side) the sleeve can pull out of engagement; a bigger load holds the gear in |
wearLife?: number | energy (J) that wears a cone out completely |
coneHeatCapacity?: number | thermal mass (J/K) and conductance to the oil (W/K) of a cone, and the ambient air temperature |
coneToOil?: number | |
ambient?: number | |
life?: LifeOptions | oil, thermal network, sound, wear (see gearbox-life.ts) |
gearJ?: Partial<Record<GearId, number>> | inertia of the free gears and the idler, by gear: from drivetrain.json when given |
dt?: DrivetrainFile |
packages/physics-mechanisms/src/gearbox.ts:96
GearboxSpec interface
interface GearboxSpecmeta: { design_torque_nm: number; rpm_limit: number } | |
pairs: Record<string, SpecPair> | |
reverse: { mn: number; z_in: number; z_out: number; z_idler: number; b: number; beta?: number } | |
final_drive: { z_pinion: number; z_crown: number; mn: number; b: number; beta: number } | |
sync: Record<string, SpecSync> | |
material: { sigma_f_allow: number; sigma_h_allow: number; tau_allow?: number; density_steel?: number; e_steel?: number } | |
efficiency: { mesh: number } | |
shafts?: { input?: { d: number; length: number }; output?: { d: number; length: number } } | |
tolerance?: { backlash_min?: number; backlash_max?: number } | |
housing?: { oil_volume_l?: number } |
packages/physics-mechanisms/src/gearbox.ts:22
GearDef interface
interface GearDefid: GearId | |
ratio: number | omega_in / omega_out, negative for reverse |
sync: string | |
side: -1 | 1 | -1 = the first gear of the sleeve's pair, +1 = the second |
eta: number | product of the engaged meshes' efficiencies |
limit: number | torque on the input shaft at which the gear's teeth give way, N·m |
teeth: number[] | pitch circle radii and tooth counts along the path, for the whine frequencies |
node: string | |
brokenNode: string | |
J: number | inertia of the free gear (and the idler), kg·m² |
broken: boolean |
packages/physics-mechanisms/src/gearbox.ts:59
Housing interface
interface HousingThe mounting of a shaft. Every step the drivetrain hands it the mean reaction torque of that step as a vector (N·m, in the housing's frame, along the
shaft's axis): the capability turns it into kernel.applyTorque on the housing body or the vessel. The shaft's speed is relative to the housing; the
pseudo-torque from the housing's own turning is ignored (the housing is heavy against the shaft, or it is the world).
torque(t: [number, number, number], dt: number): void |
packages/physics-mechanisms/src/drivetrain.ts:31
LifeOptions interface
interface LifeOptionsfatigueSpeedup?: number | accelerated life test: damage per revolution is multiplied by this (1 = real time) |
bearingScale?: number | multiplies the dynamic rating C of every bearing |
pittingLimit?: number | endurance limit of the flanks, Pa (default 0.68 of the static allowable) and the Woehler exponent and corner cycles |
pittingExponent?: number | |
pittingCycles?: number | |
airSpeed?: () => number | relative torque ripple of the engine at the input of the box (as a fraction of the design torque) used by ripple() |
restitution?: number | coefficient of restitution of a tooth impact in the backlash |
freeGearDrag?: number | drag torque of a free gear on its needle bearing, N·m |
ambient?: number |
packages/physics-mechanisms/src/gearbox-life.ts:44
MachineCapability interface
interface MachineCapability extends Capabilityreadonly train: Drivetrain | |
readonly bound: BodyBinding[] | |
bind(shaft: Shaft, body: Body, opts?: { pivot?: Vec3; axis?: Vec3 }): BodyBinding | |
couple(shaft: Shaft, body: Body, opts?: { axis?: Vec3; damping?: number }): Coupled | Dynamic mode: a shaft turns a body that a kernel hinge holds (see Coupled). |
packages/physics-mechanisms/src/index.ts:27
Reciprocator interface
interface ReciprocatorA mass that moves with the shaft's angle: x = s(theta). A slider on a crank, a cam follower, a lead screw, a Scotch yoke.
s: (theta: number) => number | |
mass: number | |
load?: (x: number, v: number) => number | force on the mass as a function of position and speed (spring, gas, load), N |
packages/physics-mechanisms/src/drivetrain.ts:53
Shaft interface
interface Shaftreadonly id: number | |
readonly name: string | |
J: number | |
b: number | |
coulomb: number | |
omega: number | |
theta: number | |
diameter?: number | |
shear?: number | |
node?: string | |
axis: [number, number, number] | |
housing?: Housing | |
reaction: number | the mean torque the shaft put on its housing over the last step, N·m about the shaft's axis (positive along it) |
sources: TorqueSource[] | |
reciprocators: Reciprocator[] | |
broken: boolean | |
transmitted: number | largest torque any coupling put on the shaft in the last step, N·m |
packages/physics-mechanisms/src/drivetrain.ts:35
ShaftDef interface
interface ShaftDefA drivetrain as a small network: shafts (one degree of freedom each, with inertia) joined by couplings that fix a speed relation. Each step solves the velocity constraints with Lagrange multipliers (implicit, so a stiff ratio is exact at any step), then the efficiency of every mesh is applied to the torque that reaches the driven side, so power in = power out + losses.
name: string | |
J: number | moment of inertia, kg·m² |
b?: number | viscous friction, N·m·s/rad |
coulomb?: number | dry (Coulomb) friction torque, N·m |
omega?: number | |
theta?: number | |
diameter?: number | shaft diameter (m) and the shear stress (Pa) it carries: it breaks when 16·T / (π·d³) passes the limit |
shear?: number | |
node?: string | the scene node this shaft turns, and the axis |
axis?: [number, number, number] | |
housing?: Housing | the body the shaft is mounted in: whatever turns the shaft pushes the opposite way on it; none = fixed to the world |
packages/physics-mechanisms/src/drivetrain.ts:6
ShiftStatus interface
interface ShiftStatustarget: GearId | 'N' | null | |
phase: Phase | |
elapsed: number | s since the command |
last: { gear: string; time: number; ok: boolean; reason?: string } | null | time the last finished shift took, s, and how it ended |
grinding: boolean |
packages/physics-mechanisms/src/gearbox.ts:117
SpecPair interface
interface SpecPairmn: number | |
z_in: number | |
z_out: number | |
beta: number | |
b: number |
packages/physics-mechanisms/src/gearbox.ts:17
SpecSync interface
interface SpecSyncgears: [string, string] | |
cone_angle: number | |
mean_radius: number | |
mu: number | |
spring_n: number | |
shift_force_n: number | |
nominal_time_s: number | |
sleeve_travel: number |
packages/physics-mechanisms/src/gearbox.ts:18
SyncUnit interface
interface SyncUnitname: string | |
spec: SpecSync | |
x: number | sleeve position along the shaft, mm from neutral: negative toward the first gear of the pair |
temperature: number | cone temperature, °C, and wear 0 (new) .. 1 (finished) |
wear: number | |
sleeveNode: string | |
forkNode: string | |
railNode: string | |
slipEnergy: number | energy slipped in the cone over its life, J |
packages/physics-mechanisms/src/gearbox.ts:79
Transaxle interface
interface Transaxletrain: Drivetrain | |
gearbox: Gearbox | |
engine: Engine | |
shafts: { flywheel: Shaft; input: Shaft; output: Shaft; carrier: Shaft; left: Shaft; right: Shaft } | |
clutch: Coupling | |
finalDrive: Coupling | |
differential: Coupling | |
brakes: Coupling[] | |
speed(): number | forward speed of the vehicle, m/s |
state(): Record<string, unknown> | |
nodeAngles(): { node: string; angle?: number; slide?: number; scale?: number; axis: [number, number, number] }[] | |
setPedal(p: number): void | clutch pedal 0 (up, engaged) .. 1 (down) |
packages/physics-mechanisms/src/gearbox.ts:521
TransaxleOptions interface
interface TransaxleOptionsdt?: DrivetrainFile | |
gearbox?: GearboxOptions | |
flywheelJ?: number | engine flywheel inertia (kg·m²); peak torque and speed limit default to the spec's design torque and rpm limit |
idleRpm?: number | |
wheelRadius?: number | vehicle: wheel radius (m), mass (kg), inertia of one wheel with its tyre (kg·m²), rolling coefficient, Cd·A (m²) |
vehicleMass?: number | |
wheelJ?: number | |
rolling?: number | |
cdA?: number | |
brakeTorque?: number | friction torque of one brake at the wheel, N·m |
clutchMargin?: number | clutch capacity as a multiple of the design torque |
finalBacklash?: number | mesh backlash of the final drive, rad on the pinion (omit: none) |
packages/physics-mechanisms/src/gearbox.ts:499
Types
CouplingKind type
type CouplingKind = 'gear' | 'worm' | 'belt' | 'planetary' | 'differential' | 'cardan' | 'speed' | 'clutch' | 'brake' | 'freewheel' | 'gearbox'packages/physics-mechanisms/src/drivetrain.ts:60
GearId type
type GearId = '1' | '2' | '3' | '4' | '5' | 'R'packages/physics-mechanisms/src/gearbox.ts:13
MachineEvent type
type MachineEvent = | { kind: 'break'; element: string; torque: number; node?: string; broken?: string; mode?: 'stripped' | 'sheared' | 'overload' } | { kind: 'wear'; element: string; mode: 'pitting' | 'bearing'; damage: number } | { kind: 'slip'; element: string; slipping: boolean; grind?: boolean; gear?: string } | { kind: 'shift'; element: string; gear: string; ok: boolean; reason?: string; time?: number } | { kind: 'stall'; element: string; stalled: boolean; torque: number }packages/physics-mechanisms/src/drivetrain.ts:109
SoundEvent type
type SoundEvent = | { t: number; kind: 'clunk'; gear: string; intensity: number } | { t: number; kind: 'grind'; gear: string; grinding: boolean; intensity: number } | { t: number; kind: 'rattle'; gear: string; intensity: number }packages/physics-mechanisms/src/gearbox-life.ts:39
TorqueSource type
type TorqueSource = (omega: number, theta: number, t: number) => numberpackages/physics-mechanisms/src/drivetrain.ts:33
Constants
BETZ const
const BETZ: numberBetz limit of a wind turbine's power coefficient.
packages/physics-mechanisms/src/turbines.ts:4
MACHINE_DEFAULTS const
const MACHINE_DEFAULTS: { substeps: number; }machines. A Drivetrain of shafts and couplings is stepped with the world; limits become events and the shafts
turn the scene nodes they name. The machine has no input binding: a game or a wire sets a command and reads speeds and torques.
values (each at world / level / zone / entity scope):
substeps solver sub-steps per world step (4)
events: machine:break { element, torque }, machine:slip { element, slipping }, machine:stall { element, stalled, torque }.
packages/physics-mechanisms/src/index.ts:19
STEEL_FLANK const
const STEEL_FLANK: FlankMaterialpackages/physics-mechanisms/src/drivetrain.ts:566