arm_manip_node.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * \file
00003  *
00004  * $Id:$
00005  *
00006  * Copyright (C) Brno University of Technology
00007  *
00008  * This file is part of software developed by dcgm-robotics@FIT group.
00009  *
00010  * Author: Zdenek Materna (imaterna@fit.vutbr.cz)
00011  * Supervised by: Michal Spanel (spanel@fit.vutbr.cz)
00012  * Date: dd/mm/2012
00013  * 
00014  * This file is free software: you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as published by
00016  * the Free Software Foundation, either version 3 of the License, or
00017  * (at your option) any later version.
00018  * 
00019  * This file is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU Lesser General Public License for more details.
00023  * 
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this file.  If not, see <http://www.gnu.org/licenses/>.
00026  */
00027 
00028 #include <srs_assisted_arm_navigation/assisted_arm_navigation/arm_manip_node.h>
00029 
00030 using namespace arm_navigation_msgs;
00031 using namespace planning_scene_utils;
00032 using namespace srs_assisted_arm_navigation;
00033 using namespace srs_assisted_arm_navigation_msgs;
00034 
00035 
00036 CArmManipulationEditor::CArmManipulationEditor(planning_scene_utils::PlanningSceneParameters& params, std::vector<string> clist) : PlanningSceneEditor(params)
00037 {
00038 
00039     action_server_ptr_ = NULL;
00040     inited = false;
00041     params_ = params;
00042 
00043     // ros::param::param<std::string>("~world_frame",world_frame_,WORLD_FRAME);
00044 
00045     ros::param::param<std::string>("~arm_planning/world_frame",collision_objects_frame_id_,WORLD_FRAME);
00046     ros::param::param<bool>("~arm_planning/make_collision_objects_selectable",coll_objects_selectable_,false);
00047 
00048     // TODO remove collision_objects_frame_id and keep just world_frame
00049     world_frame_ =  collision_objects_frame_id_;
00050 
00051     ros::param::param<std::string>("~arm_planning/aco/link",aco_link_,"/arm_7_link");
00052     ros::param::param<bool>("~arm_planning/aco/default_state",aco_,false);
00053 
00054     ros::param::param<std::string>("~arm_planning/end_eff_link",end_eff_link_,"/sdh_palm_link");
00055 
00056     ROS_INFO("Using %s frame as world frame",collision_objects_frame_id_.c_str());
00057 
00058     //collision_objects_frame_id_ = "/map"; // TODO read from parameter
00059 
00060     ros::param::param<bool>("~spacenav/enable_spacenav",use_spacenav_,false);
00061 
00062     spacenav.offset_received_ = false;
00063     spacenav.rot_offset_received_ = false;
00064     spacenav.lock_orientation_ = false;
00065     spacenav.lock_position_ = false;
00066 
00067     spacenav.buttons_.push_back(0);
00068     spacenav.buttons_.push_back(0);
00069 
00070     ros::param::param<double>("~spacenav/max_val",spacenav.max_val_,350.0);
00071     ros::param::param<double>("~spacenav/min_val_th",spacenav.min_val_th_,0.05);
00072     ros::param::param<double>("~spacenav/step",spacenav.step_,0.1);
00073     ros::param::param<double>("~spacenav/rot_step",spacenav.rot_step_,0.05);
00074     ros::param::param<bool>("~spacenav/use_rviz_cam",spacenav.use_rviz_cam_,true);
00075     ros::param::param<std::string>("~spacenav/rviz_cam_link",spacenav.rviz_cam_link_,"/rviz_cam");
00076 
00077     // TODO add checks also for other params !!!!!!!!!!!!!
00078     if (spacenav.min_val_th_ > 0.5) spacenav.min_val_th_ = 0.5;
00079     if (spacenav.min_val_th_ < 0.0) spacenav.min_val_th_ = 0.0;
00080 
00081     ros::param::param<bool>("~arm_planning/joint_controls",joint_controls_,false);
00082 
00083     state_timer_ = nh_.createTimer(ros::Duration(0.05),&CArmManipulationEditor::timerCallback,this);
00084 
00085     if (use_spacenav_) {
00086 
00087         ROS_INFO_ONCE("We are going to use spacenav");
00088 
00089         joy_sub_ = nh_.subscribe<sensor_msgs::Joy>("/spacenav/joy",1,&CArmManipulationEditor::joyCallback,this);
00090                 offset_sub_ = nh_.subscribe("/spacenav/offset",1,&CArmManipulationEditor::spacenavOffsetCallback,this);
00091                 rot_offset_sub_ = nh_.subscribe("/spacenav/rot_offset",1,&CArmManipulationEditor::spacenavRotOffsetCallback,this);
00092 
00093                 // 100 hz -> publishing TF
00094                 if (spacenav.use_rviz_cam_) tf_timer_ = nh_.createTimer(ros::Duration(0.01),&CArmManipulationEditor::tfTimerCallback,this);
00095 
00096                 // 30 Hz -> reading spacenav position
00097                 spacenav_timer_ = nh_.createTimer(ros::Duration(0.03),&CArmManipulationEditor::spacenavCallback,this);
00098 
00099     }
00100 
00101     arm_nav_state_pub_ = nh_.advertise<AssistedArmNavigationState>(TOP_STATE,5);
00102 
00103     arm_nav_state_.out_of_limits = false;
00104 
00105     links_ = clist;
00106 
00107     gripper_poses_ = new boost::circular_buffer<geometry_msgs::Pose>(20);
00108 
00109     gripper_poses_thread_ = boost::thread(&CArmManipulationEditor::GripperPoses,this);
00110 
00111     step_used_ = false;
00112 
00113     planning_scene_id = "";
00114     mpr_id = 0;
00115 
00116 }
00117 
00118 
00119 bool CArmManipulationEditor::transf(std::string target_frame,geometry_msgs::PoseStamped& pose) {
00120 
00121         // transform pose of camera into world
00122         try {
00123 
00124                         if (tfl_->waitForTransform(target_frame, pose.header.frame_id, pose.header.stamp, ros::Duration(0.5))) {
00125 
00126                           tfl_->transformPose(target_frame,pose,pose);
00127 
00128                         } else {
00129 
00130                           ROS_ERROR("Could not get TF transf. from %s into %s.",pose.header.frame_id.c_str(),target_frame.c_str());
00131                           return false;
00132 
00133                         }
00134 
00135         } catch(tf::TransformException& ex){
00136            std::cerr << "Transform error: " << ex.what() << std::endl;
00137 
00138            ROS_ERROR("Exception on TF transf.: %s",ex.what());
00139 
00140            return false;
00141         }
00142 
00143         return true;
00144 
00145 }
00146 
00147 void CArmManipulationEditor::normAngle(double& a) {
00148 
00149         if (a > 2*M_PI) {
00150 
00151                 a -= 2*M_PI;
00152                 return;
00153 
00154         }
00155 
00156         if (a < 0) {
00157 
00158                 a = 2*M_PI + a;
00159 
00160         }
00161 
00162         return;
00163 
00164 }
00165 
00166 void CArmManipulationEditor::processSpaceNav() {
00167 
00168 
00169         ROS_INFO_ONCE("Trying to process spacenav data");
00170 
00171         geometry_msgs::Vector3 offset;
00172         geometry_msgs::Vector3 rot_offset;
00173 
00174         //boost::mutex::scoped_lock(spacenav.mutex_);
00175         spacenav.mutex_.lock();
00176         bool ret = false;
00177 
00178         // there is nothing to do
00179         if (spacenav.lock_orientation_ && spacenav.lock_position_) ret = true;
00180 
00181         if (!spacenav.offset_received_) ret = true;
00182         //else spacenav.offset_received_ = false;
00183 
00184         if (!spacenav.rot_offset_received_) ret = true;
00185         //else spacenav.rot_offset_received_ = false;
00186 
00187         // continue only if the planning was started
00188         if (!inited) ret = true;
00189 
00190         if (!ret) {
00191 
00192                 ROS_INFO_ONCE("Storing local copy of spacenav data");
00193 
00194                 offset = spacenav.offset;
00195                 rot_offset = spacenav.rot_offset;
00196 
00197                 spacenav.offset.x = 0;
00198                 spacenav.offset.y = 0;
00199                 spacenav.offset.z = 0;
00200 
00201                 spacenav.rot_offset.x = 0.0;
00202                 spacenav.rot_offset.y = 0.0;
00203                 spacenav.rot_offset.z = 0.0;
00204 
00205                 spacenav.offset_received_ = false;
00206                 spacenav.rot_offset_received_ = false;
00207 
00208         }
00209 
00210         spacenav.mutex_.unlock();
00211 
00212         ROS_INFO_ONCE("We have spacenav data");
00213 
00214         if (ret) return;
00215 
00216         ROS_INFO_ONCE("Getting state of action");
00217 
00218 
00219         unsigned int state = action_server_ptr_->get_state();
00220 
00221         if (state != ManualArmManipActionServer::S_NEW && state !=ManualArmManipActionServer::S_NONE) {
00222 
00223                 ROS_DEBUG("State is %u",state);
00224 
00225                 return;
00226 
00227         }
00228 
00229         //boost::mutex::scoped_lock(im_server_mutex_);
00230         //lockScene();
00231 
00232         ROS_INFO_ONCE("Getting gripper IM");
00233 
00234         //im_server_mutex_.lock();
00235 
00236         visualization_msgs::InteractiveMarker marker;
00237         //geometry_msgs::Pose new_pose;
00238 
00239         if (!(interactive_marker_server_->get("MPR 0_end_control",marker))) {
00240 
00241                 ROS_ERROR_ONCE("Can't get gripper IM pose.");
00242 
00243                 //im_server_mutex_.unlock();
00244                 //unlockScene();
00245                 return;
00246 
00247         }
00248 
00249         //unlockScene();
00250 
00251         //im_server_mutex_.unlock();
00252 
00253         ros::Time now = /*ros::Time(0);*/ ros::Time::now();
00254 
00255 
00256         geometry_msgs::PoseStamped npose;
00257 
00258         if (spacenav.use_rviz_cam_) {
00259 
00260                 ROS_INFO_ONCE("Transforming IM pose to RVIZ camera...");
00261 
00262                 //std::cout << marker.header.frame_id << std::endl;
00263 
00264                 npose.pose = marker.pose;
00265                 npose.header.stamp = /*ros::Time::now();*/ ros::Time(0);
00266                 npose.header.frame_id = world_frame_;
00267 
00268                 if (!transf(spacenav.rviz_cam_link_ + "_add",npose)) return;
00269 
00270                 ROS_INFO_ONCE("IM pose is in %s frame",npose.header.frame_id.c_str());
00271 
00272         } else {
00273 
00274                 npose.pose = marker.pose;
00275                 npose.header.stamp = now;
00276                 npose.header.frame_id = world_frame_;
00277 
00278         }
00279 
00280         if (!spacenav.lock_position_) {
00281 
00282                 double th = spacenav.max_val_ * spacenav.min_val_th_;
00283 
00284                 if (fabs(offset.x) > th) {
00285 
00286                         double nv = offset.x/spacenav.max_val_; // normalized value
00287                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00288 
00289                         npose.pose.position.x += nv*spacenav.step_*ss;
00290 
00291                 }
00292 
00293                 if (fabs(offset.y) > th) {
00294 
00295                         double nv = offset.y/spacenav.max_val_; // normalized value
00296                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00297 
00298                         npose.pose.position.y += nv*spacenav.step_*ss;
00299 
00300                 }
00301 
00302                 if (fabs(offset.z) > th) {
00303 
00304                         double nv = offset.z/spacenav.max_val_; // normalized value
00305                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00306 
00307                         npose.pose.position.z += nv*spacenav.step_*ss;
00308 
00309                 }
00310 
00311         }
00312 
00313 
00314         if (!spacenav.lock_orientation_) {
00315 
00316                 double th = spacenav.max_val_ * spacenav.min_val_th_;
00317 
00318                 /*geometry_msgs::Vector3 rpy = GetAsEuler(npose.pose.orientation);
00319                 geometry_msgs::Vector3 old_rpy = rpy;*/
00320 
00321                 geometry_msgs::Vector3 rpy;
00322 
00323                 rpy.x = 0.0;
00324                 rpy.y = 0.0;
00325                 rpy.z = 0.0;
00326 
00327                 if (fabs(rot_offset.x) > th)  {
00328 
00329                         double nv = rot_offset.x/spacenav.max_val_;
00330                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00331 
00332                         rpy.x += nv*spacenav.rot_step_*ss;
00333                         normAngle(rpy.x);
00334 
00335                         //ROS_DEBUG("Gripper current ROLL (x): %f, new one: %f (DEG)",(old_rpy.x/(2*M_PI))*360,(rpy.x/(2*M_PI))*360);
00336 
00337                 }
00338 
00339                 if (fabs(rot_offset.y) > th)  {
00340 
00341                         double nv = rot_offset.y/spacenav.max_val_;
00342                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00343 
00344                         rpy.y += nv*spacenav.rot_step_*ss;
00345                         normAngle(rpy.y);
00346 
00347                         //ROS_DEBUG("Gripper current PITCH (y): %f, new one: %f (DEG)",(old_rpy.y/(2*M_PI))*360,(rpy.y/(2*M_PI))*360);
00348 
00349                 }
00350 
00351                 if (fabs(rot_offset.z) > th)  {
00352 
00353                         double nv = rot_offset.z/spacenav.max_val_;
00354                         double ss = (fabs(nv) + 0.2)/1.2; // 0.16 - 1.0
00355 
00356                         rpy.z += nv*spacenav.rot_step_*ss;
00357                         normAngle(rpy.z);
00358 
00359                         //ROS_DEBUG("Gripper current YAW (z): %f, new one: %f (DEG)",(old_rpy.z/(2*M_PI))*360,(rpy.z/(2*M_PI))*360);
00360 
00361                 }
00362 
00363 
00364                 // this was not working well... but I'm not 100% sure
00365                 //npose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(rpy.x,rpy.y,rpy.z);
00366 
00367                 tf::Quaternion o = tf::createQuaternionFromRPY(rpy.x,rpy.y,rpy.z); // transf. quat
00368                 tf::Quaternion g; // current IM marker pose
00369 
00370                 tf::quaternionMsgToTF(npose.pose.orientation,g);
00371                 g = o*g;
00372                 tf::quaternionTFToMsg(g,npose.pose.orientation);
00373 
00374         }
00375 
00376 
00377 
00378         if (spacenav.use_rviz_cam_) {
00379 
00380                 if (!transf(world_frame_,npose)) return;
00381 
00382         }
00383 
00384         //im_server_mutex_.lock();
00385 
00386         if ((interactive_marker_server_->setPose("MPR 0_end_control",npose.pose,npose.header))) {
00387 
00388                   interactive_marker_server_->applyChanges();
00389 
00390                   findIK(npose.pose);
00391 
00392           }
00393 
00394         //im_server_mutex_.unlock();
00395 
00396 
00397 
00398 }
00399 
00400 // timer for publishing TF for additional camera frame
00401 void CArmManipulationEditor::tfTimerCallback(const ros::TimerEvent& ev) {
00402 
00403         //boost::mutex::scoped_lock(im_server_mutex_);
00404         //im_server_mutex_.lock();
00405         //lockScene();
00406 
00407         visualization_msgs::InteractiveMarker marker;
00408         //geometry_msgs::Pose new_pose;
00409 
00410         if (!(interactive_marker_server_->get("MPR 0_end_control",marker))) {
00411 
00412                 ROS_ERROR_ONCE("Can't get gripper IM pose.");
00413                 //im_server_mutex_.unlock();
00414                 //unlockScene();
00415 
00416                 return;
00417 
00418         }
00419 
00420   ROS_INFO_ONCE("Publishing TF for additional RVIZ camera.");
00421 
00422         //im_server_mutex_.unlock();
00423         //unlockScene();
00424 
00425         ros::Time now = /*ros::Time(0);*/ ros::Time::now(); /*marker.header.stamp;*/
00426 
00427         // publish TF for additional camera frame
00428         geometry_msgs::PoseStamped cam_pose;
00429 
00430         cam_pose.pose.position.x = 0.0;
00431         cam_pose.pose.position.y = 0.0;
00432         cam_pose.pose.position.z = 0.0;
00433 
00434         cam_pose.pose.orientation.x = 0.0;
00435         cam_pose.pose.orientation.y = 0.0;
00436         cam_pose.pose.orientation.z = 0.0;
00437         cam_pose.pose.orientation.w = 1.0;
00438 
00439         cam_pose.header.stamp = now;
00440         cam_pose.header.frame_id = spacenav.rviz_cam_link_;
00441 
00442         if (!transf(world_frame_,cam_pose)) return;
00443 
00444         // set pos. of camera to be same as pos. of IM
00445         cam_pose.pose.position = marker.pose.position;
00446 
00447         geometry_msgs::Vector3 rpy = GetAsEuler(cam_pose.pose.orientation);
00448 
00449         // "reset" pitch
00450         rpy.y = 0;
00451 
00452         // "reset" roll
00453         rpy.x = 0;
00454 
00455         cam_pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(rpy.x,rpy.y,rpy.z);
00456 
00457         tf::Transform tr;
00458         tr.setOrigin(tf::Vector3(cam_pose.pose.position.x,cam_pose.pose.position.y,cam_pose.pose.position.z));
00459         tr.setRotation(tf::Quaternion(cam_pose.pose.orientation.x,cam_pose.pose.orientation.y,cam_pose.pose.orientation.z,cam_pose.pose.orientation.w));
00460         br_.sendTransform(tf::StampedTransform(tr, now, world_frame_, spacenav.rviz_cam_link_ + "_add"));
00461 
00462 
00463 
00464 }
00465 
00466 void CArmManipulationEditor::spacenavCallback(const ros::TimerEvent& ev) {
00467 
00468         // update position of IM according to spacenav data
00469     processSpaceNav();
00470 
00471 }
00472 
00473 // general timer, 20 Hz, publishes state of the node
00474 void CArmManipulationEditor::timerCallback(const ros::TimerEvent& ev) {
00475 
00476         ROS_INFO_ONCE("Assisted arm nav timer callback triggered.");
00477 
00478         // publish state of spacenav buttons (and internal state of arm nav. -> TBD)
00479         AssistedArmNavigationState msg;
00480 
00481         spacenav.mutex_.lock();
00482         msg.orientation_locked = spacenav.lock_orientation_;
00483         msg.position_locked = spacenav.lock_position_;
00484         spacenav.mutex_.unlock();
00485 
00486         msg.aco_state = aco_;
00487         msg.planning_started = inited;
00488 
00489         //motion_plan_map_[getMotionPlanRequestNameFromId(controller.motion_plan_id_)].setHasGoodIKSolution(false, type);
00490         if (inited) {
00491 
00492 
00493                 MotionPlanRequestData& data = motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)];
00494 
00495                 msg.position_reachable = data.hasGoodIKSolution(planning_scene_utils::GoalPosition);
00496 
00497                 visualization_msgs::MarkerArray arr = data.getCollisionMarkers();
00498 
00499                 if (arr.markers.size() == 0) msg.position_in_collision = false;
00500                 else msg.position_in_collision = true;
00501 
00502                 planning_models::KinematicState *robot_state = getRobotState();
00503                 planning_models::KinematicState::JointStateGroup* jsg = robot_state->getJointStateGroup(data.getGroupName());
00504                 msg.joints_out_of_limits = !( robot_state->areJointsWithinBounds(jsg->getJointNames()) );
00505 
00506         } else {
00507 
00508                 msg.joints_out_of_limits = arm_nav_state_.out_of_limits;
00509 
00510                 msg.position_reachable = false;
00511                 msg.position_in_collision = false;
00512 
00513         }
00514 
00515 
00516         if (!inited) {
00517 
00518                 msg.error_description = "No error.";
00519 
00520 
00521         } else {
00522 
00523 
00524                 if (arm_nav_state_.plan_error_code.val != arm_nav_state_.plan_error_code.SUCCESS) {
00525 
00526                         msg.error_description = arm_nav_state_.plan_desc;
00527 
00528                 } else {
00529 
00530                         if (arm_nav_state_.filter_error_code.val != arm_nav_state_.filter_error_code.SUCCESS) {
00531 
00532                                 msg.error_description = "Filtering of trajectory failed.";
00533 
00534                         }
00535 
00536                 }
00537 
00538         }
00539 
00540 
00541 
00542         arm_nav_state_pub_.publish(msg);
00543 
00544 }
00545 
00546 void CArmManipulationEditor::spacenavOffsetCallback(const geometry_msgs::Vector3ConstPtr& offset) {
00547 
00548 
00549         ROS_INFO_ONCE("Spacenav offset received!");
00550 
00551         spacenav.mutex_.lock();
00552 
00553         spacenav.offset_received_ = true;
00554 
00555         spacenav.offset = *offset;
00556 
00557         if (spacenav.offset.x > spacenav.max_val_) spacenav.offset.x = spacenav.max_val_;
00558         if (spacenav.offset.x < -spacenav.max_val_) spacenav.offset.x = -spacenav.max_val_;
00559 
00560         if (spacenav.offset.y > spacenav.max_val_) spacenav.offset.y = spacenav.max_val_;
00561         if (spacenav.offset.y < -spacenav.max_val_) spacenav.offset.y = -spacenav.max_val_;
00562 
00563         if (spacenav.offset.z > spacenav.max_val_) spacenav.offset.z = spacenav.max_val_;
00564         if (spacenav.offset.z < -spacenav.max_val_) spacenav.offset.z = -spacenav.max_val_;
00565 
00566         spacenav.mutex_.unlock();
00567 
00568         ROS_INFO_ONCE("Spacenav offset processed.");
00569 
00570 }
00571 
00572 void CArmManipulationEditor::spacenavRotOffsetCallback(const geometry_msgs::Vector3ConstPtr& rot_offset) {
00573 
00574 
00575         ROS_INFO_ONCE("Spacenav rot_offset received!");
00576 
00577         spacenav.mutex_.lock();
00578 
00579         spacenav.rot_offset_received_ = true;
00580 
00581         spacenav.rot_offset = *rot_offset;
00582 
00583         if (spacenav.rot_offset.x > spacenav.max_val_) spacenav.rot_offset.x = spacenav.max_val_;
00584         if (spacenav.rot_offset.x < -spacenav.max_val_) spacenav.rot_offset.x = -spacenav.max_val_;
00585 
00586         if (spacenav.rot_offset.y > spacenav.max_val_) spacenav.rot_offset.y = spacenav.max_val_;
00587         if (spacenav.rot_offset.y < -spacenav.max_val_) spacenav.rot_offset.y = -spacenav.max_val_;
00588 
00589         if (spacenav.rot_offset.z > spacenav.max_val_) spacenav.rot_offset.z = spacenav.max_val_;
00590         if (spacenav.rot_offset.z < -spacenav.max_val_) spacenav.rot_offset.z = -spacenav.max_val_;
00591 
00592         spacenav.mutex_.unlock();
00593 
00594         ROS_INFO_ONCE("Spacenav rot_offset processed");
00595 
00596 }
00597 
00598 void CArmManipulationEditor::joyCallback(const sensor_msgs::Joy::ConstPtr& joy) {
00599 
00600         if ((int)joy->buttons.size() == 2) {
00601 
00602                 ROS_INFO_ONCE("Spacenav data received!");
00603 
00604     if (!inited) return; // added at int. meeting
00605 
00606                 boost::mutex::scoped_lock(spacenav.mutex_);
00607 
00608                 // left button pressed
00609                 if ( (spacenav.buttons_[0] == 0) && (joy->buttons[0] == 1) ) {
00610 
00611                         if (spacenav.lock_position_) {
00612 
00613                                 ROS_INFO("Spacenav - unlocking position.");
00614                                 spacenav.lock_position_ = false;
00615 
00616                         } else {
00617 
00618                                 ROS_INFO("Spacenav - locking position.");
00619                                 spacenav.lock_position_ = true;
00620                                 spacenav.lock_orientation_ = false;
00621 
00622                         }
00623 
00624 
00625                 }
00626 
00627                 // right button pressed - we don't care about both button pressed at exactly same time
00628                 else if ( (spacenav.buttons_[1] == 0) && (joy->buttons[1] == 1) ) {
00629 
00630                         if (spacenav.lock_orientation_) {
00631 
00632                                 ROS_INFO("Spacenav - unlocking orientation.");
00633                                 spacenav.lock_orientation_ = false;
00634 
00635                         } else {
00636 
00637                                 ROS_INFO("Spacenav - locking orientation.");
00638                                 spacenav.lock_orientation_ = true;
00639                                 spacenav.lock_position_ = false;
00640 
00641                         }
00642 
00643 
00644                 }
00645 
00646 
00647                 spacenav.buttons_ = joy->buttons;
00648 
00649         } else ROS_ERROR_ONCE("Spacenav should have 2 buttons, but message has %d.",(int)joy->buttons.size());
00650 
00651 
00652 };
00653 
00654 CArmManipulationEditor::~CArmManipulationEditor() {
00655 
00656   gripper_poses_thread_.join();
00657 
00658   if (action_server_ptr_!=NULL) delete action_server_ptr_;
00659 
00660   if (tfl_!=NULL) delete tfl_;
00661 
00662   if (gripper_poses_!= NULL) delete gripper_poses_;
00663 
00664 }
00665 
00666 bool CArmManipulationEditor::checkPose(geometry_msgs::PoseStamped &p, std::string frame) {
00667 
00668 
00669  if (p.header.frame_id==frame) {
00670 
00671          return true;
00672 
00673   } else {
00674 
00675         ros::Time now = ros::Time::now();
00676 
00677         try {
00678 
00679                 ROS_INFO("Pose frame_id (%s) differs from expected (%s), transforming.",p.header.frame_id.c_str(),frame.c_str());
00680 
00681                         if (tfl_->waitForTransform(frame, p.header.frame_id, now, ros::Duration(2.0))) {
00682 
00683                           tfl_->transformPose(frame,p,p);
00684 
00685                         } else {
00686 
00687                           p.header.stamp = ros::Time(0);
00688                           tfl_->transformPose(frame,p,p);
00689                           ROS_WARN("Using latest transform available, may be wrong.");
00690 
00691                         }
00692 
00693                         return true;
00694 
00695            }
00696 
00697                 // In case of absence of transformation path
00698                 catch(tf::TransformException& ex){
00699                    std::cerr << "Transform error: " << ex.what() << std::endl;
00700                    return false;
00701                 }
00702 
00703 
00704 
00705   }
00706 
00707  return false;
00708 
00709 }
00710 
00711 
00712 void CArmManipulationEditor::onPlanningSceneLoaded() {};
00713 void CArmManipulationEditor::updateState() {};
00714 void CArmManipulationEditor::planCallback(arm_navigation_msgs::ArmNavigationErrorCodes& errorCode) {
00715 
00716         ROS_INFO_ONCE("Plan callback received.");
00717 
00718           arm_nav_state_.plan_error_code = errorCode;
00719           arm_nav_state_.plan_desc = armNavigationErrorCodeToString(errorCode);
00720 
00721           if(errorCode.val != ArmNavigationErrorCodes::SUCCESS)
00722                 {
00723 
00724                 ROS_ERROR("Planning failed with error: %s",arm_nav_state_.plan_desc.c_str());
00725 
00726 
00727                 }
00728 
00729 };
00730 void CArmManipulationEditor::filterCallback(arm_navigation_msgs::ArmNavigationErrorCodes& errorCode) {
00731 
00732   ROS_INFO_ONCE("Filter callback received.");
00733 
00734   arm_nav_state_.filter_error_code = errorCode;
00735   arm_nav_state_.filter_desc = armNavigationErrorCodeToString(errorCode);
00736 
00737   if(errorCode.val != ArmNavigationErrorCodes::SUCCESS)
00738         {
00739 
00740         ROS_ERROR("Filtering failed with error: %s",arm_nav_state_.filter_desc.c_str());
00741 
00742         }
00743 
00744 };
00745 void CArmManipulationEditor::attachObjectCallback(const std::string& name) {};
00746 void CArmManipulationEditor::selectedTrajectoryCurrentPointChanged( unsigned int new_current_point ) {};
00747 
00748 
00749 void CArmManipulationEditor::remove_coll_objects() {
00750 
00751   coll_obj_det.clear();
00752 
00753 }
00754 
00755 void CArmManipulationEditor::reset() {
00756 
00757   std::vector<std::string>::iterator tmp;
00758 
00760   for(tmp = coll_obj_attached_id.begin(); tmp != coll_obj_attached_id.end(); tmp++) {
00761 
00762     if (*tmp != "") deleteCollisionObject(*tmp);
00763 
00764     }
00765 
00766   coll_obj_attached_id.clear();
00767 
00768   std::vector<t_det_obj>::iterator tmpo;
00769 
00771   for(tmpo = coll_obj_det.begin(); tmpo != coll_obj_det.end(); tmpo++) {
00772 
00773     if ((*tmpo).id != "") deleteCollisionObject((*tmpo).id);
00774 
00775     }
00776 
00777 
00778   GripperPosesClean();
00779 
00780 
00781   if (mpr_id!=9999) {
00782 
00783           std::vector<unsigned int> erased_trajectories;
00784           deleteMotionPlanRequest(mpr_id,erased_trajectories);
00785 
00786           ROS_INFO("Motion plan request was removed from warehouse.");
00787 
00788           mpr_id = 9999; // special value
00789 
00790   }
00791 
00792   if (ros::service::exists("sn_teleop_srv_en",true)) {
00793 
00794            std_srvs::Empty srv;
00795            ros::service::call("sn_teleop_srv_en",srv);
00796 
00797      }
00798 
00799 
00800   inited = false;
00801 
00802   if (!refresh()) ROS_WARN("Error on refreshing planning scene during reset");
00803 
00804 }
00805 
00806 bool CArmManipulationEditor::refresh() {
00807 
00808   PlanningSceneData& planningSceneData = planning_scene_map_[planning_scene_id];
00809 
00810   ROS_INFO("Sending planning scene id=%u",planningSceneData.getId());
00811 
00812   return sendPlanningScene(planningSceneData);
00813 
00814 }
00815 
00816 
00817 void CArmManipulationEditor::spin_callback(const ros::TimerEvent&)
00818 {
00819 
00820   if (inited==true) {
00821 
00822           ROS_INFO_ONCE("Sending markers");
00823           sendMarkers();
00824 
00825   }
00826 
00827 
00828 }
00829 
00830 bool CArmManipulationEditor::findIK(geometry_msgs::Pose new_pose)
00831 {
00832 
00833   tf::Transform pose = toBulletTransform(new_pose);
00834 
00835   motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].getGoalState()->
00836           updateKinematicStateWithLinkAt(end_eff_link_,pose);
00837 
00838   //updateState();
00839 
00840   PositionType type = GoalPosition;
00841 
00842   if(!solveIKForEndEffectorPose(motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)], type, true)) {
00843 
00844           if(motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].hasGoodIKSolution(type))
00845       {
00846       motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].refreshColors();
00847       }
00848       motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].setHasGoodIKSolution(false, type);
00849 
00850       return true;
00851 
00852   } else {
00853 
00854       if(!motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].hasGoodIKSolution(type))
00855       {
00856       motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].refreshColors();
00857       }
00858 
00859       motion_plan_map_[getMotionPlanRequestNameFromId(mpr_id)].setHasGoodIKSolution(true, type);
00860 
00861       return false;
00862 
00863     }
00864 
00865 
00866 }
00867 
00868 
00869 // Return the rotation in Euler angles
00870 geometry_msgs::Vector3 CArmManipulationEditor::GetAsEuler(geometry_msgs::Quaternion quat)
00871 {
00872   geometry_msgs::Vector3 vec;
00873 
00874   btQuaternion q;
00875 
00876   btScalar roll, pitch, yaw;
00877 
00878   tf::quaternionMsgToTF(quat, q);
00879   btMatrix3x3(q).getRPY(roll,pitch,yaw);
00880 
00881   vec.x = (double)roll;
00882   vec.y = (double)pitch;
00883   vec.z = (double)yaw;
00884 
00885   normAngle(vec.x);
00886   normAngle(vec.y);
00887   normAngle(vec.z);
00888 
00889   return vec;
00890 
00891 }
00892 
00893 void CArmManipulationEditor::GripperPosesClean() {
00894 
00895   //boost::mutex::scoped_lock(im_server_mutex_);
00896   //lockScene();
00897 
00898   gripper_poses_->clear();
00899 
00900   //unlockScene();
00901 
00902 }
00903 
00904 void CArmManipulationEditor::GripperPoses()
00905 {
00906 
00907   ros::Rate r(1);
00908 
00909   visualization_msgs::InteractiveMarker marker;
00910   geometry_msgs::Pose last_pose;
00911   double distance;
00912   double max_change_in_angle;
00913 
00914   while(ros::ok()) {
00915 
00916     if (inited==true && disable_gripper_poses_==false) {
00917 
00918       //boost::mutex::scoped_lock(im_server_mutex_);
00919       //lockScene();
00920 
00921       if (interactive_marker_server_->get("MPR 0_end_control",marker)) {
00922 
00923         if (gripper_poses_->empty()) {
00924 
00925           ROS_INFO("Storing first pose of end effector IM");
00926           gripper_poses_->push_back(marker.pose);
00927 
00928          } else {
00929 
00930              // check if current position differs from last stored one
00931              // if yes, store it
00932 
00933              last_pose = gripper_poses_->back();
00934 
00935              distance = sqrt(pow((last_pose.position.x - marker.pose.position.x),2) +
00936                         pow((last_pose.position.y - marker.pose.position.y),2) +
00937                         pow((last_pose.position.z - marker.pose.position.z),2));
00938 
00939 
00940              geometry_msgs::Vector3 last_angles = GetAsEuler(last_pose.orientation);
00941              geometry_msgs::Vector3 current_angles = GetAsEuler(marker.pose.orientation);
00942 
00943              /*std_msgs::Int32MultiArray array;
00944              array.data.clear();
00945              array.data.push_back(current_angles.x/M_PI*360);
00946              array.data.push_back(current_angles.y/M_PI*360);
00947              array.data.push_back(current_angles.z/M_PI*360);
00948 
00949              gripper_rpy_publisher_.publish(array);*/
00950 
00951              /*geometry_msgs::Vector3 last_angles;
00952              geometry_msgs::Vector3 current_angles;
00953 
00954              tf::Quaternion q(last_pose.orientation.x,last_pose.orientation.y,last_pose.orientation.z,last_pose.orientation.z);
00955              btMatrix3x3(q).getEulerRPY((btScalar)last_angles.x,(btScalar)last_angles.y,(btScalar)last_angles.z);*/
00956 
00957 
00958              double tmp;
00959 
00960              // TODO normalize angles ?
00961 
00962              max_change_in_angle = (fabs(current_angles.x - last_angles.x)/(2*M_PI))*360;
00963 
00964              tmp = (fabs(current_angles.y - last_angles.y)/(2*M_PI))*360;
00965              if (tmp>max_change_in_angle) max_change_in_angle = tmp;
00966 
00967              tmp = (fabs(current_angles.z - last_angles.z)/(2*M_PI))*360;
00968              if (tmp>max_change_in_angle) max_change_in_angle = tmp;
00969 
00970 
00971              if (distance>0.1 || max_change_in_angle > 1.0) {
00972 
00973                //if (step_used_==false) {
00974 
00975                if (distance > 0.0) ROS_DEBUG("Distance is %f",distance);
00976 
00977                ROS_DEBUG("Roll: %f, pitch: %f, yaw: %f, max. change: %f ",
00978                                      (current_angles.x/(2*M_PI))*360,
00979                                      (current_angles.y/(2*M_PI))*360,
00980                                      (current_angles.z/(2*M_PI))*360,
00981                                      max_change_in_angle);
00982 
00983                ROS_INFO("Storing another pose of end effector IM (size of list is: %d)",(int)gripper_poses_->size());
00984                gripper_poses_->push_back(marker.pose);
00985 
00986                //} else step_used_ = false;
00987 
00988              }
00989 
00990          }
00991 
00992         //unlockScene();
00993 
00994       } else ROS_ERROR("Can't get pose of gripper IM");
00995 
00996       };
00997 
00998     r.sleep();
00999 
01000   } // while
01001 
01002   ROS_INFO("End of gripper poses thread...");
01003 
01004 }
01005 
01006 
01007 
01008 int main(int argc, char** argv)
01009 {
01010 
01011       CArmManipulationEditor * ps_editor = NULL;
01012       planning_scene_utils::PlanningSceneParameters params;
01013 
01014 
01015       ROS_INFO("Starting");
01016       ros::init(argc, argv, "but_simple_manual_arm_navigation");
01017 
01019       ros::param::param<std::string>("set_planning_scene_diff_name", params.set_planning_scene_diff_name_, SET_PLANNING_SCENE_DIFF_NAME);
01020       ros::param::param<std::string>("left_ik_name", params.left_ik_name_, LEFT_IK_NAME);
01021       ros::param::param<std::string>("left_interpolate_service_name", params.left_interpolate_service_name_, LEFT_INTERPOLATE_SERVICE_NAME);
01022       ros::param::param<std::string>("non_coll_left_ik_name", params.non_coll_left_ik_name_, NON_COLL_LEFT_IK_NAME);
01023       ros::param::param<std::string>("non_coll_right_ik_name", params.non_coll_right_ik_name_, NON_COLL_RIGHT_IK_NAME);
01024       ros::param::param<std::string>("planner_1_service_name", params.planner_1_service_name_, PLANNER_1_SERVICE_NAME);
01025       ros::param::param<std::string>("planner_2_service_name", params.planner_2_service_name_, PLANNER_2_SERVICE_NAME);
01026       ros::param::param<std::string>("proximity_space_planner_name", params.proximity_space_planner_name_, PROXIMITY_SPACE_PLANNER_NAME);
01027       ros::param::param<std::string>("proximity_space_service_name",  params.proximity_space_service_name_, PROXIMITY_SPACE_SERVICE_NAME);
01028       ros::param::param<std::string>("proximity_space_validity_name",  params.proximity_space_validity_name_,  PROXIMITY_SPACE_VALIDITY_NAME);
01029       ros::param::param<std::string>("right_ik_name", params.right_ik_name_, RIGHT_IK_NAME);
01030       ros::param::param<std::string>("right_interpolate_service_name", params.right_interpolate_service_name_, RIGHT_INTERPOLATE_SERVICE_NAME);
01031       ros::param::param<std::string>("trajectory_filter_1_service_name", params.trajectory_filter_1_service_name_, TRAJECTORY_FILTER_1_SERVICE_NAME);
01032       ros::param::param<std::string>("trajectory_filter_2_service_name", params.trajectory_filter_2_service_name_, TRAJECTORY_FILTER_2_SERVICE_NAME);
01033       ros::param::param<std::string>("vis_topic_name", params.vis_topic_name_ , VIS_TOPIC_NAME);
01034       ros::param::param<std::string>("right_ik_link", params.right_ik_link_ , RIGHT_IK_LINK);
01035       ros::param::param<std::string>("left_ik_link", params.left_ik_link_ , LEFT_IK_LINK);
01036       ros::param::param<std::string>("right_arm_group", params.right_arm_group_ , RIGHT_ARM_GROUP);
01037       ros::param::param<std::string>("left_arm_group", params.left_arm_group_ , LEFT_ARM_GROUP);
01038       ros::param::param<std::string>("right_redundancy", params.right_redundancy_ , RIGHT_ARM_REDUNDANCY);
01039       ros::param::param<std::string>("left_redundancy", params.left_redundancy_ , LEFT_ARM_REDUNDANCY);
01040       ros::param::param<std::string>("execute_left_trajectory", params.execute_left_trajectory_ , EXECUTE_LEFT_TRAJECTORY);
01041       ros::param::param<std::string>("execute_right_trajectory", params.execute_right_trajectory_ , EXECUTE_RIGHT_TRAJECTORY);
01042       ros::param::param<std::string>("list_controllers_service", params.list_controllers_service_, LIST_CONTROLLERS_SERVICE);
01043       ros::param::param<std::string>("load_controllers_service", params.load_controllers_service_, LOAD_CONTROLLERS_SERVICE);
01044       ros::param::param<std::string>("unload_controllers_service", params.unload_controllers_service_, UNLOAD_CONTROLLERS_SERVICE);
01045       ros::param::param<std::string>("switch_controllers_service", params.switch_controllers_service_, SWITCH_CONTROLLERS_SERVICE);
01046       ros::param::param<std::string>("gazebo_robot_model", params.gazebo_model_name_, GAZEBO_ROBOT_MODEL);
01047       ros::param::param<std::string>("robot_description_param", params.robot_description_param_, ROBOT_DESCRIPTION_PARAM);
01048       ros::param::param<bool>("use_robot_data", params.use_robot_data_, true);
01049       params.sync_robot_state_with_gazebo_ = false;
01050 
01051 
01052       std::vector<std::string> links;
01053 
01055       /*links.push_back("arm_7_link");
01056       links.push_back("sdh_palm_link");
01057       links.push_back("sdh_grasp_link");
01058       links.push_back("sdh_tip_link");
01059 
01060       links.push_back("sdh_finger_21_link");
01061       links.push_back("sdh_finger_22_link");
01062       links.push_back("sdh_finger_23_link");
01063 
01064       links.push_back("sdh_finger_11_link");
01065       links.push_back("sdh_finger_12_link");
01066       links.push_back("sdh_finger_13_link");
01067 
01068       links.push_back("sdh_thumb_1_link");
01069       links.push_back("sdh_thumb_2_link");
01070       links.push_back("sdh_thumb_3_link");*/
01071 
01072 
01073       ros::NodeHandle n;
01074       ros::NodeHandle nh("~");
01075 
01076 
01077 
01078       XmlRpc::XmlRpcValue v;
01079 
01080 
01081       if (nh.getParam("arm_links", v)) {
01082 
01083           for(int i =0; i < v.size(); i++)
01084           {
01085             links.push_back(v[i]);
01086             std::cerr << "link names: " << links[i] << std::endl;
01087           }
01088 
01089       } else {
01090 
01091         ROS_ERROR("Could not get param: arm_links. Using defaults...");
01092 
01093         links.push_back("arm_7_link");
01094                 links.push_back("sdh_palm_link");
01095                 links.push_back("sdh_grasp_link");
01096                 links.push_back("sdh_tip_link");
01097 
01098                 links.push_back("sdh_finger_21_link");
01099                 links.push_back("sdh_finger_22_link");
01100                 links.push_back("sdh_finger_23_link");
01101 
01102                 links.push_back("sdh_finger_11_link");
01103                 links.push_back("sdh_finger_12_link");
01104                 links.push_back("sdh_finger_13_link");
01105 
01106                 links.push_back("sdh_thumb_1_link");
01107                 links.push_back("sdh_thumb_2_link");
01108                 links.push_back("sdh_thumb_3_link");
01109 
01110         //return 0;
01111 
01112       }
01113 
01114       ROS_INFO("Creating planning scene editor");
01115       ps_editor = new CArmManipulationEditor(params,links);
01116 
01117       ROS_INFO("Advertising services");
01118 
01119       ros::ServiceServer service_new = n.advertiseService(SRV_NEW, &CArmManipulationEditor::ArmNavNew,ps_editor);
01120       ros::ServiceServer service_plan = n.advertiseService(SRV_PLAN, &CArmManipulationEditor::ArmNavPlan,ps_editor);
01121       ros::ServiceServer service_play = n.advertiseService(SRV_PLAY, &CArmManipulationEditor::ArmNavPlay,ps_editor);
01122       ros::ServiceServer service_execute = n.advertiseService(SRV_EXECUTE, &CArmManipulationEditor::ArmNavExecute,ps_editor);
01123       ros::ServiceServer service_reset = n.advertiseService(SRV_RESET, &CArmManipulationEditor::ArmNavReset,ps_editor);
01124       ros::ServiceServer service_refresh = n.advertiseService(SRV_REFRESH, &CArmManipulationEditor::ArmNavRefresh,ps_editor);
01125 
01126       ros::ServiceServer service_success = n.advertiseService(SRV_SUCCESS, &CArmManipulationEditor::ArmNavSuccess,ps_editor);
01127       ros::ServiceServer service_failed = n.advertiseService(SRV_FAILED, &CArmManipulationEditor::ArmNavFailed,ps_editor);
01128       ros::ServiceServer service_repeat = n.advertiseService(SRV_REPEAT, &CArmManipulationEditor::ArmNavRepeat,ps_editor);
01129 
01130       ros::ServiceServer service_collobj = n.advertiseService(SRV_COLLOBJ, &CArmManipulationEditor::ArmNavCollObj,ps_editor);
01131       ros::ServiceServer service_collobj_rem = n.advertiseService(SRV_COLLOBJ_REM, &CArmManipulationEditor::ArmNavRemoveCollObjects,ps_editor);
01132       ros::ServiceServer service_setattached = n.advertiseService(SRV_SET_ATTACHED, &CArmManipulationEditor::ArmNavSetAttached,ps_editor);
01133       ros::ServiceServer service_movepalmlink = n.advertiseService(SRV_MOVE_PALM_LINK, &CArmManipulationEditor::ArmNavMovePalmLink,ps_editor);
01134       ros::ServiceServer service_movepalmlinkrel = n.advertiseService(SRV_MOVE_PALM_LINK_REL, &CArmManipulationEditor::ArmNavMovePalmLinkRel,ps_editor);
01135 
01136       ros::ServiceServer service_switch_aco = n.advertiseService(SRV_SWITCH, &CArmManipulationEditor::ArmNavSwitchACO,ps_editor);
01137 
01138       ros::ServiceServer service_step = n.advertiseService(SRV_STEP, &CArmManipulationEditor::ArmNavStep,ps_editor);
01139       ros::ServiceServer service_stop = n.advertiseService(SRV_STOP, &CArmManipulationEditor::ArmNavStop,ps_editor);
01140 
01141       ros::Timer timer1 = n.createTimer(ros::Duration(0.25), &CArmManipulationEditor::spin_callback,ps_editor);
01142 
01143       ManualArmManipActionServer act_server(ACT_ARM_MANIP);
01144 
01145 
01146       //ps_editor->gripper_rpy_publisher_ = n.advertise<std_msgs::Int32MultiArray>(TOP_GRIPPER_RPY, 10);
01147 
01148       double tmp;
01149 
01150       ros::param::param<double>("~start_timeout",tmp,START_TIMEOUT);
01151       if (tmp >= 0.0) act_server.start_timeout_ = ros::Duration(tmp);
01152       else act_server.start_timeout_ = ros::Duration(START_TIMEOUT);
01153 
01154       ros::param::param<double>("~solve_timeout",tmp,SOLVE_TIMEOUT);
01155       if (tmp >= 0.0) act_server.solve_timeout_ = ros::Duration(tmp);
01156       else act_server.solve_timeout_ = ros::Duration(SOLVE_TIMEOUT);
01157 
01158       ros::param::param<double>("~inflate_bb",tmp,INFLATE_BB);
01159       if (tmp<1.0 || tmp>2.0) {
01160 
01161         tmp = 1.0;
01162         ROS_WARN("Param. inflate_bb should be in range <1.0;2.0>");
01163 
01164       }
01165 
01166       ps_editor->inflate_bb_ = tmp;
01167 
01168       ps_editor->action_server_ptr_ = &act_server;
01169 
01170       ps_editor->tfl_ = new tf::TransformListener();
01171 
01172 
01173       ROS_INFO("Spinning");
01174 
01175       ros::spin();
01176 
01177       /*ros::AsyncSpinner spinner(6);
01178       spinner.start();
01179       ros::waitForShutdown();*/
01180 
01181       delete ps_editor;
01182 
01183 }


srs_assisted_arm_navigation
Author(s): Zdenek Materna (imaterna@fit.vutbr.cz), Michal Spanel (spanel@fit.vutbr.cz)
autogenerated on Mon Oct 6 2014 08:12:08