w3DScene) and 2D Chart.js time-domain plot (w3DChart) in a flex layoutsimCustom() with buildInputFn() — supports step, ramp, sine, square, and sawtooth signals from the GUI signal selectorBug fixes:
sys.ol but Simulator used closed-loop sys.cl, causing e.g. MSD 0 dB (gain=1) in Bode but 0.5 m steady-state in Simulator. Fixed updCharts() to select sys.ol or sys.cl based on PID toggle statesimStep() unit step regardless of GUI settings. Changed to use simCustom() data matching the selected input signal and PID/filter configurationinit3D(): creates Three.js r128 WebGL scene with wall, mass block (amber), force arrow (red), damper with piston (blue), and ground plane with gridhelixCurve() using TubeGeometry + CatmullRomCurve3; dynamically rebuilt by updSpring(mx) as mass movesupdDamper(mx); force arrow length tracks instantaneous input forceanim3D() interpolates y(t) and u(t) arrays at current playback time, calls setMassPos()buildSystem() constructs open-loop L(s) = C(s)·G(s)·Filters and closed-loop CL(s) = L/(1+L)mimo.html) with A, B, C, D matrix inputbuildPID()) with Kp, Ki, Kd; derivative filter coefficient NfreqResp(): log-spaced frequency sweep, magnitude (dB) and phase (°) on separate chartsbodeMetrics(): gain margin, phase margin, gain/phase crossover frequencies, bandwidthtf2ss() state-space conversion, simStep() / simCustom() with RK4 integrationpolyMul(), polyAdd(), polyEval() for transfer function algebrasched() debouncesw.js) with cache-first strategy; manifest.json for installability