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 }