Hey all! After having such great success with the fixed orientation joint from Barenbrug's thesis, I decided to implement the hinge constraint from the thesis. I'm going to give a little background for those not familiar with the derivation and give a break down of what the jacobian looks like. My current implemention is wrong and I'm wondering if anyone could check my jacobian for me.
Instead of a single anchor point plus a line he suggests using 2 anchor points: P1 and P2.
Let:
P1A,P2A,P1B,P2B are the current P1 and P2's transformed by the bodies A and B.
L = P1A-P2A
T1,T2 = orthogonal basis of L.
RP1 = P1A - P1B
RP2 = P2A - P2B
C[0] = T1 . RP1
C[1] = T2 . RP1
C[2] = L . RP1
C[3] = T1 . RP2
C[4] = T2 . RP2
dC[0]/dt = T1 . (vA + wA x P1A_local - vB - wB x P1B_local)
etc..
First row of J looks like:
T1.x
T1.y
T1.z
T1.z * P1A.y - T1.y * P1A.z
T1.x * P1A.z - T1.z * P1A.x
T1.y * P1A.x - T1.x * P1A.y
-T1.x
-T1.y
-T1.z
-T1.z * P1A.y + T1.y * P1A.z
-T1.x * P1A.z + T1.z * P1A.x
-T1.y * P1A.x + T1.x * P1A.y
The rest of the rows follow the same pattern.
Has anyone gone down this road?
Barenbrug Hinge
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA
-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA
Okay, I went with your suggestion. I'm having problems with the simulation blowing up if I include stabilization terms for the angular error.
Scenario:
Box is hinged to a fixed box.
I drop a box onto the free box as a way of introducing some error into the
joint. If C4, and C5 are zero the joint continues to work fine, but if I set C4 and C5 to what I have below, the box starts "randomly" spinning around the hinge joint. Is there something wrong with my derivation below?
C:
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB, wB = uB.orthogonal_basis ()
C1-3 = Ball-Socket C
C4 = uA * vB
C5 = uA * wB
Jacoabian:
J1-3 = Ball-Socket J
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB, wB = uB.orthogonal_basis ()
T1 = uA.cross(vB)
T2 = uA.cross(wB)
J4 = [0 | T1 | 0 | -T1 ]
J5 = [0 | T2 | 0 | -T2 ]
Scenario:
Box is hinged to a fixed box.
I drop a box onto the free box as a way of introducing some error into the
joint. If C4, and C5 are zero the joint continues to work fine, but if I set C4 and C5 to what I have below, the box starts "randomly" spinning around the hinge joint. Is there something wrong with my derivation below?
C:
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB, wB = uB.orthogonal_basis ()
C1-3 = Ball-Socket C
C4 = uA * vB
C5 = uA * wB
Jacoabian:
J1-3 = Ball-Socket J
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB, wB = uB.orthogonal_basis ()
T1 = uA.cross(vB)
T2 = uA.cross(wB)
J4 = [0 | T1 | 0 | -T1 ]
J5 = [0 | T2 | 0 | -T2 ]
-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
If I understand you correctly you build the orthogonal axes every frame from uB. I do the following:
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB = bodyB->get_rotation_matrix() * tanget1_local_B
wB = bodyB->get_rotation_matrix() * tanget2_local_B
So you need to create the orthogonal space from the global hinge axis when you construct the joint and save it in the local frames as you do for the hinge axis itself. If you want to save memory the wB axes could be constructed per frame like this (though I would verify this for some time using an assertion just to be sure):
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB = bodyB->get_rotation_matrix() * tanget1_local_B
wB = Cross( uB, vB );
Note that it shouldn't actually make any difference since you don't need uB.
Cheers,
-Dirk
uA = bodyA->get_rotation_matrix() * hinge_axis_local_A
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB = bodyB->get_rotation_matrix() * tanget1_local_B
wB = bodyB->get_rotation_matrix() * tanget2_local_B
So you need to create the orthogonal space from the global hinge axis when you construct the joint and save it in the local frames as you do for the hinge axis itself. If you want to save memory the wB axes could be constructed per frame like this (though I would verify this for some time using an assertion just to be sure):
uB = bodyB->get_rotation_matrix() * hinge_axis_local_B
vB = bodyB->get_rotation_matrix() * tanget1_local_B
wB = Cross( uB, vB );
Note that it shouldn't actually make any difference since you don't need uB.
Cheers,
-Dirk
-
- Posts: 133
- Joined: Wed Jul 27, 2005 1:05 pm
- Location: Berkeley, CA