Servo default rotation?

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Servo default rotation?

Post by Danthekilla »

Hey norbo, when i create a revolute joint with a servo in it and tell it to go to 0 for rotation it seems to point to the center of the object it is attached to...
This is probably by design but i was wondering how i could make it just aim forward when it is at 0, so all the ones i create could aim in the same direction no matter where they are attached onto the object.

Any ideas? I thought i could get the angle between the 2 objects and then somehow get the angle relevent to the plane that the objects lay across to determine oh much to offset the servo target by but i'm really not sure...
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

That behavior is indeed by design; the RevoluteJoint SolverGroup sets up the component constraints (RevoluteAngularJoint, RevoluteMotor, RevoluteLimit, BallSocketJoint) automatically. You can use the goal angle or change the constraint bases to match what you need.

I'm not sure of the exact behavior you're looking for, but here's an example of how to set the basis such that the anchor's orientation doesn't matter:

Code: Select all

            (in the initialization)
            var boxA = new Box(new Vector3(0, -3, 0), 1, 1, 1);
            var boxB = new Box(new Vector3(0, 3, 0), 1, 1, 1, 10);

            space.add(boxA);
            space.add(boxB);

            var joint = new RevoluteJoint(boxA, boxB, (boxA.centerPosition + boxB.centerPosition) / 2, Vector3.Right);
            joint.motor.isActive = true;
            joint.motor.settings.mode = MotorMode.servomechanism;
            joint.motor.settings.servo.goal = MathHelper.PiOver2; //This bends the joint to show it reacts when the basis is modified (see next part)
            space.add(joint);

            //Make the anchor box rotate so that the orientation independence is obvious.
            boxA.internalAngularVelocity = new Vector3(0, 1, 0);

...

            (in the update method)
            //Since the orientation is changing every frame (due to the angular velocity), we have to force the joint basis to be what we want every single frame.
            //If the joint basis wasn't set each frame, it would use the previous set basis and update it using the current orientation.
            //I assume this won't be necessary in your simulation, but it helps to show the orientation independence in action.
            //This basis configuration could be moved into the initialization otherwise.

            //The motor has three involved axes: 
            //the free-rotation primary axis (1,0,0), and two axes defining the plane against which the angle is measured((0,1,0) and (0,0,1)).
            joint.motor.basis.setWorldAxes(new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1));
            //The angular joint component doesn't care about angle measurements, so we just have to set the free axis.
            joint.angularJoint.worldFreeAxisA = new Vector3(1, 0, 0);
In your situation, it may be possible just to compute an angle offset to use with your motor. There are also situations where changing the bases and other constraint configuration is needed.

A picture might help me understand the exact goal a bit better and I could provide a more targeted solution.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Servo default rotation?

Post by Danthekilla »

In this video you can see a little of our current engine and the issue I’m having.

http://www.youtube.com/watch?v=m7ek2Q7UFb0

Basically at the end you can see the issue. I attach 4 wheels to the car and they all point towards the car center.

Now i did get a hack working that fixed it in some but not all circumstances.

I Also wanted to show you some other issues we are having.
Here is a little video of a few things we are trying to accomplish (I know we are trying some very difficult things)

http://www.youtube.com/watch?v=6VopZjE3-X0

I wanted to know your ideas on a few things.
Mainly how to improve stability on these complex objects and I also wanted to know your ideas on how I could improve the handleing of these objects so that they are fully driveable.

They will obviously need some logic code behind them, and not just physics but I was wondering how best to achive that. i.e. how should I go about having the helicopter try to stay upright when it is made up of many components
Also how would I go about breaking apart compound bodys (can this be done?) I know that they can have objects removed from them so that I can handle (and creating the new object should be easy too) its more the issue of where the impact takes place and what should break… how on earth could I figure this out?

