KdlTreeId.cpp
Go to the documentation of this file.
00001 #include "robodyn_controllers/KdlTreeId.h"
00002 #include <iostream>
00003 
00004 KdlTreeId::KdlTreeId()
00005 {
00006 }
00007 
00008 
00009 KdlTreeId::~KdlTreeId()
00010 {
00011 }
00012 
00013 bool KdlTreeId::isBaseFrameInTree(const std::string& baseFrame)
00014 {
00015     return hasSegment(baseFrame);
00016 }
00017 
00018 void KdlTreeId::setFrames(const std::string& gravityFrame_in, const std::string& baseFrame_in)
00019 {
00020     if (gravityFrame == gravityFrame_in && baseFrame == baseFrame_in)
00021     {
00022         // nothing to do
00023         return;
00024     }
00025 
00026     gravityFrame = gravityFrame_in;
00027     baseFrame    = baseFrame_in;
00028     getChain(gravityFrame, baseFrame, gravBaseChain);
00029     chainFkSolver.reset(new KDL::ChainFkSolverPos_recursive(gravBaseChain));
00030 }
00031 
00032 void KdlTreeId::getAccelInBaseFrame(KDL::Vector gravity, const std::string& gravityFrame, JointDynamicsData& jd, const std::string& base, KDL::Twist& accelIn)
00033 {
00034     setFrames(gravityFrame, base);
00035     joints.resize(gravBaseChain.getNrOfJoints());
00036     jd.PopulateJointInfo(gravBaseChain, joints.q, joints.qdot, joints.qdotdot);
00037     KDL::Frame baseF;
00038     chainFkSolver->JntToCart(joints.q, baseF);
00039 
00040     gravity = baseF.M.Inverse() * gravity;
00041     accelIn = KDL::Twist(gravity, KDL::Vector::Zero());
00042 }
00043 
00044 bool KdlTreeId::treeRecursiveNewtonEuler(JointDynamicsData& jd, const std::string& baseFrame, const std::string& ignoreFrame, const KDL::Twist& velIn, const KDL::Twist& accelIn, KDL::Wrench& forceOut, KDL::RigidBodyInertia& inertiaIn)
00045 {
00046     std::vector<std::string> nL, dir;
00047     std::string node;
00048 
00049     // If only one branch from base, find branch.  Otherwise, branch is
00050     // only the current base segment
00051     if (findBranchNodes(baseFrame, ignoreFrame, nL, dir) == 1)
00052     {
00053         findChainFromNode(nL[0], dir[0], node);
00054     }
00055     else
00056     {
00057         node = baseFrame;
00058     }
00059 
00060     // Create the chain from the branch found
00061     KDL::Chain chain;
00062 
00063     if (ignoreFrame == "null")
00064     {
00065         getChain(baseFrame, node, chain);
00066     }
00067     else
00068     {
00069         getChain(ignoreFrame, node, chain);
00070     }
00071 
00072     unsigned int nj = chain.getNrOfJoints();
00073     unsigned int ns = chain.getNrOfSegments();
00074 
00075     KDL::Twist velOut, accelOut;
00076     joints.resize(nj);
00077     KDL::JntArray tau(nj), Hv(nj);
00078     KDL::Wrenches forceExt(ns), forceSeg(ns);
00079     KDL::RigidBodyInertia inertiaExt, inertiaSum, inertiaSeg;
00080 
00081     KdlChainIdRne fs(chain, velIn, accelIn);
00082     jd.PopulateExtForceInfo(chain, forceExt);
00083     inertiaExt = inertiaSum = inertiaSeg = KDL::RigidBodyInertia::Zero();
00084 
00085     if (ns == 0)
00086     {
00087         forceExt.resize(1);
00088         jd.PopulateExtForceInfo(node, forceExt);
00089     }
00090 
00091     if (nj > 0)
00092     {
00093         // Using joint state data, populate the appropriate joint arrays
00094         // for the given chain
00095         jd.PopulateJointInfo(chain, joints.q, joints.qdot, joints.qdotdot);
00096     }
00097 
00098     // Run the kinematics pass of the rne algorithm, sending back tip
00099     // velocity and acceleration
00100     if (ns > 0)
00101     {
00102         fs.KinematicsPass(joints.q, joints.qdot, joints.qdotdot, velOut, accelOut);
00103     }
00104     else
00105     {
00106         velOut = velIn;
00107         accelOut = accelIn;
00108     }
00109 
00110     // Determine which branch to ignore
00111     std::string branchIgnore;
00112 
00113     if (ns == 1 && ignoreFrame == "null")
00114     {
00115         branchIgnore = baseFrame;
00116     }
00117     else if (ns <= 1)
00118     {
00119         branchIgnore = ignoreFrame;
00120     }
00121     else
00122     {
00123         branchIgnore = chain.getSegment(ns - 2).getName();
00124     }
00125 
00126     // Find branches of current base node, call function recursively on
00127     // all its branches
00128     nL.clear();
00129     dir.clear();
00130 
00131     if (findBranchNodes(node, branchIgnore, nL, dir) != 0)
00132     {
00133         KDL::Wrenches forceBranches(nL.size());
00134 
00135         for (unsigned int i = 0; i < nL.size(); i++)
00136         {
00137             if (!treeRecursiveNewtonEuler(jd, nL[i], node, velOut, accelOut, forceBranches[i], inertiaExt))
00138             {
00139                 inertiaSeg = inertiaSeg + inertiaExt; // inertia for next joint
00140             }
00141             else
00142             {
00143                 inertiaSum = inertiaSum + inertiaExt; // inertia already compensated
00144             }
00145         }
00146 
00147         if (ns > 0)
00148         {
00149             forceExt[ns - 1] += sumForces(forceBranches);
00150         }
00151         else
00152         {
00153             forceExt[0] += sumForces(forceBranches);
00154         }
00155     }
00156 
00157     // Call the dynamics half of the rne algorithm
00158     fs.DynamicsPass(forceExt, tau, forceOut, forceSeg, inertiaSum, inertiaSeg, Hv, inertiaIn);
00159 
00160     if (ns > 0)
00161     {
00162         jd.StoreSegmentWrenches(chain, forceSeg);
00163     }
00164 
00165     if (nj > 0)
00166     {
00167         // Store off the joint torque information
00168         jd.StoreJointTorqueCommands(chain, tau);
00169         jd.StoreJointInertia(chain, Hv);
00170         return true;
00171     }
00172     else
00173     {
00174         return false;
00175     }
00176 }
00177 
00178 
00179 void KdlTreeId::findChainFromNode(const std::string& baseFrame, const std::string& direction, std::string& toolFrame)
00180 {
00181     toolFrame = baseFrame;
00182     KDL::SegmentMap::const_iterator it = tree.getSegment(toolFrame);
00183 
00184     if (direction == "parent")
00185     {
00186         while (it->second.children.size() < 2 && it != tree.getRootSegment())
00187         {
00188             toolFrame = it->second.parent->first;
00189             it = tree.getSegment(toolFrame);
00190         }
00191     }
00192     else // direction == child
00193     {
00194         while (it->second.children.size() == 1)
00195         {
00196             toolFrame = it->second.children[0]->first;
00197             it        = tree.getSegment(toolFrame);
00198         }
00199     }
00200 
00201     return;
00202 }
00203 
00204 
00205 int KdlTreeId::findBranchNodes(const std::string& baseFrame, const std::string& ignoreFrame, std::vector<std::string>& nodeList, std::vector<std::string>& direction)
00206 {
00207     KDL::SegmentMap::const_iterator it = tree.getSegment(baseFrame);
00208 
00209     if (it != tree.getRootSegment())
00210     {
00211         if (it->second.parent->first != ignoreFrame)
00212         {
00213             nodeList.push_back(it->second.parent->first);
00214             direction.push_back("parent");
00215         }
00216     }
00217 
00218     for (unsigned int i = 0; i < it->second.children.size(); i++)
00219     {
00220         if (it->second.children[i]->first != ignoreFrame)
00221         {
00222             nodeList.push_back(it->second.children[i]->first);
00223             direction.push_back("child");
00224         }
00225     }
00226 
00227     return nodeList.size();
00228 
00229 }
00230 
00231 KDL::Wrench KdlTreeId::sumForces(const KDL::Wrenches& forceIn)
00232 {
00233     KDL::Wrench sum = KDL::Wrench::Zero();
00234 
00235     for (unsigned int i = 0; i < forceIn.size(); i++)
00236     {
00237         sum += forceIn[i];
00238     }
00239 
00240     return sum;
00241 }
00242 
00243 void KdlTreeId::initialize()
00244 {
00245     getJointNames(jointNames);
00246 }
00247 


robodyn_controllers
Author(s):
autogenerated on Sat Jun 8 2019 20:20:53