## IK Solver Question

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
luckiejacky
Gnoblar
Posts: 11
Joined: Sun Nov 25, 2007 12:23 pm

### IK Solver Question

I would like to get the positional vector and orientation (Quaternion) from an animationstate at time t?
How can I do that?
Thanks
Jack
Last edited by luckiejacky on Wed Oct 15, 2014 7:46 pm, edited 1 time in total.

c6burns
Beholder
Posts: 1511
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 134

### Re: Get Positional Vector and Orientation at time t?

Code: Select all

``````myAnimState->setTimePosition(t);
myEntity->_updateAnimation()
``````

luckiejacky
Gnoblar
Posts: 11
Joined: Sun Nov 25, 2007 12:23 pm

### Re: Get Positional Vector and Orientation at time t?

It is actually yet another IK Solver question here.

I'd like to solve the IK every time step like this

Code: Select all

``````void Worker::SolveIK(Ogre::Real time) {
Ogre::Vector3 position = mLefthandChain->getPosition();
Ogre::Vector3 bonePos =  mLefthandBone->getPosition();

//position.x -= MOVEMENT_SPEED * time;
//position.y += MOVEMENT_SPEED * time;

//Update skeleton, for intermediate positions

mOTSkeleton->solve();
}
``````
And I've set the target like this

Code: Select all

``````
void Worker::SetTarget(Ogre::Vector3 target) {
mTarget = target;

// do interpolation here
}
``````
In the SolveIK function, I need to setTargetPosition for the interpolated positions rather than the target position,
so that the IK Solver can solve and update the skeleton, what interpolations functions can I use to interpolate the
left arm between the current position and the target position, and when should I apply it?
Thanks

Update:

Or should I do something like this?

Code: Select all

``````void Worker::SolveIK(Ogre::Real time) {
Ogre::Vector3 position = mLefthandChain->getPosition();
Ogre::Vector3 bonePos =  mLefthandBone->getPosition();

//position.x -= MOVEMENT_SPEED * time;
//position.y += MOVEMENT_SPEED * time;

//Update skeleton, for intermediate positions

mOTSkeleton->solve();
}

void Worker::SetTarget(Ogre::Vector3 target) {
mLefthandChain->setTargetPosition(target);

// do interpolation here
}

``````
Jack

c6burns
Beholder
Posts: 1511
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 134

### Re: Get Positional Vector and Orientation at time t?

I've actually not implemented IK in Ogre, but I have used it in other frameworks. The way I've seen the API done is in the form of a manager that takes the following parameters:
- source bone
- target affector
- blend in time
- blend out time

From there you activate or deactivate blending, and it will do a linear interpolation between the real skeleton and your affector over the amount of time you specify with blend in/blend out. So it will boil down to something like this:

Code: Select all

``````fInterpVal += Math::Clamp(frame_time * blendInOrOut, 0.0, 1.0);
vFinalPos = Math::lerp(vCurPos, vTargetPos, fInterpVal);
qFinalRot = Quaternion::Slerp(fInterpVal, qCurRot, qTargetRot);
// apply final position and rotation to the actual bone
``````

luckiejacky
Gnoblar
Posts: 11
Joined: Sun Nov 25, 2007 12:23 pm

### Re: Get Positional Vector and Orientation at time t?

c6burns wrote:

Code: Select all

``````fInterpVal += Math::Clamp(frame_time * blendInOrOut, 0.0, 1.0);
vFinalPos = Math::lerp(vCurPos, vTargetPos, fInterpVal);
qFinalRot = Quaternion::Slerp(fInterpVal, qCurRot, qTargetRot);
``````
Hello,
Thanks so much for helping!
I don't understand why we need to clamp the value to 0.0 or 1.0
because as far as interpolation is concerned, should we use a number *between* 0.0 to 1.0
Correct me if I am wrong!
Thanks
Jack

c6burns
Beholder
Posts: 1511
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 134

### Re: Get Positional Vector and Orientation at time t?

Below is Math::Clamp

Code: Select all

``````        /** Clamp a value within an inclusive range. */
template <typename T>
static T Clamp(T val, T minval, T maxval)
{
assert (minval <= maxval && "Invalid clamp range");
return std::max(std::min(val, maxval), minval);
}
``````
Clamp is just making sure we don't go above 1.0 or below 0.0 using std::max and std::min Anything in between those two values will be unaffected

You might do it differently and not need clamp, like by using an IK manager class with IK blend state classes, or however complex you want to get. I mainly just wanted to show you linear interpolation of positions using Math::lerp and spherical linear interpolation of orientations using Quaternion::Slerp

luckiejacky
Gnoblar
Posts: 11
Joined: Sun Nov 25, 2007 12:23 pm

### Re: Get Positional Vector and Orientation at time t?

Hello,
It works now.
But There seems to be working with rotations only, no translations.
So my question is now how do I ensure the end-effector reaches the target
with rotation allowed only?

So my quesitons are:
1) How can I test reachability?
2) How to interpolate the end-effector to the target with rotations only?

Thanks
Jack

c6burns
Beholder
Posts: 1511
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 134

### Re: IK Solver Question

You could test reachability by measuring the distance between the solution and the actual target.

I guess in IK you wouldn't need to alter the position of bones, just the rotations, since the limb of a skeleton is set up as a hierarchy. So altering the parent orientation will alter the position of the children appropriately. As I said I've never implemented IK, just used it in a turnkey engine ... my current ogre project only required physics ragdolls so I've left IK for another day.