kinematic_extension_urdf.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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 /* BEGIN KinematicExtensionURDF ********************************************************************************************/
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     // jacobian matrix for the extension
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;  // joint_type selector: 0.0 -> rot_axis, 1.0 -> lin_axis
00092 
00093         switch (joint.getType())
00094         {
00095             // revolute axis
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             // linear axis
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             // fixed axis
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         // rotation from base_frame of primary chain to base_frame of extension (eb)
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());  // axis wrt eb
00151         Eigen::Vector3d axis_cb = quat_cb * axis_eb;  // transform to cb
00152 
00154         // vector from base_frame of extension (eb) to endeffector (ct)
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;                  // transform to cb
00157         Eigen::Vector3d axis_cross_p_cb = axis_cb.cross(p_cb);  // tangential velocity
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     // scale with extension_ratio
00170     jac_ext *= params_.extension_ratio;
00171 
00172     // combine Jacobian of primary chain and extension
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     // ToDo: Do we need more robust parsing/handling?
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 /* END KinematicExtensionURDF ********************************************************************************************/


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Thu Jun 6 2019 21:19:26