Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00055 if(nj != tree.getNrOfJoints() || ns != tree.getNrOfSegments())
00056 return (error = E_NOT_UP_TO_DATE);
00057
00058
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
00064 rne_step(tree.getRootSegment(), q, q_dot, q_dotdot, f_ext, torques);
00065 }
00066 catch(const std::out_of_range&) {
00067
00068
00069
00070
00071
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
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
00095
00096
00097 X.at(segname) = seg.pose(q_);
00098
00099
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
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
00114
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
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
00128
00129
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);
00133 }
00134
00135
00136 if(segment != tree.getRootSegment())
00137 f.at(parname) = f.at(parname) + X.at(segname)*f.at(segname);
00138 }
00139 }