Inverse Kinematics Spider (Inherited Rotation Problems)

Started by
1 comment, last by SFA 19 years, 11 months ago
Hi there everybody. I'm currently implementing an insect simulation, the current stage being the visualisation of the insects' movement. I didn't particularly fancy modeling and animating many insects in 3DS and then importing all the models and setting up the animation and stuff, plus I can't really justify spending so much time on 'art' when I'm supposed to be doing Ph.D research! Anyway, so I've decided to physically model the insect legs using Inverse Kinematics. My 'test' insect is a Spider, due to the fact that I am terrified of them, and therefore I would know when I was on the right track because the movement would stir something deep within me. And its starting to do it... Anyway, progress has been good. I've coded everything from scratch, taking most of my Inverse Kinematics theory from Hugo Elias' page on IK. Aaaaaaarrrghhhhh!!! Where's the Phial of Galadriel when you need it, eh?
But I've run into a problem... My Inverse Kinematics spider is setup to have 8 legs, with 6 'bones' in each leg. At the end of each joint (except for the last one) there is a joint - represented by a single 'angle vector' - i.e a vector containing the current angle of rotation around each of the 3 axis. Each bone is connected to the end point of the last one (at the position of the 'joint'). By providing each bone on initialization with a length, an angle of rotation and its maximum and minimum rotation I am able to construct a 'limb'. Each frame, (as described in Hugo Elias' page), a small angle is calculated and added to each joint, so that by the following frame, the tip of the limb is closer to the target. Now a spider leg is made up of 6 bones (in my slightly simplified model). The first bone (i.e the one that connects the leg to the body) rotates around two axis (lets call them x and z), whilst all the other bones only rotate around the x axis (i.e they are hinges, like your knee. The 1st joint can therefore be called a 'ball and socket' joint, as it moves both forward and backwards and up and down. Now in my IK implementation, each joint is only capable of rotating around a single axis. To create a 'ball and socket joint' (i.e the first joint), I simply create two bones of length 1 (tiny), which rotate around the two axis I need (x and z). This works, up to a point. If you look at the images below, you can see the problem.
Straight leg
The image above left shows a single limb which is STRAIGHT. The first joint is on the right, and is slightly elivated (as a spider's body is always off the ground). The leg tip is on the left, and is currently touching the BLUE target. On the right we see the same limb from the top, and its STRAIGHT. Because the target and first joint (where the ball and socket is located) are in a straight line.
Crooked leg
The image above shows the same leg, only the target has moved backward - the ball and socket joint (i.e one x and one z axis joint) allows for the spider to move its legs forward and backwards. Now the tip of the leg reaches the target correctly, the problem is (as you can see in the top down view), that the leg is CROOKED. A screenshot of a full spider with 8 legs shows why this is a major problem :
Top view of Spider
Above is a screenshot of a spider in movement. The legs at the side are ok, because their angle of rotation along the z axis (backwards and forwards) are pretty small. The legs at the back, and more so the legs at the front, have a much larger angle of rotation, and as you can see the legs aren't straight as they should be. Now the way I've implemented the IK is that when an angle is added to a hinge joint (i.e 5/6 of the bones), that angle only rotates the bone it's attached to (its a local rotation). I.e the joints that move the bones up and down to lift the leg off the ground only affect that perticular bone. HOWEVER, when an angle is added to the joint which rotates the leg forwards and backwards (i.e ONE joint in the limb), the angle is ALSO added to all other child joints (in this case, all the other joints).


//Loop through joints (clue = they are at Bone.startPoint)
//Calculate the amount to rotate the joint for the next frame 


	for(int p = numberOfBones-1; p >= 0; p--)
		{
		CVector3 rot = CalculateJointRotationAmount(test_bone[p].GetEndPoint(), 
												    test_bone[p].GetStartPoint(),
												    test_bone[p].GetAxisOfRotation(),
												    test_bone[p].GetFlexSpeed() 
													);


		//If current joint has an influencial rotation axis
		if(test_bone[p].GetAxisOfRotation() == "z-axis")
	
			//Loop through all child joints		
			for(int q = p+1; q < numberOfBones; q++)
				{
				//add influencial rotation
				test_bone[q].IncrementAngle(rot, 
											test_bone[p].GetAxisOfRotation(), 
											test_bone[p].GetMaxAngle(), 
											test_bone[p].GetMinAngle()
											);
				}


		//Apply joint rotation to current bone 
		test_bone[p].IncrementAngle(rot, 
									test_bone[p].GetAxisOfRotation(), 
									test_bone[p].GetMaxAngle(), 
									test_bone[p].GetMinAngle()
									);



		}
            
Above is the source code for the part which increments the angle of each joint, each frame. As you can see, when the joint which rotates around the z-axis' angle is imcremented, all the child (x-axis) joints are also rotated around the z-axis by that amount. I'm just wondering wether any of you can spot a flaw in my logic here. Is adding the same z-axis rotation to each x-axis joint the correct thing to do? Spider Test If you are interested in having a look at my spider walking, feel free to download this (95k) demo : Inverse Kinematics Spider Demo The spider walks through the wall, plus there are a few bugs in it (no pun intended ), including the little 'slip' each leg does before moving forward, plus that some of the joints detach slightly at times, but hey, I only started this 2 weeks ago! If you look from the front or from the top, you can clearly see the problem I have. The legs should be STRAIGHT! Not bent like some Gorilla-Spider! Anyway, I would be Very grateful for any help you can give me! Cheers, SFA. llyrapcenydd@yahoo.co.uk [edited by - SFA on May 7, 2004 12:04:41 PM]
http://www.voodoo-magic.co.uk
Advertisement
I suspect part of the problem is conceptually the spider joints are constrained in the leg itself must be straight, but there is no such explicit constraint in the simulation.

Currently you have a single min/max angle around its directional vector to model the constraint. Thus it is legal for the leg to look ''wrong''.

The simplest way is to add more information on how each joint can move. Ie you want a greater range of movement on 2 axis for 3 joints on the leg, and the current setup for the joint between the body & the leg.
Thanks for the reply. That hadn''t occured to me!

The way it works at the moment is as follows :

All the hinge joints (i.e 5/6 of the leg) angles of rotation are constrained between their minimum and maximum.

When the ball and socket joint (the one that connects the leg to the body) moves forward and backwards, the angle it rotates by is also passed to the hinge joints angle of rotation around that axis.

The crucial bit where problems could arise is that this ''inherited'' angle of rotation is constrained along the parent''s maximum and minimum.

Could this be the reason I get these problems?

I''m also wondering something else that might be wrong in my current design :

When the leg is rotated forward and backward (i.e the ball and socket joint rotates the child bones), I simply add this same angle to all the child joints along the same axis. Is this the correct way to do it? i.e if I have a straight line of bones connected by joints and I rotate all of them by the same angle, would they still be in a straight line?

Thanks for the help!
SFA.


http://www.voodoo-magic.co.uk

This topic is closed to new replies.

Advertisement