00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
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
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
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
00126 buildState();
00127
00128
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();
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
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
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
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
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 }