robot_state.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 
00035 /* Author: Ioan Sucan, E. Gil Jones */
00036 
00037 #include <moveit/robot_state/robot_state.h>
00038 #include <geometric_shapes/shape_operations.h>
00039 #include <eigen_conversions/eigen_msg.h>
00040 
00041 robot_state::RobotState::RobotState(const robot_model::RobotModelConstPtr &kinematic_model) :
00042   kinematic_model_(kinematic_model)
00043 {
00044   root_transform_.setIdentity();
00045   buildState();
00046 }
00047 
00048 random_numbers::RandomNumberGenerator& robot_state::RobotState::getRandomNumberGenerator()
00049 {
00050   if (!rng_)
00051     rng_.reset(new random_numbers::RandomNumberGenerator());
00052   return *rng_;
00053 }
00054 
00055 void robot_state::RobotState::buildState()
00056 {
00057   const std::vector<const robot_model::JointModel*>& joint_model_vector = kinematic_model_->getJointModels();
00058   joint_state_vector_.resize(joint_model_vector.size());
00059 
00060   // create joint states
00061   for (std::size_t i = 0; i < joint_model_vector.size() ; ++i)
00062   {
00063     joint_state_vector_[i] = new JointState(joint_model_vector[i]);
00064     joint_state_map_[joint_state_vector_[i]->getName()] = joint_state_vector_[i];
00065   }
00066 
00067   // create link states
00068   const std::vector<const robot_model::LinkModel*>& link_model_vector = kinematic_model_->getLinkModels();
00069   link_state_vector_.resize(link_model_vector.size());
00070   for (std::size_t i = 0 ; i < link_model_vector.size() ; ++i)
00071   {
00072     link_state_vector_[i] = new LinkState(this, link_model_vector[i]);
00073     link_state_map_[link_state_vector_[i]->getName()] = link_state_vector_[i];
00074   }
00075 
00076   // now we need to figure out who the link parents are
00077   for (std::size_t i = 0; i < link_state_vector_.size(); ++i)
00078   {
00079     const robot_model::JointModel* parent_joint_model = link_state_vector_[i]->getLinkModel()->getParentJointModel();
00080     link_state_vector_[i]->parent_joint_state_ = joint_state_map_[parent_joint_model->getName()];
00081     if (parent_joint_model->getParentLinkModel() != NULL)
00082       link_state_vector_[i]->parent_link_state_ = link_state_map_[parent_joint_model->getParentLinkModel()->getName()];
00083   }
00084 
00085   // compute mimic joint state pointers
00086   for (std::size_t i = 0; i < joint_state_vector_.size(); ++i)
00087   {
00088     const std::vector<const robot_model::JointModel*> &mr = joint_state_vector_[i]->joint_model_->getMimicRequests();
00089     for (std::size_t j = 0 ; j < mr.size() ; ++j)
00090       joint_state_vector_[i]->mimic_requests_.push_back(joint_state_map_[mr[j]->getName()]);
00091   }
00092 
00093   // now make joint_state_groups
00094   const std::map<std::string, robot_model::JointModelGroup*>& joint_model_group_map = kinematic_model_->getJointModelGroupMap();
00095   for (std::map<std::string, robot_model::JointModelGroup*>::const_iterator it = joint_model_group_map.begin() ;
00096        it != joint_model_group_map.end() ; ++it)
00097     joint_state_group_map_[it->first] = new JointStateGroup(this, it->second);
00098 }
00099 
00100 robot_state::RobotState::RobotState(const RobotState &ks)
00101 {
00102   copyFrom(ks);
00103 }
00104 
00105 robot_state::RobotState& robot_state::RobotState::operator=(const RobotState &other)
00106 {
00107   copyFrom(other);
00108   return *this;
00109 }
00110 
00111 void robot_state::RobotState::copyFrom(const RobotState &ks)
00112 {
00113   //need to delete anything already in the state
00114   for (std::size_t i = 0; i < joint_state_vector_.size(); i++)
00115     delete joint_state_vector_[i];
00116   for (std::size_t i = 0; i < link_state_vector_.size(); i++)
00117     delete link_state_vector_[i];
00118   for (std::map<std::string, JointStateGroup*>::iterator it = joint_state_group_map_.begin();
00119        it != joint_state_group_map_.end(); ++it)
00120     delete it->second;
00121 
00122   kinematic_model_ = ks.getRobotModel();
00123   root_transform_ = ks.root_transform_;
00124 
00125   // construct state
00126   buildState();
00127 
00128   // copy attached bodies
00129   clearAttachedBodies();
00130   for (std::map<std::string, AttachedBody*>::const_iterator it = ks.attached_body_map_.begin() ; it != ks.attached_body_map_.end() ; ++it)
00131     attachBody(it->second->getName(), it->second->getShapes(), it->second->getFixedTransforms(),
00132                it->second->getTouchLinks(), it->second->getAttachedLinkName(), it->second->getDetachPosture());
00133 
00134   std::map<std::string, double> current_joint_values;
00135   ks.getStateValues(current_joint_values);
00136   setStateValues(current_joint_values);
00137 }
00138 
00139 robot_state::RobotState::~RobotState()
00140 {
00141   clearAttachedBodies(); // we call this instead of just deleting so we get the attached body callbacks
00142   for (std::size_t i = 0; i < joint_state_vector_.size(); i++)
00143     delete joint_state_vector_[i];
00144   for (std::size_t i = 0; i < link_state_vector_.size(); i++)
00145     delete link_state_vector_[i];
00146   for (std::map<std::string, JointStateGroup*>::iterator it = joint_state_group_map_.begin();
00147        it != joint_state_group_map_.end(); ++it)
00148     delete it->second;
00149 }
00150 
00151 bool robot_state::RobotState::setStateValues(const std::vector<double>& joint_state_values)
00152 {
00153   if (joint_state_values.size() != getVariableCount())
00154   {
00155     logError("RobotState: Incorrect variable count specified for array of joint values. Expected %u but got %u values",
00156              getVariableCount(), (int)joint_state_values.size());
00157     return false;
00158   }
00159 
00160   unsigned int value_counter = 0;
00161   for(std::size_t i = 0; i < joint_state_vector_.size(); i++)
00162   {
00163     unsigned int dim = joint_state_vector_[i]->getVariableCount();
00164     if (dim != 0 && joint_state_vector_[i]->getJointModel()->getMimic() == NULL)
00165     {
00166       joint_state_vector_[i]->setVariableValues(&joint_state_values[value_counter]);
00167       value_counter += dim;
00168     }
00169   }
00170   updateLinkTransforms();
00171   return true;
00172 }
00173 
00174 void robot_state::RobotState::setStateValues(const std::map<std::string, double>& joint_state_map)
00175 {
00176   for (std::size_t i = 0 ; i < joint_state_vector_.size() ; ++i)
00177     if (joint_state_vector_[i]->getJointModel()->getMimic() == NULL)
00178       joint_state_vector_[i]->setVariableValues(joint_state_map);
00179   updateLinkTransforms();
00180 }
00181 
00182 void robot_state::RobotState::setStateValues(const std::map<std::string, double>& joint_state_map, std::vector<std::string>& missing)
00183 {
00184   missing.clear();
00185   for (std::size_t i = 0 ; i < joint_state_vector_.size() ; ++i)
00186     if (joint_state_vector_[i]->getJointModel()->getMimic() == NULL)
00187       joint_state_vector_[i]->setVariableValues(joint_state_map, missing);
00188   updateLinkTransforms();
00189 }
00190 
00191 void robot_state::RobotState::setStateValues(const sensor_msgs::JointState& js)
00192 {
00193   std::map<std::string, double> vals;
00194   std::size_t position_size = js.position.size();
00195   for(std::size_t i = 0 ; i < js.name.size() ; ++i)
00196     if (i < position_size)
00197       vals[js.name[i]] = js.position[i];
00198   setStateValues(vals);
00199 }
00200 
00201 void robot_state::RobotState::setStateValues(const std::vector<std::string>& joint_names,
00202                                                      const std::vector<double>& joint_values)
00203 {
00204   std::map<std::string, double> vals;
00205   unsigned int position_size = joint_values.size();
00206   for(unsigned int i = 0 ; i < joint_names.size() ; ++i)
00207     if (i < position_size)
00208       vals[joint_names[i]] = joint_values[i];
00209   setStateValues(vals);
00210 }
00211 
00212 void robot_state::RobotState::getStateValues(std::vector<double>& joint_state_values) const
00213 {
00214   joint_state_values.clear();
00215   for (std::size_t i = 0; i < joint_state_vector_.size(); i++)
00216     if (joint_state_vector_[i]->getJointModel()->getMimic() == NULL)
00217     {
00218       const std::vector<double> &jv = joint_state_vector_[i]->getVariableValues();
00219       joint_state_values.insert(joint_state_values.end(), jv.begin(), jv.end());
00220     }
00221 }
00222 
00223 void robot_state::RobotState::getStateValues(std::map<std::string,double>& joint_state_values) const
00224 {
00225   joint_state_values.clear();
00226   for (std::size_t i = 0; i < joint_state_vector_.size(); ++i)
00227   {
00228     const std::vector<double> &jsv = joint_state_vector_[i]->getVariableValues();
00229     const std::vector<std::string> &jsn = joint_state_vector_[i]->getVariableNames();
00230     for (std::size_t j = 0 ; j < jsv.size(); ++j)
00231       joint_state_values[jsn[j]] = jsv[j];
00232   }
00233 }
00234 
00235 void robot_state::RobotState::getStateValues(sensor_msgs::JointState& js) const
00236 {
00237   std::map<std::string, double> joint_state_values;
00238   getStateValues(joint_state_values);
00239   js.name.resize(joint_state_values.size());
00240   js.position.resize(joint_state_values.size());
00241 
00242   unsigned int i = 0;
00243   for(std::map<std::string, double>::iterator it = joint_state_values.begin() ; it != joint_state_values.end() ; ++it, ++i)
00244   {
00245     js.name[i] = it->first;
00246     js.position[i] = it->second;
00247   }
00248 }
00249 
00250 void robot_state::RobotState::updateLinkTransforms()
00251 {
00252   for(unsigned int i = 0; i < link_state_vector_.size(); i++)
00253     link_state_vector_[i]->computeTransform();
00254 }
00255 
00256 bool robot_state::RobotState::updateStateWithLinkAt(const std::string& link_name, const Eigen::Affine3d& transform, bool backward)
00257 {
00258   if (!hasLinkState(link_name))
00259     return false;
00260 
00261   if (backward)
00262     link_state_map_[link_name]->computeTransformBackward(transform);
00263   else
00264     link_state_map_[link_name]->computeTransformForward(transform);
00265 
00266   return true;
00267 }
00268 
00269 const Eigen::Affine3d& robot_state::RobotState::getRootTransform() const
00270 {
00271   return root_transform_;
00272 }
00273 
00274 void robot_state::RobotState::setRootTransform(const Eigen::Affine3d &transform)
00275 {
00276   root_transform_ = transform;
00277 }
00278 
00279 void robot_state::RobotState::setToDefaultValues()
00280 {
00281   std::vector<double> default_joint_states;
00282   kinematic_model_->getVariableDefaultValues(default_joint_states);
00283   setStateValues(default_joint_states);
00284 }
00285 
00286 void robot_state::RobotState::setToRandomValues()
00287 {
00288   random_numbers::RandomNumberGenerator &rng = getRandomNumberGenerator();
00289   std::vector<double> random_joint_states;
00290   kinematic_model_->getVariableRandomValues(rng, random_joint_states);
00291   setStateValues(random_joint_states);
00292 }
00293 
00294 double robot_state::RobotState::infinityNormDistance(const robot_state::RobotState *other) const
00295 {
00296   if (joint_state_vector_.empty())
00297     return 0.0;
00298   double max_d = joint_state_vector_[0]->distance(other->joint_state_vector_[0]);
00299   for (std::size_t i = 1 ; i < joint_state_vector_.size() ; ++i)
00300   {
00301     double d = joint_state_vector_[i]->distance(other->joint_state_vector_[i]);
00302     if (d > max_d)
00303       max_d = d;
00304   }
00305   return max_d;
00306 }
00307 
00308 bool robot_state::RobotState::satisfiesBounds(const std::string& joint) const
00309 {
00310   std::vector<std::string> j(1, joint);
00311   return satisfiesBounds(j);
00312 }
00313 
00314 bool robot_state::RobotState::satisfiesBounds(const std::vector<std::string>& joints) const
00315 {
00316   for (std::vector<std::string>::const_iterator it = joints.begin(); it != joints.end(); ++it)
00317   {
00318     const JointState* joint_state = getJointState(*it);
00319     if (joint_state == NULL)
00320     {
00321       logWarn("No joint with name '%s'", it->c_str());
00322       return false;
00323     }
00324     if (!joint_state->satisfiesBounds())
00325       return false;
00326   }
00327   return true;
00328 }
00329 
00330 bool robot_state::RobotState::satisfiesBounds() const
00331 {
00332   for (std::size_t i = 0 ; i < joint_state_vector_.size() ; ++i)
00333     if (!joint_state_vector_[i]->satisfiesBounds())
00334       return false;
00335   return true;
00336 }
00337 
00338 void robot_state::RobotState::enforceBounds()
00339 {
00340   for (std::size_t i = 0 ; i < joint_state_vector_.size() ; ++i)
00341     joint_state_vector_[i]->enforceBounds();
00342   updateLinkTransforms();
00343 }
00344 
00345 const robot_state::JointStateGroup* robot_state::RobotState::getJointStateGroup(const std::string &name) const
00346 {
00347   if (joint_state_group_map_.find(name) == joint_state_group_map_.end())
00348     return NULL;
00349   return joint_state_group_map_.find(name)->second;
00350 }
00351 
00352 robot_state::JointStateGroup* robot_state::RobotState::getJointStateGroup(const std::string &name)
00353 {
00354   if (joint_state_group_map_.find(name) == joint_state_group_map_.end())
00355     return NULL;
00356   return joint_state_group_map_.find(name)->second;
00357 }
00358 
00359 bool robot_state::RobotState::hasJointStateGroup(const std::string &name) const
00360 {
00361   return joint_state_group_map_.find(name) != joint_state_group_map_.end();
00362 }
00363 
00364 void robot_state::RobotState::getJointStateGroupNames(std::vector<std::string>& names) const
00365 {
00366   for (std::map<std::string, JointStateGroup*>::const_iterator it = joint_state_group_map_.begin();
00367        it != joint_state_group_map_.end() ; ++it)
00368     names.push_back(it->first);
00369 }
00370 
00371 bool robot_state::RobotState::hasJointState(const std::string &joint) const
00372 {
00373   return joint_state_map_.find(joint) != joint_state_map_.end();
00374 }
00375 
00376 bool robot_state::RobotState::hasLinkState(const std::string& link) const
00377 {
00378   return link_state_map_.find(link) != link_state_map_.end();
00379 }
00380 
00381 robot_state::JointState* robot_state::RobotState::getJointState(const std::string &name) const
00382 {
00383   std::map<std::string, JointState*>::const_iterator it = joint_state_map_.find(name);
00384   if (it == joint_state_map_.end())
00385   {
00386     logError("Joint state '%s' not found", name.c_str());
00387     return NULL;
00388   }
00389   else
00390     return it->second;
00391 }
00392 
00393 robot_state::LinkState* robot_state::RobotState::getLinkState(const std::string &name) const
00394 {
00395   std::map<std::string, LinkState*>::const_iterator it = link_state_map_.find(name);
00396   if (it == link_state_map_.end())
00397   {
00398     logError("Link state '%s' not found", name.c_str());
00399     return NULL;
00400   }
00401   else
00402     return it->second;
00403 }
00404 
00405 bool robot_state::RobotState::hasAttachedBody(const std::string &id) const
00406 {
00407   return attached_body_map_.find(id) != attached_body_map_.end();
00408 }
00409 
00410 const robot_state::AttachedBody* robot_state::RobotState::getAttachedBody(const std::string &id) const
00411 {
00412   std::map<std::string, AttachedBody*>::const_iterator it = attached_body_map_.find(id);
00413   if (it == attached_body_map_.end())
00414   {
00415     logError("Attached body '%s' not found", id.c_str());
00416     return NULL;
00417   }
00418   else
00419     return it->second;
00420 }
00421 
00422 void robot_state::RobotState::attachBody(AttachedBody *attached_body)
00423 {
00424   LinkState *ls = getLinkState(attached_body->getAttachedLinkName());
00425   if (ls)
00426   {
00427     attached_body_map_[attached_body->getName()] = attached_body;
00428     ls->attached_body_map_[attached_body->getName()] = attached_body;
00429     attached_body->computeTransform(ls->getGlobalLinkTransform());
00430     if (attached_body_update_callback_)
00431       attached_body_update_callback_(attached_body, true);
00432   }
00433 }
00434 
00435 void robot_state::RobotState::attachBody(const std::string &id,
00436                                          const std::vector<shapes::ShapeConstPtr> &shapes,
00437                                          const EigenSTL::vector_Affine3d &attach_trans,
00438                                          const std::set<std::string> &touch_links,
00439                                          const std::string &link,
00440                                          const sensor_msgs::JointState &detach_posture)
00441 {
00442   LinkState *ls = getLinkState(link);
00443   if (ls)
00444   {
00445     AttachedBody *ab = new AttachedBody(ls->getLinkModel(), id, shapes, attach_trans, touch_links, detach_posture);
00446     ls->attached_body_map_[id] = ab;
00447     attached_body_map_[id] = ab;
00448     ab->computeTransform(ls->getGlobalLinkTransform());
00449     if (attached_body_update_callback_)
00450       attached_body_update_callback_(ab, true);
00451   }
00452 }
00453 
00454 void robot_state::RobotState::attachBody(const std::string &id,
00455                                          const std::vector<shapes::ShapeConstPtr> &shapes,
00456                                          const EigenSTL::vector_Affine3d &attach_trans,
00457                                          const std::vector<std::string> &touch_links,
00458                                          const std::string &link,
00459                                          const sensor_msgs::JointState &detach_posture)
00460 {
00461   std::set<std::string> touch_links_set(touch_links.begin(), touch_links.end());
00462   attachBody(id, shapes, attach_trans, touch_links_set, link, detach_posture);
00463 }
00464 
00465 void robot_state::RobotState::getAttachedBodies(std::vector<const AttachedBody*> &attached_bodies) const
00466 {
00467   attached_bodies.clear();
00468   attached_bodies.reserve(attached_body_map_.size());
00469   for (std::map<std::string, AttachedBody*>::const_iterator it = attached_body_map_.begin() ; it != attached_body_map_.end() ;  ++it)
00470     attached_bodies.push_back(it->second);
00471 }
00472 
00473 void robot_state::RobotState::clearAttachedBodies()
00474 {
00475   for (std::map<std::string, AttachedBody*>::const_iterator it = attached_body_map_.begin() ; it != attached_body_map_.end() ;  ++it)
00476   {
00477     if (attached_body_update_callback_)
00478       attached_body_update_callback_(it->second, false);
00479     LinkState *ls = getLinkState(it->second->getAttachedLinkName());
00480     if (ls)
00481       ls->attached_body_map_.clear();
00482     delete it->second;
00483   }
00484   attached_body_map_.clear();
00485 }
00486 
00487 void robot_state::RobotState::clearAttachedBodies(const std::string &link_name)
00488 {
00489   LinkState *ls = getLinkState(link_name);
00490   if (ls)
00491   {
00492     for (std::map<std::string, AttachedBody*>::const_iterator it = ls->attached_body_map_.begin() ; it != ls->attached_body_map_.end() ;  ++it)
00493     {
00494       if (attached_body_update_callback_)
00495         attached_body_update_callback_(it->second, false);
00496       attached_body_map_.erase(it->first);
00497       delete it->second;
00498     }
00499     ls->attached_body_map_.clear();
00500   }
00501 }
00502 
00503 bool robot_state::RobotState::clearAttachedBody(const std::string &id)
00504 {
00505   std::map<std::string, AttachedBody*>::iterator it = attached_body_map_.find(id);
00506   if (it != attached_body_map_.end())
00507   {
00508     if (attached_body_update_callback_)
00509       attached_body_update_callback_(it->second, false);
00510     LinkState *ls = getLinkState(it->second->getAttachedLinkName());
00511     if (ls)
00512     {
00513       std::map<std::string, AttachedBody*>::iterator jt = ls->attached_body_map_.find(id);
00514       ls->attached_body_map_.erase(jt);
00515     }
00516     delete it->second;
00517     attached_body_map_.erase(it);
00518     return true;
00519   }
00520   else
00521     return false;
00522 }
00523 
00524 namespace
00525 {
00526 static inline void updateAABB(const Eigen::Affine3d &t, const Eigen::Vector3d &e, std::vector<double> &aabb)
00527 {
00528   Eigen::Vector3d v = e / 2.0;
00529   Eigen::Vector3d c2 = t * v;
00530   v = -v;
00531   Eigen::Vector3d c1 = t * v;
00532   if (aabb.empty())
00533   {
00534     aabb.resize(6);
00535     aabb[0] = c1.x();
00536     aabb[2] = c1.y();
00537     aabb[4] = c1.z();
00538     aabb[1] = c2.x();
00539     aabb[3] = c2.y();
00540     aabb[5] = c2.z();
00541   }
00542   else
00543   {
00544     if (aabb[0] > c1.x())
00545       aabb[0] = c1.x();
00546     if (aabb[2] > c1.y())
00547       aabb[2] = c1.y();
00548     if (aabb[4] > c1.z())
00549       aabb[4] = c1.z();
00550     if (aabb[1] < c2.x())
00551       aabb[1] = c2.x();
00552     if (aabb[3] < c2.y())
00553       aabb[3] = c2.y();
00554     if (aabb[5] < c2.z())
00555       aabb[5] = c2.z();
00556   }
00557 }
00558 }
00559 
00560 void robot_state::RobotState::computeAABB(std::vector<double> &aabb) const
00561 {
00562   aabb.clear();
00563   for (std::size_t i = 0; i < link_state_vector_.size(); ++i)
00564   {
00565     const Eigen::Affine3d &t = link_state_vector_[i]->getGlobalCollisionBodyTransform();
00566     const Eigen::Vector3d &e = link_state_vector_[i]->getLinkModel()->getShapeExtentsAtOrigin();
00567     updateAABB(t, e, aabb);
00568   }
00569   for (std::map<std::string, AttachedBody*>::const_iterator it = attached_body_map_.begin() ; it != attached_body_map_.end() ; ++it)
00570   {
00571     const EigenSTL::vector_Affine3d &ts = it->second->getGlobalCollisionBodyTransforms();
00572     const std::vector<shapes::ShapeConstPtr> &ss = it->second->getShapes();
00573     for (std::size_t i = 0 ; i < ts.size() ; ++i)
00574     {
00575       Eigen::Vector3d e = shapes::computeShapeExtents(ss[i].get());
00576       updateAABB(ts[i], e, aabb);
00577     }
00578   }
00579   if (aabb.empty())
00580     aabb.resize(6, 0.0);
00581 }
00582 
00583 double robot_state::RobotState::distance(const RobotState &state) const
00584 {
00585   double d = 0.0;
00586   const std::vector<JointState*> &other = state.getJointStateVector();
00587   for (std::size_t i = 0; i < joint_state_vector_.size(); ++i)
00588     d += joint_state_vector_[i]->distance(other[i]) * joint_state_vector_[i]->getJointModel()->getDistanceFactor();
00589   return d;
00590 }
00591 
00592 void robot_state::RobotState::interpolate(const RobotState &to, const double t, RobotState &dest) const
00593 {
00594   for (std::size_t i = 0 ; i < joint_state_vector_.size() ; ++i)
00595     joint_state_vector_[i]->interpolate(to.joint_state_vector_[i], t, dest.joint_state_vector_[i]);
00596   dest.updateLinkTransforms();
00597 }
00598 
00599 const Eigen::Affine3d& robot_state::RobotState::getFrameTransform(const std::string &id) const
00600 {
00601   if (!id.empty() && id[0] == '/')
00602     return getFrameTransform(id.substr(1));
00603   static const Eigen::Affine3d identity_transform = Eigen::Affine3d::Identity();
00604   if (id == kinematic_model_->getModelFrame())
00605     return identity_transform;
00606   std::map<std::string, LinkState*>::const_iterator it = link_state_map_.find(id);
00607   if (it != link_state_map_.end())
00608     return it->second->getGlobalLinkTransform();
00609   std::map<std::string, AttachedBody*>::const_iterator jt = attached_body_map_.find(id);
00610   if (jt == attached_body_map_.end())
00611   {
00612     logError("Transform from frame '%s' to frame '%s' is not known ('%s' should be a link name or an attached body id).",
00613              id.c_str(), kinematic_model_->getModelFrame().c_str(), id.c_str());
00614     return identity_transform;
00615   }
00616   const EigenSTL::vector_Affine3d &tf = jt->second->getGlobalCollisionBodyTransforms();
00617   if (tf.empty())
00618   {
00619     logError("Attached body '%s' has no geometry associated to it. No transform to return.", id.c_str());
00620     return identity_transform;
00621   }
00622   if (tf.size() > 1)
00623     logWarn("There are multiple geometries associated to attached body '%s'. Returning the transform for the first one.", id.c_str());
00624   return tf[0];
00625 }
00626 
00627 bool robot_state::RobotState::knowsFrameTransform(const std::string &id) const
00628 {
00629   if (!id.empty() && id[0] == '/')
00630     return knowsFrameTransform(id.substr(1));
00631   if (hasLinkState(id))
00632     return true;
00633   std::map<std::string, AttachedBody*>::const_iterator it = attached_body_map_.find(id);
00634   return it != attached_body_map_.end() && it->second->getGlobalCollisionBodyTransforms().size() == 1;
00635 }
00636 
00637 // ------ marker functions ------
00638 
00639 void robot_state::RobotState::getRobotMarkers(visualization_msgs::MarkerArray& arr,
00640                                               const std::vector<std::string> &link_names,
00641                                               const std_msgs::ColorRGBA& color,
00642                                               const std::string& ns,
00643                                               const ros::Duration& dur,
00644                                               bool include_attached) const
00645 {
00646   std::size_t cur_num = arr.markers.size();
00647   getRobotMarkers(arr, link_names, include_attached);
00648   unsigned int id = cur_num;
00649   for (std::size_t i = cur_num ; i < arr.markers.size() ; ++i, ++id)
00650   {
00651     arr.markers[i].ns = ns;
00652     arr.markers[i].id = id;
00653     arr.markers[i].lifetime = dur;
00654     arr.markers[i].color = color;
00655   }
00656 }
00657 
00658 void robot_state::RobotState::getRobotMarkers(visualization_msgs::MarkerArray& arr, const std::vector<std::string> &link_names, bool include_attached) const
00659 {
00660   ros::Time tm = ros::Time::now();
00661   for (std::size_t i = 0; i < link_names.size(); ++i)
00662   {
00663     logDebug("Trying to get marker for link '%s'", link_names[i].c_str());
00664     visualization_msgs::Marker mark;
00665     const LinkState* ls = getLinkState(link_names[i]);
00666     if (!ls)
00667       continue;
00668     if (include_attached)
00669     {
00670       std::vector<const AttachedBody*> attached_bodies;
00671       ls->getAttachedBodies(attached_bodies);
00672       for (std::size_t j = 0; j < attached_bodies.size(); ++j)
00673         if (attached_bodies[j]->getShapes().size() > 0)
00674         {
00675           visualization_msgs::Marker att_mark;
00676           att_mark.header.frame_id = kinematic_model_->getModelFrame();
00677           att_mark.header.stamp = tm;
00678           shapes::constructMarkerFromShape(attached_bodies[j]->getShapes()[0].get(), att_mark);
00679           tf::poseEigenToMsg(attached_bodies[j]->getGlobalCollisionBodyTransforms()[0], att_mark.pose);
00680           arr.markers.push_back(att_mark);
00681         }
00682     }
00683     if (!ls->getLinkModel() || !ls->getLinkModel()->getShape())
00684       continue;
00685     mark.header.frame_id = kinematic_model_->getModelFrame();
00686     mark.header.stamp = tm;
00687     tf::poseEigenToMsg(ls->getGlobalCollisionBodyTransform(), mark.pose);
00688 
00689     // we prefer using the visual mesh, if a mesh is available
00690     const std::string& mesh_resource = ls->getLinkModel()->getVisualMeshFilename();
00691     if (mesh_resource.empty())
00692     {
00693       if (!shapes::constructMarkerFromShape(ls->getLinkModel()->getShape().get(), mark))
00694         continue;
00695       // if the object is invisible (0 volume) we skip it
00696       if (fabs(mark.scale.x * mark.scale.y * mark.scale.z) < std::numeric_limits<float>::epsilon())
00697         continue;
00698     }
00699     else
00700     {
00701       mark.type = mark.MESH_RESOURCE;
00702       mark.mesh_use_embedded_materials = false;
00703       mark.mesh_resource = mesh_resource;
00704       const Eigen::Vector3d &mesh_scale = ls->getLinkModel()->getVisualMeshScale();
00705 
00706       mark.scale.x = mesh_scale[0];
00707       mark.scale.y = mesh_scale[1];
00708       mark.scale.z = mesh_scale[2];
00709     }
00710     arr.markers.push_back(mark);
00711   }
00712 }
00713 
00714 void robot_state::RobotState::setAttachedBodyUpdateCallback(const AttachedBodyCallback &callback)
00715 {
00716   attached_body_update_callback_ = callback;
00717 }
00718 
00719 // ------ printing transforms -----
00720 
00721 void robot_state::RobotState::printStateInfo(std::ostream &out) const
00722 {
00723   std::map<std::string,double> val;
00724   getStateValues(val);
00725   for (std::map<std::string, double>::iterator it = val.begin() ; it != val.end() ; ++it)
00726     out << it->first << " = " << it->second << std::endl;
00727 }
00728 
00729 void robot_state::RobotState::getPoseString(std::stringstream& ss, const Eigen::Affine3d& pose, const std::string& pfx)
00730 {
00731   ss.precision(3);
00732   for (int y=0;y<4;y++)
00733   {
00734     ss << pfx;
00735     for (int x=0;x<4;x++)
00736     {
00737       ss << std::setw(8) << pose(y,x) << " ";
00738     }
00739     ss << std::endl;
00740   }
00741 }
00742 
00743 void robot_state::RobotState::getStateTreeJointString(std::stringstream& ss, const robot_state::JointState* js, const std::string& pfx0, bool last) const
00744 {
00745   std::string pfx = pfx0 + "+--";
00746 
00747   const robot_model::JointModel* jm = js->getJointModel();
00748   ss << pfx << "Joint: " << jm->getName() << std::endl;
00749 
00750   pfx = pfx0 + (last ? "   " : "|  ");
00751 
00752   for (int i=0; i<js->getVariableCount(); i++)
00753   {
00754     ss.precision(3);
00755     ss << pfx << js->getVariableNames()[i] << std::setw(8) << js->getVariableValues()[i] << std::endl;
00756   }
00757 
00758   const robot_model::LinkModel* lm = jm->getChildLinkModel();
00759   const LinkState* ls = getLinkState(jm->getChildLinkModel()->getName());
00760 
00761   ss << pfx << "Link: " << lm->getName() << std::endl;
00762   getPoseString(ss, lm->getJointOriginTransform(), pfx + "joint_origin:");
00763   getPoseString(ss, js->getVariableTransform(), pfx + "joint_variable:");
00764   getPoseString(ss, ls->getGlobalLinkTransform(), pfx + "link_global:");
00765 
00766   for (std::vector<robot_model::JointModel*>::const_iterator it = lm->getChildJointModels().begin() ; it != lm->getChildJointModels().end() ; ++it)
00767   {
00768     const robot_model::JointModel* cjm = *it;
00769     getStateTreeJointString(ss, getJointState(cjm->getName()), pfx, it+1 == lm->getChildJointModels().end());
00770   }
00771 }
00772 
00773 std::string robot_state::RobotState::getStateTreeString(const std::string& prefix) const
00774 {
00775   std::stringstream ss;
00776   ss << "ROBOT: " << getRobotModel()->getName() << std::endl;
00777   getPoseString(ss, getRootTransform(), "   Root: ");
00778   getStateTreeJointString(ss, getJointState(getRobotModel()->getRoot()->getName()), "   ", true);
00779   return ss.str();
00780 }
00781 
00782 void robot_state::RobotState::printTransform(const std::string &st, const Eigen::Affine3d &t, std::ostream &out) const
00783 {
00784   out << st << std::endl;
00785   const Eigen::Vector3d &v = t.translation();
00786   out << "  origin: " << v.x() << ", " << v.y() << ", " << v.z() << std::endl;
00787   Eigen::Quaterniond q(t.rotation());
00788   out << "  quaternion: " << q.x() << ", " << q.y() << ", " << q.z() << ", " << q.w() << std::endl;
00789 }
00790 
00791 void robot_state::RobotState::printTransforms(std::ostream &out) const
00792 {
00793   out << "Joint transforms:" << std::endl;
00794   for (unsigned int i = 0 ; i < joint_state_vector_.size() ; ++i)
00795   {
00796     printTransform(joint_state_vector_[i]->getName(), joint_state_vector_[i]->getVariableTransform(), out);
00797     out << std::endl;
00798   }
00799   out << "Link poses:" << std::endl;
00800   for (unsigned int i = 0 ; i < link_state_vector_.size() ; ++i)
00801   {
00802     printTransform(link_state_vector_[i]->getName(), link_state_vector_[i]->getGlobalCollisionBodyTransform(), out);
00803     out << std::endl;
00804   }
00805 }


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Mon Oct 6 2014 02:24:47