Keeping two Entities at the same position.

Discuss any questions about BEPUphysics or problems encountered.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Keeping two Entities at the same position.

Post by Jonno2343 »

Hi there
First of all, great work on the Physics engine, it is very easy to use and works fantastically.

I am developing a Virtual Reality program which uses a Head Mounted Display, Data Gloves and some 3D location / rotation trackers.
The orientation of the HMD affects the camera and then I'm wanting the Gloves (which tracks the amount your finger has bent as well as the position and orientation of the hand) to control 2 virtual hands in the application.

I have a single capsule which represents the user (entire body) and then half of your ragdoll from the demo (just the torso and arm components). I've set NoPair collision rules between the ragdoll parts and the user body so that I can move my hands inside the body capsule.
What I want to do is fix the Torso of the ragdoll to the center position of the User body. I've tried using InternalCenterPosition and setting them equal, but when I move the user, the torso and accompanying body parts lag behind.
I've tried making them Kinematic, making them way almost nothing, using BallJoints between user and torso, all to no avail.

Not moving the person, everything OK.
Image

Rotating the Person, can see rotation of Torso is not matching the rotation of Body
Image

Moving the Person backwards, can see the torso falling behind as well as the arms flailing wildly.Image

I've also tried setting the InternalPosition of the Torso during the UpdateDuringForces method which also does not work.

It seems to lag by a frame or two.

Is there someway I can do this?
Last edited by Jonno2343 on Tue Sep 11, 2012 2:31 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

Setting positions directly has the effect of 'teleporting' the involved objects. Any constraint-based physics will not work right with this, since the objects have no velocity while teleporting- their position moves only. Constraints will try to 'catch up' with separation correction, but this is a squishy, non-rigid effect that isn't designed to be main connective force.

Instead, try working on the velocity level, like the constraints. If the goal is to move an object to a location, figure out a velocity that would get the object's position to that point over some time. Set the Internal(Linear/Angular)Velocity accordingly.

There are some things in the engine that will help with this. The SingleEntityLinearMotor and SingleEntityAngularMotor take a position/orientation and attempt to reach it. Since they are constraints, they are very robust and interact with other constraints properly.

The EntityMover and EntityRotator are another set of helpers. They take any entity (dynamic or kinematic, unlike the dynamic-only motors) and move to a goal position/orientation. They are primarily used in path following processes. Internally, they use the SingleEntity motors for dynamic objects, and computed velocities for kinematics.

If you have a dynamic entity that needs to follow another entity, connecting them with a two-body constraint would probably be your best bet. The WeldJoint is a 0DOF connection which may do the job. There's many other constraints available in the Constraints namespace as well.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

Hi Norbo,
Thanks very much for that info, it was most useful.

I've now implemented the EntityMover and Rotator and the ragdoll stays together (now flailing arms) but the entire ragdoll is now, what seems to be, one step behind.
What I think is happening is, during the update I tell the MoveEntity to move it to the Person Capsule's Center Pos.
This value is then stored in the MoveEntity but, during the rest of the Game update, the person is moved by changing their velocity (similar to the way in your demos) and so the Person capsule's position also changes.
Then, when the draw method is called, the Person capsule has moved on from the position they were at when the EntiyMover's goal position was set to the Person capsule's center position.

Image

Is there any way to get around that?

Is there a reason for setting the InternalLinearVelocity in your character class as opposed to applying an impulse? Maybe my code will work if I change the way the Person capsule moves to apply an impulse?

Thanks very much
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

If the body using an EntityMover targets the current frame's position, it will indeed be a frame behind. The 'fix' is to make all expectations consistent. Right now, the camera expects the visible ragdoll body to be in the right position relative to the camera. If this were the sole goal, you could attach the camera to the ragdoll torso instead of the character controller.

Another approach is to modify the character controller such that there isn't a layer of indirection between control of the character and control of the torso. Instead of modifying only the character controller's velocity, simultaneously modify the ragdoll's velocity.

A third approach (which might be the easiest/best) is connecting the torso to the character controller body by a WeldJoint or other constraint, so the velocity of the character controller would propagate to the connected torso. They would move together, rather than the torso being one step behind.
Is there a reason for setting the InternalLinearVelocity in your character class as opposed to applying an impulse? Maybe my code will work if I change the way the Person capsule moves to apply an impulse?
Setting InternalLinearVelocity is equivalent to applying an impulse. An impulse works on momentum, which is a simple scaling factor different from linear velocity. So, if you apply an impulse that changes the velocity by X, you could equivalently just change the velocity by X.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

Norbo wrote:If the body using an EntityMover targets the current frame's position, it will indeed be a frame behind. The 'fix' is to make all expectations consistent. Right now, the camera expects the visible ragdoll body to be in the right position relative to the camera. If this were the sole goal, you could attach the camera to the ragdoll torso instead of the character controller.

Another approach is to modify the character controller such that there isn't a layer of indirection between control of the character and control of the torso. Instead of modifying only the character controller's velocity, simultaneously modify the ragdoll's velocity.

