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 
00035 
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         
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         
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             
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             
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 }