Class IKSolver
See Also: Class BaseInterfaceServer, Class ZeroPlaneMap, Class LinkChain, Inverse Kinematics
class IKSolver : public BaseInterfaceServer
Description:
This class is available in release 4.0 and later only.
This class represents the base class that IK Solver plugins should derive from.
The IK solver is a pure mathematical function and does not hold state, but instead just solves a given, self-contained, mathematical problem, e.g. the plugin solver does not have influence on when IK is invoked and what an IK problem is (what is the goal and what are the joints, etc.), but contributes to IK by providing an answer on how to solve. Structurally, it is independent of the SDK and, hence, can be built independently, except for some theoretically independent math library. See the Inverse Kinematics section for more detailed information.
Methods:
public:
Prototype:
virtual ~IKSolver();
Remarks:
Destructor.
Class Identity
Prototype:
virtual SClass_ID SuperClassID();
Remarks:
Plugins derived from this class are supposed to have IK_SOLVER_CLASS_ID as their super class ID. This method should not be overridden.
Default Implementation:
{ return IK_SOLVER_CLASS_ID; }
Prototype:
virtual Class_ID ClassID() = 0;
Remarks:
Implemented by the plug-in.
Returns the class ID of the IK Solver plugin.
Prototype:
virtual void GetClassName(TSTR& s);
Remarks:
Implemented by the plug-in.
This method returns the class name of the IK Solver plugin. This name will appear in the solver list from which users can pick or assign IK chains.
Parameters:
TSTR& s
The class name string.
Default Implementation:
{ s = TSTR(_T("IKSolver")); }
Solver Traits
Prototype:
virtual bool IsInteractive() const = 0;
Remarks:
Implemented by the plug-in.
This method indicates whether the IK Solver is a controller or an interactive manipulation tool. In the former, the relationship between the goal and the joints are permanent: joints are completely controlled by the goal. In the latter, the relationship is transient, existing only during interactive manipulation. In the end, IK solutions are registered at each joint, mostly likely as key-frames, and it no longer matters how joints have got their joint angles. Only non-interactive, or controller, IK solvers are supported in R4. Note that Interactive solvers do not need an initial pose, instead it needs a current pose.
Return Value:
TRUE if the IK Solver is an interactive tool, otherwise FALSE.
Prototype:
virtual bool IsHistoryDependent() const = 0;
Remarks:
Implemented by the plug-in.
At a specific point in time, the history dependent solver will reach solutions not only based the state of the goal at the time, but also its previous states (i.e. history dependent). On the contrary, the history independent solver does its job based on the state of the goal just at the time. The procedural implication is that, when the goal is changed at time t, the IK system would have to invalidate joints at time t for the history independent solver, and at all times that are greater or equal to t for the history dependent solver. In R4, only history dependent solvers are used by the IK system.
Return Value:
TRUE if the IK Solver is history dependent, otherwise FALSE.
Prototype:
virtual bool UseSlidingJoint() const = 0;
Remarks:
Implemented by the plug-in.
This method indicates whether the IK Solver intends to use the sliding joint (translational degrees of freedom) of the IK chain.
Return Value:
TRUE if the sliding joint of the IK chain is used, otherwise FALSE.
Prototype:
virtual bool UseSwivelAngle() const = 0;
Remarks:
Implemented by the plug-in.
This method indicates whether the IK Solver intends to use the swivel angle parameter of the IK chain.
Return Value:
TRUE if the swivel angle of the IK chain is used, otherwise FALSE.
Prototype:
virtual bool DoesOneChainOnly() const = 0;
Remarks:
Implemented by the plug-in.
When two IK chains overlap, i.e., there is a joint belonging to both IK chains, some solvers are able to negotiate between the possibly contending goals and some are not. This method indicates if the IK Solver does a single chain only. For those IK Solvers that can only solve one chain at a time, the IK system will pass to the solvers one chain at a time in a definitive order. In R4, only solvers that "do one chain only" are used.
Return Value:
TRUE if the IK Solver does only one chain, otherwise FALSE.
Prototype:
virtual bool IsAnalytic() const;
Remarks:
Implemented by the plug-in.
This method determines whether the IK Solver is analytic or needs to go through iterations. Solutions of an analytic IK Solver are not dependent on position and rotation thresholds or a maximum number of iterations.
Return Value:
TRUE if the IK Solver is analytic, otherwise FALSE.
Default Implementation:
{ return false; }
Prototype:
virtual bool DoesRootJointLimits() const;
Remarks:
Implemented by the plug-in.
This method determines whether the IK Solver handles root joint limits. If the IK Solver does not do joint limits, the result will be simply clamped into joint limits by the IK system.
Return Value:
TRUE if the IK Solver does root joint limits, otherwise FALSE.
Default Implementation:
{ return false;}
Prototype:
virtual bool DoesJointLimitsButRoot () const;
Remarks:
Implemented by the plug-in.
This method determines whether the IK Solver handles joint limits. If the IK Solver does not do joint limits, the result will be simply clamped into joint limits by the IK system.
Return Value:
TRUE if the IK Solver does joint limits, otherwise FALSE.
Default Implementation:
{ return false;}
Prototype:
virtual bool SolveEERotation() const = 0;
Remarks:
Implemented by the plug-in.
This method determines whether the rotational part of the goal node will be used.
Return Value:
TRUE if the rotational part of the goal node will be used, otherwise FALSE to indicate that only the position of the goal node is taken as the IK goal while the rotation threshold will be irrelevant.
Solution Parameters
Prototype:
virtual const IKSys::ZeroPlaneMap* GetZeroPlaneMap(const Point3& a0, const Point3& n0) const;
Remarks:
Implemented by the plug-in.
IK Solvers may have their own Zero Plane Map. If so, they must override this method. The IK system will need it to perform IK snapping, which is setting the swivel angle based on the current pose so that the pose is consistent with the swivel angle. A Zero-Plane map can depend on the initial pose, which is when the joint angles take into account the respective preferred angles. In this method, a0 is to be substituted for by the end effector axis, which is a unit vector, and n0 by the solver plane normal, also a unit vector, when the chain is at the initial pose. The IK system will call this function using IIKChainControl::InitEEAxis() and IIKChainControl::InitPlane() for the two arguments.
Parameters:
const Point3& a0
The end effector axis unit vector.
const Point3& n0
The solver plane normal.
Return Value:
A pointer to the ZeroPlaneMap.
Default Implementation:
{ return NULL; }
Prototype:
virtual float GetPosThreshold() const = 0;
Remarks:
This method allows you to retrieve the position threshold.
Prototype:
virtual float SetPosThreshold(float) const = 0;
Remarks:
This method allows you to set the position threshold.
Parameters:
float
The position threshold value.
Prototype:
virtual float GetRotThreshold() const = 0;
Remarks:
This method allows you to retrieve the rotation threshold.
Prototype:
virtual float SetRotThreshold(float) const = 0;
Remarks:
This method allows you to set the rotation threshold.
Parameters:
float
The rotation threshold value.
Prototype:
virtual unsigned GetMaxIteration() const = 0;
Remarks:
This method allows you to retrieve the maximum number of iterations.
Prototype:
virtual void SetMaxIteration(unsigned) = 0;
Remarks:
This method allows you to set the maximum number of iterations.
Parameters:
unsigned
The maximum number of iterations.
Solving IK
Prototype:
virtual ReturnCondition Solve(IKSys::LinkChain&) = 0;
Remarks:
Implemented by the plug-in.
This is the method that the IK system will call when it’s the time to update the joints according to the IK goal and other parameters. The derived class should override this method if DoesOneChainOnly() returns TRUE and HistoryDependent() returns FALSE. Note that the solver is not designed to be invoked recursively. The recursion logic existing among the IK chains is taken care of by the 3ds max IK (sub-)System. The data structure passed to the Solver is transient and thus will be discarded once the solution is copied back to the joints. If the return condition indicates failure, (i.e. > 0xff) the result will not be copied back to the joint nodes in the 3ds max scene database.
Parameters:
IKSys::LinkChain&
A reference to the Link Chain.
Return Value:
The ReturnCondition bit-set with one or more of the following flags;
bLimitReached
The limit is reached.
bLimitClamped
The limit is clamped.
bMaxIterationReached
The maximum number of iterations is reached.
bGoalTooCloseToEE
The goal is too close to the end effector.
bInvalidArgument
An invalid argument is passed.
bInvalidInitialValue
An invalid initial value is passed.