A third approach (which might be the easiest/best) is connecting the torso to the character controller body by a WeldJoint or other constraint, so the velocity of the character controller would propagate to the connected torso. They would move together, rather than the torso being one step behind.
Is there a reason for setting the InternalLinearVelocity in your character class as opposed to applying an impulse? Maybe my code will work if I change the way the Person capsule moves to apply an impulse?
Setting InternalLinearVelocity is equivalent to applying an impulse. An impulse works on momentum, which is a simple scaling factor different from linear velocity. So, if you apply an impulse that changes the velocity by X, you could equivalently just change the velocity by X.
Ok, I may try using the Torso position as the camera position instead as that should fix it all up.

Will also try setting the Torso velocity directly, didn't actually think of this for some reason :?

Tried using a Weld Joint, but now if I move forward, the ragdoll moves in front of me instead of lagging behind. I've tried making the masses the same but that doesn't stop the ragdoll moving ahead. This seems to be a complete opposite of the previous attempt, it's like it's getting the position from a frame ahead now.

Ok, I was just unsure if the ApplyImpulse did something else to the Entity.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

Tried using a Weld Joint, but now if I move forward, the ragdoll moves in front of me instead of lagging behind. I've tried making the masses the same but that doesn't stop the ragdoll moving ahead. This seems to be a complete opposite of the previous attempt, it's like it's getting the position from a frame ahead now.
The camera is probably just a frame behind, as opposed to the body behind a frame ahead. All of these problems are just from subtle order of update changes. If you find one that works (such as attaching the camera to the ragdoll and nothing else, or controlling both velocities) then just go with that instead.

The constraint approach has certain benefits (position correction in the case of opposition, robustness), though if you don't seem to need them, don't worry about it. The 'downside' to the two-body constraint approach is that it causes a physical link between the body and the torso. That might be valuable sometimes, and sometimes not.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

Ok, I've decide to leave out the Torso and just attach the Arms to the Person's capsule body.

My camera's direction is controlled by the HMD rotation sensor which reads Yaw, Pitch and Roll and so I Create the camera's lookat using those parameters as the direction.
Once that is done I use a EntityRotator's Target Orientation to a Quaternion generated using the Yaw of the camera (as body will not pitch / roll). This is obviously why the body lags behind and I'm not to sure how to fix that yet (unless I use the pitch and roll of the camera and the Yaw orientation of the body?).

The next step is to get the hands moving (which are controlled by the gloves which have a position and rotation tracker). I've tried using an EntiyMover but when I set the TargetPosition it moves the Person body with it. I definitely don't want this to happen. Do you know how I could do that? Do I need to make the hands kinematic? The position and orientation will be read directly from the sensors but I still want the hands to have collision detection so that if there is something in the way of the desired position, it will not pass through.

I want the hands to have no effect on the Person body and the hand position will be set the the Person body plus an offset plus the value read from the sensor.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

I want the hands to have no effect on the Person body and the hand position will be set the the Person body plus an offset plus the value read from the sensor.
If that's the case, then there cannot be a two-way physical link between the hands and the dynamic body. You can solve this by making the body kinematic, or controlling the position of the arms relative to the body solely through SingleEntity motors. Making the body kinematic could require some pretty significant changes to the character controller depending on how you expect it to interact with the environment, so controlling with SingleEntity motors would probably be easiest.

Using the SingleEntity motors requires care, since simply targeting the character's current position will always end up a 'frame behind' after an update (since the body has moved on). If the camera follows the physical, visible body instead of the character controller, this won't be a problem. One way to make things consistent is to consider the character controller to be your "Goal" location. It's not actually where your character is, but where it wants to be. The character controller's body prevents the 'wanted' location from ever being in an invalid location.

Another way to address this is to predict the body's next location using simple extrapolation (position + desiredVelocity * dt). This won't work perfectly, since the body may collide with something and the arms may try to go too far.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

Thanks for the quick response!
Yeah, making the body kinematic would cause big problems especially with the collision between body and the Triangle Mesh building.

The camera's position is linked to the Person's body capsule so the position will tie in with the physics entity, it's only the rotation that doesn't. Would I remove the joints between the Body and the upper arms then? Or does the Single Entity motor disregard those constraints? I would still like the joints to work so that the arm moves in a natural way.
free games online
I'll have a look at the API on it and try and implement in the morning.
Last edited by Jonno2343 on Tue Sep 11, 2012 2:41 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

Would I remove the joints between the Body and the upper arms then? Or does the Single Entity motor disregard those constraints? I would still like the joints to work so that the arm moves in a natural way.
If you don't want the capsule to be affected by constraint forces from the arms, then any physical connection between the arms and the capsule must be removed. The SingleEntity motors will keep things robustly in whatever place is specified without the two-way constraint.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

Norbo wrote:
Would I remove the joints between the Body and the upper arms then? Or does the Single Entity motor disregard those constraints? I would still like the joints to work so that the arm moves in a natural way.
If you don't want the capsule to be affected by constraint forces from the arms, then any physical connection between the arms and the capsule must be removed. The SingleEntity motors will keep things robustly in whatever place is specified without the two-way constraint.
Ok, so would I use a SingleEntity motor to keep the Upper arm in the correct place in relation to the body and one on the hand to keep the hand in the correct place according to the gloves?

