unlatching.cpp
Go to the documentation of this file.
00001 #include "unlatching.h"
00002 // arm movement
00003 #include <ee_cart_imped_action/ee_cart_imped_arm.hh>
00004 #include <cmath>  //for fabs
00005 #include "switch_controller.h"
00006 
00007 
00008 DoorOpener::DoorOpener(unsigned char side): 
00009     serviceServer(n.advertiseService("unlatch_door", &DoorOpener::listen, this)),
00010     pregrasp_sub(n, "pregrasp", 5),
00011     grasp_sub(n, "grasp", 5),
00012     postgrasp_sub(n, "postgrasp", 5),
00013     sync(MySyncPolicy(10),  pregrasp_sub, grasp_sub, postgrasp_sub),
00014     side_(side),
00015     tool_frame_name_("/r_gripper_tool_frame"),
00016     fixed_frame_name_("/torso_lift_link"),
00017     listening_(false),
00018     started_(false)
00019 {
00020   cmd_vel_pub_= n.advertise<geometry_msgs::Twist>("/base_controller/command", 12);
00021   base_cmd.linear.x = base_cmd.linear.y = base_cmd.angular.z = 0;   
00022 
00023   tflistener_ = new tf::TransformListener; 
00024   
00025   std::string gac_name("/r_gripper_controller/gripper_action");
00026   if(side_ == 'l') gac_name[1] = side_;
00027   gripperClient = new gripActClient(gac_name.c_str(), true); 
00028 
00029   //EE-Cart-Imped Controller Interface for the desired arm
00030   std::string contr_name("/r_arm_cart_imped_controller");
00031   if(side_ == 'l') contr_name[1] = side_;
00032   std::cout << contr_name;
00033   arm_ = new EECartImpedArm(contr_name.c_str());
00034 
00035   if(side_ == 'l') tool_frame_name_[1] = side_;
00036 
00037 }
00038 
00039 bool DoorOpener::listen(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
00040 {
00041   started_ = true;
00042   if(!listening_){
00043     success_ = false;
00044     listening_ = true;
00045     sync.registerCallback(boost::bind(&DoorOpener::grasp_handle, this, _1, _2, _3));
00046   }
00047   ROS_INFO("Waiting for unlatching to finish");
00048   while(ros::ok() && started_){
00049     ros::Duration(0.5).sleep();
00050     ROS_INFO_THROTTLE(30,"Still waiting for unlatching to finish");
00051   }
00052   return true;
00053 }
00054 
00055 DoorOpener::~DoorOpener(){
00056   delete gripperClient;
00057   delete arm_;
00058   delete tflistener_; 
00059 }
00060 
00061 void DoorOpener::use_gripper(float position, float effort) // Do not limit effort with negative value
00062 {
00063     while(!gripperClient->waitForServer(ros::Duration(5.0)) && ros::ok())
00064         ROS_INFO("Should use gripper, but I am waiting for the gripper action server to come up");
00065 
00066     pr2_controllers_msgs::Pr2GripperCommandGoal goal;
00067     goal.command.position = position;
00068     goal.command.max_effort = effort;  
00069 
00070     gripperClient->sendGoal(goal);
00071 }
00072 bool DoorOpener::wait_for_gripper(){ // Do not limit effort with negative value
00073     gripperClient->waitForResult();
00074 
00075     if(gripperClient->getState() == actionlib::SimpleClientGoalState::SUCCEEDED){
00076         ROS_INFO("Successfully used gripper!");
00077         return true;
00078     } else {
00079         ROS_WARN("Failed to bring gripper to desired state"); 
00080         return false;
00081     }
00082 }
00083 
00084 /*
00087 bool DoorOpener::use_gripper(float position, float effort) 
00088 {
00089     //wait for the gripper action server to come up
00090     while(!gripperClient->waitForServer(ros::Duration(5.0)) && ros::ok()){
00091       ROS_INFO("Should use gripper, but I am waiting for the gripper action server to come up");
00092     } 
00093     pr2_controllers_msgs::Pr2GripperCommandGoal goal;
00094     goal.command.position = position;
00095     goal.command.max_effort = effort;  
00096 
00097     gripperClient->sendGoal(goal);
00098     gripperClient->waitForResult();
00099 
00100     if(gripperClient->getState() == actionlib::SimpleClientGoalState::SUCCEEDED){
00101         ROS_INFO("Successfully used gripper!");
00102         return true;
00103     } else {
00104         ROS_ERROR("Failed to bring gripper to position %f with effort %f!", position, effort); 
00105         return false;
00106     }
00107 }
00108 */
00109 
00110 void DoorOpener::drive_base(const ros::TimerEvent& event)
00111 {
00112     if(base_cmd.linear.x == 0 && base_cmd.linear.y == 0 && base_cmd.angular.z == 0) return;
00113     //ROS_INFO("publishing base_cmd (x=%f, y=%f, z=%f)", base_cmd.angular.x, base_cmd.angular.y , base_cmd.angular.z  );
00114     cmd_vel_pub_.publish(base_cmd);
00115 }
00116 
00117 
00118 void DoorOpener::push_door()
00119 {
00120     float base_speed = -0.05; //in cm/s
00121 
00122     // tf stuff
00123     tf::Transform gripper_transform, last_gripper_transform,
00124                   init_gripper_global_tf, odom_to_torso_tf ;
00125 
00126     //Get initial gripper position relative to torso
00127     last_gripper_transform = getTransform(fixed_frame_name_, tool_frame_name_);
00128 
00129     //Get initial gripper position relative to odometry
00130     init_gripper_global_tf = getTransform("/odom_combined", tool_frame_name_);
00131 
00132     float px,py = 0.0,pz,rx,ry,rz,rw;
00133     px = last_gripper_transform.getOrigin().getX(); //try to keep forward distance
00134 
00135     while(fabs(py) < 0.45){
00136         //wait for transformation of gripper
00137         gripper_transform = getTransform(fixed_frame_name_, tool_frame_name_);
00138         odom_to_torso_tf = getTransform("/odom_combined",fixed_frame_name_);
00139         tf::Transform first_gripper_pose = odom_to_torso_tf.inverseTimes(init_gripper_global_tf); // initial global gripper pose relative to current torso pose
00140         tf::Transform delta = first_gripper_pose.inverseTimes(gripper_transform);
00141         printTransform(first_gripper_pose, "gripper init pose in torso frame");
00142         printTransform(delta, "global delta in torso_lift");
00143 
00144         //Adapt position to passive motion
00145         py = gripper_transform.getOrigin().getY();
00146         pz = gripper_transform.getOrigin().getZ();
00147         rx = gripper_transform.getRotation().getX();
00148         ry = gripper_transform.getRotation().getY();
00149         rz = gripper_transform.getRotation().getZ();
00150         rw = gripper_transform.getRotation().getW();
00151 
00152         //try to go linearly further in the current direction 
00153         tf::Transform gripper_delta_tf = last_gripper_transform.inverseTimes(gripper_transform); 
00154         printTransform(gripper_delta_tf, "Linear Delta");
00155         py += gripper_delta_tf.getOrigin().getY()*23;
00156         if(gripper_delta_tf.getOrigin().getX() < 0.0001) ROS_WARN("Door not moving further");
00157         //no change in height desired: pz += gripper_delta_tf.getOrigin().getZ();
00158 
00159         ee_cart_imped_msgs::EECartImpedGoal pushDoor;//,traj_l;
00160         EECartImpedArm::addTrajectoryPoint(pushDoor, px,py,pz, rx, ry, rz, rw,
00161                                            1000, 550, 1000, //stiff forward and downward, loose to the sides. Rotatio
00162                                            30, 30, 1, //loose around vertical
00163                                            false, true, false, false, false,false,//stiff (not torqe)
00164                                            0.50,fixed_frame_name_);//cumulative time
00165         //Start Driving
00166         base_cmd.linear.x = base_speed;
00167         //Start Pushing
00168         arm_->startTrajectory(pushDoor);
00169         last_gripper_transform = gripper_transform;
00170         py = gripper_transform.getOrigin().getY();
00171     }                                        
00172     base_cmd.linear.x = 0.0;
00173     /* not used anyway
00174     ee_cart_imped_msgs::EECartImpedGoal pushDoor;//,traj_l;
00175     EECartImpedArm::addTrajectoryPoint(pushDoor, px,py,pz, rx, ry, rz, rw,
00176                                        100, 1000, 100, 30, 30, 30, //torques
00177                                        false, false, false, false, false,false,//stiff (not torqe)
00178                                        0.50,fixed_frame_name_);//cumulative time
00179                                        */
00180     ROS_INFO("Gripper is outside of robot footprint" );
00181 }
00182 
00183 
00184 void DoorOpener::home_position()
00185 {
00186     ee_cart_imped_msgs::EECartImpedGoal homePos;//,traj_l;
00187 
00188     tf::Quaternion r(tf::Vector3(1,0,0), -M_PI/2.0);//gripper rotation
00189     float y = side_ == 'l'? 0.2 : -0.4;
00190     EECartImpedArm::addTrajectoryPoint(homePos, 0.35, y,-0.10, r.getX(), r.getY(), r.getZ(), r.getW(),
00191                                        100, 1000, 100, 3, 3, 3, //torques
00192                                        false, false, false, false, false,false,//stiff (not torqe)
00193                                        2,fixed_frame_name_);//cumulative time
00194     arm_->startTrajectory(homePos);
00195 }
00196 
00197 
00198 void DoorOpener::withdraw(float meters)
00199 {
00200     tf::StampedTransform gripper_transform(getTransform(fixed_frame_name_, tool_frame_name_));
00201     tf::Vector3 gripperBackward(-meters, 0,0); 
00202     gripperBackward = gripper_transform * gripperBackward;
00203 
00204     float px,py,pz,rx,ry,rz,rw;
00205     px = gripperBackward.getX();
00206     py = gripperBackward.getY();
00207     pz = gripperBackward.getZ();
00208 
00209     rx = gripper_transform.getRotation().getX();
00210     ry = gripper_transform.getRotation().getY();
00211     rz = gripper_transform.getRotation().getZ();
00212     rw = gripper_transform.getRotation().getW();
00213 
00214     ee_cart_imped_msgs::EECartImpedGoal withdrawTraj;//,traj_l;
00215     EECartImpedArm::addTrajectoryPoint(withdrawTraj, px,py,pz, rx, ry, rz, rw,
00216                                        1000, 1000, 1000, 1, 1, 1, //torques
00217                                        false, false, false, false, false,false,//stiff (not torqe)
00218                                        1.5,fixed_frame_name_);//cumulative time
00219     arm_->startTrajectory(withdrawTraj);
00220 }
00221 
00222 
00223 void DoorOpener::grasp_handle(const geometry_msgs::PoseStamped::ConstPtr a_pregrasp,
00224                               const geometry_msgs::PoseStamped::ConstPtr a_grasp,
00225                               const geometry_msgs::PoseStamped::ConstPtr a_postgrasp)
00226 {
00227     if(!started_) return;
00228     ROS_INFO("Got grasping poses");
00229     geometry_msgs::Pose postgrasp = (*a_postgrasp).pose;
00230     geometry_msgs::Pose pregrasp  = (*a_pregrasp).pose;
00231     geometry_msgs::Pose grasp     = (*a_grasp).pose;
00232 
00233     std::string desired_controller("x_arm_cart_imped_controller");
00234     desired_controller[0] = side_;
00235     std::string undesired_controller("x_arm_controller");
00236     undesired_controller[0] = side_;
00237     ROS_WARN_COND(!load_controller(desired_controller), "Could not load %s, May already be loaded.", desired_controller.c_str());
00238     int failure_count = 0;
00239     while(!switch_controller(desired_controller, undesired_controller))
00240     {
00241       failure_count++;
00242       if(failure_count > 10){
00243         success_ = false;
00244         return;
00245       }
00246 
00247       ROS_ERROR("Could not switch to %s. Waiting 2 sec before retrying. (%d/10 times)", desired_controller.c_str(), failure_count);
00248       ros::Duration(2).sleep();
00249       if(!load_controller(desired_controller)){
00250         ROS_DEBUG("Could not (re-)load %s, May already be loaded.", desired_controller.c_str());
00251       }
00252 
00253     }
00254 
00255     ee_cart_imped_msgs::EECartImpedGoal toPregrasp, toGrasp, toPostgrasp, backToGrasp;//,traj_l;
00256 
00257     ROS_INFO("opening right gripper");
00258     use_gripper(0.08, -1.0 );
00259     // go to pregrasp
00260     EECartImpedArm::addTrajectoryPoint(toPregrasp, pregrasp.position.x,pregrasp.position.y,pregrasp.position.z,
00261                                        pregrasp.orientation.x, pregrasp.orientation.y, pregrasp.orientation.z, pregrasp.orientation.w,
00262                                        1000, 1000, 1000,//forces
00263                                        30, 30, 30, //torques
00264                                        false, false, false,//stiff (not force)
00265                                        false, false,false,//stiff (not torqe)
00266                                        4,fixed_frame_name_); //cumulative time
00267     {
00268       EECartImpedClient* traj_client = arm_->startTrajectory(toPregrasp);
00269       actionlib::SimpleClientGoalState state = traj_client->getState();
00270       if (state != actionlib::SimpleClientGoalState::SUCCEEDED)
00271         return;
00272     }
00273     if( !wait_for_gripper()) return;
00274     // go to grasp position
00275     EECartImpedArm::addTrajectoryPoint(toGrasp, grasp.position.x,grasp.position.y,grasp.position.z,
00276                                        grasp.orientation.x, grasp.orientation.y, grasp.orientation.z, grasp.orientation.w,
00277                                        1000, 1000, 1000,//forces
00278                                        30, 30, 30, //torques
00279                                        false, false, false,//stiff (not force)
00280                                        false, false,false,//stiff (not torqe)
00281                                        1,fixed_frame_name_);//cumulative time
00282     {
00283       EECartImpedClient* traj_client = arm_->startTrajectory(toGrasp);
00284       actionlib::SimpleClientGoalState state = traj_client->getState();
00285       if (state != actionlib::SimpleClientGoalState::SUCCEEDED)
00286         return;
00287     }
00288 
00289     ROS_INFO("closing right gripper");
00290     use_gripper(0.005, 50.0 );
00291     if(wait_for_gripper()){
00292       ROS_WARN("Closed completely. Missed handle?");//needs to be closed
00293     }
00294     // go to postgrasp position
00295     EECartImpedArm::addTrajectoryPoint(toPostgrasp, postgrasp.position.x,postgrasp.position.y,postgrasp.position.z,
00296                                        postgrasp.orientation.x, postgrasp.orientation.y, postgrasp.orientation.z, postgrasp.orientation.w,
00297                                        500, 100, 100,//force: down and forward
00298                                        70, 70, 70, //torques: Be wobbly around vertical axis
00299                                        false, false, false,//stiff (not force)
00300                                        false, false,false,//stiff (not torqe)
00301                                        2,fixed_frame_name_);//cumulative time
00302     {
00303       EECartImpedClient* traj_client = arm_->startTrajectory(toPostgrasp);
00304       actionlib::SimpleClientGoalState state = traj_client->getState();
00305       if (state == actionlib::SimpleClientGoalState::SUCCEEDED)
00306         success_ = true;
00307     }
00308     use_gripper(0.08, -1 );
00309     // go back to grasp position
00310     EECartImpedArm::addTrajectoryPoint(backToGrasp, grasp.position.x,grasp.position.y,grasp.position.z,
00311                                        grasp.orientation.x, grasp.orientation.y, grasp.orientation.z, grasp.orientation.w,
00312                                        500, 500, 500,//forces
00313                                        20, 20, 20, //torques
00314                                        false, false, false,//stiff (not force)
00315                                        false, false,false,//stiff (not torqe)
00316                                        2,fixed_frame_name_);//cumulative time
00317 /*
00318     EECartImpedArm::addTrajectoryPoint(backToGrasp, pregrasp.position.x,pregrasp.position.y,pregrasp.position.z,
00319                                        pregrasp.orientation.x, pregrasp.orientation.y, pregrasp.orientation.z, pregrasp.orientation.w,
00320                                        1000, 1000, 1000,//forces
00321                                        30, 30, 30, //torques
00322                                        false, false, false,//stiff (not force)
00323                                        false, false,false,//stiff (not torqe)
00324                                        4,fixed_frame_name_); //cumulative time
00325                                        */
00326     {
00327       EECartImpedClient* traj_client = arm_->startTrajectory(backToGrasp);
00328       actionlib::SimpleClientGoalState state = traj_client->getState();
00329     }
00330     wait_for_gripper();//needs to be open to withdraw
00331 
00332     //withdraw(-.04);//go forward
00333     //push_door();
00334     //withdraw(.0);//20 cm
00335     //home_position();
00336     //go to middle of robot FIXME: Assuming torso frame
00337     swing_door(*a_grasp);
00338     started_ = false;
00339 }
00340 
00341 tf::StampedTransform DoorOpener::getTransform(const std::string& from, const std::string& to){
00342     tf::StampedTransform transform;
00343     ros::Time now = ros::Time::now();
00344     while(!tflistener_->waitForTransform(from, to,now, ros::Duration(6.0/30.0))){
00345       ROS_WARN_STREAM("No tranform from "<<from<<" to "<<to<<" available, when getting initial gripper position");
00346     }
00347     tflistener_->lookupTransform(from, to, now, transform);
00348     return transform;
00349 }
00350 
00351 void DoorOpener::addTrajectoryPoint(ee_cart_imped_msgs::EECartImpedGoal& msg, tf::Transform pose, float fx, float fy, float fz, float tx, float ty, float tz, float time, std::string frame_id)
00352 {
00353     EECartImpedArm::addTrajectoryPoint(msg, 
00354                                        pose.getOrigin().getX(), pose.getOrigin().getY(), pose.getOrigin().getZ(), 
00355                                        pose.getRotation().getX(), pose.getRotation().getY(), pose.getRotation().getZ(), pose.getRotation().getW(), 
00356                                        fx, fy, fz,//forces
00357                                        tx, ty, tz, //torques
00358                                        false, false, false,//stiff (not force)
00359                                        false, false,false,//stiff (not torqe)
00360                                        time, frame_id);//cumulative time
00361 
00362 }
00363 
00364 bool DoorOpener::swing_door(geometry_msgs::PoseStamped start_pose)
00365 {
00366     tf::Stamped<tf::Transform> tf_start_pose_stamped;
00367     tf::Transform tf_start_pose;
00368     tf::poseStampedMsgToTF(start_pose, tf_start_pose_stamped);
00369     tf::Transform tf_centerwards(tf::Quaternion(0,0,0,1), tf::Vector3(0,0,0.20));
00370     tf_start_pose = tf_start_pose_stamped * tf_centerwards;
00371     tf::Transform tf_forward(tf::Quaternion(0,0,0,1), tf::Vector3(0.1,0,0));
00372     tf::Transform tf_touch_pose = tf_start_pose * tf_forward;
00373     tf::Transform tf_fast_forward(tf::Quaternion(0,0,0,1), tf::Vector3(0.24,0,0));
00374     tf::Transform tf_swing_pose = tf_start_pose * tf_fast_forward;
00375     
00376     ee_cart_imped_msgs::EECartImpedGoal door;
00377 
00378     // go to pretouch
00379     tf::Quaternion r(tf::Vector3(0,1,0), -M_PI/2.0);//gripper rotation
00380     addTrajectoryPoint(door, tf_start_pose, 1000, 1000, 1000, 30, 30, 30, 2, start_pose.header.frame_id);
00381     addTrajectoryPoint(door, tf_touch_pose,  100,  100,  100, 30, 30, 30, 6, start_pose.header.frame_id);
00382     addTrajectoryPoint(door, tf_swing_pose, 1000, 1000, 1000, 30, 30, 30, 7, start_pose.header.frame_id);
00383     addTrajectoryPoint(door, tf_start_pose, 1000, 1000, 1000, 30, 30, 30, 10, start_pose.header.frame_id);
00384 
00385 
00386     EECartImpedClient* traj_client = arm_->startTrajectory(door);
00387     actionlib::SimpleClientGoalState state = traj_client->getState();
00388     return true;
00389 }
00390 void printTransform(const tf::Transform& t, const std::string& name){
00391     float px = t.getOrigin().getX();
00392     float py = t.getOrigin().getY();
00393     float pz = t.getOrigin().getZ();
00394     float rx = t.getRotation().getX();
00395     float ry = t.getRotation().getY();
00396     float rz = t.getRotation().getZ();
00397     float rw = t.getRotation().getW();
00398     ROS_INFO_STREAM("Transformation "<<name<<": ("<<px<<", "<<py<<", "<<pz<<") ["<<rx<<", "<<ry<<", "<<rz<<", "<<rw<<"]");
00399 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


door_manipulation_tools
Author(s): Felix Endres
autogenerated on Wed Dec 26 2012 16:02:19