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

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:42 2016 by Doxygen 1.6.3