$search
00001 /* 00002 * Copyright (c) 2010, Thomas Ruehr <ruehr@cs.tum.edu> 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 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 #include <ias_drawer_executive/RobotArm.h> 00031 #include <ias_drawer_executive/Pressure.h> 00032 #include <ias_drawer_executive/Geometry.h> 00033 00034 //#include <ias_drawer_executive/Poses.h> 00035 #include <ias_drawer_executive/RobotDriver.h> 00036 #include <boost/thread.hpp> 00037 #include <visualization_msgs/Marker.h> 00038 #include <kinematics_msgs/GetKinematicSolverInfo.h> 00039 #include <kinematics_msgs/GetPositionFK.h> 00040 00041 00042 actionlib::SimpleActionClient<find_base_pose::FindBasePoseAction> *RobotArm::ac_fbp_ = NULL; 00043 00044 00045 void RobotArm::jointStateCallback(const pr2_controllers_msgs::JointTrajectoryControllerState::ConstPtr& msg) 00046 { 00047 mutex_.lock(); 00048 for (int i = 0; i < 7; ++i) 00049 { 00050 joint_names[i] = msg->joint_names[i].c_str(); 00051 //ROS_INFO("JOINT NAME msg %s", msg->joint_names[i].c_str()); 00052 //ROS_INFO("JOINT NAME %s", joint_names[i].c_str()); 00053 00054 jointState[i] = msg->actual.positions[i]; 00055 jointStateDes[i] = msg->desired.positions[i]; 00056 jointStateErr[i] = msg->error.positions[i]; 00057 } 00058 haveJointState = true; 00059 mutex_.unlock(); 00060 } 00061 00062 void RobotArm::init() 00063 { 00064 if (!listener_) 00065 listener_ = new tf::TransformListener(); 00066 00067 if (!ac_fbp_) 00068 { 00069 ac_fbp_ = new actionlib::SimpleActionClient<find_base_pose::FindBasePoseAction>("find_base_pose_action",true); 00070 ROS_INFO("waiting for fbp server"); 00071 ac_fbp_->waitForServer(); //will wait for infinite time 00072 ROS_INFO("done"); 00073 } 00074 00075 } 00076 00078 RobotArm::RobotArm(int side) 00079 { 00080 00081 init(); 00082 00083 retries = 0; 00084 00085 raise_elbow = false; 00086 preset_angle = 1.9; 00087 00088 tucked = false; 00089 side_ = side; 00090 // tell the action client that we want to spin a thread by default 00091 traj_client_ = new TrajClient((side == 0) ? "r_arm_controller/joint_trajectory_action" : "l_arm_controller/joint_trajectory_action", true); 00092 // wait for action server to come up 00093 traj_client_->waitForServer(ros::Duration(1)); 00094 //{ 00095 // ROS_INFO("Waiting for the joint_trajectory_action server"); 00096 //} 00097 00098 ac_ = new actionlib::SimpleActionClient<pr2_common_action_msgs::ArmMoveIKAction>((side == 0) ? "r_arm_ik" : "l_arm_ik", true); 00099 00100 00101 //while (ros::ok() && ! 00102 ac_->waitForServer(ros::Duration(1)); 00103 //) 00104 //{ 00105 //ROS_INFO("Waiting for the move ik server %s", (side == 0) ? "r_arm_ik" : "l_arm_ik"); 00106 //} 00107 00108 for (int i = 0; i < 7; ++i) 00109 jointState[i] = 0.0f; 00110 00111 haveJointState = false; 00112 jointStateSubscriber_ = n_.subscribe((side == 0) ? "/r_arm_controller/state" : "/l_arm_controller/state", 1, &RobotArm::jointStateCallback,this); 00113 00114 //ik_client = n_.serviceClient<kinematics_msgs::GetPositionIK>((side == 0) ? "/pr2_right_arm_kinematics/get_ik" : "/pr2_left_arm_kinematics/get_ik" , true); 00115 ik_client = n_.serviceClient<kinematics_msgs::GetPositionIK>((side == 0) ? "/pr2_right_arm_kinematics/get_ik" : "/pr2_left_arm_kinematics/get_ik" , true); 00116 00117 time_to_target = 1; 00118 00119 evil_switch =false; 00120 00121 ros::service::waitForService((side_==0) ? "pr2_right_arm_kinematics/get_fk_solver_info" : "pr2_left_arm_kinematics/get_fk_solver_info",1); 00122 ros::service::waitForService((side_==0) ? "pr2_right_arm_kinematics/get_fk" : "pr2_left_arm_kinematics/get_fk",1); 00123 00124 ROS_INFO("WAITING FOR FBP AS"); 00125 ac_fbp_->waitForServer(ros::Duration(1)); //will wait for infinite time 00126 00127 query_client = n_.serviceClient<kinematics_msgs::GetKinematicSolverInfo>((side_==0) ? "pr2_right_arm_kinematics/get_fk_solver_info" : "pr2_left_arm_kinematics/get_fk_solver_info"); 00128 fk_client = n_.serviceClient<kinematics_msgs::GetPositionFK>((side_==0)? "pr2_right_arm_kinematics/get_fk" : "pr2_left_arm_kinematics/get_fk"); 00129 00130 excludeBaseProjectionFromWorkspace = false; 00131 00132 wrist_frame = (side == 0) ? "r_wrist_roll_link" : "l_wrist_roll_link"; 00133 tool_frame = (side == 0) ? "r_gripper_tool_frame" : "l_gripper_tool_frame"; 00134 00135 tool2wrist_ = Geometry::getRelativeTransform(tool_frame.c_str(),wrist_frame.c_str()); 00136 wrist2tool_ = Geometry::getRelativeTransform(wrist_frame.c_str(),tool_frame.c_str()); 00137 00138 } 00139 00141 RobotArm::~RobotArm() 00142 { 00143 ac_->cancelAllGoals(); 00144 traj_client_->cancelAllGoals(); 00145 delete traj_client_; 00146 } 00147 00148 RobotArm* RobotArm::getInstance(int side) 00149 { 00150 if (!instance[side]) 00151 instance[side] = new RobotArm(side); 00152 return instance[side]; 00153 } 00154 00155 void RobotArm::getJointState(double state[]) 00156 { 00157 haveJointState = false; //make sure to get a new state 00158 ros::Rate rate(20); 00159 while (!haveJointState) 00160 { 00161 rate.sleep(); 00162 ros::spinOnce(); 00163 } 00164 mutex_.lock(); 00165 for (int i = 0; i < 7; ++i) 00166 state[i]=jointState[i]; 00167 mutex_.unlock(); 00168 } 00169 00170 void RobotArm::getJointStateDes(double state[]) 00171 { 00172 ros::Rate rate(20); 00173 while (!haveJointState) 00174 { 00175 rate.sleep(); 00176 ros::spinOnce(); 00177 } 00178 mutex_.lock(); 00179 for (int i = 0; i < 7; ++i) 00180 state[i]=jointStateDes[i]; 00181 mutex_.unlock(); 00182 } 00183 00184 void RobotArm::getJointStateErr(double state[]) 00185 { 00186 ros::Rate rate(20); 00187 while (!haveJointState) 00188 { 00189 rate.sleep(); 00190 ros::spinOnce(); 00191 } 00192 mutex_.lock(); 00193 for (int i = 0; i < 7; ++i) 00194 state[i]=jointStateErr[i]; 00195 mutex_.unlock(); 00196 } 00197 00198 00199 tf::TransformListener *RobotArm::listener_=0; 00200 00201 //run inverse kinematics on a PoseStamped (7-dof pose 00202 //(position + quaternion orientation) + header specifying the 00203 //frame of the pose) 00204 //tries to stay close to double start_angles[7] 00205 //returns the solution angles in double solution[7] 00206 bool RobotArm::run_ik(geometry_msgs::PoseStamped pose, double start_angles[7], 00207 double solution[7], std::string link_name) 00208 { 00209 00210 if (0) 00211 if (excludeBaseProjectionFromWorkspace) 00212 { 00213 00214 //bool poseInsideFootprint = false; 00215 double padding = 0.05; 00216 double x = pose.pose.position.x; 00217 double y = pose.pose.position.y; 00218 // does target pose lie inside projection of base footprint? 00219 if ((x < .325 + padding) && (x > -.325 - padding) && (y < .325 + padding) && (y > -.325 - padding)) 00220 { 00221 //poseInsideFootprint = true; 00222 ROS_ERROR("REJECTED BECAUSE OF COLLISION WITH BASE PROJECTION"); 00223 return false; 00224 } 00225 } 00226 00227 00228 kinematics_msgs::GetPositionIK::Request ik_request; 00229 kinematics_msgs::GetPositionIK::Response ik_response; 00230 00231 ik_request.timeout = ros::Duration(5.0); 00232 if (side_ == 0) 00233 { 00234 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_pan_joint"); 00235 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_lift_joint"); 00236 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_upper_arm_roll_joint"); 00237 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_elbow_flex_joint"); 00238 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_forearm_roll_joint"); 00239 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_flex_joint"); 00240 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_roll_joint"); 00241 00242 ik_request.ik_request.robot_state.joint_state.name.push_back("r_shoulder_pan_joint"); 00243 ik_request.ik_request.robot_state.joint_state.name.push_back("r_shoulder_lift_joint"); 00244 ik_request.ik_request.robot_state.joint_state.name.push_back("r_upper_arm_roll_joint"); 00245 ik_request.ik_request.robot_state.joint_state.name.push_back("r_elbow_flex_joint"); 00246 ik_request.ik_request.robot_state.joint_state.name.push_back("r_forearm_roll_joint"); 00247 ik_request.ik_request.robot_state.joint_state.name.push_back("r_wrist_flex_joint"); 00248 ik_request.ik_request.robot_state.joint_state.name.push_back("r_wrist_roll_joint"); 00249 } 00250 else 00251 { 00252 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_shoulder_pan_joint"); 00253 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_shoulder_lift_joint"); 00254 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_upper_arm_roll_joint"); 00255 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_elbow_flex_joint"); 00256 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_forearm_roll_joint"); 00257 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_wrist_flex_joint"); 00258 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_wrist_roll_joint"); 00259 00260 ik_request.ik_request.robot_state.joint_state.name.push_back("l_shoulder_pan_joint"); 00261 ik_request.ik_request.robot_state.joint_state.name.push_back("l_shoulder_lift_joint"); 00262 ik_request.ik_request.robot_state.joint_state.name.push_back("l_upper_arm_roll_joint"); 00263 ik_request.ik_request.robot_state.joint_state.name.push_back("l_elbow_flex_joint"); 00264 ik_request.ik_request.robot_state.joint_state.name.push_back("l_forearm_roll_joint"); 00265 ik_request.ik_request.robot_state.joint_state.name.push_back("l_wrist_flex_joint"); 00266 ik_request.ik_request.robot_state.joint_state.name.push_back("l_wrist_roll_joint"); 00267 } 00268 00269 ik_request.ik_request.ik_link_name = wrist_frame; 00270 00271 ik_request.ik_request.pose_stamped = pose; 00272 ik_request.ik_request.ik_seed_state.joint_state.position.resize(7); 00273 ik_request.ik_request.robot_state.joint_state.position.resize(7); 00274 00275 for (int i=0; i<7; i++) 00276 { 00277 ik_request.ik_request.ik_seed_state.joint_state.position[i] = start_angles[i]; 00278 ik_request.ik_request.robot_state.joint_state.position[i] = start_angles[i]; 00279 } 00280 00281 //ROS_INFO("request pose: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f", pose.pose.position.x, pose.pose.position.y, pose.pose.position.z, pose.pose.orientation.x, pose.pose.orientation.y, pose.pose.orientation.z, pose.pose.orientation.w); 00282 00283 ros::service::waitForService((side_==0) ? "pr2_right_arm_kinematics/get_ik" : "pr2_left_arm_kinematics/get_ik",1); 00284 00285 bool ik_service_call = ik_client.call(ik_request,ik_response); 00286 if (!ik_service_call) 00287 { 00288 ROS_ERROR("IK service call failed! is ik service running? %s",side_ ? "/pr2_left_arm_kinematics/get_ik" : "/pr2_right_arm_kinematics/get_ik"); 00289 return 0; 00290 } 00291 if (ik_response.error_code.val == ik_response.error_code.SUCCESS) 00292 { 00293 for (int i=0; i<7; i++) 00294 { 00295 solution[i] = ik_response.solution.joint_state.position[i]; 00296 } 00297 //ROS_INFO("solution angles: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f",solution[0],solution[1], solution[2],solution[3],solution[4],solution[5],solution[6]); 00298 //ROS_INFO("IK service call succeeded"); 00299 return true; 00300 } 00301 //ROS_INFO("IK service call error code: %d", ik_response.error_code.val); 00302 return false; 00303 } 00304 00305 bool RobotArm::run_ik(tf::Stamped<tf::Pose> pose, double start_angles[7],double solution[7], std::string link_name) 00306 { 00307 if (link_name == tool_frame) { 00308 //ROS_INFO("Converting to wrist"); 00309 pose = tool2wrist(pose); 00310 } 00311 pose = Geometry::getPoseIn("base_link", pose); 00312 printPose(pose); 00313 geometry_msgs::PoseStamped ps; 00314 tf::poseStampedTFToMsg(pose, ps); 00315 return run_ik(ps,start_angles,solution,wrist_frame); 00316 } 00317 00318 00320 void RobotArm::startTrajectory(pr2_controllers_msgs::JointTrajectoryGoal goal, bool wait) 00321 { 00322 00323 // When to start the trajectory: 1s from now 00324 goal.trajectory.header.stamp = ros::Time::now(); //; + ros::Duration(0.1); 00325 00326 traj_client_->sendGoal(goal); 00327 00328 if (wait) 00329 { 00330 00331 try 00332 { 00333 traj_client_->waitForResult(); 00334 } 00335 catch ( boost::thread_interrupted ti ) 00336 { 00337 traj_client_->cancelAllGoals(); 00338 ROS_ERROR("RobotArm startTrajectory side %i Interrupted: Thread killed. Cancelling all arm ac goals", this->side_); 00339 throw ti; 00340 } 00341 } 00342 00343 //if (traj_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED) 00344 // ROS_INFO("traj action succ"); 00345 //else 00346 // ROS_INFO("traj action failed"); 00347 } 00348 00349 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::goalTraj(double a0, double a1, double a2, double a3, double a4, double a5, double a6, double dur) 00350 { 00351 double a[7]; 00352 a[0] = a0; 00353 a[1] = a1; 00354 a[2] = a2; 00355 a[3] = a3; 00356 a[4] = a4; 00357 a[5] = a5; 00358 a[6] = a6; 00359 return goalTraj(a, dur); 00360 } 00361 00362 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::goalTraj(double *poseA, double dur) 00363 { 00364 00365 //ROS_INFO("JOINT TRAJECTORY CONTROL %s ARM", side_ == 0 ? "right" : "left"); 00366 00367 //our goal variable 00368 pr2_controllers_msgs::JointTrajectoryGoal goal; 00369 00370 // First, the joint names, which apply to all waypoints 00371 if (side_==0) 00372 { 00373 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint"); 00374 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint"); 00375 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint"); 00376 goal.trajectory.joint_names.push_back("r_elbow_flex_joint"); 00377 goal.trajectory.joint_names.push_back("r_forearm_roll_joint"); 00378 goal.trajectory.joint_names.push_back("r_wrist_flex_joint"); 00379 goal.trajectory.joint_names.push_back("r_wrist_roll_joint"); 00380 } 00381 else 00382 { 00383 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint"); 00384 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint"); 00385 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint"); 00386 goal.trajectory.joint_names.push_back("l_elbow_flex_joint"); 00387 goal.trajectory.joint_names.push_back("l_forearm_roll_joint"); 00388 goal.trajectory.joint_names.push_back("l_wrist_flex_joint"); 00389 goal.trajectory.joint_names.push_back("l_wrist_roll_joint"); 00390 } 00391 00392 // We will have two waypoints in this goal trajectory 00393 goal.trajectory.points.resize(1); 00394 00395 // First trajectory point 00396 int ind = 0; 00397 goal.trajectory.points[ind].positions.resize(7); 00398 goal.trajectory.points[ind].velocities.resize(7); 00399 for (size_t j = 0; j < 7; ++j) 00400 { 00401 goal.trajectory.points[ind].positions[j] = poseA[j]; 00402 goal.trajectory.points[ind].velocities[j] = 0.0; 00403 } 00404 // To be reached 1 second after starting along the trajectory 00405 goal.trajectory.points[ind].time_from_start = ros::Duration(dur); 00406 00407 //we are done; return the goal 00408 return goal; 00409 } 00410 00411 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::goalTraj(double *poseA, double *vel) 00412 { 00413 00414 //ROS_INFO("JOINT TRAJECTORY CONTROL %s ARM", side_ == 0 ? "right" : "left"); 00415 00416 //our goal variable 00417 pr2_controllers_msgs::JointTrajectoryGoal goal; 00418 00419 // First, the joint names, which apply to all waypoints 00420 if (side_==0) 00421 { 00422 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint"); 00423 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint"); 00424 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint"); 00425 goal.trajectory.joint_names.push_back("r_elbow_flex_joint"); 00426 goal.trajectory.joint_names.push_back("r_forearm_roll_joint"); 00427 goal.trajectory.joint_names.push_back("r_wrist_flex_joint"); 00428 goal.trajectory.joint_names.push_back("r_wrist_roll_joint"); 00429 } 00430 else 00431 { 00432 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint"); 00433 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint"); 00434 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint"); 00435 goal.trajectory.joint_names.push_back("l_elbow_flex_joint"); 00436 goal.trajectory.joint_names.push_back("l_forearm_roll_joint"); 00437 goal.trajectory.joint_names.push_back("l_wrist_flex_joint"); 00438 goal.trajectory.joint_names.push_back("l_wrist_roll_joint"); 00439 } 00440 00441 // We will have two waypoints in this goal trajectory 00442 goal.trajectory.points.resize(1); 00443 00444 // First trajectory point 00445 00446 int ind = 0; 00447 goal.trajectory.points[ind].positions.resize(7); 00448 goal.trajectory.points[ind].velocities.resize(7); 00449 for (size_t j = 0; j < 7; ++j) 00450 { 00451 goal.trajectory.points[ind].positions[j] = poseA[j]; 00452 goal.trajectory.points[ind].velocities[j] = vel[j]; 00453 } 00454 // To be reached 1 second after starting along the trajectory 00455 goal.trajectory.points[ind].time_from_start = ros::Duration(0.25); 00456 00457 //we are done; return the goal 00458 return goal; 00459 } 00460 00461 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::multiPointTrajectory(const std::vector<std::vector<double> > &poses, const double &duration) 00462 { 00463 00464 ROS_INFO("JOINT TRAJECTORY CONTROL %s ARM", side_ == 0 ? "right" : "left"); 00465 00466 pr2_controllers_msgs::JointTrajectoryGoal goal; 00467 00468 // First, the joint names, which apply to all waypoints 00469 if (side_==0) 00470 { 00471 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint"); 00472 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint"); 00473 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint"); 00474 goal.trajectory.joint_names.push_back("r_elbow_flex_joint"); 00475 goal.trajectory.joint_names.push_back("r_forearm_roll_joint"); 00476 goal.trajectory.joint_names.push_back("r_wrist_flex_joint"); 00477 goal.trajectory.joint_names.push_back("r_wrist_roll_joint"); 00478 } 00479 else 00480 { 00481 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint"); 00482 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint"); 00483 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint"); 00484 goal.trajectory.joint_names.push_back("l_elbow_flex_joint"); 00485 goal.trajectory.joint_names.push_back("l_forearm_roll_joint"); 00486 goal.trajectory.joint_names.push_back("l_wrist_flex_joint"); 00487 goal.trajectory.joint_names.push_back("l_wrist_roll_joint"); 00488 } 00489 00490 // We will have two waypoints in this goal trajectory 00491 goal.trajectory.points.resize(poses.size()); 00492 00493 for (size_t ind = 0; ind < poses.size(); ind++) 00494 { 00495 00496 goal.trajectory.points[ind].positions.resize(7); 00497 goal.trajectory.points[ind].velocities.resize(7); 00498 00499 ros::Duration timetonext = ros::Duration(duration / ((double) poses.size())); 00500 00501 for (size_t j = 0; j < 7; ++j) 00502 { 00503 goal.trajectory.points[ind].positions[j] = poses[ind][j]; 00504 if (ind == poses.size() -1) 00505 goal.trajectory.points[ind].velocities[j] = 0.0; 00506 else 00507 goal.trajectory.points[ind].velocities[j] = (poses[ind + 1][j] - poses[ind][j]) / timetonext.toSec(); 00508 } 00509 // To be reached 1 second after starting along the trajectory 00510 goal.trajectory.points[ind].time_from_start = ros::Duration((ind * duration) / ((double) poses.size())); 00511 } 00512 00513 //we are done; return the goal 00514 return goal; 00515 } 00516 00517 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::multiPointTrajectory(const std::vector<std::vector<double> > &poses, const std::vector<double> &duration) 00518 { 00519 00520 ROS_INFO("JOINT TRAJECTORY CONTROL %s ARM", side_ == 0 ? "right" : "left"); 00521 00522 pr2_controllers_msgs::JointTrajectoryGoal goal; 00523 00524 // First, the joint names, which apply to all waypoints 00525 if (side_==0) 00526 { 00527 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint"); 00528 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint"); 00529 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint"); 00530 goal.trajectory.joint_names.push_back("r_elbow_flex_joint"); 00531 goal.trajectory.joint_names.push_back("r_forearm_roll_joint"); 00532 goal.trajectory.joint_names.push_back("r_wrist_flex_joint"); 00533 goal.trajectory.joint_names.push_back("r_wrist_roll_joint"); 00534 } 00535 else 00536 { 00537 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint"); 00538 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint"); 00539 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint"); 00540 goal.trajectory.joint_names.push_back("l_elbow_flex_joint"); 00541 goal.trajectory.joint_names.push_back("l_forearm_roll_joint"); 00542 goal.trajectory.joint_names.push_back("l_wrist_flex_joint"); 00543 goal.trajectory.joint_names.push_back("l_wrist_roll_joint"); 00544 } 00545 00546 // We will have two waypoints in this goal trajectory 00547 goal.trajectory.points.resize(poses.size()); 00548 00549 for (size_t ind = 0; ind < poses.size(); ind++) 00550 { 00551 00552 ros::Duration timetonext = ros::Duration(duration[ind + 1] - duration[ind]); 00553 00554 goal.trajectory.points[ind].positions.resize(7); 00555 goal.trajectory.points[ind].velocities.resize(7); 00556 for (size_t j = 0; j < 7; ++j) 00557 { 00558 goal.trajectory.points[ind].positions[j] = poses[ind][j]; 00559 if (ind == poses.size() -1) 00560 goal.trajectory.points[ind].velocities[j] = 0; 00561 else 00562 goal.trajectory.points[ind].velocities[j] = (poses[ind + 1][j] - poses[ind][j]) / timetonext.toSec(); 00563 } 00564 // To be reached 1 second after starting along the trajectory 00565 goal.trajectory.points[ind].time_from_start = ros::Duration(duration[ind]); 00566 } 00567 00568 //we are done; return the goal 00569 return goal; 00570 } 00571 00572 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::multiPointTrajectory(const std::vector<tf::Stamped<tf::Pose> > &poses, const std::vector<double> &duration) 00573 { 00574 std::vector<std::vector<double> > jointstates; 00575 pose2Joint(poses, jointstates); 00576 return multiPointTrajectory(jointstates,duration); 00577 } 00578 00579 00580 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::twoPointTrajectory(double *poseA, double *poseB) 00581 { 00582 00583 ROS_INFO("JOINT TRAJECTORY CONTROL %s ARM", side_ == 0 ? "right" : "left"); 00584 00585 //tucked = (poseB == Poses::tuckPose); 00586 //our goal variable 00587 pr2_controllers_msgs::JointTrajectoryGoal goal; 00588 00589 // First, the joint names, which apply to all waypoints 00590 if (side_==0) 00591 { 00592 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint"); 00593 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint"); 00594 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint"); 00595 goal.trajectory.joint_names.push_back("r_elbow_flex_joint"); 00596 goal.trajectory.joint_names.push_back("r_forearm_roll_joint"); 00597 goal.trajectory.joint_names.push_back("r_wrist_flex_joint"); 00598 goal.trajectory.joint_names.push_back("r_wrist_roll_joint"); 00599 } 00600 else 00601 { 00602 goal.trajectory.joint_names.push_back("l_shoulder_pan_joint"); 00603 goal.trajectory.joint_names.push_back("l_shoulder_lift_joint"); 00604 goal.trajectory.joint_names.push_back("l_upper_arm_roll_joint"); 00605 goal.trajectory.joint_names.push_back("l_elbow_flex_joint"); 00606 goal.trajectory.joint_names.push_back("l_forearm_roll_joint"); 00607 goal.trajectory.joint_names.push_back("l_wrist_flex_joint"); 00608 goal.trajectory.joint_names.push_back("l_wrist_roll_joint"); 00609 } 00610 00611 // We will have two waypoints in this goal trajectory 00612 goal.trajectory.points.resize(2); 00613 00614 // First trajectory point 00615 00616 int ind = 0; 00617 goal.trajectory.points[ind].positions.resize(7); 00618 goal.trajectory.points[ind].velocities.resize(7); 00619 for (size_t j = 0; j < 7; ++j) 00620 { 00621 goal.trajectory.points[ind].positions[j] = poseA[j]; 00622 goal.trajectory.points[ind].velocities[j] = 0.0; 00623 } 00624 // To be reached 1 second after starting along the trajectory 00625 goal.trajectory.points[ind].time_from_start = ros::Duration(2.0); 00626 00627 // Second trajectory point 00628 00629 ind += 1; 00630 goal.trajectory.points[ind].positions.resize(7); 00631 goal.trajectory.points[ind].velocities.resize(7); 00632 for (size_t j = 0; j < 7; ++j) 00633 { 00634 goal.trajectory.points[ind].positions[j] = poseB[j]; 00635 goal.trajectory.points[ind].velocities[j] = 0.0; 00636 } 00637 // To be reached 2 seconds after starting along the trajectory 00638 goal.trajectory.points[ind].time_from_start = ros::Duration(4.0); 00639 00640 //we are done; return the goal 00641 return goal; 00642 } 00643 00644 // Returns the current state of the action 00645 actionlib::SimpleClientGoalState RobotArm::getState() 00646 { 00647 return traj_client_->getState(); 00648 } 00649 00650 void RobotArm::printPose(const tf::Stamped<tf::Pose> &toolTargetPose) 00651 { 00652 ROS_INFO("%f %f %f %f %f %f %f %s\n", 00653 toolTargetPose.getOrigin().x(), toolTargetPose.getOrigin().y(), toolTargetPose.getOrigin().z(),toolTargetPose.getRotation().x(), 00654 toolTargetPose.getRotation().y(),toolTargetPose.getRotation().z(),toolTargetPose.getRotation().w(),toolTargetPose.frame_id_.c_str()); 00655 00656 } 00657 00658 00659 tf::Stamped<tf::Pose> RobotArm::getToolPose(const char frame[]) 00660 { 00661 //tf::TransformListener listener; 00662 ros::Rate rate(100.0); 00663 00664 tf::StampedTransform transform; 00665 bool transformOk = false; 00666 while (ros::ok() && (!transformOk)) 00667 { 00668 transformOk = true; 00669 try 00670 { 00671 listener_->lookupTransform(frame, (side_==0) ? "r_gripper_tool_frame" : "l_gripper_tool_frame" ,ros::Time(0), transform); 00672 } 00673 catch (tf::TransformException ex) 00674 { 00675 ROS_ERROR("getToolPose s f %s",ex.what()); 00676 transformOk = false; 00677 } 00678 rate.sleep(); 00679 } 00680 tf::Stamped<tf::Pose> ret; 00681 ret.frame_id_ = transform.frame_id_; 00682 ret.stamp_ = transform.stamp_; 00683 ret.setOrigin(transform.getOrigin()); 00684 ret.setRotation(transform.getRotation()); 00685 00686 return ret; 00687 } 00688 00689 00690 00691 void RobotArm::getToolPose(tf::Stamped<tf::Pose> &marker, const char frame[]) 00692 { 00693 //tf::TransformListener listener; 00694 ros::Rate rate(100.0); 00695 00696 tf::StampedTransform transform; 00697 bool transformOk = false; 00698 while (ros::ok() && (!transformOk)) 00699 { 00700 transformOk = true; 00701 try 00702 { 00703 listener_->lookupTransform(frame, (side_==0) ? "r_gripper_tool_frame" : "l_gripper_tool_frame" ,ros::Time(0), transform); 00704 } 00705 catch (tf::TransformException ex) 00706 { 00707 ROS_ERROR("getToolPose s f %s",ex.what()); 00708 transformOk = false; 00709 } 00710 rate.sleep(); 00711 } 00712 marker.frame_id_ = transform.frame_id_; 00713 marker.setOrigin(transform.getOrigin()); 00714 marker.setRotation(transform.getRotation()); 00715 marker.stamp_ = transform.stamp_; 00716 } 00717 00718 00719 void RobotArm::getWristPose(tf::Stamped<tf::Pose> &marker, const char frame[]) 00720 { 00721 //tf::TransformListener listener; 00722 ros::Rate rate(100.0); 00723 00724 tf::StampedTransform transform; 00725 bool transformOk = false; 00726 while (ros::ok() && (!transformOk)) 00727 { 00728 transformOk = true; 00729 try 00730 { 00731 listener_->lookupTransform(frame, (side_==0) ? "r_wrist_roll_link" : "l_wrist_roll_link" ,ros::Time(0), transform); 00732 } 00733 catch (tf::TransformException ex) 00734 { 00735 ROS_ERROR("getWristPose s f %s",ex.what()); 00736 transformOk = false; 00737 } 00738 rate.sleep(); 00739 } 00740 marker.frame_id_ = transform.frame_id_; 00741 marker.setOrigin(transform.getOrigin()); 00742 marker.setRotation(transform.getRotation()); 00743 marker.stamp_ = transform.stamp_; 00744 } 00745 00746 00747 tf::Stamped<tf::Pose> RobotArm::rotate_toolframe_ik_p(double r_x, double r_y, double r_z) 00748 { 00749 //ROS_INFO("ROTATING TOOLFRAME %f %f %f", r_x, r_y, r_z); 00750 tf::Stamped<tf::Pose> toolTargetPose; 00751 tf::Stamped<tf::Pose> trans; 00752 getToolPose(trans); 00753 toolTargetPose = trans; 00754 toolTargetPose.setOrigin(trans.getOrigin()); 00755 toolTargetPose.setRotation(trans.getRotation()); 00756 00757 tf::Stamped<tf::Pose> toolTargetPoseRotPlus = toolTargetPose; 00758 toolTargetPose *= wrist2tool_; 00759 00760 // printPose(toolTargetPose); 00761 00762 // init with some yaw pitch roll 00763 tf::Stamped<tf::Pose> toolRotPlus; 00764 toolRotPlus.setOrigin(btVector3(0,0,0)); 00765 toolRotPlus.setRotation(btQuaternion(r_x,r_y,r_z)); 00766 00767 toolTargetPoseRotPlus*=toolRotPlus; 00768 toolTargetPoseRotPlus*=wrist2tool_; 00769 00770 return toolTargetPoseRotPlus; 00771 } 00772 00773 bool RobotArm::rotate_toolframe_ik(double r_x, double r_y, double r_z) 00774 { 00775 tf::Stamped<tf::Pose> toolTargetPoseRotPlus = rotate_toolframe_ik_p(r_x, r_y, r_z); 00776 00777 return move_ik(toolTargetPoseRotPlus.getOrigin().x(),toolTargetPoseRotPlus.getOrigin().y(),toolTargetPoseRotPlus.getOrigin().z(), 00778 toolTargetPoseRotPlus.getRotation().x(),toolTargetPoseRotPlus.getRotation().y(),toolTargetPoseRotPlus.getRotation().z(),toolTargetPoseRotPlus.getRotation().w(),0.1); 00779 00780 return true; 00781 } 00782 00783 00784 bool RobotArm::move_toolframe_ik_pose(tf::Stamped<tf::Pose> toolTargetPose) 00785 { 00786 tf::Stamped<tf::Pose> toolTargetPoseWristBase; 00787 00788 toolTargetPoseWristBase = Geometry::getPoseIn("base_link", toolTargetPose); 00789 toolTargetPoseWristBase = tool2wrist(toolTargetPoseWristBase); 00790 00791 //printPose(toolTargetPoseWristBase); 00792 00793 return move_ik(toolTargetPoseWristBase.getOrigin().x(),toolTargetPoseWristBase.getOrigin().y(),toolTargetPoseWristBase.getOrigin().z(), 00794 toolTargetPoseWristBase.getRotation().x(),toolTargetPoseWristBase.getRotation().y(),toolTargetPoseWristBase.getRotation().z(),toolTargetPoseWristBase.getRotation().w(),time_to_target); 00795 00796 00797 return true; 00798 } 00799 00800 //moves the toolframe to the given position 00801 bool RobotArm::move_toolframe_ik(double x, double y, double z, double ox, double oy, double oz, double ow) 00802 { 00803 tf::Stamped<tf::Pose> toolTargetPose; 00804 00805 toolTargetPose.frame_id_ = "base_link"; 00806 toolTargetPose.stamp_ = ros::Time(); 00807 toolTargetPose.setOrigin(btVector3( x,y,z)); 00808 toolTargetPose.setRotation(btQuaternion(ox,oy,oz,ow)); 00809 00810 return move_toolframe_ik_pose(toolTargetPose); 00811 00812 /*tf::Stamped<tf::Pose> wrist2tool; 00813 00814 if (side_==0) 00815 wrist2tool.frame_id_ = "r_wrist_roll_link"; 00816 else 00817 wrist2tool.frame_id_ = "l_wrist_roll_link"; 00818 wrist2tool.stamp_ = ros::Time(); 00819 wrist2tool.setOrigin(btVector3(-.18,0,0)); 00820 wrist2tool.setRotation(btQuaternion(0,0,0,1)); 00821 00822 toolTargetPose *= wrist2tool; 00823 00824 printPose(toolTargetPose); 00825 00826 return move_ik(toolTargetPose.getOrigin().x(),toolTargetPose.getOrigin().y(),toolTargetPose.getOrigin().z(), 00827 toolTargetPose.getRotation().x(),toolTargetPose.getRotation().y(),toolTargetPose.getRotation().z(),toolTargetPose.getRotation().w(),time_to_target); 00828 00829 00830 return true;*/ 00831 } 00832 00833 00834 void RobotArm::stabilize_grip() 00835 { 00836 RobotArm *arm = this; 00837 00838 double oldtime = time_to_target; 00839 time_to_target = 1.2; 00840 00841 Pressure *p = Pressure::getInstance(side_); 00842 00843 ros::Rate rate(25.0); 00844 double pGain = 0.02; //actually seomthing p-gainy and not an increment 00845 double limit = 0.25; 00846 long cnt_ok = 0; 00847 long cnt_bad = 0; 00848 double lastval = 0; 00849 double lastdiff = 100; 00850 double lastchange = 0; // what did we do 00851 double lasteffect = 0; // how did it change the pressure center difference? 00852 while (ros::ok() && (cnt_ok < 5) && (cnt_bad < 100)) 00853 { 00854 rate.sleep(); 00855 ros::spinOnce(); 00856 double r[2],l[2]; 00857 p->getCenter(r,l); 00858 00859 double d[2]; 00860 d[0] = r[0] - l[0]; 00861 d[1] = r[1] - l[1]; 00862 00863 ROS_INFO("SIDE %i CENTERS %f %f , %f %f DIFFS %f %f", side_, r[0], r[1], l[0], l[1], d[0], d[1]); 00864 00865 lasteffect = d[1] - lastdiff; 00866 if (lastchange != 0) 00867 { 00868 double optpGain = fabs(pGain * (d[1] / lasteffect)); // for now only positive gains, although there are some strange cases where the effect seems reversed 00869 if (optpGain > 0.1) 00870 optpGain = 0.1; 00871 if (optpGain < -0.1) 00872 optpGain = -0.1; 00873 ROS_INFO("change %f effect %f change in pGains %f, new pGain %f", lastchange, lasteffect, lastchange / pGain,optpGain); 00874 pGain = optpGain; 00875 } 00876 00877 double k = d[1]; 00878 double current = 0; 00879 if (k > 1) 00880 k = 1; 00881 if (k < -1) 00882 k = -1; 00883 00884 lastchange = 0; 00885 if (fabs(d[1]) > limit) 00886 { 00887 if (d[1] > 0) 00888 ROS_INFO("pos DIFF %f %f limit %f k %f", d[0], d[1], limit, k); 00889 else 00890 ROS_INFO("neg DIFF %f %f limit %f k %f", d[0], d[1], limit, k); 00891 00892 arm->rotate_toolframe_ik(pGain * k,0,0); 00893 lastchange = pGain * k; 00894 ros::spinOnce(); 00895 current = +1; 00896 } 00897 00898 if (fabs(d[1]) > fabs(lastdiff)) 00899 { 00900 00901 ROS_INFO("SOMETHINGS WRONG, GET OUT OF STABIL %f %f", fabs(d[1]), fabs(lastdiff)); 00902 cnt_bad = 1000; 00903 } 00904 lastdiff = d[1]; 00905 00906 if (fabs(current - lastval) > 1.5) 00907 { 00908 ROS_INFO("LET ME OUT limit %f", limit); 00909 limit *= 2; 00910 pGain *= 0.5; 00911 } 00912 00913 if (fabs(d[1]) < limit) 00914 cnt_ok++; 00915 else 00916 cnt_bad++; 00917 } 00918 00919 time_to_target = oldtime; 00920 } 00921 00922 00923 bool RobotArm::move_ik(tf::Stamped<tf::Pose> targetPose, double time) 00924 { 00925 00926 ROS_INFO("MOVE TIME %f", time); 00927 tf::Stamped<tf::Pose> inbase = Geometry::getPoseIn("base_link", targetPose); 00928 return move_ik(inbase.getOrigin().x(), inbase.getOrigin().y(), inbase.getOrigin().z(), inbase.getRotation().x(), inbase.getRotation().y(), inbase.getRotation().z(), inbase.getRotation().w(), time); 00929 } 00930 00931 // rosrun tf tf_echo /base_link /r_wrist_roll_link -> position 00932 bool RobotArm::move_ik(double x, double y, double z, double ox, double oy, double oz, double ow, double time) 00933 { 00934 00935 ROS_INFO("%s arm move ik action started %f %f %f %f %f %f %f (time %f)",((side_==0) ? "right" : "left"), x, y, z, ox, oy, oz, ow, time); 00936 //actionlib::SimpleActionClient<pr2_common_action_msgs::ArmMoveIKAction> ac("r_arm_ik", true); 00937 00938 //ac.waitForServer(); //will wait for infinite time 00939 00940 //ROS_INFO("server found."); 00941 00942 pr2_common_action_msgs::ArmMoveIKGoal goal; 00943 goal.pose.header.frame_id = "base_link"; 00944 goal.pose.header.stamp = ros::Time(0); 00945 00946 goal.pose.pose.orientation.x = ox; 00947 goal.pose.pose.orientation.y = oy; 00948 goal.pose.pose.orientation.z = oz; 00949 goal.pose.pose.orientation.w = ow; 00950 goal.pose.pose.position.x = x; 00951 goal.pose.pose.position.y = y; 00952 goal.pose.pose.position.z = z; 00953 00954 goal.ik_timeout = ros::Duration(5.0); 00955 00956 if (side_==0) 00957 { 00958 goal.ik_seed.name.push_back("r_shoulder_pan_joint"); 00959 goal.ik_seed.name.push_back("r_shoulder_lift_joint"); 00960 goal.ik_seed.name.push_back("r_upper_arm_roll_joint"); 00961 goal.ik_seed.name.push_back("r_elbow_flex_joint"); 00962 goal.ik_seed.name.push_back("r_forearm_roll_joint"); 00963 goal.ik_seed.name.push_back("r_wrist_flex_joint"); 00964 goal.ik_seed.name.push_back("r_wrist_roll_joint"); 00965 } 00966 else 00967 { 00968 goal.ik_seed.name.push_back("l_shoulder_pan_joint"); 00969 goal.ik_seed.name.push_back("l_shoulder_lift_joint"); 00970 goal.ik_seed.name.push_back("l_upper_arm_roll_joint"); 00971 goal.ik_seed.name.push_back("l_elbow_flex_joint"); 00972 goal.ik_seed.name.push_back("l_forearm_roll_joint"); 00973 goal.ik_seed.name.push_back("l_wrist_flex_joint"); 00974 goal.ik_seed.name.push_back("l_wrist_roll_joint"); 00975 } 00976 00977 ros::Rate rate(20); 00978 bool good = true; 00979 while (!good) 00980 { 00981 mutex_.lock(); 00982 // start from current joint states 00983 good = true; 00984 for (int i=0; i<7; ++i) 00985 { 00986 //sumofj += jointState[i]; 00987 if (jointState[i] == 0.0f) 00988 good = false; 00989 } 00990 //ROS_INFO("Joint States %f %f %f %f %f %f %f", jointState[0],jointState[1],jointState[2],jointState[3],jointState[4],jointState[5],jointState[6]); 00991 mutex_.unlock(); 00992 ros::spinOnce(); 00993 rate.sleep(); 00994 } 00995 00996 mutex_.lock(); // for accessing current joint state 00997 for (int i=0; i<7; ++i) 00998 { 00999 if ((i != 2) || (!raise_elbow)) 01000 goal.ik_seed.position.push_back(jointState[i]); 01001 else 01002 goal.ik_seed.position.push_back((side_==0) ? -preset_angle : preset_angle); 01003 //goal.ik_seed.position.push_back((side_==0) ? -3.1 : 3.1); 01004 01005 //ROS_INFO("JOINT %i : %f", i, goal.ik_seed.position[i]); 01006 } 01007 01008 01009 mutex_.unlock(); 01010 // somewhat close to what we use for looking at the drawer 01011 goal.move_duration = ros::Duration(time); 01012 01013 ac_->sendGoal(goal); 01014 01015 if (!evil_switch) 01016 { 01017 01018 bool finished_before_timeout = false; 01019 try 01020 { 01021 finished_before_timeout = ac_->waitForResult(ros::Duration(time_to_target + 3.0f)); 01022 } 01023 catch ( boost::thread_interrupted ti) 01024 { 01025 ac_->cancelAllGoals(); 01026 ROS_ERROR("MOVE_IK side %i Interrupted: Thread killed. Cancelling all arm ac goals", this->side_); 01027 throw ti; 01028 } 01029 if (finished_before_timeout) 01030 { 01031 actionlib::SimpleClientGoalState state = ac_->getState(); 01032 ROS_INFO("%s Arm Action finished: %s",((side_==0) ? "right" : "left"), state.toString().c_str()); 01033 if ((state == actionlib::SimpleClientGoalState::PREEMPTED) || (state == actionlib::SimpleClientGoalState::SUCCEEDED)) 01034 return true; 01035 else 01036 { 01037 ROS_ERROR("Action finished: %s", state.toString().c_str()); 01038 ROS_ERROR("In move_ik, with arm %i", this->side_); 01039 ROS_ERROR("failed goal (in base): %f %f %f %f %f %f %f (time %f)", x, y, z, ox, oy, oz, ow, time); 01040 //if (--retries > 0) 01041 // return move_ik(x, y, z, ox, oy, oz, ow, time); 01042 //else 01043 return false; 01044 } 01045 } 01046 else 01047 ROS_INFO("Action did not finish before the time out."); 01048 return false; 01049 } 01050 else return true; 01051 } 01052 01053 01054 RobotArm *RobotArm::instance[] = {0,0}; 01055 01056 tf::Stamped<tf::Pose> RobotArm::tool2wrist(tf::Stamped<tf::Pose> toolPose) 01057 { 01058 tf::Stamped<tf::Pose> ret; 01059 ret = toolPose; 01060 ret *= tool2wrist_; 01061 return ret; 01062 } 01063 01064 tf::Stamped<tf::Pose> RobotArm::wrist2tool(tf::Stamped<tf::Pose> toolPose) 01065 { 01066 tf::Stamped<tf::Pose> ret; 01067 ret = toolPose; 01068 ret *= wrist2tool_; 01069 return ret; 01070 } 01071 01072 01073 //bool RobotArm::checkHypothesis() 01074 01075 #include <stdio.h> 01076 #include <stdlib.h> 01077 01078 bool RobotArm::findBaseMovement(tf::Stamped<tf::Pose> &result, std::vector<int> arm, std::vector<tf::Stamped<tf::Pose> > goal, bool drive, bool reach) 01079 { 01080 01081 init(); 01082 01083 //system("rosrun dynamic_reconfigure dynparam set /camera_synchronizer_node projector_mode 1"); 01084 01085 ros::NodeHandle node_handle; 01086 //ros::Publisher vis_pub = node_handle.advertise<visualization_msgs::Marker>( "visualization_marker", 0 ); 01087 ros::Publisher vis_pub = node_handle.advertise<visualization_msgs::Marker>( "robot_arm_marker", 1000 ); 01088 01089 ROS_INFO("looking for base movement to satisfy ik constraints : "); 01090 01091 if (arm.size() != goal.size()) 01092 { 01093 ROS_ERROR("NUMBER OF GOAL TRAJECTORY POINTS DIFFERENT FROM ARM SELECTION"); 01094 return false; 01095 } 01096 01097 find_base_pose::FindBasePoseGoal goal_msg; 01098 01099 bool some_outside_workspace = false; // TODO: move this test also to find_base_pose package 01100 01101 for (size_t k=0; k < arm.size(); ++k) 01102 { 01103 01104 geometry_msgs::PoseStamped ps; 01105 tf::poseStampedTFToMsg(goal[k],ps); 01106 01107 std_msgs::Int32 int32; 01108 int32.data = arm[k]; 01109 goal_msg.target_poses.push_back(ps); 01110 goal_msg.arm.push_back(int32); 01111 01112 if (!some_outside_workspace) 01113 { 01114 double start_angles[7]; 01115 RobotArm::getInstance(arm[k])->getJointState(start_angles); 01116 double sol_angles[7]; 01117 tf::Stamped<tf::Pose> inWrist = RobotArm::getInstance(arm[k])->tool2wrist(goal[k]); 01118 geometry_msgs::PoseStamped pstamped; 01119 tf::poseStampedTFToMsg(inWrist, pstamped); 01120 bool found = RobotArm::getInstance(arm[k])->run_ik(ps, start_angles, sol_angles, (arm[k] == 0) ? "r_wrist_roll_link" : "l_wrist_roll_link"); 01121 if (!found) 01122 some_outside_workspace = true; 01123 } 01124 } 01125 01126 if (!some_outside_workspace) 01127 { 01128 result.setOrigin(btVector3(0,0,0)); 01129 result.setRotation(btQuaternion(0,0,0,1)); 01130 ROS_INFO("find_base_pose: should exit now because all points are within workspace"); 01131 //return true; // TODO: why does this not work ? 01132 } 01133 //ROS_ERROR("we shouldnt be here"); 01134 01135 01136 ROS_INFO("Waiting for action server to start."); 01137 // wait for the action server to start 01138 //ac_fbp_->waitForServer(); //will wait for infinite time 01139 01140 ac_fbp_->sendGoal(goal_msg); 01141 01142 bool finished_before_timeout = ac_fbp_->waitForResult(ros::Duration(15.0)); 01143 01144 if (!finished_before_timeout) 01145 { 01146 ROS_INFO("findBaseMovement Action did not finish before the time out."); 01147 return false; 01148 } 01149 01150 actionlib::SimpleClientGoalState state = ac_fbp_->getState(); 01151 ROS_INFO("Action finished: %s",state.toString().c_str()); 01152 find_base_pose::FindBasePoseResultConstPtr res = ac_fbp_->getResult(); 01153 01154 if (res->base_poses.size() < 1) 01155 { 01156 ROS_INFO(" findBaseMovement Action finished before the time out but without success."); 01157 return false; 01158 } 01159 01160 for (size_t k = 0; k < res->base_poses.size(); ++k) 01161 { 01162 tf::Stamped<tf::Pose> respose; 01163 tf::poseStampedMsgToTF(res->base_poses[k], respose); 01164 ROS_INFO("Result: %f %f %f", res->base_poses[k].pose.position.x, res->base_poses[k].pose.position.y,respose.getRotation().getAngle()); 01165 } 01166 01167 //if (minDist < 10000) 01168 tf::Stamped<tf::Pose> respose; 01169 tf::poseStampedMsgToTF(res->base_poses[0], respose); 01170 01171 double ps[4]; 01172 ps[0] = respose.getOrigin().x(); 01173 ps[1] = respose.getOrigin().y(); 01174 ps[2] = respose.getRotation().z(); 01175 ps[3] = respose.getRotation().w(); 01176 01177 ROS_ERROR("FOUND BASE MOVEMENT %f %f %f %f", ps[0], ps[1], ps[2], ps[3]); 01178 01179 tf::Stamped<tf::Pose> inMap = Geometry::getPoseIn("map", respose); 01180 01181 ROS_INFO("In Map: "); 01182 printPose(inMap); 01183 01184 RobotDriver *driver = RobotDriver::getInstance(); 01185 // todo: chck for localization, since move base is not exact! pose -> mappose -> pose 01186 //move_ik(x + best_x,y + best_y,z,ox,oy,oz,ow); 01187 if (drive && ((fabs(ps[0]) > 0.001) || (fabs(ps[1]) > 0.001) || (fabs(ps[2]) > 0.001))) // && ((fabs(best_x) > 0.01) || (fabs(best_y) > 0.01))) 01188 { 01189 //driver->driveInOdom(ps,true); 01190 boost::thread t2(&RobotDriver::driveInOdom,driver,ps,true); 01191 //boost::thread t2(&RobotDriver::driveInOdom,driver,ps,false); 01192 ros::Rate rate(25.0); 01193 while (!t2.timed_join(boost::posix_time::seconds(0.01))) 01194 { 01195 //ROS_ERROR("not yet joinable"); 01196 tf::Stamped<tf::Pose> firstGoalBase = Geometry::getPoseIn("base_link",goal[0]); 01197 if (reach) 01198 RobotArm::getInstance(arm[0])->move_toolframe_ik(firstGoalBase.getOrigin().x(), firstGoalBase.getOrigin().y(), firstGoalBase.getOrigin().z(), 01199 firstGoalBase.getRotation().x(),firstGoalBase.getRotation().y(),firstGoalBase.getRotation().z(),firstGoalBase.getRotation().w()); 01200 //RobotArm::getInstance(arm[0])->move_toolframe_ik(x + best_x,y + best_y,z,ox,oy,oz,ow); 01201 rate.sleep(); 01202 } 01203 t2.join(); 01204 01205 } 01206 01207 //result = btVector3(best_x, best_y, 0); 01208 result = respose; 01209 return true; 01210 01211 01212 } 01213 01214 /* 01215 tf::Stamped<tf::Pose> RobotArm::make_pose(double x, double y, double z, double ox, double oy, double oz, double ow, const char target_frame[]) 01216 { 01217 tf::Stamped<tf::Pose> toolTargetPose; 01218 01219 toolTargetPose.frame_id_ = target_frame; 01220 toolTargetPose.stamp_ = ros::Time(0); 01221 toolTargetPose.setOrigin(btVector3( x,y,z)); 01222 toolTargetPose.setRotation(btQuaternion(ox,oy,oz,ow)); 01223 01224 return toolTargetPose; 01225 } 01226 01227 tf::Stamped<tf::Pose> RobotArm::make_pose(const btTransform &trans, const char target_frame[]) 01228 { 01229 tf::Stamped<tf::Pose> toolTargetPose; 01230 toolTargetPose.frame_id_ = target_frame; 01231 toolTargetPose.stamp_ = ros::Time(0); 01232 toolTargetPose.setOrigin(trans.getOrigin()); 01233 toolTargetPose.setRotation(trans.getRotation()); 01234 01235 return toolTargetPose; 01236 } 01237 */ 01238 01239 01240 // move the toolframe including base motions when necessary 01241 btVector3 RobotArm::universal_move_toolframe_ik(double x, double y, double z, double ox, double oy, double oz, double ow, const char target_frame[]) 01242 { 01243 tf::Stamped<tf::Pose> toolTargetPose; 01244 01245 toolTargetPose.frame_id_ = target_frame; 01246 toolTargetPose.stamp_ = ros::Time(0); 01247 toolTargetPose.setOrigin(btVector3( x,y,z)); 01248 toolTargetPose.setRotation(btQuaternion(ox,oy,oz,ow)); 01249 01250 return universal_move_toolframe_ik_pose(toolTargetPose); 01251 } 01252 01253 void RobotArm::bring_into_reach(tf::Stamped<tf::Pose> toolTargetPose) 01254 { 01255 std::vector<int> arm; 01256 std::vector<tf::Stamped<tf::Pose> > goal; 01257 tf::Stamped<tf::Pose> result; 01258 arm.push_back(side_); 01259 //toolTargetPose *= wrist2tool; 01260 tf::Stamped<tf::Pose> toolTargetPoseInMap = Geometry::getPoseIn("map",toolTargetPose); 01261 goal.push_back(toolTargetPoseInMap); 01262 //goal.push_back(toolTargetPose); 01263 ROS_INFO("BRING INTO REACH "); 01264 RobotArm::findBaseMovement(result, arm, goal, true, false); 01265 } 01266 01267 bool RobotArm::reachable(tf::Stamped<tf::Pose> target) 01268 { 01269 01270 tf::Stamped<tf::Pose> toolTargetPoseInBase = Geometry::getPoseIn("base_link",target); 01271 //ROS_INFO("tool in base_link"); 01272 //printPose(toolTargetPoseInBase); 01273 01274 tf::Stamped<tf::Pose> wristTargetBase = tool2wrist(toolTargetPoseInBase); 01275 01276 //ROS_INFO("wrist in base_link"); 01277 //printPose(wristTargetBase); 01278 01279 geometry_msgs::PoseStamped stamped_pose; 01280 tf::poseStampedTFToMsg(wristTargetBase,stamped_pose); 01281 01282 double new_state[7]; 01283 01284 double start_angles[7]; 01285 getJointState(start_angles); 01286 01287 if (raise_elbow) 01288 start_angles[2] = ((side_==0) ? -preset_angle : preset_angle); 01289 01290 return run_ik(stamped_pose,start_angles,new_state,wrist_frame); 01291 01292 } 01293 01294 01295 btVector3 RobotArm::universal_move_toolframe_ik_pose(tf::Stamped<tf::Pose> toolTargetPose) 01296 { 01297 tf::Stamped<tf::Pose> toolTargetPoseInBase = Geometry::getPoseIn("base_link",toolTargetPose); 01298 ROS_INFO("tool in base_link"); 01299 printPose(toolTargetPoseInBase); 01300 01301 tf::Stamped<tf::Pose> toolPose; 01302 getToolPose(toolPose, "base_link"); 01303 //ROS_INFO("tool pose in base link"); 01304 //printPose(toolPose); 01305 01306 tf::Stamped<tf::Pose> wristTargetBase = tool2wrist(toolTargetPoseInBase); 01307 01308 ROS_INFO("wrist in base_link"); 01309 printPose(wristTargetBase); 01310 01311 geometry_msgs::PoseStamped stamped_pose; 01312 tf::poseStampedTFToMsg(wristTargetBase,stamped_pose); 01313 01314 double new_state[7]; 01315 01316 double start_angles[7]; 01317 getJointState(start_angles); 01318 01319 if (raise_elbow) 01320 start_angles[2] = ((side_==0) ? -preset_angle : preset_angle); 01321 01322 bool foundInitially = run_ik(stamped_pose,start_angles,new_state,wrist_frame); 01323 01324 //if (poseInsideFootprint && excludeBaseProjectionFromWorkspace) 01325 // foundInitially = false; 01326 bool poseInsideFootprint = false; 01327 if (0) 01328 if (excludeBaseProjectionFromWorkspace) 01329 { 01330 ROS_WARN("excludeBaseProjectionFromWorkspace == true"); 01331 01332 double padding = 0.05; 01333 double x = stamped_pose.pose.position.x; 01334 double y = stamped_pose.pose.position.y; 01335 // does target pose lie inside projection of base footprint? 01336 if ((x < .325 + padding) && (x > -.325 - padding) && (y < .325 + padding) && (y > -.325 - padding)) 01337 poseInsideFootprint = true; 01338 } 01339 01340 01341 //if (!move_ik(x,y,z,ox,oy,oz,ow,time_to_target)) 01342 if (foundInitially && !poseInsideFootprint && move_ik(wristTargetBase.getOrigin().x(),wristTargetBase.getOrigin().y(),wristTargetBase.getOrigin().z(), 01343 wristTargetBase.getRotation().x(),wristTargetBase.getRotation().y(),wristTargetBase.getRotation().z(),wristTargetBase.getRotation().w(),time_to_target)) 01344 { 01345 if (!foundInitially) 01346 ROS_ERROR("RUN IK SAYS NOT FOUND INITIALLY BUT WE REACHED IT WITH MOVE_IK"); 01347 01348 return btVector3(0,0,0); 01349 } 01350 else 01351 { 01352 if (foundInitially) 01353 { 01354 ROS_ERROR("RobotArm::universal_move_toolframe_ik run_ik says reachable move_ik says not!"); 01355 } 01356 else 01357 { 01358 ROS_ERROR("NOT FOUND INITIALLY"); 01359 } 01360 ROS_INFO("looking for base movement to reach tf %f %f %f %f %f %f %f in %s", toolTargetPose.getOrigin().x(),toolTargetPose.getOrigin().y(),toolTargetPose.getOrigin().z(), 01361 toolTargetPose.getRotation().x(),toolTargetPose.getRotation().y(),toolTargetPose.getRotation().z(),toolTargetPose.getRotation().w(), toolTargetPose.frame_id_.c_str()); 01362 01363 std::vector<int> arm; 01364 std::vector<tf::Stamped<tf::Pose> > goal; 01365 tf::Stamped<tf::Pose> result; 01366 arm.push_back(side_); 01367 //toolTargetPose *= wrist2tool; 01368 tf::Stamped<tf::Pose> toolTargetPoseInMap = Geometry::getPoseIn("map",toolTargetPose); 01369 goal.push_back(toolTargetPoseInMap); 01370 //goal.push_back(toolTargetPose); 01371 RobotArm::findBaseMovement(result, arm, goal, true, true); 01372 return universal_move_toolframe_ik_pose(toolTargetPoseInMap); 01373 } 01374 01375 01376 return btVector3(0,0,0); 01377 } 01378 01379 01380 btVector3 RobotArm::universal_move_toolframe_ik_pose_tolerance(tf::Stamped<tf::Pose> toolTargetPose, double tolerance, double timeout) 01381 { 01382 01383 evil_switch = true; 01384 01385 ros::Time start = ros::Time::now(); 01386 01387 universal_move_toolframe_ik_pose(toolTargetPose); 01388 01389 bool reached = false; 01390 while (!reached) 01391 { 01392 reached = (getToolPose(toolTargetPose.frame_id_.c_str()).getOrigin() - toolTargetPose.getOrigin()).length() < tolerance; 01393 if ((ros::Time::now() - start) > ros::Duration(timeout)) 01394 reached = true; 01395 ros::Duration(0.001).sleep(); 01396 } 01397 01398 ROS_INFO("universal_move_toolframe_ik_pose_tolerance DIST : %f ", (getToolPose(toolTargetPose.frame_id_.c_str()).getOrigin() - toolTargetPose.getOrigin()).length()); 01399 01400 evil_switch = false; 01401 01402 return btVector3(0,0,0); 01403 } 01404 01405 01406 01407 tf::Stamped<tf::Pose> RobotArm::runFK(double jointAngles[], tf::Stamped<tf::Pose> *elbow) 01408 { 01409 01410 tf::Stamped<tf::Pose> res; 01411 // define the service messages 01412 kinematics_msgs::GetKinematicSolverInfo::Request request; 01413 kinematics_msgs::GetKinematicSolverInfo::Response response; 01414 01415 ros::service::waitForService((side_==0) ? "pr2_right_arm_kinematics/get_fk_solver_info" : "pr2_left_arm_kinematics/get_fk_solver_info"); 01416 01417 if (query_client.call(request,response)) 01418 { 01419 01420 //for (unsigned int i=0; i < response.kinematic_solver_info.joint_names.size(); i++) 01421 // { 01422 // ROS_INFO("Joint: %d %s", i,response.kinematic_solver_info.joint_names[i].c_str()); 01423 // } 01424 } 01425 else 01426 { 01427 ROS_ERROR("Could not call query service"); 01428 //ros::shutdown(); 01429 //exit(1); 01430 return res; 01431 } 01432 // define the service messages 01433 kinematics_msgs::GetPositionFK::Request fk_request; 01434 kinematics_msgs::GetPositionFK::Response fk_response; 01435 //fk_request.header.frame_id = "torso_lift_link"; 01436 //fk_request.header.frame_id = "torso_lift_joint"; 01437 fk_request.header.frame_id = "base_link"; 01438 fk_request.fk_link_names.resize(2); 01439 //for (int i = 0; i < 7; ++i) { 01440 //ROS_INFO("LINK %i : %s", i, joint_names[i].c_str()); 01441 //fk_request.fk_link_names[i] = joint_names[i]; 01442 //} 01443 fk_request.fk_link_names[0] = (side_==0) ? "r_wrist_roll_link" : "l_wrist_roll_link"; 01444 fk_request.fk_link_names[1] = (side_==0) ? "r_elbow_flex_link" : "l_elbow_flex_link" ; 01445 //fk_request.fk_link_names[0] = "r_wrist_roll_link"; 01446 //fk_request.fk_link_names[1] = "r_elbow_flex_link"; 01447 //fk_request.robot_state.joint_state.position.resize(response.kinematic_solver_info.joint_names.size()); 01448 fk_request.robot_state.joint_state.position.resize(7); 01449 fk_request.robot_state.joint_state.name=response.kinematic_solver_info.joint_names; 01450 for (unsigned int i=0; 01451 i< response.kinematic_solver_info.joint_names.size(); i++) 01452 { 01453 //ROS_INFO("LINK %i : %f", i, jointAngles[i]); 01454 fk_request.robot_state.joint_state.position[i] = jointAngles[i]; 01455 } 01456 01457 ros::service::waitForService((side_==0) ? "pr2_right_arm_kinematics/get_fk" : "pr2_left_arm_kinematics/get_fk"); 01458 if (fk_client.call(fk_request, fk_response)) 01459 { 01460 //if (0) 01461 if (fk_response.error_code.val == fk_response.error_code.SUCCESS) 01462 { 01463 if (0) 01464 for (unsigned int i=0; i < fk_response.pose_stamped.size(); i ++) 01465 { 01466 ROS_INFO_STREAM("Link : " << fk_response.fk_link_names[i].c_str()); 01467 ROS_INFO_STREAM("Position: " << 01468 fk_response.pose_stamped[i].pose.position.x << "," << 01469 fk_response.pose_stamped[i].pose.position.y << "," << 01470 fk_response.pose_stamped[i].pose.position.z); 01471 ROS_INFO("Orientation: %f %f %f %f", 01472 fk_response.pose_stamped[i].pose.orientation.x, 01473 fk_response.pose_stamped[i].pose.orientation.y, 01474 fk_response.pose_stamped[i].pose.orientation.z, 01475 fk_response.pose_stamped[i].pose.orientation.w); 01476 } 01477 01478 01479 res.frame_id_ = fk_request.header.frame_id; 01480 int o = 0; 01481 res.setOrigin(btVector3(fk_response.pose_stamped[o].pose.position.x, fk_response.pose_stamped[o].pose.position.y, fk_response.pose_stamped[o].pose.position.z)); 01482 res.setRotation(btQuaternion(fk_response.pose_stamped[o].pose.orientation.x,fk_response.pose_stamped[o].pose.orientation.y,fk_response.pose_stamped[o].pose.orientation.z,fk_response.pose_stamped[o].pose.orientation.w)); 01483 01484 if (elbow) 01485 { 01486 res.frame_id_ = fk_request.header.frame_id; 01487 int o = 1; 01488 elbow->setOrigin(btVector3(fk_response.pose_stamped[o].pose.position.x, fk_response.pose_stamped[o].pose.position.y, fk_response.pose_stamped[o].pose.position.z)); 01489 elbow->setRotation(btQuaternion(fk_response.pose_stamped[o].pose.orientation.x,fk_response.pose_stamped[o].pose.orientation.y,fk_response.pose_stamped[o].pose.orientation.z,fk_response.pose_stamped[o].pose.orientation.w)); 01490 } 01491 } 01492 else 01493 { 01494 ROS_ERROR("Forward kinematics failed"); 01495 } 01496 } 01497 else 01498 { 01499 ROS_ERROR("Forward kinematics service call failed"); 01500 } 01501 01502 01503 //fk_request.fk_link_names[1] = "r_elbow_flex_link"; 01504 01505 return res; 01506 } 01507 01508 01509 btVector3 RobotArm::cartError() 01510 { 01511 double state[7]; 01512 getJointState(state); 01513 double stateDes[7]; 01514 getJointStateDes(stateDes); 01515 tf::Stamped<tf::Pose> posAct = runFK(state); 01516 tf::Stamped<tf::Pose> posDes = runFK(stateDes); 01517 btVector3 diff = posDes.getOrigin() - posAct.getOrigin(); 01518 //ROS_INFO("DIFF %f %f %f DISTANCE %f", diff.x(), diff.y(), diff.y(), diff.length()); 01519 return diff; 01520 } 01521 01522 01523 void RobotArm::moveElbowOutOfWay(tf::Stamped<tf::Pose> toolTargetPose) 01524 { 01525 01526 RobotArm *arm = this; 01527 double state[7]; 01528 arm->getJointState(state); 01529 01530 tf::Stamped<tf::Pose> actPose; 01531 actPose = tool2wrist(Geometry::getPoseIn("base_link", toolTargetPose)); 01532 01533 01534 //arm->getWristPose(actPose,"base_link"); 01535 01536 geometry_msgs::PoseStamped stamped_pose; 01537 stamped_pose.header.frame_id = "base_link"; 01538 stamped_pose.header.stamp = ros::Time::now(); 01539 stamped_pose.pose.position.x=actPose.getOrigin().x(); 01540 stamped_pose.pose.position.y=actPose.getOrigin().y(); 01541 stamped_pose.pose.position.z=actPose.getOrigin().z(); 01542 stamped_pose.pose.orientation.x=actPose.getRotation().x(); 01543 stamped_pose.pose.orientation.y=actPose.getRotation().y(); 01544 stamped_pose.pose.orientation.z=actPose.getRotation().z(); 01545 stamped_pose.pose.orientation.w=actPose.getRotation().w(); 01546 01547 ros::Rate rate(50.0); 01548 01549 //for (double add = 0; ros::ok(); add+= 0.01) 01550 while (ros::ok()) 01551 { 01552 rate.sleep(); 01553 ros::spinOnce(); 01554 01555 double jErr[7]; 01556 double jDes[7]; 01557 01558 arm->getJointStateErr(jErr); 01559 arm->getJointStateDes(jDes); 01560 01561 double increment = .1; 01562 01563 ROS_INFO("jERR[1]=%f", jErr[1]); 01564 01565 if (fabs(jErr[1]) > 0.0001) 01566 { 01567 // { 01568 01569 double stateP[7]; 01570 double statePK[7]; 01571 double stateM[7]; 01572 //double solStateP[7]; 01573 //double solStatePK[7]; 01574 //double solStateM[7]; 01575 01576 arm->getJointState(stateP); 01577 arm->getJointState(statePK); 01578 arm->getJointState(stateM); 01579 01580 double stA[7]; 01581 double stB[7]; 01582 double stC[7]; 01583 arm->getJointState(stA); 01584 arm->getJointState(stB); 01585 arm->getJointState(stC); 01586 01587 stB[2] += increment; 01588 01589 double stAs[7]; 01590 double stBs[7]; 01591 double stCs[7]; 01592 01593 arm->run_ik(stamped_pose,stA,stAs,wrist_frame); 01594 arm->run_ik(stamped_pose,stB,stBs,wrist_frame); 01595 01596 double newinc = (jErr[1] / (stBs[1] - stAs[1])) * increment; 01597 01598 stC[2] += newinc; 01599 01600 arm->run_ik(stamped_pose,stC,stCs,wrist_frame); 01601 01602 ROS_INFO("curr (sta[1]) %f stCs %f", stA[1], stCs[1]); 01603 01604 double pose[7]; 01605 double sum = 0; 01606 for (int k = 0; k < 7; ++k) 01607 { 01608 pose[k] = stCs[k]; 01609 sum += stCs[k] * stCs[k]; 01610 } 01611 01612 if (sum > 0.01) 01613 arm->startTrajectory(arm->goalTraj(pose)); 01614 01615 if (stBs[2]==0) 01616 { 01617 increment = -increment; 01618 ROS_INFO("HIT LIMIT?"); 01619 } 01620 } 01621 else 01622 { 01623 break; 01624 } 01625 } 01626 } 01627 01628 void RobotArm::moveBothArms(tf::Stamped<tf::Pose> leftArm, tf::Stamped<tf::Pose> rightArm, double tolerance, bool wait) 01629 { 01630 std::vector<int> arm; 01631 std::vector<tf::Stamped<tf::Pose> > goal; 01632 tf::Stamped<tf::Pose> result; 01633 01634 arm.push_back(1); 01635 goal.push_back(leftArm); 01636 arm.push_back(0); 01637 goal.push_back(rightArm); 01638 01639 RobotArm::findBaseMovement(result, arm, goal,true, false); 01640 01641 if (!wait) 01642 { 01643 RobotArm::getInstance(0)->evil_switch = true; 01644 RobotArm::getInstance(1)->evil_switch = true; 01645 } 01646 01647 if (tolerance == 0) 01648 { 01649 boost::thread t1(&RobotArm::universal_move_toolframe_ik_pose,RobotArm::getInstance(0),rightArm); 01650 boost::thread t2(&RobotArm::universal_move_toolframe_ik_pose,RobotArm::getInstance(1),leftArm); 01651 t2.join(); 01652 t1.join(); 01653 } 01654 else 01655 { 01656 boost::thread t1(&RobotArm::universal_move_toolframe_ik_pose_tolerance,RobotArm::getInstance(0),rightArm,tolerance,5); 01657 boost::thread t2(&RobotArm::universal_move_toolframe_ik_pose_tolerance,RobotArm::getInstance(1),leftArm,tolerance,5); 01658 t2.join(); 01659 t1.join(); 01660 } 01661 01662 if (!wait) 01663 { 01664 RobotArm::getInstance(0)->evil_switch = false; 01665 RobotArm::getInstance(1)->evil_switch = false; 01666 } 01667 01668 } 01669 01670 01671 bool RobotArm::pose2Joint(const std::vector<tf::Stamped<tf::Pose> > &poses, std::vector<std::vector<double> > &joints) 01672 { 01673 01674 joints.resize(poses.size()); 01675 01676 double current_state[7]; 01677 getJointState(current_state); 01678 01679 for (size_t k = 0; k < poses.size(); ++k) 01680 { 01681 01682 printPose(poses[k]); 01683 double solution[7]; 01684 bool found = run_ik(poses[k], current_state,solution, tool_frame); 01685 if (!found) { 01686 ROS_ERROR("Not all poses of trajectory found %zu of %i", k, poses.size()); 01687 return false; 01688 } 01689 joints[k] = std::vector<double>(); 01690 joints[k].resize(7); 01691 for (size_t j = 0; j < 7; j++) { 01692 joints[k][j] = solution[j]; 01693 //printf("%f\n", joints[k][j] ); 01694 } 01695 } 01696 return true; 01697 } 01698 01699 bool RobotArm::executeViaJointControl(const std::vector<tf::Stamped<tf::Pose> > &poses, int start, int end) 01700 { 01701 std::vector<std::vector<double> > joint_angles; 01702 if (start < 0) 01703 start = 0; 01704 if (end < 0) 01705 end = poses.size() - 1; 01706 joint_angles.resize(end - start); 01707 int direction = (end > start) ? +1 : -1; 01708 joint_angles.resize(std::max(start,end)); 01709 01710 double current_state[7]; 01711 getJointState(current_state); 01712 01713 for (int k = start; k != end + direction; k += direction) 01714 { 01715 double solution[7]; 01716 bool found = run_ik(poses[k], current_state,solution, tool_frame); 01717 if (!found) 01718 return false; 01719 joint_angles[k].resize(7); 01720 for (size_t j = 0; j < 7; j++) 01721 joint_angles[k][j] = solution[j]; 01722 } 01723 01724 return true; 01725 }