Anyway at the moment the main issues are stability and vechcile controls, I’m assumeing it took a lot of custom code to get cars to handle good (I was actually surprised that my editor built car works at all…) I need some ideas on how I can get these to work.

Our logic switch system is almost finished (mirrors little big planets but with some more features) so you can now script events and trigger things (particles, physics, lighting etc…) all using them (we actually realized that you could build a calculator if you had the time (and assuming that our game ran fast enough)

Anyway this is just an update of how we are going on our development and those questions above.

Thanks for all your help.

ps. We have added the path system into our game (about 70% done) and it works very very well amazing work norbo, we have added a visual wrapper around it so that paths and their options can be edited visually.

Pps. What is the most stable way to create a half box (diagonally split to be a trangle) and a pyramid shape for use in a compound body?
A compound body built from triangle objects? Or just a convex hull? Or something else?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

I attached a little demo of a completely 'physical' (no raycast wheels) reverse trike vehicle. It shows a way to set up wheels and constraints to act like a vehicle.

You might have been running into some of the constraint basis setup issues in that first video. Here's a couple of common cases:
-If you create constraints connecting two entities and then later try to modify the relative orientations/positions of the involved entities without notifying the constraints, they will try to return to their original configuration.
-Many constraint constructors make simple guesses to help set themselves up. In many cases the guesses are correct, but when it doesn't quite do what you want, you'll need to configure the the constraint. In the attached ReverseTrike, this issue came up with the steering RevoluteMotor. It guessed the wrong axis to measure for steering angle, so I had to complete the configuration by setting the basis directly.

Stability for driving typically comes from a combination of sufficiently low center of mass (stopping constant rollovers), wheel friction (allowing steering and preventing sliding), and well-tuned drive forces (going into a wheelie and flipping yourself every time you go forward isn't very drivable). In the attached trike, I spread the front wheelbase out, lowered the body, and further lowered the body's center of mass. The wheels are also somewhat heavy to help with this and the mass ratio problem I'll explain in a minute. I increased the softness on the drive motors to prevent extreme acceleration. There's still some instability due to being a suspensionless, ultra-fast turning trike as opposed to a 4-wheel car and not spending much time on it, but that could be addressed.

When dealing with complex contraptions, the masses of individual pieces needs to be carefully managed. If a 'realistic' mass of 1000 was used for a car body and then masses of 1-20 were used for physical wheels, chances are the entire thing would jitter and behave awkwardly. The solver doesn't like really heavy stuff relying on/sitting on really light stuff. You could increase the iteration count to help the issue some, but it will always be a less robust simulation than if masses are kept in line. With unrealistically heavy wheels, the solver has a much easier time and usually the simulation ends up looking better since the car rolls less.

For the front wheels, I also used swivel hinges instead of revolute joints. Technically, one revolute joint could connect to a shaft which then has a second revolute joint with the wheel, so that it can both steer and roll. This would require an intermediate entity and more constraints and put a bigger load on the solver (potentially also causing mass ratio issues as outlined above). The swivel hinge approach cuts out the intermediate shaft and allows two degrees of freedom directly which can then be motorized independently.
how should I go about having the helicopter try to stay upright when it is made up of many components
If it's actually a bunch of separate entities bound together with constraints, this might be a little tricky. If it were a single CompoundBody, I'd just say use something like a SingleEntityAngularMotor in servo mode. You could target upright or slightly off upright orientations to steer the helicopter. The SingleEntityAngularMotor controls all three angular degrees of freedom, so you can use it to make it yaw around as well by changing the target orientation. You could use a similar approach for the 'bunch of entities bound by constraints' by attaching the SingleEntityAngularMotor to one of the heavier centralized objects in the structure. You might have to make it stronger since it has to indirectly rotate the rest of the helicopter.

There's also the more 'realistic' approach. Helicopters are pretty tricky to get flying in a stable manner in real life. Their rotor can pitch and roll a little and there are other flight controls in place to make it go where it needs to go. You could try emulating these systems through multiple physical interactions, though the development time required for that is more suited to a helicopter simulation game :)

It might be a little easier to simulate a realistic multi-rotor helicopter. With the right configuration, the torques would cancel themselves out and you'd be left with balancing a set of thrusters basically. This wouldn't really be directly controllable by a human, but it could have an assist which throttles up and down individual thrusters to keep things level or moving in the direction the player wants.

Though, when it comes to really complicated things, particularly on the Xbox, I'm a fan of just faking it. :wink:
Also how would I go about breaking apart compound bodys (can this be done?) I know that they can have objects removed from them so that I can handle (and creating the new object should be easy too) its more the issue of where the impact takes place and what should break… how on earth could I figure this out?
You could attach collision events (initial collision detected or contact created, for example) to the compound body or its subbodies. Each time the event fires, see if the collision pair's contact list has any contacts with high forces. Each contact's penetrationConstraint's normalForce would tell you how hard the impact is. If the normal force (perhaps summed normal force over all present contacts) exceeds some breaking limit, you could remove that entity from the compound body (or shatter the compound body completely).

Breaking only gets really tricky when you want to break procedurally (i.e. splitting a single non-compound entity into 2 or more entities on the fly) or if you want to do more analysis to see what chunk of an object would be removed given some physical impact. Usually, as far as game physics go, people aren't too good at distinguishing proper breaking physics from procedural tricks, but they are unfortunately very good at recognizing 'pre-break' patterns if they show up more than once.

If breaking only none, one, or all entities in a compound body is a little too repetitive looking, you could try taking advantage of the compound body hierarchy (you can nest a CompoundBody in another CompoundBody). This results in a CompoundBody 'tree' representing your object. When an impact hits a leaf entity, you examine the contacts. If it's a weak impact, you could do nothing or maybe knock out the leaf entity. If it's a strong impact, you could knock out the parent compound body, so instead of losing the one entity, you would lose two (or more). If it's really strong, you could go even further up the hierarchy, perhaps even knocking out half of the tree and splitting the object in two. You could still keep the removed objects in their respective compound body so that when you re-add them to the space, you have two complete rigid parts of the original whole. If for a certain piece that would look weird (such as if the pieces aren't touching), you could just split them into smaller parts or individual entities when adding it back to the space.

As long as the CompoundBody tree is organized so that spatially near pieces are close in the tree representation, that approach could make the player feel like it's a 'real' breaking system.
Our logic switch system is almost finished (mirrors little big planets but with some more features) so you can now script events and trigger things (particles, physics, lighting etc…) all using them (we actually realized that you could build a calculator if you had the time (and assuming that our game ran fast enough)

Anyway this is just an update of how we are going on our development and those questions above.

Thanks for all your help.

ps. We have added the path system into our game (about 70% done) and it works very very well amazing work norbo, we have added a visual wrapper around it so that paths and their options can be edited visually.
Great! The Blast videos are looking really nice. Things are coming along :)
Pps. What is the most stable way to create a half box (diagonally split to be a trangle) and a pyramid shape for use in a compound body?
A compound body built from triangle objects? Or just a convex hull? Or something else?
I would recommend a ConvexHull.
Attachments
ReverseTrike.zip
(3.17 KiB) Downloaded 232 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

By the way, when using fairly heavy wheels, you may notice some slightly odd effects when they start spinning very fast. Not necessarily physically incorrect, but a little strange- they act like gyroscopes :) Due to the very large angular momentum, they like to keep an orientation, which is noticeable in steering.

