cartesian_controller.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  *  Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, Johannes Maurer
00006  *                      Institute for Software Technology,
00007  *                      Graz University of Technology
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of Graz University of Technology nor the names of
00021  *     its contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  *********************************************************************/
00038 
00039 #include <tedusar_cartesian_controller/cartesian_controller.hpp>
00040 #include <pluginlib/class_list_macros.h>
00041 #include <kdl_parser/kdl_parser.hpp>
00042 
00043 PLUGINLIB_EXPORT_CLASS(velocity_controllers::CartesianController, controller_interface::ControllerBase)
00044 
00045 namespace velocity_controllers
00046 {
00047 
00048     bool CartesianController::init(hardware_interface::VelocityJointInterface* hw, ros::NodeHandle &nh)
00049     {
00050         std::string robot_description;
00051 
00052         if(!nh.searchParam("robot_description", robot_description))
00053         {
00054             ROS_ERROR("Failed to get robot_description parameter");
00055             return false;
00056         }
00057 
00058         if (!nh.getParam("root_name", root_name_))
00059         {
00060             ROS_ERROR("Failed to get root_name parameter");
00061             return false;
00062         }
00063 
00064         if (!nh.getParam("tip_name", tip_name_))
00065         {
00066             ROS_ERROR("Failed to get tip_name parameter");
00067             return false;
00068         }
00069 
00070 
00071         if (!kdl_parser::treeFromParam(robot_description, kdl_tree_)){
00072             ROS_ERROR("Failed to construct kdl tree from robot description parameter");
00073             return false;
00074         }
00075 
00076         // Populate the KDL chain
00077         if(!kdl_tree_.getChain(root_name_, tip_name_, kdl_chain_))
00078         {
00079             ROS_ERROR_STREAM("Failed to get KDL chain from tree.");
00080             return false;
00081         }
00082 
00083         // Get joint handles for all of the joints in the chain
00084         for(std::vector<KDL::Segment>::const_iterator it = kdl_chain_.segments.begin(); it != kdl_chain_.segments.end(); ++it)
00085         {
00086             joint_handles_.push_back(hw->getHandle(it->getJoint().getName()));
00087         }
00088 
00089         chain_ik_solver_vel_.reset(new KDL::ChainIkSolverVel_pinv(kdl_chain_));
00090         chain_fk_solver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00091 
00092         vel_cmd_sub_ = nh.subscribe<geometry_msgs::TwistStamped>("arm_cmd_vel", 1, &CartesianController::velCmdCB, this);
00093 
00094         double dead_man_timeout;
00095         nh.param<double>("dead_man_timeout", dead_man_timeout, 0.2);
00096         dead_man_timeout_ = ros::Duration(dead_man_timeout);
00097 
00098         nh.param<double>("joint_vel_limit", joint_vel_limit_, 0.3);
00099 
00100         return true;
00101     }
00102 
00103     void CartesianController::update(const ros::Time& time, const ros::Duration& period)
00104     {
00105         if(got_msg_)
00106         {
00107 
00108             if((time - last_msg_) >= dead_man_timeout_)
00109             {
00110                 cmd_linear_twist_[0] = 0.0;
00111                 cmd_linear_twist_[1] = 0.0;
00112                 cmd_linear_twist_[2] = 0.0;
00113                 cmd_linear_twist_[3] = 0.0;
00114                 cmd_linear_twist_[4] = 0.0;
00115                 cmd_linear_twist_[5] = 0.0;
00116 
00117                 cmd_angular_twist_[0] = 0.0;
00118                 cmd_angular_twist_[1] = 0.0;
00119                 cmd_angular_twist_[2] = 0.0;
00120                 cmd_angular_twist_[3] = 0.0;
00121                 cmd_angular_twist_[4] = 0.0;
00122                 cmd_angular_twist_[5] = 0.0;
00123 
00124                 got_msg_ = false;
00125 
00126                 for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00127                 {
00128                     joint_handles_[i].setCommand(0.0);
00129                 }
00130 
00131                 return;
00132             }
00133 
00134             // get joint positions
00135             KDL::JntArray  q(joint_handles_.size());
00136             for(size_t i=0; i<joint_handles_.size(); i++)
00137             {
00138                 q(i) = joint_handles_[i].getPosition();
00139             }
00140 
00141             KDL::Frame frame_tip_pose;
00142 
00143             if(chain_fk_solver_->JntToCart(q, frame_tip_pose) < 0)
00144             {
00145                 ROS_ERROR("Unable to compute forward kinematic.");
00146 
00147                 for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00148                 {
00149                     joint_handles_[i].setCommand(0.0);
00150                 }
00151 
00152                 return;
00153             }
00154 
00155             KDL::Frame frame_tip_pose_inv = frame_tip_pose.Inverse();
00156 
00157             KDL::Twist linear_twist = frame_tip_pose_inv * cmd_linear_twist_;
00158             KDL::Twist angular_twist = frame_tip_pose_inv.M * cmd_angular_twist_;
00159 
00160             KDL::Twist twist(linear_twist.vel, angular_twist.rot);
00161 
00162             KDL::JntArray joint_vel(joint_handles_.size());
00163             if(chain_ik_solver_vel_->CartToJnt(q, twist, joint_vel) < 0)
00164             {
00165                 ROS_ERROR("Unable to compute cartesian to joint velocity.");
00166 
00167                 for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00168                 {
00169                     joint_handles_[i].setCommand(0.0);
00170                 }
00171 
00172                 return;
00173             }
00174 
00175 
00176             double max_joint_vel = 0.0;
00177             for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00178             {
00179                 max_joint_vel = std::max(std::fabs(joint_vel(i)),max_joint_vel);
00180             }
00181 
00182             if(max_joint_vel > joint_vel_limit_)
00183             {
00184                 double factor = joint_vel_limit_ / max_joint_vel;
00185                 for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00186                 {
00187                     joint_vel(i) = joint_vel(i) * factor;
00188                 }
00189             }
00190 
00191             // Convert the wrench into joint efforts
00192             for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00193             {
00194                 joint_handles_[i].setCommand(joint_vel(i));
00195             }
00196 
00197 
00198         }
00199         else
00200         {
00201             for (unsigned int i = 0; i < kdl_chain_.getNrOfJoints(); i++)
00202             {
00203                 joint_handles_[i].setCommand(0.0);
00204             }
00205 
00206         }
00207 
00208     }
00209 
00210     void CartesianController::starting(const ros::Time& time)
00211     {
00212         cmd_linear_twist_[0] = 0.0;
00213         cmd_linear_twist_[1] = 0.0;
00214         cmd_linear_twist_[2] = 0.0;
00215         cmd_linear_twist_[3] = 0.0;
00216         cmd_linear_twist_[4] = 0.0;
00217         cmd_linear_twist_[5] = 0.0;
00218 
00219         cmd_angular_twist_[0] = 0.0;
00220         cmd_angular_twist_[1] = 0.0;
00221         cmd_angular_twist_[2] = 0.0;
00222         cmd_angular_twist_[3] = 0.0;
00223         cmd_angular_twist_[4] = 0.0;
00224         cmd_angular_twist_[5] = 0.0;
00225 
00226         last_msg_ = ros::Time::now();
00227         got_msg_ = false;
00228     }
00229 
00230     void CartesianController::stopping(const ros::Time& time)
00231     {
00232 
00233     }
00234 
00235     void CartesianController::velCmdCB(const geometry_msgs::TwistStampedConstPtr& msg)
00236     {
00237         cmd_linear_twist_.vel(0) = msg->twist.linear.x;
00238         cmd_linear_twist_.vel(1) = msg->twist.linear.y;
00239         cmd_linear_twist_.vel(2) = msg->twist.linear.z;
00240         cmd_linear_twist_.rot(0) = 0.0;
00241         cmd_linear_twist_.rot(1) = 0.0;
00242         cmd_linear_twist_.rot(2) = 0.0;
00243 
00244         cmd_angular_twist_.vel(0) = 0.0;
00245         cmd_angular_twist_.vel(1) = 0.0;
00246         cmd_angular_twist_.vel(2) = 0.0;
00247         cmd_angular_twist_.rot(0) = msg->twist.angular.x;
00248         cmd_angular_twist_.rot(1) = msg->twist.angular.y;
00249         cmd_angular_twist_.rot(2) = msg->twist.angular.z;
00250 
00251         last_msg_ = ros::Time::now();
00252         got_msg_ = true;
00253 
00254     }
00255 
00256 }


tedusar_cartesian_controller
Author(s): Johannes Maurer , Alexander Buchegger
autogenerated on Wed Aug 26 2015 16:30:39