I’m going to try this. Yesterday I simply locked ski from being able to yaw and was adding local rotation to them. Constraint prevents it from rotating to a full extent and only small yaw can pass it. Unfortunately this generates a force which starts to push sled sideways
its a shame physx has so many problems we have to consider using custom physics.
ray trace wheels are ok for some things but you really see its flaws when you have an open wheeled or very large radius wheels.
do you guys really use a framerate that gives frametime longer than substepping time (subtime16.67ms -> not 60fps, but cap to eg 55fps to have like a millisecond difference), low constraint projection values and max substeps 16 at 16.67ms?
I am just wondering that you have so many issues with constraints…
Another issue that made things really stable for me is to have all physics things tick from within one blueprint (or class in c++). Having forces and constraints tick in different BPs and use Blueprint communication to distribute commands somehow introduces lag or something that desynchronizes physics or adds latency to the physics or something. I ended up having like one big blueprint that contains all ticks, not several ticking BPs.
it has nothing to do with low framerate or ticking blueprints.
if, for example, the front wheels are turned so you are cornering at speed and you hit a curb or something, the constraint will ‘give way’ to the collision forces, forcing the front wheel to rotate on the local x axis (which is supposed to be locked)
if you apply extremely high forces on the constraint motor to try and counter this, the constraint becomes unstable.
for a low speed vehicle such as a rock crawler using constraints is pretty good, any faster than that and it all comes apart at the seems, quite literally sometimes.
From my experience from 4.3 when I was building airplane - as long as you apply forces to the same physics body, AddForce() and AddForceAtLocation() are not executed immediately but stacked to be executed later during physics update. I had some issue with airplane stability and tried to accumulate all forces myself, including calculating a torque manually instead of using AddForceAtLocation(), so that only single AddForce() function is called at the end. The results where exactly the same as calling AddForceAtLocation() from 8 airfoils in loop.
I’ll try enabling sub-stepping and raising iteration steps for ski. So far, removing friction added really good stability on sliding over surface, the issues come from cases when front of the ski hits an obstacle, few times they just went under the landscape and got stuck there.
I use high speeds and forces all the time, that’s why I am wondering. Forces reach into two digits orders of magnitude.
Boredengineer, if you want upload the skidoo project to have me and other people try to improve constraint stability tuning if physics are jittery. No need to worry about nicking of ideas or something. I uploaded the full physics tank project. Such things are just one, two hours work. Or strip it down to the essential jitter if you want.
Anyway, good luck with the vehicle tuning!
…just saw your reply, substepping is a must. And use landscape obj/fbx directly imported and not the UE4 landscapes. They acted funny as well when I tested everything in the beginning. Good luck!
@ TooManyfps
would it be too much to ask for you to upload an example of your setup?
it would be nice if this thread had different examples of how you can make a vehicle, not just my basic ray-trace car. that way we can feed off each others ideas and work to help everybody in the long run.
No problem at all. The aerosled is build as a part of tracked vehicles project, I didn’t commited it yesterday because you can’t really steer it
I’ll try to add steering using motor of constraint and checkout fresh version.
Btw, not very honest from my side to blame Physx when I know for the fact that mass ratio between ski and chassis is beyond 1:100
Done. Added steering using constraint angular motor targetting:
If you can’t grab it from GitHub for some reason, let me know and I’ll upload it to dropbox. This is a compiled version: Dropbox - Error - Simplify your life
Apparently when I switched to friction circle I wrote some derpy code without thinking about it and kind of broke it. Really glad that for making this Aerosled for testing purposes.
Tegleg, I’ll post separately fix for the pseudocode and explanation of what needs to be fixed.
Tegleg, to be fair your code might not be effected by this because I don’t know if what you’ve posted earlier is a full code or not. Judging from the fact that your Normal Force is just constant and not Suspension Force, it might not the full code.
So proper implementation, in my case, would look like this:
....
float MaxFrictionForce = wheelload * Mu;
FVector TempFrictionForce = (TempVel * -1)*BodyInstance->GetBodyMass();
FVector XFrictionForce = ProjectVectorOnVector(TempFrictionForce, WheelForwardVector) * MuX; //Full friction force in X axis of the wheel
FVector YFrictionForce = ProjectVectorOnVector(TempFrictionForce, WheelRightVector) * MuY; //Full friction force in Y axis of the wheel
FVector FullFrictionForce = ClampVectorSize(XFrictionForce + YFrictionForce, 0.0, MaxFrictionForce);
return FullFrictionForce;
Otherwise difference between MuX and MuY doesn’t do anything except just change magnitude of Mu but won’t change magnitude of FullFrictionForce depending on the angle. As you can rotate wheels, it’s important to use wheel’ forward/right vectors and not chassis. I use chassis in my case as tank’s wheels can’t rotate.
You’d put physics material with 0 friction to both sides of the contact (also to the ground). You need then to add the friction forces manually like BoredEngineer described for the grip itself.
I’ve actually done this few times on different constraint based prototypes (my very first BP vehicle prototype on unreal used this approach, and did later some testing on c++ as well). While I got it working fairly well on even surfaces, I never got the collision responses to act properly on uneven ground at faster speeds (100km/h+). Suspension springs and damping worked rather well using constraint components and I didn’t get any noticeable wobble on the contraints itself (which seems to be some concern here), so my issues were mostly about the rigidbody collision responses. I did use landscapes for testing at some point but I also got issues with regular meshes.
BoredEngineer, I looked at the project. It opened with error that some suspensions are missing and did not run, but I could see the constraints and settings.
Substepping is a must, and 16 steps, 16.667ms (maxing out) is even better. Disable collision on all constraints is also better for safety -> if you get forced overlap at high forces, then collision is ignored.
CCD, Multi-body overlap and always create physics state on rigid body’s collision is also good. Which one hsas most impact needs to be checked in 4.9. I am still on 4.8.
All async ticks are better off, at least in 4.8.
Max projection angle I use 2 in 4.8.
Position solver and velocity solver I use extraordinary high numbers. I think it caps it anyway at ~100/20 for both or something. Performance impact is negligible.
This here is for Unity, but has some good things in it.
Just assign physics material with zero friction to static mesh as 0lento mentioned, except you don’t have to apply it to landscape. More details below.
It’s ok to apply zero friction material only to a single side as long as you set it to choose minimal coefficient or multiplication, don’t remember which one I use. This way you can have rest of your objects behave normally on landscape and have zero friction only with wheels.
Have you tried applying spring froce in both directions - half of the force pushes on chassis and half of it on the wheel?
[QUOTE=TooManyfps;433539]
BoredEngineer, I looked at the project. It opened with error that some suspensions are missing and did not run, but I could see the constraints and settings.
Substepping is a must, and 16 steps, 16.667ms (maxing out) is even better. Disable collision on all constraints is also better for safety -> if you get forced overlap at high forces, then collision is ignored.
CCD, Multi-body overlap and always create physics state on rigid body’s collision is also good. Which one hsas most impact needs to be checked in 4.9. I am still on 4.8.
All async ticks are better off, at least in 4.8.
Max projection angle I use 2 in 4.8.
Position solver and velocity solver I use extraordinary high numbers. I think it caps it anyway at ~100/20 for both or something. Performance impact is negligible.
Sorry to hear that, I think it’s because project is ported to 4.9, so 4.8 just can’t open it properly. Thank you for the tips, I’ll try them today and check video.
Btw, do you know if “Mass scale” property of static mesh, effects mass ratio between constrained objects? My impression was that it’s exactly where it’s used, so I could keep ski to be around 25kg for example, for collisions and etc. but set mass scale to 15 for processing constraint. Do you think this would work?
That’s a good question. It would be great if it worked.
I opened the project in 4.9 on another rig when I got the error. But it was enough to see the settings. All my tuning tips are for 4.8, as I have not done physics tuning in later version yet. Probably never will after it took so long to find the tuning sweet spot in 4.8 for all my physics toys.
@BoredEngineer
i tried your tank project on 4.10, no errors, works great.
interesting idea how you do the ski’s. i wonder if there is a way to pass the calculations to the main pawn class, so it can deal with it in sub-step.
how are you with code? would it be helpful if i coded you something along these lines?
havnt tried the friction circle function yet, im trying not to get distracted too much with this and get on with other stuff.
here is my interpretation in actual code, does it look right?
FVector ATegCar::GetFullFrictionForce(float DeltaTime, FBodyInstance * BodyInstance, FVector Loc, FVector vCollisionSurfaceNormal, int32 Index)
{
//chassis velocity at wheel/ground vector
FVector TempVel = BodyInstance->GetUnrealWorldVelocityAtPoint(Loc);
FTransform BodyTransform = BodyInstance->GetUnrealWorldTransform();
FVector BodyLocation = BodyTransform.GetLocation();
//local direction of chassis
FVector BodyForwardVector = BodyTransform.GetUnitAxis(EAxis::X);
FVector BodyRightVector = BodyTransform.GetUnitAxis(EAxis::Y);
FVector BodyUpVector = BodyTransform.GetUnitAxis(EAxis::Z);
//local wheel direction vectors
FVector WheelRight = BodyRightVector.RotateAngleAxis(CurrentAngle[Index], BodyUpVector);
FVector WheelForward = BodyForwardVector.RotateAngleAxis(CurrentAngle[Index], BodyUpVector);
// Calculate Mu from friction from elipse defined by MuX and MuY as radius of elipse
float velF = FVector::DotProduct(BodyForwardVector, TempVel.GetSafeNormal());
TempVel = FVector::VectorPlaneProject(TempVel, vCollisionSurfaceNormal);
float tmpX = MuX * velF;
float tmpY = FMath::Sqrt(1.0f - (velF * velF)) * MuY;
FVector2D vec2d;
vec2d.X = tmpX;
vec2d.Y = tmpY;
float Mu = vec2d.Size();
float wheelload = 1.0f;
float MaxFrictionForce = wheelload * Mu;
FVector TempFrictionForce = (TempVel * -1)*BodyInstance->GetBodyMass();
FVector XFrictionForce = FVector::VectorPlaneProject(TempFrictionForce, WheelForward) * MuX; //Full friction force in X axis of the wheel
FVector YFrictionForce = FVector::VectorPlaneProject(TempFrictionForce, WheelRight) * MuY; //Full friction force in Y axis of the wheel
FVector FullFrictionForce = TempFrictionForce.ClampMaxSize(MaxFrictionForce);//clamp it!
return FullFrictionForce;
}
edit:
no hang on thats nonsense, other edit coming
other edit:
gosh i dont know any more lol, is it ok?
i should come back to this when i have more time