You can refine the behavior by improving angular integration. This can stabilize some simulations, too, at a small performance cost.

Code: Select all

            space.simulationSettings.motionUpdate.useRK4AngularIntegration = true;
            space.simulationSettings.motionUpdate.conserveAngularMomentum = true;
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Servo default rotation?

Post by Danthekilla »

I will try do all that tommorrow.

They all sound like brilliant ideas, and yer i agree with faking the controlling of the vehcials i was just thought i would use some joints and manual forces to do it so it still reacts fine in the physics system.

so what exactly does this do?
space.simulationSettings.motionUpdate.useRK4AngularIntegration = true;
space.simulationSettings.motionUpdate.conserveAngularMomentum = true;

Just lets the engine calculate some rotational forces that it useally doesnt need to bother with?

Are there any other tweaks like that, that could help with stability? Ive turned on CCD for linear motion.

Also something i wanted to ask
The engine has box vs box and box vs sphere right?
Does this make the engine more stable (accurate) at calculating boxes vs static boxes than boxes hitting a statictrimesh?
Are there any box/sphere vs statictrimesh optimizations or does it use a general case solver for these?

Also at some point you menchined about implimenting a new crash system so that NAN errors and the like could be caught early. Is this far away? It could help narrow down some bugs.
Sometimes complex objects or joint systems will just make the engine throw this error when the joints are moveing fast though the world "about 0.2 units of space per frame" i assume its errors in the wheel joints when the object they are attached too moves away from the wheels too fast for it to accurately respond and it loses accuracy somehow?

