Chaos Ragdoll Rigid Bodies not Falling Asleep Properly

Hello,

I am running into an issue where rigid bodies attached to a ragdolls not falling asleep properly even if their linear speeds dropping below the thresholds set in the physics material (with the ‘Sleep Linear Velocity Threshold’ parameter). Resulting in the rigid bodies never fully settle and continue on with jittery motion.

I am currently using the physics asset provided by Metahuman (m_tal_nrw_body_Physics) and calling SetAllBodiesBelowSimulatePhysics() to activate ragdoll.

After digging into it some more, it appears that rigid bodies with constraints are skipped entirely when performing the sleep tests:

void FPBDIslandManager::ProcessParticlesSleep(const FRealSingle Dt) { // Check the sleepiness of particles that are not in any islands. // @todo(chaos): this is very expensive because we have to search for a material in GetParticleSleepThresholds. // We should probably cache a particle's sleep (and disable) thresholds somewhere. TArray<FGeometryParticleHandle*> SleptParticles; TArray<FGeometryParticleHandle*> DisabledParticles; for (FTransientPBDRigidParticleHandle& Rigid : Particles.GetActiveDynamicMovingKinematicParticlesView()) { if (Rigid.IsDynamic() && !Rigid.IsInConstraintGraph())

This is intentional? are there other ways to put these rigid bodies to sleep?

Thanks in advance for the support.

Hi Benjamin,

Yes this is intentional. I am a little surprised that the function below this isn’t putting the whole island to sleep, but that could be due to the jittering you mention.

I’d suggest using a system approach for this (ie call through the ‘owner’ class) - there are functions such as USkeletalMeshComponent::IsAnyRigidBodyAwake and USkeletalMeshComponent::PutAllRigidBodiesToSleep which should help you.

All the best

Geoff Stacey

Developer Relations

Hi Benjamin,

On reflection you are correct, in this case that function likely won’t help you. Chaos disables the code path for a _single_ rigid body with a constraint, it would turn off an inactive island. The idea of monitoring linear speeds is reasonable enough - the other way you could do it is to monitor movement within an area, and if it doesn’t exceed a tolerance (ie X stays between 9.95 and 10.05 for 2 seconds) value in all 6 degrees of freedom then it can be put to sleep - that is used sometimes specifically for jitter in physics.

I have taken a look at the default manny and you are correct it doesn’t settle as standard, I’ll reach out dev wise to see if this is known and what the expectations are for an example asset.

All the best

Geoff

Hi Geoff,

Thanks for the reply! Do let me know what the devs says regarding this issue.

Kind regards,

Ben

Hi Benjamin,

I’m unsure what happened yesterday, but I can confirm that the default manny physics asset does in fact go to sleep (as does another project I am looking at in 5.4). I’ve looked at the code path and it is as suspected the Island sleep which is controlling that behaviour.

This means that the issue you have is not the same. I’d suspect a physics asset setup. From what you said this is a default one we use with metahuman? Could you ping me across a repro project in a default version of our engine so we can investigate please?

Thanks

Geoff

Hi Geoff,

See attached for the project.

m_med_nrw_body_Physics’ is the physics asset under ‘Content\MetaHumans\Common\Male\Medium\NormalWeight\Body’

interestingly enough…the ragdoll does settle in the physics asset editor, but it would start jittering again when the mouse cursor is in the viewport, perhaps it’s caused by any slight variance in framerate?

the upload failed due to size limit, here’s the trimmed down repro project.

Thanks Benjamin,

I’ve taken a look and there is a definite setup difference between the normal manny type physics asset and the one you are using. It looks like most of the constraints have been left as default settings which won’t resemble how joints actually move, so the character just crumples on a heap. This will affect convergence a lot since there is now a large interconnected pile of bodies folded around each other - that is terrible for convergence (which is needed for an island to sleep).

I’ll raise this as an issue on a public bug tracker, and post back here. In the meantime you can improve the stability by copying across some more sensible joint settings from the default manny physics asset.

All the best

Geoff

Can I find out where you got the assets from please Benjamin?

Hi Geoff,

I’ve followed your advice and tried out the default Manny asset, and unfortunately it’s exhibiting the exact same symptoms I’ve described here:

interestingly enough…the ragdoll does settle in the physics asset editor, but it would start jittering again when the mouse cursor is in the viewport, perhaps it’s caused by any slight variance in framerate?

See attached video for what I am seeing.

I can see that in the Physics Asset editor. I’m unsure what is causing that - I’ll ask around. However does this settle in PIE since that is the important situation?

If you let it sleep (which may take a little while) then this will stop. You are correct that this is probably the dt getting a bit larger while processing the mouse events, which will affect the simulation.

Hi Geoff,

If the simulation is that sensitive to dt being different, that does reinforce the need of having the ability to specify a custom threshold to allow the physics bodies to go to sleep - presumably once the bodies are asleep the unstable frame rate will no longer be a factor unless they are manually woken up again. If memory serves correctly this did used to be supported with PhysX and is no longer the case after the transition to Chaos.

As mentioned before, it would be really nice to have this as an out of the box feature, as I assume every project attempting to integrate ragdoll into the game will run into this issue at one point.

Hi Ben,

Correct, once asleep any variations will be irrelevant. Do you recall how the PhysX handled custom thresholds? Was it at the individual level, or island level?

To increase convergence and ensure sleep happens you can clip the maximum dt allowed, enable substepping, increase iterations in the solver if you need faster convergence.

Coming back to the earlier question though - does this happen in the game, or it is purely in a tool which is editor only?

Geoff

Hi Geoff,

It does happen in game, it’s hard to tell if it’s due to unstable frame rate or not. I am checking UE4 to see what the old behaviour was.

Hi Benjamin,

I’m really struggling to see this on my end. I can get it in the editor, but not in game (although it can take upto 10 seconds in some cases). From chatting with the devs as well, and from what I’ve had in support wise, this is the first we’ve heard of this.

I was reflecting on this today, and if instability can be caused by the time changing even slightly in game, then I’d suggest you specifically alter the Physics Asset’s solver properties - this way any extra cost is localised.

[Image Removed]Initially I’d increase the Velocity solver counts from 2 to 4 and see if that fixes it.

UE4 won’t really help much in this case, this is a completely different physics engine, and they have completely different advantages and disadvantages. (As far as I can remember, Physx is a velocity based engine, we are a position based engine, so completely different in at least one major component).

All the best

Geoff

Hi Geoff,

Thank you for the reply!

here’s a similar issue that was reported, the response points to the solver being sensitive to variable framerates. [Content removed]

‘To increase convergence and ensure sleep happens you can clip the maximum dt allowed, enable substepping, increase iterations in the solver if you need faster convergence.’

can you elaborate on what exactly ‘convergence’ means? your comment seems to indicate that the ragdoll does come to a sleep eventually, is it based on some thresholds that are not exposed?

‘I can get it in the editor, but not in game (although it can take upto 10 seconds in some cases)’

The most common usage for ragdolls is probably death hit reactions, and it will look a bit silly if the dead body continues to twitch and jitter for that long.

I will try tweaking the solver iterations, and try enabling substepping and see if that helps. If ragdolls are still having trouble settling, is monitoring the speed of the bodies externally and putting them to sleep a viable option?

Kind regards,

Ben

Hi Benjamin,

Apologies - certainly. Convergence is essentially when the physics gets the correct answer. Iterations is how many ‘refinements’ it can use to get the correct answer. In this case, the constraints and collisions are ‘fighting’ each other - so they don’t agree on the direction to move the body in overall. This is a very common issue in physics. You will be seeing this as the ‘jitter’ you mention.

When the ragdoll goes to sleep in the normal case it is from the ‘island sleep’ function in the physics. This uses the current state (linear and angular velocity) and compares it to a physics material sleep value. This is actually exposed and is where I’d probably look to try first. In PhysicsMaterial.h you can see a SleepLinearVelocity, SleepAngularVelocity and SleepCounterThreshold - all of these will find their way through to that function.

[Image Removed]

If you open that material up in editor you can see the values to alter.

All the best

Geoff

Hi Geoff,

I found the source for those spheres, they seem to be constraints created by the Physical Animation Component. Which explains why you are having trouble seeing it in game for you. We have it enabled for our in-game characters, the dummy character in the in physics asset editor has it as well.

The spheres are created here:

void UPhysicalAnimationComponent::UpdatePhysicsEngineImp()I tried adding a bit of epsilon for the position test but it would simply accumulate enough errors before waking up again.

My current working theory is that the Physical Animation Component is accumulating really small errors in the kinematic target it generates, causing the constraints to never fall asleep.

That is strange about the spheres. I’ve tried your repro project and I can’t see any ragdoll effects. It seems to be playing a level sequence. If you could let me know where to find the ragdoll effect example you are using I can take a look.

I’d be wary of altering that code - essentially that just masks a problem at engine level. I’d be more curious what those spheres are (I don’t have that when I try in a local example), and why they aren’t the same as the target - what is stopping that from happening?

I’d also be curious if you start with a vanilla project, and try the physics asset for the default manny, whether you’d find the same as me - ie it sleeps as expected