00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #pragma once
00035
00038 class TreeChain{
00039 std::vector<int> chain2Tree;
00040 KDL::Chain chain;
00041 KDL::JntArray jnts;
00042 KDL::JntArrayVel jntsVel;
00043 KDL::JntArray result;
00044 KDL::JntArray full_result;
00045 KDL::Jacobian J;
00046 KDL::Jacobian fullJ;
00047
00048 std::vector<double>* pK;
00049 std::vector<double>* pD;
00050
00051 int jnt_size;
00052 int tree_size;
00053
00054 void update( const std::vector<double>& treeJnts, const std::vector<double>& treeJntsVel ){
00055 for( int x=0; x<jnt_size; ++x ){
00056 int idx = chain2Tree[x];
00057 jnts(x) = treeJnts[ idx ];
00058 jntsVel.q(x) = jnts(x);
00059 jntsVel.qdot(x) = treeJntsVel[ idx ];
00060 }
00061 KDL::ChainJntToJacSolver solver(chain);
00062 solver.JntToJac( jnts, J );
00063 for( int y=0; y<jnt_size; ++y ){
00064 int iy = chain2Tree[y];
00065 for( int x=0; x<6; ++x ){
00066 fullJ( x, iy ) = J( x, y );
00067 }
00068 }
00069 }
00070
00071 public:
00072 int size()const{ return jnt_size; }
00073 int treeIdx( int chainIdx )const{
00074 return chain2Tree[ chainIdx ];
00075 }
00076
00077 const KDL::Jacobian& getJ()const{ return fullJ; }
00078 TreeChain(): jnt_size(0), tree_size(0){}
00079 void init( const KDL::Tree& tree, const std::string& root, const std::string& tip, std::vector<double>& Kgains, std::vector<double>& Dgains){
00080 bool r = tree.getChain( root, tip, chain );
00081 (void)r;
00082 assert(r);
00083 jnt_size = chain.getNrOfJoints();
00084 tree_size = tree.getNrOfJoints();
00085
00086 jnts.resize(jnt_size);
00087 jntsVel.resize(jnt_size);
00088
00089 result.resize(jnt_size);
00090 KDL::SetToZero(result);
00091
00092 full_result.resize(tree_size);
00093 KDL::SetToZero(full_result);
00094
00095 J.resize(jnt_size);
00096 fullJ.resize(tree_size);
00097 SetToZero(fullJ);
00098
00099 pK = &Kgains;
00100 pD = &Dgains;
00101
00102
00103
00104
00105
00106 chain2Tree.resize(jnt_size);
00107 const KDL::SegmentMap& sm = tree.getSegments();
00108
00109 int tj=0;
00110 for( KDL::SegmentMap::const_iterator i= sm.begin(); i!=sm.end(); ++i ){
00111 const KDL::Segment& seg = i->second.segment;
00112 const KDL::Joint& joint = seg.getJoint();
00113 if( joint.getType() == KDL::Joint::None )
00114 continue;
00115 int cj =0;
00116 const int segCnt = (int)chain.getNrOfSegments();
00117 for( int x=0; x<segCnt; ++x ){
00118 const KDL::Segment& c_seg = chain.getSegment(x);
00119 if( c_seg.getJoint().getType() == KDL::Joint::None )
00120 continue;
00121 if( c_seg.getJoint().getName() == joint.getName() ){
00122 chain2Tree[cj] = tj;
00123 break;
00124 }
00125 ++cj;
00126 }
00127 ++tj;
00128 }
00129 }
00130
00131 const KDL::JntArray& moveCart( Eigen::Matrix<double, 7, 1>& cartCmd, const std::vector<double>& treeJnts, const std::vector<double>& treeJntsVel ){
00132 update( treeJnts, treeJntsVel );
00133
00134 Eigen::Matrix<double, 7, 1> current = fk();
00135 Eigen::Matrix<double, 6, 1> v = fk_vel();
00136
00137 KDL::Frame f1( KDL::Rotation::Quaternion( current[4], current[5], current[6], current[3] ), KDL::Vector( current[0], current[1], current[2] ) );
00138 KDL::Frame f2( KDL::Rotation::Quaternion( cartCmd[4], cartCmd[5], cartCmd[6], cartCmd[3] ), KDL::Vector( cartCmd[0], cartCmd[1], cartCmd[2] ) );
00139
00140 KDL::Twist twist = KDL::diff( f1, f2 );
00141 Eigen::Matrix<double, 6, 1> delta;
00142
00143 std::vector<double>& K = *pK;
00144 std::vector<double>& D = *pD;
00145
00146 delta << twist.vel(0) * K[0] - v[0]*D[0],
00147 twist.vel(1) * K[1] - v[1]*D[1],
00148 twist.vel(2) * K[2] - v[2]*D[2],
00149 twist.rot(0) * K[3] - v[3]*D[3],
00150 twist.rot(1) * K[4] - v[4]*D[4],
00151 twist.rot(2) * K[5] - v[5]*D[5];
00152
00153 result.data = J.data.transpose()*delta;
00154
00155 for( int x=0; x<jnt_size; ++x ){
00156 full_result( chain2Tree[x] ) = result( x );
00157 }
00158 return full_result;
00159 }
00160 const KDL::JntArray& moveCart( KDL::Twist& cartVelCmd, const std::vector<double>& treeJnts, const std::vector<double>& treeJntsVel ){
00161 update( treeJnts, treeJntsVel );
00162
00163 Eigen::Matrix<double, 6, 1> v = fk_vel();
00164 Eigen::Matrix<double, 6, 1> delta;
00165 std::vector<double>& D = *pD;
00166 delta << (cartVelCmd.vel(0) - v[0] )*D[0],
00167 (cartVelCmd.vel(1) - v[1] )*D[1],
00168 (cartVelCmd.vel(2) - v[2] )*D[2],
00169 (cartVelCmd.rot(0) - v[3] )*D[3],
00170 (cartVelCmd.rot(1) - v[4] )*D[4],
00171 (cartVelCmd.rot(2) - v[5] )*D[5];
00172 result.data = J.data.transpose()*delta;
00173 for( int x=0; x<jnt_size; ++x ){
00174 full_result( chain2Tree[x] ) = result( x );
00175 }
00176 return full_result;
00177 }
00178 const KDL::JntArray& moveCart( Eigen::Matrix<double, 7, 1>& cartCmd, KDL::Twist& cartVelCmd, const std::vector<double>& treeJnts, const std::vector<double>& treeJntsVel ){
00179 update( treeJnts, treeJntsVel );
00180
00181 Eigen::Matrix<double, 7, 1> current = fk();
00182 Eigen::Matrix<double, 6, 1> v = fk_vel();
00183
00184 KDL::Frame f1( KDL::Rotation::Quaternion( current[4], current[5], current[6], current[3] ), KDL::Vector( current[0], current[1], current[2] ) );
00185 KDL::Frame f2( KDL::Rotation::Quaternion( cartCmd[4], cartCmd[5], cartCmd[6], cartCmd[3] ), KDL::Vector( cartCmd[0], cartCmd[1], cartCmd[2] ) );
00186
00187 KDL::Twist twist = KDL::diff( f1, f2 );
00188 Eigen::Matrix<double, 6, 1> delta;
00189
00190 std::vector<double>& K = *pK;
00191 std::vector<double>& D = *pD;
00192
00193 delta << twist.vel(0) * K[0] + ( cartVelCmd.vel(0) - v[0] ) *D[0],
00194 twist.vel(1) * K[1] + ( cartVelCmd.vel(1) - v[1] ) *D[1],
00195 twist.vel(2) * K[2] + ( cartVelCmd.vel(2) - v[2] ) *D[2],
00196 twist.rot(0) * K[3] + ( cartVelCmd.rot(0) - v[3] ) *D[3],
00197 twist.rot(1) * K[4] + ( cartVelCmd.rot(1) - v[4] ) *D[4],
00198 twist.rot(2) * K[5] + ( cartVelCmd.rot(2) - v[5] ) *D[5];
00199
00200 result.data = J.data.transpose()*delta;
00201
00202 for( int x=0; x<jnt_size; ++x ){
00203 full_result( chain2Tree[x] ) = result( x );
00204 }
00205 return full_result;
00206 }
00207
00208 Eigen::Matrix<double,7,1> fk( const std::vector<double>& treeJnts ){
00209 for( int x=0; x<jnt_size; ++x )
00210 jnts(x) = treeJnts[ chain2Tree[x] ];
00211 return fk();
00212 }
00213
00214 Eigen::Matrix<double,7, 1> fk(){
00215 Eigen::Matrix<double,7,1> result;
00216
00217 KDL::ChainFkSolverPos_recursive solver(chain);
00218 KDL::Frame frame;
00219 solver.JntToCart( jnts, frame );
00220
00221 result[0] = frame.p(0);
00222 result[1] = frame.p(1);
00223 result[2] = frame.p(2);
00224 double& w = result[3];
00225 double& x = result[4];
00226 double& y = result[5];
00227 double& z = result[6];
00228 frame.M.GetQuaternion( x, y, z, w );
00229
00230 return result;
00231 }
00232 Eigen::Matrix<double,6, 1> fk_vel(){
00234 Eigen::Matrix<double,6,1> result;
00235
00236 KDL::ChainFkSolverVel_recursive solver(chain);
00237 KDL::FrameVel frame;
00238
00239 solver.JntToCart( jntsVel, frame );
00240 result[0] = frame.p.v(0);
00241 result[1] = frame.p.v(1);
00242 result[2] = frame.p.v(2);
00243 result[3] = frame.M.w(0);
00244 result[4] = frame.M.w(1);
00245 result[5] = frame.M.w(2);
00246 for( int x=0; x<6; ++x ){
00247 assert( result[x] == result[x] );
00248 }
00249 return result;
00250 }
00251
00252
00253
00254
00255 };
00256
00257