Dexteroid CN
Dexteroid CN

Reputation: 81

Best Inverse kinematics algorithm with constraints on joint angles

I implemented the CCD algorithm for Inverse kinematics, it works great but it fails with constraints, I want to implement a system in which if the arm cannot reach the target it tries to get closer to it.

I tried to put the constraints in CCD algorithm, that is if my rotation angle goes above or below the constraint i limit it to max or min. for example, if the rotation angle is 100 degree and the constraint is 90, then I rotate 90 and based on that I calculate other angles, It works for some cases but fails for most.

CAn anyone tell me a 3D IK algorithm which takes care of constraints?

Upvotes: 1

Views: 4317

Answers (1)

cegprakash
cegprakash

Reputation: 3125

CCD itself will work like a charm. If you are working on 3D, first find the rotation you should do in each axis without applying bone limits.

After that, the approach

expectedRotation.X = min(expectedRotation.X, maxLimit.X)
expectedRotation.X = max(expectedRotation.X, minLimit.X)
expectedRotation.Y = min(expectedRotation.Y, maxLimit.Y)
expectedRotation.Y = max(expectedRotation.Y, minLimit.Y)
expectedRotation.Z = min(expectedRotation.Z, maxLimit.Z)
expectedRotation.Z = max(expectedRotation.Z, minLimit.Z)

is wrong. Because, if you can't move in one of the axis further, the other two axis will keep moving and you will get weird results.

The fix:

If any of the 3 axis mismatches with the limit constraints, you must not change the rotation at all.

First convert all the angles into degrees in -180 to 180 format. Then the following will do

vector3df angleDifference = expectedRotation - baseRotation; //baseRotation is just the initial rotation from which the bone limits are calculated.

if(angleDifference.X < boneLimits.minRotation.X || angleDifference.Y < boneLimits.minRotation.Y || angleDifference.Z < boneLimits.minRotation.Z || angleDifference.X > boneLimits.maxRotation.X || angleDifference.Y > boneLimits.maxRotation.Y || angleDifference.Z > boneLimits.maxRotation.Z)
    return currentRotation;

return expectedRotation;

Upvotes: 3

Related Questions