utilities.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2013 Southwest Research Institute
00003 
00004  Licensed under the Apache License, Version 2.0 (the "License");
00005  you may not use this file except in compliance with the License.
00006  You may obtain a copy of the License at
00007 
00008  http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  Unless required by applicable law or agreed to in writing, software
00011  distributed under the License is distributed on an "AS IS" BASIS,
00012  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  See the License for the specific language governing permissions and
00014  limitations under the License.
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   // parsing components
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   // parsing orientation
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   // parsing position and orientation values
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   // This line makes the assumption that a path is tied to a single group
00151   // (which is only true for out case, not in general)
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 &paramVal)
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     // fetching frame id and link name
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     // fetching cartesian via point struct array
00204     cartesian_points_param = paramVal["via_points"];
00205 
00206     // parsing each struct
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           // parsing failed, exiting loop
00220           ROS_ERROR_STREAM("Parsing error in cartesian_trajectory point");
00221           success = false;
00222           break;
00223         }
00224         // storing as transform
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   // initializing pose stamped object
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   // allocating grasp and model data
00294   this->desired_grasps.resize(1);
00295   this->target.potential_models.resize(1);
00296 
00297   // parsing arm group name
00298   this->arm_name = static_cast<std::string>(val["arm_group"]);
00299 
00300   // parsing distances
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   // parsing reference frame info
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   // parsing grasp pose and direction
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   // allocating place pose
00336   this->place_locations.resize(1);
00337 
00338   // parsing arm group name
00339   this->arm_name = static_cast<std::string>(val["arm_group"]);
00340 
00341   // parsing distances
00342   this->approach.desired_distance = static_cast<double>(val["approach_distance"]);
00343   this->desired_retreat_distance = static_cast<double>(val["retreat_distance"]);
00344 
00345   // parsing reference frame info
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 &param)
00373 {
00374   // declaring member name strings
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   // declaring params
00383   XmlRpc::XmlRpcValue joint_param;
00384 
00385   // parsing arm group name (optional)
00386   arm_group = (param.hasMember(arm_group_mb) ? static_cast<std::string>(param[arm_group_mb]) : arm_group);
00387 
00388   // checking joints struct array
00389   if (!param.hasMember(joints_mb))
00390   {
00391     return false;
00392   }
00393 
00394   // clearing arrays
00395   position.clear();
00396   name.clear();
00397   velocity.clear();
00398   effort.clear();
00399 
00400   // retrieving and parsing joint struct array
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       // optional entries ( Assigns 0  when member is not found )
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   // printing results
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 


mtconnect_cnc_robot_example
Author(s): Jnicho
autogenerated on Mon Jan 6 2014 11:31:45