And as i said i will look at the demo you sent me over the next few days.
Thanks so much for the help you have provided.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Servo default rotation?

Post by Danthekilla »

Oh and i was just wondering how .14 is going with the new threading system.

Also have you ever used resharper? its a amazing program that i use.
It intergrates into visual studio and can .netinize your entire solution in minutes automaticly and also provides underlineing support for variables and functions that don't meet the specifcation.
Also it has a much better and smarter version of intellisense that is optional but great.
You can configure it to refactor your code to match any type of spesification and even tell it to re-arange functions alphabetticly or by frequency used and much more.

Anyway i just thought i would let you know.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

so what exactly does this do?
space.simulationSettings.motionUpdate.useRK4AngularIntegration = true;
space.simulationSettings.motionUpdate.conserveAngularMomentum = true;

Just lets the engine calculate some rotational forces that it useally doesnt need to bother with?
The engine doesn't conserve angular momentum by default. When an impulse is applied, it incrementally changes the velocity directly rather than changing the momentum and then calculating the velocity. The two are equivalent when it comes to linear velocity, but angular velocity can change even when angular momentum is constant when angular momentum is conserved.

Conserving angular momentum is a more physically correct approach, but tends to make things harder on the default symplectic Euler integrator. Objects with high angular velocities can undergo odd orientation drift sometimes. RK4 angular integration is more expensive but handles conservation of angular momentum better.
Are there any other tweaks like that, that could help with stability? Ive turned on CCD for linear motion.
The major ones are increasing the solver iteration count (space.simulationSettings.collisionResponse.iterations) or increasing the number of timesteps taken per second. Those options can have a pretty serious impact on performance, though.

