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
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
00050
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
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
00094
00095 jd.PopulateJointInfo(chain, joints.q, joints.qdot, joints.qdotdot);
00096 }
00097
00098
00099
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
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
00127
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;
00140 }
00141 else
00142 {
00143 inertiaSum = inertiaSum + inertiaExt;
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
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
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
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