SNAPKITTYWEST's picture
push from SNAPKITTYWEST/sovereign-apollo
5befefa verified
Raw History Blame Contribute Delete
2.51 kB
/**
* Physics Engine β€” MODERN DESIGN preserving Apollo constraints
* Deterministic fixed-step; drives Servicer 2-s cycle
*/
import { State, GuidanceMode, PropulsionState } from "../mission/state.js";
export interface PhysicsConfig {
dtMs: number; // minor cycle 1ms
servicerPeriodMs: number; // 2000ms DOCUMENTED
}
export const DEFAULT_CONFIG: PhysicsConfig = { dtMs: 1, servicerPeriodMs: 2000 };
export class PhysicsEngine {
state: State;
tMs = 0;
servicerAccum = 0;
cfg: PhysicsConfig;
constructor(initial: State, cfg=DEFAULT_CONFIG){ this.state=initial; this.cfg=cfg; }
/** Deterministic step β€” no Date.now, no random without seed */
step(dtMs?: number): void {
const dt = (dtMs ?? this.cfg.dtMs)/1000; // s
this.tMs += dt*1000;
this.servicerAccum += dt*1000;
// Simple Euler for demo β€” RECONSTRUCTED: replace with RK4+thrust per propulsion.ts
// Apply thrust if ENG ON
if (this.state.propulsion.thrustN>0) {
const mass = this.state.massKg;
const a = this.state.propulsion.thrustN / mass;
// assume +Z thrust in local β€” INFERRED simplification
this.state.velocity[2] += a*dt;
// mass flow
const isp = this.state.propulsion.ispS;
const mdot = this.state.propulsion.thrustN / (isp*9.80665);
this.state.massKg -= mdot*dt;
if (this.state.massKg < this.state.dryMassKg) this.state.massKg = this.state.dryMassKg;
}
// gravity (central body) β€” simplified; orbital.ts does N-body
const g0 = 1.62; // lunar β€” INFERRED; engine swaps body by altitude
this.state.velocity[2] -= g0*dt * 0.1; // placeholder
// position integrate
this.state.position[0]+= this.state.velocity[0]*dt;
this.state.position[1]+= this.state.velocity[1]*dt;
this.state.position[2]+= this.state.velocity[2]*dt;
if (this.servicerAccum >= this.cfg.servicerPeriodMs) {
this.servicerTick();
this.servicerAccum=0;
}
}
private servicerTick() {
// DOCUMENTED: Servicer 2-s guidance cycle would call LUNAR_LANDING_GUIDANCE_EQUATIONS
// Here we enforce guidance invariants (see sovereign/verification.ts)
// throttle logic etc. injected externally
}
runUntil(metSeconds: number): State[] {
const trace: State[] = [];
const targetMs = metSeconds*1000;
while (this.tMs < targetMs) { this.step(); if (this.tMs % 2000 <1) trace.push(structuredClone(this.state)); }
return trace;
}
}