00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <ias_drawer_executive/RobotArm.h>
00031 #include <ias_drawer_executive/Pressure.h>
00032 #include <ias_drawer_executive/Geometry.h>
00033
00034
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
00052
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();
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
00091 traj_client_ = new TrajClient((side == 0) ? "r_arm_controller/joint_trajectory_action" : "l_arm_controller/joint_trajectory_action", true);
00092
00093 traj_client_->waitForServer(ros::Duration(1));
00094
00095
00096
00097
00098 ac_ = new actionlib::SimpleActionClient<pr2_common_action_msgs::ArmMoveIKAction>((side == 0) ? "r_arm_ik" : "l_arm_ik", true);
00099
00100
00101
00102 ac_->waitForServer(ros::Duration(1));
00103
00104
00105
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
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));
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;
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
00202
00203
00204
00205
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
00215 double padding = 0.05;
00216 double x = pose.pose.position.x;
00217 double y = pose.pose.position.y;
00218
00219 if ((x < .325 + padding) && (x > -.325 - padding) && (y < .325 + padding) && (y > -.325 - padding))
00220 {
00221
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
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
00298
00299 return true;
00300 }
00301
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
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
00324 goal.trajectory.header.stamp = ros::Time::now();
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
00344
00345
00346
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
00366
00367
00368 pr2_controllers_msgs::JointTrajectoryGoal goal;
00369
00370
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
00393 goal.trajectory.points.resize(1);
00394
00395
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
00405 goal.trajectory.points[ind].time_from_start = ros::Duration(dur);
00406
00407
00408 return goal;
00409 }
00410
00411 pr2_controllers_msgs::JointTrajectoryGoal RobotArm::goalTraj(double *poseA, double *vel)
00412 {
00413
00414
00415
00416
00417 pr2_controllers_msgs::JointTrajectoryGoal goal;
00418
00419
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
00442 goal.trajectory.points.resize(1);
00443
00444
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
00455 goal.trajectory.points[ind].time_from_start = ros::Duration(0.25);
00456
00457
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
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
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
00510 goal.trajectory.points[ind].time_from_start = ros::Duration((ind * duration) / ((double) poses.size()));
00511 }
00512
00513
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
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
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
00565 goal.trajectory.points[ind].time_from_start = ros::Duration(duration[ind]);
00566 }
00567
00568
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
00586
00587 pr2_controllers_msgs::JointTrajectoryGoal goal;
00588
00589
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
00612 goal.trajectory.points.resize(2);
00613
00614
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
00625 goal.trajectory.points[ind].time_from_start = ros::Duration(2.0);
00626
00627
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
00638 goal.trajectory.points[ind].time_from_start = ros::Duration(4.0);
00639
00640
00641 return goal;
00642 }
00643
00644
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
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
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
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
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
00761
00762
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
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
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
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
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;
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;
00851 double lasteffect = 0;
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));
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
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
00937
00938
00939
00940
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
00983 good = true;
00984 for (int i=0; i<7; ++i)
00985 {
00986
00987 if (jointState[i] == 0.0f)
00988 good = false;
00989 }
00990
00991 mutex_.unlock();
00992 ros::spinOnce();
00993 rate.sleep();
00994 }
00995
00996 mutex_.lock();
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
01004
01005
01006 }
01007
01008
01009 mutex_.unlock();
01010
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
01041
01042
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
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
01084
01085 ros::NodeHandle node_handle;
01086
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;
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
01132 }
01133
01134
01135
01136 ROS_INFO("Waiting for action server to start.");
01137
01138
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
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
01186
01187 if (drive && ((fabs(ps[0]) > 0.001) || (fabs(ps[1]) > 0.001) || (fabs(ps[2]) > 0.001)))
01188 {
01189
01190 boost::thread t2(&RobotDriver::driveInOdom,driver,ps,true);
01191
01192 ros::Rate rate(25.0);
01193 while (!t2.timed_join(boost::posix_time::seconds(0.01)))
01194 {
01195
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
01201 rate.sleep();
01202 }
01203 t2.join();
01204
01205 }
01206
01207
01208 result = respose;
01209 return true;
01210
01211
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
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
01260 tf::Stamped<tf::Pose> toolTargetPoseInMap = Geometry::getPoseIn("map",toolTargetPose);
01261 goal.push_back(toolTargetPoseInMap);
01262
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
01272
01273
01274 tf::Stamped<tf::Pose> wristTargetBase = tool2wrist(toolTargetPoseInBase);
01275
01276
01277
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
01304
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
01325
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
01336 if ((x < .325 + padding) && (x > -.325 - padding) && (y < .325 + padding) && (y > -.325 - padding))
01337 poseInsideFootprint = true;
01338 }
01339
01340
01341
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
01368 tf::Stamped<tf::Pose> toolTargetPoseInMap = Geometry::getPoseIn("map",toolTargetPose);
01369 goal.push_back(toolTargetPoseInMap);
01370
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
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
01421
01422
01423
01424 }
01425 else
01426 {
01427 ROS_ERROR("Could not call query service");
01428
01429
01430 return res;
01431 }
01432
01433 kinematics_msgs::GetPositionFK::Request fk_request;
01434 kinematics_msgs::GetPositionFK::Response fk_response;
01435
01436
01437 fk_request.header.frame_id = "base_link";
01438 fk_request.fk_link_names.resize(2);
01439
01440
01441
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
01446
01447
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
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
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
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
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
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
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
01573
01574
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
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 }