Joints creating weirdly offset positions

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Joints creating weirdly offset positions

Post by mcmonkey »

So I have a big object.
This object has, connected to it, several smaller objects.

The small objects are set to not collide with the big object.

Connecting the big object to the small objects is a few joints to control motion, and one key connector joint: The PointOnLineJoint.

It's constructed with:

(BigObject, SmallObject, small.Position, (0, 0, -1), small.Position)

so the small object's position is used for both reference points, the axis is 'straight down' the z axis, (relative to big object's orientation).

At time of construction of all this, both object's orientation's are an Identity quaternion.

I have the oddest problem here:

When the big object rotates, the small objects follow the rotation imperfectly: if the object angles its front end upwards along the Z axis (pitching up), the wheels will move extra far forward and up.
If the object angles downward along the Z axis (pitching down), the wheels move backwards (and thus upwards again)

Rotating /around/ the Z axis (yawing), they'll be offset to the side.

Rotating around the Y axis (Rolling), they'll again offset in whichever direction makes them the most upward.

They offset as much as 1 unit out of place, possibly 2 (eyeballing it).

They have a LinearAxisLimit that should restrict them from moving between 0 and 0.1 units on that axis,
and a servomotor LinearAxisMotor trying to push them 1 unit down that axis (possible issue with that being stronger than it needs to (1 unit down vs. 0.1 units down), but it /should/ be fine)

There are some other joints, but they have been move about in the past with no visible changes, so I'm going to guess those are irrelevant.

I'm at least halfway sure it's somewhere in the physics setup I have going, as opposed to the network or rendering logic being offput.
(Though, admittedly, not entirely. This setup is getting a bit complex and full of code I haven't looked at in long periods of time...)

So... my question is, do you have any ideas why this offset might be occurring?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Joints creating weirdly offset positions

Post by Norbo »

Can't say for sure; I would recommend trying to reproduce it in the demos. It sounds like you want something similar to this, which works as expected:

Code: Select all

            var body = new Box(new Vector3(10, 10, 10), 4, 1, 1, 10);
            var wheel1 = new Cylinder(body.Position - new Vector3(-2, 0, -0.25f), 1, 0.5f, 5);
            var wheel2 = new Cylinder(body.Position - new Vector3(2, 0, -0.25f), 1, 0.5f, 5);
            CollisionRules.AddRule(body, wheel1, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(body, wheel2, CollisionRule.NoBroadPhase);

            var line1 = new PointOnLineJoint(body, wheel1, wheel1.Position, new Vector3(0, 0, -1), wheel1.Position);
            var line2 = new PointOnLineJoint(body, wheel2, wheel2.Position, new Vector3(0, 0, -1), wheel2.Position);
            var linearAxisLimit1 = new LinearAxisLimit(body, wheel1, wheel1.Position, wheel1.Position, new Vector3(0, 0, -1), -0.5f, 0);
            var linearAxisLimit2 = new LinearAxisLimit(body, wheel2, wheel2.Position, wheel2.Position, new Vector3(0, 0, -1), -0.5f, 0);
            var linearAxisMotor1 = new LinearAxisMotor(body, wheel1, wheel1.Position, wheel1.Position, new Vector3(0, 0, -1));
            var linearAxisMotor2 = new LinearAxisMotor(body, wheel2, wheel2.Position, wheel2.Position, new Vector3(0, 0, -1));
            var revolute1 = new RevoluteAngularJoint(body, wheel1, new Vector3(0, 1, 0));
            var revolute2 = new RevoluteAngularJoint(body, wheel2, new Vector3(0, 1, 0));
            linearAxisMotor1.Settings.Mode = MotorMode.Servomechanism;
            linearAxisMotor2.Settings.Mode = MotorMode.Servomechanism;
            linearAxisMotor1.Settings.Servo.Goal = -0.5f;
            linearAxisMotor2.Settings.Servo.Goal = -0.5f;
            linearAxisMotor1.Settings.Servo.SpringSettings.Damping /= 1000;
            linearAxisMotor2.Settings.Servo.SpringSettings.Damping /= 1000;
            linearAxisMotor1.Settings.Servo.SpringSettings.Stiffness /= 1000;
            linearAxisMotor2.Settings.Servo.SpringSettings.Stiffness /= 1000;
            Space.Add(body);
            Space.Add(wheel1);
            Space.Add(wheel2);
            Space.Add(line1);
            Space.Add(line2);
            Space.Add(linearAxisLimit1);
            Space.Add(linearAxisLimit2);
            Space.Add(linearAxisMotor1);
            Space.Add(linearAxisMotor2);
            Space.Add(revolute1);
            Space.Add(revolute2);
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Re: Joints creating weirdly offset positions

Post by mcmonkey »

So I tried to reproduce it in the demos, but the demos ran it fine without the issue.

And I thought to myself, what's the difference between the demos and my code?

and after thinking a bit, realization struck:

I was trusting my own older code to work in a situation that hadn't actually been 100% tested previously...

Naturally, I was rendering the model rotated around the wrong center point, thanks to the recentering logic BEPU automatically applies.

(Matrices were multiplied in the wrong order: I had scale * orientation * offset * position, I needed to have scale * offset * orientation * position!)

Upon fixing this, the wheels now appear to be placed correctly...
Or, more accurately, the plane now is rotated relative to the wheels correctly, heh.

I never noticed this issue before because I had never had static-jointed objects attached to a rotating object, I only had non-static joints and non-jointed rotating object.
Funny how long a trivial issue like this can hide... I've had this code for I think two years almost now.
Post Reply