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
00040
00041
00042 #include <pluginlib/class_list_macros.h>
00043 #include <robot_controllers/cartesian_twist.h>
00044
00045 #include <urdf/model.h>
00046 #include <kdl_parser/kdl_parser.hpp>
00047
00048 #include <tf_conversions/tf_kdl.h>
00049
00050 PLUGINLIB_EXPORT_CLASS(robot_controllers::CartesianTwistController, robot_controllers::Controller)
00051
00052 namespace robot_controllers
00053 {
00054 CartesianTwistController::CartesianTwistController() :
00055 initialized_(false),
00056 is_active_(false)
00057 {
00058 }
00059
00060 int CartesianTwistController::init(ros::NodeHandle& nh, ControllerManager* manager)
00061 {
00062
00063 if (!manager)
00064 {
00065 initialized_ = false;
00066 return -1;
00067 }
00068
00069 Controller::init(nh, manager);
00070 manager_ = manager;
00071
00072
00073 std::string tip_link, root_link;
00074 nh.param<std::string>("root_name", root_link, "torso_lift_link");
00075 nh.param<std::string>("tip_name", tip_link, "wrist_roll_link");
00076
00077
00078 urdf::Model model;
00079 if (!model.initParam("robot_description"))
00080 {
00081 ROS_ERROR("Failed to parse URDF");
00082 return -1;
00083 }
00084
00085
00086 KDL::Tree kdl_tree;
00087 if (!kdl_parser::treeFromUrdfModel(model, kdl_tree))
00088 {
00089 ROS_ERROR("Could not construct tree from URDF");
00090 return -1;
00091 }
00092
00093
00094 if (!kdl_tree.getChain(root_link, tip_link, kdl_chain_))
00095 {
00096 ROS_ERROR("Could not construct chain from URDF");
00097 return -1;
00098 }
00099
00100 solver_.reset(new KDL::ChainIkSolverVel_wdls(kdl_chain_));
00101 fksolver_.reset(new KDL::ChainFkSolverPos_recursive(kdl_chain_));
00102 unsigned num_joints = kdl_chain_.getNrOfJoints();
00103 tgt_jnt_pos_.resize(num_joints);
00104 tgt_jnt_vel_.resize(num_joints);
00105 last_tgt_jnt_vel_.resize(num_joints);
00106
00107
00108 joints_.clear();
00109 for (size_t i = 0; i < kdl_chain_.getNrOfSegments(); ++i)
00110 if (kdl_chain_.getSegment(i).getJoint().getType() != KDL::Joint::None)
00111 joints_.push_back(manager_->getJointHandle(kdl_chain_.getSegment(i).getJoint().getName()));
00112
00113 if (joints_.size() != num_joints)
00114 {
00115 ROS_ERROR("Inconsistant joint count %d, %d", num_joints, int(joints_.size()));
00116 return -1;
00117 }
00118
00119 for (unsigned ii = 0; ii < num_joints; ++ii)
00120 {
00121 last_tgt_jnt_vel_(ii) = 0.0;
00122 }
00123
00124
00125 command_sub_ = nh.subscribe<geometry_msgs::TwistStamped>("command", 1,
00126 boost::bind(&CartesianTwistController::command, this, _1));
00127 last_command_time_ = ros::Time(0);
00128
00129 initialized_ = true;
00130 return 0;
00131 }
00132
00133 bool CartesianTwistController::start()
00134 {
00135 if (!initialized_)
00136 {
00137 ROS_ERROR_NAMED("CartesianTwistController",
00138 "Unable to start, not initialized.");
00139 is_active_ = false;
00140 return false;
00141 }
00142
00143 for (unsigned ii = 0; ii < joints_.size(); ++ii)
00144 {
00145 last_tgt_jnt_vel_(ii) = joints_[ii]->getVelocity();
00146 tgt_jnt_pos_(ii) = joints_[ii]->getPosition();
00147 }
00148 is_active_ = true;
00149 return true;
00150 }
00151
00152 bool CartesianTwistController::stop(bool force)
00153 {
00154 is_active_ = false;
00155 return true;
00156 }
00157
00158 bool CartesianTwistController::reset()
00159 {
00160
00161 return (manager_->requestStop(getName()) == 0);
00162 }
00163
00164 void CartesianTwistController::update(const ros::Time& now, const ros::Duration& dt)
00165 {
00166
00167 if (!initialized_)
00168 return;
00169
00170 KDL::Frame cart_pose;
00171
00172 KDL::Twist twist;
00173 ros::Time last_command_time;
00174 {
00175 boost::mutex::scoped_lock lock(mutex_);
00176
00177 if (fksolver_->JntToCart(tgt_jnt_pos_, cart_pose) < 0)
00178 {
00179 twist.Zero();
00180 ROS_ERROR_THROTTLE(1.0, "FKsolver solver failed");
00181 }
00182 else
00183 {
00184 if (twist_command_frame_ == "end_effector_frame")
00185 {
00186 twist = cart_pose.M*twist_command_;
00187 }
00188 else
00189 {
00190 twist = twist_command_;
00191 }
00192 }
00193 last_command_time = last_command_time_;
00194 }
00195
00196 unsigned num_joints = joints_.size();
00197
00198 if ((now - last_command_time) > ros::Duration(0.5))
00199 {
00200 manager_->requestStop(getName());
00201 }
00202
00203
00204 if (solver_->CartToJnt(tgt_jnt_pos_, twist, tgt_jnt_vel_) < 0)
00205 {
00206 for (unsigned ii = 0; ii < num_joints; ++ii)
00207 {
00208 tgt_jnt_vel_(ii) = 0.0;
00209 }
00210 }
00211
00212
00213 double max_vel = 0.0;
00214 for (unsigned ii = 0; ii < num_joints; ++ii)
00215 {
00216 max_vel = std::max(std::abs(tgt_jnt_vel_(ii)), max_vel);
00217 }
00218
00219 double joint_velocity_limit = 0.5;
00220 double scale = 1.0;
00221 if (max_vel > joint_velocity_limit)
00222 {
00223 double scale = joint_velocity_limit / max_vel;
00224 for (unsigned ii = 0; ii < num_joints; ++ii)
00225 {
00226 tgt_jnt_vel_(ii) *= scale;
00227 }
00228 ROS_DEBUG_THROTTLE(1.0, "Joint velocity limit reached.");
00229 }
00230
00231
00232 for (unsigned ii = 0; ii < num_joints; ++ii)
00233 {
00234 if (!std::isfinite(tgt_jnt_vel_(ii)))
00235 {
00236 ROS_ERROR_THROTTLE(1.0, "Target joint velocity (%d) is not finite : %f", ii, tgt_jnt_vel_(ii));
00237 tgt_jnt_vel_(ii) = 1.0;
00238 }
00239 }
00240
00241
00242
00243 scale = 1.0;
00244 double accel_limit = 1.0;
00245 double vel_delta_limit = accel_limit * dt.toSec();
00246 for (unsigned ii = 0; ii < num_joints; ++ii)
00247 {
00248 double vel_delta = std::abs(tgt_jnt_vel_(ii) - last_tgt_jnt_vel_(ii));
00249 if (vel_delta > vel_delta_limit)
00250 {
00251 scale = std::min(scale, vel_delta_limit/vel_delta);
00252 }
00253 }
00254
00255 if (scale <= 0.0)
00256 {
00257 ROS_ERROR_THROTTLE(1.0, "CartesianTwistController: acceleration limit produces non-positive scale %f", scale);
00258 scale = 0.0;
00259 }
00260
00261
00262
00263
00264 for (unsigned ii = 0; ii < num_joints; ++ii)
00265 {
00266 tgt_jnt_vel_(ii) = (tgt_jnt_vel_(ii) - last_tgt_jnt_vel_(ii))*scale + last_tgt_jnt_vel_(ii);
00267 }
00268
00269
00270 double dt_sec = dt.toSec();
00271 for (unsigned ii = 0; ii < num_joints; ++ii)
00272 {
00273 tgt_jnt_pos_(ii) += tgt_jnt_vel_(ii) * dt_sec;
00274 }
00275
00276
00277 for (unsigned ii = 0; ii < num_joints; ++ii)
00278 {
00279 if (!joints_[ii]->isContinuous())
00280 {
00281 if (tgt_jnt_pos_(ii) > joints_[ii]->getPositionMax())
00282 {
00283 tgt_jnt_pos_(ii) = joints_[ii]->getPositionMax();
00284 }
00285 else if (tgt_jnt_pos_(ii) < joints_[ii]->getPositionMin())
00286 {
00287 tgt_jnt_pos_(ii) = joints_[ii]->getPositionMin();
00288 }
00289 }
00290 }
00291
00292
00293 for (size_t ii = 0; ii < joints_.size(); ++ii)
00294 {
00295 joints_[ii]->setPosition(tgt_jnt_pos_(ii), tgt_jnt_vel_(ii), 0.0);
00296 last_tgt_jnt_vel_(ii) = tgt_jnt_vel_(ii);
00297 }
00298 }
00299
00300 void CartesianTwistController::command(const geometry_msgs::TwistStamped::ConstPtr& goal)
00301 {
00302
00303 if (!initialized_)
00304 {
00305 ROS_ERROR("CartesianTwistController: Cannot accept goal, controller is not initialized.");
00306 return;
00307 }
00308
00309 if (goal->header.frame_id.empty())
00310 {
00311 manager_->requestStop(getName());
00312 return;
00313 }
00314
00315 KDL::Twist twist;
00316 twist(0) = goal->twist.linear.x;
00317 twist(1) = goal->twist.linear.y;
00318 twist(2) = goal->twist.linear.z;
00319 twist(3) = goal->twist.angular.x;
00320 twist(4) = goal->twist.angular.y;
00321 twist(5) = goal->twist.angular.z;
00322
00323 for (int ii=0; ii<6; ++ii)
00324 {
00325 if (!std::isfinite(twist(ii)))
00326 {
00327 ROS_ERROR_THROTTLE(1.0, "Twist command value (%d) is not finite : %f", ii, twist(ii));
00328 twist(ii) = 0.0;
00329 }
00330 }
00331
00332 ros::Time now(ros::Time::now());
00333
00334 {
00335 boost::mutex::scoped_lock lock(mutex_);
00336 twist_command_frame_ = goal->header.frame_id;
00337 twist_command_ = twist;
00338 last_command_time_ = now;
00339 }
00340
00341 if (!is_active_ && manager_->requestStart(getName()) != 0)
00342 {
00343 ROS_ERROR("CartesianTwistController: Cannot start, blocked by another controller.");
00344 return;
00345 }
00346 }
00347
00348 std::vector<std::string> CartesianTwistController::getCommandedNames()
00349 {
00350 std::vector<std::string> names;
00351 if (initialized_)
00352 {
00353 for (size_t i = 0; i < kdl_chain_.getNrOfSegments(); ++i)
00354 if (kdl_chain_.getSegment(i).getJoint().getType() != KDL::Joint::None)
00355 names.push_back(kdl_chain_.getSegment(i).getJoint().getName());
00356 }
00357 return names;
00358 }
00359
00360 std::vector<std::string> CartesianTwistController::getClaimedNames()
00361 {
00362 return getCommandedNames();
00363 }
00364
00365 }