I'm not looking forward to implementing fingers :)
Last edited by Jonno2343 on Tue Sep 11, 2012 2:40 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

Ok, so would I use a SingleEntity motor to keep the Upper arm in the correct place in relation to the body and one on the hand to keep the hand in the correct place according to the gloves?
That's the general idea.

If the data for fingers is purely positional, they will indeed be quite a mess :) However, if there is any extra information, you might be able to use some two-way constraints between the main glove part and the individual finger parts to help. For example, if you know the desired orientation of the glove and the desired orientation of the connected fingerbone from the data, you could use an AngularMotor that tries to maintain the orientation difference. If you just have 1DOF angle data for each joint, you could construct the orientation difference and use the AngularMotor anyway, or use some other constraint which manages 1DOF of angular freedom (like the Revolute joint types).

By the way, for future's reference, you may find yourself dealing with instability at some point depending on what kind of interaction will be going on. If it does happen, try increasing the solver iterations (currently in Space.SimulationSettings.CollisionResponse.Iterations, changing to a property on Space.Solver in v0.15.0). It defaults to 10, but highly articulated and solver-intense simulations can benefit from more sometimes. Additionally, using smaller timesteps can help a lot. Finally, the default rigidity on motors may be too strong (resulting in 'squishing' objects out of the grip). This can be addressed by going into their settings and adjusting their spring constants to something more human-handlike.
Jonno2343
Posts: 12
Joined: Fri Jan 28, 2011 12:16 pm
Contact:

Re: Keeping two Entities at the same position.

Post by Jonno2343 »

I tried implementing SingleEntity motors to get the pieces all lined up but I'm having a few problems, some of which you said I'd have.
The one issue is that if the hand is told to be at a position further away than the lenght of the hand, the entities stretch out and wriggle around. Is there anyway to stop that from happening? I would like the hand to be told where to go to but if it is further than the arm allows, it just points in that direction. legal aid
The lagging behind of the arms is now much, much worse than it ever was, like you said it would be and I'm seriously considering just having the arms have an influence on the body. Could I not make the arms very light? Or set the EntityMover max torque to something that would not rip the body along?
I don't need gravity and such things to have an effect on the arms, I just want it to have the collision detection.
Last edited by Jonno2343 on Tue Sep 11, 2012 2:39 pm, edited 1 time in total.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

The one issue is that if the hand is told to be at a position further away than the lenght of the hand, the entities stretch out and wriggle around. Is there anyway to stop that from happening? I would like the hand to be told where to go to but if it is further than the arm allows, it just points in that direction.
This occurs because there are two rigid joints fighting each other. The joints of the arm want to maintain a length, while the motor wants to pull them further. If the motor has sufficient strength, it will start winning the fight. To solve this, the motor has a variety of settings which can be configured through its Settings property. These include maximum force as well as damping/spring constants for servo-mode motors. Extremely high damping/spring constants correspond to nearly rigid constraints. Try reducing the constants or maximum force on the hand motor so that it still has enough strength to move the arm around, but doesn't win against the arm's constraints when pulling away.
The lagging behind of the arms is now much, much worse than it ever was, like you said it would be and I'm seriously considering just having the arms have an influence on the body. Could I not make the arms very light? Or set the EntityMover max torque to something that would not rip the body along?
Establishing a two-way connection between the body and the arms can be made to work. Reducing the arms' weights is one partial solution, but it will still have an effect proportional to the remaining mass (effectively slowing down the motion of the body compared to the desired velocity). However, the slowdown can be avoided if constraints are used to move the body as well. Changing the desired velocity with a constraint (in velocity mode) would propagate the velocity to the arms without slowing down the body, unlike simply setting the linear velocity.

If you go with a motor to control the body, it would be a good idea to also limit its maximum force. Make sure it has enough to move the object effectively, but not so much that it can win against collisions and shove itself through a wall.

Using a single entity constraint to control the body might not work great, depending on how your character controller needs to work. The single entity motors control all three degrees of freedom, so the character would completely define its behavior without regard for gravity or other forces (unless those other forces can overpower the constraint).

Instead, you might want to look into using something like a LinearAxisMotor. A LinearAxisMotor is a two-entity constraint that operates on only 1 linear DOF. Two-entity constraints can be constructed with one connection as null to connect them to the world frame. This means that it behaves somewhat like a one-entity constraint. It could control the driving velocity of the character, leaving the other degrees of freedom unaffected. If side-to-side motion control is needed, another horizontal perpendicular LinearAxisMotor can be used.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping two Entities at the same position.

Post by Norbo »

And of course, there's still the option of changing what is expected as I mentioned before. Following the physics body with the camera instead of the character controller and considering the character controller to be the desired location would resolve a lot of the 'delays' without having to resort to more complicated constraint systems.
Post Reply