arm_kinematics_constraint_aware.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * Author: Sachin Chitta
00032  */
00033 
00034 #include <arm_kinematics_constraint_aware/arm_kinematics_constraint_aware.h>
00035 
00036 #include <sensor_msgs/JointState.h>
00037 #include <kinematics_msgs/utils.h>
00038 #include <visualization_msgs/Marker.h>
00039 #include <visualization_msgs/MarkerArray.h>
00040 
00041 namespace arm_kinematics_constraint_aware {
00042 
00043 static const std::string IK_WITH_COLLISION_SERVICE = "get_constraint_aware_ik";
00044   static const std::string IK_INFO_SERVICE = "get_ik_solver_info";
00045   static const std::string FK_INFO_SERVICE = "get_fk_solver_info";
00046 static const std::string IK_SERVICE = "get_ik";
00047 static const std::string FK_SERVICE = "get_fk";
00048 static const double IK_DEFAULT_TIMEOUT = 10.0;
00049 
00050 ArmKinematicsConstraintAware::ArmKinematicsConstraintAware(): kinematics_loader_("kinematics_base","kinematics::KinematicsBase"),node_handle_("~"),setup_collision_environment_(false)
00051 {
00052   std::string group_name, kinematics_solver_name;
00053   node_handle_.param<bool>("visualize_solution",visualize_solution_,true);
00054   node_handle_.param<std::string>("group", group_, std::string());
00055   node_handle_.param<std::string>("kinematics_solver",kinematics_solver_name," ");
00056   ROS_INFO("Using kinematics solver name: %s",kinematics_solver_name.c_str());
00057   if (group_.empty())
00058   {
00059     ROS_ERROR("No 'group' parameter specified. Without the name of the group of joints to monitor, node cannot compute collision aware inverse kinematics");
00060     active_ = false;
00061     return;
00062   }
00063 
00064   kinematics_solver_ = NULL;
00065   try
00066   {
00067     kinematics_solver_ = kinematics_loader_.createClassInstance(kinematics_solver_name);
00068   }
00069   catch(pluginlib::PluginlibException& ex)
00070   {
00071     ROS_ERROR("The plugin failed to load. Error: %s", ex.what());    //handle the class failing to load
00072     active_ = false;
00073     return;
00074   }
00075   if(kinematics_solver_->initialize(group_))
00076     active_ = true;
00077   else
00078   {
00079     active_ = false;
00080     return;
00081   }
00082   root_name_ = kinematics_solver_->getBaseFrame();
00083   if(!getChainInfo(group_,chain_info_))
00084   {
00085     ROS_ERROR("Could not construct chain info for group %s",group_.c_str());
00086     return;
00087   }
00088   advertiseBaseKinematicsServices();
00089   if(setupCollisionEnvironment())
00090   {
00091     ROS_DEBUG("Advertising constraint aware services");
00092     advertiseConstraintIKService();
00093     ROS_INFO("Collision environment setup.");
00094   }
00095   else
00096   {
00097     ROS_ERROR("Could not initialize collision environment");
00098   }
00099 }
00100 
00101 void ArmKinematicsConstraintAware::advertiseBaseKinematicsServices()
00102 {
00103   ik_service_ = node_handle_.advertiseService(IK_SERVICE,&ArmKinematicsConstraintAware::getPositionIK,this);
00104   fk_service_ = node_handle_.advertiseService(FK_SERVICE,&ArmKinematicsConstraintAware::getPositionFK,this);
00105   ik_solver_info_service_ = node_handle_.advertiseService(IK_INFO_SERVICE,&ArmKinematicsConstraintAware::getIKSolverInfo,this);
00106   fk_solver_info_service_ = node_handle_.advertiseService(FK_INFO_SERVICE,&ArmKinematicsConstraintAware::getFKSolverInfo,this);
00107 }
00108 
00109 void ArmKinematicsConstraintAware::advertiseConstraintIKService()
00110 {
00111   ik_collision_service_ = node_handle_.advertiseService(IK_WITH_COLLISION_SERVICE,&ArmKinematicsConstraintAware::getConstraintAwarePositionIK,this);
00112   display_trajectory_publisher_ = root_handle_.advertise<motion_planning_msgs::DisplayTrajectory>("ik_solution_display", 1);
00113 }
00114 
00115 bool ArmKinematicsConstraintAware::isReady(motion_planning_msgs::ArmNavigationErrorCodes &error_code)
00116 {
00117  if(!active_)
00118   {
00119     ROS_ERROR("IK service is not ready");
00120     return false;
00121   }
00122   if(!setup_collision_environment_)
00123   {
00124     ROS_INFO("Waiting for collision environment setup.");
00125     if(!setupCollisionEnvironment())
00126     {
00127       ROS_INFO("Could not initialize collision environment");
00128       error_code.val = error_code.COLLISION_CHECKING_UNAVAILABLE;
00129       return false;
00130     }    
00131     else
00132     {
00133       setup_collision_environment_ = true;
00134     }
00135   }
00136   error_code.val = error_code.SUCCESS;
00137   return true;
00138 }
00139 
00140 bool ArmKinematicsConstraintAware::getConstraintAwarePositionIK(kinematics_msgs::GetConstraintAwarePositionIK::Request &request_in,
00141                                                                 kinematics_msgs::GetConstraintAwarePositionIK::Response &response)
00142 {
00143   if(!isReady(response.error_code))
00144     return true;
00145 
00146   if(!checkConstraintAwareIKService(request_in,response,chain_info_))
00147   {
00148     ROS_ERROR("IK service request is malformed");
00149     return true;
00150   }
00151 
00152   ros::Time start_time = ros::Time::now();
00153   ROS_INFO("Received IK request is in the frame: %s",request_in.ik_request.pose_stamped.header.frame_id.c_str());
00154 
00155   ik_request_ = request_in.ik_request;
00156   collision_operations_ = request_in.ordered_collision_operations;
00157   link_padding_ = request_in.link_padding;
00158   allowed_contacts_ = request_in.allowed_contacts;
00159   constraints_ = request_in.constraints;
00160 
00161   geometry_msgs::PoseStamped pose_msg_in = ik_request_.pose_stamped;
00162   geometry_msgs::PoseStamped pose_msg_out;
00163   if(!arm_kinematics_constraint_aware::convertPoseToRootFrame(pose_msg_in,pose_msg_out,root_name_,tf_))
00164   {
00165     response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00166     return true;
00167   }
00168   motion_planning_msgs::Constraints emp;
00169 
00170   //setting up planning monitor
00171   planning_monitor_->prepareForValidityChecks(chain_info_.joint_names,
00172                                               collision_operations_,
00173                                               allowed_contacts_,
00174                                               emp,
00175                                               constraints_,
00176                                               link_padding_,
00177                                               response.error_code);
00178   //can't transform constraints
00179   if(response.error_code.val == response.error_code.FRAME_TRANSFORM_FAILURE) {
00180     return true;
00181   }
00182   
00183   kinematic_state_ = new planning_models::KinematicState(planning_monitor_->getKinematicModel());
00184   planning_monitor_->setRobotStateAndComputeTransforms(ik_request_.robot_state, *kinematic_state_);
00185   ik_request_.pose_stamped = pose_msg_out;
00186   ROS_DEBUG("Transformed IK request is in the frame: %s",ik_request_.pose_stamped.header.frame_id.c_str());
00187   arm_kinematics_constraint_aware::reorderJointState(ik_request_.ik_seed_state.joint_state,chain_info_);
00188 
00189   ros::Time ik_solver_time = ros::Time::now();
00190   int kinematics_error_code;
00191   bool ik_valid = (kinematics_solver_->searchPositionIK(ik_request_.pose_stamped.pose,
00192                                                         ik_request_.ik_seed_state.joint_state.position,
00193                                                         request_in.timeout.toSec(),
00194                                                         response.solution.joint_state.position,
00195                                                         boost::bind(&ArmKinematicsConstraintAware::initialPoseCheck, this, _1, _2, _3),
00196                                                         boost::bind(&ArmKinematicsConstraintAware::collisionCheck, this, _1, _2, _3),kinematics_error_code)>0);
00197   ROS_INFO("IK solver time: %f",(ros::Time::now()-ik_solver_time).toSec());
00198 
00199   planning_monitor_->revertToDefaultState();
00200   if(ik_valid)
00201   {
00202     response.solution.joint_state.name = chain_info_.joint_names;
00203     if(visualize_solution_)
00204     {
00205       motion_planning_msgs::DisplayTrajectory display_trajectory;
00206       display_trajectory.trajectory.joint_trajectory.points.resize(1);
00207       display_trajectory.trajectory.joint_trajectory.points[0].positions = response.solution.joint_state.position;
00208       display_trajectory.trajectory.joint_trajectory.joint_names = response.solution.joint_state.name;
00209       planning_monitor_->convertKinematicStateToRobotState(*kinematic_state_,display_trajectory.robot_state);
00210       display_trajectory_publisher_.publish(display_trajectory);
00211     }
00212     ROS_INFO("IK service time: %f",(ros::Time::now()-start_time).toSec());
00213     response.error_code.val = response.error_code.SUCCESS;
00214     delete kinematic_state_;
00215     return true;
00216   }
00217   else
00218   {
00219     ROS_ERROR("An IK solution could not be found");
00220     response.error_code = kinematicsErrorCodeToMotionPlanningErrorCode(kinematics_error_code);
00221     if(response.error_code.val != response.error_code.IK_LINK_IN_COLLISION) 
00222     {
00223       sendEndEffectorPose(kinematic_state_,true);
00224     }
00225     delete kinematic_state_;
00226     return true;
00227   }
00228 }
00229 
00230 void ArmKinematicsConstraintAware::collisionCheck(const geometry_msgs::Pose &ik_pose,
00231                                                   const std::vector<double> &ik_solution,
00232                                                   int &error_code)
00233 {
00234   std::map<std::string, double> joint_values;
00235   for(unsigned int i=0; i < chain_info_.joint_names.size(); i++)
00236     joint_values[chain_info_.joint_names[i]] = ik_solution[i];
00237 
00238   kinematic_state_->setKinematicState(joint_values);
00239   planning_monitor_->getEnvironmentModel()->updateRobotModel(kinematic_state_);
00240 
00241   bool check = (!planning_monitor_->getEnvironmentModel()->isCollision() &&  !planning_monitor_->getEnvironmentModel()->isSelfCollision());
00242   if(!check) 
00243   {
00244     planning_monitor_->broadcastCollisions();
00245     error_code = kinematics::STATE_IN_COLLISION;
00246   }
00247   else {
00248     error_code = kinematics::SUCCESS;
00249   }
00250   
00251   if(!planning_monitor_->checkGoalConstraints(kinematic_state_, false)) {
00252     error_code = kinematics::GOAL_CONSTRAINTS_VIOLATED;
00253     ROS_INFO("Constraints violated at current state");
00254   }
00255 }
00256 
00257 void ArmKinematicsConstraintAware::initialPoseCheck(const geometry_msgs::Pose &ik_pose,
00258                                                     const std::vector<double> &ik_solution,
00259                                                     int &error_code)
00260 {
00261   std::string kinematic_frame_id = kinematics_solver_->getBaseFrame();
00262   std::string planning_frame_id = planning_monitor_->getWorldFrameId();
00263   geometry_msgs::PoseStamped pose_stamped;
00264   pose_stamped.pose = ik_pose;
00265   pose_stamped.header.stamp = ros::Time::now();
00266   pose_stamped.header.frame_id = kinematic_frame_id;
00267   if (!tf_.canTransform(planning_frame_id,
00268                         pose_stamped.header.frame_id,
00269                         pose_stamped.header.stamp))
00270   {
00271     std::string err;
00272     ros::Time tmp;
00273     if(tf_.getLatestCommonTime(pose_stamped.header.frame_id,planning_frame_id,tmp,&err) != tf::NO_ERROR)
00274     {
00275       ROS_ERROR("Cannot transform from '%s' to '%s'. TF said: %s",pose_stamped.header.frame_id.c_str(),planning_frame_id.c_str(), err.c_str());
00276     }
00277     else
00278       pose_stamped.header.stamp = tmp;
00279   }
00280     
00281   try
00282   {
00283     tf_.transformPose(planning_frame_id,pose_stamped,pose_stamped);
00284   }
00285   catch(tf::TransformException& ex)
00286   {
00287     ROS_ERROR("Cannot transform from '%s' to '%s'. Tf said: %s",
00288               pose_stamped.header.frame_id.c_str(),planning_frame_id.c_str(), ex.what());
00289     error_code = kinematics::FRAME_TRANSFORM_FAILURE;
00290     return;
00291   }
00292   
00293   //need to disable collisions correctly, and re-enable at the end
00294   std::vector<std::vector<bool> > orig_allowed;
00295   std::map<std::string, unsigned int> vecIndices;
00296   planning_monitor_->getEnvironmentModel()->getCurrentAllowedCollisionMatrix(orig_allowed, vecIndices);
00297 
00298   std::vector<std::vector<bool> > new_allowed = orig_allowed;
00299   for(unsigned int i = 0; i < arm_links_.size(); i++) {
00300     unsigned int vind = vecIndices[arm_links_[i]];
00301     for(unsigned int j = 0; j < new_allowed.size(); j++) {
00302       new_allowed[vind][j] = true;
00303       new_allowed[j][vind] = true;
00304     }
00305   }
00306   //planning_monitor_->printAllowedCollisionMatrix(orig_allowed, vecIndices);
00307   //planning_monitor_->printAllowedCollisionMatrix(new_allowed, vecIndices);
00308   planning_monitor_->getEnvironmentModel()->setAllowedCollisionMatrix(new_allowed, vecIndices);
00309 
00310   btTransform transform;
00311   tf::poseMsgToTF(pose_stamped.pose,transform);
00312   if(!kinematic_state_->hasLinkState(ik_request_.ik_link_name)) {
00313     ROS_ERROR("Could not find end effector root_link %s", ik_request_.ik_link_name.c_str());
00314     error_code  = kinematics::INVALID_LINK_NAME;
00315     return;
00316   }
00317   kinematic_state_->updateKinematicStateWithLinkAt(ik_request_.ik_link_name, transform);
00318   planning_monitor_->getEnvironmentModel()->updateRobotModel(kinematic_state_);
00319 
00320   bool check = ( !planning_monitor_->getEnvironmentModel()->isCollision() &&  
00321             !planning_monitor_->getEnvironmentModel()->isSelfCollision() );
00322   if(!check) {
00323     error_code  = kinematics::IK_LINK_IN_COLLISION;
00324     planning_monitor_->broadcastCollisions();
00325     sendEndEffectorPose(kinematic_state_, false);
00326   }
00327   else
00328     error_code = kinematics::SUCCESS;
00329     
00330   planning_monitor_->getEnvironmentModel()->setAllowedCollisionMatrix(orig_allowed, vecIndices);
00331   ROS_DEBUG("Initial pose check done with result %s",check ? "not_in_collision" : "in_collision" );
00332 }
00333 
00334 void ArmKinematicsConstraintAware::sendEndEffectorPose(const planning_models::KinematicState* state, bool valid) {
00335   if(!robot_model_initialized_) return;
00336   visualization_msgs::MarkerArray hand_array;
00337   unsigned int id = 0;
00338   for(unsigned int i = 0; i < end_effector_collision_links_.size(); i++) {
00339     boost::shared_ptr<const urdf::Link> urdf_link = robot_model_.getLink(end_effector_collision_links_[i]);
00340     if(urdf_link == NULL) {
00341       ROS_DEBUG_STREAM("No entry in urdf for link " << end_effector_collision_links_[i]);
00342       continue;
00343     }
00344     if(!urdf_link->collision) {
00345       continue;
00346     }
00347     const urdf::Geometry *geom = urdf_link->collision->geometry.get();
00348     if(!geom) {
00349       ROS_DEBUG_STREAM("No collision geometry for link " << end_effector_collision_links_[i]);
00350       continue;
00351     }
00352     const urdf::Mesh *mesh = dynamic_cast<const urdf::Mesh*>(geom);
00353     if(mesh) {
00354       if (!mesh->filename.empty()) {
00355         planning_models::KinematicState::LinkState* ls = state->getLinkState(end_effector_collision_links_[i]);
00356         visualization_msgs::Marker mark;
00357         mark.header.frame_id = planning_monitor_->getWorldFrameId();
00358         mark.header.stamp = ros::Time::now();
00359         mark.id = id++;
00360         if(!valid) {
00361           mark.ns = "initial_pose_collision";
00362         } else {
00363           mark.ns = "initial_pose_ok";
00364         }
00365         mark.type = mark.MESH_RESOURCE;
00366         mark.scale.x = 1.0;
00367         mark.scale.y = 1.0;
00368         mark.scale.z = 1.0;
00369         if(!valid) {
00370           mark.color.r = 1.0;
00371         } else {
00372           mark.color.g = 1.0;
00373         }
00374         mark.color.a = .8;
00375         mark.pose.position.x = ls->getGlobalCollisionBodyTransform().getOrigin().x();
00376         mark.pose.position.y = ls->getGlobalCollisionBodyTransform().getOrigin().y();
00377         mark.pose.position.z = ls->getGlobalCollisionBodyTransform().getOrigin().z();
00378         mark.pose.orientation.x = ls->getGlobalCollisionBodyTransform().getRotation().x();
00379         mark.pose.orientation.y = ls->getGlobalCollisionBodyTransform().getRotation().y();
00380         mark.pose.orientation.z = ls->getGlobalCollisionBodyTransform().getRotation().z();
00381         mark.pose.orientation.w = ls->getGlobalCollisionBodyTransform().getRotation().w();
00382         mark.mesh_resource = mesh->filename;
00383         hand_array.markers.push_back(mark);
00384       }
00385     }
00386   }
00387   vis_marker_array_publisher_.publish(hand_array);
00388 }
00389 
00390 void ArmKinematicsConstraintAware::printStringVec(const std::string &prefix, const std::vector<std::string> &string_vector)
00391 {
00392   ROS_DEBUG("%s",prefix.c_str());
00393   for(unsigned int i=0; i < string_vector.size(); i++)
00394   {
00395     ROS_DEBUG("%s",string_vector[i].c_str());
00396   }
00397 }
00398 
00399 bool ArmKinematicsConstraintAware::setupCollisionEnvironment()
00400 {
00401   node_handle_.param<bool>("use_collision_map", use_collision_map_, true);
00402 
00403   std::string urdf_xml,full_urdf_xml;
00404   root_handle_.param("urdf_xml", urdf_xml, std::string("robot_description"));
00405   if(!root_handle_.getParam(urdf_xml,full_urdf_xml))
00406   {
00407     ROS_ERROR("Could not load the xml from parameter server: %s\n", urdf_xml.c_str());
00408     robot_model_initialized_ = false;
00409   }
00410   else
00411   {
00412     robot_model_.initString(full_urdf_xml);
00413     robot_model_initialized_ = true;
00414   }
00415 
00416   // monitor robot
00417   collision_models_ = new planning_environment::CollisionModels("robot_description");
00418 
00419   if(!collision_models_)
00420   {
00421     ROS_INFO("Could not initialize collision models");
00422     return false;
00423   }
00424   planning_monitor_ = new planning_environment::PlanningMonitor(collision_models_, &tf_);
00425 
00426   if(!planning_monitor_)
00427   {
00428     ROS_ERROR("Could not initialize planning monitor");
00429     return false;
00430   }
00431   else
00432   {
00433     ROS_INFO("Initialized planning monitor");
00434   }
00435 
00436   planning_monitor_->setUseCollisionMap(use_collision_map_);
00437   planning_monitor_->startEnvironmentMonitor();
00438   if(!collision_models_->loadedModels())
00439   {
00440     ROS_ERROR("Could not load models");
00441     return false;
00442   }
00443   if (!collision_models_->getKinematicModel()->hasModelGroup(group_))
00444   {
00445     ROS_ERROR("Group '%s' is not known", group_.c_str());
00446     return false;
00447   }
00448   else
00449     ROS_INFO("Configuring action for '%s'", group_.c_str());
00450 
00451   const std::vector<const planning_models::KinematicModel::JointModel*>& p_joints = collision_models_->getKinematicModel()->getModelGroup(group_)->getJointModels();
00452   for(unsigned int i=0; i < p_joints.size(); i++)
00453   {
00454     default_collision_links_.push_back(p_joints[i]->getChildLinkModel()->getName()); 
00455   }
00456 
00457   //getting arm link names
00458   arm_links_ = collision_models_->getPlanningGroupLinks().at(group_);
00459 
00460   if (planning_monitor_->getExpectedJointStateUpdateInterval() > 1e-3)
00461     planning_monitor_->waitForState();
00462   if (planning_monitor_->getExpectedMapUpdateInterval() > 1e-3 && use_collision_map_)
00463     planning_monitor_->waitForMap();
00464   //planning_monitor_->setCollisionCheckOnlyLinks(default_collision_links_,true);
00465 
00466   end_effector_collision_links_.clear();
00467   const planning_models::KinematicModel::LinkModel* end_effector_link = planning_monitor_->getKinematicModel()->getLinkModel(chain_info_.link_names.back());
00468   std::vector<const planning_models::KinematicModel::LinkModel*> tempLinks;
00469   planning_monitor_->getKinematicModel()->getChildLinkModels(end_effector_link, tempLinks);
00470   for (unsigned int i = 0 ; i < tempLinks.size() ; ++i)
00471     end_effector_collision_links_.push_back(tempLinks[i]->getName());
00472   for(unsigned int i=0; i < end_effector_collision_links_.size(); i++)
00473     default_collision_links_.push_back(end_effector_collision_links_[i]);
00474 
00475   printStringVec("Default collision links",default_collision_links_);
00476   printStringVec("End effector links",end_effector_collision_links_);
00477 
00478   ROS_DEBUG("Root link name is: %s",root_name_.c_str());
00479 
00480   planning_monitor_->setOnCollisionContactCallback(boost::bind(&ArmKinematicsConstraintAware::contactFound, this, _1));
00481   vis_marker_publisher_ = root_handle_.advertise<visualization_msgs::Marker>("kinematics_collisions", 128);
00482   vis_marker_array_publisher_ = root_handle_.advertise<visualization_msgs::MarkerArray>("kinematics_collisions_array", 128);
00483 
00484   setup_collision_environment_ = true;
00485   return true;
00486 }
00487 
00490 void ArmKinematicsConstraintAware::contactFound(collision_space::EnvironmentModel::Contact &contact)
00491 {
00492 
00493   static int count = 0;
00494   
00495   std::string ns_name;
00496   if(contact.link1 != NULL) {
00497     //ROS_INFO_STREAM("Link 1 is " << contact.link2->name);
00498     if(contact.link1_attached_body_index == 0) {
00499       ns_name += contact.link1->getName()+"+";
00500     } else {
00501       if(contact.link1->getAttachedBodyModels().size() < contact.link1_attached_body_index) {
00502         ROS_ERROR("Link doesn't have attached body with indicated index");
00503       } else {
00504         ns_name += contact.link1->getAttachedBodyModels()[contact.link1_attached_body_index-1]->getName()+"+";
00505       }
00506     }
00507   } 
00508   
00509   if(contact.link2 != NULL) {
00510     //ROS_INFO_STREAM("Link 2 is " << contact.link2->name);
00511     if(contact.link2_attached_body_index == 0) {
00512       ns_name += contact.link2->getName();
00513     } else {
00514       if(contact.link2->getAttachedBodyModels().size() < contact.link2_attached_body_index) {
00515         ROS_ERROR("Link doesn't have attached body with indicated index");
00516       } else {
00517         ns_name += contact.link2->getAttachedBodyModels()[contact.link2_attached_body_index-1]->getName();
00518       }
00519     }
00520   } 
00521   
00522   if(!contact.object_name.empty()) {
00523     //ROS_INFO_STREAM("Object is " << contact.object_name);
00524     ns_name += contact.object_name;
00525   }
00526   
00527   visualization_msgs::Marker mk;
00528   mk.header.stamp = planning_monitor_->lastPoseUpdate();
00529   mk.header.frame_id = planning_monitor_->getWorldFrameId();
00530   mk.ns = ns_name;
00531   mk.id = count++;
00532   mk.type = visualization_msgs::Marker::SPHERE;
00533   mk.action = visualization_msgs::Marker::ADD;
00534   mk.pose.position.x = contact.pos.x();
00535   mk.pose.position.y = contact.pos.y();
00536   mk.pose.position.z = contact.pos.z();
00537   mk.pose.orientation.w = 1.0;
00538   
00539   mk.scale.x = mk.scale.y = mk.scale.z = 0.01;
00540   
00541   mk.color.a = 0.6;
00542   mk.color.r = 1.0;
00543   mk.color.g = 0.04;
00544   mk.color.b = 0.04;
00545   
00546   //mk.lifetime = ros::Duration(30.0);
00547   
00548   vis_marker_publisher_.publish(mk);
00549 }
00550 
00551 bool ArmKinematicsConstraintAware::getPositionIK(kinematics_msgs::GetPositionIK::Request &request, 
00552                                                  kinematics_msgs::GetPositionIK::Response &response)
00553 {
00554   if(!active_)
00555   {
00556     ROS_ERROR("IK service not active");
00557     return true;
00558   }
00559 
00560   if(!checkIKService(request,response,chain_info_))
00561     return true;
00562 
00563   geometry_msgs::PoseStamped pose_msg_in = request.ik_request.pose_stamped;
00564   geometry_msgs::PoseStamped pose_msg_out;
00565   if(!convertPoseToRootFrame(pose_msg_in,pose_msg_out,root_name_,tf_))
00566   {
00567     response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00568     return true;
00569   }
00570   arm_kinematics_constraint_aware::reorderJointState(request.ik_request.ik_seed_state.joint_state,chain_info_);
00571 
00572   int kinematics_error_code;
00573   bool ik_valid = kinematics_solver_->searchPositionIK(pose_msg_out.pose,
00574                                                       request.ik_request.ik_seed_state.joint_state.position,
00575                                                       request.timeout.toSec(),
00576                                                       response.solution.joint_state.position,
00577                                                       kinematics_error_code);
00578 
00579   response.error_code = kinematicsErrorCodeToMotionPlanningErrorCode(kinematics_error_code);
00580 
00581   if(ik_valid)
00582   {
00583     response.solution.joint_state.name = chain_info_.joint_names;
00584     response.error_code.val = response.error_code.SUCCESS;
00585     return true;
00586   }
00587   else
00588   {
00589     ROS_DEBUG("An IK solution could not be found");   
00590     return true;
00591   }
00592 }
00593 
00594 bool ArmKinematicsConstraintAware::getIKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request, 
00595                                                      kinematics_msgs::GetKinematicSolverInfo::Response &response)
00596 {
00597   if(!active_)
00598   {
00599     ROS_ERROR("IK node not active");
00600     return true;
00601   }
00602   response.kinematic_solver_info = chain_info_;
00603   return true;
00604 }
00605 
00606 bool ArmKinematicsConstraintAware::getFKSolverInfo(kinematics_msgs::GetKinematicSolverInfo::Request &request, 
00607                                                      kinematics_msgs::GetKinematicSolverInfo::Response &response)
00608 {
00609   if(!active_)
00610   {
00611     ROS_ERROR("IK node not active");
00612     return true;
00613   }
00614   response.kinematic_solver_info = chain_info_;
00615   return true;
00616 }
00617 
00618 bool ArmKinematicsConstraintAware::getPositionFK(kinematics_msgs::GetPositionFK::Request &request, 
00619                                                    kinematics_msgs::GetPositionFK::Response &response)
00620 {
00621   if(!active_)
00622   {
00623     ROS_ERROR("FK service not active");
00624     return true;
00625   }
00626 
00627   if(!checkFKService(request,response,chain_info_))
00628     return true;
00629 
00630   arm_kinematics_constraint_aware::reorderJointState(request.robot_state.joint_state,chain_info_);
00631 
00632   response.pose_stamped.resize(request.fk_link_names.size());
00633   response.fk_link_names.resize(request.fk_link_names.size());
00634 
00635   bool valid = true;
00636   std::vector<geometry_msgs::Pose> solutions;
00637   solutions.resize(request.fk_link_names.size());
00638   if(kinematics_solver_->getPositionFK(request.fk_link_names,request.robot_state.joint_state.position,solutions) >=0)
00639   {    
00640     for(unsigned int i=0; i < solutions.size(); i++)
00641     {      
00642       geometry_msgs::PoseStamped pose_stamped;
00643       pose_stamped.pose = solutions[i];
00644       pose_stamped.header.frame_id = root_name_;
00645       pose_stamped.header.stamp = ros::Time();
00646       try
00647       {
00648         tf_.transformPose(request.header.frame_id,pose_stamped,pose_stamped);
00649       }
00650       catch(...)
00651       {
00652         ROS_ERROR("Could not transform FK pose to frame: %s",request.header.frame_id.c_str());
00653         response.error_code.val = response.error_code.FRAME_TRANSFORM_FAILURE;
00654         return false;
00655       }
00656       response.pose_stamped[i] = pose_stamped;
00657       response.fk_link_names[i] = request.fk_link_names[i];
00658       response.error_code.val = response.error_code.SUCCESS;
00659     }
00660   }
00661   else
00662   {
00663     ROS_ERROR("Could not compute FK");
00664     response.error_code.val = response.error_code.NO_FK_SOLUTION;
00665     valid = false;
00666   }
00667   return valid;
00668 }
00669 
00670 } // namespace
00671 


arm_kinematics_constraint_aware
Author(s): Sachin Chitta
autogenerated on Tue Jan 7 2014 11:18:56