chainiksolver_vel_pinv_mimic.cpp
Go to the documentation of this file.
00001 // Copyright  (C)  2007  Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
00002 
00003 // Version: 1.0
00004 // Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
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 // Modified to account for "mimic" joints, i.e. joints whose motion has a
00023 // linear relationship to that of another joint.
00024 // Copyright  (C)  2013  Sachin Chitta, Willow Garage
00025 
00026 #include <moveit/kdl_kinematics_plugin/chainiksolver_vel_pinv_mimic.hpp>
00027 #include <ros/console.h>
00028 
00029 namespace KDL
00030 {
00031 ChainIkSolverVel_pinv_mimic::ChainIkSolverVel_pinv_mimic(const Chain& _chain, int _num_mimic_joints, int _num_redundant_joints, bool _position_ik, double _eps, int _maxiter):
00032   position_ik(_position_ik),
00033   chain(_chain),
00034   jnt2jac(chain),
00035   jac(chain.getNrOfJoints()),
00036   jac_locked(chain.getNrOfJoints()-_num_redundant_joints-_num_mimic_joints),
00037   jac_reduced(chain.getNrOfJoints()-_num_mimic_joints),
00038   svd(jac_reduced),
00039   U_locked(MatrixXd::Zero(6,chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00040   S_locked(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00041   V_locked(MatrixXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints,chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00042   tmp_locked(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00043 
00044   U_translate_locked(MatrixXd::Zero(3,chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00045   S_translate_locked(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00046   V_translate_locked(MatrixXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints,chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00047   tmp_translate_locked(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints)),
00048 
00049   U_translate(MatrixXd::Zero(3,chain.getNrOfJoints()-_num_mimic_joints)),
00050   S_translate(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints)),
00051   V_translate(MatrixXd::Zero(chain.getNrOfJoints()-_num_mimic_joints,chain.getNrOfJoints()-_num_mimic_joints)),
00052   tmp_translate(VectorXd::Zero(chain.getNrOfJoints()-_num_mimic_joints)),
00053   U(6,JntArray(chain.getNrOfJoints()-_num_mimic_joints)),
00054   S(chain.getNrOfJoints()-_num_mimic_joints),
00055   V(chain.getNrOfJoints()-_num_mimic_joints,JntArray(chain.getNrOfJoints()-_num_mimic_joints)),
00056   tmp(chain.getNrOfJoints()-_num_mimic_joints),
00057   eps(_eps),
00058   maxiter(_maxiter),
00059   qdot_out_reduced(chain.getNrOfJoints()-_num_mimic_joints),
00060   qdot_out_reduced_locked(chain.getNrOfJoints()-_num_mimic_joints-_num_redundant_joints),
00061   qdot_out_locked(chain.getNrOfJoints()-_num_redundant_joints),
00062   num_mimic_joints(_num_mimic_joints),
00063   num_redundant_joints(_num_redundant_joints),
00064   redundant_joints_locked(false)
00065 {
00066   mimic_joints_.resize(chain.getNrOfJoints());
00067   for(std::size_t i=0; i < mimic_joints_.size(); ++i)
00068     mimic_joints_[i].reset(i);
00069 }
00070 
00071 ChainIkSolverVel_pinv_mimic::~ChainIkSolverVel_pinv_mimic()
00072 {
00073 }
00074 
00075 bool ChainIkSolverVel_pinv_mimic::setMimicJoints(const std::vector<kdl_kinematics_plugin::JointMimic> & mimic_joints)
00076 {
00077   if(mimic_joints.size() != chain.getNrOfJoints())
00078     return false;
00079 
00080   for(std::size_t i=0; i < mimic_joints.size(); ++i)
00081   {
00082     if(mimic_joints[i].map_index >= chain.getNrOfJoints())
00083       return false;
00084   }
00085   mimic_joints_ = mimic_joints;
00086   return true;
00087 }
00088 
00089 bool ChainIkSolverVel_pinv_mimic::setRedundantJointsMapIndex(const std::vector<unsigned int> & redundant_joints_map_index)
00090 {
00091   if(redundant_joints_map_index.size() != chain.getNrOfJoints()-num_mimic_joints-num_redundant_joints)
00092     return false;
00093 
00094   for(std::size_t i=0; i < redundant_joints_map_index.size(); ++i)
00095   {
00096     if(redundant_joints_map_index[i] >= chain.getNrOfJoints()-num_mimic_joints)
00097       return false;
00098   }
00099   locked_joints_map_index = redundant_joints_map_index;
00100   return true;
00101 }
00102 
00103 bool ChainIkSolverVel_pinv_mimic::jacToJacReduced(const Jacobian &jac, Jacobian &jac_reduced_l)
00104 {
00105   jac_reduced_l.data.setZero();
00106   for(std::size_t i=0; i < chain.getNrOfJoints(); ++i)
00107   {
00108     Twist vel1 = jac_reduced_l.getColumn(mimic_joints_[i].map_index);
00109     Twist vel2 = jac.getColumn(i);
00110     Twist result = vel1 + (mimic_joints_[i].multiplier*vel2);
00111     jac_reduced_l.setColumn(mimic_joints_[i].map_index,result);
00112   }
00113   return true;
00114 }
00115 
00116 bool ChainIkSolverVel_pinv_mimic::jacToJacLocked(const Jacobian &jac, Jacobian &jac_locked)
00117 {
00118   jac_locked.data.setZero();
00119   for(std::size_t i=0; i < chain.getNrOfJoints()-num_mimic_joints-num_redundant_joints; ++i)
00120   {
00121     jac_locked.setColumn(i, jac.getColumn(locked_joints_map_index[i]));
00122   }
00123   return true;
00124 }
00125 
00126 int ChainIkSolverVel_pinv_mimic::CartToJntRedundant(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
00127 {
00128   qdot_out.data.setZero();
00129   //Let the ChainJntToJacSolver calculate the jacobian "jac" for
00130   //the current joint positions "q_in". This will include the mimic joints
00131   if(num_mimic_joints > 0)
00132   {
00133     jnt2jac.JntToJac(q_in,jac);
00134     //Now compute the actual jacobian that involves only the active DOFs
00135     jacToJacReduced(jac,jac_reduced);
00136   }
00137   else
00138     jnt2jac.JntToJac(q_in,jac_reduced);
00139 
00140   //Now compute the jacobian with redundant joints locked
00141   jacToJacLocked(jac_reduced,jac_locked);
00142 
00143   //Do a singular value decomposition of "jac" with maximum
00144   //iterations "maxiter", put the results in "U", "S" and "V"
00145   //jac = U*S*Vt
00146 
00147   int ret;
00148   if(!position_ik)
00149     ret = svd_eigen_HH(jac_locked.data,U_locked,S_locked,V_locked,tmp_locked,maxiter);
00150   else
00151     ret = svd_eigen_HH(jac_locked.data.topLeftCorner(3,chain.getNrOfJoints()-num_mimic_joints-num_redundant_joints),U_translate_locked,S_translate_locked,V_translate_locked,tmp_translate_locked,maxiter);
00152 
00153   double sum;
00154   unsigned int i,j;
00155 
00156   // We have to calculate qdot_out = jac_pinv*v_in
00157   // Using the svd decomposition this becomes(jac_pinv=V*S_pinv*Ut):
00158   // qdot_out = V*S_pinv*Ut*v_in
00159 
00160   unsigned int columns, rows;
00161   if(!position_ik)
00162     rows = jac_locked.rows();
00163   else
00164     rows = 3;
00165 
00166   //first we calculate Ut*v_in
00167   for (i=0;i<jac_locked.columns();i++) {
00168     sum = 0.0;
00169     for (j=0;j<rows;j++) {
00170       if(!position_ik)
00171         sum+= U_locked(j,i)*v_in(j);
00172       else
00173         sum+= U_translate_locked(j,i)*v_in(j);
00174     }
00175     //If the singular value is too small (<eps), don't invert it but
00176     //set the inverted singular value to zero (truncated svd)
00177     if(!position_ik)
00178       tmp(i) = sum*(fabs(S_locked(i))<eps?0.0:1.0/S_locked(i));
00179     else
00180       tmp(i) = sum*(fabs(S_translate_locked(i))<eps?0.0:1.0/S_translate_locked(i));
00181   }
00182   //tmp is now: tmp=S_pinv*Ut*v_in, we still have to premultiply
00183   //it with V to get qdot_out
00184   for (i=0;i<jac_locked.columns();i++) {
00185     sum = 0.0;
00186     for (j=0;j<jac_locked.columns();j++) {
00187       if(!position_ik)
00188         sum+=V_locked(i,j)*tmp(j);
00189       else
00190         sum+=V_translate_locked(i,j)*tmp(j);
00191     }
00192     //Put the result in qdot_out_reduced if mimic joints exist, otherwise in qdot_out
00193     if(num_mimic_joints > 0)
00194       qdot_out_reduced_locked(i)=sum;
00195     else
00196       qdot_out_locked(i) = sum;
00197   }
00198   ROS_DEBUG_STREAM_NAMED("kdl","Solution:");
00199 
00200   if(num_mimic_joints > 0)
00201   {
00202     for(i=0; i < chain.getNrOfJoints()-num_mimic_joints-num_redundant_joints; ++i)
00203     {
00204       qdot_out_reduced(locked_joints_map_index[i]) = qdot_out_reduced_locked(i);
00205     }
00206     for(i=0; i < chain.getNrOfJoints(); ++i)
00207     {
00208       qdot_out(i) = qdot_out_reduced(mimic_joints_[i].map_index) * mimic_joints_[i].multiplier;
00209     }
00210   }
00211   else
00212   {
00213     for(i=0; i < chain.getNrOfJoints()-num_redundant_joints; ++i)
00214     {
00215       qdot_out(locked_joints_map_index[i]) = qdot_out_locked(i);
00216     }
00217   }
00218   // Reset the flag
00219   // redundant_joints_locked = false;
00220   //return the return value of the svd decomposition
00221   return ret;
00222 }
00223 
00224 int ChainIkSolverVel_pinv_mimic::CartToJnt(const JntArray& q_in, const Twist& v_in, JntArray& qdot_out)
00225 {
00226   if(redundant_joints_locked)
00227     return CartToJntRedundant(q_in, v_in, qdot_out);
00228 
00229   //Let the ChainJntToJacSolver calculate the jacobian "jac" for
00230   //the current joint positions "q_in". This will include the mimic joints
00231   if(num_mimic_joints > 0)
00232   {
00233     jnt2jac.JntToJac(q_in,jac);
00234     //Now compute the actual jacobian that involves only the active DOFs
00235     jacToJacReduced(jac,jac_reduced);
00236   }
00237   else
00238     jnt2jac.JntToJac(q_in,jac_reduced);
00239 
00240   //Do a singular value decomposition of "jac" with maximum
00241   //iterations "maxiter", put the results in "U", "S" and "V"
00242   //jac = U*S*Vt
00243 
00244   int ret;
00245   if(!position_ik)
00246     ret = svd.calculate(jac_reduced,U,S,V,maxiter);
00247   else
00248     ret = svd_eigen_HH(jac_reduced.data.topLeftCorner(3,chain.getNrOfJoints()-num_mimic_joints),U_translate,S_translate,V_translate,tmp_translate,maxiter);
00249 
00250   double sum;
00251   unsigned int i,j;
00252 
00253   // We have to calculate qdot_out = jac_pinv*v_in
00254   // Using the svd decomposition this becomes(jac_pinv=V*S_pinv*Ut):
00255   // qdot_out = V*S_pinv*Ut*v_in
00256 
00257   unsigned int columns, rows;
00258   if(!position_ik)
00259     rows = jac_reduced.rows();
00260   else
00261     rows = 3;
00262 
00263   //first we calculate Ut*v_in
00264   for (i=0;i<jac_reduced.columns();i++) {
00265     sum = 0.0;
00266     for (j=0;j<rows;j++) {
00267       if(!position_ik)
00268         sum+= U[j](i)*v_in(j);
00269       else
00270         sum+= U_translate(j,i)*v_in(j);
00271     }
00272     //If the singular value is too small (<eps), don't invert it but
00273     //set the inverted singular value to zero (truncated svd)
00274     if(!position_ik)
00275       tmp(i) = sum*(fabs(S(i))<eps?0.0:1.0/S(i));
00276     else
00277       tmp(i) = sum*(fabs(S_translate(i))<eps?0.0:1.0/S_translate(i));
00278   }
00279   //tmp is now: tmp=S_pinv*Ut*v_in, we still have to premultiply
00280   //it with V to get qdot_out
00281   for (i=0;i<jac_reduced.columns();i++) {
00282     sum = 0.0;
00283     for (j=0;j<jac_reduced.columns();j++) {
00284       if(!position_ik)
00285         sum+=V[i](j)*tmp(j);
00286       else
00287         sum+=V_translate(i,j)*tmp(j);
00288     }
00289     //Put the result in qdot_out_reduced if mimic joints exist, otherwise in qdot_out
00290     if(num_mimic_joints > 0)
00291       qdot_out_reduced(i)=sum;
00292     else
00293       qdot_out(i) = sum;
00294   }
00295   ROS_DEBUG_STREAM_NAMED("kdl","Solution:");
00296   if(num_mimic_joints > 0)
00297   {
00298     for(i=0; i < chain.getNrOfJoints(); ++i)
00299     {
00300       qdot_out(i) = qdot_out_reduced(mimic_joints_[i].map_index) * mimic_joints_[i].multiplier;
00301     }
00302   }
00303   //return the return value of the svd decomposition
00304   return ret;
00305 }
00306 }


planning
Author(s): Ioan Sucan , Sachin Chitta
autogenerated on Mon Oct 6 2014 02:31:39