Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

IKThreeLink.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_IKThreeLink_h_
00003 #define INCLUDED_IKThreeLink_h_
00004 
00005 #include "IKSolver.h"
00006 
00007 //! Performs analytical solution for position control of a variety of three or fewer link configurations
00008 /*! Link configurations must conform to one of these patterns (R=revolute joint, P=prismatic joint):
00009  *  - R
00010  *  - P
00011  *  - R₁R₂, where R₁ and R₂ are either parallel or orthogonal
00012  *  - RP, where R and P are orthogonal
00013  *  - R₁R₂R₃, where R₁ and R₂ are orthogonal, and R₂ and R₃ are either orthogonal (Aibo leg) or parallel (Chiara leg)
00014  *  - R₁R₂P, where R₁ and R₂ are orthogonal, P is orthogonal to R₂, and P intersects R₁ (Pan/Tilt camera)
00015  *
00016  *  Orientation solutions are not supported (yet?)
00017  *  Solutions will degrade gracefully when out of reach, either effector range or joint limit, and should return
00018  *  the closest possible solution.
00019  */
00020 class IKThreeLink : public IKSolver {
00021 public:
00022   //! constructor
00023   IKThreeLink() : IKSolver(), invertThird(false), hasInverseSolution(false), inverseKnee() {}
00024   
00025   virtual bool solve(const Point& pEff, const Rotation& oriEff, KinematicJoint& j, const Position& pTgt, float posPri, const Orientation& oriTgt, float oriPri) const;
00026   using IKSolver::solve;
00027   
00028   virtual IKSolver::StepResult_t step(const Point& pEff, const Rotation& oriEff, KinematicJoint& j, const Position& pTgt, float pDist, float posPri, const Orientation& oriTgt, float oriDist, float oriPri) const;
00029   using IKSolver::step;
00030   
00031 protected:
00032   //! roundoff for numerical error (probably should split this for angular vs. linear values)
00033   static const float EPSILON;
00034   //! searches @a eff parents to assign @a remain mobile joints into @a links
00035   static unsigned int setLinks(KinematicJoint& eff, KinematicJoint* links[], unsigned int remain);
00036   
00037   //! forwards to either computeFirstLinkRevolute() or computeFirstLinkPrismatic() based on @a curlink
00038   void computeFirstLink(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool& valid) const {
00039     if(curlink.jointType==KinematicJoint::PRISMATIC) {
00040       computeFirstLinkPrismatic(curlink,Pobj,endlink,Plink,valid);
00041     } else {
00042       computeFirstLinkRevolute(curlink,Pobj,endlink,Plink,valid);
00043     }
00044   }
00045   //! sets the angle of curlink based directly on the projected angle of the objective minus the projected angle of the effector point (Plink)
00046   void computeFirstLinkRevolute(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool& valid) const;
00047   //! sets the angle of curlink based directly on the projected angle of the objective minus the projected angle of the effector point (Plink)
00048   void computeFirstLinkPrismatic(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool& valid) const;
00049   
00050   //! forwards to either computeSecondLinkRevolute() or computeSecondLinkPrismatic() based on @a curlink
00051   void computeSecondLink(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const {
00052     if(curlink.jointType==KinematicJoint::PRISMATIC) {
00053       computeSecondLinkPrismatic(curlink,Pobj,endlink,Plink,invert,valid);
00054     } else {
00055       computeSecondLinkRevolute(curlink,Pobj,endlink,Plink,invert,valid);
00056     }
00057   }
00058   //! sets the angle of curlink based on the elevation of the objective point vs effector point, projecting about parent link's z axis (which will be set from computeFirstLink())
00059   void computeSecondLinkRevolute(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const;
00060   //! sets the length of curlink based on the distance of the objective point, projecting about parent link's z axis (which will be set from computeFirstLink())
00061   void computeSecondLinkPrismatic(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const;
00062   
00063   //! forwards to either computeThirdLinkRevolute() or computeThirdLinkPrismatic() based on @a curlink
00064   void computeThirdLink(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const {
00065     if(curlink.jointType==KinematicJoint::PRISMATIC) {
00066       computeThirdLinkPrismatic(curlink,Pobj,endlink,Plink,invert,valid);
00067     } else {
00068       computeThirdLinkRevolute(curlink,Pobj,endlink,Plink,invert,valid);
00069     }
00070   }
00071   //! sets the angle of curlink based on length of thigh (distance from curlink to parent origin), and distance from curlink to effector point, to achieve desired distance from parent to effector.
00072   void computeThirdLinkRevolute(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const;
00073   //! sets the length of curlink based on length of thigh (distance from curlink to parent origin), the angle between the parent and effector point, and the distance from parent to objective.
00074   void computeThirdLinkPrismatic(KinematicJoint& curlink, const fmat::Column<3>& Pobj, KinematicJoint& endlink, const fmat::Column<3>& Plink, bool invert, bool& valid) const;
00075   
00076   //! solves for a prismatic link, pass the objective distance squared, the "neck" distance squared, and the inner product of the neck angle, i.e. inner = neck·linkZ = neckD · 1 · cos(neckAng)
00077   static fmat::fmatReal computePrismaticQ(fmat::fmatReal objD2, fmat::fmatReal neckD2, fmat::fmatReal inner);
00078   
00079   //! ensures that @a t is in the range ±π  (upper boundary may not be inclusive...?)
00080   static float normalize_angle(float x) { return x - static_cast<float>( rint(x/(2*M_PI)) * (2*M_PI) ); }
00081   
00082   bool invertThird; //!< there are two knee solutions, this will choose the non-default solution.
00083   
00084   mutable bool hasInverseSolution; //!< set to true if there is another solution within range
00085   mutable float inverseKnee; //!< alternative angle for knee
00086 
00087 private:
00088   //! holds the class name, set via registration with the DeviceDriver registry
00089   static const std::string autoRegisterIKThreeLink;
00090 };
00091 /*! @file
00092  * @brief 
00093  * @author Ethan Tira-Thompson (ejt) (Creator)
00094  */
00095 
00096 #endif

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:42 2012 by Doxygen 1.6.3