00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <mtconnect_cnc_robot_example/utilities/utilities.h>
00018 #include <mtconnect_task_parser/task_parser.h>
00019 #include <boost/tuple/tuple.hpp>
00020 #include "boost/make_shared.hpp"
00021
00022 using namespace move_arm_utils;
00023
00024 bool move_arm_utils::parsePoint(XmlRpc::XmlRpcValue &pointVal, geometry_msgs::Point &point)
00025 {
00026
00027 point.x = static_cast<double>(pointVal["x"]);
00028 point.y = static_cast<double>(pointVal["y"]);
00029 point.z = static_cast<double>(pointVal["z"]);
00030 return true;
00031 }
00032
00033 bool move_arm_utils::parseOrientation(XmlRpc::XmlRpcValue &val, tf::Quaternion &q)
00034 {
00035 double angle;
00036 tf::Vector3 axis;
00037
00038
00039 angle = static_cast<double>(val["angle"]);
00040 parseVect3(val["axis"], axis);
00041 q.setRotation(axis, angle);
00042 return true;
00043 }
00044
00045 bool move_arm_utils::parseOrientation(XmlRpc::XmlRpcValue &val, geometry_msgs::Quaternion &q)
00046 {
00047 tf::Quaternion q_tf;
00048
00049 if (!parseOrientation(val, q_tf))
00050 {
00051 return false;
00052 }
00053
00054 tf::quaternionTFToMsg(q_tf, q);
00055 return true;
00056 }
00057
00058 bool move_arm_utils::parseVect3(XmlRpc::XmlRpcValue &val, geometry_msgs::Vector3 &v)
00059 {
00060 tf::Vector3 vect;
00061 parseVect3(val, vect);
00062 tf::vector3TFToMsg(vect, v);
00063 return true;
00064 }
00065
00066 bool move_arm_utils::parseVect3(XmlRpc::XmlRpcValue &vectVal, tf::Vector3 &v)
00067 {
00068 double val;
00069 val = static_cast<double>(vectVal["x"]);
00070 v.setX(val);
00071 val = static_cast<double>(vectVal["y"]);
00072 v.setY(val);
00073 val = static_cast<double>(vectVal["z"]);
00074 v.setZ(val);
00075 return true;
00076 }
00077
00078 bool move_arm_utils::parsePose(XmlRpc::XmlRpcValue &val, geometry_msgs::Pose &pose)
00079 {
00080
00081 if (parsePoint(val["position"], pose.position) && parseOrientation(val["orientation"], pose.orientation))
00082 {
00083 return true;
00084 }
00085 else
00086 {
00087 return false;
00088 }
00089 }
00090
00091 bool move_arm_utils::parseTransform(XmlRpc::XmlRpcValue &val, tf::Transform &t)
00092 {
00093 geometry_msgs::Pose p;
00094
00095 if (!parsePose(val, p))
00096 {
00097 return false;
00098 }
00099
00100 tf::poseMsgToTF(p, t);
00101 return true;
00102 }
00103
00104 bool move_arm_utils::parseTaskXml(const std::string & xml,
00105 std::map<std::string, trajectory_msgs::JointTrajectoryPtr> & paths)
00106 {
00107 typedef std::map<std::string, boost::shared_ptr<mtconnect::Path> >::iterator PathMapIter;
00108 bool rtn;
00109
00110 mtconnect::Task task;
00111
00112 if (mtconnect::fromXml(task, xml))
00113 {
00114 for (PathMapIter iter = task.paths_.begin(); iter != task.paths_.end(); ++iter)
00115 {
00116 trajectory_msgs::JointTrajectoryPtr jt(new trajectory_msgs::JointTrajectory());
00117
00118 if (toJointTrajectory(iter->second, jt))
00119 {
00120 paths[iter->first] = jt;
00121 ROS_INFO_STREAM("Converted path: " << iter->first << " to joint trajectory");
00122 rtn = true;
00123 }
00124 else
00125 {
00126 ROS_ERROR_STREAM("Failed to convert path: " << iter->first << " to joint trajectory");
00127 rtn = false;
00128 break;
00129 }
00130
00131 }
00132 ROS_INFO_STREAM("Converted " << task.paths_.size() << " paths to "
00133 << paths.size() << " joint paths");
00134 }
00135 else
00136 {
00137 ROS_ERROR("Failed to parse task xml string");
00138 rtn = false;
00139 }
00140
00141 return rtn;
00142
00143 }
00144
00145 bool move_arm_utils::toJointTrajectory(boost::shared_ptr<mtconnect::Path> & path,
00146 trajectory_msgs::JointTrajectoryPtr & traj)
00147 {
00148 typedef std::vector<mtconnect::JointMove>::iterator JointMovesIter;
00149
00150
00151
00152 traj->joint_names = path->moves_.front().point_->group_->joint_names_;
00153 traj->points.clear();
00154 for (JointMovesIter iter = path->moves_.begin(); iter != path->moves_.end(); iter++)
00155 {
00156 ROS_INFO("Converting point to joint trajectory point");
00157 trajectory_msgs::JointTrajectoryPoint jt_point;
00158 jt_point.positions = iter->point_->values_;
00159 traj->points.push_back(jt_point);
00160 ROS_INFO_STREAM("Added point to trajectory, new size: " << traj->points.size());
00161
00162 }
00163 return true;
00164 }
00165
00166 std::string CartesianTrajectory::toString()
00167 {
00168 std::stringstream ss;
00169 ss << "\n";
00170 ss << "arm_group: " << arm_group_ << "\n";
00171 ss << "frame_id: " << frame_id_ << "\n";
00172 ss << "tool_name: " << link_name_ << "\n";
00173 ss << "via points: " << "transform array with " << cartesian_points_.size() << " elements" << "\n";
00174 tf::Vector3 pos;
00175 tf::Quaternion q;
00176 for (std::size_t i = 0; i < cartesian_points_.size(); i++)
00177 {
00178 tf::Transform &t = cartesian_points_[i];
00179 pos = t.getOrigin();
00180 q = t.getRotation();
00181
00182 ss << "\t - pos:[ " << pos.getX() << ", " << pos.getY() << ", " << pos.getZ() << "]\n";
00183 ss << "\t axis:[ " << q.getAxis().getX() << ", " << q.getAxis().getY() << ", " << q.getAxis().getZ()
00184 << "], angle: " << q.getAngle() << "\n";
00185 }
00186
00187 return ss.str();
00188 }
00189
00190 bool CartesianTrajectory::parseParameters(XmlRpc::XmlRpcValue ¶mVal)
00191 {
00192 XmlRpc::XmlRpcValue cartesian_points_param;
00193 ros::NodeHandle nh;
00194
00195 bool success = true;
00196 if (paramVal.getType() == XmlRpc::XmlRpcValue::TypeStruct)
00197 {
00198
00199 arm_group_ = static_cast<std::string>(paramVal["arm_group"]);
00200 frame_id_ = static_cast<std::string>(paramVal["frame_id"]);
00201 link_name_ = static_cast<std::string>(paramVal["tool_name"]);
00202
00203
00204 cartesian_points_param = paramVal["via_points"];
00205
00206
00207 if ((cartesian_points_param.getType() == XmlRpc::XmlRpcValue::TypeArray)
00208 && (cartesian_points_param[0].getType() == XmlRpc::XmlRpcValue::TypeStruct))
00209 {
00210 tf::Transform t;
00211
00212 ROS_INFO_STREAM("Parsing via points struct array"<<toString());
00213 cartesian_points_.clear();
00214 for (int i = 0; i < cartesian_points_param.size(); i++)
00215 {
00216
00217 if (!parseTransform(cartesian_points_param[i], t))
00218 {
00219
00220 ROS_ERROR_STREAM("Parsing error in cartesian_trajectory point");
00221 success = false;
00222 break;
00223 }
00224
00225 cartesian_points_.push_back(t);
00226 }
00227 }
00228 else
00229 {
00230 ROS_ERROR_STREAM("Parsing error in cartesian_trajectory, structure array is not well formed");
00231 success = false;
00232 }
00233 }
00234 else
00235 {
00236 ROS_ERROR_STREAM(ros::this_node::getName()<<": Parsing error in cartesian_trajectory parameter");
00237 success = false;
00238 }
00239
00240 ROS_INFO_STREAM(ros::this_node::getName()<<": cartesian_trajectory parameter successfully parsed"<<toString());
00241 return success;
00242 }
00243
00244 void CartesianTrajectory::getMarker(nav_msgs::Path &p)
00245 {
00246 p.header.frame_id = frame_id_;
00247 p.header.stamp = ros::Time(0.0f);
00248 geometry_msgs::PoseStamped poseSt;
00249
00250
00251 poseSt.header.frame_id = frame_id_;
00252 poseSt.header.stamp = ros::Time(0.0f);
00253
00254 std::vector<tf::Transform>::iterator i;
00255 for (i = cartesian_points_.begin(); i != cartesian_points_.end(); i++)
00256 {
00257 tf::poseTFToMsg(*i, poseSt.pose);
00258 p.poses.push_back(poseSt);
00259 }
00260
00261 }
00262
00263 bool CartesianTrajectory::fetchParameters(std::string nameSpace)
00264 {
00265 XmlRpc::XmlRpcValue val;
00266 bool success = ros::param::get(nameSpace, val) && parseParameters(val);
00267 if (!success)
00268 {
00269 ROS_ERROR_STREAM(ros::this_node::getName()<<": Parsing error in cartesian_trajectory parameter");
00270 }
00271 return success;
00272 }
00273
00274 bool PickupGoalInfo::fetchParameters(std::string nameSpace)
00275 {
00276 ros::NodeHandle nh;
00277 XmlRpc::XmlRpcValue val;
00278
00279 if (nh.getParam(nameSpace, val) && parseParameters(val))
00280 {
00281 return true;
00282 }
00283 else
00284 {
00285 return false;
00286 }
00287 }
00288
00289 bool PickupGoalInfo::parseParameters(XmlRpc::XmlRpcValue &val)
00290 {
00291 bool success = true;
00292
00293
00294 this->desired_grasps.resize(1);
00295 this->target.potential_models.resize(1);
00296
00297
00298 this->arm_name = static_cast<std::string>(val["arm_group"]);
00299
00300
00301 this->lift.desired_distance = static_cast<double>(val["lift_distance"]);
00302 this->desired_grasps[0].desired_approach_distance = static_cast<double>(val["approach_distance"]);
00303
00304
00305 this->target.reference_frame_id = static_cast<std::string>(val["frame_id"]);
00306 this->lift.direction.header.frame_id = static_cast<std::string>(val["tool_name"]);
00307
00308
00309 success = val.hasMember("lift_direction") && parseVect3(val["lift_direction"], this->lift.direction.vector)
00310 && val.hasMember("grasp_pose") && parsePose(val["grasp_pose"], this->desired_grasps[0].grasp_pose)
00311 && val.hasMember("object_pose") && parsePose(val["object_pose"], this->target.potential_models[0].pose.pose);
00312
00313 if (success)
00314 {
00315 ROS_INFO_STREAM("Pickup goal parameters found");
00316 }
00317 else
00318 {
00319 ROS_ERROR_STREAM("Pickup goal parameters not found");
00320 }
00321
00322 return success;
00323 }
00324
00325 bool PlaceGoalInfo::fetchParameters(std::string nameSpace)
00326 {
00327 XmlRpc::XmlRpcValue val;
00328 return ros::param::get(nameSpace, val) && parseParameters(val);
00329 }
00330
00331 bool PlaceGoalInfo::parseParameters(XmlRpc::XmlRpcValue &val)
00332 {
00333 bool success = true;
00334
00335
00336 this->place_locations.resize(1);
00337
00338
00339 this->arm_name = static_cast<std::string>(val["arm_group"]);
00340
00341
00342 this->approach.desired_distance = static_cast<double>(val["approach_distance"]);
00343 this->desired_retreat_distance = static_cast<double>(val["retreat_distance"]);
00344
00345
00346 this->place_locations[0].header.frame_id = static_cast<std::string>(val["frame_id"]);
00347 this->approach.direction.header.frame_id = static_cast<std::string>(val["tool_name"]);
00348
00349 success = val.hasMember("approach_direction")
00350 && parseVect3(val["approach_direction"], this->approach.direction.vector) && val.hasMember("place_pose")
00351 && parsePose(val["place_pose"], this->place_locations[0].pose) && val.hasMember("grasp_pose")
00352 && parsePose(val["grasp_pose"], this->grasp.grasp_pose);
00353
00354 if (success)
00355 {
00356 ROS_INFO_STREAM("Place goal parameters found");
00357 }
00358 else
00359 {
00360 ROS_ERROR_STREAM("Place goal parameters not found");
00361 }
00362
00363 return success;
00364 }
00365
00366 bool JointStateInfo::fetchParameters(std::string nameSpace)
00367 {
00368 XmlRpc::XmlRpcValue val;
00369 return ros::param::get(nameSpace, val) && parseParameters(val);
00370 }
00371
00372 bool JointStateInfo::parseParameters(XmlRpc::XmlRpcValue ¶m)
00373 {
00374
00375 const std::string arm_group_mb = "arm_group";
00376 const std::string joints_mb = "joints";
00377 const std::string position_mb = "position";
00378 const std::string name_mb = "name";
00379 const std::string velocity_mb = "velocity";
00380 const std::string effort_mb = "effort";
00381
00382
00383 XmlRpc::XmlRpcValue joint_param;
00384
00385
00386 arm_group = (param.hasMember(arm_group_mb) ? static_cast<std::string>(param[arm_group_mb]) : arm_group);
00387
00388
00389 if (!param.hasMember(joints_mb))
00390 {
00391 return false;
00392 }
00393
00394
00395 position.clear();
00396 name.clear();
00397 velocity.clear();
00398 effort.clear();
00399
00400
00401 joint_param = param[joints_mb];
00402 if (joint_param.getType() == XmlRpc::XmlRpcValue::TypeArray
00403 && joint_param[0].getType() == XmlRpc::XmlRpcValue::TypeStruct && joint_param[0].hasMember(position_mb)
00404 && joint_param[0].hasMember(name_mb))
00405 {
00406 for (int i = 0; i < joint_param.size(); i++)
00407 {
00408 XmlRpc::XmlRpcValue &element = joint_param[i];
00409 position.push_back(static_cast<double>(element[position_mb]));
00410 name.push_back(static_cast<std::string>(element[name_mb]));
00411
00412
00413 velocity.push_back(element.hasMember(velocity_mb) ? static_cast<double>(element[velocity_mb]) : 0);
00414 effort.push_back(element.hasMember(effort_mb) ? static_cast<double>(element[effort_mb]) : 0);
00415 }
00416 }
00417 else
00418 {
00419 return false;
00420 }
00421
00422
00423 std::stringstream ss;
00424 boost::tuples::tuple<std::string, double> joint_val;
00425 ss << "\n\tJoints State:\n";
00426 for (std::size_t i = 0; i < name.size(); i++)
00427 {
00428 joint_val.get<0>() = name[i];
00429 joint_val.get<1>() = position[i];
00430 ss << "\t\t[ " << joint_val.get<0>() << ", " << joint_val.get<1>() << " ]\n";
00431 }
00432
00433 ROS_INFO_STREAM(ss.str());
00434
00435 return true;
00436 }
00437
00438 void JointStateInfo::toJointConstraints(double tol_above, double tol_below,
00439 std::vector<arm_navigation_msgs::JointConstraint> &joint_constraints)
00440 {
00441 arm_navigation_msgs::JointConstraint val;
00442 val.tolerance_above = tol_above;
00443 val.tolerance_below = tol_below;
00444 val.weight = 0.0f;
00445
00446 for (std::size_t i = 0; i < name.size(); i++)
00447 {
00448 val.joint_name = name[i];
00449 val.position = position[i];
00450 joint_constraints.push_back(val);
00451 }
00452 }
00453