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
00042 #include <ros/ros.h>
00043 #include <boost/format.hpp>
00044 #include <tf/transform_listener.h>
00045 #include <geometry_msgs/PoseStamped.h>
00046 #include <tf_conversions/tf_kdl.h>
00047
00048 #include "manipulation_transforms/manipulation_transforms_ros.h"
00049 #include "manipulation_transforms/util.h"
00050
00051 using namespace std;
00052
00053 ManipulationTransformsROS::ManipulationTransformsROS(const std::string &reference_frame) :
00054 BASE_FRAME_(reference_frame)
00055 {
00056 init_services();
00057 }
00058
00059 ManipulationTransformsROS::ManipulationTransformsROS(const std::string &reference_frame, const std::string &ns) :
00060 BASE_FRAME_(reference_frame)
00061 {
00062 if (ros::isStarted()) {
00063 init_services(ns);
00064
00065
00066 ROS_DEBUG_STREAM("Waiting for transforms under namespace " << param_nh_.getNamespace());
00067 ros::Rate r = ros::Rate(15);
00068 while ( checkForParamServerTransforms(param_nh_, false) < 1 && !ros::isShuttingDown())
00069 r.sleep();
00070
00071
00072
00073
00074 if (loadParamServerTransforms(param_nh_))
00075 ROS_INFO("READY!");
00076 }
00077 }
00078
00079 ManipulationTransformsROS::ManipulationTransformsROS(const std::string &reference_frame,
00080 geometry_msgs::PoseStamped &obj_init_pose,
00081 std::vector<geometry_msgs::PoseStamped> effector_init_poses) :
00082 BASE_FRAME_(reference_frame)
00083 {
00084 ROS_WARN_STREAM_COND(obj_init_pose.header.frame_id != BASE_FRAME_, "frame_id for object_pose should be \""
00085 << BASE_FRAME_ << "\", but it's \"" << obj_init_pose.header.frame_id << "\"");
00086
00087
00088 n_effectors_ = effector_init_poses.size();
00089 ROS_INFO("Initializing with %u effector transforms", n_effectors_);
00090
00091 if (n_effectors_ < 1 ) {
00092 ROS_ERROR("Expected transforms for at least one effector, but got %u", n_effectors_);
00093 ROS_WARN_COND(n_effectors_ != 1 && n_effectors_ != 2, "Querying object pose only supported for 1 or 2 effectors");
00094 }
00095
00096 btTransform bt_object_pose;
00097 tf::poseMsgToTF(obj_init_pose.pose, bt_object_pose);
00098
00099 vector<btTransform> bt_effector_poses;
00100 bt_effector_poses.resize(n_effectors_);
00101
00102 for (unsigned int i = 0; i < n_effectors_; ++i) {
00103 ROS_WARN_STREAM_COND(effector_init_poses[i].header.frame_id != BASE_FRAME_, "frame_id for effector_pose should be \""
00104 << BASE_FRAME_ << "\", but it's \"" << effector_init_poses[i].header.frame_id << "\"");
00105 tf::poseMsgToTF(effector_init_poses[i].pose, bt_effector_poses[i]);
00106 }
00107
00108
00109 solver_.setInitialTransforms(bt_object_pose, bt_effector_poses);
00110 }
00111
00112 ManipulationTransformsROS::~ManipulationTransformsROS(){}
00113
00114 void ManipulationTransformsROS::init_services(const std::string &ns)
00115 {
00116
00117 private_nh_ = ros::NodeHandle("~");
00118
00119
00120 param_nh_ = ros::NodeHandle(ns);
00121
00122
00123 load_initial_transforms_service_ = private_nh_.advertiseService("LoadInitialTransforms", &ManipulationTransformsROS::loadInitialTransforms, this);
00124 set_initial_transforms_service_ = private_nh_.advertiseService("SetInitialTransforms", &ManipulationTransformsROS::setInitialTransforms, this);
00125 effector_poses_to_object_service_ = private_nh_.advertiseService("MapEffectorPosesToObject", &ManipulationTransformsROS::mapEffectorPosesToObject, this);
00126 object_pose_to_effectors_service_ = private_nh_.advertiseService("MapObjectPoseToEffectors", &ManipulationTransformsROS::mapObjectPoseToEffectors, this);
00127 effector_twists_to_object_service_ = private_nh_.advertiseService("MapEffectorTwistsToObject", &ManipulationTransformsROS::mapEffectorTwistsToObject, this);
00128 object_twist_to_effectors_service_ = private_nh_.advertiseService("MapObjectTwistToEffectors", &ManipulationTransformsROS::mapObjectTwistToEffectors, this);
00129 effector_trajectories_to_object_service_ = private_nh_.advertiseService("MapEffectorTrajectoriesToObject", &ManipulationTransformsROS::mapEffectorTrajectoriesToObject, this);
00130 object_trajectory_to_effectors_service_ = private_nh_.advertiseService("MapObjectTrajectoryToEffectors", &ManipulationTransformsROS::mapObjectTrajectoryToEffectors, this);
00131 }
00132
00133 bool ManipulationTransformsROS::setInitialTransforms(manipulation_transforms::SetInitialTransforms::Request &req,
00134 manipulation_transforms::SetInitialTransforms::Response &resp)
00135 {
00136 ROS_WARN_STREAM_COND(req.object_pose.header.frame_id != BASE_FRAME_, "frame_id for object_pose should be \""
00137 << BASE_FRAME_ << "\", but it's \"" << req.object_pose.header.frame_id << "\"");
00138
00139
00140 n_effectors_ = req.effector_poses.size();
00141 ROS_INFO("Initializing with %u effector transforms", n_effectors_);
00142
00143 if (n_effectors_ < 1 ) {
00144 ROS_ERROR("Expected transforms for at least one effector, but got %u", n_effectors_);
00145 ROS_WARN_COND(n_effectors_ != 1 && n_effectors_ != 2, "Querying object pose only supported for 1 or 2 effectors");
00146 resp.success = false;
00147 }
00148
00149 tf::poseMsgToTF(req.object_pose.pose, obj_initial_pose_);
00150
00151 effector_init_poses.resize(n_effectors_);
00152
00153 for (unsigned int i = 0; i < n_effectors_; ++i) {
00154 ROS_WARN_STREAM_COND(req.effector_poses[i].header.frame_id != BASE_FRAME_, "frame_id for effector_pose should be \""
00155 << BASE_FRAME_ << "\", but it's \"" << req.effector_poses[i].header.frame_id << "\"");
00156 tf::poseMsgToTF(req.effector_poses[i].pose, effector_init_poses[i]);
00157 }
00158
00159
00160 solver_.setInitialTransforms(obj_initial_pose_, effector_init_poses);
00161
00162
00163 ROS_DEBUG_STREAM("OBJECT INITIAL POSE: " << manipulation_transforms_util::btTransform_to_string(obj_initial_pose_));
00164 for (unsigned int i = 0; i < n_effectors_; ++i)
00165 ROS_DEBUG_STREAM("EFFECTOR " << i << " INITIAL POSE: " << manipulation_transforms_util::btTransform_to_string(effector_init_poses[i]));
00166
00167 resp.success = true;
00168
00169 return resp.success;
00170 }
00171
00172 bool ManipulationTransformsROS::loadInitialTransforms(manipulation_transforms::LoadInitialTransforms::Request &req,
00173 manipulation_transforms::LoadInitialTransforms::Response &resp)
00174 {
00175
00176 if (req.name == "useprivate") {
00177 resp.success = loadParamServerTransforms(param_nh_);
00178 }
00179 else {
00180 ros::NodeHandle nh(req.name);
00181 resp.success = loadParamServerTransforms(nh);
00182 }
00183
00184 return resp.success;
00185 }
00186
00190 bool ManipulationTransformsROS::mapEffectorPosesToObject(manipulation_transforms::MapEffectorPosesToObject::Request &req,
00191 manipulation_transforms::MapEffectorPosesToObject::Response &resp)
00192 {
00193 if (n_effectors_ != req.effector_poses.size()) {
00194 ROS_ERROR("Expected transforms for %u effectors, but got %lu", n_effectors_, req.effector_poses.size());
00195 }
00196
00197
00198 btTransform bt_object_pose;
00199 vector<btTransform> bt_effector_poses;
00200 bt_effector_poses.resize(n_effectors_);
00201
00202 for (unsigned int i = 0; i < n_effectors_; ++i) {
00203 ROS_WARN_STREAM_COND(req.effector_poses[i].header.frame_id != BASE_FRAME_,
00204 "frame_id for effector pose " << i << " should be \"" << BASE_FRAME_ << "\", but it's \""
00205 << req.effector_poses[i].header.frame_id << "\"");
00206 ROS_DEBUG_STREAM("effector " << i << " query pose: " << req.effector_poses[i].pose);
00207 tf::poseMsgToTF(req.effector_poses[i].pose, bt_effector_poses[i]);
00208 }
00209
00210
00211 resp.error = solver_.mapEffectorPosesToObject(bt_effector_poses, bt_object_pose);
00212
00213
00214 tf::poseTFToMsg(bt_object_pose, resp.object_pose.pose);
00215 resp.object_pose.header.frame_id = BASE_FRAME_;
00216 resp.object_pose.header.stamp = ros::Time::now();
00217
00218 ROS_DEBUG_STREAM("result obj pose: " << resp.object_pose);
00219
00220 return true;
00221 }
00222
00226 bool ManipulationTransformsROS::mapObjectPoseToEffectors(manipulation_transforms::MapObjectPoseToEffectors::Request &req,
00227 manipulation_transforms::MapObjectPoseToEffectors::Response &resp)
00228 {
00229 ROS_WARN_STREAM_COND(req.object_pose.header.frame_id != BASE_FRAME_,
00230 "frame_id for object_pose should be \"" << BASE_FRAME_ << "\", but it's \""
00231 << req.object_pose.header.frame_id << "\"");
00232
00233 ROS_DEBUG_STREAM("obj query pose: " << req.object_pose);
00234
00235
00236 btTransform bt_object_pose;
00237 tf::poseMsgToTF(req.object_pose.pose, bt_object_pose);
00238
00239
00240 vector<btTransform> bt_effector_poses;
00241 bt_effector_poses.resize(n_effectors_);
00242
00243
00244 solver_.mapObjectPoseToEffectors(bt_object_pose, bt_effector_poses);
00245
00246
00247 resp.effector_poses.resize(n_effectors_);
00248 for (unsigned int i = 0; i < n_effectors_; ++i) {
00249 tf::poseTFToMsg(bt_effector_poses[i], resp.effector_poses[i].pose);
00250 resp.effector_poses[i].header.frame_id = BASE_FRAME_;
00251 resp.effector_poses[i].header.stamp = ros::Time::now();
00252
00253 ROS_DEBUG_STREAM("effector " << i << " result pose: " << resp.effector_poses[i]);
00254 }
00255
00256 return true;
00257 }
00258
00262 bool ManipulationTransformsROS::mapEffectorTwistsToObject(manipulation_transforms::MapEffectorTwistsToObject::Request &req,
00263 manipulation_transforms::MapEffectorTwistsToObject::Response &resp)
00264 {
00265 if (n_effectors_ != req.effector_twists.size()) {
00266 ROS_ERROR("Expected transforms for %u effectors, but got %lu", n_effectors_, req.effector_twists.size());
00267 }
00268
00269
00270 KDL::Twist object_twist;
00271 vector<KDL::Twist> effector_twists;
00272 effector_twists.resize(n_effectors_);
00273
00274 for (unsigned int i = 0; i < n_effectors_; ++i) {
00275 ROS_WARN_STREAM_COND(req.effector_twists[i].header.frame_id != BASE_FRAME_,
00276 "frame_id for effector pose " << i << " should be \"" << BASE_FRAME_ << "\", but it's \""
00277 << req.effector_twists[i].header.frame_id << "\"");
00278 ROS_DEBUG_STREAM("effector " << i << " query twist: " << req.effector_twists[i].twist);
00279 tf::TwistMsgToKDL(req.effector_twists[i].twist, effector_twists[i]);
00280 }
00281
00282
00283 resp.error = solver_.mapEffectorTwistsToObject(effector_twists, object_twist);
00284
00285
00286 tf::TwistKDLToMsg(object_twist, resp.object_twist.twist);
00287 resp.object_twist.header.frame_id = BASE_FRAME_;
00288 resp.object_twist.header.stamp = ros::Time::now();
00289
00290 ROS_DEBUG_STREAM("result obj pose: " << resp.object_twist);
00291
00292 return true;
00293 }
00294
00298 bool ManipulationTransformsROS::mapObjectTwistToEffectors(manipulation_transforms::MapObjectTwistToEffectors::Request &req,
00299 manipulation_transforms::MapObjectTwistToEffectors::Response &resp)
00300 {
00301
00302 ROS_WARN_STREAM_COND(req.object_twist.header.frame_id != BASE_FRAME_,
00303 "frame_id for object_pose should be \"" << BASE_FRAME_ << "\", but it's \""
00304 << req.object_twist.header.frame_id << "\"");
00305
00306 ROS_DEBUG_STREAM("obj query pose: " << req.object_twist);
00307
00308
00309 KDL::Twist object_twist;
00310 tf::TwistMsgToKDL(req.object_twist.twist, object_twist);
00311
00312
00313 vector<KDL::Twist> effector_twists;
00314 effector_twists.resize(n_effectors_);
00315
00316
00317 solver_.mapObjectTwistToEffectors(object_twist, effector_twists);
00318
00319
00320 resp.effector_twists.resize(n_effectors_);
00321 for (unsigned int i = 0; i < n_effectors_; ++i) {
00322 tf::TwistKDLToMsg(effector_twists[i], resp.effector_twists[i].twist);
00323 resp.effector_twists[i].header.frame_id = BASE_FRAME_;
00324 resp.effector_twists[i].header.stamp = ros::Time::now();
00325
00326 ROS_DEBUG_STREAM("effector " << i << " result twist: " << resp.effector_twists[i]);
00327 }
00328
00329 return true;
00330 }
00331
00335 bool ManipulationTransformsROS::mapObjectTrajectoryToEffectors(manipulation_transforms::MapObjectTrajectoryToEffectors::Request &req,
00336 manipulation_transforms::MapObjectTrajectoryToEffectors::Response &resp)
00337 {
00338
00339 return true;
00340 }
00341
00345 bool ManipulationTransformsROS::mapEffectorTrajectoriesToObject(manipulation_transforms::MapEffectorTrajectoriesToObject::Request &req,
00346 manipulation_transforms::MapEffectorTrajectoriesToObject::Response &resp)
00347 {
00348
00349 return true;
00350 }
00351
00352 int ManipulationTransformsROS::checkForParamServerTransforms(const ros::NodeHandle &nh, bool warn)
00353 {
00354
00355 bool user_obj_params = false;
00356 user_obj_params |= nh.hasParam("obj_init_pose/position");
00357 user_obj_params |= nh.hasParam("obj_init_pose/orientation");
00358
00359
00360 if (!user_obj_params) {
00361 ROS_WARN_STREAM_COND(warn,
00362 "Could not detect required transform parameters \"obj_init_pose\" under namespace \""
00363 << nh.getNamespace() << "\"");
00364 return -1;
00365 }
00366
00367
00368 int n = 0;
00369 while (nh.hasParam((boost::format("effector%u_init_pose/position") % n).str()) &&
00370 nh.hasParam((boost::format("effector%u_init_pose/orientation") % n).str())) {
00371 n++;
00372 }
00373
00374 return n;
00375 }
00376
00377 bool ManipulationTransformsROS::loadParamServerTransforms(const ros::NodeHandle &nh)
00378 {
00379
00380 if ((n_effectors_ = checkForParamServerTransforms(nh, false)) < 1)
00381 return false;
00382
00383 ROS_WARN_COND(n_effectors_ != 1 && n_effectors_ != 2, "Querying object pose only supported for 1 or 2 effectors");
00384 ROS_INFO("Initializing with %u effector transforms found on the parameter server", n_effectors_);
00385
00386 obj_initial_pose_ = manipulation_transforms_util::readTransformParameter(nh, "obj_init_pose");
00387 effector_init_poses.resize(n_effectors_);
00388
00389 for (unsigned int i = 0; i < n_effectors_; ++i)
00390 effector_init_poses[i] = manipulation_transforms_util::readTransformParameter(nh, (boost::format("effector%u_init_pose") % i).str());
00391
00392
00393 solver_.setInitialTransforms(obj_initial_pose_, effector_init_poses);
00394
00395 ROS_INFO_STREAM("Loaded new obj grasp transforms from namespace \"" << nh.getNamespace() << "\"");
00396 ROS_DEBUG_STREAM("OBJECT INITIAL POSE: " << manipulation_transforms_util::btTransform_to_string(obj_initial_pose_));
00397 for (unsigned int i = 0; i < n_effectors_; ++i)
00398 ROS_DEBUG_STREAM("EFFECTOR " << i << " INITIAL POSE: " << manipulation_transforms_util::btTransform_to_string(effector_init_poses[i]));
00399
00400 return true;
00401 }
00402
00403