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