model_utils.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 * 
00004 *  Copyright (c) 2010, Willow Garage, Inc.
00005 *  All rights reserved.
00006 * 
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 * 
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 * 
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00037 #include <planning_environment/models/model_utils.h>
00038 #include <geometric_shapes/bodies.h>
00039 #include <planning_environment/util/construct_object.h>
00040 
00041 //returns true if the joint_state_map sets all the joints in the state, 
00042 bool planning_environment::setRobotStateAndComputeTransforms(const arm_navigation_msgs::RobotState &robot_state,
00043                                                              planning_models::KinematicState& state)
00044 {
00045   if(robot_state.joint_state.name.size() != robot_state.joint_state.position.size()) {
00046     ROS_INFO_STREAM("Different number of names and positions: " << robot_state.joint_state.name.size() 
00047                     << " " << robot_state.joint_state.position.size());
00048     return false;
00049   }
00050   std::map<std::string, double> joint_state_map;
00051   for (unsigned int i = 0 ; i < robot_state.joint_state.name.size(); ++i)
00052   {
00053     joint_state_map[robot_state.joint_state.name[i]] = robot_state.joint_state.position[i];
00054   }
00055   std::vector<std::string> missing_states;
00056   bool complete = state.setKinematicState(joint_state_map, missing_states);
00057   if(!complete) {
00058     if(missing_states.empty()) {
00059       ROS_INFO("Incomplete, but no missing states");
00060     }
00061   }
00062   std::map<std::string, bool> has_missing_state_map;
00063   for(unsigned int i = 0; i < missing_states.size(); i++) {
00064     has_missing_state_map[missing_states[i]] = false;
00065   }
00066   bool need_to_update = false;
00067   if(robot_state.multi_dof_joint_state.joint_names.size() > 1) {
00068     ROS_INFO("More than 1 joint names");
00069   }
00070   for(unsigned int i = 0; i < robot_state.multi_dof_joint_state.joint_names.size(); i++) {
00071     std::string joint_name = robot_state.multi_dof_joint_state.joint_names[i];
00072     if(!state.hasJointState(joint_name)) {
00073       ROS_WARN_STREAM("No joint matching multi-dof joint " << joint_name);
00074       continue;
00075     }
00076     planning_models::KinematicState::JointState* joint_state = state.getJointState(joint_name);
00077     if(robot_state.multi_dof_joint_state.frame_ids.size() <= i) {
00078       ROS_INFO_STREAM("Robot state msg had bad multi_dof transform - not enough frame ids");
00079     } else if(robot_state.multi_dof_joint_state.child_frame_ids.size() <= i) {
00080       ROS_INFO_STREAM("Robot state msg had bad multi_dof transform - not enough child frame ids");
00081     } else if(robot_state.multi_dof_joint_state.frame_ids[i] != joint_state->getParentFrameId() ||
00082               robot_state.multi_dof_joint_state.child_frame_ids[i] != joint_state->getChildFrameId()) {
00083       ROS_WARN_STREAM("Robot state msg has bad multi_dof transform - frame ids or child frame_ids do not match up with joint");
00084     } else {
00085       tf::StampedTransform transf;
00086       tf::poseMsgToTF(robot_state.multi_dof_joint_state.poses[i], transf);
00087       joint_state->setJointStateValues(transf);
00088       need_to_update = true;
00089       //setting true for all individual joint names because we're setting the transform
00090       for(unsigned int i = 0; i < joint_state->getJointStateNameOrder().size(); i++) {
00091         has_missing_state_map[joint_state->getJointStateNameOrder()[i]] = true;
00092       }
00093     }
00094   }
00095   if(need_to_update) {
00096     state.updateKinematicLinks();
00097   }
00098   if(!complete) {
00099     for(std::map<std::string, bool>::iterator it = has_missing_state_map.begin();
00100         it != has_missing_state_map.end();
00101         it++) {
00102       if(!it->second) {
00103         return false;
00104       }
00105     }
00106     return true;
00107   }
00108   return true;
00109 }
00110 
00111 void planning_environment::convertKinematicStateToRobotState(const planning_models::KinematicState& kinematic_state,
00112                                                              const ros::Time& timestamp,
00113                                                              const std::string& header_frame,
00114                                                              arm_navigation_msgs::RobotState &robot_state)
00115 {
00116   robot_state.joint_state.position.clear();
00117   robot_state.joint_state.name.clear();
00118 
00119   robot_state.multi_dof_joint_state.joint_names.clear();
00120   robot_state.multi_dof_joint_state.frame_ids.clear();
00121   robot_state.multi_dof_joint_state.child_frame_ids.clear();
00122   robot_state.multi_dof_joint_state.poses.clear();
00123 
00124   const std::vector<planning_models::KinematicState::JointState*>& joints = kinematic_state.getJointStateVector();
00125   for(std::vector<planning_models::KinematicState::JointState*>::const_iterator it = joints.begin();
00126       it != joints.end();
00127       it++) {
00128     const std::vector<double>& joint_state_values = (*it)->getJointStateValues();
00129     const std::vector<std::string>& joint_state_value_names = (*it)->getJointStateNameOrder();
00130     for(unsigned int i = 0; i < joint_state_values.size(); i++) {
00131       robot_state.joint_state.name.push_back(joint_state_value_names[i]);
00132       robot_state.joint_state.position.push_back(joint_state_values[i]);
00133     }
00134     if(!(*it)->getParentFrameId().empty() && !(*it)->getChildFrameId().empty()) {
00135       robot_state.multi_dof_joint_state.stamp = ros::Time::now();
00136       robot_state.multi_dof_joint_state.joint_names.push_back((*it)->getName());
00137       robot_state.multi_dof_joint_state.frame_ids.push_back((*it)->getParentFrameId());
00138       robot_state.multi_dof_joint_state.child_frame_ids.push_back((*it)->getChildFrameId());
00139       tf::Pose p((*it)->getVariableTransform());
00140       geometry_msgs::Pose pose;
00141       tf::poseTFToMsg(p, pose);
00142       robot_state.multi_dof_joint_state.poses.push_back(pose);
00143     }
00144   }
00145   robot_state.joint_state.header.stamp = timestamp;
00146   robot_state.joint_state.header.frame_id = header_frame;
00147   return;
00148 }
00149 
00150 void planning_environment::applyOrderedCollisionOperationsToMatrix(const arm_navigation_msgs::OrderedCollisionOperations &ord,
00151                                                                    collision_space::EnvironmentModel::AllowedCollisionMatrix& acm) {
00152   if(ord.collision_operations.size() == 0) {
00153     ROS_INFO_STREAM("No allowed collision operations");
00154   }
00155   
00156   for(size_t i = 0; i < ord.collision_operations.size(); i++) {
00157     
00158     bool allowed = (ord.collision_operations[i].operation == arm_navigation_msgs::CollisionOperation::DISABLE);
00159 
00160     ROS_INFO_STREAM("Setting collision operation between " << ord.collision_operations[i].object1
00161                     << " and " << ord.collision_operations[i].object2 << " allowed " << allowed);
00162 
00163     if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL &&
00164        ord.collision_operations[i].object2 == ord.collision_operations[i].COLLISION_SET_ALL) {
00165       acm.changeEntry(allowed);
00166       ROS_INFO_STREAM("Should be setting all");
00167     } else if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL ||
00168               ord.collision_operations[i].object2 == ord.collision_operations[i].COLLISION_SET_ALL) {
00169       //second case - only one all
00170       std::string other;
00171       if(ord.collision_operations[i].object1 == ord.collision_operations[i].COLLISION_SET_ALL) {
00172         other = ord.collision_operations[i].object2;
00173       } else {
00174         other = ord.collision_operations[i].object1;
00175       }
00176       bool ok = acm.changeEntry(other,allowed);
00177       if(!ok) {
00178         ROS_WARN_STREAM("No allowed collision entry for " << other);
00179       }
00180     } else {
00181       //third case - must be both objects
00182       bool ok = acm.changeEntry(ord.collision_operations[i].object1,
00183                                 ord.collision_operations[i].object2,
00184                                 allowed);
00185       if(!ok) {
00186         ROS_WARN_STREAM("No entry in allowed collision matrix for at least one of " 
00187                         << ord.collision_operations[i].object1 << " and " 
00188                         << ord.collision_operations[i].object2);
00189       }
00190     }
00191   }
00192 }
00193 
00194 void planning_environment::convertFromACMToACMMsg(const collision_space::EnvironmentModel::AllowedCollisionMatrix& acm,
00195                                                   arm_navigation_msgs::AllowedCollisionMatrix& matrix) {
00196   if(!acm.getValid()) return;
00197   matrix.link_names.resize(acm.getSize());
00198   matrix.entries.resize(acm.getSize());
00199   const collision_space::EnvironmentModel::AllowedCollisionMatrix::entry_type& bm = acm.getEntriesBimap();
00200   for(collision_space::EnvironmentModel::AllowedCollisionMatrix::entry_type::right_const_iterator it = bm.right.begin();
00201       it != bm.right.end();
00202       it++) {
00203     matrix.link_names[it->first] = it->second;
00204     for(unsigned int i = 0; i < acm.getSize(); i++) {
00205       bool allowed;
00206       matrix.entries[i].enabled.resize(acm.getSize());
00207       acm.getAllowedCollision(it->first, i, allowed); 
00208       if(it->first >= matrix.entries[i].enabled.size()) {
00209         ROS_WARN_STREAM("Trouble size " << matrix.entries[i].enabled.size() << " ind " << it->first); 
00210       } else {
00211         matrix.entries[it->first].enabled[i] = allowed;
00212       }
00213     }
00214   }
00215 }
00216 
00217 collision_space::EnvironmentModel::AllowedCollisionMatrix 
00218 planning_environment::convertFromACMMsgToACM(const arm_navigation_msgs::AllowedCollisionMatrix& matrix)
00219 {
00220   std::map<std::string, unsigned int> indices;
00221   std::vector<std::vector<bool> > vecs;
00222   unsigned int ns = matrix.link_names.size();
00223   if(matrix.entries.size() != ns) {
00224     ROS_WARN_STREAM("Matrix messed up");
00225   }
00226   vecs.resize(ns);
00227   for(unsigned int i = 0; i < std::min(ns, (unsigned int) matrix.entries.size()); i++) {
00228     indices[matrix.link_names[i]] = i;
00229     if(matrix.entries[i].enabled.size() != ns) {
00230       ROS_WARN_STREAM("Matrix messed up");
00231     }
00232     vecs[i].resize(ns);
00233     for(unsigned int j = 0; j < std::min(ns, (unsigned int) matrix.entries[i].enabled.size()); j++) {
00234       vecs[i][j] = matrix.entries[i].enabled[j];
00235     }
00236   }
00237   collision_space::EnvironmentModel::AllowedCollisionMatrix acm(vecs,indices);
00238   return acm;
00239 }
00240 
00241 bool planning_environment::applyOrderedCollisionOperationsListToACM(const arm_navigation_msgs::OrderedCollisionOperations& ordered_coll,
00242                                                                     const std::vector<std::string>& object_names,
00243                                                                     const std::vector<std::string>& att_names,
00244                                                                     const planning_models::KinematicModel* model,
00245                                                                     collision_space::EnvironmentModel::AllowedCollisionMatrix& matrix)
00246 {
00247   bool all_ok = true;
00248   for(std::vector<arm_navigation_msgs::CollisionOperation>::const_iterator it = ordered_coll.collision_operations.begin();
00249       it != ordered_coll.collision_operations.end();
00250       it++) {
00251     bool op = (*it).operation != arm_navigation_msgs::CollisionOperation::ENABLE;
00252     std::vector<std::string> svec1, svec2;
00253     bool special1 = false;
00254     bool special2 = false;
00255     if((*it).object1 == (*it).COLLISION_SET_OBJECTS) {
00256       svec1 = object_names;
00257       special1 = true;
00258     }
00259     if((*it).object2 == (*it).COLLISION_SET_OBJECTS) {
00260       svec2 = object_names;
00261       special2 = true;
00262     }
00263     if((*it).object1 == (*it).COLLISION_SET_ATTACHED_OBJECTS) {
00264       svec1 = att_names;
00265       special1 = true;
00266     }
00267     if((*it).object2 == (*it).COLLISION_SET_ATTACHED_OBJECTS) {
00268       svec2 = att_names;
00269       special2 = true;
00270     }
00271     if(model->getModelGroup((*it).object1) != NULL) {
00272       svec1 = model->getModelGroup((*it).object1)->getGroupLinkNames();
00273       special1 = true;
00274     }
00275     if(model->getModelGroup((*it).object2) != NULL) {
00276       svec2 = model->getModelGroup((*it).object2)->getGroupLinkNames();
00277       special2 = true;
00278     }
00279     if(!special1) {
00280       svec1.push_back((*it).object1);
00281     }
00282     if(!special2) {
00283       svec2.push_back((*it).object2);
00284     }
00285 
00286     bool first_all = false;
00287     bool second_all = false;
00288     for(unsigned int j = 0; j < svec1.size(); j++) {
00289       if(svec1[j] == (*it).COLLISION_SET_ALL) {
00290         first_all = true;
00291         if(svec1.size() > 1) {
00292           ROS_WARN("Shouldn't have collision object all in multi-item list");
00293           all_ok = false;
00294         }
00295         break;
00296       }
00297     }
00298     for(unsigned int j = 0; j < svec2.size(); j++) {
00299       if(svec2[j] == (*it).COLLISION_SET_ALL) {
00300         second_all = true;
00301         if(svec2.size() > 1) {
00302           ROS_WARN("Shouldn't have collision object all in multi-item list");
00303           all_ok = false;
00304         }
00305         break;
00306       }
00307     }
00308 
00309     ROS_DEBUG_STREAM("Coll op first and second all " << first_all << " " << second_all);
00310     if(first_all && second_all) {
00311       matrix.changeEntry(op);
00312     } else if(first_all) {
00313       for(unsigned int j = 0; j < svec2.size(); j++) {
00314         matrix.changeEntry(svec2[j], op);
00315       }
00316     } else if(second_all) {
00317       for(unsigned int j = 0; j < svec1.size(); j++) {
00318         matrix.changeEntry(svec1[j], op);
00319       }
00320     } else {
00321       bool ok = matrix.changeEntry(svec1, svec2, (*it).operation != arm_navigation_msgs::CollisionOperation::ENABLE);
00322       if(!ok) {
00323         ROS_DEBUG_STREAM("No entry in acm for some member of " << (*it).object1 << " and " << (*it).object2);
00324         all_ok = false;
00325       }
00326     }
00327   }
00328   return all_ok;
00329 }               
00330 
00331 arm_navigation_msgs::AllowedCollisionMatrix 
00332 planning_environment::applyOrderedCollisionOperationsToCollisionsModel(const planning_environment::CollisionModels* cm,
00333                                                                        const arm_navigation_msgs::OrderedCollisionOperations& ordered_coll,
00334                                                                        const std::vector<std::string>& object_names,
00335                                                                        const std::vector<std::string>& att_names)
00336 {
00337   collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm->getDefaultAllowedCollisionMatrix();
00338   
00339   for(unsigned int i = 0; i < object_names.size(); i++) {
00340     if(!acm.hasEntry(object_names[i])) {
00341       acm.addEntry(object_names[i], false);
00342     } 
00343   }
00344 
00345   for(unsigned int i = 0; i < att_names.size(); i++) {
00346     if(!acm.hasEntry(att_names[i])) {
00347       acm.addEntry(att_names[i], false);
00348     } 
00349   }
00350 
00351   applyOrderedCollisionOperationsListToACM(ordered_coll, object_names, att_names, cm->getKinematicModel(), acm);
00352                          
00353   arm_navigation_msgs::AllowedCollisionMatrix ret_msg;
00354   convertFromACMToACMMsg(acm, ret_msg);
00355   return ret_msg;
00356 }
00357 
00358 bool planning_environment::doesKinematicStateObeyConstraints(const planning_models::KinematicState& state,
00359                                                              const arm_navigation_msgs::Constraints& constraints,
00360                                                              bool verbose) {
00361   planning_environment::KinematicConstraintEvaluatorSet constraint_evaluator;
00362   
00363   constraint_evaluator.add(constraints.joint_constraints);
00364   constraint_evaluator.add(constraints.position_constraints);
00365   constraint_evaluator.add(constraints.orientation_constraints);
00366   constraint_evaluator.add(constraints.visibility_constraints);
00367   return(constraint_evaluator.decide(&state, verbose));
00368 }
00369 
00370 void planning_environment::setMarkerShapeFromShape(const arm_navigation_msgs::Shape &obj, visualization_msgs::Marker &mk)
00371 {
00372   switch (obj.type)
00373   {
00374   case arm_navigation_msgs::Shape::SPHERE:
00375     mk.type = visualization_msgs::Marker::SPHERE;
00376     mk.scale.x = mk.scale.y = mk.scale.z = obj.dimensions[0] * 2.0;
00377     break;
00378     
00379   case arm_navigation_msgs::Shape::BOX:
00380     mk.type = visualization_msgs::Marker::CUBE;
00381     mk.scale.x = obj.dimensions[0];
00382     mk.scale.y = obj.dimensions[1];
00383     mk.scale.z = obj.dimensions[2];
00384     break;
00385     
00386   case arm_navigation_msgs::Shape::CYLINDER:
00387     mk.type = visualization_msgs::Marker::CYLINDER;
00388     mk.scale.x = obj.dimensions[0] * 2.0;
00389     mk.scale.y = obj.dimensions[0] * 2.0;
00390     mk.scale.z = obj.dimensions[1];
00391     break;
00392     
00393   case arm_navigation_msgs::Shape::MESH:
00394     mk.type = visualization_msgs::Marker::LINE_LIST;
00395     mk.scale.x = mk.scale.y = mk.scale.z = 0.001;
00396     {
00397       unsigned int nt = obj.triangles.size() / 3;
00398       for (unsigned int i = 0 ; i < nt ; ++i)
00399       {
00400         mk.points.push_back(obj.vertices[obj.triangles[3*i]]);
00401         mk.points.push_back(obj.vertices[obj.triangles[3*i+ 1]]);
00402         mk.points.push_back(obj.vertices[obj.triangles[3*i]]);
00403         mk.points.push_back(obj.vertices[obj.triangles[3*i+2]]);
00404         mk.points.push_back(obj.vertices[obj.triangles[3*i+1]]);
00405         mk.points.push_back(obj.vertices[obj.triangles[3*i+2]]);
00406       }
00407     }
00408     
00409     break;
00410     
00411   default:
00412     ROS_ERROR("Unknown object type: %d", (int)obj.type);
00413   }
00414 }
00415 
00416 void planning_environment::setMarkerShapeFromShape(const shapes::Shape *obj, visualization_msgs::Marker &mk, double padding)
00417 {
00418   switch (obj->type)
00419   {
00420   case shapes::SPHERE:
00421     mk.type = visualization_msgs::Marker::SPHERE;
00422     mk.scale.x = mk.scale.y = mk.scale.z = static_cast<const shapes::Sphere*>(obj)->radius * 2.0 + padding;
00423     break;
00424     
00425   case shapes::BOX:
00426     mk.type = visualization_msgs::Marker::CUBE;
00427     {
00428       const double *size = static_cast<const shapes::Box*>(obj)->size;
00429       mk.scale.x = size[0] + padding*2.0;
00430       mk.scale.y = size[1] + padding*2.0;
00431       mk.scale.z = size[2] + padding*2.0;
00432     }
00433     break;
00434     
00435   case shapes::CYLINDER:
00436     mk.type = visualization_msgs::Marker::CYLINDER;
00437     mk.scale.x = static_cast<const shapes::Cylinder*>(obj)->radius * 2.0 + padding;
00438     mk.scale.y = mk.scale.x;
00439     mk.scale.z = static_cast<const shapes::Cylinder*>(obj)->length + padding*2.0;
00440     break;
00441     
00442   case shapes::MESH:
00443     mk.type = visualization_msgs::Marker::LINE_LIST;
00444     mk.scale.x = mk.scale.y = mk.scale.z = 0.001;
00445     {      
00446       const shapes::Mesh *mesh = static_cast<const shapes::Mesh*>(obj);
00447       double* vertices = new double[mesh->vertexCount * 3];
00448       double sx = 0.0, sy = 0.0, sz = 0.0;
00449       for(unsigned int i = 0; i < mesh->vertexCount; ++i) {
00450         unsigned int i3 = i * 3;
00451         vertices[i3] = mesh->vertices[i3];
00452         vertices[i3 + 1] = mesh->vertices[i3 + 1];
00453         vertices[i3 + 2] = mesh->vertices[i3 + 2];
00454         sx += vertices[i3];
00455         sy += vertices[i3 + 1];
00456         sz += vertices[i3 + 2];
00457       }
00458       // the center of the mesh
00459       sx /= (double)mesh->vertexCount;
00460       sy /= (double)mesh->vertexCount;
00461       sz /= (double)mesh->vertexCount;
00462       
00463       for (unsigned int i = 0 ; i < mesh->vertexCount ; ++i)
00464       {
00465         unsigned int i3 = i * 3;
00466         
00467         // vector from center to the vertex
00468         double dx = vertices[i3] - sx;
00469         double dy = vertices[i3 + 1] - sy;
00470         double dz = vertices[i3 + 2] - sz;
00471         
00472         // length of vector
00473         //double norm = sqrt(dx * dx + dy * dy + dz * dz);
00474         
00475         double ndx = ((dx > 0) ? dx+padding : dx-padding);
00476         double ndy = ((dy > 0) ? dy+padding : dy-padding);
00477         double ndz = ((dz > 0) ? dz+padding : dz-padding);
00478         
00479         // the new distance of the vertex from the center
00480         //double fact = scale + padding/norm;
00481         vertices[i3] = sx + ndx; //dx * fact;
00482         vertices[i3 + 1] = sy + ndy; //dy * fact;
00483         vertices[i3 + 2] = sz + ndz; //dz * fact;                   
00484       }
00485       
00486       tf::Transform trans;
00487       tf::poseMsgToTF(mk.pose, trans);
00488 
00489       for (unsigned int j = 0 ; j < mesh->triangleCount; ++j) {
00490         unsigned int t1ind = mesh->triangles[3*j];
00491         unsigned int t2ind = mesh->triangles[3*j + 1];
00492         unsigned int t3ind = mesh->triangles[3*j + 2];
00493         
00494         tf::Vector3 vec1(vertices[t1ind*3],
00495                        vertices[t1ind*3+1],
00496                        vertices[t1ind*3+2]);
00497         
00498         tf::Vector3 vec2(vertices[t2ind*3],
00499                        vertices[t2ind*3+1],
00500                        vertices[t2ind*3+2]);
00501         
00502         tf::Vector3 vec3(vertices[t3ind*3],
00503                        vertices[t3ind*3+1],
00504                        vertices[t3ind*3+2]);
00505         
00506         //vec1 = trans*vec1;
00507         //vec2 = trans*vec2;
00508         //vec3 = trans*vec3;
00509         
00510         geometry_msgs::Point pt1;
00511         pt1.x = vec1.x();
00512         pt1.y = vec1.y();
00513         pt1.z = vec1.z();
00514 
00515         geometry_msgs::Point pt2;
00516         pt2.x = vec2.x();
00517         pt2.y = vec2.y();
00518         pt2.z = vec2.z();
00519         
00520         geometry_msgs::Point pt3;
00521         pt3.x = vec3.x();
00522         pt3.y = vec3.y();
00523         pt3.z = vec3.z();
00524         
00525         mk.points.push_back(pt1);
00526         mk.points.push_back(pt2);
00527         
00528         mk.points.push_back(pt1);
00529         mk.points.push_back(pt3);
00530         
00531         mk.points.push_back(pt2);
00532         mk.points.push_back(pt3);
00533       }
00534       delete[] vertices;
00535     }
00536     break;
00537     
00538   default:
00539     ROS_ERROR("Unknown object type: %d", (int)obj->type);
00540   }
00541 }
00542 
00543 void planning_environment::convertFromLinkPaddingMapToLinkPaddingVector(const std::map<std::string, double>& link_padding_map,
00544                                                                         std::vector<arm_navigation_msgs::LinkPadding>& link_padding_vector)
00545 {
00546   for(std::map<std::string, double>::const_iterator it = link_padding_map.begin();
00547       it != link_padding_map.end();
00548       it++) {
00549     arm_navigation_msgs::LinkPadding lp;
00550     lp.link_name = it->first;
00551     lp.padding = it->second;
00552     link_padding_vector.push_back(lp);
00553   }
00554 }
00555 
00556 void planning_environment::getAllKinematicStateStampedTransforms(const planning_models::KinematicState& state,
00557                                                                  std::vector<geometry_msgs::TransformStamped>& trans_vector,
00558                                                                  const ros::Time& stamp)
00559 {
00560   trans_vector.clear();
00561   for(unsigned int i = 0; i < state.getLinkStateVector().size(); i++) {      
00562     const planning_models::KinematicState::LinkState* ls = state.getLinkStateVector()[i];
00563     geometry_msgs::TransformStamped ts;
00564     ts.header.stamp = stamp;
00565     ts.header.frame_id = state.getKinematicModel()->getRoot()->getParentFrameId();
00566     ts.child_frame_id = ls->getName();
00567     if(ts.header.frame_id == ts.child_frame_id) continue; 
00568     tf::transformTFToMsg(ls->getGlobalLinkTransform(),ts.transform);
00569     trans_vector.push_back(ts);
00570   }
00571 } 
00572 
00573 void planning_environment::convertAllowedContactSpecificationMsgToAllowedContactVector(const std::vector<arm_navigation_msgs::AllowedContactSpecification>& acmv,
00574                                                                                        std::vector<collision_space::EnvironmentModel::AllowedContact>& acv)
00575 {
00576   //assumes that poses are in the global frame
00577   acv.clear();
00578   for(unsigned int i = 0; i < acmv.size(); i++) {
00579     const arm_navigation_msgs::AllowedContactSpecification& acs = acmv[i];
00580     if(acs.link_names.size() != 2) {
00581       ROS_WARN_STREAM("Allowed collision specification has link_names size " << acs.link_names.size()
00582                       << " while the only supported size is 2");
00583       continue;
00584     }
00585     shapes::Shape* shape = constructObject(acs.shape);
00586     boost::shared_ptr<bodies::Body> bodysp(bodies::createBodyFromShape(shape));
00587     delete shape;
00588     tf::Transform trans;
00589     tf::poseMsgToTF(acs.pose_stamped.pose, trans);
00590     bodysp->setPose(trans);
00591 
00592     collision_space::EnvironmentModel::AllowedContact allc;
00593     allc.bound = bodysp;
00594     allc.body_name_1 = acs.link_names[0];
00595     allc.body_name_2 = acs.link_names[1];
00596     allc.depth = acs.penetration_depth;
00597     acv.push_back(allc);
00598   }
00599 }
00600 
00601 void planning_environment::getCollisionMarkersFromContactInformation(const std::vector<arm_navigation_msgs::ContactInformation>& coll_info_vec,
00602                                                                      const std::string& world_frame_id,
00603                                                                      visualization_msgs::MarkerArray& arr,
00604                                                                      const std_msgs::ColorRGBA& color,
00605                                                                      const ros::Duration& lifetime)
00606 {
00607   std::map<std::string, unsigned> ns_counts;
00608   for(unsigned int i = 0; i < coll_info_vec.size(); i++) {
00609     std::string ns_name;
00610     ns_name = coll_info_vec[i].contact_body_1;
00611     ns_name +="+";
00612     ns_name += coll_info_vec[i].contact_body_2;
00613     if(ns_counts.find(ns_name) == ns_counts.end()) {
00614       ns_counts[ns_name] = 0;
00615     } else {
00616       ns_counts[ns_name]++;
00617     }
00618     visualization_msgs::Marker mk;
00619     mk.header.stamp = ros::Time::now();
00620     mk.header.frame_id = world_frame_id;
00621     mk.ns = ns_name;
00622     mk.id = ns_counts[ns_name];
00623     mk.type = visualization_msgs::Marker::SPHERE;
00624     mk.action = visualization_msgs::Marker::ADD;
00625     mk.pose.position.x = coll_info_vec[i].position.x;
00626     mk.pose.position.y = coll_info_vec[i].position.y;
00627     mk.pose.position.z = coll_info_vec[i].position.z;
00628     mk.pose.orientation.w = 1.0;
00629     
00630     mk.scale.x = mk.scale.y = mk.scale.z = 0.035;
00631 
00632     mk.color.a = color.a;
00633     if(mk.color.a == 0.0) {
00634       mk.color.a = 1.0;
00635     }
00636     mk.color.r = color.r;
00637     mk.color.g = color.g;
00638     mk.color.b = color.b;
00639     
00640     mk.lifetime = lifetime;
00641     arr.markers.push_back(mk);
00642   }
00643 }


planning_environment
Author(s): Ioan Sucan
autogenerated on Thu Dec 12 2013 11:09:24