treeidsolver_recursive_newton_euler.cpp
Go to the documentation of this file.
00001 // Copyright  (C)  2009  Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
00002 
00003 // Version: 1.0
00004 // Author: Franco Fusco <franco dot fusco at ls2n dot fr>
00005 // Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
00006 // URL: http://www.orocos.org/kdl
00007 
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Lesser General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2.1 of the License, or (at your option) any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Lesser General Public License for more details.
00017 
00018 // You should have received a copy of the GNU Lesser General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022 #include "treeidsolver_recursive_newton_euler.hpp"
00023 #include "frames_io.hpp"
00024 #include <stdexcept>
00025 
00026 namespace KDL{
00027 
00028     TreeIdSolver_RNE::TreeIdSolver_RNE(const Tree& tree_, Vector grav):
00029         tree(tree_), nj(tree.getNrOfJoints()), ns(tree.getNrOfSegments())
00030     {
00031       ag=-Twist(grav,Vector::Zero());
00032       initAuxVariables();
00033     }
00034 
00035     void TreeIdSolver_RNE::updateInternalDataStructures() {
00036       nj = tree.getNrOfJoints();
00037       ns = tree.getNrOfSegments();
00038       initAuxVariables();
00039     }
00040 
00041     void TreeIdSolver_RNE::initAuxVariables() {
00042       const SegmentMap& segments = tree.getSegments();
00043       for(SegmentMap::const_iterator seg = segments.begin(); seg != segments.end(); seg++) {
00044         X[seg->first] = Frame();
00045         S[seg->first] = Twist();
00046         v[seg->first] = Twist();
00047         a[seg->first] = Twist();
00048         f[seg->first] = Wrench();
00049       }
00050     }
00051 
00052     int TreeIdSolver_RNE::CartToJnt(const JntArray &q, const JntArray &q_dot, const JntArray &q_dotdot, const WrenchMap& f_ext, JntArray &torques)
00053     {
00054       //Check that the tree was not modified externally
00055       if(nj != tree.getNrOfJoints() || ns != tree.getNrOfSegments())
00056         return (error = E_NOT_UP_TO_DATE);
00057 
00058       //Check sizes of joint vectors
00059       if(q.rows()!=nj || q_dot.rows()!=nj || q_dotdot.rows()!=nj || torques.rows()!=nj)
00060         return (error = E_SIZE_MISMATCH);
00061 
00062       try {
00063         //Do the recursion here
00064         rne_step(tree.getRootSegment(), q, q_dot, q_dotdot, f_ext, torques);
00065       }
00066       catch(const std::out_of_range&) {
00067         //If in rne_step we get an out_of_range exception it means that some call
00068         //to map::at failed. This can happen only if updateInternalDataStructures
00069         //was not called after changing something in the tree. Note that it
00070         //should be impossible to reach this point as consistency of the tree is
00071         //checked above.
00072         return (error = E_NOT_UP_TO_DATE);
00073       }
00074       return (error = E_NOERROR);
00075     }
00076 
00077 
00078     void TreeIdSolver_RNE::rne_step(SegmentMap::const_iterator segment, const JntArray &q, const JntArray &q_dot, const JntArray &q_dotdot, const WrenchMap& f_ext, JntArray& torques) {
00079       const Segment& seg = GetTreeElementSegment(segment->second);
00080       const std::string& segname = segment->first;
00081       const std::string& parname = GetTreeElementParent(segment->second)->first;
00082 
00083       //Do forward calculations involving velocity & acceleration of this segment
00084       double q_, qdot_, qdotdot_;
00085       unsigned int j = GetTreeElementQNr(segment->second);
00086       if(seg.getJoint().getType()!=Joint::None){
00087         q_ = q(j);
00088         qdot_ = q_dot(j);
00089         qdotdot_ = q_dotdot(j);
00090       }
00091       else
00092         q_ = qdot_ = qdotdot_ = 0.0;
00093 
00094       //Calculate segment properties: X,S,vj,cj
00095 
00096       //Remark this is the inverse of the frame for transformations from the parent to the current coord frame
00097       X.at(segname) = seg.pose(q_);
00098 
00099       //Transform velocity and unit velocity to segment frame
00100       Twist vj = X.at(segname).M.Inverse( seg.twist(q_,qdot_) );
00101       S.at(segname) = X.at(segname).M.Inverse( seg.twist(q_,1.0) );
00102 
00103       //calculate velocity and acceleration of the segment (in segment coordinates)
00104       if(segment == tree.getRootSegment()) {
00105         v.at(segname) = vj;
00106         a.at(segname) = X.at(segname).Inverse(ag) + S.at(segname)*qdotdot_+ v.at(segname)*vj;
00107       }
00108       else {
00109         v.at(segname) = X.at(segname).Inverse(v.at(parname)) + vj;
00110         a.at(segname) = X.at(segname).Inverse(a.at(parname)) + S.at(segname)*qdotdot_ + v.at(segname)*vj;
00111       }
00112 
00113       //Calculate the force for the joint
00114       //Collect RigidBodyInertia and external forces
00115       const RigidBodyInertia& I = seg.getInertia();
00116       f.at(segname) = I*a.at(segname) + v.at(segname)*(I*v.at(segname));
00117       if(f_ext.find(segname) != f_ext.end())
00118         f.at(segname) = f.at(segname) - f_ext.at(segname);
00119 
00120       //propagate calculations over each child segment
00121       SegmentMap::const_iterator child;
00122       for (unsigned int i = 0; i < GetTreeElementChildren(segment->second).size(); i++) {
00123         child = GetTreeElementChildren(segment->second)[i];
00124         rne_step(child, q, q_dot, q_dotdot, f_ext, torques);
00125       }
00126 
00127       //do backward calculations involving wrenches and joint efforts
00128 
00129       //If there is a moving joint, evaluate its effort
00130       if(seg.getJoint().getType()!=Joint::None){
00131         torques(j) = dot(S.at(segname), f.at(segname));
00132         torques(j) += seg.getJoint().getInertia()*q_dotdot(j);  // add torque from joint inertia
00133       }
00134 
00135       //add reaction forces to parent segment
00136       if(segment != tree.getRootSegment())
00137         f.at(parname) = f.at(parname) + X.at(segname)*f.at(segname);
00138     }
00139 }//namespace


orocos_kdl
Author(s):
autogenerated on Fri Jun 14 2019 19:33:23