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
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #ifndef REEM_KINEMATICS_IK_SOLVER_
00038 #define REEM_KINEMATICS_IK_SOLVER_
00039
00040
00041 #include <cassert>
00042 #include <cstddef>
00043 #include <map>
00044 #include <string>
00045 #include <vector>
00046
00047
00048 #include <boost/scoped_ptr.hpp>
00049
00050
00051 #include <Eigen/Dense>
00052
00053
00054 #include <kdl/jacobian.hpp>
00055 #include <kdl/jntarray.hpp>
00056
00057 namespace KDL
00058 {
00059 template <typename T> class MatrixInverter;
00060 class TreeFkSolverPos_recursive;
00061 class TreeJntToJacSolver;
00062 }
00063
00064 namespace reem_kinematics_constraint_aware
00065 {
00066
00072 class JointPositionLimitsAvoider
00073 {
00074 public:
00076 JointPositionLimitsAvoider(int q_dim)
00077 : w_(Eigen::VectorXd::Ones(q_dim)),
00078 q_min_(Eigen::VectorXd::Constant(q_dim, Eigen::NumTraits<double>::lowest())),
00079 q_max_(Eigen::VectorXd::Constant(q_dim, Eigen::NumTraits<double>::highest())),
00080 q_activation_min_(q_min_),
00081 q_activation_max_(q_max_),
00082 q_activation_size_(Eigen::VectorXd::Zero(q_dim)),
00083 smoothing_(0.0)
00084 {
00085 resetJointLimitAvoidance();
00086 }
00087
00092 JointPositionLimitsAvoider& setJointLimits(const Eigen::VectorXd& q_min,
00093 const Eigen::VectorXd& q_max,
00094 double activation_window);
00095
00096 JointPositionLimitsAvoider& setWeights(const Eigen::VectorXd& w)
00097 {
00098 assert(w.size() == w_.size() && "Wrong weight vector size.");
00099 w_ = w;
00100 return *this;
00101 }
00102
00103 Eigen::VectorXd& getWeights() {return w_scaled_;}
00104 const Eigen::VectorXd& getWeights() const {return w_scaled_;}
00105
00106 JointPositionLimitsAvoider& setSmoothing(const double smoothing)
00107 {
00108 assert(smoothing >= 0.0 && smoothing <= 1.0 && "Smoothing should belong to [0, 1].");
00109 smoothing_ = smoothing;
00110 return *this;
00111 }
00112
00113 JointPositionLimitsAvoider& resetJointLimitAvoidance()
00114 {
00115 w_scaling_.setOnes(w_.size());
00116 w_scaling_prev_ = w_scaling_;
00117 w_scaled_ = w_;
00118 return *this;
00119 }
00120
00123 JointPositionLimitsAvoider& applyJointLimitAvoidance(const Eigen::VectorXd& q);
00124
00126 bool isValid(const Eigen::VectorXd& q)
00127 {
00128 typedef Eigen::VectorXd::Index Index;
00129 for(Index i = 0; i < q_min_.size(); ++i)
00130 {
00131 if (q(i) < q_min_(i) || q(i) > q_max_(i)) {return false;}
00132 }
00133 return true;
00134 }
00135
00136 private:
00137 Eigen::VectorXd w_;
00138 Eigen::VectorXd w_scaled_;
00139 Eigen::VectorXd w_scaling_;
00140 Eigen::VectorXd w_scaling_prev_;
00141 Eigen::VectorXd q_min_;
00142 Eigen::VectorXd q_max_;
00143 Eigen::VectorXd q_activation_min_;
00144 Eigen::VectorXd q_activation_max_;
00145 Eigen::VectorXd q_activation_size_;
00146
00149 double smoothing_;
00150 };
00151
00152
00153 class IkSolver
00154 {
00155 public:
00157 enum EndpointCoupling
00158 {
00159 Position = 1,
00160 Orientation = 2,
00161 Pose = Position | Orientation
00162 };
00163
00164 typedef std::vector<std::string> EndpointNameList;
00165 typedef std::vector<EndpointCoupling> EndpointCouplingList;
00166
00167
00168 IkSolver(const KDL::Tree& tree,
00169 const EndpointNameList& endpoint_names,
00170 const EndpointCouplingList& endpoint_couplings);
00171
00173 IkSolver(const KDL::Chain& chain);
00174
00175 virtual ~IkSolver();
00176
00177 bool solve(const KDL::JntArray& q_current,
00178 const std::vector<KDL::Frame>& x_desired,
00179 KDL::JntArray& q_next);
00180
00183 bool solve(const KDL::JntArray& q_current,
00184 const KDL::Frame& x_desired,
00185 KDL::JntArray& q_next);
00186
00187
00188 void setJointPositionLimits(const Eigen::VectorXd& q_min, const Eigen::VectorXd& q_max);
00189 void setMaxDeltaPosTask(double delta_twist_max) {delta_twist_max_ = delta_twist_max;}
00190 void setMaxDeltaPosJoint(double delta_joint_pos_max) {delta_joint_pos_max_ = delta_joint_pos_max;}
00191 void setVelocityIkGain(double velik_gain) {velik_gain_ = velik_gain;}
00192 void setEpsilon(double eps) {eps_ = eps;}
00193 void setMaxIterations(std::size_t max_iter) {max_iter_ = max_iter;}
00194 void setPosture(const KDL::JntArray& q_posture) {q_posture_ = q_posture;}
00195 void setJointSpaceWeights(const Eigen::VectorXd& Wq) {assert(limits_avoider_); limits_avoider_->setWeights(Wq);}
00196 void setTaskSpaceWeights(const Eigen::VectorXd& Wq) {Wx_ = Wq;}
00197
00198 private:
00199 typedef std::vector<std::size_t> CoupledDirections;
00200 typedef KDL::TreeFkSolverPos_recursive FkSolver;
00201 typedef boost::scoped_ptr<FkSolver> FkSolverPtr;
00202 typedef KDL::TreeJntToJacSolver JacSolver;
00203 typedef boost::scoped_ptr<JacSolver> JacSolverPtr;
00204 typedef KDL::MatrixInverter<Eigen::MatrixXd> Inverter;
00205 typedef boost::scoped_ptr<Inverter> InverterPtr;
00206 typedef std::map<std::string, int> JointNameToIndexMap;
00207
00208 FkSolverPtr fk_solver_;
00209 JacSolverPtr jac_solver_;
00210 InverterPtr inverter_;
00211
00212 std::vector<std::string> endpoint_names_;
00213 std::vector<CoupledDirections> coupled_dirs_;
00214 JointNameToIndexMap joint_name_to_idx_;
00215
00216 Eigen::VectorXd delta_twist_;
00217 Eigen::VectorXd delta_q_;
00218 Eigen::VectorXd q_tmp_;
00219
00220 Eigen::MatrixXd jacobian_;
00221 KDL::Jacobian jacobian_tmp_;
00222 Eigen::VectorXd Wx_;
00223
00224
00225 Eigen::MatrixXd nullspace_projector_;
00226 Eigen::MatrixXd identity_qdim_;
00227 KDL::JntArray q_posture_;
00228
00229
00230 double delta_twist_max_;
00231 double delta_joint_pos_max_;
00232 double velik_gain_;
00233 double eps_;
00234 std::size_t max_iter_;
00235
00236 boost::scoped_ptr<JointPositionLimitsAvoider> limits_avoider_;
00237
00238 void init(const KDL::Tree& tree,
00239 const std::vector<std::string>& endpoint_names,
00240 const std::vector<EndpointCoupling>& endpoint_couplings);
00241
00242 void updateDeltaTwist(const KDL::JntArray& q, const std::vector<KDL::Frame>& x_desired);
00243
00244 void updateJacobian(const KDL::JntArray& q);
00245 };
00246
00247 inline void IkSolver::setJointPositionLimits(const Eigen::VectorXd& q_min, const Eigen::VectorXd& q_max)
00248 {
00249 assert(limits_avoider_);
00250 limits_avoider_->setJointLimits(q_min, q_max, 0.2);
00251 }
00252
00253 inline bool IkSolver::solve(const KDL::JntArray& q_current,
00254 const KDL::Frame& x_desired,
00255 KDL::JntArray& q_next)
00256 {
00257 return solve(q_current,
00258 std::vector<KDL::Frame>(1, x_desired),
00259 q_next);
00260 }
00261
00262 }
00263
00264 #endif // REEM_KINEMATICS_IK_SOLVER_