CCD can sometimes improve stability (if you're noticing objects going through the ground due to high speeds), but it can actually introduce little jerks that make complicated simulations less stable than the discrete version. This is because CCD is an approximation; it determines the first time of impact and doesn't let the object move farther than that. In effect, the entity loses part of its timestep. If a constraint expects an object to follow a certain trajectory based on its velocity but it ends up moving one fifth of that, the positions will drift apart and require more correction.

The collision system rewrite is going to open the door for some quicker, better CCD options.
The engine has box vs box and box vs sphere right?
Yes.
Does this make the engine more stable (accurate) at calculating boxes vs static boxes than boxes hitting a statictrimesh?
Yes.
Are there any box/sphere vs statictrimesh optimizations or does it use a general case solver for these?
Box-triangle is general case currently. Sphere-triangle has a special case.
Also at some point you menchined about implimenting a new crash system so that NAN errors and the like could be caught early. Is this far away? It could help narrow down some bugs.
I haven't decided the best way to handle this yet. It's not really practical to do the most robust option (always verify inputs and outputs locally), and once it leaves the 'triggering' method, tracking it down is going to be a pain in general whether it's caught by the getExtremePoints function or some other special 'NaN catcher' one.
Sometimes complex objects or joint systems will just make the engine throw this error when the joints are moveing fast though the world "about 0.2 units of space per frame" i assume its errors in the wheel joints when the object they are attached too moves away from the wheels too fast for it to accurately respond and it loses accuracy somehow?
Constraints and collisions shouldn't ever cause NaN errors provided that they have a good configuration. Collision pairs might sometimes be trouble if the involved geometry is extremely over- or under-scaled due to the creation of NaN contact positions or normals. Sometimes the constraint constructor guesses will guess incorrectly about your desired configuration, leading to bad bases and in turn NaN's. Bad basis guesses usually cause crashes as soon as they are updated, though.

I've stretched and pulled constraints across huge distances (actually 11,000 units to be precise) without problems. They generally corrected their positions from such an extreme state within a second or two. If you are seeing a NaN from constraints with 'good' configuration, there might be a bug in some specific constraint too (like an unprotected Vector3.Normalize) which would require further investigation.
Oh and i was just wondering how .14 is going with the new threading system.
I finished the rewrite, though I didn't see the performance gains I was looking for. The PC got a little bit faster depending on the simulation (0-20%). It balances loads efficiently on the PC, so it will play better with other programs eating up the CPU at the same time. The Xbox360 was more disappointing; the same system that gave the PC the 0-20% boost actually slowed down the Xbox360 by 0-20%. I fell back to using an improved version of the original threadpool on the Xbox360, giving a tiny boost.

One nice side effect of the rewrite is that it's very easy to write and incorporate new thread managers. People could write them externally if they really wanted. This will be leveraged in the XNA 4.0 version of v0.14.0 to use .NET 4.0's new threading magic for a significant performance boost on the PC.

The resource pool has also been rewritten to behave better with threading, too. It avoids ever using a heavy lock. The new system is also cleaner and allows the user to specify custom initialization logic through a delegate.
Also have you ever used resharper? its a amazing program that i use.
I've heard of it (and many, many good things about it), though I don't personally use it. Unfortunately I can't rely on its refactoring capabilities to do the .NETization since the process will change a few thousand symbols, and I wouldn't want people using BEPUphysics without fancy tools to be crushed with the burden of dealing with that :)
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Servo default rotation?

Post by Danthekilla »

Thanks for the great reply, we are currently using

space = new Space();
space.simulationSettings.motionUpdate.gravity = new Vector3(0, -20f, 0);
space.simulationSettings.collisionResponse.iterations = 10;
space.simulationSettings.timeStep.timeStepDuration = 1 / 50f;
space.simulationSettings.collisionDetection.collisionDetectionType = CollisionDetectionType.fullyContinuous;
space.simulationSettings.collisionDetection.useContinuousDetectionAgainstMovingKinematics = false;
space.simulationSettings.motionUpdate.useRK4AngularIntegration = true;
space.simulationSettings.motionUpdate.conserveAngularMomentum = true;
space.useMultithreadedUpdate = true;

for our settings now, we are noticing that a car for instance may jiggle around a bit even when it isn't moving, would a higher iteration count help that or could that be because of the CCD? Is there anyway to turn the ccd on for just a few objects?
I haven't decided the best way to handle this yet. It's not really practical to do the most robust option (always verify inputs and outputs locally), and once it leaves the 'triggering' method, tracking it down is going to be a pain in general whether it's caught by the getExtremePoints function or some other special 'NaN catcher' one.
Would it be possible to have some additional nan catchers thoughout the engine using a special define? Like when ROBUST_NAN_ON is defined it could verify some additional propertys?
I know that this would normally slow down the simulator but this way we could turn it on and hopefully catch an exception a little earlyer and get a better idea of why it is happening.

