Go to the documentation of this file.00001 #include <robodyn_controllers/KdlChainIk.h>
00002
00003 #include <kdl/chain.hpp>
00004 #include <kdl/chainfksolverpos_recursive.hpp>
00005 #include <kdl/chainiksolvervel_pinv.hpp>
00006 #include <kdl/chainiksolverpos_nr_jl.hpp>
00007 #include "nasa_common_logging/Logger.h"
00008
00014 KdlChainIk::KdlChainIk(const KDL::Chain& _chain)
00015 : chain(_chain)
00016 {
00017
00018 std::map<std::string, double> jointMin;
00019 std::map<std::string, double> jointMax;
00020
00021 jointMin["/r2/left_leg/joint0"] = -1.5708;
00022 jointMax["/r2/left_leg/joint0"] = 1.5708;
00023 jointMin["/r2/left_leg/joint1"] = -1.3875;
00024 jointMax["/r2/left_leg/joint1"] = 1.1694;
00025 jointMin["/r2/left_leg/joint2"] = -3.14159;
00026 jointMax["/r2/left_leg/joint2"] = 3.14159;
00027 jointMin["/r2/left_leg/joint3"] = -0.0698;
00028 jointMax["/r2/left_leg/joint3"] = 2.6529;
00029 jointMin["/r2/left_leg/joint4"] = -3.14159;
00030 jointMax["/r2/left_leg/joint4"] = 3.14159;
00031 jointMin["/r2/left_leg/joint5"] = -0.0698;
00032 jointMax["/r2/left_leg/joint5"] = 2.6529;
00033 jointMin["/r2/left_leg/joint6"] = -3.14159;
00034 jointMax["/r2/left_leg/joint6"] = 3.14159;
00035
00036 jointMin["/r2/right_leg/joint0"] = -1.5708;
00037 jointMax["/r2/right_leg/joint0"] = 1.5708;
00038 jointMin["/r2/right_leg/joint1"] = -1.3875;
00039 jointMax["/r2/right_leg/joint1"] = 1.1694;
00040 jointMin["/r2/right_leg/joint2"] = -3.14159;
00041 jointMax["/r2/right_leg/joint2"] = 3.14159;
00042 jointMin["/r2/right_leg/joint3"] = -0.0698;
00043 jointMax["/r2/right_leg/joint3"] = 2.6529;
00044 jointMin["/r2/right_leg/joint4"] = -3.14159;
00045 jointMax["/r2/right_leg/joint4"] = 3.14159;
00046 jointMin["/r2/right_leg/joint5"] = -0.0698;
00047 jointMax["/r2/right_leg/joint5"] = 2.6529;
00048 jointMin["/r2/right_leg/joint6"] = -3.14159;
00049 jointMax["/r2/right_leg/joint6"] = 3.14159;
00050
00051 if (chain.getNrOfJoints() == 0)
00052 {
00053 std::stringstream err;
00054 err << "KdlChainIk given chain with no joints";
00055 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlChainIk", log4cpp::Priority::ERROR, err.str());
00056 throw std::runtime_error(err.str());
00057 return;
00058 }
00059
00060
00061 KDL::JntArray jMin(chain.getNrOfJoints()), jMax(chain.getNrOfJoints());
00062 unsigned int j = 0;
00063
00064 for (unsigned int i = 0; i < chain.getNrOfSegments(); ++i)
00065 {
00066 if (chain.getSegment(i).getJoint().getType() != KDL::Joint::None)
00067 {
00068 std::string jointName = chain.getSegment(i).getJoint().getName();
00069
00070 jMin(j) = jointMin[jointName];
00071 jMax(j) = jointMax[jointName];
00072
00073 ++j;
00074 }
00075 }
00076
00077
00078 fkPosSolverPtr.reset(new KDL::ChainFkSolverPos_recursive(chain));
00079 ikVelSolverPtr.reset(new KDL::ChainIkSolverVel_pinv(chain));
00080 ikPosSolverPtr.reset(new KDL::ChainIkSolverPos_NR_JL(chain, jMin, jMax, *fkPosSolverPtr, *ikVelSolverPtr));
00081 }
00082
00083 KdlChainIk::~KdlChainIk()
00084 {
00085 }
00086
00092 const std::string& KdlChainIk::getBaseFrame() const
00093 {
00094 return (chain.getSegment(0).getName());
00095 }
00096
00102 void KdlChainIk::getJointNames(std::vector<std::string>& jointNames) const
00103 {
00104 jointNames.clear();
00105
00106 for (unsigned int i = 0; i < chain.getNrOfSegments(); ++i)
00107 {
00108 if (chain.getSegment(i).getJoint().getType() != KDL::Joint::None)
00109 {
00110 std::string jointName = chain.getSegment(i).getJoint().getName();
00111 jointNames.push_back(jointName);
00112 }
00113 }
00114 }
00115
00123 void KdlChainIk::getJointPositions(const KDL::JntArray& joints_in,
00124 const std::vector<KDL::Frame>& tipPositions,
00125 std::vector<KDL::JntArray>& joints_out) const
00126 {
00127 joints_out.clear();
00128 joints_out.resize(tipPositions.size());
00129
00130 KDL::JntArray jointPoseIn = joints_in;
00131 KDL::JntArray jointPoseOut;
00132
00133 for (unsigned int i = 0; i < tipPositions.size(); ++i)
00134 {
00135 int ret = ikPosSolverPtr->CartToJnt(jointPoseIn, tipPositions[i], jointPoseOut);
00136
00137 if (ret >= 0)
00138 {
00139 joints_out[i] = jointPoseOut;
00140 jointPoseIn = jointPoseOut;
00141 }
00142 else
00143 {
00144 std::stringstream err;
00145 err << "Unable to find an IK solution for tipPosition[" << i << "]" << std::endl;
00146 double x, y, z, w;
00147 tipPositions[i].M.GetQuaternion(x, y, z, w);
00148 err << "\t" << tipPositions[i].p.x() << ", " << tipPositions[i].p.y() << ", " <<
00149 tipPositions[i].p.z() << ", " << x << ", " << y << ", " << z << ", " << w << std::endl;
00150 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlChainIk", log4cpp::Priority::WARN, err.str());
00151 throw std::runtime_error(err.str());
00152 }
00153 }
00154 }
00155
00156 void KdlChainIk::getCurrentPose(const KDL::JntArray& joints_in, KDL::Frame& currPose) const
00157 {
00158 if (fkPosSolverPtr->JntToCart(joints_in, currPose) < 0)
00159 {
00160 std::stringstream err;
00161 err << "Unable to find an FK solution";
00162 NasaCommonLogging::Logger::log("gov.nasa.controllers.KdlChainIk", log4cpp::Priority::ERROR, err.str());
00163 throw std::runtime_error(err.str());
00164 }
00165 }