common_actions.cpp
Go to the documentation of this file.
00001 #include <carl_moveit/common_actions.h>
00002 
00003 using namespace std;
00004 
00005 CommonActions::CommonActions() :
00006     moveToJointPoseClient("carl_moveit_wrapper/move_to_joint_pose"),
00007     moveToPoseClient("carl_moveit_wrapper/move_to_pose"),
00008     gripperClient("jaco_arm/manipulation/gripper"),
00009     liftClient("carl_moveit_wrapper/common_actions/lift"),
00010     liftServer(n, "carl_moveit_wrapper/common_actions/lift", boost::bind(&CommonActions::liftArm, this, _1), false),
00011     armServer(n, "carl_moveit_wrapper/common_actions/arm_action", boost::bind(&CommonActions::executeArmAction, this, _1), false),
00012     pickupServer(n, "carl_moveit_wrapper/common_actions/pickup", boost::bind(&CommonActions::executePickup, this, _1), false),
00013     storeServer(n, "carl_moveit_wrapper/common_actions/store", boost::bind(&CommonActions::executeStore, this, _1), false),
00014     wipeSurfaceServer(n, "carl_moveit_wrapper/common_actions/wipe_surface", boost::bind(&CommonActions::executeWipeSurface, this, _1), false)
00015 {
00016   //setup home position
00017   homePosition.resize(NUM_JACO_JOINTS);
00018   homePosition[0] = -1.410;
00019   homePosition[1] = 2.975;
00020   homePosition[2] = .868;
00021   homePosition[3] = -2.323;
00022   homePosition[4] = 1.626;
00023   homePosition[5] = 1.393;
00024 
00025   defaultRetractPosition.resize(NUM_JACO_JOINTS);
00026   defaultRetractPosition[0] = -2.57;
00027   defaultRetractPosition[1] = 1.39;
00028   defaultRetractPosition[2] = .527;
00029   defaultRetractPosition[3] = -.084;
00030   defaultRetractPosition[4] = .515;
00031   defaultRetractPosition[5] = -1.745;
00032 
00033   angularCmdPublisher = n.advertise<wpi_jaco_msgs::AngularCommand>("jaco_arm/angular_cmd", 1);
00034 
00035   eraseTrajectoriesClient = n.serviceClient<std_srvs::Empty>("jaco_arm/erase_trajectories");
00036   cartesianPathClient = n.serviceClient<rail_manipulation_msgs::CartesianPath>("carl_moveit_wrapper/cartesian_path");
00037   jacoPosClient = n.serviceClient<wpi_jaco_msgs::GetAngularPosition>("jaco_arm/get_angular_position");
00038   attachClosestObjectClient = n.serviceClient<std_srvs::Empty>("carl_moveit_wrapper/attach_closest_object");
00039   detachObjectsClient = n.serviceClient<std_srvs::Empty>("carl_moveit_wrapper/detach_objects");
00040 
00041   //start action server
00042   liftServer.start();
00043   armServer.start();
00044   pickupServer.start();
00045   storeServer.start();
00046   wipeSurfaceServer.start();
00047 }
00048 
00049 void CommonActions::executePickup(const rail_manipulation_msgs::PickupGoalConstPtr &goal)
00050 {
00051   rail_manipulation_msgs::PickupFeedback feedback;
00052   rail_manipulation_msgs::PickupResult result;
00053   stringstream ss;
00054 
00055   //make sure pose is in the base_footprint frame
00056   geometry_msgs::PoseStamped graspPose, approachAnglePose;
00057   graspPose.header.frame_id = "base_footprint";
00058   if (goal->pose.header.frame_id != "base_footprint")
00059     tfListener.transformPose("base_footprint", goal->pose, graspPose);
00060   else
00061     graspPose = goal->pose;
00062 
00063   tf::Transform graspTransform;
00064   graspTransform.setOrigin(tf::Vector3(graspPose.pose.position.x, graspPose.pose.position.y, graspPose.pose.position.z));
00065   graspTransform.setRotation(tf::Quaternion(graspPose.pose.orientation.x, graspPose.pose.orientation.y, graspPose.pose.orientation.z, graspPose.pose.orientation.w));
00066   ros::Time now = ros::Time::now();
00067   tfBroadcaster.sendTransform(tf::StampedTransform(graspTransform, now, "base_footprint", "grasp_frame"));
00068   tfListener.waitForTransform("grasp_frame", "base_footprint", now, ros::Duration(5.0));
00069 
00070   approachAnglePose.header.frame_id = "grasp_frame";
00071   approachAnglePose.pose.position.x = -0.1;
00072   approachAnglePose.pose.orientation.w = 1.0;
00073 
00074   //move to approach angle
00075   ss.str("");
00076   ss << "Attempting to move gripper to approach angle...";
00077   feedback.message = ss.str();
00078   pickupServer.publishFeedback(feedback);
00079 
00080   rail_manipulation_msgs::MoveToPoseGoal approachAngleGoal;
00081   approachAngleGoal.pose = approachAnglePose;
00082   moveToPoseClient.sendGoal(approachAngleGoal);
00083   moveToPoseClient.waitForResult(ros::Duration(30.0));
00084   if (!moveToPoseClient.getResult()->success)
00085   {
00086     ss.str("");
00087     ss << "Moving to approach angle failed for this grasp.";
00088     feedback.message = ss.str();
00089     pickupServer.publishFeedback(feedback);
00090     result.success = false;
00091     pickupServer.setAborted(result, "Unable to move to appraoch angle.");
00092     return;
00093   }
00094 
00095   //open gripper
00096   ss.str("");
00097   ss << "Opening gripper...";
00098   feedback.message = ss.str();
00099   pickupServer.publishFeedback(feedback);
00100 
00101   rail_manipulation_msgs::GripperGoal gripperGoal;
00102   gripperGoal.close = false;
00103   gripperClient.sendGoal(gripperGoal);
00104   gripperClient.waitForResult(ros::Duration(10.0));
00105   if (!gripperClient.getResult()->success)
00106   {
00107     ROS_INFO("Opening gripper failed.");
00108     result.success = false;
00109     pickupServer.setAborted(result, "Unable to open gripper.");
00110     return;
00111   }
00112 
00113   //follow approach angle to grasp
00114   ss.str("");
00115   ss << "Moving along approach angle...";
00116   feedback.message = ss.str();
00117   pickupServer.publishFeedback(feedback);
00118 
00119   rail_manipulation_msgs::CartesianPath srv;
00120   geometry_msgs::PoseStamped cartesianPose;
00121   cartesianPose.header.frame_id = "base_footprint";
00122   tfListener.transformPose("base_footprint", graspPose, cartesianPose);
00123   srv.request.waypoints.push_back(cartesianPose);
00124   srv.request.avoidCollisions = false;
00125   if (!cartesianPathClient.call(srv))
00126   {
00127     ROS_INFO("Could not call Jaco Cartesian path service.");
00128     result.success = false;
00129     pickupServer.setAborted(result, "Could not call Jaco Cartesian path service.");
00130     return;
00131   }
00132 
00133   //close gripper
00134   ss.str("");
00135   ss << "Closing gripper...";
00136   feedback.message = ss.str();
00137   pickupServer.publishFeedback(feedback);
00138 
00139   gripperGoal.close = true;
00140   gripperClient.sendGoal(gripperGoal);
00141   gripperClient.waitForResult(ros::Duration(10.0));
00142   if (!gripperClient.getResult()->success)
00143   {
00144     ROS_INFO("Closing gripper failed.");
00145     result.success = false;
00146     pickupServer.setAborted(result, "Unable to close gripper.");
00147     return;
00148   }
00149 
00150   //attach scene object to gripper
00151   std_srvs::Empty emptySrv;
00152   if (!attachClosestObjectClient.call(emptySrv))
00153   {
00154     ROS_INFO("No scene object to attach...");
00155   }
00156 
00157   if (goal->lift)
00158   {
00159     //lift hand
00160     ss.str("");
00161     ss << "Lifting hand...";
00162     feedback.message = ss.str();
00163     pickupServer.publishFeedback(feedback);
00164 
00165     rail_manipulation_msgs::LiftGoal liftGoal;
00166     liftClient.sendGoal(liftGoal);
00167     liftClient.waitForResult(ros::Duration(10.0));
00168   }
00169 
00170   result.success = true;
00171   pickupServer.setSucceeded(result);
00172 }
00173 
00174 void CommonActions::executeStore(const rail_manipulation_msgs::StoreGoalConstPtr &goal)
00175 {
00176   rail_manipulation_msgs::StoreFeedback feedback;
00177   rail_manipulation_msgs::StoreResult result;
00178   stringstream ss;
00179 
00180   //make sure pose is in the base_footprint frame
00181   /*
00182   geometry_msgs::PoseStamped storePose;
00183   storePose.header.frame_id = "base_link";
00184   storePose.pose.position.x = .047;
00185   storePose.pose.position.y = -.191;
00186   storePose.pose.position.z = .831;
00187   storePose.pose.orientation.x = .699;
00188   storePose.pose.orientation.y = -.294;
00189   storePose.pose.orientation.z = -.620;
00190   storePose.pose.orientation.w = -.202;
00191    */
00192 
00193   //move above store position
00194   ss.str("");
00195   ss << "Moving gripper above store position...";
00196   feedback.message = ss.str();
00197   storeServer.publishFeedback(feedback);
00198 
00199   rail_manipulation_msgs::MoveToPoseGoal approachAngleGoal;
00200   approachAngleGoal.pose = goal->store_pose;
00201   approachAngleGoal.pose.pose.position.z += .1;
00202   moveToPoseClient.sendGoal(approachAngleGoal);
00203   moveToPoseClient.waitForResult(ros::Duration(30.0));
00204   if (!moveToPoseClient.getResult()->success)
00205   {
00206     ss.str("");
00207     ss << "Moving gripper above store position failed.";
00208     feedback.message = ss.str();
00209     storeServer.publishFeedback(feedback);
00210     result.success = false;
00211     storeServer.setAborted(result, "Unable to move gripper above store position.");
00212     return;
00213   }
00214 
00215   //lower gripper
00216   ss.str("");
00217   ss << "Lowering gripper...";
00218   feedback.message = ss.str();
00219   storeServer.publishFeedback(feedback);
00220 
00221   rail_manipulation_msgs::CartesianPath srv;
00222   geometry_msgs::PoseStamped cartesianPose;
00223   approachAngleGoal.pose.pose.position.z -= .1;
00224   cartesianPose.header.frame_id = "base_footprint";
00225   tfListener.transformPose("base_footprint", approachAngleGoal.pose, cartesianPose);
00226   srv.request.waypoints.push_back(cartesianPose);
00227   srv.request.avoidCollisions = false;
00228   if (!cartesianPathClient.call(srv))
00229   {
00230     ROS_INFO("Could not call Jaco Cartesian path service.");
00231     result.success = false;
00232     storeServer.setAborted(result, "Could not call Jaco Cartesian path service.");
00233     return;
00234   }
00235 
00236   //open gripper
00237   ss.str("");
00238   ss << "Opening gripper...";
00239   feedback.message = ss.str();
00240   storeServer.publishFeedback(feedback);
00241 
00242   rail_manipulation_msgs::GripperGoal gripperGoal;
00243   gripperGoal.close = false;
00244   gripperClient.sendGoal(gripperGoal);
00245   gripperClient.waitForResult(ros::Duration(10.0));
00246   if (!gripperClient.getResult()->success)
00247   {
00248     ROS_INFO("Opening gripper failed.");
00249     result.success = false;
00250     storeServer.setAborted(result, "Unable to open gripper.");
00251     return;
00252   }
00253 
00254   //detach any attached collision objects
00255   std_srvs::Empty emptySrv;
00256   if (!detachObjectsClient.call(emptySrv))
00257   {
00258     ROS_INFO("Couldn't call detach objects service.");
00259   }
00260 
00261   //raise gripper
00262   ss.str("");
00263   ss << "Raising gripper...";
00264   feedback.message = ss.str();
00265   storeServer.publishFeedback(feedback);
00266 
00267   cartesianPose.pose.position.z += .05;
00268   srv.request.waypoints.clear();
00269   srv.request.waypoints.push_back(cartesianPose);
00270   srv.request.avoidCollisions = false;
00271   if (!cartesianPathClient.call(srv))
00272   {
00273     ROS_INFO("Could not call Jaco Cartesian path service.");
00274     result.success = false;
00275     storeServer.setAborted(result, "Could not call Jaco Cartesian path service.");
00276     return;
00277   }
00278 
00279   result.success = true;
00280   storeServer.setSucceeded(result);
00281 }
00282 
00283 void CommonActions::executeArmAction(const rail_manipulation_msgs::ArmGoalConstPtr &goal)
00284 {
00285   rail_manipulation_msgs::ArmFeedback feedback;
00286   rail_manipulation_msgs::ArmResult result;
00287 
00288   switch (goal->action) {
00289     case rail_manipulation_msgs::ArmGoal::READY:
00290       feedback.message = "Readying arm...";
00291       armServer.publishFeedback(feedback);
00292     break;
00293     case rail_manipulation_msgs::ArmGoal::RETRACT:
00294       feedback.message = "Retracting arm...";
00295       armServer.publishFeedback(feedback);
00296     break;
00297     default:
00298       feedback.message = "Executing arm action...";
00299       armServer.publishFeedback(feedback);
00300     break;
00301   }
00302 
00303   if (goal->action == rail_manipulation_msgs::ArmGoal::RETRACT)
00304   {
00305     if (isArmRetracted(defaultRetractPosition))
00306     {
00307       feedback.message = "Arm is already retracted.";
00308       armServer.publishFeedback(feedback);
00309 
00310       result.success = true;
00311       armServer.setSucceeded(result);
00312       return;
00313     }
00314   }
00315 
00316   rail_manipulation_msgs::MoveToJointPoseGoal jointPoseGoal;
00317 
00318   vector<float> baseJointPoseGoal;
00319   baseJointPoseGoal.resize(homePosition.size());
00320   for (unsigned int i = 0; i < baseJointPoseGoal.size(); i ++)
00321   {
00322     baseJointPoseGoal[i] = homePosition[i];
00323   }
00324   jointPoseGoal.joints.resize(baseJointPoseGoal.size());
00325   for (unsigned int i = 0; i < jointPoseGoal.joints.size(); i ++)
00326   {
00327     jointPoseGoal.joints[i] = baseJointPoseGoal[i];
00328   }
00329   bool succeeded = false;
00330   int counter = 0;
00331   int attempts = MAX_HOME_ATTEMPTS;
00332   while (!succeeded && counter < attempts)
00333   {
00334     stringstream ss;
00335     ss << "Planning and moving arm to ready position (attempt " << counter + 1 << "/" << attempts << ")";
00336     feedback.message = ss.str();
00337     armServer.publishFeedback(feedback);
00338 
00339     ROS_INFO("Ready arm attempt %d", counter);
00340 
00341     moveToJointPoseClient.sendGoal(jointPoseGoal);
00342     ROS_INFO("Moving arm to ready position...");
00343     while (!moveToJointPoseClient.getState().isDone())
00344     {
00345       if (armServer.isPreemptRequested() || !ros::ok())
00346       {
00347         ROS_INFO("Ready arm action preempted.");
00348         moveToJointPoseClient.cancelAllGoals();
00349         result.success = false;
00350         armServer.setPreempted(result);
00351         return;
00352       }
00353     }
00354 
00355     rail_manipulation_msgs::MoveToJointPoseResultConstPtr readyResult = moveToJointPoseClient.getResult();
00356 
00357     succeeded = readyResult->success;
00358     counter ++;
00359 
00360     //slightly vary joint goal and retry planning
00361     if (!succeeded && counter < attempts)
00362     {
00363       ROS_INFO("Ready arm failed, resampling goal for another attempt...");
00364       for (unsigned int i = 0; i < jointPoseGoal.joints.size(); i ++)
00365       {
00366         jointPoseGoal.joints[i] = baseJointPoseGoal[i] + (rand() % 700 - 350) / 10000;  //vary by up to ~2 degrees
00367       }
00368     }
00369   }
00370 
00371   if (!succeeded)
00372   {
00373     feedback.message = "Failed to ready arm.";
00374     armServer.publishFeedback(feedback);
00375 
00376     ROS_INFO("Plan and move to ready position failed.");
00377     result.success = false;
00378     armServer.setSucceeded(result);
00379     return;
00380   }
00381 
00382   if (goal->action == rail_manipulation_msgs::ArmGoal::RETRACT)
00383   {
00384     feedback.message = "Moving arm to retracted position...";
00385     armServer.publishFeedback(feedback);
00386 
00387     wpi_jaco_msgs::AngularCommand cmd;
00388     cmd.armCommand = true;
00389     cmd.fingerCommand = false;
00390     cmd.position = true;
00391     cmd.repeat = false;
00392     cmd.joints = defaultRetractPosition;
00393     angularCmdPublisher.publish(cmd);
00394     ros::Time startTime = ros::Time::now();
00395     ros::Rate loopRate(30);
00396     bool retracted = false;
00397     while (!retracted)
00398     {
00399       //check for preempt
00400       if (armServer.isPreemptRequested() || !ros::ok())
00401       {
00402         ROS_INFO("Ready arm action preempted.");
00403         std_srvs::Empty srv;
00404         if (!eraseTrajectoriesClient.call(srv))
00405         {
00406           ROS_INFO("Could not call erase trajectories service...");
00407         }
00408         result.success = false;
00409         armServer.setPreempted(result);
00410         return;
00411       }
00412 
00413       //check if arm is retracted
00414       retracted = isArmRetracted(defaultRetractPosition);
00415 
00416       //check for timeout
00417       ros::Time currentTime = ros::Time::now();
00418       if ((currentTime.toSec() - startTime.toSec()) > 10.0)
00419       {
00420         feedback.message = "Retracting arm timed out.";
00421         armServer.publishFeedback(feedback);
00422 
00423         ROS_INFO("Ready arm timed out.");
00424         result.success = false;
00425         armServer.setSucceeded(result);
00426         return;
00427       }
00428       loopRate.sleep();
00429     }
00430   }
00431 
00432   switch (goal->action) {
00433     case rail_manipulation_msgs::ArmGoal::READY:
00434       feedback.message = "Ready arm completed.";
00435       armServer.publishFeedback(feedback);
00436       break;
00437     case rail_manipulation_msgs::ArmGoal::RETRACT:
00438       feedback.message = "Retract arm completed.";
00439       armServer.publishFeedback(feedback);
00440       break;
00441     default:
00442       feedback.message = "Arm action completed.";
00443       armServer.publishFeedback(feedback);
00444       break;
00445   }
00446 
00447   result.success = succeeded;
00448   armServer.setSucceeded(result);
00449 }
00450 
00451 void CommonActions::executeWipeSurface(const carl_moveit::WipeSurfaceGoalConstPtr &goal)
00452 {
00453   carl_moveit::WipeSurfaceFeedback feedback;
00454   carl_moveit::WipeSurfaceResult result;
00455   stringstream ss;
00456 
00457   //move to wiping position
00458   rail_manipulation_msgs::MoveToPoseGoal poseGoal;
00459   poseGoal.pose.header.frame_id = "base_footprint";
00460   poseGoal.pose.pose.position.x = 0.869;
00461   poseGoal.pose.pose.position.y = 0.0;
00462   poseGoal.pose.pose.position.z = goal->height;
00463   poseGoal.pose.pose.orientation.x = -0.605;
00464   poseGoal.pose.pose.orientation.y = 0.271;
00465   poseGoal.pose.pose.orientation.z = 0.699;
00466   poseGoal.pose.pose.orientation.w = 0.267;
00467 
00468   moveToPoseClient.sendGoal(poseGoal);
00469   moveToPoseClient.waitForResult(ros::Duration(30.0));
00470   if (!moveToPoseClient.getResult()->success)
00471   {
00472     ss.str("");
00473     ss << "Moving to initial wiping position failed.";
00474     feedback.message = ss.str();
00475     wipeSurfaceServer.publishFeedback(feedback);
00476     result.success = false;
00477     wipeSurfaceServer.setAborted(result, "Unable to move to appraoch angle.");
00478     return;
00479   }
00480 
00481   //move arm back and forth to wipe
00482   ss.str("");
00483   ss << "Wiping...";
00484   feedback.message = ss.str();
00485   wipeSurfaceServer.publishFeedback(feedback);
00486 
00487   rail_manipulation_msgs::CartesianPath srv;
00488   for (unsigned int i = 0; i < 3; i ++)
00489   {
00490     geometry_msgs::PoseStamped pose = poseGoal.pose;
00491     /*
00492     //back and forth motion
00493     pose.position.y += .2;
00494     srv.request.waypoints.push_back(pose);
00495     pose.position.y -= .4;
00496     srv.request.waypoints.push_back(pose);
00497     */
00498     //diamond motion
00499     pose.pose.position.y += .15;
00500     srv.request.waypoints.push_back(pose);
00501     pose.pose.position.y -= .15;
00502     pose.pose.position.x += .05;
00503     srv.request.waypoints.push_back(pose);
00504     pose.pose.position.y -= .15;
00505     pose.pose.position.x -= .05;
00506     srv.request.waypoints.push_back(pose);
00507     pose.pose.position.y += .15;
00508     pose.pose.position.x -= .05;
00509     srv.request.waypoints.push_back(pose);
00510   }
00511   ROS_INFO("Waypoints y:");
00512   for (unsigned int i = 0; i < srv.request.waypoints.size(); i ++)
00513   {
00514     ROS_INFO("%f", srv.request.waypoints[i].pose.position.y);
00515   }
00516   srv.request.avoidCollisions = false;
00517   if (!cartesianPathClient.call(srv))
00518   {
00519     ROS_INFO("Could not call Jaco Cartesian path service.");
00520     result.success = false;
00521     wipeSurfaceServer.setAborted(result, "Could not call Jaco Cartesian path service.");
00522     return;
00523   }
00524 
00525   ROS_INFO("Wipe surface action completed successfully.");
00526   result.success = true;
00527   wipeSurfaceServer.setSucceeded(result);
00528 }
00529 
00530 void CommonActions::liftArm(const rail_manipulation_msgs::LiftGoalConstPtr &goal)
00531 {
00532   rail_manipulation_msgs::LiftResult result;
00533 
00534   rail_manipulation_msgs::CartesianPath srv;
00535   tf::StampedTransform currentEefTransform;
00536   tfListener.waitForTransform("jaco_link_eef", "base_footprint", ros::Time::now(), ros::Duration(1.0));
00537   tfListener.lookupTransform("base_footprint", "jaco_link_eef", ros::Time(0), currentEefTransform);
00538   geometry_msgs::PoseStamped liftPose;
00539   liftPose.header.frame_id = "base_footprint";
00540   liftPose.pose.position.x = currentEefTransform.getOrigin().x();
00541   liftPose.pose.position.y = currentEefTransform.getOrigin().y();
00542   liftPose.pose.position.z = currentEefTransform.getOrigin().z() + .1;
00543   liftPose.pose.orientation.x = currentEefTransform.getRotation().x();
00544   liftPose.pose.orientation.y = currentEefTransform.getRotation().y();
00545   liftPose.pose.orientation.z = currentEefTransform.getRotation().z();
00546   liftPose.pose.orientation.w = currentEefTransform.getRotation().w();
00547   srv.request.waypoints.push_back(liftPose);
00548   srv.request.avoidCollisions = false;
00549 
00550   if (!cartesianPathClient.call(srv))
00551   {
00552     ROS_INFO("Could not call Jaco Cartesian path service.");
00553     result.success = false;
00554     liftServer.setAborted(result, "Could not call Jaco Cartesian path service.");
00555     return;
00556   }
00557 
00558   result.success = srv.response.success;
00559   liftServer.setSucceeded(result);
00560 }
00561 
00562 bool CommonActions::isArmRetracted(const vector<float> &retractPos)
00563 {
00564   float dstFromRetract = 0;
00565 
00566   //get joint positions
00567   wpi_jaco_msgs::GetAngularPosition::Request req;
00568   wpi_jaco_msgs::GetAngularPosition::Response res;
00569   if(!jacoPosClient.call(req, res))
00570   {
00571     ROS_INFO("Could not call Jaco joint position service.");
00572     return false;
00573   }
00574 
00575   for (unsigned int i = 0; i < retractPos.size(); i ++)
00576   {
00577     dstFromRetract += fabs(retractPos[i] - res.pos[i]);
00578   }
00579 
00580   if (dstFromRetract > 0.175)
00581     return false;
00582   return true;
00583 }
00584 
00585 int main(int argc, char **argv)
00586 {
00587   ros::init(argc, argv, "carl_moveit_common_actions");
00588 
00589   CommonActions ca;
00590 
00591   ros::spin();
00592 }


carl_moveit
Author(s): David Kent
autogenerated on Thu Jun 6 2019 20:28:44