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 #include <string>
00019 #include <limits>
00020 #include <eigen_conversions/eigen_kdl.h>
00021 #include "cob_twist_controller/kinematic_extensions/kinematic_extension_urdf.h"
00022
00023
00024 bool KinematicExtensionURDF::initExtension()
00025 {
00027 KDL::Tree tree;
00028 if (!kdl_parser::treeFromParam("robot_description", tree))
00029 {
00030 ROS_ERROR("Failed to construct kdl tree");
00031 return false;
00032 }
00033
00034 tree.getChain(ext_base_, ext_tip_, chain_);
00035 if (chain_.getNrOfJoints() == 0)
00036 {
00037 ROS_ERROR("Failed to initialize kinematic chain");
00038 return false;
00039 }
00040
00041 for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
00042 {
00043 ROS_DEBUG_STREAM("Segment[" << i << "] Name : " << chain_.getSegment(i).getName());
00044 ROS_DEBUG_STREAM("Joint[" << i << "] Name: " << chain_.getSegment(i).getJoint().getName());
00045 ROS_DEBUG_STREAM("Joint[" << i << "] Type: " << chain_.getSegment(i).getJoint().getTypeName());
00046 if (chain_.getSegment(i).getJoint().getType() != KDL::Joint::None)
00047 {
00048 ROS_DEBUG_STREAM("Adding Joint " << chain_.getSegment(i).getJoint().getName());
00049 joint_names_.push_back(chain_.getSegment(i).getJoint().getName());
00050 }
00051 }
00052 this->ext_dof_ = chain_.getNrOfJoints();
00053 this->joint_states_.last_q_.resize(ext_dof_);
00054 this->joint_states_.last_q_dot_.resize(ext_dof_);
00055 this->joint_states_.current_q_.resize(ext_dof_);
00056 this->joint_states_.current_q_dot_.resize(ext_dof_);
00057
00059 urdf::Model model;
00060 if (!model.initParam("/robot_description"))
00061 {
00062 ROS_ERROR("Failed to parse urdf file for JointLimits");
00063 return false;
00064 }
00065
00066 for (unsigned int i = 0; i < ext_dof_; i++)
00067 {
00068 limits_max_.push_back(model.getJoint(joint_names_[i])->limits->upper);
00069 limits_min_.push_back(model.getJoint(joint_names_[i])->limits->lower);
00070 limits_vel_.push_back(model.getJoint(joint_names_[i])->limits->velocity);
00071 limits_acc_.push_back(std::numeric_limits<double>::max());
00072 }
00073
00074 return true;
00075 }
00076
00077 KDL::Jacobian KinematicExtensionURDF::adjustJacobian(const KDL::Jacobian& jac_chain)
00078 {
00080 KDL::Jacobian jac_full;
00081
00082
00083 Eigen::Matrix<double, 6, Eigen::Dynamic> jac_ext;
00084 jac_ext.resize(6, ext_dof_);
00085 jac_ext.setZero();
00086
00087 unsigned int k = 0;
00088 for (unsigned int i = 0; i < chain_.getNrOfSegments(); i++)
00089 {
00090 KDL::Joint joint = chain_.getSegment(i).getJoint();
00091 double eps_type = -1.0;
00092
00093 switch (joint.getType())
00094 {
00095
00096 case KDL::Joint::RotAxis:
00097 case KDL::Joint::RotX:
00098 case KDL::Joint::RotY:
00099 case KDL::Joint::RotZ:
00100 eps_type = 0.0;
00101 break;
00102
00103 case KDL::Joint::TransAxis:
00104 case KDL::Joint::TransX:
00105 case KDL::Joint::TransY:
00106 case KDL::Joint::TransZ:
00107 eps_type = 1.0;
00108 break;
00109
00110 case KDL::Joint::None:
00111 default:
00112 break;
00113 }
00114
00115 if (eps_type < 0.0)
00116 {
00117 ROS_DEBUG_STREAM("Not considering " << joint.getName() << " in jac_ext");
00118 continue;
00119 }
00120
00122 tf::StampedTransform eb_transform_ct, cb_transform_eb;
00123 KDL::Frame eb_frame_ct, cb_frame_eb;
00124 try
00125 {
00126 ros::Time now = ros::Time::now();
00127 tf_listener_.waitForTransform(chain_.getSegment(i).getName(), params_.chain_tip_link, now, ros::Duration(0.5));
00128 tf_listener_.lookupTransform(chain_.getSegment(i).getName(), params_.chain_tip_link, now, eb_transform_ct);
00129
00130 tf_listener_.waitForTransform(params_.chain_base_link, chain_.getSegment(i).getName(), now, ros::Duration(0.5));
00131 tf_listener_.lookupTransform(params_.chain_base_link, chain_.getSegment(i).getName(), now, cb_transform_eb);
00132 }
00133 catch (tf::TransformException& ex)
00134 {
00135 ROS_ERROR("%s", ex.what());
00136 }
00137
00138 eb_frame_ct.p = KDL::Vector(eb_transform_ct.getOrigin().x(), eb_transform_ct.getOrigin().y(), eb_transform_ct.getOrigin().z());
00139 eb_frame_ct.M = KDL::Rotation::Quaternion(eb_transform_ct.getRotation().x(), eb_transform_ct.getRotation().y(), eb_transform_ct.getRotation().z(), eb_transform_ct.getRotation().w());
00140
00141 cb_frame_eb.p = KDL::Vector(cb_transform_eb.getOrigin().x(), cb_transform_eb.getOrigin().y(), cb_transform_eb.getOrigin().z());
00142 cb_frame_eb.M = KDL::Rotation::Quaternion(cb_transform_eb.getRotation().x(), cb_transform_eb.getRotation().y(), cb_transform_eb.getRotation().z(), cb_transform_eb.getRotation().w());
00143
00144
00145 Eigen::Quaterniond quat_cb;
00146 tf::quaternionKDLToEigen(cb_frame_eb.M, quat_cb);
00147 Eigen::Matrix3d rot_cb = quat_cb.toRotationMatrix();
00148
00150 Eigen::Vector3d axis_eb(joint.JointAxis().x(), joint.JointAxis().y(), joint.JointAxis().z());
00151 Eigen::Vector3d axis_cb = quat_cb * axis_eb;
00152
00154
00155 Eigen::Vector3d p_eb(eb_frame_ct.p.x(), eb_frame_ct.p.y(), eb_frame_ct.p.z());
00156 Eigen::Vector3d p_cb = quat_cb * p_eb;
00157 Eigen::Vector3d axis_cross_p_cb = axis_cb.cross(p_cb);
00158
00160 jac_ext(0, k) = eps_type * axis_cb(0) + (1.0 - eps_type) * axis_cross_p_cb(0);
00161 jac_ext(1, k) = eps_type * axis_cb(0) + (1.0 - eps_type) * axis_cross_p_cb(1);
00162 jac_ext(2, k) = eps_type * axis_cb(0) + (1.0 - eps_type) * axis_cross_p_cb(2);
00163 jac_ext(3, k) = eps_type * 0.0 + (1.0 - eps_type) * axis_cb(0);
00164 jac_ext(4, k) = eps_type * 0.0 + (1.0 - eps_type) * axis_cb(1);
00165 jac_ext(5, k) = eps_type * 0.0 + (1.0 - eps_type) * axis_cb(2);
00166 k++;
00167 }
00168
00169
00170 jac_ext *= params_.extension_ratio;
00171
00172
00173 Matrix6Xd_t jac_full_matrix;
00174 jac_full_matrix.resize(6, jac_chain.data.cols() + jac_ext.cols());
00175 jac_full_matrix << jac_chain.data, jac_ext;
00176 jac_full.resize(jac_chain.data.cols() + jac_ext.cols());
00177 jac_full.data << jac_full_matrix;
00178
00179 return jac_full;
00180 }
00181
00182 JointStates KinematicExtensionURDF::adjustJointStates(const JointStates& joint_states)
00183 {
00184 JointStates js;
00185 unsigned int chain_dof = joint_states.current_q_.rows();
00186 js.current_q_.resize(chain_dof + ext_dof_);
00187 js.last_q_.resize(chain_dof + ext_dof_);
00188 js.current_q_dot_.resize(chain_dof + ext_dof_);
00189 js.last_q_dot_.resize(chain_dof + ext_dof_);
00190
00191 for (unsigned int i = 0; i< chain_dof; i++)
00192 {
00193 js.current_q_(i) = joint_states.current_q_(i);
00194 js.last_q_(i) = joint_states.last_q_(i);
00195 js.current_q_dot_(i) = joint_states.current_q_dot_(i);
00196 js.last_q_dot_(i) = joint_states.last_q_dot_(i);
00197 }
00198 for (unsigned int i = 0; i < ext_dof_; i++)
00199 {
00200 js.current_q_(chain_dof + i) = this->joint_states_.current_q_(i);
00201 js.last_q_(chain_dof + i) = this->joint_states_.last_q_(i);
00202 js.current_q_dot_(chain_dof + i) = this->joint_states_.current_q_dot_(i);
00203 js.last_q_dot_(chain_dof + i) = this->joint_states_.last_q_dot_(i);
00204 }
00205
00206 return js;
00207 }
00208
00209 LimiterParams KinematicExtensionURDF::adjustLimiterParams(const LimiterParams& limiter_params)
00210 {
00211 LimiterParams lp = limiter_params;
00212 for (unsigned int i = 0; i < ext_dof_; i++)
00213 {
00214 lp.limits_max.push_back(limits_max_[i]);
00215 lp.limits_min.push_back(limits_min_[i]);
00216 lp.limits_vel.push_back(limits_vel_[i]);
00217 lp.limits_acc.push_back(limits_acc_[i]);
00218 }
00219 return lp;
00220 }
00221
00222 void KinematicExtensionURDF::processResultExtension(const KDL::JntArray& q_dot_ik)
00223 {
00224 std_msgs::Float64MultiArray command_msg;
00225
00226 for (unsigned int i = 0; i < ext_dof_; i++)
00227 {
00228 command_msg.data.push_back(q_dot_ik(params_.dof+i));
00229 }
00230
00231 command_pub_.publish(command_msg);
00232 }
00233
00234 void KinematicExtensionURDF::jointstateCallback(const sensor_msgs::JointState::ConstPtr& msg)
00235 {
00236 KDL::JntArray q_temp = this->joint_states_.current_q_;
00237 KDL::JntArray q_dot_temp = this->joint_states_.current_q_dot_;
00238
00239
00240 for (unsigned int i = 0; i < ext_dof_; i++)
00241 {
00242 q_temp(i) = msg->position[i];
00243 q_dot_temp(i) = msg->velocity[i];
00244 }
00245
00246 this->joint_states_.last_q_ = joint_states_.current_q_;
00247 this->joint_states_.last_q_dot_ = joint_states_.current_q_dot_;
00248 this->joint_states_.current_q_ = q_temp;
00249 this->joint_states_.current_q_dot_ = q_dot_temp;
00250 }
00251