distance_manager.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include <limits>
00019 #include <string>
00020 #include <vector>
00021 
00022 #include "cob_obstacle_distance/distance_manager.hpp"
00023 
00024 
00025 #include <stdint.h>
00026 
00027 #include <ros/ros.h>
00028 
00029 #include <fcl/collision_object.h>
00030 #include <fcl/collision.h>
00031 #include <fcl/distance.h>
00032 #include <fcl/collision_data.h>
00033 
00034 #include <std_msgs/Float64.h>
00035 #include <visualization_msgs/Marker.h>
00036 
00037 #include "cob_control_msgs/ObstacleDistance.h"
00038 #include "cob_control_msgs/ObstacleDistances.h"
00039 
00040 #include <boost/filesystem.hpp>
00041 #include <boost/filesystem/path.hpp>
00042 #include <boost/pointer_cast.hpp>
00043 
00044 #include <eigen_conversions/eigen_kdl.h>
00045 #include <eigen_conversions/eigen_msg.h>
00046 
00047 #include <kdl_conversions/kdl_msg.h>
00048 
00049 #include <urdf/model.h>
00050 
00051 #include <shape_msgs/Mesh.h>
00052 #include <shape_msgs/MeshTriangle.h>
00053 #include <shape_msgs/SolidPrimitive.h>
00054 
00055 #define VEC_X 0
00056 #define VEC_Y 1
00057 #define VEC_Z 2
00058 
00059 
00060 uint32_t DistanceManager::seq_nr_ = 0;
00061 
00062 DistanceManager::DistanceManager(ros::NodeHandle& nh) : nh_(nh), stop_sca_threads_(false)
00063 {}
00064 
00065 DistanceManager::~DistanceManager()
00066 {
00067     this->clear();
00068 }
00069 
00070 int DistanceManager::init()
00071 {
00072     this->stop_sca_threads_ = false;
00073 
00074     // Latched and continue in case there is no subscriber at the moment for a marker
00075     this->marker_pub_ = this->nh_.advertise<visualization_msgs::MarkerArray>("obstacle_distance/marker", 10, true);
00076     this->obstacle_distances_pub_ = this->nh_.advertise<cob_control_msgs::ObstacleDistances>("obstacle_distance", 1);
00077     obstacle_mgr_.reset(new ShapesManager(this->marker_pub_));
00078     object_of_interest_mgr_.reset(new ShapesManager(this->marker_pub_));
00079     KDL::Tree robot_structure;
00080     if (!kdl_parser::treeFromParam("/robot_description", robot_structure))
00081     {
00082         ROS_ERROR("Failed to construct kdl tree from parameter '/robot_description'.");
00083         return -1;
00084     }
00085 
00086     if (!nh_.getParam("joint_names", this->joints_))
00087     {
00088         ROS_ERROR("Failed to get parameter \"joint_names\".");
00089         return -2;
00090     }
00091 
00092     if (!nh_.getParam("root_frame", this->root_frame_id_))
00093     {
00094         ROS_ERROR("Failed to get parameter \"chain_base_link\".");
00095         return -3;
00096     }
00097 
00098     if (!nh_.getParam("chain_base_link", this->chain_base_link_))
00099     {
00100         ROS_ERROR("Failed to get parameter \"chain_base_link\".");
00101         return -3;
00102     }
00103 
00104     if (!nh_.getParam("chain_tip_link", this->chain_tip_link_))
00105     {
00106         ROS_ERROR("Failed to get parameter \"chain_tip_link\".");
00107         return -4;
00108     }
00109 
00110     robot_structure.getChain(this->chain_base_link_, this->chain_tip_link_, this->chain_);
00111     if (chain_.getNrOfJoints() == 0)
00112     {
00113         ROS_ERROR("Failed to initialize kinematic chain");
00114         return -5;
00115     }
00116 
00117     for (uint16_t i = 0; i < chain_.getNrOfSegments(); ++i)
00118     {
00119         KDL::Segment s = chain_.getSegment(i);
00120         this->segments_.push_back(s.getName());
00121         ROS_INFO_STREAM("Managing Segment Name: " << s.getName());
00122     }
00123 
00124     adv_chn_fk_solver_vel_.reset(new AdvancedChainFkSolverVel_recursive(chain_));
00125     last_q_ = KDL::JntArray(chain_.getNrOfJoints());
00126     last_q_dot_ = KDL::JntArray(chain_.getNrOfJoints());
00127     if (!this->link_to_collision_.initParameter(this->root_frame_id_, "/robot_description"))
00128     {
00129         ROS_ERROR("Failed to initialize robot model from URDF by parameter \"/robot_description\".");
00130         return -6;
00131     }
00132     else
00133     {
00134         XmlRpc::XmlRpcValue scm;
00135         bool success = false;
00136         if (nh_.getParam("self_collision_map", scm))
00137         {
00138             success = this->link_to_collision_.initSelfCollision(scm, obstacle_mgr_);
00139         }
00140 
00141         if (!success)
00142         {
00143             ROS_WARN("Parameter 'self_collision_map' not found or map empty.");
00144         }
00145 
00146         for (LinkToCollision::MapSelfCollisions_t::iterator it = this->link_to_collision_.getSelfCollisionsIterBegin();
00147                 it != this->link_to_collision_.getSelfCollisionsIterEnd();
00148                 it++)
00149         {
00150             self_collision_transform_threads_.push_back(std::thread(&DistanceManager::transformSelfCollisionLinks, this, it->first));
00151         }
00152     }
00153 
00154     return 0;
00155 }
00156 
00157 void DistanceManager::clear()
00158 {
00159     this->stop_sca_threads_ = true;
00160     for (std::vector<std::thread>::iterator it = this->self_collision_transform_threads_.begin();
00161             it != this->self_collision_transform_threads_.end(); it++)
00162     {
00163         it->join();
00164     }
00165 
00166     this->obstacle_mgr_->clear();
00167     this->object_of_interest_mgr_->clear();
00168 }
00169 
00170 
00171 void DistanceManager::addObstacle(const std::string& id, PtrIMarkerShape_t s)
00172 {
00173     this->obstacle_mgr_->addShape(id, s);
00174 }
00175 
00176 
00177 void DistanceManager::addObjectOfInterest(const std::string& id, PtrIMarkerShape_t s)
00178 {
00179     this->object_of_interest_mgr_->addShape(id, s);
00180 }
00181 
00182 
00183 void DistanceManager::drawObstacles()
00184 {
00185     this->obstacle_mgr_->draw();
00186 }
00187 
00188 
00189 void DistanceManager::drawObjectsOfInterest()
00190 {
00191     this->object_of_interest_mgr_->draw();
00192 }
00193 
00194 
00195 void DistanceManager::calculate()
00196 {
00197     cob_control_msgs::ObstacleDistances obstacle_distances;
00198 
00199     // Transform needs to be calculated only once for robot structure
00200     // and is same for all obstacles.
00201     if (this->object_of_interest_mgr_->count() > 0)
00202     {
00203         KDL::FrameVel p_dot_out;
00204         KDL::JntArrayVel jnt_arr(last_q_, last_q_dot_);
00205         adv_chn_fk_solver_vel_->JntToCart(jnt_arr, p_dot_out);
00206     }
00207 
00208     for (ShapesManager::MapIter_t it = this->object_of_interest_mgr_->begin(); it != this->object_of_interest_mgr_->end(); ++it)
00209     {
00210         std::string object_of_interest_name = it->first;
00211         std::vector<std::string>::const_iterator str_it = std::find(this->segments_.begin(),
00212                                                                     this->segments_.end(),
00213                                                                     object_of_interest_name);
00214         if (this->segments_.end() == str_it)
00215         {
00216             ROS_ERROR_STREAM("Could not find: " << object_of_interest_name << ". Skipping it ...");
00217             continue;
00218         }
00219 
00220         // Representation of segment_of_interest as specific shape
00221         PtrIMarkerShape_t ooi = it->second;
00222         uint16_t idx = str_it - this->segments_.begin();
00223         geometry_msgs::Pose origin_p = ooi->getOriginRelToFrame();
00224         KDL::Frame origin_f;
00225         tf::poseMsgToKDL(origin_p, origin_f);
00226 
00227         // ******* Start Transformation part **************
00228         KDL::FrameVel frame_vel = adv_chn_fk_solver_vel_->getFrameVelAtSegment(idx);
00229         KDL::Frame frame_pos = frame_vel.GetFrame();
00230         KDL::Frame frame_with_offset = frame_pos * origin_f;
00231 
00232         Eigen::Vector3d chainbase2frame_pos(frame_with_offset.p.x(),
00233                                             frame_with_offset.p.y(),
00234                                             frame_with_offset.p.z());
00235 
00236         Eigen::Affine3d tmp_tf_cb_frame_bl = this->getSynchedCbToBlTransform();
00237         Eigen::Affine3d tmp_inv_tf_cb_frame_bl = tmp_tf_cb_frame_bl.inverse();
00238         Eigen::Vector3d abs_jnt_pos = tmp_inv_tf_cb_frame_bl * chainbase2frame_pos;
00239 
00240         Eigen::Quaterniond q;
00241         tf::quaternionKDLToEigen(frame_with_offset.M, q);
00242         Eigen::Matrix3d x = (tmp_inv_tf_cb_frame_bl * q).rotation();
00243         Eigen::Quaterniond q_1(x);
00244         // ******* End Transformation part **************
00245 
00246         geometry_msgs::Vector3 v3;
00247         geometry_msgs::Quaternion quat;
00248         tf::quaternionEigenToMsg(q_1, quat);
00249         tf::vectorEigenToMsg(abs_jnt_pos, v3);
00250         ooi->updatePose(v3, quat);
00251 
00252         fcl::CollisionObject ooi_co = ooi->getCollisionObject();
00253         fcl::FCL_REAL last_dist = std::numeric_limits<fcl::FCL_REAL>::max();
00254         {  // introduced the block to lock this critical section until block leaved.
00255             std::lock_guard<std::mutex> lock(obstacle_mgr_mtx_);
00256             for (ShapesManager::MapIter_t it = this->obstacle_mgr_->begin(); it != this->obstacle_mgr_->end(); ++it)
00257             {
00258                 const std::string obstacle_id = it->first;
00259                 if (this->link_to_collision_.ignoreSelfCollisionPart(object_of_interest_name, obstacle_id))
00260                 {
00261                     // Ignore elements that can never be in collision
00262                     // (specified in parameter and parent / child frames)
00263                     continue;
00264                 }
00265 
00266                 PtrIMarkerShape_t obstacle = it->second;
00267                 fcl::CollisionObject collision_obj = obstacle->getCollisionObject();
00268                 fcl::DistanceResult dist_result;
00269                 fcl::DistanceRequest dist_request(true, 5.0, 0.01);
00270                 fcl::FCL_REAL dist = fcl::distance(&ooi_co, &collision_obj, dist_request, dist_result);
00271 
00272 
00273                 Eigen::Vector3d abs_obst_vector(dist_result.nearest_points[1][VEC_X],
00274                                                 dist_result.nearest_points[1][VEC_Y],
00275                                                 dist_result.nearest_points[1][VEC_Z]);
00276                 Eigen::Vector3d obst_vector = tmp_tf_cb_frame_bl * abs_obst_vector;
00277 
00278                 Eigen::Vector3d abs_jnt_pos_update(dist_result.nearest_points[0][VEC_X],
00279                                                    dist_result.nearest_points[0][VEC_Y],
00280                                                    dist_result.nearest_points[0][VEC_Z]);
00281 
00282                 // vector from arm base link frame to nearest collision point on frame
00283                 Eigen::Vector3d rel_base_link_frame_pos = tmp_tf_cb_frame_bl * abs_jnt_pos_update;
00284                 ROS_DEBUG_STREAM("Link \"" << object_of_interest_name << "\": Minimal distance: " << dist_result.min_distance);
00285                 if (dist_result.min_distance < MIN_DISTANCE)
00286                 {
00287                     cob_control_msgs::ObstacleDistance od_msg;
00288                     od_msg.distance = dist_result.min_distance;
00289                     od_msg.link_of_interest = object_of_interest_name;
00290                     od_msg.obstacle_id = obstacle_id;
00291                     od_msg.header.frame_id = chain_base_link_;
00292                     od_msg.header.stamp = ros::Time::now();
00293                     od_msg.header.seq = seq_nr_;
00294                     tf::vectorEigenToMsg(obst_vector, od_msg.nearest_point_obstacle_vector);
00295                     tf::vectorEigenToMsg(rel_base_link_frame_pos, od_msg.nearest_point_frame_vector);
00296                     tf::vectorEigenToMsg(chainbase2frame_pos, od_msg.frame_vector);
00297                     obstacle_distances.distances.push_back(od_msg);
00298                 }
00299             }
00300         }
00301     }
00302 
00303     if (obstacle_distances.distances.size() > 0)
00304     {
00305         this->obstacle_distances_pub_.publish(obstacle_distances);
00306     }
00307 }
00308 
00309 
00310 void DistanceManager::transform()
00311 {
00312     while (!this->stop_sca_threads_)
00313     {
00314         try
00315         {
00316             tf::StampedTransform cb_transform_bl;
00317             ros::Time time = ros::Time(0);
00318             if (tf_listener_.waitForTransform(chain_base_link_, root_frame_id_, time, ros::Duration(5.0)))
00319             {
00320                 std::lock_guard<std::mutex> lock(mtx_);
00321                 tf_listener_.lookupTransform(chain_base_link_, root_frame_id_, time, cb_transform_bl);
00322                 tf::transformTFToEigen(cb_transform_bl, tf_cb_frame_bl_);
00323             }
00324         }
00325         catch (tf::TransformException& ex)
00326         {
00327             ROS_ERROR("%s", ex.what());
00328         }
00329 
00330         ros::Duration(0.1).sleep();
00331     }
00332 }
00333 
00334 
00335 void DistanceManager::transformSelfCollisionLinks(const std::string link_name)
00336 {
00337     ROS_INFO_STREAM("Starting transform_listener thread for link name: " << link_name);
00338     while (!this->stop_sca_threads_)
00339     {
00340         try
00341         {
00342             ros::Time time = ros::Time(0);
00343             // https://github.com/ros-visualization/rviz/issues/702: TF listener is thread safe
00344             if (tf_listener_.waitForTransform(root_frame_id_, link_name, time, ros::Duration(5.0)))
00345             {
00346                 std::lock_guard<std::mutex> lock(obstacle_mgr_mtx_);
00347                 tf::StampedTransform stamped_transform;
00348                 geometry_msgs::Transform msg_transform;
00349                 tf_listener_.lookupTransform(root_frame_id_, link_name, time, stamped_transform);
00350                 PtrIMarkerShape_t shape_ptr;
00351                 if (this->obstacle_mgr_->getShape(link_name, shape_ptr))
00352                 {
00353                     geometry_msgs::Pose origin_p = shape_ptr->getOriginRelToFrame();
00354                     tf::Transform tf_origin_pose;
00355                     tf::poseMsgToTF(origin_p, tf_origin_pose);
00356                     tf::Transform updated_pose = tf::Transform(stamped_transform) * tf_origin_pose;
00357                     tf::transformTFToMsg(updated_pose, msg_transform);
00358                     shape_ptr->updatePose(msg_transform.translation, msg_transform.rotation);
00359                 }
00360             }
00361         }
00362         catch (tf::TransformException& ex)
00363         {
00364             ROS_ERROR("%s", ex.what());
00365         }
00366 
00367         ros::Duration(0.1).sleep();
00368     }
00369 }
00370 
00371 
00372 void DistanceManager::jointstateCb(const sensor_msgs::JointState::ConstPtr& msg)
00373 {
00374     KDL::JntArray q_temp = last_q_;
00375     KDL::JntArray q_dot_temp = last_q_dot_;
00376     uint16_t count = 0;
00377 
00378     for (uint16_t j = 0; j < chain_.getNrOfJoints(); j++)
00379     {
00380         for (uint16_t i = 0; i < msg->name.size(); i++)
00381         {
00382             if (strcmp(msg->name[i].c_str(), joints_[j].c_str()) == 0)
00383             {
00384                 q_temp(j) = msg->position[i];
00385                 q_dot_temp(j) = msg->velocity[i];
00386                 count++;
00387                 break;
00388             }
00389         }
00390     }
00391 
00392     if (joints_.size() == count)
00393     {
00394         last_q_ = q_temp;
00395         last_q_dot_ = q_dot_temp;
00396     }
00397     else
00398     {
00399         ROS_ERROR("jointstateCb: received unexpected 'joint_states'");
00400     }
00401 }
00402 
00403 
00404 void DistanceManager::registerObstacle(const moveit_msgs::CollisionObject::ConstPtr& msg)
00405 {
00406     std::lock_guard<std::mutex> lock(obstacle_mgr_mtx_);
00407 
00408     const std::string frame_id = msg->header.frame_id;
00409     tf::StampedTransform frame_transform_root;
00410     Eigen::Affine3d tf_frame_root;
00411 
00412     if (msg->meshes.size() > 0 && msg->primitives.size() > 0)
00413     {
00414         ROS_ERROR_STREAM("registerObstacle: Can either build mesh or primitive but not both in one message for one id.");
00415         return;
00416     }
00417 
00418     if (msg->operation == msg->ADD && this->obstacle_mgr_->count(msg->id) > 0)
00419     {
00420         ROS_ERROR_STREAM("registerObstacle: Element " << msg->id << " exists already. ADD not allowed!");
00421         return;
00422     }
00423 
00424     try
00425     {
00426         ros::Time time = ros::Time(0);
00427         tf_listener_.waitForTransform(root_frame_id_, msg->header.frame_id, time, ros::Duration(0.5));
00428         tf_listener_.lookupTransform(root_frame_id_, msg->header.frame_id, time, frame_transform_root);
00429         tf::transformTFToEigen(frame_transform_root, tf_frame_root);
00430     }
00431     catch (tf::TransformException& ex)
00432     {
00433         ROS_ERROR("TransformException: %s", ex.what());
00434         return;
00435     }
00436 
00437     if ((msg->type.db.length() > 0 && 0 < msg->mesh_poses.size()) ||
00438        (msg->meshes.size() > 0 && msg->meshes.size() == msg->mesh_poses.size()))
00439     {
00440         this->buildObstacleMesh(msg, frame_transform_root);
00441     }
00442 
00443     if (msg->primitives.size() > 0 && msg->primitives.size() == msg->primitive_poses.size())
00444     {
00445         this->buildObstaclePrimitive(msg, frame_transform_root);
00446     }
00447 
00448     this->drawObstacles();
00449 }
00450 
00451 
00452 void DistanceManager::buildObstacleMesh(const moveit_msgs::CollisionObject::ConstPtr& msg, const tf::StampedTransform& transform)
00453 {
00454     uint32_t m_size = msg->mesh_poses.size();
00455     const std::string package_file_name = msg->type.db;  // using db field for package name instead of db json string
00456 
00457     if (msg->mesh_poses.size() > 1)
00458     {
00459         ROS_WARN("Currenty only one mesh per message is supported! So only the first one is processed ...");
00460         m_size = 1;
00461     }
00462 
00463     if (package_file_name.length() <= 0 && msg->mesh_poses.size() != msg->meshes.size())
00464     {
00465        ROS_ERROR("Mesh poses and meshes do not have the same size. If package resource string is empty then the sizes must be equal!");
00466        return;
00467     }
00468 
00469     if (msg->ADD == msg->operation)
00470     {
00471         for (uint32_t i = 0; i < m_size; ++i)
00472         {
00473             geometry_msgs::Pose p = msg->mesh_poses[i];
00474             tf::Pose tf_p;
00475             tf::poseMsgToTF(p, tf_p);
00476             tf::Pose new_tf_p = transform * tf_p;
00477             tf::poseTFToMsg(new_tf_p, p);
00478             PtrIMarkerShape_t sptr_Bvh;
00479             if (package_file_name.length() > 0)
00480             {
00481                 sptr_Bvh.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
00482                                                           package_file_name,
00483                                                           p,
00484                                                           g_shapeMsgTypeToVisMarkerType.obstacle_color_));
00485             }
00486             else
00487             {
00488                 shape_msgs::Mesh m = msg->meshes[i];  // is only filled in case of no package file name has been given
00489                 sptr_Bvh.reset(new MarkerShape<BVH_RSS_t>(this->root_frame_id_,
00490                                                           m,
00491                                                           p,
00492                                                           g_shapeMsgTypeToVisMarkerType.obstacle_color_));
00493             }
00494 
00495             this->addObstacle(msg->id, sptr_Bvh);
00496         }
00497     }
00498     else if (msg->MOVE == msg->operation)
00499     {
00500         PtrIMarkerShape_t sptr;
00501         for (uint32_t i = 0; i < m_size; ++i)
00502         {
00503             if (this->obstacle_mgr_->getShape(msg->id, sptr))
00504             {
00505                 geometry_msgs::Pose p = msg->mesh_poses[i];
00506                 tf::Pose tf_p;
00507                 tf::poseMsgToTF(p, tf_p);
00508                 tf::Pose new_tf_p = transform * tf_p;
00509                 tf::poseTFToMsg(new_tf_p, p);
00510                 sptr->updatePose(p);
00511             }
00512         }
00513     }
00514     else if (msg->REMOVE == msg->operation)
00515     {
00516         this->obstacle_mgr_->removeShape(msg->id);
00517     }
00518     else
00519     {
00520         ROS_ERROR_STREAM("Operation not supported!");
00521     }
00522 }
00523 
00524 
00525 void DistanceManager::buildObstaclePrimitive(const moveit_msgs::CollisionObject::ConstPtr& msg, const tf::StampedTransform& transform)
00526 {
00527     uint32_t p_size = msg->primitives.size();
00528     if (msg->primitives.size() > 1)
00529     {
00530         ROS_WARN("Currenty only one primitive per message is supported! So only the first one is processed ...");
00531         p_size = 1;
00532     }
00533 
00534     if (msg->ADD == msg->operation)
00535     {
00536         for (uint32_t i = 0; i < p_size; ++i)
00537         {
00538             shape_msgs::SolidPrimitive sp = msg->primitives[i];
00539             geometry_msgs::Pose p = msg->primitive_poses[i];
00540             tf::Pose tf_p;
00541             tf::poseMsgToTF(p, tf_p);
00542             tf::Pose new_tf_p = transform * tf_p;
00543             tf::poseTFToMsg(new_tf_p, p);
00544 
00545             PtrIMarkerShape_t sptr;
00546             Eigen::Vector3d dim;
00547             if (shape_msgs::SolidPrimitive::BOX == sp.type)
00548             {
00549                 dim(FCL_BOX_X) = sp.dimensions[shape_msgs::SolidPrimitive::BOX_X];
00550                 dim(FCL_BOX_Y) = sp.dimensions[shape_msgs::SolidPrimitive::BOX_Y];
00551                 dim(FCL_BOX_Z) = sp.dimensions[shape_msgs::SolidPrimitive::BOX_Z];
00552             }
00553             else if (shape_msgs::SolidPrimitive::SPHERE == sp.type)
00554             {
00555                 dim(FCL_RADIUS) = sp.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS];
00556             }
00557             else if (shape_msgs::SolidPrimitive::CYLINDER == sp.type)
00558             {
00559                 dim(FCL_RADIUS) = sp.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS];
00560                 dim(FCL_CYL_LENGTH) = sp.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT];
00561             }
00562             else
00563             {
00564                 ROS_ERROR_STREAM("Shape type not supported: " << sp.type);
00565                 break;
00566             }
00567 
00568             uint32_t shape_type = g_shapeMsgTypeToVisMarkerType.map_[sp.type];
00569             this->link_to_collision_.getMarkerShapeFromType(shape_type,
00570                                                              p,
00571                                                              msg->id,
00572                                                              dim,
00573                                                              sptr);
00574             this->addObstacle(msg->id, sptr);
00575         }
00576     }
00577     else if (msg->MOVE == msg->operation)
00578     {
00579         PtrIMarkerShape_t sptr;
00580         for (uint32_t i = 0; i < p_size; ++i)
00581         {
00582             if (this->obstacle_mgr_->getShape(msg->id, sptr))
00583             {
00584                 geometry_msgs::Pose p = msg->primitive_poses[i];
00585                 tf::Pose tf_p;
00586                 tf::poseMsgToTF(p, tf_p);
00587                 tf::Pose new_tf_p = transform * tf_p;
00588                 tf::poseTFToMsg(new_tf_p, p);
00589                 sptr->updatePose(p);
00590             }
00591         }
00592     }
00593     else if (msg->REMOVE == msg->operation)
00594     {
00595         this->obstacle_mgr_->removeShape(msg->id);
00596     }
00597     else
00598     {
00599         ROS_ERROR_STREAM("Operation not supported!");
00600     }
00601 }
00602 
00603 
00604 bool DistanceManager::registerLinkOfInterest(cob_srvs::SetString::Request& request,
00605                                               cob_srvs::SetString::Response& response)
00606 {
00607     if (this->object_of_interest_mgr_->count(request.data) > 0)
00608     {
00609         response.success = true;
00610         response.message = "Element " + request.data + " already registered.";
00611     }
00612     else
00613     {
00614         try
00615         {
00616             PtrIMarkerShape_t ooi;
00617             Eigen::Quaterniond q;
00618             Eigen::Vector3d v3;
00619             if (this->link_to_collision_.getMarkerShapeFromUrdf(v3, q, request.data, ooi))
00620             {
00621                 this->addObjectOfInterest(request.data, ooi);
00622                 response.success = true;
00623                 response.message = "Successfully registered element " + request.data + ".";
00624             }
00625             else
00626             {
00627                 response.success = false;
00628                 response.message = "Failed to register element " + request.data + "!";
00629             }
00630         }
00631         catch(...)
00632         {
00633             response.success = false;
00634             response.message = "Failed to register element " + request.data + "!";
00635             ROS_ERROR_STREAM(response.message);
00636         }
00637     }
00638 
00639     ROS_INFO_STREAM("DistanceManager::Registration: " << response.message);
00640     return true;
00641 }
00642 
00643 
00644 Eigen::Affine3d DistanceManager::getSynchedCbToBlTransform()
00645 {
00646     std::lock_guard<std::mutex> lock(mtx_);
00647     return this->tf_cb_frame_bl_;
00648 }


cob_obstacle_distance
Author(s): Marco Bezzon
autogenerated on Thu Jun 6 2019 21:19:14