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 #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());
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
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
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
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
00307
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
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
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
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
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
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
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
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 }
00671