But then again it would be more work for you and it is probably not worth it.

I finished the rewrite, though I didn't see the performance gains I was looking for. The PC got a little bit faster depending on the simulation (0-20%). It balances loads efficiently on the PC, so it will play better with other programs eating up the CPU at the same time. The Xbox360 was more disappointing; the same system that gave the PC the 0-20% boost actually slowed down the Xbox360 by 0-20%. I fell back to using an improved version of the original threadpool on the Xbox360, giving a tiny boost.
That sucks about the 360 performance, i assume that the tiny boost on 360 isn't at a noticeable level?

Good job on making the engines threading cleaner and easier to work with.
It sucks that the 360 doesn't get the new threading support from .net 4.0

Anyway keep up the amazing work :)
And thanks for taking the time to give me such awesome answers to my questions.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

for our settings now, we are noticing that a car for instance may jiggle around a bit even when it isn't moving, would a higher iteration count help that or could that be because of the CCD? Is there anyway to turn the ccd on for just a few objects?
The jiggling may be because of the mass ratio/complex structure issues I outlined earlier. If that's the case, increasing iterations could help, though addressing the mass ratios or simplifying the structure would be a more direct fix. CCD shouldn't cause stationary jiggling, and there's no way to currently disable/enable it for specific entities (though that is on the todo list for the rewrite).

It may also be a case of fighting constraints. If two rigid constraints like a collision pair and ball socket joint have an unresolvable argument, it can introduce energy/jiggles to the simulation. The best way to stop this is to make sure that the fighting constraints can resolve the argument (by moving out of penetration, for example). Setting collision rules between certain entities to stop superfluous collision pairs can also help with performance and stability.
Would it be possible to have some additional nan catchers thoughout the engine using a special define? Like when ROBUST_NAN_ON is defined it could verify some additional propertys?
As a compromise of sorts, I think I'll be piggybacking on some of the architectural revisions coming up that split the update process into clear and visible modules. Between each module, the space will gain an event, letting you specify arbitrary logic to execute in-line. A delegate could be added to each phase for debugging purposes that analyzes every entity in the space and their NaN-prone properties (primarily velocity). That way, the precise stage at which the error occurs, along with what entity is involved, can be identified.

Something similar to this can be done in the current version using Updateables, but they only offer 4 different stages (forces, before collision detection, on update, on frame update). Having an event right after the solver runs would be particularly valuable.
That sucks about the 360 performance, i assume that the tiny boost on 360 isn't at a noticeable level?
I haven't done quite as extensive testing on the Xbox as the PC, but any Xbox performance improvement seems to have been mostly hidden in the ambient performance 'noise.'
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

I did some more Xbox360 performance testing. I can't really identify a noticeable improvement from the old "SimpleThreadManager" and the new "ThreadTaskManager," but there is a performance difference between the ThreadTaskManager and the SpecializedThreadManager.

After tuning the system, it appears the major difference is in consistency. ThreadTaskManager/SimpleThreadManager have a fairly large performance range on a constant simulation, while the SpecializedThreadManager has a narrower range somewhere inside the ThreadTaskManager's. So it seems to have a lower maximum speed, but also sometimes a higher minimum speed. I'm going to leave the Xbox360 with using ThreadTaskManager for now since it's similar to how it worked before, but switching the system used is trivial (space.threadManager = new SpecializedThreadManager()).
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Servo default rotation?

Post by Norbo »

I also just completed a little XNA 4.0 TPL testing. Once again, I'm a little disappointed and surprised at the results. Despite previous simulated workloads showing a substantial improvement (20%+) when using the TPL, it actually performs marginally worse than the new SpecializedThreadManager in some BEPUphysics tests.

The experimental ThreadManagerTPL will be included in the XNA 4.0 version anyway, though the SpecializedThreadManager will continue to be the default option on the PC. I'll probably return to research this more later, but other lower hanging fruits have priority right now :)
Post Reply