Summary
A ballistic pendulum on a ball-and-socket 6DOF constraint (all linear axes Locked, all angular axes Free) shows a frame-rate-dependent restoring acceleration. At ~3200 fps (headless, unbounded) the restoring term is uniformly scaled to ~0.73x of the analytic value (period error +18.3%); at t.MaxFPS 60 the period error reaches +96%. This makes Chaos 6DOF constraints unusable for physically accurate constrained rotation (robotics joints, physics simulation/education, metrology).
What Type of Bug are you experiencing?
Simulation
Steps to Reproduce
- Create a UPhysicsConstraintComponent (or APhysicsConstraintActor) between a static anchor body and a dynamic sphere (1 kg, r = 5 cm).
- Lock all linear limits (0); set Swing1/Swing2/Twist to Free; disable projection; disable collision between the pair.
- Displace the sphere 15 deg from vertical, rod length L = 200 cm.
- Run -game headless (-unattended -nullrhi); measure the period from zero-crossings of the lateral position.
- Repeat with t.MaxFPS 60.
Minimal setup code:/nJoint->SetConstrainedComponents(Anchor, NAME_None, Bob, NAME_None);
Joint->SetLinearXLimit(ELinearConstraintMotion::LCM_Locked, 0.f);
Joint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0.f);
Joint->SetLinearZLimit(ELinearConstraintMotion::LCM_Locked, 0.f);
Joint->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Free, 0.f);
Joint->SetAngularSwing2Limit(EAngularConstraintMotion::ACM_Free, 0.f);
Joint->SetAngularTwistLimit(EAngularConstraintMotion::ACM_Free, 0.f);
Joint->SetDisableCollision(true);
Joint->ConstraintInstance.DisableProjection();
Joint->InitComponentConstraint();
Note: the constraint must be initialized AFTER the dynamic particle is live in the solver (see Additional Notes).
Expected Result
Period should match the analytic small-angle value T = 2pisqrt(L/g) = 2.8375 s (L = 200 cm, g = 980.665 cm/s^2) and be independent of frame rate.
Observed Result
~3200 fps (headless, unbounded): T = 3.3574 s → +18.32% error.
60 fps (t.MaxFPS 60): T = 5.57 s → +96% error.
The restoring acceleration measured pointwise is alpha(theta) = 0.73 * g*sin(theta)/L at every sampled angle (uniform deficit, not angle-dependent).
Affects Versions
5.8
Platform(s)
Windows
Additional Notes
ELIMINATION CHAIN (instrumented, each ruled out with measurements):
- Sphere rotation absorbing KE: omega = v/L about Y, rotational KE = 0.02% of translational → ruled out.
- Inertia tensor: I = (10,10,10) kg*cm^2, exact for 1 kg r=5 cm sphere → ruled out.
- Constraint projection: DisableProjection(), probe confirms proj=0, no change → ruled out.
- Setup mechanism: manual component init vs APhysicsConstraintActor → identical 18.32%.
- Geometry: L_eff from trajectory arc = 201.2 cm (0.6%) → ruled out.
- Simulation clock: free-fall rig on the same map measures g at 0.12% error → ruled out.
- Rope-length dependence: L = 400 gives 18.22% (vs 18.32% at L = 200) → L-independent.
The ONLY variable that moves the error is solver dt (frame rate).
WORKAROUND WE SHIPPED: per-tick PBD-style exact rod (radial velocity projection + position snap in Tick): period error 0.60%, frame-rate independent. Confirms gravity/clock/free-body integration are sound; the defect is localized to the 6DOF constraint solve.
ADDITIONAL FINDINGS (possibly separate tickets):
- Runtime-initialized constraints are silently inert if InitComponentConstraint() runs before the dynamic particle is ingested (born-dynamic body, first frames). The body free-falls; no warning is emitted.
- A body that sleeps with gravity disabled (SetEnableGravity(false)) could not be woken by SetEnableGravity(true) + WakeRigidBody() + AddImpulse() (IsInstanceAwake() = 0 forever).
- Pendulums freeze at the apex with default sleep settings (near-zero-velocity frames trigger sleep; gravity never wakes the body). Workaround: SleepFamily = Custom, CustomSleepThresholdMultiplier = 0.
ENVIRONMENT: UE 5.8.2 source build, Win64, Development Editor; Windows 11 x64; VS2022 MSVC 14.44. Reproduced headless (-game -unattended -nullrhi) and with t.MaxFPS 60.
Full CSV trajectories (L=200/400, unbounded/60fps), pointwise alpha(theta) table and probe logs available on request.